diff --git a/RESOURCES/FEATURE_FLAGS.md b/RESOURCES/FEATURE_FLAGS.md
index d029ca6c3cbd6..f2263f1ee0674 100644
--- a/RESOURCES/FEATURE_FLAGS.md
+++ b/RESOURCES/FEATURE_FLAGS.md
@@ -52,7 +52,6 @@ These features are **finished** but currently being tested. They are usable, but
- GENERIC_CHART_AXES
- GLOBAL_ASYNC_QUERIES [(docs)](https://github.com/apache/superset/blob/master/CONTRIBUTING.md#async-chart-queries)
- HORIZONTAL_FILTER_BAR
-- PLAYWRIGHT_REPORTS_AND_THUMBNAILS
- RLS_IN_SQLLAB
- SSH_TUNNELING [(docs)](https://superset.apache.org/docs/installation/setup-ssh-tunneling)
- USE_ANALAGOUS_COLORS
diff --git a/docker/docker-bootstrap.sh b/docker/docker-bootstrap.sh
index 7d53f92898fb8..2f86342714760 100755
--- a/docker/docker-bootstrap.sh
+++ b/docker/docker-bootstrap.sh
@@ -35,14 +35,6 @@ else
echo "Skipping local overrides"
fi
-#
-# playwright is an optional package - run only if it is installed
-#
-if command -v playwright > /dev/null 2>&1; then
- playwright install-deps
- playwright install chromium
-fi
-
case "${1}" in
worker)
echo "Starting Celery worker..."
diff --git a/requirements/testing.in b/requirements/testing.in
index 5b498bb09005d..b991be1040d4a 100644
--- a/requirements/testing.in
+++ b/requirements/testing.in
@@ -16,7 +16,7 @@
#
-r development.in
-r integration.in
--e file:.[bigquery,hive,presto,prophet,trino,gsheets,playwright]
+-e file:.[bigquery,hive,presto,prophet,trino,gsheets]
docker
flask-testing
freezegun
diff --git a/requirements/testing.txt b/requirements/testing.txt
index 6f52842026396..da79433632307 100644
--- a/requirements/testing.txt
+++ b/requirements/testing.txt
@@ -1,4 +1,4 @@
-# SHA1:95300275481abb1413eb98a5c79fb7cf96814cdd
+# SHA1:78d0270a4f583095e0587aa21f57fc2ff7fe8b84
#
# This file is autogenerated by pip-compile-multi
# To update, run:
@@ -104,8 +104,6 @@ parameterized==0.9.0
# via -r requirements/testing.in
pathable==0.4.3
# via jsonschema-spec
-playwright==1.37.0
- # via apache-superset
prophet==1.1.1
# via apache-superset
proto-plus==1.22.2
diff --git a/setup.py b/setup.py
index f43097b0bfc2a..6190eaf65c782 100644
--- a/setup.py
+++ b/setup.py
@@ -183,7 +183,6 @@ def get_git_sha() -> str:
],
"oracle": ["cx-Oracle>8.0.0, <8.1"],
"pinot": ["pinotdb>=0.3.3, <0.4"],
- "playwright": ["playwright>=1.37.0, <2"],
"postgres": ["psycopg2-binary==2.9.6"],
"presto": ["pyhive[presto]>=0.6.5"],
"trino": ["trino>=0.324.0"],
diff --git a/superset-frontend/src/components/ErrorMessage/ErrorAlert.tsx b/superset-frontend/src/components/ErrorMessage/ErrorAlert.tsx
index da5894e887fd0..d61abea5976b4 100644
--- a/superset-frontend/src/components/ErrorMessage/ErrorAlert.tsx
+++ b/superset-frontend/src/components/ErrorMessage/ErrorAlert.tsx
@@ -183,7 +183,6 @@ export default function ErrorAlert({
level={level}
show={isModalOpen}
onHide={() => setIsModalOpen(false)}
- destroyOnClose
title={
{level === 'error' ? (
diff --git a/superset/config.py b/superset/config.py
index 7463d3083f580..f2daaf5dea577 100644
--- a/superset/config.py
+++ b/superset/config.py
@@ -500,10 +500,6 @@ class D3Format(TypedDict, total=False):
# returned from each database in the ``SUPERSET_META_DB_LIMIT`` configuration value
# in this file.
"ENABLE_SUPERSET_META_DB": False,
- # Set to True to replace Selenium with Playwright to execute reports and thumbnails.
- # Unlike Selenium, Playwright reports support deck.gl visualizations
- # Enabling this feature flag requires installing "playwright" pip package
- "PLAYWRIGHT_REPORTS_AND_THUMBNAILS": False,
}
# ------------------------------
@@ -1351,11 +1347,9 @@ def EMAIL_HEADER_MUTATOR( # pylint: disable=invalid-name,unused-argument
"pixel_density": 1,
}
-# An optional override to the default auth hook used to provide auth to the offline
-# webdriver (when using Selenium) or browser context (when using Playwright - see
-# PLAYWRIGHT_REPORTS_AND_THUMBNAILS feature flag)
+# An optional override to the default auth hook used to provide auth to the
+# offline webdriver
WEBDRIVER_AUTH_FUNC = None
-BROWSER_CONTEXT_AUTH_FUNC = None
# Any config options to be passed as-is to the webdriver
WEBDRIVER_CONFIGURATION: dict[Any, Any] = {"service_log_path": "/dev/null"}
diff --git a/superset/utils/machine_auth.py b/superset/utils/machine_auth.py
index 6cd1c0ba7449e..1340ddbdc6d16 100644
--- a/superset/utils/machine_auth.py
+++ b/superset/utils/machine_auth.py
@@ -18,8 +18,7 @@
from __future__ import annotations
import logging
-from typing import Any, Callable, TYPE_CHECKING
-from urllib.parse import urlparse
+from typing import Callable, TYPE_CHECKING
from flask import current_app, Flask, request, Response, session
from flask_login import login_user
@@ -34,24 +33,14 @@
if TYPE_CHECKING:
from flask_appbuilder.security.sqla.models import User
- try:
- from playwright.sync_api import BrowserContext
- except ModuleNotFoundError:
- BrowserContext = Any
-
class MachineAuthProvider:
def __init__(
- self,
- auth_webdriver_func_override: Callable[[WebDriver, User], WebDriver],
- auth_context_func_override: Callable[[BrowserContext, User], BrowserContext],
+ self, auth_webdriver_func_override: Callable[[WebDriver, User], WebDriver]
):
- # This is here in order to allow for the authenticate_webdriver
- # or authenticate_browser_context (if PLAYWRIGHT_REPORTS_AND_THUMBNAILS is
- # enabled) func to be overridden via config, as opposed to the entire
- # provider implementation
+ # This is here in order to allow for the authenticate_webdriver func to be
+ # overridden via config, as opposed to the entire provider implementation
self._auth_webdriver_func_override = auth_webdriver_func_override
- self._auth_context_func_override = auth_context_func_override
def authenticate_webdriver(
self,
@@ -69,54 +58,17 @@ def authenticate_webdriver(
# Setting cookies requires doing a request first
driver.get(headless_url("/login/"))
- cookies = self.get_cookies(user)
-
- for cookie_name, cookie_val in cookies.items():
- driver.add_cookie({"name": cookie_name, "value": cookie_val})
-
- return driver
-
- def authenticate_browser_context(
- self,
- browser_context: BrowserContext,
- user: User,
- ) -> BrowserContext:
- # Short-circuit this method if we have an override configured
- if self._auth_context_func_override: # type: ignore
- return self._auth_context_func_override(browser_context, user)
-
- url = urlparse(current_app.config["WEBDRIVER_BASEURL"])
-
- # Setting cookies requires doing a request first
- page = browser_context.new_page()
- page.goto(headless_url("/login/"))
-
- cookies = self.get_cookies(user)
-
- browser_context.clear_cookies()
- browser_context.add_cookies(
- [
- {
- "name": cookie_name,
- "value": cookie_val,
- "domain": url.netloc,
- "path": "/",
- "sameSite": "Lax",
- "httpOnly": True,
- }
- for cookie_name, cookie_val in cookies.items()
- ]
- )
- return browser_context
-
- def get_cookies(self, user: User | None) -> dict[str, str]:
if user:
cookies = self.get_auth_cookies(user)
elif request.cookies:
cookies = request.cookies
else:
cookies = {}
- return cookies
+
+ for cookie_name, cookie_val in cookies.items():
+ driver.add_cookie({"name": cookie_name, "value": cookie_val})
+
+ return driver
@staticmethod
def get_auth_cookies(user: User) -> dict[str, str]:
@@ -150,7 +102,7 @@ def __init__(self) -> None:
def init_app(self, app: Flask) -> None:
self._auth_provider = load_class_from_name(
app.config["MACHINE_AUTH_PROVIDER_CLASS"]
- )(app.config["WEBDRIVER_AUTH_FUNC"], app.config["BROWSER_CONTEXT_AUTH_FUNC"])
+ )(app.config["WEBDRIVER_AUTH_FUNC"])
@property
def instance(self) -> MachineAuthProvider:
diff --git a/superset/utils/screenshots.py b/superset/utils/screenshots.py
index 8609d65038273..2743f85195b3d 100644
--- a/superset/utils/screenshots.py
+++ b/superset/utils/screenshots.py
@@ -22,15 +22,12 @@
from flask import current_app
-from superset import feature_flag_manager
from superset.utils.hashing import md5_sha_from_dict
from superset.utils.urls import modify_url_query
from superset.utils.webdriver import (
ChartStandaloneMode,
DashboardStandaloneMode,
- WebDriver,
- WebDriverPlaywright,
- WebDriverSelenium,
+ WebDriverProxy,
WindowSize,
)
@@ -64,11 +61,9 @@ def __init__(self, url: str, digest: str):
self.url = url
self.screenshot: bytes | None = None
- def driver(self, window_size: WindowSize | None = None) -> WebDriver:
+ def driver(self, window_size: WindowSize | None = None) -> WebDriverProxy:
window_size = window_size or self.window_size
- if feature_flag_manager.is_feature_enabled("PLAYWRIGHT_REPORTS_AND_THUMBNAILS"):
- return WebDriverPlaywright(self.driver_type, window_size)
- return WebDriverSelenium(self.driver_type, window_size)
+ return WebDriverProxy(self.driver_type, window_size)
def cache_key(
self,
diff --git a/superset/utils/webdriver.py b/superset/utils/webdriver.py
index 720c399b2a67a..39c6d514d6fa9 100644
--- a/superset/utils/webdriver.py
+++ b/superset/utils/webdriver.py
@@ -18,7 +18,6 @@
from __future__ import annotations
import logging
-from abc import ABC, abstractmethod
from enum import Enum
from time import sleep
from typing import Any, TYPE_CHECKING
@@ -35,26 +34,16 @@
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
-from superset import feature_flag_manager
from superset.extensions import machine_auth_provider_factory
from superset.utils.retries import retry_call
WindowSize = tuple[int, int]
logger = logging.getLogger(__name__)
+
if TYPE_CHECKING:
from flask_appbuilder.security.sqla.models import User
-if feature_flag_manager.is_feature_enabled("PLAYWRIGHT_REPORTS_AND_THUMBNAILS"):
- from playwright.sync_api import (
- BrowserContext,
- ElementHandle,
- Error,
- Page,
- sync_playwright,
- TimeoutError as PlaywrightTimeout,
- )
-
class DashboardStandaloneMode(Enum):
HIDE_NAV = 1
@@ -67,188 +56,67 @@ class ChartStandaloneMode(Enum):
SHOW_NAV = 0
-# pylint: disable=too-few-public-methods
-class WebDriverProxy(ABC):
- def __init__(self, driver_type: str, window: WindowSize | None = None):
- self._driver_type = driver_type
- self._window: WindowSize = window or (800, 600)
- self._screenshot_locate_wait = current_app.config["SCREENSHOT_LOCATE_WAIT"]
- self._screenshot_load_wait = current_app.config["SCREENSHOT_LOAD_WAIT"]
+def find_unexpected_errors(driver: WebDriver) -> list[str]:
+ error_messages = []
- @abstractmethod
- def get_screenshot(self, url: str, element_name: str, user: User) -> bytes | None:
- """
- Run webdriver and return a screenshot
- """
+ try:
+ alert_divs = driver.find_elements(By.XPATH, "//div[@role = 'alert']")
+ logger.debug(
+ "%i alert elements have been found in the screenshot", len(alert_divs)
+ )
+ for alert_div in alert_divs:
+ # See More button
+ alert_div.find_element(By.XPATH, ".//*[@role = 'button']").click()
-class WebDriverPlaywright(WebDriverProxy):
- @staticmethod
- def auth(user: User, context: BrowserContext) -> BrowserContext:
- return machine_auth_provider_factory.instance.authenticate_browser_context(
- context, user
- )
+ # wait for modal to show up
+ modal = WebDriverWait(
+ driver, current_app.config["SCREENSHOT_WAIT_FOR_ERROR_MODAL_VISIBLE"]
+ ).until(
+ EC.visibility_of_any_elements_located(
+ (By.CLASS_NAME, "ant-modal-content")
+ )
+ )[
+ 0
+ ]
- @staticmethod
- def find_unexpected_errors(page: Page) -> list[str]:
- error_messages = []
+ err_msg_div = modal.find_element(By.CLASS_NAME, "ant-modal-body")
- try:
- alert_divs = page.get_by_role("alert").all()
+ # collect error message
+ error_messages.append(err_msg_div.text)
- logger.debug(
- "%i alert elements have been found in the screenshot", len(alert_divs)
- )
+ # close modal after collecting error messages
+ modal.find_element(By.CLASS_NAME, "ant-modal-close").click()
- for alert_div in alert_divs:
- # See More button
- alert_div.get_by_role("button").click()
-
- # wait for modal to show up
- page.wait_for_selector(
- ".ant-modal-content",
- timeout=current_app.config[
- "SCREENSHOT_WAIT_FOR_ERROR_MODAL_VISIBLE"
- ]
- * 1000,
- state="visible",
- )
- err_msg_div = page.locator(".ant-modal-content .ant-modal-body")
- #
- # # collect error message
- error_messages.append(err_msg_div.text_content())
- #
- # # Use HTML so that error messages are shown in the same style (color)
- error_as_html = err_msg_div.inner_html().replace("'", "\\'")
- #
- # # close modal after collecting error messages
- page.locator(".ant-modal-content .ant-modal-close").click()
- #
- # # wait until the modal becomes invisible
- page.wait_for_selector(
- ".ant-modal-content",
- timeout=current_app.config[
- "SCREENSHOT_WAIT_FOR_ERROR_MODAL_INVISIBLE"
- ]
- * 1000,
- state="detached",
- )
- try:
- # Even if some errors can't be updated in the screenshot,
- # keep all the errors in the server log and do not fail the loop
- alert_div.evaluate(
- "(node, error_html) => node.innerHtml = error_html",
- [error_as_html],
- )
- except Error:
- logger.exception("Failed to update error messages using alert_div")
- except Error:
- logger.exception("Failed to capture unexpected errors")
+ # wait until the modal becomes invisible
+ WebDriverWait(
+ driver, current_app.config["SCREENSHOT_WAIT_FOR_ERROR_MODAL_INVISIBLE"]
+ ).until(EC.invisibility_of_element(modal))
- return error_messages
+ # Use HTML so that error messages are shown in the same style (color)
+ error_as_html = err_msg_div.get_attribute("innerHTML").replace("'", "\\'")
- def get_screenshot(self, url: str, element_name: str, user: User) -> bytes | None:
- with sync_playwright() as playwright:
- browser = playwright.chromium.launch()
- pixel_density = current_app.config["WEBDRIVER_WINDOW"].get(
- "pixel_density", 1
- )
- context = browser.new_context(
- bypass_csp=True,
- viewport={
- "height": self._window[1],
- "width": self._window[0],
- },
- device_scale_factor=pixel_density,
- )
- self.auth(user, context)
- page = context.new_page()
- page.goto(url)
- img: bytes | None = None
- selenium_headstart = current_app.config["SCREENSHOT_SELENIUM_HEADSTART"]
- logger.debug("Sleeping for %i seconds", selenium_headstart)
- page.wait_for_timeout(selenium_headstart * 1000)
- element: ElementHandle
try:
- try:
- # page didn't load
- logger.debug(
- "Wait for the presence of %s at url: %s", element_name, url
- )
- element = page.wait_for_selector(
- f".{element_name}",
- timeout=self._screenshot_locate_wait * 1000,
- )
- except PlaywrightTimeout as ex:
- logger.exception("Timed out requesting url %s", url)
- raise ex
-
- try:
- # chart containers didn't render
- logger.debug("Wait for chart containers to draw at url: %s", url)
- page.wait_for_selector(
- ".slice_container", timeout=self._screenshot_locate_wait * 1000
- )
- except PlaywrightTimeout as ex:
- logger.exception(
- "Timed out waiting for chart containers to draw at url %s",
- url,
- )
- raise ex
- try:
- # charts took too long to load
- logger.debug(
- "Wait for loading element of charts to be gone at url: %s", url
- )
- page.wait_for_selector(
- ".loading",
- timeout=self._screenshot_locate_wait * 1000,
- state="detached",
- )
- except PlaywrightTimeout as ex:
- logger.exception(
- "Timed out waiting for charts to load at url %s", url
- )
- raise ex
-
- selenium_animation_wait = current_app.config[
- "SCREENSHOT_SELENIUM_ANIMATION_WAIT"
- ]
- logger.debug(
- "Wait %i seconds for chart animation", selenium_animation_wait
- )
- page.wait_for_timeout(selenium_animation_wait * 1000)
- logger.debug(
- "Taking a PNG screenshot of url %s as user %s",
- url,
- user.username,
- )
- if current_app.config["SCREENSHOT_REPLACE_UNEXPECTED_ERRORS"]:
- unexpected_errors = WebDriverPlaywright.find_unexpected_errors(page)
- if unexpected_errors:
- logger.warning(
- "%i errors found in the screenshot. URL: %s. Errors are: %s",
- len(unexpected_errors),
- url,
- unexpected_errors,
- )
- img = element.screenshot()
- except PlaywrightTimeout:
- # raise again for the finally block, but handled above
- pass
- except StaleElementReferenceException:
- logger.exception(
- "Selenium got a stale element while requesting url %s",
- url,
+ # Even if some errors can't be updated in the screenshot,
+ # keep all the errors in the server log and do not fail the loop
+ driver.execute_script(
+ f"arguments[0].innerHTML = '{error_as_html}'", alert_div
)
except WebDriverException:
- logger.exception(
- "Encountered an unexpected error when requeating url %s", url
- )
- return img
+ logger.exception("Failed to update error messages using alert_div")
+ except WebDriverException:
+ logger.exception("Failed to capture unexpected errors")
+
+ return error_messages
-class WebDriverSelenium(WebDriverProxy):
+class WebDriverProxy:
+ def __init__(self, driver_type: str, window: WindowSize | None = None):
+ self._driver_type = driver_type
+ self._window: WindowSize = window or (800, 600)
+ self._screenshot_locate_wait = current_app.config["SCREENSHOT_LOCATE_WAIT"]
+ self._screenshot_load_wait = current_app.config["SCREENSHOT_LOAD_WAIT"]
+
def create(self) -> WebDriver:
pixel_density = current_app.config["WEBDRIVER_WINDOW"].get("pixel_density", 1)
if self._driver_type == "firefox":
@@ -298,64 +166,6 @@ def destroy(driver: WebDriver, tries: int = 2) -> None:
except Exception: # pylint: disable=broad-except
pass
- @staticmethod
- def find_unexpected_errors(driver: WebDriver) -> list[str]:
- error_messages = []
-
- try:
- alert_divs = driver.find_elements(By.XPATH, "//div[@role = 'alert']")
- logger.debug(
- "%i alert elements have been found in the screenshot", len(alert_divs)
- )
-
- for alert_div in alert_divs:
- # See More button
- alert_div.find_element(By.XPATH, ".//*[@role = 'button']").click()
-
- # wait for modal to show up
- modal = WebDriverWait(
- driver,
- current_app.config["SCREENSHOT_WAIT_FOR_ERROR_MODAL_VISIBLE"],
- ).until(
- EC.visibility_of_any_elements_located(
- (By.CLASS_NAME, "ant-modal-content")
- )
- )[
- 0
- ]
-
- err_msg_div = modal.find_element(By.CLASS_NAME, "ant-modal-body")
-
- # collect error message
- error_messages.append(err_msg_div.text)
-
- # close modal after collecting error messages
- modal.find_element(By.CLASS_NAME, "ant-modal-close").click()
-
- # wait until the modal becomes invisible
- WebDriverWait(
- driver,
- current_app.config["SCREENSHOT_WAIT_FOR_ERROR_MODAL_INVISIBLE"],
- ).until(EC.invisibility_of_element(modal))
-
- # Use HTML so that error messages are shown in the same style (color)
- error_as_html = err_msg_div.get_attribute("innerHTML").replace(
- "'", "\\'"
- )
-
- try:
- # Even if some errors can't be updated in the screenshot,
- # keep all the errors in the server log and do not fail the loop
- driver.execute_script(
- f"arguments[0].innerHTML = '{error_as_html}'", alert_div
- )
- except WebDriverException:
- logger.exception("Failed to update error messages using alert_div")
- except WebDriverException:
- logger.exception("Failed to capture unexpected errors")
-
- return error_messages
-
def get_screenshot(self, url: str, element_name: str, user: User) -> bytes | None:
driver = self.auth(user)
driver.set_window_size(*self._window)
@@ -419,7 +229,7 @@ def get_screenshot(self, url: str, element_name: str, user: User) -> bytes | Non
)
if current_app.config["SCREENSHOT_REPLACE_UNEXPECTED_ERRORS"]:
- unexpected_errors = WebDriverSelenium.find_unexpected_errors(driver)
+ unexpected_errors = find_unexpected_errors(driver)
if unexpected_errors:
logger.warning(
"%i errors found in the screenshot. URL: %s. Errors are: %s",
diff --git a/tests/integration_tests/thumbnails_tests.py b/tests/integration_tests/thumbnails_tests.py
index df558105b52a4..eb2be859ba3ac 100644
--- a/tests/integration_tests/thumbnails_tests.py
+++ b/tests/integration_tests/thumbnails_tests.py
@@ -34,7 +34,7 @@
from superset.tasks.types import ExecutorType
from superset.utils.screenshots import ChartScreenshot, DashboardScreenshot
from superset.utils.urls import get_url_path
-from superset.utils.webdriver import WebDriverSelenium
+from superset.utils.webdriver import find_unexpected_errors, WebDriverProxy
from tests.integration_tests.conftest import with_feature_flags
from tests.integration_tests.fixtures.birth_names_dashboard import (
load_birth_names_dashboard_with_slices,
@@ -79,11 +79,11 @@ def test_get_async_dashboard_screenshot(self):
class TestWebDriverScreenshotErrorDetector(SupersetTestCase):
@patch("superset.utils.webdriver.WebDriverWait")
@patch("superset.utils.webdriver.firefox")
- @patch("superset.utils.webdriver.WebDriverSelenium.find_unexpected_errors")
+ @patch("superset.utils.webdriver.find_unexpected_errors")
def test_not_call_find_unexpected_errors_if_feature_disabled(
self, mock_find_unexpected_errors, mock_firefox, mock_webdriver_wait
):
- webdriver_proxy = WebDriverSelenium("firefox")
+ webdriver_proxy = WebDriverProxy("firefox")
user = security_manager.get_user_by_username(
app.config["THUMBNAIL_SELENIUM_USER"]
)
@@ -94,12 +94,12 @@ def test_not_call_find_unexpected_errors_if_feature_disabled(
@patch("superset.utils.webdriver.WebDriverWait")
@patch("superset.utils.webdriver.firefox")
- @patch("superset.utils.webdriver.WebDriverSelenium.find_unexpected_errors")
+ @patch("superset.utils.webdriver.find_unexpected_errors")
def test_call_find_unexpected_errors_if_feature_enabled(
self, mock_find_unexpected_errors, mock_firefox, mock_webdriver_wait
):
app.config["SCREENSHOT_REPLACE_UNEXPECTED_ERRORS"] = True
- webdriver_proxy = WebDriverSelenium("firefox")
+ webdriver_proxy = WebDriverProxy("firefox")
user = security_manager.get_user_by_username(
app.config["THUMBNAIL_SELENIUM_USER"]
)
@@ -115,7 +115,7 @@ def test_find_unexpected_errors_no_alert(self):
webdriver.find_elements.return_value = []
- unexpected_errors = WebDriverSelenium.find_unexpected_errors(driver=webdriver)
+ unexpected_errors = find_unexpected_errors(driver=webdriver)
assert len(unexpected_errors) == 0
assert "alert" in webdriver.find_elements.call_args_list[0][0][1]
@@ -128,7 +128,7 @@ def test_find_unexpected_errors(self, mock_webdriver_wait):
webdriver.find_elements.return_value = [alert_div]
alert_div.find_elements.return_value = MagicMock()
- unexpected_errors = WebDriverSelenium.find_unexpected_errors(driver=webdriver)
+ unexpected_errors = find_unexpected_errors(driver=webdriver)
assert len(unexpected_errors) == 1
# attempt to find alerts
@@ -141,14 +141,14 @@ def test_find_unexpected_errors(self, mock_webdriver_wait):
assert alert_div == webdriver.execute_script.call_args_list[0][0][1]
-class TestWebDriverSelenium(SupersetTestCase):
+class TestWebDriverProxy(SupersetTestCase):
@patch("superset.utils.webdriver.WebDriverWait")
@patch("superset.utils.webdriver.firefox")
@patch("superset.utils.webdriver.sleep")
def test_screenshot_selenium_headstart(
self, mock_sleep, mock_webdriver, mock_webdriver_wait
):
- webdriver = WebDriverSelenium("firefox")
+ webdriver = WebDriverProxy("firefox")
user = security_manager.get_user_by_username(
app.config["THUMBNAIL_SELENIUM_USER"]
)
@@ -161,7 +161,7 @@ def test_screenshot_selenium_headstart(
@patch("superset.utils.webdriver.firefox")
def test_screenshot_selenium_locate_wait(self, mock_webdriver, mock_webdriver_wait):
app.config["SCREENSHOT_LOCATE_WAIT"] = 15
- webdriver = WebDriverSelenium("firefox")
+ webdriver = WebDriverProxy("firefox")
user = security_manager.get_user_by_username(
app.config["THUMBNAIL_SELENIUM_USER"]
)
@@ -173,7 +173,7 @@ def test_screenshot_selenium_locate_wait(self, mock_webdriver, mock_webdriver_wa
@patch("superset.utils.webdriver.firefox")
def test_screenshot_selenium_load_wait(self, mock_webdriver, mock_webdriver_wait):
app.config["SCREENSHOT_LOAD_WAIT"] = 15
- webdriver = WebDriverSelenium("firefox")
+ webdriver = WebDriverProxy("firefox")
user = security_manager.get_user_by_username(
app.config["THUMBNAIL_SELENIUM_USER"]
)
@@ -187,7 +187,7 @@ def test_screenshot_selenium_load_wait(self, mock_webdriver, mock_webdriver_wait
def test_screenshot_selenium_animation_wait(
self, mock_sleep, mock_webdriver, mock_webdriver_wait
):
- webdriver = WebDriverSelenium("firefox")
+ webdriver = WebDriverProxy("firefox")
user = security_manager.get_user_by_username(
app.config["THUMBNAIL_SELENIUM_USER"]
)