diff --git a/CHANGELOG.md b/CHANGELOG.md index 870b9d294a..7d7df52520 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ This project adheres to [Semantic Versioning](https://semver.org/). `dangerously_allow_html=True` + `mathjax=True` works in some cases, and in some cases not. - [#2047](https://github.com/plotly/dash/pull/2047) Fix bug [#1979](https://github.com/plotly/dash/issues/1979) in which `DASH_DEBUG` as enviroment variable gets ignored. +### Changed + +- [#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`. + ## [2.4.1] - 2022-05-11 ### Fixed diff --git a/dash/testing/browser.py b/dash/testing/browser.py index 4449f0abb5..29203dedd8 100644 --- a/dash/testing/browser.py +++ b/dash/testing/browser.py @@ -12,7 +12,6 @@ from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.common.keys import Keys -from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.common.action_chains import ActionChains from selenium.common.exceptions import ( @@ -229,18 +228,27 @@ def take_snapshot(self, name): self.driver.save_screenshot(f"{target}/{name}_{self.session_id}.png") - def find_element(self, selector): - """find_element returns the first found element by the css `selector` - shortcut to `driver.find_element(By.CSS_SELECTOR, ...)`.""" - return self.driver.find_element(By.CSS_SELECTOR, selector) - - def find_elements(self, selector): - """find_elements returns a list of all elements matching the css - `selector`. + def find_element(self, selector, attribute="CSS_SELECTOR"): + """find_element returns the first found element by the attribute `selector` + shortcut to `driver.find_element(By.CSS_SELECTOR, ...)`. + args: + - attribute: the attribute type to search for, aligns with the Selenium + API's `By` class. default "CSS_SELECTOR" + valid values: "CSS_SELECTOR", "ID", "NAME", "TAG_NAME", + "CLASS_NAME", "LINK_TEXT", "PARTIAL_LINK_TEXT", "XPATH" + """ + return self.driver.find_element(getattr(By, attribute.upper()), selector) - shortcut to `driver.find_elements(By.CSS_SELECTOR, ...)`. + def find_elements(self, selector, attribute="CSS_SELECTOR"): + """find_elements returns a list of all elements matching the attribute + `selector`. Shortcut to `driver.find_elements(By.CSS_SELECTOR, ...)`. + args: + - attribute: the attribute type to search for, aligns with the Selenium + API's `By` class. default "CSS_SELECTOR" + valid values: "CSS_SELECTOR", "ID", "NAME", "TAG_NAME", + "CLASS_NAME", "LINK_TEXT", "PARTIAL_LINK_TEXT", "XPATH" """ - return self.driver.find_elements(By.CSS_SELECTOR, selector) + return self.driver.find_elements(getattr(By, attribute.upper()), selector) def _get_element(self, elem_or_selector): if isinstance(elem_or_selector, str): @@ -430,9 +438,8 @@ def _get_wd_options(self): def _get_chrome(self): options = self._get_wd_options() - capabilities = DesiredCapabilities.CHROME - capabilities["loggingPrefs"] = {"browser": "SEVERE"} - capabilities["goog:loggingPrefs"] = {"browser": "SEVERE"} + options.set_capability("loggingPrefs", {"browser": "SEVERE"}) + options.set_capability("goog:loggingPrefs", {"browser": "SEVERE"}) if "DASH_TEST_CHROMEPATH" in os.environ: options.binary_location = os.environ["DASH_TEST_CHROMEPATH"] @@ -453,13 +460,9 @@ def _get_chrome(self): options.add_argument("--remote-debugging-port=9222") chrome = ( - webdriver.Remote( - command_executor=self._remote_url, - options=options, - desired_capabilities=capabilities, - ) + webdriver.Remote(command_executor=self._remote_url, options=options) if self._remote - else webdriver.Chrome(options=options, desired_capabilities=capabilities) + else webdriver.Chrome(options=options) ) # https://bugs.chromium.org/p/chromium/issues/detail?id=696481 @@ -482,15 +485,12 @@ def _get_chrome(self): def _get_firefox(self): options = self._get_wd_options() - capabilities = DesiredCapabilities.FIREFOX - capabilities["loggingPrefs"] = {"browser": "SEVERE"} - capabilities["marionette"] = True + options.set_capability("loggingPrefs", {"browser": "SEVERE"}) + options.set_capability("marionette", True) - # https://developer.mozilla.org/en-US/docs/Download_Manager_preferences - fp = webdriver.FirefoxProfile() - fp.set_preference("browser.download.dir", self.download_path) - fp.set_preference("browser.download.folderList", 2) - fp.set_preference( + options.set_preference("browser.download.dir", self.download_path) + options.set_preference("browser.download.folderList", 2) + options.set_preference( "browser.helperApps.neverAsk.saveToDisk", "application/octet-stream", # this MIME is generic for binary ) @@ -498,12 +498,9 @@ def _get_firefox(self): webdriver.Remote( command_executor=self._remote_url, options=options, - desired_capabilities=capabilities, ) if self._remote - else webdriver.Firefox( - firefox_profile=fp, options=options, capabilities=capabilities - ) + else webdriver.Firefox(options=options) ) @staticmethod diff --git a/tests/integration/dash_assets/test_dash_assets.py b/tests/integration/dash_assets/test_dash_assets.py index dc55e07d86..1a6573546e 100644 --- a/tests/integration/dash_assets/test_dash_assets.py +++ b/tests/integration/dash_assets/test_dash_assets.py @@ -114,7 +114,7 @@ def test_dada002_external_files_init(dash_duo): (("//script[@src='{}']", x) for x in js_urls), (("//link[@href='{}']", x) for x in css_urls), ): - dash_duo.driver.find_element_by_xpath(fmt.format(url)) + dash_duo.find_element(fmt.format(url), attribute="XPATH") assert ( dash_duo.find_element("#btn").value_of_css_property("height") == "18px" diff --git a/tests/integration/devtools/test_devtools_ui.py b/tests/integration/devtools/test_devtools_ui.py index ae9d7910ec..922ca576a7 100644 --- a/tests/integration/devtools/test_devtools_ui.py +++ b/tests/integration/devtools/test_devtools_ui.py @@ -256,4 +256,4 @@ def create_an_alternative_response(): ) driver.get(dash_thread_server.url) - driver.find_element_by_id("alternative_id") + dash_br.find_element("#alternative_id")