teodesian / Selenium-Remote-Driver

Perl Bindings to the Selenium Webdriver server
174 stars 90 forks source link

Starting with a dedicated Firefox profile doesn't work #444

Open inpbox opened 4 years ago

inpbox commented 4 years ago

--- Summary: ---

--- Environment: ---

--- Code to launch with a dedicated Firefox-profile: ---

use 5.018;
use Selenium::Firefox::Profile;
use Selenium::Firefox;

my $driver = Selenium::Firefox->new(
    'firefox_profile' => Selenium::Firefox::Profile->new(
        'profile_dir'=>'/path/to/firefox/profile'
    )
);

$driver->get('https://www.mozilla.org');
say $driver->get_title();
sleep(60); # Just to get time to run the ps and look for the Firefox-entry

--- Run code, verify profile being used from ps: ---

The firefox-entry should pop up:

inpbox commented 4 years ago

Could this problem be related to the same issue this user is experiencing:

or it could be related to this:

inpbox commented 4 years ago

--- This code will launch a dedicated profile ---

my $url = ''; my $profile_dir = ''; my $binary_port = ''; my $sleep = 0; GetOptions( 'url=s' => \$url, 'profile=s' => \$profile_dir, 'port=i' => \$binary_port, 'sleep:i' => \$sleep, );

my $driver = Selenium::Firefox->new( 'extra_capabilities' => { 'moz:firefoxOptions' => { 'args' => ['-profile',$profile_dir], } }, 'binary_port' => $binary_port, 'fixed_ports' => 1, );

$driver->get($url); say $driver->get_title(); sleep($sleep);


--- Issues ---
This way of launching has other issues. You can't launch **multiple profiles**. Trying to launch a second profile will just result in an error.
* `perl launch_ff_profile.pl -port=6061 -sleep=5 -profile='/path/to/firefox/second_profile' -url='https://www.chrome.com'`

Could not create new session: invalid argument: can't kill an exited process



I'm guessing this error comes from trying to use the same default marionette-port (2828) as the already launched browser. But using arg: **marionette_port** doesn't work either.

Trying to launch with a **marionette_port** will start the browser but no communication between the client and server occurs!
inpbox commented 4 years ago

--- Trying to get the marionette port to be sent to the geckodriver ---

Problem we're trying to solve: geckodriver needs to be passed the correct marionette-port to be able to communicate with Firefox

--- Try 1, set port through prefs - No go ---

my $driver = Selenium::Firefox->new(
    'extra_capabilities' => {
        'moz:firefoxOptions' => {
            'args'  => ['-profile',$profile_dir],
            'prefs' => {'marionette.port' => $marionette_port}
        }
    },
    'binary_port'     => $binary_port,
    'marionette_port' => $marionette_port,
    'fixed_ports'     => 1,
);

--- Try 2, set the marionette-port directly in the profile - Works! ---

Modify file: /path/to/firefox/profile/user.js file for the profile you want to use and add:

This works!

Both profiles should be able to launch at the same time, provided that you have set the port-number in each user.js file:

--- Run-it ---

--- Code example ---

use 5.018;
use Getopt::Long;
use Selenium::Firefox;

my $url             = '';
my $profile_dir     = '';
my $binary_port     = '';
my $marionette_port = '';
my $sleep           = 0;
GetOptions(
    'url=s'         => \$url,
    'profile=s'     => \$profile_dir,
    'port=i'        => \$binary_port,
    'marionette=i'  => \$marionette_port,
    'sleep:i'       => \$sleep,
);

my $driver = Selenium::Firefox->new(
    'extra_capabilities' => {
        'moz:firefoxOptions' => {
            'args'  => ['-profile',$profile_dir],
        }
    },
    'marionette_port' => $marionette_port,
    'binary_port'     => $binary_port,
    'fixed_ports'     => 1,
);

$driver->get($url);
say $driver->get_title();
sleep($sleep);

--- Conclusion ---

Try 2 works, for multiple profiles, but requires that you go into each profile and set the marionette-port you want to use. When running a specific profile you would also have to remember the correct port-number since it's now fixed.

inpbox commented 4 years ago

See, this thread, could this be the whole problem with the marionette-port?

Looks like:

Selenium::Firefox::Profile::add_marionette uses defaultPrefs.port

https://metacpan.org/source/Selenium::Firefox::Profile

sub add_marionette {
    my ( $self, $port ) = @_;
    return if !$port;
    $self->set_preference( 'marionette.defaultPrefs.port', $port );
}
hornschorsch commented 4 years ago

Its a bug in geckodriver which they are not able to fix since two years: https://bugzilla.mozilla.org/show_bug.cgi?id=1421766

inpbox commented 4 years ago

Ouch, gone from a P1 to P3-issue. Hope they implement your patch.

teodesian commented 4 years ago

So, should I close this issue since it's clearly an upstream problem, or should I try to work around this as suggested by inpbox and provide marionette.port?

inpbox commented 4 years ago

The problem with the geckodriver/marionette-port is clearly an upstream problem. But why does this code create a tmp-profile:

my $driver = Selenium::Firefox->new(
    'firefox_profile' => Selenium::Firefox::Profile->new(
        'profile_dir'=>'/path/to/firefox/profile'
    )
);

when this doesn't:

my $driver = Selenium::Firefox->new(
    'extra_capabilities' => {
        'moz:firefoxOptions' => {
            'args'  => ['-profile','/path/to/firefox/profile'],
        }
    }
);

Shouldn't they both launch the dedicated profile?

teodesian commented 4 years ago

You would hope so. Sounds like you are on to something there, I'll look at a patch as soon as I can.

hornschorsch commented 4 years ago

I believe the first example creates a temporary profile from the given directory while the second example actually uses the given directory as profile.

pabloneruda1 commented 4 years ago

Any solution or how can I save settings for temporary profile?? It is really annoying...

Okahoux commented 4 years ago

@pabloneruda1

Please, look at the solution I posted here : https://stackoverflow.com/a/63247874/10912110