From 1cc02af08577a9d57e08b0d175dee9dd4dd81f59 Mon Sep 17 00:00:00 2001 From: byron Date: Fri, 15 Nov 2019 12:42:26 -0500 Subject: [PATCH 1/6] :mute: remove the warning as it might confuse non dash usage --- dash/testing/plugin.py | 11 ++++------- setup.py | 1 + 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/dash/testing/plugin.py b/dash/testing/plugin.py index 894cccad80..715d6ef640 100644 --- a/dash/testing/plugin.py +++ b/dash/testing/plugin.py @@ -1,11 +1,8 @@ # pylint: disable=missing-docstring,redefined-outer-name -import warnings +import pytest from .consts import SELENIUM_GRID_DEFAULT - try: - import pytest - from dash.testing.application_runners import ( ThreadedRunner, ProcessRunner, @@ -14,7 +11,7 @@ from dash.testing.browser import Browser from dash.testing.composite import DashComposite, DashRComposite except ImportError: - warnings.warn("run `pip install dash[testing]` if you need dash.testing") + pass WEBDRIVERS = {"Chrome", "Firefox"} @@ -51,8 +48,8 @@ def pytest_addoption(parser): dash.addoption( "--percy-assets", action="store", - default='tests/assets', - help="configure how Percy will discover your app's assets" + default="tests/assets", + help="configure how Percy will discover your app's assets", ) dash.addoption( diff --git a/setup.py b/setup.py index 68557bb43b..ec8cafd8bd 100644 --- a/setup.py +++ b/setup.py @@ -26,6 +26,7 @@ def read_req_file(req_type): long_description=io.open("README.md", encoding="utf-8").read(), long_description_content_type="text/markdown", install_requires=read_req_file("install"), + python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*', extras_require={ "dev": read_req_file("dev"), "testing": read_req_file("testing"), From 821bdeba7be654bc17b60102919a80a0dd328664 Mon Sep 17 00:00:00 2001 From: byron Date: Mon, 18 Nov 2019 00:20:41 -0500 Subject: [PATCH 2/6] mute pytest11 if no testing modules installed --- dash/testing/plugin.py | 4 +--- setup.py | 25 ++++++++++++++++--------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/dash/testing/plugin.py b/dash/testing/plugin.py index 715d6ef640..b2206006bf 100644 --- a/dash/testing/plugin.py +++ b/dash/testing/plugin.py @@ -13,15 +13,13 @@ except ImportError: pass -WEBDRIVERS = {"Chrome", "Firefox"} - def pytest_addoption(parser): dash = parser.getgroup("Dash", "Dash Integration Tests") dash.addoption( "--webdriver", - choices=tuple(WEBDRIVERS), + choices=("Chrome", "Firefox"), default="Chrome", help="Name of the selenium driver to use", ) diff --git a/setup.py b/setup.py index ec8cafd8bd..03b5d5f4db 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,20 @@ import io +import pkgutil from setuptools import setup, find_packages +ENTRY_POINTS = { + "console_scripts": [ + "dash-generate-components = " + "dash.development.component_generator:cli", + "renderer = dash.development.build_process:renderer", + ] +} + +# this is not a complete guess, but picking two typical dash dependencies in +# require-testing.txt +if pkgutil.find_loader("waitress") and pkgutil.find_loader("percy"): + ENTRY_POINTS["pytest11"] = ["dash = dash.testing.plugin"] + main_ns = {} exec(open("dash/version.py").read(), main_ns) # pylint: disable=exec-used @@ -26,19 +40,12 @@ def read_req_file(req_type): long_description=io.open("README.md", encoding="utf-8").read(), long_description_content_type="text/markdown", install_requires=read_req_file("install"), - python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*', + python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*", extras_require={ "dev": read_req_file("dev"), "testing": read_req_file("testing"), }, - entry_points={ - "console_scripts": [ - "dash-generate-components = " - "dash.development.component_generator:cli", - "renderer = dash.development.build_process:renderer", - ], - "pytest11": ["dash = dash.testing.plugin"], - }, + entry_points=ENTRY_POINTS, url="https://plot.ly/dash", classifiers=[ "Development Status :: 5 - Production/Stable", From fbdb9743a588615b71a24f2fe12b2c30d54733b9 Mon Sep 17 00:00:00 2001 From: byron Date: Mon, 18 Nov 2019 20:23:10 -0500 Subject: [PATCH 3/6] :ok_hand: skip the plugin if not in the context of testing as extras --- dash/testing/plugin.py | 306 ++++++++++++++++++++--------------------- setup.py | 23 ++-- 2 files changed, 161 insertions(+), 168 deletions(-) diff --git a/dash/testing/plugin.py b/dash/testing/plugin.py index b2206006bf..4eee911c27 100644 --- a/dash/testing/plugin.py +++ b/dash/testing/plugin.py @@ -1,157 +1,157 @@ # pylint: disable=missing-docstring,redefined-outer-name +import pkgutil import pytest from .consts import SELENIUM_GRID_DEFAULT -try: - from dash.testing.application_runners import ( - ThreadedRunner, - ProcessRunner, - RRunner, - ) - from dash.testing.browser import Browser - from dash.testing.composite import DashComposite, DashRComposite -except ImportError: - pass - - -def pytest_addoption(parser): - dash = parser.getgroup("Dash", "Dash Integration Tests") - - dash.addoption( - "--webdriver", - choices=("Chrome", "Firefox"), - default="Chrome", - 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", - help="set this flag to run in headless mode", - ) - - dash.addoption( - "--percy-assets", - action="store", - default="tests/assets", - help="configure how Percy will discover your app's assets", - ) - - dash.addoption( - "--nopercyfinalize", - action="store_false", - help="set this flag to control percy finalize at CI level", - ) - - -@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 - # execute all other hooks to obtain the report object - outcome = yield - rep = outcome.get_result() - - # we only look at actual failing test calls, not setup/teardown - if rep.when == "call" and rep.failed: - for name, fixture in item.funcargs.items(): - try: - if name in {"dash_duo", "dash_br", "dashr"}: - fixture.take_snapshot(item.name) - except Exception as e: # pylint: disable=broad-except - print(e) - - -############################################################################### -# Fixtures -############################################################################### - - -@pytest.fixture -def dash_thread_server(): - """Start a local dash server in a new thread.""" - with ThreadedRunner() as starter: - yield starter - - -@pytest.fixture -def dash_process_server(): - """Start a Dash server with subprocess.Popen and waitress-serve.""" - with ProcessRunner() as starter: - yield starter - - -@pytest.fixture -def dashr_server(): - with RRunner() as starter: - yield starter - - -@pytest.fixture -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, - percy_assets_root=request.config.getoption("percy_assets"), - percy_finalize=request.config.getoption("nopercyfinalize"), - ) as browser: - yield browser - - -@pytest.fixture -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, - percy_assets_root=request.config.getoption("percy_assets"), - percy_finalize=request.config.getoption("nopercyfinalize"), - ) as dc: - yield dc - - -@pytest.fixture -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, - percy_assets_root=request.config.getoption("percy_assets"), - percy_finalize=request.config.getoption("nopercyfinalize"), - ) as dc: - yield dc +# this is not a complete guess, but picking few typical dash dependencies in +# require-testing.txt +if ( + pkgutil.find_loader("waitress") + and pkgutil.find_loader("percy") + and pkgutil.find_loader("beautifulsoup4") +): + try: + from dash.testing.application_runners import ( + ThreadedRunner, + ProcessRunner, + RRunner, + ) + from dash.testing.browser import Browser + from dash.testing.composite import DashComposite, DashRComposite + except ImportError: + pass + + def pytest_addoption(parser): + dash = parser.getgroup("Dash", "Dash Integration Tests") + + dash.addoption( + "--webdriver", + choices=("Chrome", "Firefox"), + default="Chrome", + 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", + help="set this flag to run in headless mode", + ) + + dash.addoption( + "--percy-assets", + action="store", + default="tests/assets", + help="configure how Percy will discover your app's assets", + ) + + dash.addoption( + "--nopercyfinalize", + action="store_false", + help="set this flag to control percy finalize at CI level", + ) + + @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 + # execute all other hooks to obtain the report object + outcome = yield + rep = outcome.get_result() + + # we only look at actual failing test calls, not setup/teardown + if rep.when == "call" and rep.failed: + for name, fixture in item.funcargs.items(): + try: + if name in {"dash_duo", "dash_br", "dashr"}: + fixture.take_snapshot(item.name) + except Exception as e: # pylint: disable=broad-except + print(e) + + ############################################################################### + # Fixtures + ############################################################################### + + @pytest.fixture + def dash_thread_server(): + """Start a local dash server in a new thread.""" + with ThreadedRunner() as starter: + yield starter + + @pytest.fixture + def dash_process_server(): + """Start a Dash server with subprocess.Popen and waitress-serve.""" + with ProcessRunner() as starter: + yield starter + + @pytest.fixture + def dashr_server(): + with RRunner() as starter: + yield starter + + @pytest.fixture + 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, + percy_assets_root=request.config.getoption("percy_assets"), + percy_finalize=request.config.getoption("nopercyfinalize"), + ) as browser: + yield browser + + @pytest.fixture + 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, + percy_assets_root=request.config.getoption("percy_assets"), + percy_finalize=request.config.getoption("nopercyfinalize"), + ) as dc: + yield dc + + @pytest.fixture + 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, + percy_assets_root=request.config.getoption("percy_assets"), + percy_finalize=request.config.getoption("nopercyfinalize"), + ) as dc: + yield dc diff --git a/setup.py b/setup.py index 03b5d5f4db..c352eae627 100644 --- a/setup.py +++ b/setup.py @@ -1,20 +1,6 @@ import io -import pkgutil from setuptools import setup, find_packages -ENTRY_POINTS = { - "console_scripts": [ - "dash-generate-components = " - "dash.development.component_generator:cli", - "renderer = dash.development.build_process:renderer", - ] -} - -# this is not a complete guess, but picking two typical dash dependencies in -# require-testing.txt -if pkgutil.find_loader("waitress") and pkgutil.find_loader("percy"): - ENTRY_POINTS["pytest11"] = ["dash = dash.testing.plugin"] - main_ns = {} exec(open("dash/version.py").read(), main_ns) # pylint: disable=exec-used @@ -45,7 +31,14 @@ def read_req_file(req_type): "dev": read_req_file("dev"), "testing": read_req_file("testing"), }, - entry_points=ENTRY_POINTS, + entry_points={ + "console_scripts": [ + "dash-generate-components = " + "dash.development.component_generator:cli", + "renderer = dash.development.build_process:renderer", + ], + "pytest11": ["dash = dash.testing.plugin"], + }, url="https://plot.ly/dash", classifiers=[ "Development Status :: 5 - Production/Stable", From ca03fcc9c9d9e6d71bc434feaa2d3f37dec1015a Mon Sep 17 00:00:00 2001 From: byron Date: Mon, 18 Nov 2019 22:42:38 -0500 Subject: [PATCH 4/6] :wrench: add install -e before unit --- .circleci/config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index f1d5e193cb..ab6323e407 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -60,6 +60,7 @@ jobs: name: 🐍 Python Unit Tests command: | . venv/bin/activate + pip install -e .[testing,dev] --progress-bar off PYTHONPATH=~/dash/tests/assets pytest tests/unit - run: name: ☕ JS Unit Tests From 4b82a484b7181283b76d41c90aa2ae3c137536be Mon Sep 17 00:00:00 2001 From: byron Date: Mon, 18 Nov 2019 22:58:25 -0500 Subject: [PATCH 5/6] reinstall --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ab6323e407..068f79c230 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -60,7 +60,7 @@ jobs: name: 🐍 Python Unit Tests command: | . venv/bin/activate - pip install -e .[testing,dev] --progress-bar off + pip install -e .[testing,dev] --progress-bar off --force-reinstall PYTHONPATH=~/dash/tests/assets pytest tests/unit - run: name: ☕ JS Unit Tests From ce032a3337a3e6a4be49f4f1558b419c6681e734 Mon Sep 17 00:00:00 2001 From: byron Date: Wed, 20 Nov 2019 16:54:48 -0500 Subject: [PATCH 6/6] the skip approarch in plugin does not work, revert it back --- .circleci/config.yml | 1 - dash/testing/plugin.py | 307 +++++++++++++++++++++-------------------- 2 files changed, 154 insertions(+), 154 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 068f79c230..f1d5e193cb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -60,7 +60,6 @@ jobs: name: 🐍 Python Unit Tests command: | . venv/bin/activate - pip install -e .[testing,dev] --progress-bar off --force-reinstall PYTHONPATH=~/dash/tests/assets pytest tests/unit - run: name: ☕ JS Unit Tests diff --git a/dash/testing/plugin.py b/dash/testing/plugin.py index 4eee911c27..c42c36e9fb 100644 --- a/dash/testing/plugin.py +++ b/dash/testing/plugin.py @@ -1,157 +1,158 @@ # pylint: disable=missing-docstring,redefined-outer-name -import pkgutil import pytest from .consts import SELENIUM_GRID_DEFAULT -# this is not a complete guess, but picking few typical dash dependencies in -# require-testing.txt -if ( - pkgutil.find_loader("waitress") - and pkgutil.find_loader("percy") - and pkgutil.find_loader("beautifulsoup4") -): - try: - from dash.testing.application_runners import ( - ThreadedRunner, - ProcessRunner, - RRunner, - ) - from dash.testing.browser import Browser - from dash.testing.composite import DashComposite, DashRComposite - except ImportError: - pass - - def pytest_addoption(parser): - dash = parser.getgroup("Dash", "Dash Integration Tests") - - dash.addoption( - "--webdriver", - choices=("Chrome", "Firefox"), - default="Chrome", - 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", - help="set this flag to run in headless mode", - ) - - dash.addoption( - "--percy-assets", - action="store", - default="tests/assets", - help="configure how Percy will discover your app's assets", - ) - - dash.addoption( - "--nopercyfinalize", - action="store_false", - help="set this flag to control percy finalize at CI level", - ) - - @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 - # execute all other hooks to obtain the report object - outcome = yield - rep = outcome.get_result() - - # we only look at actual failing test calls, not setup/teardown - if rep.when == "call" and rep.failed: - for name, fixture in item.funcargs.items(): - try: - if name in {"dash_duo", "dash_br", "dashr"}: - fixture.take_snapshot(item.name) - except Exception as e: # pylint: disable=broad-except - print(e) - - ############################################################################### - # Fixtures - ############################################################################### - - @pytest.fixture - def dash_thread_server(): - """Start a local dash server in a new thread.""" - with ThreadedRunner() as starter: - yield starter - - @pytest.fixture - def dash_process_server(): - """Start a Dash server with subprocess.Popen and waitress-serve.""" - with ProcessRunner() as starter: - yield starter - - @pytest.fixture - def dashr_server(): - with RRunner() as starter: - yield starter - - @pytest.fixture - 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, - percy_assets_root=request.config.getoption("percy_assets"), - percy_finalize=request.config.getoption("nopercyfinalize"), - ) as browser: - yield browser - - @pytest.fixture - 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, - percy_assets_root=request.config.getoption("percy_assets"), - percy_finalize=request.config.getoption("nopercyfinalize"), - ) as dc: - yield dc - - @pytest.fixture - 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, - percy_assets_root=request.config.getoption("percy_assets"), - percy_finalize=request.config.getoption("nopercyfinalize"), - ) as dc: - yield dc + +try: + from dash.testing.application_runners import ( + ThreadedRunner, + ProcessRunner, + RRunner, + ) + from dash.testing.browser import Browser + from dash.testing.composite import DashComposite, DashRComposite +except ImportError: + pass + + +def pytest_addoption(parser): + dash = parser.getgroup("Dash", "Dash Integration Tests") + + dash.addoption( + "--webdriver", + choices=("Chrome", "Firefox"), + default="Chrome", + 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", + help="set this flag to run in headless mode", + ) + + dash.addoption( + "--percy-assets", + action="store", + default="tests/assets", + help="configure how Percy will discover your app's assets", + ) + + dash.addoption( + "--nopercyfinalize", + action="store_false", + help="set this flag to control percy finalize at CI level", + ) + + +@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 + # execute all other hooks to obtain the report object + outcome = yield + rep = outcome.get_result() + + # we only look at actual failing test calls, not setup/teardown + if rep.when == "call" and rep.failed: + for name, fixture in item.funcargs.items(): + try: + if name in {"dash_duo", "dash_br", "dashr"}: + fixture.take_snapshot(item.name) + except Exception as e: # pylint: disable=broad-except + print(e) + + +############################################################################### +# Fixtures +############################################################################### + + +@pytest.fixture +def dash_thread_server(): + """Start a local dash server in a new thread.""" + with ThreadedRunner() as starter: + yield starter + + +@pytest.fixture +def dash_process_server(): + """Start a Dash server with subprocess.Popen and waitress-serve.""" + with ProcessRunner() as starter: + yield starter + + +@pytest.fixture +def dashr_server(): + with RRunner() as starter: + yield starter + + +@pytest.fixture +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, + percy_assets_root=request.config.getoption("percy_assets"), + percy_finalize=request.config.getoption("nopercyfinalize"), + ) as browser: + yield browser + + +@pytest.fixture +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, + percy_assets_root=request.config.getoption("percy_assets"), + percy_finalize=request.config.getoption("nopercyfinalize"), + ) as dc: + yield dc + + +@pytest.fixture +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, + percy_assets_root=request.config.getoption("percy_assets"), + percy_finalize=request.config.getoption("nopercyfinalize"), + ) as dc: + yield dc