aboutsummaryrefslogtreecommitdiff
path: root/venv/lib/python3.8/site-packages/dash/testing/dash_page.py
diff options
context:
space:
mode:
Diffstat (limited to 'venv/lib/python3.8/site-packages/dash/testing/dash_page.py')
-rw-r--r--venv/lib/python3.8/site-packages/dash/testing/dash_page.py99
1 files changed, 99 insertions, 0 deletions
diff --git a/venv/lib/python3.8/site-packages/dash/testing/dash_page.py b/venv/lib/python3.8/site-packages/dash/testing/dash_page.py
new file mode 100644
index 0000000..2f4d69f
--- /dev/null
+++ b/venv/lib/python3.8/site-packages/dash/testing/dash_page.py
@@ -0,0 +1,99 @@
+# type: ignore[reportAttributeAccessIssue]
+# Ignore attribute access issues when type checking because mixin
+# class depends on other class lineage to supply things. We could use
+# a protocol definition here instead…
+
+from bs4 import BeautifulSoup
+
+
+class DashPageMixin:
+ def _get_dash_dom_by_attribute(self, attr):
+ return BeautifulSoup(
+ self.find_element(self.dash_entry_locator).get_attribute(attr), "lxml"
+ )
+
+ @property
+ def devtools_error_count_locator(self):
+ return ".test-devtools-error-count"
+
+ @property
+ def dash_entry_locator(self):
+ return "#react-entry-point"
+
+ @property
+ def dash_outerhtml_dom(self):
+ return self._get_dash_dom_by_attribute("outerHTML")
+
+ @property
+ def dash_innerhtml_dom(self):
+ return self._get_dash_dom_by_attribute("innerHTML")
+
+ @property
+ def redux_state_paths(self):
+ return self.driver.execute_script(
+ """
+ var p = window.store.getState().paths;
+ return {strs: p.strs, objs: p.objs}
+ """
+ )
+
+ @property
+ def redux_state_rqs(self):
+ return self.driver.execute_script(
+ """
+
+ // Check for legacy `pendingCallbacks` store prop (compatibility for Dash matrix testing)
+ var pendingCallbacks = window.store.getState().pendingCallbacks;
+ if (pendingCallbacks) {
+ return pendingCallbacks.map(function(cb) {
+ var out = {};
+ for (var key in cb) {
+ if (typeof cb[key] !== 'function') { out[key] = cb[key]; }
+ }
+ return out;
+ });
+ }
+
+ // Otherwise, use the new `callbacks` store prop
+ var callbacksState = Object.assign({}, window.store.getState().callbacks);
+ delete callbacksState.stored;
+ delete callbacksState.completed;
+
+ return Array.prototype.concat.apply([], Object.values(callbacksState));
+ """
+ )
+
+ @property
+ def redux_state_is_loading(self):
+ return self.driver.execute_script(
+ """
+ return window.store.getState().isLoading;
+ """
+ )
+
+ @property
+ def window_store(self):
+ return self.driver.execute_script("return window.store")
+
+ def _wait_for_callbacks(self):
+ return (not self.window_store) or self.redux_state_rqs == []
+
+ def get_local_storage(self, store_id="local"):
+ return self.driver.execute_script(
+ f"return JSON.parse(window.localStorage.getItem('{store_id}'));"
+ )
+
+ def get_session_storage(self, session_id="session"):
+ return self.driver.execute_script(
+ f"return JSON.parse(window.sessionStorage.getItem('{session_id}'));"
+ )
+
+ def clear_local_storage(self):
+ self.driver.execute_script("window.localStorage.clear()")
+
+ def clear_session_storage(self):
+ self.driver.execute_script("window.sessionStorage.clear()")
+
+ def clear_storage(self):
+ self.clear_local_storage()
+ self.clear_session_storage()