Skip to content

Commit 9e47def

Browse files
committed
Add pressed() method
1 parent b83d353 commit 9e47def

File tree

3 files changed

+62
-19
lines changed

3 files changed

+62
-19
lines changed

docs/keyboard.rst

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@ keyboard events inside the current browser window.
1616
.. note:: Input detection is limited to the page. You cannot control the browser
1717
or your operating system directly using the keyboard.
1818

19+
The keyboard interface is generally used to trigger modifier keys.
20+
For text input, using the keyboard is not recommended. Instead, use the
21+
:func:`element.fill() <splinter.driver.ElementAPI.fill>` method.
22+
1923
.. note:: The control modifier key is different across operating systems.
20-
e.g.: macOS uses `Command` and Windows & Linux use `Control`.
21-
If you need a cross-platform solution, `CTRL` can be used and will be resolved
24+
e.g.: macOS uses `COMMAND` and Windows & Linux use `CONTROL`.
25+
For a cross-platform solution, `CTRL` can be used and will be resolved
2226
for you.
2327

2428
Actions
@@ -86,6 +90,23 @@ This allows multiple presses to be chained together:
8690
the press method is designed for single keys. There may be unintended
8791
side effects to using it in place of Element.fill() or Element.type().
8892

93+
Press Using a Context Manager
94+
-----------------------------
95+
96+
Using the `pressed()` method, a context manager will be invoked.
97+
The specified key will be held down, then released when the block is exited.
98+
99+
.. code-block:: python
100+
101+
from splinter import Browser
102+
103+
104+
browser = Browser()
105+
browser.visit("https://duckduckgo.com/")
106+
with browser.keyboard.pressed("SHIFT"):
107+
browser.find_by_css("[@name='q']").fill('splinter')
108+
109+
89110
Element.press()
90111
---------------
91112

splinter/driver/webdriver/keyboard.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import contextlib
12
import platform
3+
from collections.abc import Iterator
24
from typing import Union
35

46
from selenium.webdriver.common.action_chains import ActionChains
@@ -136,3 +138,19 @@ def press(self, key_pattern: str, delay: int = 0) -> "Keyboard":
136138
chain.perform()
137139

138140
return self
141+
142+
@contextlib.contextmanager
143+
def pressed(self, key_pattern: str) -> Iterator[None]:
144+
"""Hold a key pattern inside a `with` block and releas it upon exit.
145+
146+
Arguments:
147+
key_pattern: Pattern of keys to hold and release.
148+
149+
Example:
150+
>>> b = Browser()
151+
>>> with b.keyboard.pressed('CONTROL'):
152+
>>> ...
153+
"""
154+
self.down(key_pattern)
155+
yield
156+
self.up(key_pattern)

tests/tests_webdriver/test_keyboard.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
from splinter.driver.webdriver import Keyboard
2-
3-
41
def test_keyboard_down_modifier(browser, app_url):
52
"""Scenario: Keys can be held down"""
63
browser.visit(app_url)
74

8-
keyboard = Keyboard(browser.driver)
9-
10-
keyboard.down("CONTROL")
5+
browser.keyboard.down("CONTROL")
116

127
elem = browser.find_by_css("#keypress_detect")
138
assert elem.first
@@ -17,22 +12,18 @@ def test_keyboard_up_modifier(browser, app_url):
1712
"""Scenario: Keys can be held up"""
1813
browser.visit(app_url)
1914

20-
keyboard = Keyboard(browser.driver)
21-
22-
keyboard.down("CONTROL")
23-
keyboard.up("CONTROL")
15+
browser.keyboard.down("CONTROL")
16+
browser.keyboard.up("CONTROL")
2417

2518
elem = browser.find_by_css("#keyup_detect")
2619
assert elem.first
2720

2821

2922
def test_keyboard_press_modifier(browser, app_url):
30-
"""Keys can be pressed"""
23+
"""Scenario: Keys can be pressed"""
3124
browser.visit(app_url)
3225

33-
keyboard = Keyboard(browser.driver)
34-
35-
keyboard.press("CONTROL")
26+
browser.keyboard.press("CONTROL")
3627

3728
elem = browser.find_by_css("#keyup_detect")
3829
assert elem.first
@@ -42,14 +33,27 @@ def test_element_press_combo(browser, app_url):
4233
"""Scenario: Key presses can be used in a combo"""
4334
browser.visit(app_url)
4435

45-
keyboard = Keyboard(browser.driver)
46-
47-
keyboard.press("CONTROL+a")
36+
browser.keyboard.press("CONTROL+a")
4837

4938
elem = browser.find_by_css("#keypress_detect_a")
5039
assert elem.first
5140

5241

42+
def test_keyboard_pressed_modifier(browser, app_url):
43+
"""Scenario: Keys can be pressed by a context manager."""
44+
browser.visit(app_url)
45+
46+
with browser.keyboard.pressed("CONTROL"):
47+
down_elem = browser.find_by_css("#keypress_detect")
48+
assert down_elem.first
49+
50+
up_elem = browser.find_by_css("#keyup_detect")
51+
assert up_elem.is_empty()
52+
53+
up_elem = browser.find_by_css("#keyup_detect")
54+
assert up_elem.first
55+
56+
5357
def test_keyboard_ctrl(browser, app_url):
5458
"""Scenario: The CTRL value is correct across platforms"""
5559
browser.visit(app_url)

0 commit comments

Comments
 (0)