I'm attempting to use selenium chromebrowser to test a Dash app as recommended in the Dash docs for testing. When I run the tests with pytest, I get a huge error message, the gist of which seems to say that the chromebrowser webdriver is timing out and not initializing correctly.
My error is
============================================================================================================================== ERRORS ===============================================================================================================================
____________________________________________________________________________________________________________ ERROR at setup of test_bsly001_falsy_child _____________________________________________________________________________________________________________
request = <SubRequest 'dash_duo' for <Function test_bsly001_falsy_child>>, dash_thread_server = <dash.testing.application_runners.ThreadedRunner object at 0x11e57bc70>
tmpdir = local('/private/var/folders/mf/nsy2wm4j33nb995x9rgllwbr0000gn/T/pytest-of-hyrumdickinson/pytest-16/test_bsly001_falsy_child0')
@pytest.fixture
def dash_duo(request, dash_thread_server, tmpdir) -> DashComposite:
> 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"),
pause=request.config.getoption("pause"),
) as dc:
/opt/homebrew/lib/python3.9/site-packages/dash/testing/plugin.py:151:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/opt/homebrew/lib/python3.9/site-packages/dash/testing/composite.py:6: in __init__
super().__init__(**kwargs)
/opt/homebrew/lib/python3.9/site-packages/dash/testing/browser.py:68: in __init__
self._driver = until(self.get_webdriver, timeout=1)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
wait_cond = <bound method Browser.get_webdriver of <dash.testing.composite.DashComposite object at 0x11e57b8b0>>, timeout = 1, poll = 0.1, msg = 'expected condition not met within timeout'
def until(
wait_cond, timeout, poll=0.1, msg="expected condition not met within timeout"
): # noqa: C0330
res = wait_cond()
logger.debug(
"start wait.until with method, timeout, poll => %s %s %s",
wait_cond,
timeout,
poll,
)
end_time = time.time() + timeout
while not res:
if time.time() > end_time:
> raise TestingTimeoutError(msg)
E dash.testing.errors.TestingTimeoutError: expected condition not met within timeout
/opt/homebrew/lib/python3.9/site-packages/dash/testing/wait.py:26: TestingTimeoutError
------------------------------------------------------------------------------------------------------------------------ Captured log setup -------------------------------------------------------------------------------------------------------------------------
ERROR dash.testing.browser:browser.py:455 <<<Webdriver not initialized correctly>>>
Traceback (most recent call last):
File "/opt/homebrew/lib/python3.9/site-packages/dash/testing/browser.py", line 453, in get_webdriver
return getattr(self, f"_get_{self._browser}")()
File "/opt/homebrew/lib/python3.9/site-packages/dash/testing/browser.py", line 497, in _get_chrome
else webdriver.Chrome(options=options)
File "/opt/homebrew/lib/python3.9/site-packages/selenium/webdriver/chrome/webdriver.py", line 69, in __init__
super().__init__(DesiredCapabilities.CHROME['browserName'], "goog",
File "/opt/homebrew/lib/python3.9/site-packages/selenium/webdriver/chromium/webdriver.py", line 89, in __init__
self.service.start()
File "/opt/homebrew/lib/python3.9/site-packages/selenium/webdriver/common/service.py", line 98, in start
self.assert_process_still_running()
File "/opt/homebrew/lib/python3.9/site-packages/selenium/webdriver/common/service.py", line 110, in assert_process_still_running
raise WebDriverException(
selenium.common.exceptions.WebDriverException: Message: Service chromedriver unexpectedly exited. Status code was: -9
ERROR dash.testing.browser:browser.py:455 <<<Webdriver not initialized correctly>>>
Traceback (most recent call last):
File "/opt/homebrew/lib/python3.9/site-packages/dash/testing/browser.py", line 453, in get_webdriver
return getattr(self, f"_get_{self._browser}")()
File "/opt/homebrew/lib/python3.9/site-packages/dash/testing/browser.py", line 497, in _get_chrome
else webdriver.Chrome(options=options)
File "/opt/homebrew/lib/python3.9/site-packages/selenium/webdriver/chrome/webdriver.py", line 69, in __init__
super().__init__(DesiredCapabilities.CHROME['browserName'], "goog",
File "/opt/homebrew/lib/python3.9/site-packages/selenium/webdriver/chromium/webdriver.py", line 89, in __init__
self.service.start()
File "/opt/homebrew/lib/python3.9/site-packages/selenium/webdriver/common/service.py", line 98, in start
self.assert_process_still_running()
File "/opt/homebrew/lib/python3.9/site-packages/selenium/webdriver/common/service.py", line 110, in assert_process_still_running
raise WebDriverException(
selenium.common.exceptions.WebDriverException: Message: Service chromedriver unexpectedly exited. Status code was: -9
ERROR dash.testing.browser:browser.py:455 <<<Webdriver not initialized correctly>>>
Traceback (most recent call last):
File "/opt/homebrew/lib/python3.9/site-packages/dash/testing/browser.py", line 453, in get_webdriver
return getattr(self, f"_get_{self._browser}")()
File "/opt/homebrew/lib/python3.9/site-packages/dash/testing/browser.py", line 497, in _get_chrome
else webdriver.Chrome(options=options)
File "/opt/homebrew/lib/python3.9/site-packages/selenium/webdriver/chrome/webdriver.py", line 69, in __init__
super().__init__(DesiredCapabilities.CHROME['browserName'], "goog",
File "/opt/homebrew/lib/python3.9/site-packages/selenium/webdriver/chromium/webdriver.py", line 89, in __init__
self.service.start()
File "/opt/homebrew/lib/python3.9/site-packages/selenium/webdriver/common/service.py", line 98, in start
self.assert_process_still_running()
File "/opt/homebrew/lib/python3.9/site-packages/selenium/webdriver/common/service.py", line 110, in assert_process_still_running
raise WebDriverException(
selenium.common.exceptions.WebDriverException: Message: Service chromedriver unexpectedly exited. Status code was: -9
====================================================================================================================== short test summary info ======================================================================================================================
ERROR parmoo/parmoo/viz_test/test_one.py::test_bsly001_falsy_child - dash.testing.errors.TestingTimeoutError: expected condition not met within timeout
The script causing the error is a copy-paste of the Dash test example script at https://dash.plotly.com/testing:
import dash
from dash import html
# 2. give each testcase a tcid, and pass the fixture
# as a function argument, less boilerplate
def test_bsly001_falsy_child(dash_duo):
# 3. define your app inside the test function
app = dash.Dash(__name__)
app.layout = html.Div(id="nully-wrapper", children=0)
# 4. host the app locally in a thread, all dash server configs could be
# passed after the first app argument
dash_duo.start_server(app)
# 5. use wait_for_* if your target element is the result of a callback,
# keep in mind even the initial rendering can trigger callbacks
dash_duo.wait_for_text_to_equal("#nully-wrapper", "0", timeout=4)
# 6. use this form if its present is expected at the action point
assert dash_duo.find_element("#nully-wrapper").text == "0"
# 7. to make the checkpoint more readable, you can describe the
# acceptance criterion as an assert message after the comma.
assert dash_duo.get_logs() == [], "browser console should contain no error"
# 8. visual testing with percy snapshot
dash_duo.percy_snapshot("bsly001-layout")
The test folder contains an empty __init__.py
file and the script above. The command the runs the test and triggers the error is
python3 -m pytest location/of/test/folder
Solutions I've already tried (unsuccessfully) include
- putting chromedriver in the PATH
- making sure chromedriver's version lines up with my version of Google Chrome
- making sure that Google Chrome is installed in the default location on my machine
- making the chromedriver file executable via
chmod +x [location]
- removing duplicate installations of chromedriver
- deleting and reinstalling chromedriver
- letting chromedriver through my safety permissions (both graphically and via
xattr -d com.apple.quarantine /path-to-quarantined-file
- making sure chromedriver's dependencies are installed (this was the solution to this StackOverflow post)
- increasing the
timeout
length
I'm using ChromeDriver 103.0.5060.53 on a 2020 M1 MacBook Pro running Chrome version 103 on macOS Monterey. I'm using the Dash docs 'example' test script. My python version is 3.9.13, with pytest-7.1.2, dash-2.5.1, selenium-4.3.0, handled by pip-22.1.1 which is in turn handled by homebrew-3.5.4. I am not using a virtual environment tool.