Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add extra wait for callbacks in queue #974

Merged
merged 13 commits into from
Oct 29, 2019
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ updates in clientside functions.
- [#899](https://github.com/plotly/dash/pull/899) Add support for async dependencies and components
- [#973](https://github.com/plotly/dash/pull/973) Adds support for resource caching and adds a fallback caching mechanism through etag


### Fixed
- [#974](https://github.com/plotly/dash/pull/974) Fix and improve a percy snapshot behavior issue we found in dash-docs testing. It adds a flag `wait_for_callbacks`
to ensure that, in the context of a dash app testing, the percy snapshot action will happen only after all callbacks get fired.

## [1.4.1] - 2019-10-17
### Fixed
- [#969](https://github.com/plotly/dash/pull/969) Fix warnings emitted by react devtools coming from our own devtools components.
Expand Down
14 changes: 10 additions & 4 deletions dash/testing/browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,16 @@ def __exit__(self, exc_type, exc_val, traceback):
except percy.errors.Error:
logger.exception("percy runner failed to finalize properly")

def percy_snapshot(self, name=""):
def percy_snapshot(self, name="", wait_for_callbacks=False):
"""percy_snapshot - visual test api shortcut to `percy_runner.snapshot`.
It also combines the snapshot `name` with the python version.
"""
snapshot_name = "{} - py{}.{}".format(
name, sys.version_info.major, sys.version_info.minor
)
logger.info("taking snapshot name => %s", snapshot_name)
if wait_for_callbacks:
until(self._wait_for_callbacks, timeout=10)
self.percy_runner.snapshot(name=snapshot_name)

def take_snapshot(self, name):
Expand Down Expand Up @@ -445,7 +447,7 @@ def zoom_in_graph_by_ratio(
elem_or_selector,
start_fraction=0.5,
zoom_box_fraction=0.2,
compare=True
compare=True,
):
"""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
Expand Down Expand Up @@ -498,14 +500,18 @@ def reset_log_timestamp(self):
if entries:
self._last_ts = entries[-1]["timestamp"]

def visit_and_snapshot(self, resource_path, hook_id, assert_check=True):
def visit_and_snapshot(
self, resource_path, hook_id, wait_for_callbacks=True, assert_check=True
):
try:
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))

# wait for the hook_id to present and all callbacks get fired
self.wait_for_element_by_id(hook_id)
self.percy_snapshot(path)
self.percy_snapshot(path, wait_for_callbacks=wait_for_callbacks)
if assert_check:
assert not self.driver.find_elements_by_css_selector(
"div.dash-debug-alert"
Expand Down
11 changes: 11 additions & 0 deletions dash/testing/dash_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ def redux_state_rqs(self):
"return window.store.getState().requestQueue"
)

@property
def window_store(self):
return self.driver.execute_script("return window.store")

def _wait_for_callbacks(self):
if self.window_store:
return self.redux_state_rqs and all(
(_.get("responseTime") for _ in self.redux_state_rqs)
)
return True

def get_local_storage(self, store_id="local"):
return self.driver.execute_script(
"return JSON.parse(window.localStorage.getItem('{}'));".format(
Expand Down