Skip to content

Commit d1dc568

Browse files
authored
Merge pull request #894 from plotly/remote-grid
Remote grid
2 parents b2064f8 + af86268 commit d1dc568

File tree

5 files changed

+105
-21
lines changed

5 files changed

+105
-21
lines changed

dash/CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## Unreleased
2+
3+
### Fixed
4+
5+
- [#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.
6+
17
## [1.2.0] - 2019-08-27
28
### Added
39
- [#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.

dash/testing/browser.py

+32-18
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
)
2424
from dash.testing.dash_page import DashPageMixin
2525
from dash.testing.errors import DashAppLoadingError, BrowserError
26+
from dash.testing.consts import SELENIUM_GRID_DEFAULT
2627

2728

2829
logger = logging.getLogger(__name__)
@@ -32,21 +33,28 @@ class Browser(DashPageMixin):
3233
def __init__(
3334
self,
3435
browser,
36+
remote=False,
37+
remote_url=None,
3538
headless=False,
3639
options=None,
37-
remote=None,
3840
download_path=None,
3941
percy_finalize=True,
4042
wait_timeout=10,
4143
):
4244
self._browser = browser.lower()
45+
self._remote_url = remote_url
46+
self._remote = (
47+
True
48+
if remote_url and remote_url != SELENIUM_GRID_DEFAULT
49+
else remote
50+
)
4351
self._headless = headless
4452
self._options = options
4553
self._download_path = download_path
4654
self._wait_timeout = wait_timeout
4755
self._percy_finalize = percy_finalize
4856

49-
self._driver = until(lambda: self.get_webdriver(remote), timeout=1)
57+
self._driver = until(self.get_webdriver, timeout=1)
5058
self._driver.implicitly_wait(2)
5159

5260
self._wd_wait = WebDriverWait(self.driver, wait_timeout)
@@ -285,21 +293,11 @@ def open_new_tab(self, url=None):
285293
)
286294
)
287295

288-
def get_webdriver(self, remote):
296+
def get_webdriver(self):
289297
try:
290-
return (
291-
getattr(self, "_get_{}".format(self._browser))()
292-
if remote is None
293-
else webdriver.Remote(
294-
command_executor=remote,
295-
desired_capabilities=getattr(
296-
DesiredCapabilities, self._browser.upper()
297-
),
298-
)
299-
)
298+
return getattr(self, "_get_{}".format(self._browser))()
300299
except WebDriverException:
301300
logger.exception("<<<Webdriver not initialized correctly>>>")
302-
return None
303301

304302
def _get_wd_options(self):
305303
options = (
@@ -333,8 +331,16 @@ def _get_chrome(self):
333331
},
334332
)
335333

336-
chrome = webdriver.Chrome(
337-
options=options, desired_capabilities=capabilities
334+
chrome = (
335+
webdriver.Remote(
336+
command_executor=self._remote_url,
337+
options=options,
338+
desired_capabilities=capabilities,
339+
)
340+
if self._remote
341+
else webdriver.Chrome(
342+
options=options, desired_capabilities=capabilities
343+
)
338344
)
339345

340346
# https://bugs.chromium.org/p/chromium/issues/detail?id=696481
@@ -372,8 +378,16 @@ def _get_firefox(self):
372378
"browser.helperApps.neverAsk.saveToDisk",
373379
"application/octet-stream", # this MIME is generic for binary
374380
)
375-
return webdriver.Firefox(
376-
firefox_profile=fp, options=options, capabilities=capabilities
381+
return (
382+
webdriver.Remote(
383+
command_executor=self._remote_url,
384+
options=options,
385+
desired_capabilities=capabilities,
386+
)
387+
if self._remote
388+
else webdriver.Firefox(
389+
firefox_profile=fp, options=options, capabilities=capabilities
390+
)
377391
)
378392

379393
@staticmethod

dash/testing/consts.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SELENIUM_GRID_DEFAULT = "http://localhost:4444/wd/hub"

dash/testing/plugin.py

+22-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# pylint: disable=missing-docstring,redefined-outer-name
22
import warnings
3+
from .consts import SELENIUM_GRID_DEFAULT
4+
35

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

17-
WEBDRIVERS = {"Chrome", "Firefox", "Remote"}
19+
WEBDRIVERS = {"Chrome", "Firefox"}
1820

1921

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

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

32+
dash.addoption(
33+
"--remote",
34+
action="store_true",
35+
help="instruct pytest to use selenium grid",
36+
)
37+
38+
dash.addoption(
39+
"--remote-url",
40+
action="store",
41+
default=SELENIUM_GRID_DEFAULT,
42+
help="set a different selenium grid remote url if other than default",
43+
)
44+
3245
dash.addoption(
3346
"--headless",
3447
action="store_true",
@@ -99,6 +112,8 @@ def dashr_server():
99112
def dash_br(request, tmpdir):
100113
with Browser(
101114
browser=request.config.getoption("webdriver"),
115+
remote=request.config.getoption("remote"),
116+
remote_url=request.config.getoption("remote_url"),
102117
headless=request.config.getoption("headless"),
103118
options=request.config.hook.pytest_setup_options(),
104119
download_path=tmpdir.mkdir("download").strpath,
@@ -112,6 +127,8 @@ def dash_duo(request, dash_thread_server, tmpdir):
112127
with DashComposite(
113128
dash_thread_server,
114129
browser=request.config.getoption("webdriver"),
130+
remote=request.config.getoption("remote"),
131+
remote_url=request.config.getoption("remote_url"),
115132
headless=request.config.getoption("headless"),
116133
options=request.config.hook.pytest_setup_options(),
117134
download_path=tmpdir.mkdir("download").strpath,
@@ -125,6 +142,8 @@ def dashr(request, dashr_server, tmpdir):
125142
with DashRComposite(
126143
dashr_server,
127144
browser=request.config.getoption("webdriver"),
145+
remote=request.config.getoption("remote"),
146+
remote_url=request.config.getoption("remote_url"),
128147
headless=request.config.getoption("headless"),
129148
options=request.config.hook.pytest_setup_options(),
130149
download_path=tmpdir.mkdir("download").strpath,

tests/unit/test_browser.py

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import pytest
2+
from dash.testing.browser import Browser
3+
from dash.testing.consts import SELENIUM_GRID_DEFAULT
4+
5+
6+
@pytest.mark.parametrize("browser_type", ("Chrome", "Firefox"))
7+
def test_browser_smoke(browser_type, tmpdir):
8+
9+
browser = Browser(
10+
browser=browser_type,
11+
remote=False,
12+
remote_url=SELENIUM_GRID_DEFAULT,
13+
headless=True,
14+
options=None,
15+
download_path=tmpdir.mkdir("download").strpath,
16+
percy_finalize=True,
17+
)
18+
assert browser.driver.name == browser_type.lower()
19+
20+
21+
def test_browser_use_remote_webdriver(tmpdir):
22+
# test creation with remote=True
23+
with pytest.raises(Exception):
24+
Browser(
25+
browser="Chrome",
26+
remote=True,
27+
remote_url=SELENIUM_GRID_DEFAULT,
28+
headless=True,
29+
options=None,
30+
download_path=tmpdir.mkdir("download").strpath,
31+
percy_finalize=True,
32+
)
33+
34+
# test creation with remote_url other than default
35+
with pytest.raises(Exception):
36+
Browser(
37+
browser="Chrome",
38+
remote=False,
39+
remote_url="http://[email protected]:3333",
40+
headless=True,
41+
options=None,
42+
download_path=tmpdir.mkdir("download").strpath,
43+
percy_finalize=True,
44+
)

0 commit comments

Comments
 (0)