is not held down, this method has no effect.
+
+ Arguments:
+ key: The name of a key to release.
+
+ Example:
+
+ >>> b = Browser()
+ >>> Keyboard(b.driver).down('SHIFT')
+ >>> Keyboard(b.driver).up('SHIFT')
+ """
+ chain = ActionChains(self.driver)
+ chain = self._resolve_key_up_action(chain, key)
+ chain.perform()
+ return self
+
+ def press(self, key_pattern: str, delay: int = 0) -> "Keyboard":
+ """Hold and release a key pattern.
+
+ Key patterns are strings of key names separated by '+'.
+ The following are examples of key patterns:
+ - 'CONTROL'
+ - 'CONTROL+a'
+ - 'CONTROL+a+BACKSPACE+b'
+
+ Arguments:
+ key_pattern: Pattern of keys to hold and release.
+ delay: Time, in seconds, to wait between the hold and release.
+
+ Example:
+
+ >>> b = Browser()
+ >>> Keyboard(b.driver).press('CONTROL+a')
+ """
+ keys_names = key_pattern.split("+")
+
+ chain = ActionChains(self.driver)
+
+ for item in keys_names:
+ chain = self._resolve_key_down_action(chain, item)
+
+ if delay:
+ chain = chain.pause(delay)
+
+ for item in keys_names:
+ chain = self._resolve_key_up_action(chain, item)
+
+ chain.perform()
+
+ return self
diff --git a/tests/static/index.html b/tests/static/index.html
index a8265e73e..9e547c1a1 100644
--- a/tests/static/index.html
+++ b/tests/static/index.html
@@ -32,6 +32,22 @@
addShadowRoot();
}, false);
+ document.onkeydown = function (e) {
+ if (e.key === "Control") {
+ $('body').append('Added when "Control" key is pressed down.
');
+ }
+ if (e.key === "a") {
+ $('body').append('Added when "a" key is pressed down.
');
+ }
+ };
+
+ document.onkeyup = function (e) {
+ e = e || window.event;
+ if (e.key === "Control") {
+ $('body').append('Added when "Control" key is released.
');
+ }
+ };
+
$(document).ready(function() {
$(".draggable").draggable();
$(".droppable").droppable({
diff --git a/tests/tests_webdriver/test_keyboard.py b/tests/tests_webdriver/test_keyboard.py
new file mode 100644
index 000000000..e29d1fb42
--- /dev/null
+++ b/tests/tests_webdriver/test_keyboard.py
@@ -0,0 +1,66 @@
+import platform
+
+from splinter.driver.webdriver import Keyboard
+
+
+def test_keyboard_down_modifier(browser, app_url):
+ browser.visit(app_url)
+
+ keyboard = Keyboard(browser.driver)
+
+ keyboard.down("CONTROL")
+
+ elem = browser.find_by_css("#keypress_detect")
+ assert elem.first
+
+
+def test_keyboard_up_modifier(browser, app_url):
+ browser.visit(app_url)
+
+ keyboard = Keyboard(browser.driver)
+
+ keyboard.down("CONTROL")
+ keyboard.up("CONTROL")
+
+ elem = browser.find_by_css("#keyup_detect")
+ assert elem.first
+
+
+def test_keyboard_press_modifier(browser, app_url):
+ browser.visit(app_url)
+
+ keyboard = Keyboard(browser.driver)
+
+ keyboard.press("CONTROL")
+
+ elem = browser.find_by_css("#keyup_detect")
+ assert elem.first
+
+
+def test_element_press_combo(browser, app_url):
+ browser.visit(app_url)
+
+ keyboard = Keyboard(browser.driver)
+
+ keyboard.press("CONTROL+a")
+
+ elem = browser.find_by_css("#keypress_detect_a")
+ assert elem.first
+
+
+def test_element_copy_paste(browser, app_url):
+ control_key = "META" if platform.system() == "Darwin" else "CONTROL"
+
+ browser.visit(app_url)
+
+ elem = browser.find_by_name("q")
+ elem.fill("Copy this value")
+ elem.press(f"{control_key}+a")
+ elem.press(f"{control_key}+c")
+ elem.clear()
+
+ assert elem.first.value == ""
+
+ elem.press(f"{control_key}+v")
+
+ assert elem.first.value == "Copy this Value"