Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Selenium Firefox geckodriver. Detach browser from terminal

With Chrome (chromedriver) it's very simple:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_experimental_option('detach', True)

With Firefox (geckodriver) no:

from selenium import webdriver
from selenium.webdriver.firefox.options import Options
options = Options()
options.add_experimental_option('detach', True)  # Returns syntax error

What is the equivalent syntax for leaving the Firefox browser open even when the script ends?

like image 952
Mario Palumbo Avatar asked Apr 06 '26 18:04

Mario Palumbo


2 Answers

The underlying structure of Chrome (chromedriver) and Firefox (geckodriver) are different.

For example the add_experimental_option exists in chromedriver enter image description here

This add_experimental_option does not exist in geckodriver, so that is why you are getting an error.

enter image description here

I have looked through various geckodriver documents and haven't seen a reference similar to this one from chromedriver.

enter image description here

Please note the options_spec.rb code below is from the Ruby source code for selenium.

The code below is from the file options_spec.rb, which is part of the selenium source code for chromedriver. Note the detach: true in the dictionary.

opts = Options.new(browser_version: '75',
                   platform_name: 'win10',
                   accept_insecure_certs: false,
                   page_load_strategy: 'eager',
                   unhandled_prompt_behavior: 'accept',
                   strict_file_interactability: true,
                   timeouts: {script: 40000,
                              page_load: 400000,
                              implicit: 1},
                   set_window_rect: false,
                   args: %w[foo bar],
                   prefs: {foo: 'bar'},
                   binary: '/foo/bar',
                   extensions: ['foo.crx', 'bar.crx'],
                   encoded_extensions: ['encoded_foobar'],
                   foo: 'bar',
                   emulation: {device_name: :bar},
                   local_state: {foo: 'bar'},
                   detach: true,
                   debugger_address: '127.0.0.1:8181',
                   exclude_switches: %w[foobar barfoo],
                   minidump_path: 'linux/only',
                   perf_logging_prefs: {enable_network: true},
                   window_types: %w[normal devtools],
                   'custom:options': {foo: 'bar'})

The code below is from the file options_spec.rb, which is part of the selenium source code for geckodriver. Note there is no detach: true in the dictionary.

opts = Options.new(browser_version: '66',
                   platform_name: 'win10',
                   accept_insecure_certs: false,
                   page_load_strategy: 'eager',
                   unhandled_prompt_behavior: 'accept',
                   strict_file_interactability: true,
                   timeouts: {script: 40000,
                              page_load: 400000,
                              implicit: 1},
                   set_window_rect: false,
                   args: %w[foo bar],
                   binary: '/foo/bar',
                   prefs: {foo: 'bar'},
                   foo: 'bar',
                   profile: profile,
                   log_level: :debug,
                   'custom:options': {foo: 'bar'})

The code below is from the file options_spec.rb, which is part of the selenium source code for edgedriver. Note there is a detach: true in the dictionary.

opts = Options.new(browser_version: '75',
                   platform_name: 'win10',
                   accept_insecure_certs: false,
                   page_load_strategy: 'eager',
                   unhandled_prompt_behavior: 'accept',
                   strict_file_interactability: true,
                   timeouts: {script: 40000,
                              page_load: 400000,
                              implicit: 1},
                   set_window_rect: false,
                   args: %w[foo bar],
                   prefs: {foo: 'bar'},
                   binary: '/foo/bar',
                   extensions: ['foo.crx', 'bar.crx'],
                   encoded_extensions: ['encoded_foobar'],
                   foo: 'bar',
                   emulation: {device_name: :bar},
                   local_state: {foo: 'bar'},
                   detach: true,
                   debugger_address: '127.0.0.1:8181',
                   exclude_switches: %w[foobar barfoo],
                   minidump_path: 'linux/only',
                   perf_logging_prefs: {enable_network: true},
                   window_types: %w[normal devtools],
                   'custom:options': {foo: 'bar'})

Based on the dictionaries in these 3 option files, one would assume that {'detach': True} isn't an option in the geckodriver.

The options.py for the geckodriver in the Python selenium structure is different than the Ruby file options_spec.rb.

def preferences(self) -> dict:
       """:Returns: A dict of preferences."""
       return self._preferences

def set_preference(self, name: str, value: Union[str, int, bool]):
       """Sets a preference."""
       self._preferences[name] = value

When looking through the source code for the Python geckodriver in Mozilla's gecko-dev GitHub repository I saw that I could query pre-defined preferences and capabilities.

from selenium.webdriver.firefox.options import Options
firefox_options = Options()

print(firefox_options.arguments)
# output
['--test-type', '--ignore-certificate-errors', '--disable-infobars', '--disable-extensions', '--disable-popup-blocking']

print(firefox_options.capabilities)
# output
{'browserName': 'firefox', 'marionette': True, 'acceptInsecureCerts': True}

print(firefox_options.preferences)
# output
{'detach': True}

So {'detach': True} is an option in the geckodriver, so you should be able to set the option this way:

firefox_options.set_preference('detach', True)
like image 171
Life is complex Avatar answered Apr 08 '26 08:04

Life is complex


If you never call driver.close(), the browser window will stay open and you can examine/use it however you like. Have you tried this?

like image 24
C. Peck Avatar answered Apr 08 '26 06:04

C. Peck