Skip to content

[🐛 Bug]: Python - not shutting down Firefox/Geckodriver when service gets garbage collected #15399

Open
@cgoldberg

Description

@cgoldberg

What happened?

(this issue is kind of long, but this behavior has been driving me crazy and I needed to document it so hopefully we can fix it)

Expected behavior:

When a Python script completes, Firefox and Geckodriver processes are terminated.

Actual behavior:

When a Python script completes, Firefox and Geckodriver processes are still running.

Why should they not be running?

Normally, you would launch Firefox by calling driver = webdriver.Firefox(). Once launched, you can call driver.quit() to stop Firefox and Geckodriver. This works fine.

Alternately, you can launch Firefox by first creating a service = webdriver.firefox.service.Service() instance and using that when calling driver = webdriver.Firefox(service=service). After that, you can stop the service with service.stop(). This should stop the Geckodriver process from running. This works fine.

However, if you launch Firefox, then let your script end, the underlying service object gets destroyed during garbage collection and its __del__ method gets called. Inside service.__del__() is a call to service.stop(), which should stop the service and kill Geckodriver. For some reason, this isn't working and it leaves Firefox open and a geckodriver process running.

Firefox/Geckodriver behaves different than other browsers/drivers:

This is most noticeable by the difference in how Firefox behaves compared to other browsers.

For example, run the following code in a Python script (this won't be reproducible from an interactive interpreter, so make sure you create a script and call it from the command line):

from selenium import webdriver
driver = webdriver.Firefox()

After this script completes, you will notice Firefox is still visible and a geckodriver process is active:

$ ps | grep geckodriver
31328 pts/2    00:00:00 geckodriver
$

Now compare that to Chrome:

from selenium import webdriver
driver = webdriver.Chrome()

After this script completes, Chrome closes and and no chromedriver process is active:

$ ps | grep chromedriver
$

I think the Chrome behavior is correct and the Firefox is not.

This is most likely happening somewhere in py/selenium/webdriver/common/service.py ... but I've been through the code and can't figure out why Firefox isn't properly terminated. It would be great to figure this out and have consistent behavior across all browsers/drivers.

How can we reproduce the issue?

from selenium import webdriver
driver = webdriver.Firefox()

Relevant log output

DEBUG:selenium.webdriver.common.selenium_manager:Selenium Manager binary found at: /home/cgoldberg617/code/selenium/py/selenium/webdriver/common/linux/selenium-manager
DEBUG:selenium.webdriver.common.selenium_manager:Executing process: /home/cgoldberg617/code/selenium/py/selenium/webdriver/common/linux/selenium-manager --browser firefox --debug --language-binding python --output json
DEBUG:selenium.webdriver.common.selenium_manager:Sending stats to Plausible: Props { browser: "firefox", browser_version: "", os: "linux", arch: "x86_64", lang: "python", selenium_version: "4.29" }
DEBUG:selenium.webdriver.common.selenium_manager:geckodriver not found in PATH
DEBUG:selenium.webdriver.common.selenium_manager:firefox not found in PATH
DEBUG:selenium.webdriver.common.selenium_manager:firefox not found in the system
DEBUG:selenium.webdriver.common.selenium_manager:Required browser: firefox 136.0
DEBUG:selenium.webdriver.common.selenium_manager:firefox 136.0 already exists
DEBUG:selenium.webdriver.common.selenium_manager:firefox 136.0 is available at /home/cgoldberg617/.cache/selenium/firefox/linux64/136.0/firefox
DEBUG:selenium.webdriver.common.selenium_manager:Valid geckodriver versions for firefox 136: ["0.36.0", "0.35.0", "0.34.0"]
DEBUG:selenium.webdriver.common.selenium_manager:Required driver: geckodriver 0.36.0
DEBUG:selenium.webdriver.common.selenium_manager:geckodriver 0.36.0 already in the cache
DEBUG:selenium.webdriver.common.selenium_manager:Driver path: /home/cgoldberg617/.cache/selenium/geckodriver/linux64/0.36.0/geckodriver
DEBUG:selenium.webdriver.common.selenium_manager:Browser path: /home/cgoldberg617/.cache/selenium/firefox/linux64/136.0/firefox
DEBUG:selenium.webdriver.common.service:Started executable: `/home/cgoldberg617/.cache/selenium/geckodriver/linux64/0.36.0/geckodriver` in a child process with pid: 31845 using 0 to output -3
DEBUG:selenium.webdriver.remote.remote_connection:POST http://localhost:39093/session {'capabilities': {'firstMatch': [{}], 'alwaysMatch': {'browserName': 'firefox', 'acceptInsecureCerts': True, 'moz:debuggerAddress': True, 'pageLoadStrategy': <PageLoadStrategy.normal: 'normal'>, 'browserVersion': None, 'moz:firefoxOptions': {'binary': '/home/cgoldberg617/.cache/selenium/firefox/linux64/136.0/firefox', 'prefs': {'remote.active-protocols': 3}}}}}
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): localhost:39093
DEBUG:urllib3.connectionpool:http://localhost:39093 "POST /session HTTP/1.1" 200 0
DEBUG:selenium.webdriver.remote.remote_connection:Remote response: status=200 | data={"value":{"sessionId":"69af9487-5782-433a-9cdb-ce8b764d5c4a","capabilities":{"acceptInsecureCerts":true,"browserName":"firefox","browserVersion":"136.0","moz:accessibilityChecks":false,"moz:buildID":"20250227124745","moz:debuggerAddress":"127.0.0.1:59767","moz:geckodriverVersion":"0.36.0","moz:headless":false,"moz:platformVersion":"6.6.65-06377-gaae6fc9ba7df","moz:processID":31848,"moz:profile":"/tmp/rust_mozprofileoDQJGh","moz:shutdownTimeout":60000,"moz:webdriverClick":true,"moz:windowless":false,"pageLoadStrategy":"normal","platformName":"linux","proxy":{},"setWindowRect":true,"strictFileInteractability":false,"timeouts":{"implicit":0,"pageLoad":300000,"script":30000},"unhandledPromptBehavior":"dismiss and notify","userAgent":"Mozilla/5.0 (X11; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0"}}} | headers=HTTPHeaderDict({'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-cache', 'content-length': '814', 'date': 'Mon, 10 Mar 2025 22:10:51 GMT'})
DEBUG:selenium.webdriver.remote.remote_connection:Finished Request

Operating System

Linux (Debian Stable)

Selenium version

Python Selenium 4.30

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

Firefox 136.0 (64-bit)

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

Geckodriver 0.36.0

Are you using Selenium Grid?

No

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-pyPython BindingsI-defectSomething is not working as intended

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions