Add keyboard class and Element.press()
This PR implements browser.keyboard and element.press(). These act as keyboard-specific APIs for using modifier keys so users do not need to use Selenium's ActionChains API directly. It addresses the issues raised in #572.
As a downside to the input method, it may lead to typos such as:
browser.keyboard.press("CONTROLx") instead of browser.keyboard.press("CONTROL+x")
However, the following is valid and safer, if clunky:
browser.keyboard.press(selenium.Keys.CONTROL)
browser.keyboard.press(f"{selenium.Keys.CONTROL}+x")
An alternative implementation could use a list instead:
browser.keyboard.press(["CONTROL", "x"]) and browser.keyboard.press([selenium.Keys.CONTROL, "x"])
The inspiration for this design comes from: https://playwright.dev/python/docs/input#keys-and-shortcuts
Sending an arbitrary number of arguments is something I don't favour. It makes type checking more difficult and the code more brittle.
A list is less ambiguous and more difficult to typo. However, the "foo+bar" pattern makes it clearer that press("CONTROL+a") will do:
CONTROL down, a down, CONTROL up, a up and not CONTROL down, CONTROL up, a down, a up
@fsouza I'm not 100% done testing and documenting this feature, but it more or less works. Opening the floor to discuss the implementation here before merging.