Skip to content

provide easier way to run integration tests in a Docker container #1420

Open

Description

My environment:

dash                 1.16.0
dash-core-components 1.12.0
dash-html-components 1.1.1
dash-table           4.10.1

I'm trying to runn integration tests with

pytest --headless tests/

inside a docker container, and it fails with messages like

ERROR    dash.testing.browser:browser.py:415 <<<Webdriver not initialized correctly>>>
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/dash/testing/browser.py", line 413, in get_webdriver
    return getattr(self, "_get_{}".format(self._browser))()
  File "/usr/local/lib/python3.8/site-packages/dash/testing/browser.py", line 459, in _get_chrome
    else webdriver.Chrome(options=options, desired_capabilities=capabilities)
  File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/chrome/webdriver.py", line 76, in __init__
    RemoteWebDriver.__init__(
  File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 157, in __init__
    self.start_session(capabilities, browser_profile)
  File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 252, in start_session
    response = self.execute(Command.NEW_SESSION, parameters)
  File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python3.8/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: exited abnormally.
  (unknown error: DevToolsActivePort file doesn't exist)
  (The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)
                         

I have made the same tests pass outside the container. The code is sent to jenkins and a docker image get build, I'm trying to use the image for running tests on jenkins, which is why container becomes relevant.

Is this a good practice, if not, what's the recommended way?

Btw, I can actually make the tests pass by adding options.add_argument("--no-sandbox") right before these lines:

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

learned from this answer, but it feels hacky. It seems related to starting chrome as root, so I also tried starting the container as non-root, but it still doesn't work.

A minimal reproducible example can be

$ cat Dockerfile

FROM python:3.8

RUN apt-get update -y

RUN apt-get install -y unzip openjdk-11-jre-headless xvfb libxi6 libgconf-2-4
RUN curl -sS -o - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add
RUN echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list
RUN apt-get -y update
RUN apt-get -y install google-chrome-stable

RUN wget https://chromedriver.storage.googleapis.com/85.0.4183.87/chromedriver_linux64.zip && unzip chromedriver_linux64.zip && mv chromedriver /usr/bin && rm -v chromedriver_linux64.zip

WORKDIR /app

RUN python -m pip install --upgrade pip && python -m pip install dash[testing]

COPY . /app/

with the test example from https://dash.plotly.com/testing

$ cat tests/test_example.py

import dash
import dash_html_components as html


def test_bsly001_falsy_child(dash_duo):
    app = dash.Dash(__name__)
    app.layout = html.Div(id="nully-wrapper", children=0)

    dash_duo.start_server(app)

    dash_duo.wait_for_text_to_equal("#nully-wrapper", "0", timeout=4)

    assert dash_duo.find_element("#nully-wrapper").text == "0"

    assert dash_duo.get_logs() == [], "browser console should contain no error"

    dash_duo.percy_snapshot("bsly001-layout")

The directory structure is

$ tree .

.
├── Dockerfile
└── tests
    └── test_example.py

To reproduce error:

docker build . -t myapp
docker run -it --rm  myapp:latest pytest --headless tests  

To run the container as non-root user:

docker run -it --rm  --user 1000:1000 myapp:latest pytest --headless tests

To add options.add_argument("--no-sandbox"), one needs to get inside the container, change the dash source code, and then rerun pytest:

docker run -it --rm  myapp:latest /bin/bash
# add the line to /usr/local/lib/python3.8/site-packages/dash/testing/browser.py
root@e566ed62cea1:/app# pytest --headless tests/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    P3backlogfeaturesomething newtestingautomated tests

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions