Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API to test global shortcuts #96

Closed
rayrutjes opened this issue Jul 24, 2016 · 13 comments
Closed

API to test global shortcuts #96

rayrutjes opened this issue Jul 24, 2016 · 13 comments

Comments

@rayrutjes
Copy link

I have window that only shows when a key combination is pressed (Ctrl+Space by default).
The behaviour uses electron's globalShortcut.

I have found no way of simulating the shortcut, is this possible somehow?

Keep it up!

@MarshallOfSound
Copy link
Member

@rayrutjes This brings up something I mentioned in another issue somewhere.

However this raises a point about testing as a whole. Considering the frameworks that electron uses are thoroughly tested both in Electron and upstream in Chromium.

Do you actually want / need to test that globalShortcut works correctly. What you need to test is that given a function is called with the correct parameters the correct action occurs. For example.

// This is what you need to test
const doThing = () => {
  // Do the thing
};

// This is not
globalShortcut.register('Ctrl+A', doThing);

You should assume that the framework you are using (Electron) is tested correctly and test your code does what it should, not that globalShortcut does what it should.

This is all just IMO but it makes sense to me 😆

So you shouldn't be mocking or simulating the shortcut. Simply call the function the shortcut is associated with. 👍

@rayrutjes
Copy link
Author

Thank you @MarshallOfSound for your answer.
I agree with the fact that we shouldn't be testing electron itself.
In my app, I already have bunch of unit tests. That said, I wanted to test a user scenario:

  • When user presses "Ctrl+Space" then the search window becomes visible and the focus should be given to the search input.
  • When the user presses enter, a new page should be opened in the default browser and the search window should be closed.

I feel like this is what spectron is aimed at solving, right? If it isn't, would you be so kind as to suggest a case where spectron makes sense?

I've seen tests where we test the size of the windows, but that brings us back to testing electron.
There also seems to be no way of getting a window based on some kind of unique identifier, which makes the tests brittle if based on app.browserWindow.

Some insights about where spectron makes sense would be very much appreciated.

@bayleedev
Copy link
Contributor

I agree this would be useful, I'm dynamically creating global shortcuts. Testing the action that happens is done, but knowing those shortcuts work in combination and through the stack would be amazing.

@bayleedev
Copy link
Contributor

I couldn't get this integrated into spectron, but I did manage to get robotjs integrated into my test suite. Using robot.tapKey() to test my dynamic keyboard shortcuts.

@aigarsdz
Copy link

aigarsdz commented Oct 1, 2016

I am facing the same problem. RobotJS is nice and does the job well, but I really don't want to add another dependency just to test a single feature of my app. Any chance for this to be implemented into Spectorn?

@tansaku
Copy link

tansaku commented Sep 4, 2017

@blainesch I really need this functionality - do you have an example of robotjs integrated with spectron so I can copy the setup? many thanks in advance ...

@bayleedev
Copy link
Contributor

@tansaku spectron and robotjs are used inside of zazu. Check out the features/step_definitions directory for usage.

@tansaku
Copy link

tansaku commented Sep 5, 2017

thanks @blainesch - I have something working :-)

@tansaku
Copy link

tansaku commented Sep 6, 2017

what I notice though is that robotjs is hitting the computer generally rather than the electron app specifically, so if I start trying to do something else during the acceptance tests, then the change of window focus screws things up.

Would really love to be able to send specific key presses to electron via chromedriver ...

@linonetwo
Copy link

robotjs is not working for zazu, robotjs don't support node 12 at this time.

I use this to press keys:

  hitKey (key, modifier) {
    if (os.type() === 'Darwin' && !isTravis) {
      const keyForAppleScript = key.length === 1 ? `\\"${key}\\"` : key
      if (modifier) {
        const modifierForAppleScript = modifier.replace('alt', 'option')
        return exec(`Script="tell app \\"System Events\\" to keystroke ${keyForAppleScript} using ${modifierForAppleScript} down"
          osascript -e "$Script"`)
      } else {
        return exec(`Script="tell app \\"System Events\\" to keystroke ${keyForAppleScript}"
          osascript -e "$Script"`)
      }
    }
    const robot = require('robotjs')
    if (modifier) {
      return Promise.resolve(robot.keyTap(key, modifier))
    } else {
      // * will becomes 8, see https://github.com/octalmage/robotjs/issues/285
      const robotjsBadChars = /[~!@#$%^&*()_+{}|:"<>?]/
      let match = key.match(robotjsBadChars)
      if (match) {
        return Promise.resolve(robot.keyTap(key, 'shift'))
      }
      return Promise.resolve(robot.keyTap(key))
    }
  }

@codebytere
Copy link
Member

Closing in light of above workarounds.

@AdrianoFerrari
Copy link
Contributor

I recommend this issue be re-opened. None of the above work-arounds work reliably (they've all worked for me at some point, but updates to Node, Electron, or new OS cause them to break, especially on macOS).

Given that Electron apps can and do use global shortcuts, it'd be great to be able to test them. As it stands, I've had to disable testing on macOS, because I can't get spectron to handle global shortcuts like "Cmd+S".

@coda-nsit
Copy link

I have reopened this issue in light of the comment by AdrianoFerrari
#1010

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants