Skip to content

Commit

Permalink
Merge pull request #2049 from MrTeale/wait-for-class-values
Browse files Browse the repository at this point in the history
Wait for class testing utilities
  • Loading branch information
alexcjohnson authored May 21, 2022
2 parents 49fab85 + 12e6d97 commit 04217e8
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ This project adheres to [Semantic Versioning](https://semver.org/).

- [#2050](https://github.com/plotly/dash/pull/2050) Changed `find_element` and `find_elements` to accept an `attribute` argument that aligns with Selenium's `By` class, allowing you to search elements by other attributes. Default value is `CSS_SELECTOR` to maintain backwards compatibility with previous `find_elements`.

### Added

- [#2049](https://github.com/plotly/dash/pull/2043) Added `wait_for_class_to_equal` and `wait_for_contains_class` methods to `dash.testing`

## [2.4.1] - 2022-05-11

### Fixed
Expand Down
34 changes: 33 additions & 1 deletion dash/testing/browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@
MoveTargetOutOfBoundsException,
)

from dash.testing.wait import text_to_equal, style_to_equal, contains_text, until
from dash.testing.wait import (
text_to_equal,
style_to_equal,
class_to_equal,
contains_text,
contains_class,
until,
)
from dash.testing.dash_page import DashPageMixin
from dash.testing.errors import DashAppLoadingError, BrowserError, TestingTimeoutError
from dash.testing.consts import SELENIUM_GRID_DEFAULT
Expand Down Expand Up @@ -309,6 +316,17 @@ def wait_for_element_by_id(self, element_id, timeout=None):
f"timeout {timeout or self._wait_timeout}s => waiting for element id {element_id}",
)

def wait_for_class_to_equal(self, selector, classname, timeout=None):
"""Explicit wait until the element's class has expected `value` timeout
if not set, equals to the fixture's `wait_timeout` shortcut to
`WebDriverWait` with customized `class_to_equal` condition."""
return self._wait_for(
method=class_to_equal,
args=(selector, classname),
timeout=timeout,
msg=f"classname => {classname} not found within {timeout or self._wait_timeout}s",
)

def wait_for_style_to_equal(self, selector, style, val, timeout=None):
"""Explicit wait until the element's style has expected `value` timeout
if not set, equals to the fixture's `wait_timeout` shortcut to
Expand All @@ -334,6 +352,20 @@ def wait_for_text_to_equal(self, selector, text, timeout=None):
msg=f"text -> {text} not found within {timeout or self._wait_timeout}s",
)

def wait_for_contains_class(self, selector, classname, timeout=None):
"""Explicit wait until the element's classes contains the expected `classname`.
timeout if not set, equals to the fixture's `wait_timeout`
shortcut to `WebDriverWait` with customized `contains_class`
condition.
"""
return self._wait_for(
method=contains_class,
args=(selector, classname),
timeout=timeout,
msg=f"classname -> {classname} not found inside element within {timeout or self._wait_timeout}s",
)

def wait_for_contains_text(self, selector, text, timeout=None):
"""Explicit wait until the element's text contains the expected `text`.
Expand Down
34 changes: 34 additions & 0 deletions dash/testing/wait.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,23 @@ def __call__(self, driver):
return False


class contains_class:
def __init__(self, selector, classname):
self.selector = selector
self.classname = classname

def __call__(self, driver):
try:
elem = driver.find_element(By.CSS_SELECTOR, self.selector)
classname = elem.get_attribute("class")
logger.debug(
"contains class {%s} => expected %s", classname, self.classname
)
return self.classname in str(classname).split(" ")
except WebDriverException:
return False


class text_to_equal:
def __init__(self, selector, text):
self.selector = selector
Expand Down Expand Up @@ -99,3 +116,20 @@ def __call__(self, driver):
return val == self.val
except WebDriverException:
return False


class class_to_equal:
def __init__(self, selector, classname):
self.selector = selector
self.classname = classname

def __call__(self, driver):
try:
elem = driver.find_element(By.CSS_SELECTOR, self.selector)
classname = elem.get_attribute("class")
logger.debug(
"class to equal {%s} => expected %s", classname, self.classname
)
return str(classname) == self.classname
except WebDriverException:
return False

0 comments on commit 04217e8

Please sign in to comment.