[Python] Getting "SessionNotCreatedException" error while running selenium tests in docker...

Discussão em 'Python' iniciado por Stack, Maio 10, 2025.

  1. Stack

    Stack Membro Participativo

    I have my test automation framework built using Selenium with Python, and I'm trying to execute my tests in a container using docker. While doing so I'm getting "SessionNotCreatedException"

    When I run my code on my laptop it runs fine, however fails when executing them in a container

    Things that I have tried (after asking chatgpt/gemini/claude:

    • Setting some fresh new temporary directory options.add_argument(f'--user-data-dir={user_data_dir}'), where variable user_data_dir is some randomly generated temporary directory

    Please find below the contents from different files (code snippets), and the entire error stacktrace

    test_dockerized_tests.py

    from selenium.webdriver import Chrome
    from selenium.webdriver.chrome.options import Options as chrome_options

    class TestDockerized:

    def test_selenium_visit_a_site_and_validate(self):
    options = chrome_options()
    options.add_argument("--headless")
    # options.add_argument('--incognito')
    # options.add_argument('--disable-dev-shm-usage')
    driver = Chrome(options=options)
    driver.get('https://example.com')
    expected_title = 'Example Domain'
    actual_title = driver.title
    assert actual_title == expected_title


    Dockerfile

    FROM python:3.12

    WORKDIR /practice-python

    RUN apt-get update && apt-get install -y \
    wget \
    unzip \
    curl \
    gnupg \
    ca-certificates \
    fonts-liberation \
    libasound2 \
    libatk-bridge2.0-0 \
    libatk1.0-0 \
    libcups2 \
    libdbus-1-3 \
    libgdk-pixbuf2.0-0 \
    libnspr4 \
    libnss3 \
    libx11-xcb1 \
    libxcomposite1 \
    libxdamage1 \
    libxrandr2 \
    xdg-utils \
    git \
    chromium \
    --no-install-recommends && rm -rf /var/lib/apt/lists/*

    COPY requirements.txt .

    RUN pip install --upgrade pip && \
    pip install --no-cache-dir -r requirements.txt

    COPY . .

    ENV CHROME_BIN=/usr/bin/chromium
    ENV CHROMEDRIVER_PATH=/usr/bin/chromedriver

    CMD ["pytest", "-rA", "-v", "tests/test_dockerized_tests.py"]


    requirements.txt

    selenium==4.27.1
    playwright==1.49.0

    pytest==8.3.3
    pytest-xdist==3.6.1
    pytest-html==4.1.1
    pytest-playwright==0.6.2
    pytest-base-url==2.1.0
    pytest-asyncio==0.25.0
    python-dotenv==1.0.1
    pytest-rerunfailures
    allure-pytest==2.13.5

    requests==2.32.3
    urllib3==2.2.3
    # psycopg2==2.9.10
    psycopg2-binary==2.9.10
    typing_extensions==4.12.2


    Error stacktrace

    ============================= test session starts ==============================
    platform linux -- Python 3.13.3, pytest-8.3.3, pluggy-1.5.0 -- /usr/local/bin/python3.13
    cachedir: .pytest_cache
    metadata: {'Python': '3.13.3', 'Platform': 'Linux-6.11.0-1012-azure-x86_64-with-glibc2.36', 'Packages': {'pytest': '8.3.3', 'pluggy': '1.5.0'}, 'Plugins': {'rerunfailures': '15.0', 'xdist': '3.6.1', 'html': '4.1.1', 'allure-pytest': '2.13.5', 'base-url': '2.1.0', 'metadata': '3.1.1', 'playwright': '0.6.2', 'asyncio': '0.25.0'}, 'Base URL': ''}
    rootdir: /practice-python
    plugins: rerunfailures-15.0, xdist-3.6.1, html-4.1.1, allure-pytest-2.13.5, base-url-2.1.0, metadata-3.1.1, playwright-0.6.2, asyncio-0.25.0
    asyncio: mode=Mode.STRICT, asyncio_default_fixture_loop_scope=None
    collecting ... collected 1 items

    tests/test_dockerized_tests.py::TestDockerized::test_selenium_visit_a_site_and_validate FAILED [100%]

    =================================== FAILURES ===================================
    ____________ TestDockerized.test_selenium_visit_a_site_and_validate ____________

    self = <tests.test_dockerized_tests.TestDockerized object at 0x7fb24ee7ead0>

    def test_selenium_visit_a_site_and_validate(self):
    # driver = get_selenium_driver
    # driver.get('https://example.com')
    # expected_title = 'Example Domain'
    # actual_title = driver.title
    # print(f'Actual title = {actual_title}')
    # assert actual_title == expected_title

    options = chrome_options()
    options.add_argument("--headless")
    # options.add_argument('--incognito')
    # options.add_argument('--disable-dev-shm-usage')
    > driver = Chrome(options=options)

    tests/test_dockerized_tests.py:20:
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    /usr/local/lib/python3.13/site-packages/selenium/webdriver/chrome/webdriver.py:45: in __init__
    super().__init__(
    /usr/local/lib/python3.13/site-packages/selenium/webdriver/chromium/webdriver.py:66: in __init__
    super().__init__(command_executor=executor, options=options)
    /usr/local/lib/python3.13/site-packages/selenium/webdriver/remote/webdriver.py:241: in __init__
    self.start_session(capabilities)
    /usr/local/lib/python3.13/site-packages/selenium/webdriver/remote/webdriver.py:329: in start_session
    response = self.execute(Command.NEW_SESSION, caps)["value"]
    /usr/local/lib/python3.13/site-packages/selenium/webdriver/remote/webdriver.py:384: in execute
    self.error_handler.check_response(response)
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

    self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x7fb24ed09940>
    response = {'status': 500, 'value': '{"value":{"error":"session not created","message":"session not created: probably user data d...\\n#15 0x55fe3c8d9856 \\u003Cunknown>\\n#16 0x55fe3c8ea666 \\u003Cunknown>\\n#17 0x7fdda00c11f5 \\u003Cunknown>\\n"}}'}

    def check_response(self, response: Dict[str, Any]) -> None:
    """Checks that a JSON response from the WebDriver does not have an
    error.

    :Args:
    - response - The JSON response from the WebDriver server as a dictionary
    object.

    :Raises: If the response contains an error message.
    """
    status = response.get("status", None)
    if not status or status == ErrorCode.SUCCESS:
    return
    value = None
    message = response.get("message", "")
    screen: str = response.get("screen", "")
    stacktrace = None
    if isinstance(status, int):
    value_json = response.get("value", None)
    if value_json and isinstance(value_json, str):
    import json

    try:
    value = json.loads(value_json)
    if len(value) == 1:
    value = value["value"]
    status = value.get("error", None)
    if not status:
    status = value.get("status", ErrorCode.UNKNOWN_ERROR)
    message = value.get("value") or value.get("message")
    if not isinstance(message, str):
    value = message
    message = message.get("message")
    else:
    message = value.get("message", None)
    except ValueError:
    pass

    exception_class: Type[WebDriverException]
    e = ErrorCode()
    error_codes = [item for item in dir(e) if not item.startswith("__")]
    for error_code in error_codes:
    error_info = getattr(ErrorCode, error_code)
    if isinstance(error_info, list) and status in error_info:
    exception_class = getattr(ExceptionMapping, error_code, WebDriverException)
    break
    else:
    exception_class = WebDriverException

    if not value:
    value = response["value"]
    if isinstance(value, str):
    raise exception_class(value)
    if message == "" and "message" in value:
    message = value["message"]

    screen = None # type: ignore[assignment]
    if "screen" in value:
    screen = value["screen"]

    stacktrace = None
    st_value = value.get("stackTrace") or value.get("stacktrace")
    if st_value:
    if isinstance(st_value, str):
    stacktrace = st_value.split("\n")
    else:
    stacktrace = []
    try:
    for frame in st_value:
    line = frame.get("lineNumber", "")
    file = frame.get("fileName", "<anonymous>")
    if line:
    file = f"{file}:{line}"
    meth = frame.get("methodName", "<anonymous>")
    if "className" in frame:
    meth = f"{frame['className']}.{meth}"
    msg = " at %s (%s)"
    msg = msg % (meth, file)
    stacktrace.append(msg)
    except TypeError:
    pass
    if exception_class == UnexpectedAlertPresentException:
    alert_text = None
    if "data" in value:
    alert_text = value["data"].get("text")
    elif "alert" in value:
    alert_text = value["alert"].get("text")
    raise exception_class(message, screen, stacktrace, alert_text) # type: ignore[call-arg] # mypy is not smart enough here
    > raise exception_class(message, screen, stacktrace)
    E selenium.common.exceptions.SessionNotCreatedException: Message: session not created: probably user data directory is already in use, please specify a unique value for --user-data-dir argument, or don't use --user-data-dir
    E Stacktrace:
    E #0 0x55fe3c8eb7fa <unknown>
    E #1 0x55fe3c38fe90 <unknown>
    E #2 0x55fe3c3c9cfb <unknown>
    E #3 0x55fe3c3c5a3f <unknown>
    E #4 0x55fe3c415c15 <unknown>
    E #5 0x55fe3c415136 <unknown>
    E #6 0x55fe3c407013 <unknown>
    E #7 0x55fe3c3d3b3b <unknown>
    E #8 0x55fe3c3d47a1 <unknown>
    E #9 0x55fe3c8b0b9b <unknown>
    E #10 0x55fe3c8b4a8a <unknown>
    E #11 0x55fe3c898912 <unknown>
    E #12 0x55fe3c8b5604 <unknown>
    E #13 0x55fe3c87d74f <unknown>
    E #14 0x55fe3c8d9678 <unknown>
    E #15 0x55fe3c8d9856 <unknown>
    E #16 0x55fe3c8ea666 <unknown>
    E #17 0x7fdda00c11f5 <unknown>

    /usr/local/lib/python3.13/site-packages/selenium/webdriver/remote/errorhandler.py:232: SessionNotCreatedException
    ==================================== PASSES ====================================
    ___________ TestDockerized.test_playwright_visit_a_site_and_validate ___________
    ----------------------------- Captured stdout call -----------------------------
    Actual title = Example Domain
    ---------------- Generated html report: file:///practice-python/report.html ----------------
    =========================== short test summary info ============================
    FAILED tests/test_dockerized_tests.py::TestDockerized::test_selenium_visit_a_site_and_validate
    ========================= 1 failed in 1.28s ==========================
    Error: Process completed with exit code 1

    Continue reading...

Compartilhe esta Página