5

Trying to do accessibility automation and want to use shift+tab to go back an element. But can't seem to get anything to work. Tried what the doc imply should work based off their "Example, pressing ctrl+c:":

action = ActionChains(driver)
action.key_down(Keys.SHIFT)
action.send_keys(Keys.TAB)
action.key_up(Keys.SHIFT)
action.perform();

Then I guessed at :

action = ActionChains(driver)
action.key_down(Keys.SHIFT).key_down(Keys.TAB)
action.key_up(Keys.SHIFT).key_up(Keys.TAB)
action.perform();

And:

action = ActionChains(driver)
action.key_down(Keys.SHIFT)
action.key_down(Keys.TAB)
action.perform();
action = ActionChains(driver)
action.key_up(Keys.SHIFT)
action.key_up(Keys.TAB)
action.perform();

And:

action = ActionChains(driver)
action.send_keys(Keys.TAB + Keys.SHIFT).perform();

And:

ActionChains(driver).send_keys(Keys.TAB).perform() # Tabs 1 forward
time.sleep(1)
ActionChains(driver).send_keys(Keys.SHIFT, Keys.TAB).perform() # Tabs 1 backwards
time.sleep(1)
ActionChains(driver).send_keys(Keys.SHIFT, Keys.TAB).perform() # Tabs 1 forward
time.sleep(1)

But none of them work. At least at selenium 3.14 & chrome 71.


So how do I hit shift and tab at the same time in Python Webdriver?

UPDATE: The correct answer, answered the summary question of two keys at the same time. But my specific example, I had tried the correct way to send them but it was working intermittently. This is because unbeknownst to me it was treating the shift key as a press down and not release. So the second time I would try it, it was release shift (and thus not tab backwards every other time). So specially for shift and tab you need to do this to press, shift, tab, then release shift.

# At time of writing this didn't work, but now seems to.
action = ActionChains(context.driver)
action.key_down(Keys.SHIFT)
action.send_keys(Keys.TAB)
action.key_up(Keys.SHIFT)
action.perform()

# Chrome was only taking this at time of writing question.
ActionChains(driver).send_keys(Keys.SHIFT, Keys.TAB, Keys.SHIFT).perform()

2 Answers 2

2

That's the signature for send_keys:

send_keys(*keys_to_send)

The asterisk means it expects a variable number of arguments. So, you should do something like:

send_keys(Keys.ALT, Keys.TAB)

Or maybe a combination of key_down and key_up.

2
  • So this kinda worked but not for the purposes I need. In the interest of keeping the code formatted I added it as the last example to my question. But sending them comma separated goes back 1 element but then if you do it a 2nd time it only goes forward instead.
    – Cynic
    Dec 8, 2018 at 16:40
  • 1
    Of I get it, for shift you have to send it again to release. Will you please update your answer to include for shift tab the release. ActionChains(driver).send_keys(Keys.SHIFT, Keys.TAB, Keys.SHIFT).perform().
    – Cynic
    Dec 8, 2018 at 16:48
1

I can't get this to work on my end either. Digging around, I found a Stack Overflow answer that points to this Chromium bug, which says:

This is a limitation in the way we simulate keyboard input in ChromeDriver. Keys get sent directly to the render process, bypassing the browser process. So any keyboard shortcut handlers in the browser process will not be invoked by sendKeys().

Possibly this problem also applies to ActionChains. Please let us know if you do figure out a way!

1
  • 1
    Just so you know I did get this to work for tabbing to elements. But my solution does not work for opening a new tab as mentioned in this bug.
    – Cynic
    Jan 15, 2019 at 17:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.