SeleniumHQ / selenium

A browser automation framework and ecosystem.
https://selenium.dev
Apache License 2.0
30.58k stars 8.17k forks source link

[πŸ› Bug]: Python 4.11.x `selenium.common.exceptions.NoSuchDriverException` Docker arm64 #12522

Closed mietzen closed 1 year ago

mietzen commented 1 year ago

What happened?

I'm running a small data scraper inside a Docker container. Recently I updated from chrome 112 and selenium 4.7.2 to chrome 115 and selenium 4.11.2.

After the upgrade I get this error (full output see below):

selenium.common.exceptions.NoSuchDriverException: Message: Unable to obtain driver for chrome using Selenium Manager.; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location

I tested:

chrome 112 chrome 115
selenium 4.7.2 βœ… βœ…
selenium 4.10.0 βœ… βœ…
selenium 4.11.0 ❌ ❌
selenium 4.11.2 ❌ ❌

How can we reproduce the issue?

All run on a RPI 4 8GB - Debian GNU/Linux 11 (bullseye) arm64

Dockerfile WORKING Chrome 112, Selenium 4.7.2

FROM python:3.11-bullseye

RUN apt-get update && apt-get install -y \
    chromium=112.0.5615.138-1~deb11u1 \
    chromium-common=112.0.5615.138-1~deb11u1 \
    chromium-driver=112.0.5615.138-1~deb11u1

RUN pip3 install selenium==4.7.2

COPY entrypoint.py /entrypoint.py

ENTRYPOINT [ "python3", "/entrypoint.py"]

Dockerfile NOT WORKING Chrome 115, Selenium 4.11.2

FROM python:3.11-bullseye

RUN apt-get update && apt-get install -y \
    chromium=115.0.5790.170-1~deb11u1 \
    chromium-common=115.0.5790.170-1~deb11u1 \
    chromium-driver=115.0.5790.170-1~deb11u1

RUN pip3 install selenium==4.11.2

COPY entrypoint.py /entrypoint.py

ENTRYPOINT [ "python3", "/entrypoint.py"]

Entrypoint:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

selenium_options = Options()
selenium_options.add_argument('--headless')
selenium_options.add_argument('--no-sandbox')
selenium_options.add_argument('--disable-gpu')
selenium_options.add_argument('--disable-dev-shm-usage')
selenium_options.add_argument("--window-size=1920,1200")

driver = webdriver.Chrome(options=selenium_options)
driver.get('https://google.com')

Docker compose:

version: '3'
services:
  selenium-test:
    build: '.'
    restart: unless-stopped

Relevant log output

