Firefox::Marionette - Automate the Firefox browser with the Marionette protocol
Version 0.60
use Firefox::Marionette(); use v5.10; my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/'); say $firefox->html(); $firefox->find_class('container-fluid')->find_id('search-input')->type('Test::More'); my $file_handle = $firefox->selfie(highlights => [ $firefox->find_name('lucky') ]); $firefox->find('//button[@name="lucky"]')->click(); $firefox->await(sub { $firefox->interactive() && $firefox->find_partial('Download') })->click();
This is a client module to automate the Mozilla Firefox browser via the Marionette protocol
accepts an optional hash as a parameter. Allowed keys are below;
firefox_binary - use the specified path to the Firefox binary, rather than the default path.
capabilities - use the supplied capabilities object, for example to set whether the browser should accept insecure certs or whether the browser should use a proxy.
profile_name - pick a specific existing profile to automate, rather than creating a new profile. Note that firefox refuses to allow more than one instance of a profile to run at the same time. Profile names can be obtained by using the Firefox::Marionette::Profile::names() method. NOTE: firefox ignores any changes made to the profile on the disk while it is running.
profile - create a new profile based on the supplied profile. NOTE: firefox ignores any changes made to the profile on the disk while it is running.
debug - should firefox's debug to be available via STDERR. This defaults to "0".
addons - should any firefox extensions and themes be available in this session. This defaults to "0".
mime_types - any MIME types that Firefox will encounter during this session. MIME types that are not specified will result in a hung browser (the File Download popup will appear).
sleep_time_in_ms - the amount of time (in milliseconds) that this module should sleep when unsuccessfully calling the subroutine provided to the await or bye methods. This defaults to "1" millisecond.
visible - should firefox be visible on the desktop. This defaults to "0".
timeouts - a shortcut to allow directly providing a timeout object, instead of needing to use timeouts from the capabilities parameter. Overrides the timeouts provided (if any) in the capabilities parameter.
page_load - a shortcut to allow directly providing the page_load timeout, instead of needing to use timeouts from the capabilities parameter. Overrides all longer ways.
script - a shortcut to allow directly providing the script timeout, instead of needing to use timeouts from the capabilities parameter. Overrides all longer ways.
implicit - a shortcut to allow directly providing the implicit timeout, instead of needing to use timeouts from the capabilities parameter. Overrides all longer ways.
This method returns a new Firefox::Marionette object, connected to an instance of firefox. In a non MacOS/Win32/Cygwin environment, if necessary (no DISPLAY variable can be found and visible has been set to true) and possible (Xvfb can be executed successfully), this method will also automatically start an Xvfb instance.
Firefox::Marionette
Navigates 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. This method returns itself to aid in chaining methods
returns the current URI of current top level browsing context for Desktop. It is equivalent to the javascript document.location.href
document.location.href
returns the current title of the window.
accepts an xpath expression 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.
accepts an id as the first parameter and returns the first element with a matching 'id' property.
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'); }
This method returns the first element with a matching 'name' property.
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'); }
accepts a class name as the first parameter and returns the first element with a matching 'class' property.
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'); }
accepts a CSS Selector as the first parameter and returns the first element that matches that selector.
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'); }
accepts a tag name as the first parameter and returns the first element with this tag name.
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 }
accepts a text string as the first parameter and returns the first link element that has a matching link text.
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(); }
accepts a text string as the first parameter and returns the first link element that has a partially matching link text.
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(); }
accepts 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.
accepts 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!");
accepts 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!";
returns true if document.readyState === "interactive" or if loaded is true
document.readyState === "interactive"
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->interactive()) { # redirecting to Test::More page }
returns true if document.readyState === "complete"
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 }
returns a list of MIME types that will be downloaded by firefox and made available from the downloads method
use Firefox::Marionette(); use v5.10; my $firefox = Firefox::Marionette->new(mime_types => [ 'application/pkcs10' ]) foreach my $mime_type ($firefox->mime_types()) { say $mime_type; }
returns 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; }
returns true if any files in downloads end in .part
.part
use Firefox::Marionette(); 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; }
accepts a scalar containing a javascript function that is executed in the browser, and an optional hash as a second parameter. Allowed keys are below;
args - The reference to a list is the arguments passed to the script.
scriptTime - A timeout to override the default scripts timeout.
sandbox - Name of the sandbox to evaluate the script in. The sandbox is cached for later re-use on the same windowobject if newSandbox is false. If he parameter is undefined, the script is evaluated in a mutable sandbox. If the parameter is "system", it will be evaluted in a sandbox with elevated system privileges, equivalent to chrome space.
newSandbox
newSandbox - Forces the script to be evaluated in a fresh sandbox. Note that if it is undefined, the script will normally be evaluted in a fresh sandbox.
filename - Filename of the client's program where this script is evaluated.
line - Line in the client's program where this script is evaluated.
debug_script - Attach an onerror event handler on the window object. It does not differentiate content errors from chrome errors.
directInject - Evaluate the script without wrapping it in a function.
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! }
The executing javascript is subject to the scripts timeout, which, by default is 30 seconds.
accepts a scalar containing a javascript function that is executed in the browser. This method returns itself to aid in chaining methods.
returns 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();
returns 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()->got('https://fastapi.metacpan.org/v1/download_url/Firefox::Marionette")->strip())->{version};
returns a JSON object that has been parsed from the page source of the content document. This is a convenience method that wraps the html method.
use Firefox::Marionette(); use v5.10; say Firefox::Marionette->new()->got('https://fastapi.metacpan.org/v1/download_url/Firefox::Marionette")->json()->{version};
returns the context type that is Marionette's current target for browsing context scoped commands.
accepts 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.
deletes a single cookie by name. Accepts a scalar containing the cookie name as a parameter. This method returns itself to aid in chaining methods.
here be cookie monsters! This method returns itself to aid in chaining methods.
returns the contents of the cookie jar in scalar or list context.
accepts 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.
accepts 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();
accepts 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();
accepts 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)
accepts an element as the first parameter. This method returns true or false depending on if the element is displayed.
accepts an element as the first parameter. This method returns true or false depending on if the element is enabled.
accepts an element as the first parameter. This method returns true or false depending on if the element is selected.
returns the active element of the current browsing context's document element, if the document element is non-null.
causes 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.
causes 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.
returns the current active frame if there is one in the current browsing context. Otherwise, this method returns undef.
accepts an element as a parameter and switches to it's shadow root
accepts a window handle (either the result of window_handles or a window name as a parameter and switches focus to this window.
accepts a frame as a parameter and switches to it within the current window.
set the current browsing context for future commands to the parent of the current browsing context
closes 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.
closes the current window/tab. It returns a list of still available window/tab handles.
full screens the firefox window. This method returns itself to aid in chaining methods.
minimises the firefox window. This method returns itself to aid in chaining methods.
maximises the firefox window. This method returns itself to aid in chaining methods.
refreshes 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.
Returns the message shown in a currently displayed modal message box
dismisses a currently displayed modal message box
accepts a currently displayed modal message box
sends keys to the input field of a currently displayed modal message box
returns the capabilities of the current firefox binary. You can retrieve timeouts or a proxy with this method.
returns 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).
returns 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;
hash - return a SHA256 hex encoded digest of the PNG image rather than the image itself
full - take a screenshot of the whole document unless the first element parameter has been supplied.
scroll - scroll to the element supplied
highlights - a reference to a list containing elements to draw a highlight around
accepts a Firefox::Marionette::Element object as the first parameter and returns the relevant tag name. For example 'a' or 'input'.
accepts 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.
accepts a element as the first parameter and returns the current position and size of the element
accepts a element as the first parameter and returns the text that is contained by that element (if any)
accepts a element as the first parameter and clears any user supplied input
accepts 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.
returns the current timeouts for page loading, searching, and scripts.
creates 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.
deletes the current WebDriver session.
returns the current window's type. This should be 'navigator:browser'.
returns 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.
returns 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.
Enables 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.
see chrome_window_handle.
returns 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.
returns identifiers for each open chrome window for tests interested in managing a set of chrome windows and tabs separately.
accepts the fully qualified path to an .xpi addon file as the first parameter and an optional true/false second parameter to indicate if the xpi addon file should be a temporary addition (just for the existance of this browser instance). Unsigned xpi addon files may be loaded temporarily. 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');
accepts 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.
returns the application type for the Marionette protocol. Should be 'gecko'.
returns the version for the Marionette protocol. Current most recent version is '3'.
returns 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.
returns the pid of the xvfb process if it exists.
Marionette 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 process
This method returns version of firefox.
This method returns the $? (CHILD_ERROR) for the Firefox process, or undefined if the process has not yet exited.
This 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.
This method returns true or false depending on if the Firefox process is still running.
Failed to correctly setup the Firefox process
The module was unable to retrieve a session id and capabilities from Firefox when it requests a new_session as part of the initial setup of the connection to Firefox.
Failed to correctly determined the Firefox process id through the initial connection capabilities
The module was found that firefox is reporting through it's Capabilities object a different process id than this module was using. This is probably a bug in this module's logic. Please report as described in the BUGS AND LIMITATIONS section below.
'%s --version' did not produce output that looks like 'Mozilla Firefox \\d+[.]\\d+([.]\\d+)?':%s
The Firefox binary did not produce a version number that could be recognised as a Firefox version number.
Failed to create process from '%s':%s
The module was to start Firefox process in a Win32 environment. Something is seriously wrong with your environment.
Failed to redirect %s to %s:%s
The module was unable to redirect a file handle's output. Something is seriously wrong with your environment.
Failed to exec %s:%s
The module was unable to run the Firefox binary. Check the path is correct and the current user has execute permissions.
Failed to fork:%s
The module was unable to fork itself, prior to executing a command. Check the current ulimit for max number of user processes.
ulimit
Failed to open directory '%s':%s
The module was unable to open a directory. Something is seriously wrong with your environment.
Failed to close directory '%s':%s
The module was unable to close a directory. Something is seriously wrong with your environment.
Failed to open '%s' for writing:%s
The module was unable to create a file in your temporary directory. Maybe your disk is full?
Failed to open temporary file for writing:%s
Failed to close '%s':%s
The module was unable to close a file in your temporary directory. Maybe your disk is full?
Failed to close temporary file:%s
Failed to create temporary directory:%s
The module was unable to create a directory in your temporary directory. Maybe your disk is full?
Failed to clear the close-on-exec flag on a temporary file:%s
The module was unable to call fcntl using F_SETFD for a file in your temporary directory. Something is seriously wrong with your environment.
Failed to seek to start of temporary file:%s
The module was unable to seek to the start of a file in your temporary directory. Something is seriously wrong with your environment.
Failed to create a socket:%s
The module was unable to even create a socket. Something is seriously wrong with your environment.
Failed to connect to %s on port %d:%s
The module was unable to connect to the Marionette port. This is probably a bug in this module's logic. Please report as described in the BUGS AND LIMITATIONS section below.
Firefox killed by a %s signal (%d)
Firefox crashed after being hit with a signal.
Firefox exited with a %d
Firefox has exited with an error code
Failed to bind socket:%s
The module was unable to bind a socket to any port. Something is seriously wrong with your environment.
Failed to close random socket:%s
The module was unable to close a socket without any reads or writes being performed on it. Something is seriously wrong with your environment.
moz:headless has not been determined correctly
The module was unable to correctly determine whether Firefox is running in "headless" or not. This is probably a bug in this module's logic. Please report as described in the BUGS AND LIMITATIONS section below.
%s method requires a Firefox::Marionette::Element parameter
This function was called incorrectly by your code. Please supply a Firefox::Marionette::Element parameter when calling this function.
Failed to write to temporary file:%s
The module was unable to write to a file in your temporary directory. Maybe your disk is full?
Failed to close socket to firefox:%s
The module was unable to even close a socket. Something is seriously wrong with your environment.
Failed to send request to firefox:%s
The module was unable to perform a syswrite on the socket connected to firefox. Maybe firefox crashed?
Failed to read size of response from socket to firefox:%s
The module was unable to read from the socket connected to firefox. Maybe firefox crashed?
Failed to read response from socket to firefox:%s
Firefox::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.
Firefox::Marionette requires the following non-core Perl modules
IPC::Run
JSON
URI
None reported.
Currently the following Marionette methods have not been implemented;
WebDriver:ReleaseAction
WebDriver:PerformActions
WebDriver:SetScreenOrientation
No bugs have been reported.
Please report any bugs or feature requests to bug-firefox-marionette@rt.cpan.org, or through the web interface at http://rt.cpan.org.
bug-firefox-marionette@rt.cpan.org
MozRepl
Selenium::Firefox
Firefox::Application
Mozilla::Mechanize
Gtk2::MozEmbed
David Dick <ddick@cpan.org>
<ddick@cpan.org>
Thanks to the entire Mozilla organisation for a great browser and to the team behind Marionette for providing an interface for automation.
Thanks also to the authors of the documentation in the following sources;
Marionette Protocol
Marionette Documentation
Marionette driver.js at github
about:config
nsIPrefService interface
Copyright (c) 2018, 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.
BECAUSE 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.
To install Firefox::Marionette, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Firefox::Marionette
CPAN shell
perl -MCPAN -e shell install Firefox::Marionette
For more information on module installation, please visit the detailed CPAN module installation guide.