Skip to content

Commit 6d11358

Browse files
authored
Merge pull request #282 from seleniumbase/add-exact-text-methods
Adding exact text methods and other improvements
2 parents 81d2f9e + 456a311 commit 6d11358

File tree

8 files changed

+101
-15
lines changed

8 files changed

+101
-15
lines changed

examples/my_first_test.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@
44
class MyTestClass(BaseCase):
55

66
def test_basic(self):
7-
self.open('https://xkcd.com/353/') # Navigate to the web page
7+
self.open("https://xkcd.com/353/") # Navigate browser to page
88
self.assert_element('img[alt="Python"]') # Assert element on page
99
self.click('a[rel="license"]') # Click element on page
10-
self.assert_text('free to copy', 'div center') # Assert text on page
10+
self.assert_text("free to copy", "div center") # Assert text in area
1111
self.open("https://xkcd.com/1481/")
1212
title = self.get_attribute("#comic img", "title") # Get an attribute
1313
self.assert_true("86,400 seconds per day" in title)
14-
self.click('link=Blag') # Click on link
15-
self.assert_text('The blag of the webcomic', 'h2')
16-
self.update_text('input#s', 'Robots!\n') # Type text
17-
self.assert_text('Hooray robots!', '#content')
18-
self.open('https://xkcd.com/1319/')
19-
self.assert_text('Automation', 'div#ctitle')
14+
self.click("link=Blag") # Click on link
15+
self.assert_text("The blag of the webcomic", "h2")
16+
self.update_text("input#s", "Robots!\n") # Type text
17+
self.assert_text("Hooray robots!", "#content")
18+
self.open("https://xkcd.com/1319/")
19+
self.assert_exact_text("Automation", "#ctitle")
2020

2121
####
2222

