I'm working on an automation suite where I need to test keyboard shortcuts, specifically something like 'Ctrl + A' to select all text or 'Ctrl + Shift + S' to save a document. I tried using the standard send_keys() method twice, but it just types the letters sequentially instead of holding them down together. Is there a specific class or method in Selenium that allows for chorded key presses or simulating holding a modifier key while pressing another?
3 answers
To handle multiple keys or keyboard shortcuts in Selenium, you must use the ActionChains class rather than the basic send_keys method. ActionChains allows you to queue up multiple actions, such as key_down, send_keys, and key_up. For example, to perform a Ctrl+C, you would use ActionChains(driver).key_down(Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL).perform(). This ensures the modifier key is physically held down while the subsequent key is pressed. Always remember to call .perform() at the end of your chain, or the actions will never be executed by the driver. It’s also a good habit to release the keys (key_up) to avoid getting the browser stuck in a state where it thinks a modifier is still active.
Does this approach work consistently across different browsers like Safari or Chrome on macOS, given that Mac uses the Command key instead of Control? I’ve run into issues where my scripts fail on different operating systems because the modifier key constants are different.
You can also use the Keys.chord() method for simpler combinations. For example, element.send_keys(Keys.CONTROL, "a") often works as a shortcut without needing the full ActionChains setup
I agree with Heather; Keys.chord() is great for quick two-key combinations. However, as Sarah mentioned, if you need more complex sequences—like holding Shift and Alt while clicking—ActionChains is definitely the more reliable and professional way to handle those complex user interactions.
Mark, you’ve touched on a classic cross-platform testing headache. To solve this, you can implement a simple check for the platform using sys.platform. If it's 'darwin', you should use Keys.COMMAND; otherwise, use Keys.CONTROL. By wrapping this logic in a helper function, your tests for shortcuts like 'Copy/Paste' will remain robust and portable regardless of whether the CI/CD pipeline is running on a Linux container or a local Mac machine.