|
NAMEFirefox::Marionette - Automate the Firefox browser with the Marionette protocolVERSIONVersion 1.17SYNOPSISuse Firefox::Marionette(); use v5.10; my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); say $firefox->find_tag('title')->property('innerHTML'); # same as $firefox->title(); say $firefox->html(); $firefox->find_class('container-fluid')->find_id('search-input')->type('Test::More'); say "Height of search box is " . $firefox->find_class('container-fluid')->css('height'); my $file_handle = $firefox->selfie(); $firefox->find('//button[@name="lucky"]')->click(); $firefox->await(sub { $firefox->interactive() && $firefox->find_partial('Download') })->click(); DESCRIPTIONThis is a client module to automate the Mozilla Firefox browser via the Marionette protocol <https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/Protocol>SUBROUTINES/METHODSaccept_alertaccepts a currently displayed modal message boxaccept_connectionsEnables or disables accepting new socket connections. By calling this method with false the server will not accept any further connections, but existing connections will not be forcible closed. Use true to re-enable accepting connections.Please note that when closing the connection via the client you can end-up in a non-recoverable state if it hasn't been enabled before. active_elementreturns the active element of the current browsing context's document element, if the document element is non-null.add_certificateaccepts a hash as a parameter and adds the specified certificate to the Firefox database with the supplied or default trust. Allowed keys are below;
This method returns itself to aid in chaining methods. use Firefox::Marionette(); my $pem_encoded_string = <<'_PEM_'; -----BEGIN CERTIFICATE----- MII.. -----END CERTIFICATE----- _PEM_ my $firefox = Firefox::Marionette->new()->add_certificate(string => $pem_encoded_string); add_cookieaccepts a single cookie object as the first parameter and adds it to the current cookie jar. This method returns itself to aid in chaining methods.This method throws an exception if you try to add a cookie for a different domain than the current document <https://developer.mozilla.org/en-US/docs/Web/WebDriver/Errors/InvalidCookieDomain>. add_headeraccepts a hash of HTTP headers to include in every future HTTP Request.use Firefox::Marionette(); use UUID(); my $firefox = Firefox::Marionette->new(); my $uuid = UUID::uuid(); $firefox->add_header( 'Track-my-automated-tests' => $uuid ); $firefox->go('https://metacpan.org/'); these headers are added to any existing headers. To clear headers, see the delete_header method use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->delete_header( 'Accept' )->add_header( 'Accept' => 'text/perl' )->go('https://metacpan.org/'); will only send out an Accept <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept> header that looks like "Accept: text/perl". use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->add_header( 'Accept' => 'text/perl' )->go('https://metacpan.org/'); by itself, will send out an Accept <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept> header that may resemble "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8, text/perl". This method returns itself to aid in chaining methods. add_loginaccepts a hash of the following keys;
or a Firefox::Marionette::Login object as the first parameter and adds the login to the Firefox login database. use Firefox::Marionette(); use UUID(); my $firefox = Firefox::Marionette->new(); # for http auth logins my $http_auth_login = Firefox::Marionette::Login->new(host => 'https://pause.perl.org', user => 'AUSER', password => 'qwerty', realm => 'PAUSE'); $firefox->add_login($http_auth_login); $firefox->go('https://pause.perl.org/pause/authenquery')->accept_alert(); # this goes to the page and submits the http auth popup # for form based login $firefox->add_login(host => 'https://github.com', origin => 'https://github.com', user => 'me@example.org', password => 'qwerty', user_field => 'login', password_field => 'password'); my $form_login = Firefox::Marionette::Login(host => 'https://github.com', user => 'me2@example.org', password => 'uiop[]', user_field => 'login', password_field => 'password'); # or just directly $firefox->add_login(host => 'https://github.com', user => 'me2@example.org', password => 'uiop[]', user_field => 'login', password_field => 'password'); This method returns itself to aid in chaining methods. add_site_headeraccepts a host name and a hash of HTTP headers to include in every future HTTP Request that is being sent to that particular host.use Firefox::Marionette(); use UUID(); my $firefox = Firefox::Marionette->new(); my $uuid = UUID::uuid(); $firefox->add_site_header( 'metacpan.org', 'Track-my-automated-tests' => $uuid ); $firefox->go('https://metacpan.org/'); these headers are added to any existing headers going to the metacpan.org site, but no other site. To clear site headers, see the delete_site_header method addonsreturns if pre-existing addons (extensions/themes) are allowed to run. This will be true for Firefox versions less than 55, as -safe-mode cannot be automated.alert_textReturns the message shown in a currently displayed modal message boxaliveThis method returns true or false depending on if the Firefox process is still running.application_typereturns the application type for the Marionette protocol. Should be 'gecko'.async_scriptaccepts a scalar containing a javascript function that is executed in the browser. This method returns itself to aid in chaining methods.The executing javascript is subject to the script timeout, which, by default is 30 seconds. attributeaccepts an element as the first parameter and a scalar attribute name as the second parameter. It returns the initial value of the attribute with the supplied name. This method will return the initial content, the property method will return the current content.use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); my $element = $firefox->find_id('search_input'); !defined $element->attribute('value') or die "attribute is not defined!"); $element->type('Test::More'); !defined $element->attribute('value') or die "attribute is still not defined!"); awaitaccepts a subroutine reference as a parameter and then executes the subroutine. If a not found exception is thrown, this method will sleep for sleep_time_in_ms milliseconds and then execute the subroutine again. When the subroutine executes successfully, it will return what the subroutine returns.use Firefox::Marionette(); my $firefox = Firefox::Marionette->new(sleep_time_in_ms => 5)->go('https://metacpan.org/'); $firefox->find_id('search-input')->type('Test::More'); $firefox->find_name('lucky')->click(); $firefox->await(sub { $firefox->interactive() && $firefox->find_partial('Download') })->click(); backcauses the browser to traverse one step backward in the joint history of the current browsing context. The browser will wait for the one step backward to complete or the session's page_load duration to elapse before returning, which, by default is 5 minutes. This method returns itself to aid in chaining methods.debugaccept a boolean and return the current value of the debug setting. This allows the dynamic setting of debug.default_binary_namejust returns the string 'firefox'. Only of interest when sub-classing.browser_versionThis method returns the current version of firefox.byeaccepts a subroutine reference as a parameter and then executes the subroutine. If the subroutine executes successfully, this method will sleep for sleep_time_in_ms milliseconds and then execute the subroutine again. When a not found exception is thrown, this method will return itself to aid in chaining methods.use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); $firefox->find_id('search-input')->type('Test::More'); $firefox->find_name('lucky')->click(); $firefox->bye(sub { $firefox->find_name('lucky') })->await(sub { $firefox->interactive() && $firefox->find_partial('Download') })->click(); capabilitiesreturns the capabilities of the current firefox binary. You can retrieve timeouts or a proxy with this method.certificate_as_pemaccepts a certificate stored in the Firefox database as a parameter and returns a PEM encoded X.509 certificate <https://datatracker.ietf.org/doc/html/rfc7468#section-5> as a string.use Firefox::Marionette(); my $firefox = Firefox::Marionette->new(); # Generating a ca-bundle.crt to STDOUT from the current firefox instance foreach my $certificate (sort { $a->display_name() cmp $b->display_name } $firefox->certificates()) { if ($certificate->is_ca_cert()) { print '# ' . $certificate->display_name() . "\n" . $firefox->certificate_as_pem($certificate) . "\n"; } } The ca-bundle-for-firefox command that is provided as part of this distribution does this. certificatesreturns a list of all known certificates in the Firefox database.use Firefox::Marionette(); use v5.10; # Sometimes firefox can neglect old certificates. See https://bugzilla.mozilla.org/show_bug.cgi?id=1710716 my $firefox = Firefox::Marionette->new(); foreach my $certificate (grep { $_->is_ca_cert() && $_->not_valid_after() < time } $firefox->certificates()) { say "The " . $certificate->display_name() " . certificate has expired and should be removed"; } This method returns itself to aid in chaining methods. child_errorThis method returns the $? (CHILD_ERROR) for the Firefox process, or undefined if the process has not yet exited.chromechanges the scope of subsequent commands to chrome context. This allows things like interacting with firefox menu's and buttons outside of the browser window.use Firefox::Marionette(); use v5.10; my $firefox = Firefox::Marionette->new()->chrome(); $firefox->script(...); # running script in chrome context $firefox->content(); See the context method for an alternative methods for changing the context. chrome_window_handlereturns an server-assigned integer identifiers for the current chrome window that uniquely identifies it within this Marionette instance. This can be used to switch to this window at a later point. This corresponds to a window that may itself contain tabs. This method is replaced by window_handle and appropriate context calls for Firefox 94 and after.chrome_window_handlesreturns identifiers for each open chrome window for tests interested in managing a set of chrome windows and tabs separately. This method is replaced by window_handles and appropriate context calls for Firefox 94 and after.clearaccepts a element as the first parameter and clears any user supplied inputclickaccepts a element as the first parameter and sends a 'click' to it. The browser will wait for any page load to complete or the session's page_load duration to elapse before returning, which, by default is 5 minutes. The click method is also used to choose an option in a select dropdown.use Firefox::Marionette(); my $firefox = Firefox::Marionette->new(visible => 1)->go('https://ebay.com'); my $select = $firefox->find_tag('select'); foreach my $option ($select->find_tag('option')) { if ($option->property('value') == 58058) { # Computers/Tablets & Networking $option->click(); } } close_current_chrome_window_handlecloses the current chrome window (that is the entire window, not just the tabs). It returns a list of still available chrome window handles. You will need to switch_to_window to use another window.close_current_window_handlecloses the current window/tab. It returns a list of still available window/tab handles.contentchanges the scope of subsequent commands to browsing context. This is the default for when firefox starts and restricts commands to operating in the browser window only.use Firefox::Marionette(); use v5.10; my $firefox = Firefox::Marionette->new()->chrome(); $firefox->script(...); # running script in chrome context $firefox->content(); See the context method for an alternative methods for changing the context. contextaccepts a string as the first parameter, which may be either 'content' or 'chrome'. It returns the context type that is Marionette's current target for browsing context scoped commands.use Firefox::Marionette(); use v5.10; my $firefox = Firefox::Marionette->new(); if ($firefox->context() eq 'content') { say "I knew that was going to happen"; } my $old_context = $firefox->context('chrome'); $firefox->script(...); # running script in chrome context $firefox->context($old_context); See the content and chrome methods for alternative methods for changing the context. cookiesreturns the contents of the cookie jar in scalar or list context.use Firefox::Marionette(); use v5.10; my $firefox = Firefox::Marionette->new()->go('https://github.com'); foreach my $cookie ($firefox->cookies()) { if (defined $cookie->same_site()) { say "Cookie " . $cookie->name() . " has a SameSite of " . $cookie->same_site(); } else { warn "Cookie " . $cookie->name() . " does not have the SameSite attribute defined"; } } cssaccepts an element as the first parameter and a scalar CSS property name as the second parameter. It returns the value of the computed style for that property.use Firefox::Marionette(); use v5.10; my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); say $firefox->find_id('search-input')->css('height'); current_chrome_window_handlesee chrome_window_handle.delete_certificateaccepts a certificate stored in the Firefox database as a parameter and deletes/distrusts the certificate from the Firefox database.use Firefox::Marionette(); use v5.10; my $firefox = Firefox::Marionette->new(); foreach my $certificate ($firefox->certificates()) { if ($certificate->is_ca_cert()) { $firefox->delete_certificate($certificate); } else { say "This " . $certificate->display_name() " certificate is NOT a certificate authority, therefore it is not being deleted"; } } say "Good luck visiting a HTTPS website!"; This method returns itself to aid in chaining methods. delete_cookiedeletes a single cookie by name. Accepts a scalar containing the cookie name as a parameter. This method returns itself to aid in chaining methods.use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://github.com'); foreach my $cookie ($firefox->cookies()) { warn "Cookie " . $cookie->name() . " is being deleted"; $firefox->delete_cookie($cookie->name()); } foreach my $cookie ($firefox->cookies()) { die "Should be no cookies here now"; } delete_cookieshere be cookie monsters! This method returns itself to aid in chaining methods.delete_headeraccepts a list of HTTP header names to delete from future HTTP Requests.use Firefox::Marionette(); my $firefox = Firefox::Marionette->new(); $firefox->delete_header( 'User-Agent', 'Accept', 'Accept-Encoding' ); will remove the User-Agent <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent>, Accept <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept> and Accept-Encoding <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding> headers from all future requests This method returns itself to aid in chaining methods. delete_loginaccepts a login as a parameter.use Firefox::Marionette(); my $firefox = Firefox::Marionette->new(); foreach my $login ($firefox->logins()) { if ($login->user() eq 'me@example.org') { $firefox->delete_login($login); } } will remove the logins with the username matching 'me@example.org'. This method returns itself to aid in chaining methods. delete_loginsThis method empties the password database.use Firefox::Marionette(); my $firefox = Firefox::Marionette->new(); $firefox->delete_logins(); This method returns itself to aid in chaining methods. delete_sessiondeletes the current WebDriver session.delete_site_headeraccepts a host name and a list of HTTP headers names to delete from future HTTP Requests.use Firefox::Marionette(); my $firefox = Firefox::Marionette->new(); $firefox->delete_header( 'metacpan.org', 'User-Agent', 'Accept', 'Accept-Encoding' ); will remove the User-Agent <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent>, Accept <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept> and Accept-Encoding <https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding> headers from all future requests to metacpan.org. This method returns itself to aid in chaining methods. developerreturns true if the current version of firefox is a developer edition <https://www.mozilla.org/en-US/firefox/developer/> (does the minor version number end with an 'b\d+'?) version.dismiss_alertdismisses a currently displayed modal message boxdownloadaccepts a filesystem path and returns a matching filehandle. This is trivial for locally running firefox, but sufficiently complex to justify the method for a remote firefox running over ssh.use Firefox::Marionette(); use v5.10; my $firefox = Firefox::Marionette->new( host => '10.1.2.3' )->go('https://metacpan.org/'); $firefox->find_class('container-fluid')->find_id('search-input')->type('Test::More'); $firefox->find('//button[@name="lucky"]')->click(); $firefox->await(sub { $firefox->interactive() && $firefox->find_partial('Download') })->click(); while(!$firefox->downloads()) { sleep 1 } foreach my $path ($firefox->downloads()) { my $handle = $firefox->download($path); # do something with downloaded file handle } downloadingreturns true if any files in downloads end in ".part"use Firefox::Marionette(); use v5.10; my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); $firefox->find_class('container-fluid')->find_id('search-input')->type('Test::More'); $firefox->find('//button[@name="lucky"]')->click(); $firefox->await(sub { $firefox->interactive() && $firefox->find_partial('Download') })->click(); while(!$firefox->downloads()) { sleep 1 } while($firefox->downloading()) { sleep 1 } foreach my $path ($firefox->downloads()) { say $path; } downloadsreturns a list of file paths (including partial downloads) of downloads during this Firefox session.use Firefox::Marionette(); use v5.10; my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); $firefox->find_class('container-fluid')->find_id('search-input')->type('Test::More'); $firefox->find('//button[@name="lucky"]')->click(); $firefox->await(sub { $firefox->interactive() && $firefox->find_partial('Download') })->click(); while(!$firefox->downloads()) { sleep 1 } foreach my $path ($firefox->downloads()) { say $path; } error_messageThis method returns a human readable error message describing how the Firefox process exited (assuming it started okay). On Win32 platforms this information is restricted to exit code.executeThis utility method executes a command with arguments and returns STDOUT as a chomped string. It is a simple method only intended for the Firefox::Marionette::* modules.fill_loginThis method searchs the Password Manager <https://support.mozilla.org/en-US/kb/password-manager-remember-delete-edit-logins> for an appropriate login for any form on the current page. The form must match the host, the action attribute and the user and password field names.use Firefox::Marionette(); use IO::Prompt(); my $firefox = Firefox::Marionette->new(); my $firefox = Firefox::Marionette->new(); my $url = 'https://github.com'; my $user = 'me@example.org'; my $password = IO::Prompt::prompt(-echo => q[*], "Please enter the password for the $user account when logging into $url:"); $firefox->add_login(host => $url, user => $user, password => 'qwerty', user_field => 'login', password_field => 'password'); $firefox->go("$url/login"); $firefox->fill_login(); findaccepts an xpath expression <https://en.wikipedia.org/wiki/XPath> as the first parameter and returns the first element that matches this expression.This method is subject to the implicit timeout, which, by default is 0 seconds. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); $firefox->find('//input[@id="search-input"]')->type('Test::More'); # OR in list context foreach my $element ($firefox->find('//input[@id="search-input"]')) { $element->type('Test::More'); } If no elements are found, a not found exception will be thrown. For the same functionality that returns undef if no elements are found, see the has method. find_idaccepts an id <https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id> as the first parameter and returns the first element with a matching 'id' property.This method is subject to the implicit timeout, which, by default is 0 seconds. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); $firefox->find_id('search-input')->type('Test::More'); # OR in list context foreach my $element ($firefox->find_id('search-input')) { $element->type('Test::More'); } If no elements are found, a not found exception will be thrown. For the same functionality that returns undef if no elements are found, see the has_id method. find_nameThis method returns the first element with a matching 'name' property.This method is subject to the implicit timeout, which, by default is 0 seconds. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); $firefox->find_name('q')->type('Test::More'); # OR in list context foreach my $element ($firefox->find_name('q')) { $element->type('Test::More'); } If no elements are found, a not found exception will be thrown. For the same functionality that returns undef if no elements are found, see the has_name method. find_classaccepts a class name <https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/class> as the first parameter and returns the first element with a matching 'class' property.This method is subject to the implicit timeout, which, by default is 0 seconds. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); $firefox->find_class('form-control home-search-input')->type('Test::More'); # OR in list context foreach my $element ($firefox->find_class('form-control home-search-input')) { $element->type('Test::More'); } If no elements are found, a not found exception will be thrown. For the same functionality that returns undef if no elements are found, see the has_class method. find_selectoraccepts a CSS Selector <https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors> as the first parameter and returns the first element that matches that selector.This method is subject to the implicit timeout, which, by default is 0 seconds. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); $firefox->find_selector('input.home-search-input')->type('Test::More'); # OR in list context foreach my $element ($firefox->find_selector('input.home-search-input')) { $element->type('Test::More'); } If no elements are found, a not found exception will be thrown. For the same functionality that returns undef if no elements are found, see the has_selector method. find_tagaccepts a tag name <https://developer.mozilla.org/en-US/docs/Web/API/Element/tagName> as the first parameter and returns the first element with this tag name.This method is subject to the implicit timeout, which, by default is 0 seconds. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); my $element = $firefox->find_tag('input'); # OR in list context foreach my $element ($firefox->find_tag('input')) { # do something } If no elements are found, a not found exception will be thrown. For the same functionality that returns undef if no elements are found, see the has_tag method. find_linkaccepts a text string as the first parameter and returns the first link element that has a matching link text.This method is subject to the implicit timeout, which, by default is 0 seconds. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); $firefox->find_link('API')->click(); # OR in list context foreach my $element ($firefox->find_link('API')) { $element->click(); } If no elements are found, a not found exception will be thrown. For the same functionality that returns undef if no elements are found, see the has_link method. find_partialaccepts a text string as the first parameter and returns the first link element that has a partially matching link text.This method is subject to the implicit timeout, which, by default is 0 seconds. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); $firefox->find_partial('AP')->click(); # OR in list context foreach my $element ($firefox->find_partial('AP')) { $element->click(); } If no elements are found, a not found exception will be thrown. For the same functionality that returns undef if no elements are found, see the has_partial method. forwardcauses the browser to traverse one step forward in the joint history of the current browsing context. The browser will wait for the one step forward to complete or the session's page_load duration to elapse before returning, which, by default is 5 minutes. This method returns itself to aid in chaining methods.full_screenfull screens the firefox window. This method returns itself to aid in chaining methods.goNavigates the current browsing context to the given URI and waits for the document to load or the session's page_load duration to elapse before returning, which, by default is 5 minutes.use Firefox::Marionette(); my $firefox = Firefox::Marionette->new(); $firefox->go('https://metacpan.org/'); # will only return when metacpan.org is FULLY loaded (including all images / js / css) To make the go method return quicker, you need to set the page load strategy capability to an appropriate value, such as below; use Firefox::Marionette(); my $firefox = Firefox::Marionette->new( capabilities => Firefox::Marionette::Capabilities->new( page_load_strategy => 'eager' )); $firefox->go('https://metacpan.org/'); # will return once the main document has been loaded and parsed, but BEFORE sub-resources (images/stylesheets/frames) have been loaded. When going directly to a URL that needs to be downloaded, please see BUGS AND LIMITATIONS for a necessary workaround. This method returns itself to aid in chaining methods. harreturns a hashref representing the http archive <https://en.wikipedia.org/wiki/HAR_(file_format)> of the session. This function is subject to the script timeout, which, by default is 30 seconds. It is also possible for the function to hang (until the script timeout) if the original devtools <https://developer.mozilla.org/en-US/docs/Tools> window is closed. The hashref has been designed to be accepted by the Archive::Har module. This function should be considered experimental. Feedback welcome.use Firefox::Marionette(); use Archive::Har(); use v5.10; my $firefox = Firefox::Marionette->new(visible => 1, debug => 1, har => 1); $firefox->go("http://metacpan.org/"); $firefox->find('//input[@id="search-input"]')->type('Test::More'); $firefox->find_name('lucky')->click(); my $har = Archive::Har->new(); $har->hashref($firefox->har()); foreach my $entry ($har->entries()) { say $entry->request()->url() . " spent " . $entry->timings()->connect() . " ms establishing a TCP connection"; } hasaccepts an xpath expression <https://en.wikipedia.org/wiki/XPath> as the first parameter and returns the first element that matches this expression.This method is subject to the implicit timeout, which, by default is 0 seconds. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); if (my $element = $firefox->has('//input[@id="search-input"]')) { $element->type('Test::More'); } If no elements are found, this method will return undef. For the same functionality that throws a not found exception, see the find method. has_idaccepts an id <https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id> as the first parameter and returns the first element with a matching 'id' property.This method is subject to the implicit timeout, which, by default is 0 seconds. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); if (my $element = $firefox->has_id('search-input')) { $element->type('Test::More'); } If no elements are found, this method will return undef. For the same functionality that throws a not found exception, see the find_id method. has_nameThis method returns the first element with a matching 'name' property.This method is subject to the implicit timeout, which, by default is 0 seconds. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); if (my $element = $firefox->has_name('q')) { $element->type('Test::More'); } If no elements are found, this method will return undef. For the same functionality that throws a not found exception, see the find_name method. has_classaccepts a class name <https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/class> as the first parameter and returns the first element with a matching 'class' property.This method is subject to the implicit timeout, which, by default is 0 seconds. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); if (my $element = $firefox->has_class('form-control home-search-input')) { $element->type('Test::More'); } If no elements are found, this method will return undef. For the same functionality that throws a not found exception, see the find_class method. has_selectoraccepts a CSS Selector <https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors> as the first parameter and returns the first element that matches that selector.This method is subject to the implicit timeout, which, by default is 0 seconds. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); if (my $element = $firefox->has_selector('input.home-search-input')) { $element->type('Test::More'); } If no elements are found, this method will return undef. For the same functionality that throws a not found exception, see the find_selector method. has_tagaccepts a tag name <https://developer.mozilla.org/en-US/docs/Web/API/Element/tagName> as the first parameter and returns the first element with this tag name.This method is subject to the implicit timeout, which, by default is 0 seconds. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); if (my $element = $firefox->has_tag('input')) { # do something } If no elements are found, this method will return undef. For the same functionality that throws a not found exception, see the find_tag method. has_linkaccepts a text string as the first parameter and returns the first link element that has a matching link text.This method is subject to the implicit timeout, which, by default is 0 seconds. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); if (my $element = $firefox->has_link('API')) { $element->click(); } If no elements are found, this method will return undef. For the same functionality that throws a not found exception, see the find_link method. has_partialaccepts a text string as the first parameter and returns the first link element that has a partially matching link text.This method is subject to the implicit timeout, which, by default is 0 seconds. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); if (my $element = $firefox->find_partial('AP')) { $element->click(); } If no elements are found, this method will return undef. For the same functionality that throws a not found exception, see the find_partial method. htmlreturns the page source of the content document. This page source can be wrapped in html that firefox provides. See the json method for an alternative when dealing with response content types such as application/json and strip for an alterative when dealing with other non-html content types such as text/plain.use Firefox::Marionette(); use v5.10; say Firefox::Marionette->new()->go('https://metacpan.org/')->html(); imagesreturns a list of all of the following elements;
as Firefox::Marionette::Image objects. This method is subject to the implicit timeout, which, by default is 0 seconds. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); if (my $link = $firefox->images()) { say "Found a image with width " . $image->width() . "px and height " . $image->height() . "px from " . $image->URL(); } If no elements are found, this method will return undef. installaccepts the following as the first parameter;
and an optional true/false second parameter to indicate if the xpi file should be a temporary extension <https://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/> (just for the existance of this browser instance). Unsigned xpi files may only be loaded temporarily <https://wiki.mozilla.org/Add-ons/Extension_Signing> (except for nightly firefox installations <https://www.mozilla.org/en-US/firefox/channel/desktop/#nightly>). It returns the GUID for the addon which may be used as a parameter to the uninstall method. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new(); my $extension_id = $firefox->install('/full/path/to/gnu_terry_pratchett-0.4-an+fx.xpi'); # OR downloading and installing source code system { 'git' } 'git', 'clone', 'https://github.com/kkapsner/CanvasBlocker.git'; if ($firefox->nightly()) { $extension_id = $firefox->install('./CanvasBlocker'); # permanent install for unsigned packages in nightly firefox } else { $extension_id = $firefox->install('./CanvasBlocker', 1); # temp install for normal firefox } interactivereturns true if "document.readyState === "interactive"" or if loaded is trueuse Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); $firefox->find_id('search_input')->type('Type::More'); $firefox->find('//button[@name="lucky"]')->click(); while(!$firefox->interactive()) { # redirecting to Test::More page } is_displayedaccepts an element as the first parameter. This method returns true or false depending on if the element is displayed <https://firefox-source-docs.mozilla.org/testing/marionette/internals/interaction.html#interaction.isElementDisplayed>.is_enabledaccepts an element as the first parameter. This method returns true or false depending on if the element is enabled <https://w3c.github.io/webdriver/#is-element-enabled>.is_selectedaccepts an element as the first parameter. This method returns true or false depending on if the element is selected <https://w3c.github.io/webdriver/#dfn-is-element-selected>. Note that this method only makes sense for checkbox <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox> or radio <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio> inputs or option <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option> elements in a select <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select> dropdown.jsonreturns a JSON object that has been parsed from the page source of the content document. This is a convenience method that wraps the strip method.use Firefox::Marionette(); use v5.10; say Firefox::Marionette->new()->go('https://fastapi.metacpan.org/v1/download_url/Firefox::Marionette")->json()->{version}; key_downaccepts a parameter describing a key and returns an action for use in the perform method that corresponding with that key being depressed.use Firefox::Marionette(); use Firefox::Marionette::Keys qw(:all); my $firefox = Firefox::Marionette->new(); $firefox->chrome()->perform( $firefox->key_down(CONTROL()), $firefox->key_down('l'), )->release()->content(); key_upaccepts a parameter describing a key and returns an action for use in the perform method that corresponding with that key being released.use Firefox::Marionette(); use Firefox::Marionette::Keys qw(:all); my $firefox = Firefox::Marionette->new(); $firefox->chrome()->perform( $firefox->key_down(CONTROL()), $firefox->key_down('l'), $firefox->pause(20), $firefox->key_up('l'), $firefox->key_up(CONTROL()) )->content(); loadedreturns true if "document.readyState === "complete""use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); $firefox->find_id('search_input')->type('Type::More'); $firefox->find('//button[@name="lucky"]')->click(); while(!$firefox->loaded()) { # redirecting to Test::More page } linksreturns a list of all of the following elements;
as Firefox::Marionette::Link objects. This method is subject to the implicit timeout, which, by default is 0 seconds. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); if (my $link = $firefox->links()) { if ($link->tag() eq 'a') { warn "Found a hyperlink to " . $link->URL(); } } If no elements are found, this method will return undef. macos_binary_pathsreturns a list of filesystem paths that this module will check for binaries that it can automate when running on MacOS <https://en.wikipedia.org/wiki/MacOS>. Only of interest when sub-classing.marionette_protocolreturns the version for the Marionette protocol. Current most recent version is '3'.maximisemaximises the firefox window. This method returns itself to aid in chaining methods.mime_typesreturns a list of MIME types that will be downloaded by firefox and made available from the downloads methoduse Firefox::Marionette(); use v5.10; my $firefox = Firefox::Marionette->new(mime_types => [ 'application/pkcs10' ]) foreach my $mime_type ($firefox->mime_types()) { say $mime_type; } minimiseminimises the firefox window. This method returns itself to aid in chaining methods.mouse_downaccepts a parameter describing which mouse button the method should apply to (left, middle or right) and returns an action for use in the perform method that corresponding with a mouse button being depressed.mouse_moveaccepts a element parameter, or a "( x => 0, y => 0 )" type hash manually describing exactly where to move the mouse to and returns an action for use in the perform method that corresponding with such a mouse movement, either to the specified co-ordinates or to the middle of the supplied element parameter. Other parameters that may be passed are listed below;
This method returns itself to aid in chaining methods. mouse_upaccepts a parameter describing which mouse button the method should apply to (left, middle or right) and returns an action for use in the perform method that corresponding with a mouse button being released.newaccepts an optional hash as a parameter. Allowed keys are below;
This method returns a new "Firefox::Marionette" object, connected to an instance of firefox <https://firefox.com>. In a non MacOS/Win32/Cygwin environment, if necessary (no DISPLAY variable can be found and the visible parameter to the new method has been set to true) and possible (Xvfb can be executed successfully), this method will also automatically start an Xvfb <https://en.wikipedia.org/wiki/Xvfb> instance. use Firefox::Marionette(); my $remote_darwin_firefox = Firefox::Marionette->new( debug => 1, host => '10.1.2.3', trust => '/path/to/root_ca.pem', binary => '/Applications/Firefox.app/Contents/MacOS/firefox' ); # start a temporary profile for a remote firefox and load a new CA into the temp profile ... foreach my $profile_name (Firefox::Marionette::Profile->names()) { my $firefox_with_existing_profile = Firefox::Marionette->new( profile_name => $profile_name, visible => 1 ); ... } new_windowaccepts an optional hash as the parameter. Allowed keys are below;
Returns the window handle for the new window. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new(); my $window_handle = $firefox->new_window(type => 'tab'); $firefox->switch_to_window($window_handle); new_sessioncreates a new WebDriver session. It is expected that the caller performs the necessary checks on the requested capabilities to be WebDriver conforming. The WebDriver service offered by Marionette does not match or negotiate capabilities beyond type and bounds checks.nightlyreturns true if the current version of firefox is a nightly release <https://www.mozilla.org/en-US/firefox/channel/desktop/#nightly> (does the minor version number end with an 'a1'?)paper_sizesreturns a list of all the recognised names for paper sizes, such as A4 or LEGAL.pauseaccepts a parameter in milliseconds and returns a corresponding action for the perform method that will cause a pause in the chain of actions given to the perform method.
returns a File::Temp object containing a PDF encoded version of the current page for printing. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); my $handle = $firefox->pdf(); foreach my $paper_size ($firefox->paper_sizes()) { $handle = $firefox->pdf(size => $paper_size, landscape => 1, margin => { top => 0.5, left => 1.5 }); ... print $firefox->pdf(page => { width => 21, height => 27 }, raw => 1); ... } performaccepts a list of actions (see mouse_up, mouse_down, mouse_move, pause, key_down and key_up) and performs these actions in sequence. This allows fine control over interactions, including sending right clicks to the browser and sending Control, Alt and other special keys. The release method will complete outstanding actions (such as mouse_up or key_up actions).use Firefox::Marionette(); use Firefox::Marionette::Keys qw(:all); use Firefox::Marionette::Buttons qw(:all); my $firefox = Firefox::Marionette->new(); $firefox->chrome()->perform( $firefox->key_down(CONTROL()), $firefox->key_down('l'), $firefox->key_up('l'), $firefox->key_up(CONTROL()) )->content(); $firefox->go('https://metacpan.org'); my $help_button = $firefox->find_class('btn search-btn help-btn'); $firefox->perform( $firefox->mouse_move($help_button), $firefox->mouse_down(RIGHT_BUTTON()), $firefox->pause(4), $firefox->mouse_up(RIGHT_BUTTON()), ); See the release method for an alternative for manually specifying all the mouse_up and key_up methods profile_directoryreturns the profile directory used by the current instance of firefox. This is mainly intended for debugging firefox. Firefox is not designed to cope with these files being altered while firefox is running.propertyaccepts an element as the first parameter and a scalar attribute name as the second parameter. It returns the current value of the property with the supplied name. This method will return the current content, the attribute method will return the initial content.use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); my $element = $firefox->find_id('search_input'); $element->property('value') eq '' or die "Initial property is the empty string"; $element->type('Test::More'); $element->property('value') eq 'Test::More' or die "This property should have changed!"; # OR getting the innerHTML property my $title = $firefox->find_tag('title')->property('innerHTML'); # same as $firefox->title(); pwd_mgr_lockAccepts a new primary password <https://support.mozilla.org/en-US/kb/use-primary-password-protect-stored-logins> and locks the Password Manager <https://support.mozilla.org/en-US/kb/password-manager-remember-delete-edit-logins> with it.use Firefox::Marionette(); use IO::Prompt(); my $firefox = Firefox::Marionette->new(); my $password = IO::Prompt::prompt(-echo => q[*], "Please enter the password for the Firefox Password Manager:"); $firefox->pwd_mgr_lock($password); $firefox->pwd_mgr_logout(); # now no-one can access the Password Manager Database without the value in $password This method returns itself to aid in chaining methods. pwd_mgr_loginAccepts the primary password <https://support.mozilla.org/en-US/kb/use-primary-password-protect-stored-logins> and allows the user to access the Password Manager <https://support.mozilla.org/en-US/kb/password-manager-remember-delete-edit-logins>.use Firefox::Marionette(); use IO::Prompt(); my $firefox = Firefox::Marionette->new( profile_name => 'default' ); my $password = IO::Prompt::prompt(-echo => q[*], "Please enter the password for the Firefox Password Manager:"); $firefox->pwd_mgr_login($password); ... # access the Password Database. ... $firefox->pwd_mgr_logout(); ... # no longer able to access the Password Database. This method returns itself to aid in chaining methods. pwd_mgr_logoutLogs the user out of being able to access the Password Manager <https://support.mozilla.org/en-US/kb/password-manager-remember-delete-edit-logins>.use Firefox::Marionette(); use IO::Prompt(); my $firefox = Firefox::Marionette->new( profile_name => 'default' ); my $password = IO::Prompt::prompt(-echo => q[*], "Please enter the password for the Firefox Password Manager:"); $firefox->pwd_mgr_login($password); ... # access the Password Database. ... $firefox->pwd_mgr_logout(); ... # no longer able to access the Password Database. This method returns itself to aid in chaining methods. pwd_mgr_needs_loginreturns true or false if the Password Manager <https://support.mozilla.org/en-US/kb/password-manager-remember-delete-edit-logins> has been locked and needs a primary password <https://support.mozilla.org/en-US/kb/use-primary-password-protect-stored-logins> to access it.use Firefox::Marionette(); use IO::Prompt(); my $firefox = Firefox::Marionette->new( profile_name => 'default' ); if ($firefox->pwd_mgr_needs_login()) { my $password = IO::Prompt::prompt(-echo => q[*], "Please enter the password for the Firefox Password Manager:"); $firefox->pwd_mgr_login($password); } quitMarionette will stop accepting new connections before ending the current session, and finally attempting to quit the application. This method returns the $? (CHILD_ERROR) value for the Firefox processrectaccepts a element as the first parameter and returns the current position and size of the elementrefreshrefreshes the current page. The browser will wait for the page to completely refresh or the session's page_load duration to elapse before returning, which, by default is 5 minutes. This method returns itself to aid in chaining methods.releasecompletes any outstanding actions issued by the perform method.use Firefox::Marionette(); use Firefox::Marionette::Keys qw(:all); use Firefox::Marionette::Buttons qw(:all); my $firefox = Firefox::Marionette->new(); $firefox->chrome()->perform( $firefox->key_down(CONTROL()), $firefox->key_down('l'), )->release()->content(); $firefox->go('https://metacpan.org'); my $help_button = $firefox->find_class('btn search-btn help-btn'); $firefox->perform( $firefox->mouse_move($help_button), $firefox->mouse_down(RIGHT_BUTTON()), $firefox->pause(4), )->release(); restartrestarts the browser. After the restart, capabilities should be restored. The same profile settings should be applied, but the current state of the browser (such as the uri will be reset (like after a normal browser restart). This method is primarily intended for use by the update method. Not sure if this is useful by itself.use Firefox::Marionette(); my $firefox = Firefox::Marionette->new(); $firefox->restart(); # but why? This method returns itself to aid in chaining methods. root_directorythis is the root directory for the current instance of firefox. The directory may exist on a remote server. For debugging purposes only.screen_orientationreturns the current browser orientation. This will be one of the valid primary orientation values 'portrait-primary', 'landscape-primary', 'portrait-secondary', or 'landscape-secondary'. This method is only currently available on Android (Fennec).scriptaccepts a scalar containing a javascript function body that is executed in the browser, and an optional hash as a second parameter. Allowed keys are below;
Returns the result of the javascript function. use Firefox::Marionette(); my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); if ($firefox->script('return window.find("lucky");')) { # luckily! } my $search_input = $firefox->find_by_id('search-input'); $firefox->script('arguments[0].style.backgroundColor = "red"', args => [ $search_input ]); # turn the search input box red The executing javascript is subject to the script timeout, which, by default is 30 seconds. selfiereturns a File::Temp object containing a lossless PNG image screenshot. If an element is passed as a parameter, the screenshot will be restricted to the element.If an element is not passed as a parameter and the current context is 'chrome', a screenshot of the current viewport will be returned. If an element is not passed as a parameter and the current context is 'content', a screenshot of the current frame will be returned. The parameters after the element parameter are taken to be a optional hash with the following allowed keys;
send_alert_textsends keys to the input field of a currently displayed modal message boxsleep_time_in_msaccepts a new time to sleep in await or bye methods and returns the previous time. The default time is "1" millisecond.use Firefox::Marionette(); my $firefox = Firefox::Marionette->new(sleep_time_in_ms => 5); # setting default time to 5 milliseconds my $old_time_in_ms = $firefox->sleep_time_in_ms(8); # setting default time to 8 milliseconds, returning 5 (milliseconds) ssh_local_directoryreturns the path to the local directory for the ssh connection (if any). For debugging purposes only.stripreturns the page source of the content document after an attempt has been made to remove typical firefox html wrappers of non html content types such as text/plain and application/json. See the json method for an alternative when dealing with response content types such as application/json and html for an alterative when dealing with html content types. This is a convenience method that wraps the html method.use Firefox::Marionette(); use JSON(); use v5.10; say JSON::decode_json(Firefox::Marionette->new()->go("https://fastapi.metacpan.org/v1/download_url/Firefox::Marionette")->strip())->{version}; Note that this method will assume the bytes it receives from the html method are UTF-8 encoded and will translate accordingly, throwing an exception in the process if the bytes are not UTF-8 encoded. switch_to_frameaccepts a frame as a parameter and switches to it within the current window.switch_to_parent_frameset the current browsing context for future commands to the parent of the current browsing contextswitch_to_windowaccepts a window handle (either the result of window_handles or a window name as a parameter and switches focus to this window.use Firefox::Marionette(); my $firefox = Firefox::Marionette->new(); $firefox->version my $original_window_uuid = $firefox->window_handle(); $firefox->new_window( type => 'tab' ); $firefox->new_window( type => 'window' ); $firefox->switch_to_window($original_window_uuid); $firefox->go('https://metacpan.org'); tag_nameaccepts a Firefox::Marionette::Element object as the first parameter and returns the relevant tag name. For example 'a <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a>' or 'input <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input>'.textaccepts a element as the first parameter and returns the text that is contained by that element (if any)timeoutsreturns the current timeouts for page loading, searching, and scripts.titlereturns the current title <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title> of the window.typeaccepts an element as the first parameter and a string as the second parameter. It sends the string to the specified element in the current page, such as filling out a text box. This method returns itself to aid in chaining methods.updatequeries the Update Services and applies any available updates. Restarts the browser if necessary to complete the update. This function is experimental and currently has not been successfully tested on Win32 or MacOS.use Firefox::Marionette(); use v5.10; my $firefox = Firefox::Marionette->new(); my $update = $firefox->update(); while($update->successful()) { $update = $firefox->update(); } say "Updated to " . $update->display_version() . " - Build ID " . $update->build_id(); $firefox->quit(); returns a status object that contains useful information about any updates that occurred. uninstallaccepts the GUID for the addon to uninstall. The GUID is returned when from the install method. This method returns itself to aid in chaining methods.use Firefox::Marionette(); my $firefox = Firefox::Marionette->new(); my $extension_id = $firefox->install('/full/path/to/gnu_terry_pratchett-0.4-an+fx.xpi'); # do something $firefox->uninstall($extension_id); # not recommended to uninstall this extension IRL. urireturns the current URI of current top level browsing context for Desktop. It is equivalent to the javascript "document.location.href"win32_organisationaccepts a parameter of a Win32 product name and returns the matching organisation. Only of interest when sub-classing.win32_product_namesreturns a hash of known Windows product names (such as 'Mozilla Firefox') with priority orders. The lower the priority will determine the order that this module will check for the existance of this product. Only of interest when sub-classing.window_handlereturns the current window's handle. On desktop this typically corresponds to the currently selected tab. returns an opaque server-assigned identifier to this window that uniquely identifies it within this Marionette instance. This can be used to switch to this window at a later point.use Firefox::Marionette(); use 5.010; my $firefox = Firefox::Marionette->new(); my $original_window_uuid = $firefox->window_handle(); window_handlesreturns a list of top-level browsing contexts. On desktop this typically corresponds to the set of open tabs for browser windows, or the window itself for non-browser chrome windows. Each window handle is assigned by the server and is guaranteed unique, however the return array does not have a specified ordering.use Firefox::Marionette(); use 5.010; my $firefox = Firefox::Marionette->new(); my $original_window_uuid = $firefox->window_handle(); $firefox->new_window( type => 'tab' ); $firefox->new_window( type => 'window' ); say "There are " . $firefox->window_handles() . " tabs open in total"; say "Across " . $firefox->chrome()->window_handles()->content() . " chrome windows"; window_rectaccepts an optional position and size as a parameter, sets the current browser window to that position and size and returns the previous position, size and state of the browser window. If no parameter is supplied, it returns the current position, size and state of the browser window.window_typereturns the current window's type. This should be 'navigator:browser'.xvfb_pidreturns the pid of the xvfb process if it exists.xvfb_displayreturns the value for the DISPLAY environment variable if one has been generated for the xvfb environment.xvfb_xauthorityreturns the value for the XAUTHORITY environment variable if one has been generated for the xvfb environmentAUTOMATING THE FIREFOX PASSWORD MANAGERThis module allows you to login to a website without ever directly handling usernames and password details. The Password Manager may be preloaded with appropriate passwords and locked, like so;use Firefox::Marionette(); my $firefox = Firefox::Marionette->new( profile_name => 'locked' ); # using a pre-built profile called 'locked' if ($firefox->pwd_mgr_needs_login()) { my $new_password = IO::Prompt::prompt(-echo => q[*], 'Enter the password for the locked profile:'); $firefox->pwd_mgr_login($password); } else { my $new_password = IO::Prompt::prompt(-echo => q[*], 'Enter the new password for the locked profile:'); $firefox->pwd_mgr_lock($password); } ... $firefox->pwd_mgr_logout(); Usernames and passwords (for both HTTP Authentication popups and HTML Form based logins) may be added, viewed and deleted. use WebService::HIBP(); my $hibp = WebService::HIBP->new(); $firefox->add_login(host => 'https://github.com', user => 'me@example.org', password => 'qwerty', user_field => 'login', password_field => 'password'); $firefox->add_login(host => 'https://pause.perl.org', user => 'AUSER', password => 'qwerty', realm => 'PAUSE'); ... foreach my $login ($firefox->logins()) { if ($hibp->password($login->password())) { # does NOT send the password to the HIBP webservice warn "HIBP reports that your password for the " . $login->user() " account at " . $login->host() . " has been found in a data breach"; $firefox->delete_login($login); # how could this possibly help? } } And used to fill in login prompts without explicitly knowing the account details. $firefox->go('https://pause.perl.org/pause/authenquery')->accept_alert(); # this goes to the page and submits the http auth popup $firefox->go('https://github.com/login')->fill_login(); # fill the login and password fields without needing to see them REMOTE AUTOMATION OF FIREFOX VIA SSHuse Firefox::Marionette(); my $firefox = Firefox::Marionette->new( host => 'remote.example.org', debug => 1 ); $firefox->go('https://metacpan.org/'); # OR specify a different user to login as ... my $firefox = Firefox::Marionette->new( host => 'remote.example.org', user => 'R2D2', debug => 1 ); $firefox->go('https://metacpan.org/'); # OR specify a different port to connect to my $firefox = Firefox::Marionette->new( host => 'remote.example.org', port => 2222, debug => 1 ); $firefox->go('https://metacpan.org/'); This module has support for creating and automating an instance of Firefox on a remote node. It has been tested against a number of operating systems, including recent version of Windows 10 or Windows Server 2019 <https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse>, OS X, and Linux and BSD distributions. It expects to be able to login to the remote node via public key authentication. It can be further secured via the command <https://man.openbsd.org/sshd#command=_command_> option in the OpenSSH <https://www.openssh.com/> authorized_keys <https://man.openbsd.org/sshd#AUTHORIZED_KEYS_FILE_FORMAT> file such as; no-agent-forwarding,no-pty,no-X11-forwarding,permitopen="127.0.0.1:*",command="/usr/local/bin/ssh-auth-cmd-marionette" ssh-rsa AAAA ... == user@server As an example, the ssh-auth-cmd-marionette command is provided as part of this distribution. When using ssh, Firefox::Marionette will attempt to pass the TMPDIR <https://en.wikipedia.org/wiki/TMPDIR> environment variable across the ssh connection to make cleanups easier. In order to allow this, the AcceptEnv <https://man.openbsd.org/sshd_config#AcceptEnv> setting in the remote sshd configuration <https://man.openbsd.org/sshd_config> should be set to allow TMPDIR, which will look like; AcceptEnv TMPDIR This module uses ControlMaster <https://man.openbsd.org/ssh_config#ControlMaster> functionality when using ssh <https://man.openbsd.org/ssh>, for a useful speedup of executing remote commands. Unfortunately, when using ssh to move from a cygwin <https://gcc.gnu.org/wiki/SSH_connection_caching>, Windows 10 or Windows Server 2019 <https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse> node to a remote environment, we cannot use ControlMaster <https://man.openbsd.org/ssh_config#ControlMaster>, because at this time, Windows does not support ControlMaster <https://github.com/Microsoft/vscode-remote-release/issues/96> and therefore this type of automation is still possible, but slower than other client platforms. DIAGNOSTICS
CONFIGURATION AND ENVIRONMENTFirefox::Marionette requires no configuration files or environment variables. It will however use the DISPLAY and XAUTHORITY environment variables to try to connect to an X Server. It will also use the HTTP_PROXY, HTTPS_PROXY, FTP_PROXY and ALL_PROXY environment variables as defaults if the session capabilities do not specify proxy information.DEPENDENCIESFirefox::Marionette requires the following non-core Perl modules
INCOMPATIBILITIESNone reported. Always interested in any products with marionette support that this module could be patched to work with.BUGS AND LIMITATIONSDOWNLOADING USING GO METHODWhen using the go method to go directly to a URL containing a downloadable file, Firefox can hang. You can work around this by setting the page_load_strategy to "none" like below;#! /usr/bin/perl use strict; use warnings; use Firefox::Marionette(); my $firefox = Firefox::Marionette->new( capabilities => Firefox::Marionette::Capabilities->new( page_load_strategy => 'none' ) ); $firefox->go("https://github.com/david-dick/firefox-marionette/archive/refs/heads/master.zip"); while(!$firefox->downloads()) { sleep 1 } while($firefox->downloading()) { sleep 1 } foreach my $path ($firefox->downloads()) { warn "$path has been downloaded"; } $firefox->quit(); MISSING METHODSCurrently the following Marionette methods have not been implemented;
To report a bug, or view the current list of bugs, please visit <https://github.com/david-dick/firefox-marionette/issues> SEE ALSO
AUTHORDavid Dick "<ddick@cpan.org>"ACKNOWLEDGEMENTSThanks to the entire Mozilla organisation for a great browser and to the team behind Marionette for providing an interface for automation.Thanks to Jan Odvarko <http://www.softwareishard.com/blog/about/> for creating the HAR Export Trigger <https://github.com/firefox-devtools/har-export-trigger> extension for Firefox. Thanks to Mike Kaply <https://mike.kaply.com/about/> for his post <https://mike.kaply.com/2015/02/10/installing-certificates-into-firefox/> describing importing certificates into Firefox. Thanks also to the authors of the documentation in the following sources;
LICENSE AND COPYRIGHTCopyright (c) 2021, David Dick "<ddick@cpan.org>". All rights reserved.This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See "perlartistic" in perlartistic. The Firefox::Marionette::Extension::HarExportTrigger module includes the HAR Export Trigger <https://github.com/firefox-devtools/har-export-trigger> extension which is licensed under the Mozilla Public License 2.0 <https://www.mozilla.org/en-US/MPL/2.0/>. DISCLAIMER OF WARRANTYBECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION.IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
Visit the GSP FreeBSD Man Page Interface. |