Skip to content

Commit

Permalink
Merge pull request #805 from plotly/headless-mode
Browse files Browse the repository at this point in the history
Headless mode
  • Loading branch information
byronz authored Jul 5, 2019
2 parents b41a533 + 65ab456 commit 21efbfe
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ valid-metaclass-classmethod-first-arg=mcs
[DESIGN]

# Maximum number of arguments for function / method
max-args=5
max-args=10

# Maximum number of attributes for a class (see R0902).
max-attributes=20
Expand Down
2 changes: 1 addition & 1 deletion .pylintrc37
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ valid-metaclass-classmethod-first-arg=mcs
[DESIGN]

# Maximum number of arguments for function / method.
max-args=5
max-args=10

# Maximum number of attributes for a class (see R0902).
max-attributes=20
Expand Down
2 changes: 2 additions & 0 deletions dash/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
- 💥 [#808](https://github.com/plotly/dash/pull/808) Remove strong `dash.testing` dependencies per community feedbacks.
Testing users should do `pip install dash[testing]` afterwards.

- [#805](https://github.com/plotly/dash/pull/805) Add headless mode for dash.testing, add `pytest_setup_options` hook for full configuration of `WebDriver Options`.

## [1.0.0] - 2019-06-20
### Changed
- 💥 [#761](https://github.com/plotly/dash/pull/761) Several breaking changes to the `dash.Dash` API:
Expand Down
38 changes: 29 additions & 9 deletions dash/testing/browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.action_chains import ActionChains
Expand All @@ -25,8 +24,17 @@


class Browser(DashPageMixin):
def __init__(self, browser, remote=None, wait_timeout=10):
def __init__(
self,
browser,
headless=False,
options=None,
remote=None,
wait_timeout=10,
):
self._browser = browser.lower()
self._headless = headless
self._options = options
self._wait_timeout = wait_timeout

self._driver = self.get_webdriver(remote)
Expand Down Expand Up @@ -244,10 +252,20 @@ def get_webdriver(self, remote):
)
)

@staticmethod
def _get_chrome():
options = Options()
options.add_argument("--no-sandbox")
def _get_wd_options(self):
options = (
self._options[0]
if self._options and isinstance(self._options, list)
else getattr(webdriver, self._browser).options.Options()
)

if self._headless:
options.headless = True

return options

def _get_chrome(self):
options = self._get_wd_options()

capabilities = DesiredCapabilities.CHROME
capabilities["loggingPrefs"] = {"browser": "SEVERE"}
Expand All @@ -261,8 +279,8 @@ def _get_chrome():
chrome.set_window_position(0, 0)
return chrome

@staticmethod
def _get_firefox():
def _get_firefox(self):
options = self._get_wd_options()

capabilities = DesiredCapabilities.FIREFOX
capabilities["loggingPrefs"] = {"browser": "SEVERE"}
Expand All @@ -278,7 +296,9 @@ def _get_firefox():
fp.set_preference("browser.download.folderList", 2)
fp.set_preference("browser.download.manager.showWhenStarting", False)

return webdriver.Firefox(fp, capabilities=capabilities)
return webdriver.Firefox(
fp, options=options, capabilities=capabilities
)

@staticmethod
def _is_windows():
Expand Down
7 changes: 3 additions & 4 deletions dash/testing/composite.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@


class DashComposite(Browser):

def __init__(self, server, browser, remote=None, wait_timeout=10):
super(DashComposite, self).__init__(browser, remote, wait_timeout)
def __init__(self, server, **kwargs):
super(DashComposite, self).__init__(**kwargs)
self.server = server

def start_server(self, app, **kwargs):
'''start the local server with app'''
"""start the local server with app"""

# start server with app and pass Dash arguments
self.server(app, **kwargs)
Expand Down
2 changes: 2 additions & 0 deletions dash/testing/newhooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
def pytest_setup_options():
"""called before webdriver is initialized"""
30 changes: 28 additions & 2 deletions dash/testing/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,25 @@ def pytest_addoption(parser):
help="Name of the selenium driver to use",
)

dash.addoption(
"--headless",
action="store",
default=False,
help="Run tests in headless mode",
)


@pytest.mark.tryfirst
def pytest_addhooks(pluginmanager):
# https://github.com/pytest-dev/pytest-xdist/blob/974bd566c599dc6a9ea291838c6f226197208b46/xdist/plugin.py#L67
# avoid warnings with pytest-2.8
from dash.testing import newhooks

method = getattr(pluginmanager, "add_hookspecs", None)
if method is None:
method = pluginmanager.addhooks # pragma: no cover
method(newhooks)


@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call): # pylint: disable=unused-argument
Expand Down Expand Up @@ -63,13 +82,20 @@ def dash_process_server():

@pytest.fixture
def dash_br(request):
with Browser(request.config.getoption("webdriver")) as browser:
with Browser(
browser=request.config.getoption("webdriver"),
headless=request.config.getoption("headless"),
options=request.config.hook.pytest_setup_options(),
) as browser:
yield browser


@pytest.fixture
def dash_duo(request, dash_thread_server):
with DashComposite(
dash_thread_server, request.config.getoption("webdriver")
dash_thread_server,
browser=request.config.getoption("webdriver"),
headless=request.config.getoption("headless"),
options=request.config.hook.pytest_setup_options(),
) as dc:
yield dc
2 changes: 1 addition & 1 deletion requires-install.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ plotly
dash_renderer==1.0.0
dash-core-components==1.0.0
dash-html-components==1.0.0
dash-table==4.0.0
dash-table==4.0.0

0 comments on commit 21efbfe

Please sign in to comment.