mozilla / geckodriver

WebDriver for Firefox
https://firefox-source-docs.mozilla.org/testing/geckodriver/
Mozilla Public License 2.0
7.03k stars 1.51k forks source link

Firefox is already running, but is not responding. The old Firefox process must be closed to open a new window. #2179

Closed MagdelineNg closed 1 month ago

MagdelineNg commented 1 month ago

System

Testcase

import configparser
import os

web_driver = selenium_webdriver.Firefox(executable_path='C:\\Users\\mnxl\\.wdm\\drivers\\geckodriver\\win64\\v0.34.0\\geckodriver')
profile = web_driver.capabilities['moz:profile']

Path to the Firefox profiles folder
profiles_path = os.path.expanduser(r'~\AppData\Roaming\Mozilla\Firefox')

Path to the profiles.ini file
profiles_ini_path = os.path.join(profiles_path, 'profiles.ini')

Read the profiles.ini file
config = configparser.ConfigParser()
config.read(profiles_ini_path)

Find the section for the profile to set as default
for section in config.sections():

   if config.has_option(section, 'Path') and config.get(section, 'Path') == profile:
       # Set this profile as the default
       config.set(section, 'Default', '1')
   else:
       # Set all other profiles as not default
       config.set(section, 'Default', '0')
Write the changes back to the profiles.ini file
with open(profiles_ini_path, 'w') as configfile:

   config.write(configfile)

Stacktrace

1714986617679 geckodriver INFO Listening on 127.0.0.1:64390 1714986620687 mozrunner::runner INFO Running command: "C:\Program Files\Mozilla Firefox\firefox.exe" "--marionette" "-profile" "C:\Users\ngm1admin\AppData\Roaming\Mozilla\Firefox\Profiles\4qeq4qz4.Default" "-no-remote" Read port: 55353 console.warn: services.settings: Ignoring preference override of remote settings server console.warn: services.settings: Allow by setting MOZ_REMOTE_SETTINGS_DEVTOOLS=1 in the environment 1714986621150 Marionette INFO Marionette enabled 1714986621195 Marionette INFO Listening on port 64403 Read port: 64403 1714986622852 RemoteAgent WARN TLS certificate errors will be ignored for this session JavaScript warning: resource://gre/modules/Troubleshoot.sys.mjs, line 759: WebGL context was lost. JavaScript warning: resource://gre/modules/Troubleshoot.sys.mjs, line 726: WebGL warning: : AllowWebgl2:false restricts context creation on this system. JavaScript warning: resource://gre/modules/Troubleshoot.sys.mjs, line 726: Failed to create WebGL context: WebGL creation failed:

Receiving this error: Firefox is already running, but is not responding. The old Firefox process must be closed to open a new window.

My desktop app redirects user to a login screen on Firefox, and I want to automate it using Selenium. My current workflow:

  1. Launch Selenium-controlled Firefox browser using GeckoDriver
  2. Click on "Login" button on my desktop app. The desktop app launches the login screen on user's OS default browser using the default user profile (in which case I set in profiles.ini to the temp profile copy created by Selenium).
  3. (ERROR) Popup on the above error is displayed
whimboo commented 1 month ago

Could you please attach a trace-level log from geckodriver? Read more about reporting actionable bugs in our contribution guidelines.

MagdelineNg commented 1 month ago

I have updated the stracktrace @whimboo . I am also receiving this

image
whimboo commented 1 month ago

The first launch of Firefox somehow failed and maybe these WebGL warnings indicate a problem. After that Firefox gets started a second time and not Marionette runs successfully. I'm not sure why its failing first and why it's started a 2nd time. The code above doesn't indicate that. Also the profile manager dialog should never be seen given that geckodriver doesn't make use of the -P argument of Firefox. So something else might come into play here.

MagdelineNg commented 1 month ago

@whimboo I am adding the new user profile selenium creates into profiles.ini, and I launch my desktop app manually after running the code above. Reason for updating profiles.ini is that my desktop app follows the user's default browser settings and user profile to redirect user to the login url screen. However, I receive the "Firefox - Choose User Profile" upon launching my app

whimboo commented 1 month ago

If you are launching Firefox manually with more than a profile available then you will indeed get the profile manager shown. There you will have to select the newly created / added profile. Is this window empty? If yes, then check the updated profiles.ini if entries are correctly set. Otherwise the UI might not list any profiles.

Further you most likely need the -remote argument when launching Firefox, or you have to set the MOZ_NO_REMOTE=1` environment variable to indicate Firefox to not re-use an already open Firefox instance.

MagdelineNg commented 1 month ago

@whimboo Should I be removing the -no-remoteand -new-instance arguments, as they seem to be added by default by FirefoxOptions(). I want to ensure my new login url screen opens in the existing Firefox instance, does that mean "reusing the same Firefox instance" for my use case?

I understand Selenium creates a user profile (for example, C:\Users\mnxl\AppData\Local\Temp\rust_mozprofileXXbpxK), which I get from my code in web_driver.capabilities['moz:profile'] and set it as default in profiles.ini , so that my desktop app can launch the login url in the Selenium-controlled browser.

Here is my profiles.ini (I make sure to delete Profile1 after running the code above every time so there are no duplicate profiles):

[Install308046B0AF4A39CB]
default = 0
locked = 1
Default=Profiles/982casda.Default
Locked=1

[Profile1]
name = NewProfile
isrelative = 1
path = C:\Users\mnxl\AppData\Roaming\Mozilla\Firefox\Profiles\4qeq4qz4.Default
default = 1

[Profile0]
Name=Default
IsRelative=1
Path=Profiles/982casda.Default

[General]
startwithlastprofile = 0
version = 2
default = 0
Version=2

[BackgroundTasksProfiles]
mozillabackgroundtask-308046b0af4a39cb-defaultagent = 9jdb6ygt.MozillaBackgroundTask-308046B0AF4A39CB-defaultagent
mozillabackgroundtask-308046b0af4a39cb-backgroundupdate = 4n7ck25n.MozillaBackgroundTask-308046B0AF4A39CB-backgroundupdate
default = 0

Is this a possible approach to ensure my login url is launched in the existing firefox instance that I start with selenium webdriver?

Update: I removed -no-remote manually from the command and ran it to launch the Firefox browser like so "C:\\Program Files\\Mozilla Firefox\\firefox.exe" "--marionette" "-profile" C:\Users\NGM1AD~1\AppData\Local\Temp\rust_mozprofileRGuu0Q and my app was able to detect it. My question is, is it possible to remove the -no-remote from the code below?

binary = FirefoxBinary(r"C:\Program Files\Mozilla Firefox\firefox.exe")
browser_options = FirefoxOptions()
browser_options.log.level = "trace"
os.environ['MOZ_NO_REMOTE'] = '0'   #does not work

web_driver = selenium_webdriver.Firefox(options=browser_options, firefox_binary=binary, executable_path=GeckoDriverManager().install())

Here is the browser options (that I believe is set by selenium webdriver by default) since it's not in the code:

image
whimboo commented 1 month ago

It's still not clear to me how the order of steps are. You said that you are using the script and geckodriver to create a Firefox profile that you are using manually afterward. But now it's about connecting to an existing Firefox instance. Note that you cannot replace the underying profile while Firefox is running. Also I do not know how well Selenium actually supports this use case. Usually automation or tests create their own Firefox instance.

whimboo commented 1 month ago

No further feedback from reporter. As such I'm going to close this issue.