Skip to content

Commit 2450902

Browse files
authored
Merge pull request #22 from levi-rs/add-find-write
Add find_write to waiter
2 parents 8ab497e + ef0ba97 commit 2450902

File tree

3 files changed

+144
-4
lines changed

3 files changed

+144
-4
lines changed

README.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,23 @@ Explicit easily solves this by waiting for the element to load in:
110110
login_button.click()
111111
finally:
112112
driver.quit()
113+
114+
Additionally, you can use explicit to handle the writing:
115+
116+
.. code-block:: python
117+
118+
from explicit import waiter
119+
from selenium import webdriver
120+
from selenium.webdriver.common.by import By
121+
122+
driver = webdriver.Chrome()
123+
124+
try:
125+
driver.get("https://github.com/this/doesntexist")
126+
127+
waiter.find_write(driver, "login_field", "my_username", by=By.ID)
128+
129+
waiter.find_write(driver, "password", "my_password", by=By.ID, send_enter=True)
130+
131+
finally:
132+
driver.quit()

explicit/waiter.py

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"""
88

99
from selenium.webdriver.common.by import By
10+
from selenium.webdriver.common.keys import Keys
1011
from selenium.webdriver.support.ui import WebDriverWait
1112
from selenium.webdriver.support import expected_conditions as EC
1213

@@ -18,7 +19,7 @@
1819

1920

2021
def find_element(driver, elem_path, by=CSS, timeout=TIMEOUT, poll_frequency=0.5):
21-
""" find and return an element once located
22+
""" Find and return an element once located
2223
2324
find_element locates an element on the page, waiting
2425
for up to timeout seconds. The element, when located,
@@ -39,3 +40,41 @@ def find_element(driver, elem_path, by=CSS, timeout=TIMEOUT, poll_frequency=0.5)
3940
"""
4041
wait = WebDriverWait(driver, timeout, poll_frequency)
4142
return wait.until(EC.presence_of_element_located((by, elem_path)))
43+
44+
45+
def find_write(driver, elem_path, write_str, clear_first=True, send_enter=False,
46+
by=CSS, timeout=TIMEOUT, poll_frequency=0.5):
47+
""" Find a writable element and write to it
48+
49+
find_write locates a writable element on the page, waiting
50+
for up to timeout seconds. Once found, it writes the string
51+
to it.
52+
53+
Args:
54+
driver (selenium webdriver or element): A driver or element
55+
elem_path (str): String used to located the element
56+
write_str (str): String to write
57+
clear_first (bool): Clear the contents before writing (default True)
58+
send_enter (bool): Send a keyboard ENTER after writing string
59+
by (selenium By): Selenium By reference
60+
timeout (int): Selenium Wait timeout, in seconds
61+
poll_frequency (float): Selenium Wait polling frequency, in seconds
62+
63+
Returns:
64+
element: Selenium element
65+
66+
Raises:
67+
TimeoutException: Raised when target element isn't located
68+
"""
69+
elem = find_element(driver, elem_path=elem_path, by=by, timeout=timeout,
70+
poll_frequency=poll_frequency)
71+
72+
if clear_first:
73+
elem.clear()
74+
75+
elem.send_keys(write_str)
76+
77+
if send_enter:
78+
elem.send_keys(Keys.ENTER)
79+
80+
return elem

tests/test_waiter.py

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,94 @@
1+
try:
2+
import mock
3+
except ImportError:
4+
from unittest import mock
5+
6+
from selenium.webdriver.common.by import By
7+
from selenium.webdriver.common.keys import Keys
8+
19
from explicit import waiter
210

11+
CSS = By.CSS_SELECTOR
12+
13+
14+
def test_find_element_with_defaults(driver, element):
15+
""" Verify the waiter can find and return an element
16+
"""
17+
mock_css_path = "div.mock-css-path"
18+
19+
driver.find_element.side_effect = [None, element]
20+
21+
elem = waiter.find_element(driver, mock_css_path)
22+
23+
assert driver.find_element.called
24+
assert elem is element
25+
assert len(driver.mock_calls) == 2
26+
assert driver.find_element.call_args_list == [mock.call(CSS, mock_css_path),
27+
mock.call(CSS, mock_css_path)]
28+
29+
30+
def test_find_element_with_non_defaults(driver, element):
31+
""" Verify the waiter can find and return an element when using
32+
non-default kwargs
33+
"""
34+
mock_xpath_path = "div[@id=mock-id]"
35+
36+
driver.find_element.side_effect = [None, element]
37+
38+
elem = waiter.find_element(driver, mock_xpath_path, by=By.XPATH)
339

4-
def test_find_element(driver, element):
5-
""" Verify the water can find and return an element
40+
assert driver.find_element.called
41+
assert elem is element
42+
assert len(driver.mock_calls) == 2
43+
assert driver.find_element.call_args_list == [mock.call(By.XPATH, mock_xpath_path),
44+
mock.call(By.XPATH, mock_xpath_path)]
45+
46+
47+
def test_find_write_with_defaults(driver, element):
48+
""" Verify the waiter can find and write to an element, using
49+
default kwargs
650
"""
51+
mock_css_path = "div.mock-css-path"
52+
mock_write_string = "mock write string"
53+
754
driver.find_element.side_effect = [None, element]
855

9-
elem = waiter.find_element(driver, "div.mock-css-path")
56+
elem = waiter.find_write(driver, mock_css_path, mock_write_string)
1057

58+
# Element locating asserts
1159
assert driver.find_element.called
60+
assert elem is element
1261
assert len(driver.mock_calls) == 2
62+
assert driver.find_element.call_args_list == [mock.call(CSS, mock_css_path),
63+
mock.call(CSS, mock_css_path)]
64+
65+
# Element writing asserts
66+
assert elem.clear.called
67+
assert len(elem.send_keys.call_args_list) == 1
68+
assert elem.send_keys.call_args == mock.call(mock_write_string)
69+
70+
71+
def test_find_write_with_non_defaults(driver, element):
72+
""" Verify the waiter can find and write to an element, using
73+
non-default kwargs
74+
"""
75+
mock_id_path = "mock id"
76+
mock_write_string = "mock write string"
77+
78+
driver.find_element.side_effect = [None, element]
79+
80+
elem = waiter.find_write(driver, mock_id_path, mock_write_string,
81+
by=By.ID, clear_first=False, send_enter=True)
82+
83+
# Element locating asserts
84+
assert driver.find_element.called
1385
assert elem is element
86+
assert len(driver.mock_calls) == 2
87+
assert driver.find_element.call_args_list == [mock.call(By.ID, mock_id_path),
88+
mock.call(By.ID, mock_id_path)]
89+
90+
# Element writing asserts
91+
assert not elem.clear.called
92+
assert len(elem.send_keys.call_args_list) == 2
93+
assert elem.send_keys.call_args_list == [mock.call(mock_write_string),
94+
mock.call(Keys.ENTER)]

0 commit comments

Comments
 (0)