help_docs/method_summary.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@ self.assert_element(
261261
self.wait_for_text_visible(text, selector="html", by=By.CSS_SELECTOR,
262262
timeout=settings.LARGE_TIMEOUT)
263263

264+
self.wait_for_exact_text_visible(text, selector="html", by=By.CSS_SELECTOR,
265+
timeout=settings.LARGE_TIMEOUT)
266+
264267
self.wait_for_text(text, selector="html", by=By.CSS_SELECTOR,
265268
timeout=settings.LARGE_TIMEOUT)
266269

@@ -273,6 +276,9 @@ self.assert_text_visible(text, selector="html", by=By.CSS_SELECTOR,
273276
self.assert_text(text, selector="html", by=By.CSS_SELECTOR,
274277
timeout=settings.SMALL_TIMEOUT)
275278

279+
self.assert_exact_text(text, selector="html", by=By.CSS_SELECTOR,
280+
timeout=settings.SMALL_TIMEOUT)
281+
276282
########
277283

278284
self.wait_for_link_text_visible(link_text, timeout=settings.LARGE_TIMEOUT)

integrations/node_js/my_first_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ def test_basic(self):
1616
self.update_text('input#s', 'Robots!\n')
1717
self.assert_text('Hooray robots!', '#content')
1818
self.open('http://xkcd.com/1319/')
19-
self.assert_text('Automation', 'div#ctitle')
19+
self.assert_exact_text('Automation', '#ctitle')

requirements.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ unittest2
88
selenium==3.141.0
99
requests==2.21.0
1010
urllib3==1.24.1
11-
pytest>=4.2.0
11+
pytest>=4.2.1
1212
pytest-cov>=2.6.1
1313
pytest-html>=1.20.0
1414
pytest-rerunfailures>=6.0
@@ -18,7 +18,6 @@ beautifulsoup4>=4.6.0
1818
colorama==0.4.1
1919
pyotp>=2.2.7
2020
boto>=2.49.0
21-
more-itertools>=5.0.0,<6.0.0
2221
flake8==3.7.5
2322
PyVirtualDisplay==0.2.1
2423
-e .

seleniumbase/console_scripts/sb_mkdir.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ def main():
9393
data.append(" self.update_text('input#s', 'Robots!\\n')")
9494
data.append(" self.assert_text('Hooray robots!', '#content')")
9595
data.append(" self.open('https://xkcd.com/1319/')")
96-
data.append(" self.assert_text('Automation', 'div#ctitle')")
96+
data.append(" self.assert_exact_text('Automation', '#ctitle')")
9797
data.append("")
9898
file_path = "%s/%s" % (dir_name, "my_first_test.py")
9999
file = codecs.open(file_path, "w+", "utf-8")

seleniumbase/fixtures/base_case.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,13 +437,16 @@ def get_current_url(self):
437437
return self.driver.current_url
438438

439439
def get_page_source(self):
440+
self.wait_for_ready_state_complete()
440441
return self.driver.page_source
441442

442443
def get_page_title(self):
444+
self.wait_for_ready_state_complete()
443445
return self.driver.title
444446

445447
def get_title(self):
446448
""" The shorter version of self.get_page_title() """
449+
self.wait_for_ready_state_complete()
447450
return self.driver.title
448451

449452
def go_back(self):
@@ -2065,6 +2068,19 @@ def wait_for_text_visible(self, text, selector="html", by=By.CSS_SELECTOR,
20652068
return page_actions.wait_for_text_visible(
20662069
self.driver, text, selector, by, timeout)
20672070

2071+
def wait_for_exact_text_visible(self, text, selector="html",
2072+
by=By.CSS_SELECTOR,
2073+
timeout=settings.LARGE_TIMEOUT):
2074+
if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT:
2075+
timeout = self.__get_new_timeout(timeout)
2076+
if page_utils.is_xpath_selector(selector):
2077+
by = By.XPATH
2078+
if page_utils.is_link_text_selector(selector):
2079+
selector = page_utils.get_link_text_from_selector(selector)
2080+
by = By.LINK_TEXT
2081+
return page_actions.wait_for_exact_text_visible(
2082+
self.driver, text, selector, by, timeout)
2083+
20682084
def wait_for_text(self, text, selector="html", by=By.CSS_SELECTOR,
20692085
timeout=settings.LARGE_TIMEOUT):
20702086
""" The shorter version of wait_for_text_visible() """
@@ -2108,6 +2124,29 @@ def assert_text(self, text, selector="html", by=By.CSS_SELECTOR,
21082124
self.__highlight_with_assert_success(messenger_post, selector, by)
21092125
return True
21102126

2127+
def assert_exact_text(self, text, selector="html", by=By.CSS_SELECTOR,
2128+
timeout=settings.SMALL_TIMEOUT):
2129+
""" Similar to assert_text(), but the text must be exact, rather than
2130+
exist as a subset of the full text.
2131+
(Extra whitespace at the beginning or the end doesn't count.)
2132+
Raises an exception if the element or the text is not found.
2133+
Returns True if successful. Default timeout = SMALL_TIMEOUT. """
2134+
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
2135+
timeout = self.__get_new_timeout(timeout)
2136+
self.wait_for_exact_text_visible(
2137+
text, selector, by=by, timeout=timeout)
2138+
2139+
if self.demo_mode:
2140+
if page_utils.is_xpath_selector(selector):
2141+
by = By.XPATH
2142+
if page_utils.is_link_text_selector(selector):
2143+
selector = page_utils.get_link_text_from_selector(selector)
2144+
by = By.LINK_TEXT
2145+
messenger_post = ("ASSERT TEXT {%s} in %s: %s"
2146+
% (text, by, selector))
2147+
self.__highlight_with_assert_success(messenger_post, selector, by)
2148+
return True
2149+
21112150
# For backwards compatibility, earlier method names of the next
21122151
# four methods have remained even though they do the same thing,
21132152
# with the exception of assert_*, which won't return the element,

seleniumbase/fixtures/page_actions.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,49 @@ def wait_for_text_visible(driver, text, selector, by=By.CSS_SELECTOR,
280280
(text, selector, timeout, plural))
281281

282282

283+
def wait_for_exact_text_visible(driver, text, selector, by=By.CSS_SELECTOR,
284+
timeout=settings.LARGE_TIMEOUT):
285+
"""
286+
Searches for the specified element by the given selector. Returns the
287+
element object if the text matches exactly with the text in the element,
288+
and the text is visible.
289+
Raises an exception if the text or element do not appear
290+
in the specified timeout.
291+
@Params
292+
driver - the webdriver object (required)
293+
text - the exact text that is expected for the element (required)
294+
selector - the locator that is used (required)
295+
by - the method to search for the locator (Default: By.CSS_SELECTOR)
296+
timeout - the time to wait for elements in seconds
297+
@Returns
298+
A web element object that contains the text searched for
299+
"""
300+
301+
element = None
302+
start_ms = time.time() * 1000.0
303+
stop_ms = start_ms + (timeout * 1000.0)
304+
for x in range(int(timeout * 10)):
305+
try:
306+
element = driver.find_element(by=by, value=selector)
307+
if element.is_displayed() and text.strip() == element.text.strip():
308+
return element
309+
else:
310+
element = None
311+
raise Exception()
312+
except Exception:
313+
now_ms = time.time() * 1000.0
314+
if now_ms >= stop_ms:
315+
break
316+
time.sleep(0.1)
317+
plural = "s"
318+
if timeout == 1:
319+
plural = ""
320+
if not element:
321+
raise ElementNotVisibleException(
322+
"Expected exact text {%s} for {%s} was not visible "
323+
"after %s second%s!" % (text, selector, timeout, plural))
324+
325+
283326
def wait_for_element_absent(driver, selector, by=By.CSS_SELECTOR,
284327
timeout=settings.LARGE_TIMEOUT):
285328
"""

setup.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
setup(
1919
name='seleniumbase',
20-
version='1.19.5',
20+
version='1.19.6',
2121
description='Reliable Browser Automation & Testing Framework',
2222
long_description=long_description,
2323
long_description_content_type='text/markdown',
@@ -61,7 +61,7 @@
6161
'selenium==3.141.0',
6262
'requests==2.21.0', # Changing this may effect "urllib3"
6363
'urllib3==1.24.1', # Keep this lib in sync with "requests"
64-
'pytest>=4.2.0',
64+
'pytest>=4.2.1',
6565
'pytest-cov>=2.6.1',
6666
'pytest-html>=1.20.0',
6767
'pytest-rerunfailures>=6.0',
@@ -71,7 +71,6 @@
7171
'colorama==0.4.1',
7272
'pyotp>=2.2.7',
7373
'boto>=2.49.0',
74-
'more-itertools>=5.0.0,<6.0.0', # Keep this for Python 2 compatibility
7574
'flake8>=3.6.0,<3.8.0',
7675
'PyVirtualDisplay==0.2.1',
7776
],

0 commit comments

Comments
 (0)