node.jscontinuous-integrationelectronkeyboard-shortcutsrobotjs

Simulating global keyboard shortcuts to test an Electron app in travis-ci and appveyor


I am trying to do an end-to-end test of my Electron app using Spectron. I need these tests to work on travis-ci (linux and mac) and appveyor (windows).

I need to simulate the global shortcut Ctrl + X (⌘ + X on Mac). Spectron does not provide the functionality to simulate key presses. Therefore I tried using RobotJS, but it's extremely difficult to get it to build reliably on travis and appveyor. I've also tried node-key-sender, which works fine for windows and linux, but I can't get it to press the key. I've tried using the string 'command' and 'meta' in node-key-sender with no success.

Is there a solution for this problem that works reliably on travis-ci and appveyor?

Note: Skipping simulating they key press entirely is not and option. I am trying to write an end-to-end test using Spectron and there's no way to call functions in your app directly from Spectron.


Solution

  • Have you tried sending key-codes themselves using the key-down and key-up events?

    To do this using node-key-sender it looks like you can use the batchTypeKey methods (there might be other methods that take the event type too, I'm not sure)

    Sending text using node-key-sender will send key-codes that are dependent on the caller's keyboard layout configuration, which can be set manually in node-key-sender.

    The interpretation of keyboard events can vary depending on the keyboard, its driver, and the OS, so you need to know what exactly your application expects.

    Take a look at this w3 key press tool and play around with it yourself and see if your sending the correct key-event/key-code combinations.

    On my Mac, using the above tool, the left command key is shown as generating a key-down event with key-code 91 and metadata set to true followed by a key-up event with key-code 91. In contrast, the opening bracket key is shown as generating a key-down, followed by a key-press, followed by a key-up using key-code 91 for the key press event and key-code 219 for the key down/up events. (Note: My guess is that only the key down/up events are coming from the keyboard and that Safari itself is generating the key-press event in-between the key-down and key-up events, but I'm not 100% on that)

    In reply to my comment, you can test to see if travis-ci is affected by this mapping change, if so switching the control/command key on Macs is common enough that I would suspect there is a travis-ci setting to indicate this switch. If it works, the change would eliminate the need for system dependent code when sending the control key in your tests.

    Personally I'd rather abstract sending a control-key and make it context and system aware than re-map the command key in my Mac OS, reason being if you have other applications that interact with the Mac OS (travis-ci for example) then you don't have to worry about the mapping change affecting them.

    More reading on javascript key events