From dc7f90580a394472f809f2c31315ab9c178aa50f Mon Sep 17 00:00:00 2001 From: byron Date: Mon, 23 Sep 2019 13:39:12 -0400 Subject: [PATCH 1/3] add two APIs --- dash/testing/browser.py | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/dash/testing/browser.py b/dash/testing/browser.py index 8ed194accf..64cbcd9b26 100644 --- a/dash/testing/browser.py +++ b/dash/testing/browser.py @@ -13,7 +13,11 @@ from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.common.action_chains import ActionChains -from selenium.common.exceptions import WebDriverException, TimeoutException +from selenium.common.exceptions import ( + WebDriverException, + TimeoutException, + MoveTargetOutOfBoundsException, +) from dash.testing.wait import ( text_to_equal, @@ -429,6 +433,32 @@ def clear_input(self, elem): .send_keys(Keys.DELETE) ).perform() + def zoom_in_graph_by_ratio( + self, elem, start_point_ratio=0.5, zoom_ratio=0.2, compare=True + ): + """zoom out a graph by its dimension ratio + default start at middle with a rectangle of 20% of the dimension + """ + prev = elem.get_attribute("innerHTML") + w, h = elem.size["width"], elem.size["height"] + try: + ActionChains(self.driver).move_to_element_with_offset( + elem, w * start_point_ratio, h * start_point_ratio + ).drag_and_drop_by_offset( + elem, w * zoom_ratio, h * zoom_ratio + ).perform() + except MoveTargetOutOfBoundsException: + logger.exception("graph offset outside of the boundary") + if compare: + assert prev != elem.get_attribute( + "innerHTML" + ), "SVG content should be different after zoom" + + def click_at_coord_fractions(self, elem, fx, fy): + ActionChains(self.driver).move_to_element_with_offset( + elem, elem.size["width"] * fx, elem.size["height"] * fy + ).click().perform() + def get_logs(self): """return a list of `SEVERE` level logs after last reset time stamps (default to 0, resettable by `reset_log_timestamp`. Chrome only @@ -453,10 +483,10 @@ def reset_log_timestamp(self): def visit_and_snapshot(self, resource_path, hook_id, assert_check=True): try: - path = resource_path.lstrip('/') + path = resource_path.lstrip("/") if path != resource_path: logger.warning("we stripped the left '/' in resource_path") - self.driver.get("{}/{}".format(self.server_url.rstrip('/'), path)) + self.driver.get("{}/{}".format(self.server_url.rstrip("/"), path)) self.wait_for_element_by_id(hook_id) self.percy_snapshot(path) if assert_check: From 90aab51eae30f8f860ab44716663f52afa24a1f2 Mon Sep 17 00:00:00 2001 From: byron Date: Mon, 23 Sep 2019 13:52:48 -0400 Subject: [PATCH 2/3] :pencil: changelog --- dash/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dash/CHANGELOG.md b/dash/CHANGELOG.md index f74fb37877..cdf0fb3afa 100644 --- a/dash/CHANGELOG.md +++ b/dash/CHANGELOG.md @@ -1,3 +1,9 @@ +## Unreleased + +### Added + +- [#937](https://github.com/plotly/dash/pull/937) `dash.testing` adds two APIs `zoom_in_graph_by_ratio` and `click_at_coord_fractions` about advanced interactions using mouse `ActionChain` + ## [1.3.1] - 2019-09-19 ### Changed - Bumped dash-core-components version from 1.2.0 to [1.2.1](https://github.com/plotly/dash-core-components/blob/master/CHANGELOG.md#120---2019-09-19) From f635de81d9ef7c9d4486507e0f79bceb209d7f83 Mon Sep 17 00:00:00 2001 From: byron Date: Mon, 23 Sep 2019 23:35:17 -0400 Subject: [PATCH 3/3] :ok_hand: per comments --- dash/testing/browser.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dash/testing/browser.py b/dash/testing/browser.py index 64cbcd9b26..ad4f35d92a 100644 --- a/dash/testing/browser.py +++ b/dash/testing/browser.py @@ -434,18 +434,19 @@ def clear_input(self, elem): ).perform() def zoom_in_graph_by_ratio( - self, elem, start_point_ratio=0.5, zoom_ratio=0.2, compare=True + self, elem, start_fraction=0.5, zoom_box_fraction=0.2, compare=True ): - """zoom out a graph by its dimension ratio - default start at middle with a rectangle of 20% of the dimension + """zoom out a graph with a zoom box fraction of component dimension + default start at middle with a rectangle of 1/5 of the dimension + use `compare` to control if we check the svg get changed """ prev = elem.get_attribute("innerHTML") w, h = elem.size["width"], elem.size["height"] try: ActionChains(self.driver).move_to_element_with_offset( - elem, w * start_point_ratio, h * start_point_ratio + elem, w * start_fraction, h * start_fraction ).drag_and_drop_by_offset( - elem, w * zoom_ratio, h * zoom_ratio + elem, w * zoom_box_fraction, h * zoom_box_fraction ).perform() except MoveTargetOutOfBoundsException: logger.exception("graph offset outside of the boundary")