Skip to content

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

Open
@zyxue

Description

@zyxue

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/

Metadata

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