From 16f81f417085e4b2da2cc77392501902aa41c8c0 Mon Sep 17 00:00:00 2001 From: Lachlan Teale Date: Fri, 13 May 2022 13:06:05 +1000 Subject: [PATCH 1/4] Added wait_for_class_to_equal --- dash/testing/browser.py | 19 ++++++++++++++++++- dash/testing/wait.py | 17 +++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/dash/testing/browser.py b/dash/testing/browser.py index 4449f0abb5..6aef9ab9e0 100644 --- a/dash/testing/browser.py +++ b/dash/testing/browser.py @@ -21,7 +21,13 @@ 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, + until, +) from dash.testing.dash_page import DashPageMixin from dash.testing.errors import DashAppLoadingError, BrowserError, TestingTimeoutError from dash.testing.consts import SELENIUM_GRID_DEFAULT @@ -301,6 +307,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 diff --git a/dash/testing/wait.py b/dash/testing/wait.py index 7c877c0e0c..c04d2bb522 100644 --- a/dash/testing/wait.py +++ b/dash/testing/wait.py @@ -99,3 +99,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 From d3d7360788c5e5b2722c9e71f5ac817d41572f08 Mon Sep 17 00:00:00 2001 From: Lachlan Teale Date: Fri, 13 May 2022 13:08:32 +1000 Subject: [PATCH 2/4] Added wait_for_contains_class --- dash/testing/browser.py | 15 +++++++++++++++ dash/testing/wait.py | 17 +++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/dash/testing/browser.py b/dash/testing/browser.py index 6aef9ab9e0..f376db48ae 100644 --- a/dash/testing/browser.py +++ b/dash/testing/browser.py @@ -26,6 +26,7 @@ style_to_equal, class_to_equal, contains_text, + contains_class, until, ) from dash.testing.dash_page import DashPageMixin @@ -343,6 +344,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`. diff --git a/dash/testing/wait.py b/dash/testing/wait.py index c04d2bb522..2d1380807b 100644 --- a/dash/testing/wait.py +++ b/dash/testing/wait.py @@ -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) + except WebDriverException: + return False + + class text_to_equal: def __init__(self, selector, text): self.selector = selector From 2772badc8e23236212f00f8a295ce58f8f262114 Mon Sep 17 00:00:00 2001 From: Lachlan Teale Date: Fri, 13 May 2022 13:38:56 +1000 Subject: [PATCH 3/4] Add change to CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index de45fb014f..f1097b470c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ This project adheres to [Semantic Versioning](https://semver.org/). [#2003](https://github.com/plotly/dash/issues/2003) in which `dangerously_allow_html=True` + `mathjax=True` works in some cases, and in some cases not. +- [#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 From 12e6d976bd9a8cd0b61cce2ac310ec4e606742dd Mon Sep 17 00:00:00 2001 From: Lachlan Teale Date: Sat, 21 May 2022 09:23:27 +1000 Subject: [PATCH 4/4] Add changes from PR --- CHANGELOG.md | 3 ++- dash/testing/wait.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1097b470c..74f1c10a8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,9 @@ This project adheres to [Semantic Versioning](https://semver.org/). [#2003](https://github.com/plotly/dash/issues/2003) in which `dangerously_allow_html=True` + `mathjax=True` works in some cases, and in some cases not. -- [#2049](https://github.com/plotly/dash/pull/2043) Added `wait_for_class_to_equal` and `wait_for_contains_class` methods to `dash.testing` +### 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 diff --git a/dash/testing/wait.py b/dash/testing/wait.py index 2d1380807b..c0d41baa70 100644 --- a/dash/testing/wait.py +++ b/dash/testing/wait.py @@ -80,7 +80,7 @@ def __call__(self, driver): logger.debug( "contains class {%s} => expected %s", classname, self.classname ) - return self.classname in str(classname) + return self.classname in str(classname).split(" ") except WebDriverException: return False