$ docker-compose up
Creating chromium-115_selenium-4112_selenium-test_1 ... done
Attaching to chromium-115_selenium-4112_selenium-test_1
selenium-test_1  | Traceback (most recent call last):
selenium-test_1  |   File "/usr/local/lib/python3.11/site-packages/selenium/webdriver/common/selenium_manager.py", line 123, in run
selenium-test_1  |     completed_proc = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
selenium-test_1  |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
selenium-test_1  |   File "/usr/local/lib/python3.11/subprocess.py", line 548, in run
selenium-test_1  |     with Popen(*popenargs, **kwargs) as process:
selenium-test_1  |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^
selenium-test_1  |   File "/usr/local/lib/python3.11/subprocess.py", line 1026, in __init__
selenium-test_1  |     self._execute_child(args, executable, preexec_fn, close_fds,
selenium-test_1  |   File "/usr/local/lib/python3.11/subprocess.py", line 1950, in _execute_child
selenium-test_1  |     raise child_exception_type(errno_num, err_msg, err_filename)
selenium-test_1  | OSError: [Errno 8] Exec format error: '/usr/local/lib/python3.11/site-packages/selenium/webdriver/common/linux/selenium-manager'
selenium-test_1  |
selenium-test_1  | The above exception was the direct cause of the following exception:
selenium-test_1  |
selenium-test_1  | Traceback (most recent call last):
selenium-test_1  |   File "/usr/local/lib/python3.11/site-packages/selenium/webdriver/common/driver_finder.py", line 38, in get_path
selenium-test_1  |     path = SeleniumManager().driver_location(options) if path is None else path
selenium-test_1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
selenium-test_1  |   File "/usr/local/lib/python3.11/site-packages/selenium/webdriver/common/selenium_manager.py", line 90, in driver_location
selenium-test_1  |     output = self.run(args)
selenium-test_1  |              ^^^^^^^^^^^^^^
selenium-test_1  |   File "/usr/local/lib/python3.11/site-packages/selenium/webdriver/common/selenium_manager.py", line 129, in run
selenium-test_1  |     raise WebDriverException(f"Unsuccessful command executed: {command}") from err
selenium-test_1  | selenium.common.exceptions.WebDriverException: Message: Unsuccessful command executed: /usr/local/lib/python3.11/site-packages/selenium/webdriver/common/linux/selenium-manager --browser chrome --output json
selenium-test_1  |
selenium-test_1  |
selenium-test_1  | The above exception was the direct cause of the following exception:
selenium-test_1  |
selenium-test_1  | Traceback (most recent call last):
selenium-test_1  |   File "/entrypoint.py", line 11, in <module>
selenium-test_1  |     driver = webdriver.Chrome(options=selenium_options)
selenium-test_1  |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
selenium-test_1  |   File "/usr/local/lib/python3.11/site-packages/selenium/webdriver/chrome/webdriver.py", line 45, in __init__
selenium-test_1  |     super().__init__(
selenium-test_1  |   File "/usr/local/lib/python3.11/site-packages/selenium/webdriver/chromium/webdriver.py", line 51, in __init__
selenium-test_1  |     self.service.path = DriverFinder.get_path(self.service, options)
selenium-test_1  |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
selenium-test_1  |   File "/usr/local/lib/python3.11/site-packages/selenium/webdriver/common/driver_finder.py", line 41, in get_path
selenium-test_1  |     raise NoSuchDriverException(msg) from err
selenium-test_1  | selenium.common.exceptions.NoSuchDriverException: Message: Unable to obtain driver for chrome using Selenium Manager.; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location
selenium-test_1  |

Operating System

Debian GNU/Linux 11 (bullseye) arm64

Selenium version

Python 4.11.2

What are the browser(s) and version(s) where you see this issue?

chromium=115.0.5790.170-1~deb11u1

What are the browser driver(s) and version(s) where you see this issue?

chromium-driver=115.0.5790.170-1~deb11u1

Are you using Selenium Grid?

No response

github-actions[bot] commented 1 year ago

@mietzen, thank you for creating this issue. We will troubleshoot it as soon as we can.


Info for maintainers

Triage this issue by using labels.

If information is missing, add a helpful comment and then I-issue-template label.

If the issue is a question, add the I-question label.

If the issue is valid but there is no time to troubleshoot it, consider adding the help wanted label.

If the issue requires changes or fixes from an external project (e.g., ChromeDriver, GeckoDriver, MSEdgeDriver, W3C), add the applicable G-* label, and it will provide the correct link and auto-close the issue.

After troubleshooting the issue, please add the R-awaiting answer label.

Thank you!

titusfortner commented 1 year ago

Yes, selenium manager is assuming chrome and not chromium right now. We're going to fix it for the next release. In the meantime, if you set the binary location in the chrome options class it should do the right thing.

bhawna0612 commented 1 year ago

I am also having the same issue when trying to run the Selenium Python Script from TeamCity.

Updated the Selenium to 4.11.2 and the browser version is 115+

image

ilyadesyatov commented 1 year ago

have same problem in rails (macOS CPU-Intel) selenium-webdriver-4.11.0

with selenium-webdriver-4.10.0 all work fine but gem selenium-webdriver not have version 4.11.2

driver = Selenium::WebDriver.for :chrome
2023-08-10 23:04:50 INFO Selenium [:logger_info] Details on how to use and modify Selenium logger:
  https://selenium.dev/documentation/webdriver/troubleshooting/logging

2023-08-10 23:04:50 DEBUG Selenium [:selenium_manager] Selenium Manager binary found at /Users/ilya/.rvm/gems/ruby-3.1.4@t/gems/selenium-webdriver-4.11.0/bin/macos/selenium-manager 
2023-08-10 23:04:50 DEBUG Selenium [:selenium_manager] Executing Process ["/Users/ilya/.rvm/gems/ruby-3.1.4@t/gems/selenium-webdriver-4.11.0/bin/macos/selenium-manager", "--browser", "chrome", "--output", "json", "--debug"] 
Selenium::WebDriver::Error::NoSuchDriverError: Unable to obtain chromedriver using Selenium Manager; Unsuccessful command executed: ["/Users/ilya/.rvm/gems/ruby-3.1.4@t/gems/selenium-webdriver-4.11.0/bin/macos/selenium-manager", "--browser", "chrome", "--output", "json", "--debug"]; undefined method `[]' for nil:NilClass

            result = json_output['result']
                                ^^^^^^^^^^; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location
from /Users/ilya/.rvm/gems/ruby-3.1.4@t/gems/selenium-webdriver-4.11.0/lib/selenium/webdriver/common/driver_finder.rb:30:in `rescue in path'
Caused by Selenium::WebDriver::Error::WebDriverError: Unsuccessful command executed: ["/Users/ilya/.rvm/gems/ruby-3.1.4@t/gems/selenium-webdriver-4.11.0/bin/macos/selenium-manager", "--browser", "chrome", "--output", "json", "--debug"]; undefined method `[]' for nil:NilClass

            result = json_output['result']
                                ^^^^^^^^^^
from /Users/ilya/.rvm/gems/ruby-3.1.4@t/gems/selenium-webdriver-4.11.0/lib/selenium/webdriver/common/selenium_manager.rb:114:in `rescue in run'
Caused by NoMethodError: undefined method `[]' for nil:NilClass

            result = json_output['result']
                                ^^^^^^^^^^
from /Users/ilya/.rvm/gems/ruby-3.1.4@t/gems/selenium-webdriver-4.11.0/lib/selenium/webdriver/common/selenium_manager.rb:112:in `run'
titusfortner commented 1 year ago

@bhawna0612 what is the code you are executing to get that result?

@ilyadesyatov there is a bug preventing Ruby from logging the output of Selenium Manager. I can't tell right now why it isn't working, we need to wait for the next release to investigate. It's also possible that one of the many bug fixes to Selenium Manager has fixed it. Hoping to have a release "soon"

bhawna0612 commented 1 year ago

@titusfortner sorry I was out of town.

I am just running login using Pytest framework through Teamcity. Chrome browser is downloaded. But I didn't download any binaries or chromedriver executable file. I am assuming that if it is not downloaded, selenium will take care of it after version 4.6.0. My Selenium version is 4.11.2 and Chrome browser is 115+

Below is my login method


        self.driver.get(url)
        self.enter_clientID(clientID)
        self.enter_username(username)
        self.enter_password(password)
        self.click_login_button()```

The driver is initialized in the fixture

```pytest.fixture(scope='session')
def driverObject(request):
    global driver
    sys.path.insert(0, os.getcwd())
    browser = option.browser
    if browser in 'firefox':
        driver = webdriver.Firefox()
    else:
        options = webdriver.ChromeOptions()
        logging_prefs = {'browser': 'ALL'}
        options.add_experimental_option('w3c', False)
        options.add_experimental_option('goog:loggingPrefs', logging_prefs)
        options.add_experimental_option('excludeSwitches', ['enable-logging'])
        driver = webdriver.Chrome(options=options)
        driver.get_log('browser')
    driver.maximize_window()
    driver.implicitly_wait(60)
    config = yaml.safe_load(open('config/config.yml'))
    logFolder = f"./failure_log/{runTime}"
    return driver, config, logFolder```

ANd here I am calling the login method

```def test_valid_login(driverObject):
    driver, config, logFolder = driverObject
    try:
        url = config['URL']
        clientId = config['clientID']
        username = config['username']
        password = config['password']
        app = config['app']
        logs = driver.get_log("browser")
        for log in logs:
            print(f"{log['DEBUG']}: {log['message']}")
        login(driver, url, clientId, username, password, app)```
titusfortner commented 1 year ago

@bhawna0612 to double check are you running Linux Docker container on arm64 architecture?

bhawna0612 commented 1 year ago

@titusfortner No I am not running via Docker. These tests are running on a Windows environment

titusfortner commented 1 year ago

Then this bug is not your bug, and we need to handle it separately.

Same with @ilyadesyatov

The issue with Docker/Linux/Arm is that there is no chromedriver for selenium to manage. The question is whether Linux selenium manager can parse the version of chromium and locate the previously downloaded driver on PATH or if the user needs to specify the location in the service clasd to bypass selenium manager entirely.

bhawna0612 commented 1 year ago

@titusfortner This is the command I am running in the Teamcity to check the version of Chrome and Chromedriver version. Chrome version is 116 and but because chromedriver was not downloaded, so system doesn't recognize it

image

and I am getting the below result


[15:10:22 ]Starting: C:\BuildAgent\temp\agentTmp\custom_script17020972792163744888.cmd
[15:10:22 ] in directory: C:\BuildAgent\work\c7087d58c8f595f4
[15:10:22 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Google Chrome
[15:10:22 ]     DisplayName    REG_SZ    Google Chrome
[15:10:22 ]UninstallString    REG_SZ    "C:\Program Files\Google\Chrome\Application\116.0.5845.97\Installer\setup.exe" --uninstall --channel=stable --system-level --verbose-logging
[15:10:22 ]      InstallLocation    REG_SZ    C:\Program Files\Google\Chrome\Application
[15:10:22 ]      DisplayIcon    REG_SZ    C:\Program Files\Google\Chrome\Application\chrome.exe,0
[15:10:22 ]      NoModify    REG_DWORD    0x1
[15:10:22 ]      NoRepair    REG_DWORD    0x1
[15:10:22 ]      Publisher    REG_SZ    Google LLC
[15:10:22 ]      Version    REG_SZ    116.0.5845.97
[15:10:22 ]      DisplayVersion    REG_SZ    116.0.5845.97
[15:10:22 ]      InstallDate    REG_SZ    20230822
[15:10:22 ]     VersionMajor    REG_DWORD    0x16d5
[15:10:22 ]     VersionMinor    REG_DWORD    0x61
[15:10:22 ]      sEstimatedSize2    REG_DWORD    0x0
[15:10:22 ]      EstimatedSize    REG_DWORD    0x9af7a
[15:10:22 ] 
[15:10:22 ]  'chromedriver' is not recognized as an internal or external command,
[15:10:22 ]  operable program or batch file.
diemol commented 1 year ago

Yes, selenium manager is assuming chrome and not chromium right now. We're going to fix it for the next release. In the meantime, if you set the binary location in the chrome options class it should do the right thing.

I just wanted to let you know that I am closing this because the original report has the workaround mentioned above. The next version, 4.13.0, is coming soon and will also help.

For all the other folks who are still having an issue, please open a new bug report and fill out all the information, including logging https://www.selenium.dev/documentation/webdriver/troubleshooting/logging/

titusfortner commented 1 year ago

fwiw, I'm not sure that workaround is sufficient for Linux/ARM. It's possible the binary we have will do something, but maybe not.

diemol commented 1 year ago

I believe the binary they are using for ChromeDriver is a community-generated one for ARM, so it should still work.

titusfortner commented 1 year ago

But it has to be put on PATH and I'm not sure our Linux Selenium Manager on ARM can execute and find it? I don't have ARM to test a VM of it.

titusfortner commented 1 year ago

Alternative is for user to specify it in Service class so we may want to be explicit about that limitation somewhere in our docs

mietzen commented 1 year ago

Yes, selenium manager is assuming chrome and not chromium right now. We're going to fix it for the next release. In the meantime, if you set the binary location in the chrome options class it should do the right thing.

I just wanted to let you know that I am closing this because the original report has the workaround mentioned above. The next version, 4.13.0, is coming soon and will also help.

For all the other folks who are still having an issue, please open a new bug report and fill out all the information, including logging https://www.selenium.dev/documentation/webdriver/troubleshooting/logging/

@diemol So whats the workaround exactly? Using 4.10?

I find it a bit uncommon to close a issue with the promise that the next version is coming soon, is there already a commit with a fix?

titusfortner commented 1 year ago

The purpose of this issue tracker is to keep track of the work we need to do. If we've done the work, we can close it. If the next version does not work as we hope, please let us know and we can re-open.

diemol commented 1 year ago

Either 4.10 or 4.11 and setting the binary location.

mietzen commented 1 year ago

@titusfortner This Error is still present in 4.12

titusfortner commented 1 year ago

Ah, Chromium was fixed, but arm64 was not.

I'm adding a note to our documentation describing the situation: https://github.com/SeleniumHQ/seleniumhq.github.io/pull/1471

mietzen commented 1 year ago

Ah, Chromium was fixed, but arm64 was not.

I'm adding a note to our documentation describing the situation: SeleniumHQ/seleniumhq.github.io#1471

Could you explain why it's not working? And Point to the line of code where it breaks? As I understood it Selenium <= 4.10 searched the PATH for chromedriver and used that one. After since 4.11 Selenium tries to load the matching chromedriver from the internet. Does it fail because there is no official arm64 chromedriver? Is there no Fallback to look on the PATH like in Selenium <= 4.10?

I'm just trying to understand what's the Issue.

titusfortner commented 1 year ago

Selenium manager is looking on path instead of the bindings. So if you can't use the binary, putting them on PATH won't work.

github-actions[bot] commented 10 months ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.