Skip to content

Commit

Permalink
Merge pull request #894 from plotly/remote-grid
Browse files Browse the repository at this point in the history
Remote grid
  • Loading branch information
byronz committed Sep 3, 2019
2 parents b2064f8 + af86268 commit d1dc568
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 21 deletions.
6 changes: 6 additions & 0 deletions dash/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## Unreleased

### Fixed

- [#829](https://github.com/plotly/dash/issues/829) Fixes the `--remote` pytest argument which was not effective in the code, adding a new argument `--remote-url` to support the selenium grid usage in the cloud.

## [1.2.0] - 2019-08-27
### Added
- [#860](https://github.com/plotly/dash/pull/860) Adds a new arg `dev_tools_prune_errors` to `app.run_server` and `app.enable_dev_tools`. Default `True`, tracebacks only include user code and below. Set it to `False` for the previous behavior showing all the Dash and Flask parts of the stack.
Expand Down
50 changes: 32 additions & 18 deletions dash/testing/browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
)
from dash.testing.dash_page import DashPageMixin
from dash.testing.errors import DashAppLoadingError, BrowserError
from dash.testing.consts import SELENIUM_GRID_DEFAULT


logger = logging.getLogger(__name__)
Expand All @@ -32,21 +33,28 @@ class Browser(DashPageMixin):
def __init__(
self,
browser,
remote=False,
remote_url=None,
headless=False,
options=None,
remote=None,
download_path=None,
percy_finalize=True,
wait_timeout=10,
):
self._browser = browser.lower()
self._remote_url = remote_url
self._remote = (
True
if remote_url and remote_url != SELENIUM_GRID_DEFAULT
else remote
)
self._headless = headless
self._options = options
self._download_path = download_path
self._wait_timeout = wait_timeout
self._percy_finalize = percy_finalize

self._driver = until(lambda: self.get_webdriver(remote), timeout=1)
self._driver = until(self.get_webdriver, timeout=1)
self._driver.implicitly_wait(2)

self._wd_wait = WebDriverWait(self.driver, wait_timeout)
Expand Down Expand Up @@ -285,21 +293,11 @@ def open_new_tab(self, url=None):
)
)

def get_webdriver(self, remote):
def get_webdriver(self):
try:
return (
getattr(self, "_get_{}".format(self._browser))()
if remote is None
else webdriver.Remote(
command_executor=remote,
desired_capabilities=getattr(
DesiredCapabilities, self._browser.upper()
),
)
)
return getattr(self, "_get_{}".format(self._browser))()
except WebDriverException:
logger.exception("<<<Webdriver not initialized correctly>>>")
return None

def _get_wd_options(self):
options = (
Expand Down Expand Up @@ -333,8 +331,16 @@ def _get_chrome(self):
},
)

chrome = webdriver.Chrome(
options=options, desired_capabilities=capabilities
chrome = (
webdriver.Remote(
command_executor=self._remote_url,
options=options,
desired_capabilities=capabilities,
)
if self._remote
else webdriver.Chrome(
options=options, desired_capabilities=capabilities
)
)

# https://bugs.chromium.org/p/chromium/issues/detail?id=696481
Expand Down Expand Up @@ -372,8 +378,16 @@ def _get_firefox(self):
"browser.helperApps.neverAsk.saveToDisk",
"application/octet-stream", # this MIME is generic for binary
)
return webdriver.Firefox(
firefox_profile=fp, options=options, capabilities=capabilities
return (
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
)
)

@staticmethod
Expand Down
1 change: 1 addition & 0 deletions dash/testing/consts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELENIUM_GRID_DEFAULT = "http://localhost:4444/wd/hub"
25 changes: 22 additions & 3 deletions dash/testing/plugin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# pylint: disable=missing-docstring,redefined-outer-name
import warnings
from .consts import SELENIUM_GRID_DEFAULT


try:
import pytest
Expand All @@ -14,12 +16,10 @@
except ImportError:
warnings.warn("run `pip install dash[testing]` if you need dash.testing")

WEBDRIVERS = {"Chrome", "Firefox", "Remote"}
WEBDRIVERS = {"Chrome", "Firefox"}


def pytest_addoption(parser):
# Add options to the pytest parser, either on the commandline or ini
# TODO add more options for the selenium driver.
dash = parser.getgroup("Dash", "Dash Integration Tests")

dash.addoption(
Expand All @@ -29,6 +29,19 @@ def pytest_addoption(parser):
help="Name of the selenium driver to use",
)

dash.addoption(
"--remote",
action="store_true",
help="instruct pytest to use selenium grid",
)

dash.addoption(
"--remote-url",
action="store",
default=SELENIUM_GRID_DEFAULT,
help="set a different selenium grid remote url if other than default",
)

dash.addoption(
"--headless",
action="store_true",
Expand Down Expand Up @@ -99,6 +112,8 @@ def dashr_server():
def dash_br(request, tmpdir):
with Browser(
browser=request.config.getoption("webdriver"),
remote=request.config.getoption("remote"),
remote_url=request.config.getoption("remote_url"),
headless=request.config.getoption("headless"),
options=request.config.hook.pytest_setup_options(),
download_path=tmpdir.mkdir("download").strpath,
Expand All @@ -112,6 +127,8 @@ def dash_duo(request, dash_thread_server, tmpdir):
with DashComposite(
dash_thread_server,
browser=request.config.getoption("webdriver"),
remote=request.config.getoption("remote"),
remote_url=request.config.getoption("remote_url"),
headless=request.config.getoption("headless"),
options=request.config.hook.pytest_setup_options(),
download_path=tmpdir.mkdir("download").strpath,
Expand All @@ -125,6 +142,8 @@ def dashr(request, dashr_server, tmpdir):
with DashRComposite(
dashr_server,
browser=request.config.getoption("webdriver"),
remote=request.config.getoption("remote"),
remote_url=request.config.getoption("remote_url"),
headless=request.config.getoption("headless"),
options=request.config.hook.pytest_setup_options(),
download_path=tmpdir.mkdir("download").strpath,
Expand Down
44 changes: 44 additions & 0 deletions tests/unit/test_browser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import pytest
from dash.testing.browser import Browser
from dash.testing.consts import SELENIUM_GRID_DEFAULT


@pytest.mark.parametrize("browser_type", ("Chrome", "Firefox"))
def test_browser_smoke(browser_type, tmpdir):

browser = Browser(
browser=browser_type,
remote=False,
remote_url=SELENIUM_GRID_DEFAULT,
headless=True,
options=None,
download_path=tmpdir.mkdir("download").strpath,
percy_finalize=True,
)
assert browser.driver.name == browser_type.lower()


def test_browser_use_remote_webdriver(tmpdir):
# test creation with remote=True
with pytest.raises(Exception):
Browser(
browser="Chrome",
remote=True,
remote_url=SELENIUM_GRID_DEFAULT,
headless=True,
options=None,
download_path=tmpdir.mkdir("download").strpath,
percy_finalize=True,
)

# test creation with remote_url other than default
with pytest.raises(Exception):
Browser(
browser="Chrome",
remote=False,
remote_url="http://token@any.selenium.grid:3333",
headless=True,
options=None,
download_path=tmpdir.mkdir("download").strpath,
percy_finalize=True,
)

0 comments on commit d1dc568

Please sign in to comment.