The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Selenium::CanStartBinary - Teach a WebDriver how to start its own binary aka no JRE!

VERSION

version 1.19

SYNOPSIS

    package My::Selenium::Chrome {
        use Moo;
        extends 'Selenium::Remote::Driver';

        has 'binary' => ( is => 'ro', default => 'chromedriver' );
        has 'binary_port' => ( is => 'ro', default => 9515 );
        has '_binary_args' => ( is => 'ro', default => sub {
            return ' --port=' . shift->port . ' --url-base=wd/hub ';
        });
        with 'Selenium::CanStartBinary';
        1
    };

    my $chrome_via_binary = My::Selenium::Chrome->new;
    my $chrome_with_path  = My::Selenium::Chrome->new(
        binary => './chromedriver'
    );

DESCRIPTION

This role takes care of the details for starting up a Webdriver instance. It does not do any downloading or installation of any sort - you're still responsible for obtaining and installing the necessary binaries into your $PATH for this role to find. You may be interested in Selenium::Chrome, Selenium::Firefox, or Selenium::PhantomJS if you're looking for classes that already consume this role.

The role determines whether or not it should try to do its own magic based on whether the consuming class is instantiated with a remote_server_addr and/or port.

    # We'll start up the Chrome binary for you
    my $chrome_via_binary = Selenium::Chrome->new;

    # Look for a selenium server running on 4444.
    my $chrome_via_server = Selenium::Chrome->new( port => 4444 );

If they're missing, we assume the user wants to use a webdriver directly and act accordingly. We handle finding the proper associated binary (or you can specify it with "binary"), figuring out what arguments it wants, setting up any necessary environments, and starting up the binary.

There's a number of TODOs left over - namely Windows support is severely lacking, and we're pretty naive when we attempt to locate the executables on our own.

In the following documentation, required refers to when you're consuming the role, not the required when you're instantiating a class that has already consumed the role.

ATTRIBUTES

binary

Required: Specify the path to the executable in question, or the name of the executable for us to find via "which" in File::Which.

binary_port

Required: Specify a default port that for the webdriver binary to try to bind to. If that port is unavailable, we'll probe above that port until we find a valid one.

_binary_args

Required: Specify the arguments that the particular binary needs in order to start up correctly. In particular, you may need to tell the binary about the proper port when we start it up, or that it should use a particular prefix to match up with the behavior of the Remote Driver server.

If your binary doesn't need any arguments, just have the default be an empty string.

port

The role will attempt to determine the proper port for us. Consuming roles should set a default port in "binary_port" at which we will begin searching for an open port.

Note that if we cannot locate a suitable "binary", port will be set to 4444 so we can attempt to look for a Selenium server at 127.0.0.1:4444.

fixed_ports

Optional: By default, if binary_port and marionette_port are not free a higher free port is probed and acquired if possible, until a free one if found or a timeout is exceeded.

    my $driver1 = Selenium::Chrome->new;
    my $driver2 = Selenium::Chrome->new( port => 1234 );

The default behavior can be overridden. In this case, only the default or given binary_port and marionette_port are probed, without probing higher ports. This ensures that either the default or given port will be assigned, or no port will be assigned at all.

    my $driver1 = Selenium::Chrome->new( fixed_ports => 1 );
    my $driver2 = Selenium::Chrome->new( port => 1234, fixed_ports => 1);

custom_args

Optional: If you want to pass additional options to the binary when it starts up, you can add that here. For example, if your binary accepts an argument on the command line like --log-path=/path/to/log, and you'd like to specify that the binary uses that option, you could do:

    my $chrome = Selenium::Chrome->new(
        custom_args => '--log-path=/path/to/log'
    );

To specify multiple arguments, just include them all in the string.

startup_timeout

Optional: you can modify how long we will wait for the binary to start up. By default, we will start the binary and check the intended destination port for 10 seconds before giving up. If the machine you're using to run your browsers is slower or smaller, you may need to increase this timeout.

The following:

    my $f = Selenium::Firefox->new(
        startup_timeout => 60
    );

will wait up to 60 seconds for the firefox binary to respond on the proper port. To use this constructor option, you should specify a time in seconds as an integer, and it will be passed to the arguments section of a "wait_until" in Selenium::Waiter subroutine call.

binary_mode

Mostly intended for internal use, its builder coordinates all the side effects of interacting with the binary: locating the executable, finding an open port, setting up the environment, shelling out to start the binary, and ensuring that the webdriver is listening on the correct port.

If all of the above steps pass, it will return truthy after instantiation. If any of them fail, it should return falsy and the class should attempt normal Selenium::Remote::Driver behavior.

window_title

Intended for internal use: this will build us a unique title for the background binary process of the Webdriver. Then, when we're cleaning up, we know what the window title is that we're going to taskkill.

command

Intended for internal use: this read-only attribute is built by us, but it can be useful after instantiation to see exactly what command was run to start the webdriver server.

    my $f = Selenium::Firefox->new;
    say $f->_command;

SEE ALSO

Please see those modules/websites for more information related to this module.

BUGS

Please report any bugs or feature requests on the bugtracker website https://github.com/gempesaw/Selenium-Remote-Driver/issues

When submitting a bug or request, please include a test-file or a patch to an existing test-file that illustrates the bug or desired feature.

AUTHORS

Current Maintainers:

  • Daniel Gempesaw <gempesaw@gmail.com>

  • Emmanuel Peroumalnaïk <peroumalnaik.emmanuel@gmail.com>

Previous maintainers:

  • Luke Closs <cpan@5thplane.com>

  • Mark Stosberg <mark@stosberg.com>

Original authors:

  • Aditya Ivaturi <ivaturi@gmail.com>

COPYRIGHT AND LICENSE

Copyright (c) 2010-2011 Aditya Ivaturi, Gordon Child

Copyright (c) 2014-2017 Daniel Gempesaw

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.