{"id":15017587,"url":"https://github.com/david-dick/firefox-marionette","last_synced_at":"2025-04-09T19:42:26.044Z","repository":{"id":38363393,"uuid":"312532120","full_name":"david-dick/firefox-marionette","owner":"david-dick","description":"This is a client module to automate the Mozilla Firefox browser via the Marionette protocol","archived":false,"fork":false,"pushed_at":"2025-03-20T04:37:00.000Z","size":3220,"stargazers_count":16,"open_issues_count":3,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-20T05:27:30.729Z","etag":null,"topics":["anti-detection","anti-fingerprinting","aria","bookmark-manager","browser-automation","certificate-authorities","firefox-browser","headless-testing","marionette","marionette-client","mozilla-firefox","password-manager","perl","perl-module","perl5","perl5-module","root-certificates","shadow-dom","ssh-tunnel","waterfox"],"latest_commit_sha":null,"homepage":"https://metacpan.org/dist/Firefox-Marionette","language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/david-dick.png","metadata":{"files":{"readme":"README","changelog":"Changes","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-11-13T09:35:35.000Z","updated_at":"2025-03-20T04:37:04.000Z","dependencies_parsed_at":"2023-12-07T10:28:32.280Z","dependency_job_id":"91a72fe1-1e39-4f6d-b234-2e2e4dfca0e8","html_url":"https://github.com/david-dick/firefox-marionette","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/david-dick%2Ffirefox-marionette","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/david-dick%2Ffirefox-marionette/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/david-dick%2Ffirefox-marionette/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/david-dick%2Ffirefox-marionette/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/david-dick","download_url":"https://codeload.github.com/david-dick/firefox-marionette/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248101081,"owners_count":21047898,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["anti-detection","anti-fingerprinting","aria","bookmark-manager","browser-automation","certificate-authorities","firefox-browser","headless-testing","marionette","marionette-client","mozilla-firefox","password-manager","perl","perl-module","perl5","perl5-module","root-certificates","shadow-dom","ssh-tunnel","waterfox"],"created_at":"2024-09-24T19:50:43.282Z","updated_at":"2025-04-09T19:42:26.026Z","avatar_url":"https://github.com/david-dick.png","language":"Perl","funding_links":[],"categories":[],"sub_categories":[],"readme":"NAME\n\n    Firefox::Marionette - Automate the Firefox browser with the Marionette\n    protocol\n\nVERSION\n\n    Version 1.64\n\nSYNOPSIS\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n    \n        say $firefox-\u003efind_tag('title')-\u003eproperty('innerHTML'); # same as $firefox-\u003etitle();\n    \n        say $firefox-\u003ehtml();\n    \n        $firefox-\u003efind_class('page-content')-\u003efind_id('metacpan_search-input')-\u003etype('Test::More');\n    \n        say \"Height of page-content div is \" . $firefox-\u003efind_class('page-content')-\u003ecss('height');\n    \n        my $file_handle = $firefox-\u003eselfie();\n    \n        $firefox-\u003eawait(sub { $firefox-\u003efind_class('autocomplete-suggestion'); })-\u003eclick();\n    \n        $firefox-\u003efind_partial('Download')-\u003eclick();\n\nDESCRIPTION\n\n    This is a client module to automate the Mozilla Firefox browser via the\n    Marionette protocol\n    \u003chttps://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/Protocol\u003e\n\nCONSTANTS\n\n BCD_PATH\n\n    returns the local path used for storing the brower compability data for\n    the agent method when the stealth parameter is supplied to the new\n    method. This database is built by the build-bcd-for-firefox\n    \u003chttps://metacpan.org/pod/build-bcd-for-firefox\u003e binary.\n\nSUBROUTINES/METHODS\n\n accept_alert\n\n    accepts a currently displayed modal message box\n\n accept_connections\n\n    Enables or disables accepting new socket connections. By calling this\n    method with false the server will not accept any further connections,\n    but existing connections will not be forcible closed. Use true to\n    re-enable accepting connections.\n\n    Please note that when closing the connection via the client you can\n    end-up in a non-recoverable state if it hasn't been enabled before.\n\n active_element\n\n    returns the active element of the current browsing context's document\n    element, if the document element is non-null.\n\n add_bookmark\n\n    accepts a bookmark as a parameter and adds the specified bookmark to\n    the Firefox places database.\n\n        use Firefox::Marionette();\n    \n        my $bookmark = Firefox::Marionette::Bookmark-\u003enew(\n                         url   =\u003e 'https://metacpan.org',\n                         title =\u003e 'This is MetaCPAN!'\n                                 );\n        my $firefox = Firefox::Marionette-\u003enew()-\u003eadd_bookmark($bookmark);\n\n    This method returns itself to aid in chaining methods.\n\n add_certificate\n\n    accepts a hash as a parameter and adds the specified certificate to the\n    Firefox database with the supplied or default trust. Allowed keys are\n    below;\n\n      * path - a file system path to a single PEM encoded X.509 certificate\n      \u003chttps://datatracker.ietf.org/doc/html/rfc7468#section-5\u003e.\n\n      * string - a string containing a single PEM encoded X.509 certificate\n      \u003chttps://datatracker.ietf.org/doc/html/rfc7468#section-5\u003e\n\n      * trust - This is the trustargs\n      \u003chttps://www.mankier.com/1/certutil#-t\u003e value for NSS\n      \u003chttps://wiki.mozilla.org/NSS\u003e. If defaults to 'C,,';\n\n    This method returns itself to aid in chaining methods.\n\n        use Firefox::Marionette();\n    \n        my $pem_encoded_string = \u003c\u003c'_PEM_';\n        -----BEGIN CERTIFICATE-----\n        MII..\n        -----END CERTIFICATE-----\n        _PEM_\n        my $firefox = Firefox::Marionette-\u003enew()-\u003eadd_certificate(string =\u003e $pem_encoded_string);\n\n add_cookie\n\n    accepts a single cookie object as the first parameter and adds it to\n    the current cookie jar. This method returns itself to aid in chaining\n    methods.\n\n    This method throws an exception if you try to add a cookie for a\n    different domain than the current document\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/WebDriver/Errors/InvalidCookieDomain\u003e.\n\n add_header\n\n    accepts a hash of HTTP headers to include in every future HTTP Request.\n\n        use Firefox::Marionette();\n        use UUID();\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        my $uuid = UUID::uuid();\n        $firefox-\u003eadd_header( 'Track-my-automated-tests' =\u003e $uuid );\n        $firefox-\u003ego('https://metacpan.org/');\n\n    these headers are added to any existing headers. To clear headers, see\n    the delete_header method\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003edelete_header( 'Accept' )-\u003eadd_header( 'Accept' =\u003e 'text/perl' )-\u003ego('https://metacpan.org/');\n\n    will only send out an Accept\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept\u003e\n    header that looks like Accept: text/perl.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003eadd_header( 'Accept' =\u003e 'text/perl' )-\u003ego('https://metacpan.org/');\n\n    by itself, will send out an Accept\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept\u003e\n    header that may resemble Accept:\n    text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8,\n    text/perl. This method returns itself to aid in chaining methods.\n\n add_login\n\n    accepts a hash of the following keys;\n\n      * host - The scheme + hostname of the page where the login applies,\n      for example 'https://www.example.org'.\n\n      * user - The username for the login.\n\n      * password - The password for the login.\n\n      * origin - The scheme + hostname that the form-based login was\n      submitted to\n      \u003chttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-action\u003e.\n      Forms with no action attribute default to submitting to the URL of\n      the page containing the login form, so that is stored here. This\n      field should be omitted (it will be set to undef) for http auth type\n      authentications and \"\" means to match against any form action.\n\n      * realm - The HTTP Realm for which the login was requested. When an\n      HTTP server sends a 401 result, the WWW-Authenticate header includes\n      a realm. See RFC 2617\n      \u003chttps://datatracker.ietf.org/doc/html/rfc2617\u003e. If the realm is not\n      specified, or it was blank, the hostname is used instead. For HTML\n      form logins, this field should not be specified.\n\n      * user_field - The name attribute for the username input in a form.\n      Non-form logins should not specify this field.\n\n      * password_field - The name attribute for the password input in a\n      form. Non-form logins should not specify this field.\n\n    or a Firefox::Marionette::Login object as the first parameter and adds\n    the login to the Firefox login database.\n\n        use Firefox::Marionette();\n        use UUID();\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n    \n        # for http auth logins\n    \n        my $http_auth_login = Firefox::Marionette::Login-\u003enew(host =\u003e 'https://pause.perl.org', user =\u003e 'AUSER', password =\u003e 'qwerty', realm =\u003e 'PAUSE');\n        $firefox-\u003eadd_login($http_auth_login);\n        $firefox-\u003ego('https://pause.perl.org/pause/authenquery')-\u003eaccept_alert(); # this goes to the page and submits the http auth popup\n    \n        # for form based login\n    \n        my $form_login = Firefox::Marionette::Login(host =\u003e 'https://github.com', user =\u003e 'me2@example.org', password =\u003e 'uiop[]', user_field =\u003e 'login', password_field =\u003e 'password');\n        $firefox-\u003eadd_login($form_login);\n    \n        # or just directly\n    \n        $firefox-\u003eadd_login(host =\u003e 'https://github.com', user =\u003e 'me2@example.org', password =\u003e 'uiop[]', user_field =\u003e 'login', password_field =\u003e 'password');\n\n    Note for HTTP Authentication, the realm\n    \u003chttps://datatracker.ietf.org/doc/html/rfc2617#section-2\u003e must\n    perfectly match the correct realm supplied by the server.\n\n    This method returns itself to aid in chaining methods.\n\n add_site_header\n\n    accepts a host name and a hash of HTTP headers to include in every\n    future HTTP Request that is being sent to that particular host.\n\n        use Firefox::Marionette();\n        use UUID();\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        my $uuid = UUID::uuid();\n        $firefox-\u003eadd_site_header( 'metacpan.org', 'Track-my-automated-tests' =\u003e $uuid );\n        $firefox-\u003ego('https://metacpan.org/');\n\n    these headers are added to any existing headers going to the\n    metacpan.org site, but no other site. To clear site headers, see the\n    delete_site_header method\n\n add_webauthn_authenticator\n\n    accepts a hash of the following keys;\n\n      * has_resident_key - boolean value to indicate if the authenticator\n      will support client side discoverable credentials\n      \u003chttps://www.w3.org/TR/webauthn-2/#client-side-discoverable-credential\u003e\n\n      * has_user_verification - boolean value to determine if the\n      authenticator\n      \u003chttps://www.w3.org/TR/webauthn-2/#virtual-authenticators\u003e supports\n      user verification\n      \u003chttps://www.w3.org/TR/webauthn-2/#user-verification\u003e.\n\n      * is_user_consenting - boolean value to determine the result of all\n      user consent \u003chttps://www.w3.org/TR/webauthn-2/#user-consent\u003e\n      authorization gestures\n      \u003chttps://www.w3.org/TR/webauthn-2/#authorization-gesture\u003e, and by\n      extension, any test of user presence\n      \u003chttps://www.w3.org/TR/webauthn-2/#test-of-user-presence\u003e performed\n      on the Virtual Authenticator\n      \u003chttps://www.w3.org/TR/webauthn-2/#virtual-authenticators\u003e. If set to\n      true, a user consent will always be granted. If set to false, it will\n      not be granted.\n\n      * is_user_verified - boolean value to determine the result of User\n      Verification \u003chttps://www.w3.org/TR/webauthn-2/#user-verification\u003e\n      performed on the Virtual Authenticator\n      \u003chttps://www.w3.org/TR/webauthn-2/#virtual-authenticators\u003e. If set to\n      true, User Verification will always succeed. If set to false, it will\n      fail.\n\n      * protocol - the protocol spoken by the authenticator. This may be\n      CTAP1_U2F, CTAP2 or CTAP2_1.\n\n      * transport - the transport simulated by the authenticator. This may\n      be BLE, HYBRID, INTERNAL, NFC, SMART_CARD or USB.\n\n    It returns the newly created authenticator.\n\n        use Firefox::Marionette();\n        use Crypt::URandom();\n    \n        my $user_name = MIME::Base64::encode_base64( Crypt::URandom::urandom( 10 ), q[] ) . q[@example.com];\n        my $firefox = Firefox::Marionette-\u003enew( webauthn =\u003e 0 );\n        my $authenticator = $firefox-\u003eadd_webauthn_authenticator( transport =\u003e Firefox::Marionette::WebAuthn::Authenticator::INTERNAL(), protocol =\u003e Firefox::Marionette::WebAuthn::Authenticator::CTAP2() );\n        $firefox-\u003ego('https://webauthn.io');\n        $firefox-\u003efind_id('input-email')-\u003etype($user_name);\n        $firefox-\u003efind_id('register-button')-\u003eclick();\n        $firefox-\u003eawait(sub { sleep 1; $firefox-\u003efind_class('alert-success'); });\n        $firefox-\u003efind_id('login-button')-\u003eclick();\n        $firefox-\u003eawait(sub { sleep 1; $firefox-\u003efind_class('hero confetti'); });\n\n add_webauthn_credential\n\n    accepts a hash of the following keys;\n\n      * authenticator - contains the authenticator that the credential will\n      be added to. If this parameter is not supplied, the credential will\n      be added to the default authenticator, if one exists.\n\n      * host - contains the domain that this credential is to be used for.\n      In the language of WebAuthn \u003chttps://www.w3.org/TR/webauthn-2\u003e, this\n      field is referred to as the relying party identifier\n      \u003chttps://www.w3.org/TR/webauthn-2/#relying-party-identifier\u003e or RP ID\n      \u003chttps://www.w3.org/TR/webauthn-2/#rp-id\u003e.\n\n      * id - contains the unique id for this credential, also known as the\n      Credential ID \u003chttps://www.w3.org/TR/webauthn-2/#credential-id\u003e. If\n      this is not supplied, one will be generated.\n\n      * is_resident - contains a boolean that if set to true, a client-side\n      discoverable credential\n      \u003chttps://w3c.github.io/webauthn/#client-side-discoverable-credential\u003e\n      is created. If set to false, a server-side credential\n      \u003chttps://w3c.github.io/webauthn/#server-side-credential\u003e is created\n      instead.\n\n      * private_key - either a RFC5958\n      \u003chttps://www.rfc-editor.org/rfc/rfc5958\u003e encoded private key encoded\n      using encode_base64url or a hash containing the following keys;\n\n\t* name - contains the name of the private key algorithm, such as\n\t\"RSA-PSS\" (the default), \"RSASSA-PKCS1-v1_5\", \"ECDSA\" or \"ECDH\".\n\n\t* size - contains the modulus length of the private key. This is\n\tonly valid for \"RSA-PSS\" or \"RSASSA-PKCS1-v1_5\" private keys.\n\n\t* hash - contains the name of the hash algorithm, such as \"SHA-512\"\n\t(the default). This is only valid for \"RSA-PSS\" or\n\t\"RSASSA-PKCS1-v1_5\" private keys.\n\n\t* curve - contains the name of the curve for the private key, such\n\tas \"P-384\" (the default). This is only valid for \"ECDSA\" or \"ECDH\"\n\tprivate keys.\n\n      * sign_count - contains the initial value for a signature counter\n      \u003chttps://w3c.github.io/webauthn/#signature-counter\u003e associated to the\n      public key credential source\n      \u003chttps://w3c.github.io/webauthn/#public-key-credential-source\u003e. It\n      will default to 0 (zero).\n\n      * user - contains the userHandle\n      \u003chttps://w3c.github.io/webauthn/#public-key-credential-source-userhandle\u003e\n      associated to the credential encoded using encode_base64url. This\n      property is optional.\n\n    It returns the newly created credential. If of course, the credential\n    is just created, it probably won't be much good by itself. However, you\n    can use it to recreate a credential, so long as you know all the\n    parameters.\n\n        use Firefox::Marionette();\n        use Crypt::URandom();\n    \n        my $user_name = MIME::Base64::encode_base64( Crypt::URandom::urandom( 10 ), q[] ) . q[@example.com];\n        my $firefox = Firefox::Marionette-\u003enew();\n        $firefox-\u003ego('https://webauthn.io');\n        $firefox-\u003efind_id('input-email')-\u003etype($user_name);\n        $firefox-\u003efind_id('register-button')-\u003eclick();\n        $firefox-\u003eawait(sub { sleep 1; $firefox-\u003efind_class('alert-success'); });\n        $firefox-\u003efind_id('login-button')-\u003eclick();\n        $firefox-\u003eawait(sub { sleep 1; $firefox-\u003efind_class('hero confetti'); });\n        foreach my $credential ($firefox-\u003ewebauthn_credentials()) {\n            $firefox-\u003edelete_webauthn_credential($credential);\n\n    # ... time passes ...\n\n            $firefox-\u003eadd_webauthn_credential(\n                      id            =\u003e $credential-\u003eid(),\n                      host          =\u003e $credential-\u003ehost(),\n                      user          =\u003e $credential-\u003euser(),\n                      private_key   =\u003e $credential-\u003eprivate_key(),\n                      is_resident   =\u003e $credential-\u003eis_resident(),\n                      sign_count    =\u003e $credential-\u003esign_count(),\n                                  );\n        }\n        $firefox-\u003ego('about:blank');\n        $firefox-\u003eclear_cache(Firefox::Marionette::Cache::CLEAR_COOKIES());\n        $firefox-\u003ego('https://webauthn.io');\n        $firefox-\u003efind_id('input-email')-\u003etype($user_name);\n        $firefox-\u003efind_id('login-button')-\u003eclick();\n        $firefox-\u003eawait(sub { sleep 1; $firefox-\u003efind_class('hero confetti'); });\n\n addons\n\n    returns if pre-existing addons (extensions/themes) are allowed to run.\n    This will be true for Firefox versions less than 55, as -safe-mode\n    \u003chttp://kb.mozillazine.org/Command_line_arguments#List_of_command_line_arguments_.28incomplete.29\u003e\n    cannot be automated.\n\n agent\n\n    accepts an optional value for the User-Agent\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent\u003e\n    header and sets this using the profile preferences and inserting\n    javascript into the current page. It returns the current value, such as\n    'Mozilla/5.0 (\u003csystem-information\u003e) \u003cplatform\u003e (\u003cplatform-details\u003e)\n    \u003cextensions\u003e'. This value is retrieved with navigator.userAgent\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/API/Navigator/userAgent\u003e.\n\n    This method can be used to set a user agent string like so;\n\n        use Firefox::Marionette();\n        use strict;\n    \n        # useragents.me should only be queried once a month or less.\n        # these UA strings should be cached locally.\n    \n        my %user_agent_strings = map { $_-\u003e{ua} =\u003e $_-\u003e{pct} } @{$firefox-\u003ejson(\"https://www.useragents.me/api\")-\u003e{data}};\n        my ($user_agent) = reverse sort { $user_agent_strings{$a} \u003c=\u003e $user_agent_strings{$b} } keys %user_agent_strings;\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        $firefox-\u003eagent($user_agent); # agent is now the most popular agent from useragents.me\n\n    If the user agent string that is passed as a parameter looks like a\n    Chrome \u003chttps://www.google.com/chrome/\u003e, Edge\n    \u003chttps://microsoft.com/edge\u003e or Safari \u003chttps://www.apple.com/safari/\u003e\n    user agent string, then this method will also try and change other\n    profile preferences to match the new agent string. These parameters\n    are;\n\n      * general.appversion.override\n\n      * general.oscpu.override\n\n      * general.platform.override\n\n      * network.http.accept\n\n      * network.http.accept-encoding\n\n      * network.http.accept-encoding.secure\n\n      * privacy.donottrackheader.enabled\n\n    In addition, this method will accept a hash of values as parameters as\n    well. When a hash is provided, this method will alter specific parts of\n    the normal Firefox User Agent. These hash parameters are;\n\n      * os - The desired operating system, known values are \"linux\",\n      \"win32\", \"darwin\", \"freebsd\", \"netbsd\", \"openbsd\" and \"dragonfly\"\n\n      * version - A specific version of firefox, such as 120.\n\n      * arch - A specific version of the architecture, such as \"x86_64\" or\n      \"aarch64\" or \"s390x\".\n\n      * increment - A specific offset from the actual version of firefox,\n      such as -5\n\n    These parameters can be used to set a user agent string like so;\n\n        use Firefox::Marionette();\n        use strict;\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        $firefox-\u003eagent(os =\u003e 'freebsd', version =\u003e 118);\n    \n        # user agent is now equal to\n        # Mozilla/5.0 (X11; FreeBSD amd64; rv:109.0) Gecko/20100101 Firefox/118.0\n    \n        $firefox-\u003eagent(os =\u003e 'linux', arch =\u003e 's390x', version =\u003e 115);\n        # user agent is now equal to\n        # Mozilla/5.0 (X11; Linux s390x; rv:109.0) Gecko/20100101 Firefox/115.0\n\n    If the stealth parameter has supplied to the new method, it will also\n    attempt to create known specific javascript functions to imitate the\n    required browser. If the database built by build-bcd-for-firefox\n    \u003chttps://metacpan.org/pod/build-bcd-for-firefox\u003e is accessible, then it\n    will also attempt to delete/provide dummy implementations for the\n    corresponding javascript attributes\n    \u003chttps://github.com/mdn/browser-compat-data\u003e for the desired browser.\n    The following websites have been very useful in testing these ideas;\n\n      * https://browserleaks.com/javascript\n\n      * https://www.amiunique.org/fingerprint\n\n      * https://bot.sannysoft.com/\n\n      * https://lraj22.github.io/browserfeatcl/\n\n    Importantly, this will break feature detection\n    \u003chttps://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Feature_detection\u003e\n    for any website that relies on it.\n\n    See IMITATING OTHER BROWSERS a discussion of these types of techniques.\n    These changes are not foolproof, but it is interesting to see what can\n    be done with modern browsers. All this behaviour should be regarded as\n    extremely experimental and subject to change. Feedback welcome.\n\n alert_text\n\n    Returns the message shown in a currently displayed modal message box\n\n alive\n\n    This method returns true or false depending on if the Firefox process\n    is still running.\n\n application_type\n\n    returns the application type for the Marionette protocol. Should be\n    'gecko'.\n\n arch\n\n    returns the architecture of the machine running firefox. Should be\n    something like 'x86_64' or 'arm'. This is only intended for test suite\n    support.\n\n aria_label\n\n    accepts an element as the parameter. It returns the ARIA label\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label\u003e\n    for the element.\n\n aria_role\n\n    accepts an element as the parameter. It returns the ARIA role\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles\u003e\n    for the element.\n\n async_script\n\n    accepts a scalar containing a javascript function that is executed in\n    the browser. This method returns itself to aid in chaining methods.\n\n    The executing javascript is subject to the script timeout, which, by\n    default is 30 seconds.\n\n attribute\n\n    accepts an element as the first parameter and a scalar attribute name\n    as the second parameter. It returns the initial value of the attribute\n    with the supplied name. This method will return the initial content\n    from the HTML source code, the property method will return the current\n    content.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        my $element = $firefox-\u003efind_id('metacpan_search-input');\n        !defined $element-\u003eattribute('value') or die \"attribute is defined but did not exist in the html source!\";\n        $element-\u003etype('Test::More');\n        !defined $element-\u003eattribute('value') or die \"attribute has changed but only the property should have changed!\";\n\n await\n\n    accepts a subroutine reference as a parameter and then executes the\n    subroutine. If a not found exception is thrown, this method will sleep\n    for sleep_time_in_ms milliseconds and then execute the subroutine\n    again. When the subroutine executes successfully, it will return what\n    the subroutine returns.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew(sleep_time_in_ms =\u003e 5)-\u003ego('https://metacpan.org/');\n    \n        $firefox-\u003efind_id('metacpan_search-input')-\u003etype('Test::More');\n    \n        $firefox-\u003eawait(sub { $firefox-\u003efind_class('autocomplete-suggestion'); })-\u003eclick();\n\n back\n\n    causes the browser to traverse one step backward in the joint history\n    of the current browsing context. The browser will wait for the one step\n    backward to complete or the session's page_load duration to elapse\n    before returning, which, by default is 5 minutes. This method returns\n    itself to aid in chaining methods.\n\n debug\n\n    accept a boolean and return the current value of the debug setting.\n    This allows the dynamic setting of debug.\n\n default_binary_name\n\n    just returns the string 'firefox'. Only of interest when sub-classing.\n\n download\n\n    accepts a URI and an optional timeout in seconds (the default is 5\n    minutes) as parameters and downloads the URI in the background and\n    returns a handle to the downloaded file.\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n    \n        my $handle = $firefox-\u003edownload('https://raw.githubusercontent.com/david-dick/firefox-marionette/master/t/data/keepassxs.csv');\n    \n        foreach my $line (\u003c$handle\u003e) {\n          print $line;\n        }\n\n bookmarks\n\n    accepts either a scalar or a hash as a parameter. The scalar may by the\n    title of a bookmark or the URL of the bookmark. The hash may have the\n    following keys;\n\n      * title - The title of the bookmark.\n\n      * url - The url of the bookmark.\n\n    returns a list of all Firefox::Marionette::Bookmark objects that match\n    the supplied parameters (if any).\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n    \n        foreach my $bookmark ($firefox-\u003ebookmarks(title =\u003e 'This is MetaCPAN!')) {\n          say \"Bookmark found\";\n        }\n    \n        # OR\n    \n        foreach my $bookmark ($firefox-\u003ebookmarks()) {\n          say \"Bookmark found with URL \" . $bookmark-\u003eurl();\n        }\n    \n        # OR\n    \n        foreach my $bookmark ($firefox-\u003ebookmarks('https://metacpan.org')) {\n          say \"Bookmark found\";\n        }\n\n browser_version\n\n    This method returns the current version of firefox.\n\n bye\n\n    accepts a subroutine reference as a parameter and then executes the\n    subroutine. If the subroutine executes successfully, this method will\n    sleep for sleep_time_in_ms milliseconds and then execute the subroutine\n    again. When a not found exception is thrown, this method will return\n    itself to aid in chaining methods.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n    \n        $firefox-\u003efind_id('metacpan_search-input')-\u003etype('Test::More');\n    \n        $firefox-\u003eawait(sub { $firefox-\u003efind_class('autocomplete-suggestion'); })-\u003eclick();\n    \n        $firefox-\u003ebye(sub { $firefox-\u003efind_name('metacpan_search-input') })-\u003eawait(sub { $firefox-\u003einteractive() \u0026\u0026 $firefox-\u003efind_partial('Download') })-\u003eclick();\n\n cache_keys\n\n    returns the set of all cache keys from Firefox::Marionette::Cache.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        foreach my $key_name ($firefox-\u003ecache_keys()) {\n          my $key_value = $firefox-\u003echeck_cache_key($key_name);\n          if (Firefox::Marionette::Cache-\u003e$key_name() != $key_value) {\n            warn \"This module this the value of $key_name is \" . Firefox::Marionette::Cache-\u003e$key_name();\n            warn \"Firefox thinks the value of   $key_name is $key_value\";\n          }\n        }\n\n capabilities\n\n    returns the capabilities of the current firefox binary. You can\n    retrieve timeouts or a proxy with this method.\n\n certificate_as_pem\n\n    accepts a certificate stored in the Firefox database as a parameter and\n    returns a PEM encoded X.509 certificate\n    \u003chttps://datatracker.ietf.org/doc/html/rfc7468#section-5\u003e as a string.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n    \n        # Generating a ca-bundle.crt to STDOUT from the current firefox instance\n    \n        foreach my $certificate (sort { $a-\u003edisplay_name() cmp $b-\u003edisplay_name } $firefox-\u003ecertificates()) {\n            if ($certificate-\u003eis_ca_cert()) {\n                print '# ' . $certificate-\u003edisplay_name() . \"\\n\" . $firefox-\u003ecertificate_as_pem($certificate) . \"\\n\";\n            }\n        }\n\n    The ca-bundle-for-firefox\n    \u003chttps://metacpan.org/pod/ca-bundle-for-firefox\u003e command that is\n    provided as part of this distribution does this.\n\n certificates\n\n    returns a list of all known certificates in the Firefox database.\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        # Sometimes firefox can neglect old certificates.  See https://bugzilla.mozilla.org/show_bug.cgi?id=1710716\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        foreach my $certificate (grep { $_-\u003eis_ca_cert() \u0026\u0026 $_-\u003enot_valid_after() \u003c time } $firefox-\u003ecertificates()) {\n            say \"The \" . $certificate-\u003edisplay_name() \" . certificate has expired and should be removed\";\n            print 'PEM Encoded Certificate ' . \"\\n\" . $firefox-\u003ecertificate_as_pem($certificate) . \"\\n\";\n        }\n\n    This method returns itself to aid in chaining methods.\n\n check_cache_key\n\n    accepts a cache_key as a parameter.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        foreach my $key_name ($firefox-\u003ecache_keys()) {\n          my $key_value = $firefox-\u003echeck_cache_key($key_name);\n          if (Firefox::Marionette::Cache-\u003e$key_name() != $key_value) {\n            warn \"This module this the value of $key_name is \" . Firefox::Marionette::Cache-\u003e$key_name();\n            warn \"Firefox thinks the value of   $key_name is $key_value\";\n          }\n        }\n\n    This method returns the cache_key's actual value from firefox as a\n    number. This may differ from the current value of the key from\n    Firefox::Marionette::Cache as these values have changed as firefox has\n    evolved.\n\n child_error\n\n    This method returns the $? (CHILD_ERROR) for the Firefox process, or\n    undefined if the process has not yet exited.\n\n chrome\n\n    changes the scope of subsequent commands to chrome context. This allows\n    things like interacting with firefox menu's and buttons outside of the\n    browser window.\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003echrome();\n        $firefox-\u003escript(...); # running script in chrome context\n        $firefox-\u003econtent();\n\n    See the context method for an alternative methods for changing the\n    context.\n\n chrome_window_handle\n\n    returns a server-assigned identifier for the current chrome window that\n    uniquely identifies it within this Marionette instance. This can be\n    used to switch to this window at a later point. This corresponds to a\n    window that may itself contain tabs. This method is replaced by\n    window_handle and appropriate context calls for Firefox 94 and after\n    \u003chttps://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/94#webdriver_conformance_marionette\u003e.\n\n chrome_window_handles\n\n    returns identifiers for each open chrome window for tests interested in\n    managing a set of chrome windows and tabs separately. This method is\n    replaced by window_handles and appropriate context calls for Firefox 94\n    and after\n    \u003chttps://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/94#webdriver_conformance_marionette\u003e.\n\n clear\n\n    accepts a element as the first parameter and clears any user supplied\n    input\n\n clear_cache\n\n    accepts a single flag parameter, which can be an ORed set of keys from\n    Firefox::Marionette::Cache and clears the appropriate sections of the\n    cache. If no flags parameter is supplied, the default is CLEAR_ALL.\n    Note that this method, unlike delete_cookies will actually delete all\n    cookies for all hosts, not just the current webpage.\n\n        use Firefox::Marionette();\n        use Firefox::Marionette::Cache qw(:all);\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://do.lots.of.evil/')-\u003eclear_cache(); # default clear all\n    \n        $firefox-\u003ego('https://cookies.r.us')-\u003eclear_cache(CLEAR_COOKIES());\n\n    This method returns itself to aid in chaining methods.\n\n clear_pref\n\n    accepts a preference \u003chttp://kb.mozillazine.org/About:config\u003e name and\n    restores it to the original value. See the get_pref and set_pref\n    methods to get a preference value and to set to it to a particular\n    value. This method returns itself to aid in chaining methods.\n\n        use Firefox::Marionette();\n        my $firefox = Firefox::Marionette-\u003enew();\n    \n        $firefox-\u003eclear_pref('browser.search.defaultenginename');\n\n click\n\n    accepts a element as the first parameter and sends a 'click' to it. The\n    browser will wait for any page load to complete or the session's\n    page_load duration to elapse before returning, which, by default is 5\n    minutes. The click method is also used to choose an option in a select\n    dropdown.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew(visible =\u003e 1)-\u003ego('https://ebay.com');\n        my $select = $firefox-\u003efind_tag('select');\n        foreach my $option ($select-\u003efind_tag('option')) {\n            if ($option-\u003eproperty('value') == 58058) { # Computers/Tablets \u0026 Networking\n                $option-\u003eclick();\n            }\n        }\n\n close_current_chrome_window_handle\n\n    closes the current chrome window (that is the entire window, not just\n    the tabs). It returns a list of still available chrome window handles.\n    You will need to switch_to_window to use another window.\n\n close_current_window_handle\n\n    closes the current window/tab. It returns a list of still available\n    window/tab handles.\n\n content\n\n    changes the scope of subsequent commands to browsing context. This is\n    the default for when firefox starts and restricts commands to operating\n    in the browser window only.\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003echrome();\n        $firefox-\u003escript(...); # running script in chrome context\n        $firefox-\u003econtent();\n\n    See the context method for an alternative methods for changing the\n    context.\n\n context\n\n    accepts a string as the first parameter, which may be either 'content'\n    or 'chrome'. It returns the context type that is Marionette's current\n    target for browsing context scoped commands.\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        if ($firefox-\u003econtext() eq 'content') {\n           say \"I knew that was going to happen\";\n        }\n        my $old_context = $firefox-\u003econtext('chrome');\n        $firefox-\u003escript(...); # running script in chrome context\n        $firefox-\u003econtext($old_context);\n\n    See the content and chrome methods for alternative methods for changing\n    the context.\n\n cookies\n\n    returns the contents of the cookie jar in scalar or list context.\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://github.com');\n        foreach my $cookie ($firefox-\u003ecookies()) {\n            if (defined $cookie-\u003esame_site()) {\n                say \"Cookie \" . $cookie-\u003ename() . \" has a SameSite of \" . $cookie-\u003esame_site();\n            } else {\n                warn \"Cookie \" . $cookie-\u003ename() . \" does not have the SameSite attribute defined\";\n            }\n        }\n\n css\n\n    accepts an element as the first parameter and a scalar CSS property\n    name as the second parameter. It returns the value of the computed\n    style for that property.\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        say $firefox-\u003efind_id('metacpan_search-input')-\u003ecss('height');\n\n current_chrome_window_handle\n\n    see chrome_window_handle.\n\n delete_bookmark\n\n    accepts a bookmark as a parameter and deletes the bookmark from the\n    Firefox database.\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        foreach my $bookmark (reverse $firefox-\u003ebookmarks()) {\n          if ($bookmark-\u003eparent_guid() ne Firefox::Marionette::Bookmark::ROOT()) {\n            $firefox-\u003edelete_bookmark($bookmark);\n          }\n        }\n        say \"Bookmarks? We don't need no stinking bookmarks!\";\n\n    This method returns itself to aid in chaining methods.\n\n delete_certificate\n\n    accepts a certificate stored in the Firefox database as a parameter and\n    deletes/distrusts the certificate from the Firefox database.\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        foreach my $certificate ($firefox-\u003ecertificates()) {\n            if ($certificate-\u003eis_ca_cert()) {\n                $firefox-\u003edelete_certificate($certificate);\n            } else {\n                say \"This \" . $certificate-\u003edisplay_name() \" certificate is NOT a certificate authority, therefore it is not being deleted\";\n            }\n        }\n        say \"Good luck visiting a HTTPS website!\";\n\n    This method returns itself to aid in chaining methods.\n\n delete_cookie\n\n    deletes a single cookie by name. Accepts a scalar containing the cookie\n    name as a parameter. This method returns itself to aid in chaining\n    methods.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://github.com');\n        foreach my $cookie ($firefox-\u003ecookies()) {\n            warn \"Cookie \" . $cookie-\u003ename() . \" is being deleted\";\n            $firefox-\u003edelete_cookie($cookie-\u003ename());\n        }\n        foreach my $cookie ($firefox-\u003ecookies()) {\n            die \"Should be no cookies here now\";\n        }\n\n delete_cookies\n\n    Here be cookie monsters! Note that this method will only delete cookies\n    for the current site. See clear_cache for an alternative. This method\n    returns itself to aid in chaining methods.\n\n delete_header\n\n    accepts a list of HTTP header names to delete from future HTTP\n    Requests.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        $firefox-\u003edelete_header( 'User-Agent', 'Accept', 'Accept-Encoding' );\n\n    will remove the User-Agent\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent\u003e,\n    Accept\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept\u003e and\n    Accept-Encoding\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding\u003e\n    headers from all future requests\n\n    This method returns itself to aid in chaining methods.\n\n delete_login\n\n    accepts a login as a parameter.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        foreach my $login ($firefox-\u003elogins()) {\n            if ($login-\u003euser() eq 'me@example.org') {\n                $firefox-\u003edelete_login($login);\n            }\n        }\n\n    will remove the logins with the username matching 'me@example.org'.\n\n    This method returns itself to aid in chaining methods.\n\n delete_logins\n\n    This method empties the password database.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        $firefox-\u003edelete_logins();\n\n    This method returns itself to aid in chaining methods.\n\n delete_session\n\n    deletes the current WebDriver session.\n\n delete_site_header\n\n    accepts a host name and a list of HTTP headers names to delete from\n    future HTTP Requests.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        $firefox-\u003edelete_header( 'metacpan.org', 'User-Agent', 'Accept', 'Accept-Encoding' );\n\n    will remove the User-Agent\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent\u003e,\n    Accept\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept\u003e and\n    Accept-Encoding\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding\u003e\n    headers from all future requests to metacpan.org.\n\n    This method returns itself to aid in chaining methods.\n\n delete_webauthn_all_credentials\n\n    This method accepts an optional authenticator, in which case it will\n    delete all credentials from this authenticator. If no parameter is\n    supplied, the default authenticator will have all credentials deleted.\n\n        my $firefox = Firefox::Marionette-\u003enew();\n        my $authenticator = $firefox-\u003eadd_webauthn_authenticator( transport =\u003e Firefox::Marionette::WebAuthn::Authenticator::INTERNAL(), protocol =\u003e Firefox::Marionette::WebAuthn::Authenticator::CTAP2() );\n        $firefox-\u003edelete_webauthn_all_credentials($authenticator);\n        $firefox-\u003edelete_webauthn_all_credentials();\n\n delete_webauthn_authenticator\n\n    This method accepts an optional authenticator, in which case it will\n    delete this authenticator from the current Firefox instance. If no\n    parameter is supplied, the default authenticator will be deleted.\n\n        my $firefox = Firefox::Marionette-\u003enew();\n        my $authenticator = $firefox-\u003eadd_webauthn_authenticator( transport =\u003e Firefox::Marionette::WebAuthn::Authenticator::INTERNAL(), protocol =\u003e Firefox::Marionette::WebAuthn::Authenticator::CTAP2() );\n        $firefox-\u003edelete_webauthn_authenticator($authenticator);\n        $firefox-\u003edelete_webauthn_authenticator();\n\n delete_webauthn_credential\n\n    This method accepts either a credential and an authenticator, in which\n    case it will remove the credential from the supplied authenticator or\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        my $authenticator = $firefox-\u003eadd_webauthn_authenticator( transport =\u003e Firefox::Marionette::WebAuthn::Authenticator::INTERNAL(), protocol =\u003e Firefox::Marionette::WebAuthn::Authenticator::CTAP2() );\n        foreach my $credential ($firefox-\u003ewebauthn_credentials($authenticator)) {\n            $firefox-\u003edelete_webauthn_credential($credential, $authenticator);\n        }\n\n    just a credential, in which case it will remove the credential from the\n    default authenticator.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        ...\n        foreach my $credential ($firefox-\u003ewebauthn_credentials()) {\n            $firefox-\u003edelete_webauthn_credential($credential);\n        }\n\n    This method returns itself to aid in chaining methods.\n\n developer\n\n    returns true if the current version of firefox is a developer edition\n    \u003chttps://www.mozilla.org/en-US/firefox/developer/\u003e (does the minor\n    version number end with an 'b\\d+'?) version.\n\n dismiss_alert\n\n    dismisses a currently displayed modal message box\n\n displays\n\n    accepts an optional regex to filter against the usage for the display\n    and returns a list of all the known displays\n    \u003chttps://en.wikipedia.org/wiki/List_of_common_resolutions\u003e as a\n    Firefox::Marionette::Display.\n\n        use Firefox::Marionette();\n        use Encode();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew( visible =\u003e 1, kiosk =\u003e 1 )-\u003ego('http://metacpan.org');;\n        my $element = $firefox-\u003efind_id('metacpan_search-input');\n        foreach my $display ($firefox-\u003edisplays(qr/iphone/smxi)) {\n            say 'Can Firefox resize for \"' . Encode::encode('UTF-8', $display-\u003eusage(), 1) . '\"?';\n            if ($firefox-\u003eresize($display-\u003ewidth(), $display-\u003eheight())) {\n                say 'Now displaying with a Pixel aspect ratio of ' . $display-\u003epar();\n                say 'Now displaying with a Storage aspect ratio of ' . $display-\u003esar();\n                say 'Now displaying with a Display aspect ratio of ' . $display-\u003edar();\n            } else {\n                say 'Apparently NOT!';\n            }\n        }\n\n downloaded\n\n    accepts a filesystem path and returns a matching filehandle. This is\n    trivial for locally running firefox, but sufficiently complex to\n    justify the method for a remote firefox running over ssh.\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew( host =\u003e '10.1.2.3' )-\u003ego('https://metacpan.org/');\n    \n        $firefox-\u003efind_class('page-content')-\u003efind_id('metacpan_search-input')-\u003etype('Test::More');\n    \n        $firefox-\u003eawait(sub { $firefox-\u003efind_class('autocomplete-suggestion'); })-\u003eclick();\n    \n        $firefox-\u003efind_partial('Download')-\u003eclick();\n    \n        while(!$firefox-\u003edownloads()) { sleep 1 }\n    \n        foreach my $path ($firefox-\u003edownloads()) {\n    \n            my $handle = $firefox-\u003edownloaded($path);\n    \n            # do something with downloaded file handle\n    \n        }\n\n downloading\n\n    returns true if any files in downloads end in .part\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n    \n        $firefox-\u003efind_class('page-content')-\u003efind_id('metacpan_search-input')-\u003etype('Test::More');\n    \n        $firefox-\u003eawait(sub { $firefox-\u003efind_class('autocomplete-suggestion'); })-\u003eclick();\n    \n        $firefox-\u003efind_partial('Download')-\u003eclick();\n    \n        while(!$firefox-\u003edownloads()) { sleep 1 }\n    \n        while($firefox-\u003edownloading()) { sleep 1 }\n    \n        foreach my $path ($firefox-\u003edownloads()) {\n            say $path;\n        }\n\n downloads\n\n    returns a list of file paths (including partial downloads) of downloads\n    during this Firefox session.\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n    \n        $firefox-\u003efind_class('page-content')-\u003efind_id('metacpan_search-input')-\u003etype('Test::More');\n    \n        $firefox-\u003eawait(sub { $firefox-\u003efind_class('autocomplete-suggestion'); })-\u003eclick();\n    \n        $firefox-\u003efind_partial('Download')-\u003eclick();\n    \n        while(!$firefox-\u003edownloads()) { sleep 1 }\n    \n        foreach my $path ($firefox-\u003edownloads()) {\n            say $path;\n        }\n\n error_message\n\n    This method returns a human readable error message describing how the\n    Firefox process exited (assuming it started okay). On Win32 platforms\n    this information is restricted to exit code.\n\n execute\n\n    This utility method executes a command with arguments and returns\n    STDOUT as a chomped string. It is a simple method only intended for the\n    Firefox::Marionette::* modules.\n\n fill_login\n\n    This method searches the Password Manager\n    \u003chttps://support.mozilla.org/en-US/kb/password-manager-remember-delete-edit-logins\u003e\n    for an appropriate login for any form on the current page. The form\n    must match the host, the action attribute and the user and password\n    field names.\n\n        use Firefox::Marionette();\n        use IO::Prompt();\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n    \n        my $url = 'https://github.com';\n    \n        my $user = 'me@example.org';\n    \n        my $password = IO::Prompt::prompt(-echo =\u003e q[*], \"Please enter the password for the $user account when logging into $url:\");\n    \n        $firefox-\u003eadd_login(host =\u003e $url, user =\u003e $user, password =\u003e 'qwerty', user_field =\u003e 'login', password_field =\u003e 'password');\n    \n        $firefox-\u003ego(\"$url/login\");\n    \n        $firefox-\u003efill_login();\n\n find\n\n    accepts an xpath expression \u003chttps://en.wikipedia.org/wiki/XPath\u003e as\n    the first parameter and returns the first element that matches this\n    expression.\n\n    This method is subject to the implicit timeout, which, by default is 0\n    seconds.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n    \n        $firefox-\u003efind('//input[@id=\"metacpan_search-input\"]')-\u003etype('Test::More');\n    \n        # OR in list context \n    \n        foreach my $element ($firefox-\u003efind('//input[@id=\"metacpan_search-input\"]')) {\n            $element-\u003etype('Test::More');\n        }\n\n    If no elements are found, a not found exception will be thrown. For the\n    same functionality that returns undef if no elements are found, see the\n    has method.\n\n find_id\n\n    accepts an id\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id\u003e\n    as the first parameter and returns the first element with a matching\n    'id' property.\n\n    This method is subject to the implicit timeout, which, by default is 0\n    seconds.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n    \n        $firefox-\u003efind_id('metacpan_search-input')-\u003etype('Test::More');\n    \n        # OR in list context \n    \n        foreach my $element ($firefox-\u003efind_id('metacpan_search-input')) {\n            $element-\u003etype('Test::More');\n        }\n\n    If no elements are found, a not found exception will be thrown. For the\n    same functionality that returns undef if no elements are found, see the\n    has_id method.\n\n find_name\n\n    This method returns the first element with a matching 'name' property.\n\n    This method is subject to the implicit timeout, which, by default is 0\n    seconds.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        $firefox-\u003efind_name('q')-\u003etype('Test::More');\n    \n        # OR in list context \n    \n        foreach my $element ($firefox-\u003efind_name('q')) {\n            $element-\u003etype('Test::More');\n        }\n\n    If no elements are found, a not found exception will be thrown. For the\n    same functionality that returns undef if no elements are found, see the\n    has_name method.\n\n find_class\n\n    accepts a class name\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/class\u003e\n    as the first parameter and returns the first element with a matching\n    'class' property.\n\n    This method is subject to the implicit timeout, which, by default is 0\n    seconds.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        $firefox-\u003efind_class('form-control home-metacpan_search-input')-\u003etype('Test::More');\n    \n        # OR in list context \n    \n        foreach my $element ($firefox-\u003efind_class('form-control home-metacpan_search-input')) {\n            $element-\u003etype('Test::More');\n        }\n\n    If no elements are found, a not found exception will be thrown. For the\n    same functionality that returns undef if no elements are found, see the\n    has_class method.\n\n find_selector\n\n    accepts a CSS Selector\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors\u003e as the\n    first parameter and returns the first element that matches that\n    selector.\n\n    This method is subject to the implicit timeout, which, by default is 0\n    seconds.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        $firefox-\u003efind_selector('input.home-metacpan_search-input')-\u003etype('Test::More');\n    \n        # OR in list context \n    \n        foreach my $element ($firefox-\u003efind_selector('input.home-metacpan_search-input')) {\n            $element-\u003etype('Test::More');\n        }\n\n    If no elements are found, a not found exception will be thrown. For the\n    same functionality that returns undef if no elements are found, see the\n    has_selector method.\n\n find_tag\n\n    accepts a tag name\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/API/Element/tagName\u003e as\n    the first parameter and returns the first element with this tag name.\n\n    This method is subject to the implicit timeout, which, by default is 0\n    seconds.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        my $element = $firefox-\u003efind_tag('input');\n    \n        # OR in list context \n    \n        foreach my $element ($firefox-\u003efind_tag('input')) {\n            # do something\n        }\n\n    If no elements are found, a not found exception will be thrown. For the\n    same functionality that returns undef if no elements are found, see the\n    has_tag method.\n\n find_link\n\n    accepts a text string as the first parameter and returns the first link\n    element that has a matching link text.\n\n    This method is subject to the implicit timeout, which, by default is 0\n    seconds.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        $firefox-\u003efind_link('API')-\u003eclick();\n    \n        # OR in list context \n    \n        foreach my $element ($firefox-\u003efind_link('API')) {\n            $element-\u003eclick();\n        }\n\n    If no elements are found, a not found exception will be thrown. For the\n    same functionality that returns undef if no elements are found, see the\n    has_link method.\n\n find_partial\n\n    accepts a text string as the first parameter and returns the first link\n    element that has a partially matching link text.\n\n    This method is subject to the implicit timeout, which, by default is 0\n    seconds.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        $firefox-\u003efind_partial('AP')-\u003eclick();\n    \n        # OR in list context \n    \n        foreach my $element ($firefox-\u003efind_partial('AP')) {\n            $element-\u003eclick();\n        }\n\n    If no elements are found, a not found exception will be thrown. For the\n    same functionality that returns undef if no elements are found, see the\n    has_partial method.\n\n forward\n\n    causes the browser to traverse one step forward in the joint history of\n    the current browsing context. The browser will wait for the one step\n    forward to complete or the session's page_load duration to elapse\n    before returning, which, by default is 5 minutes. This method returns\n    itself to aid in chaining methods.\n\n full_screen\n\n    full screens the firefox window. This method returns itself to aid in\n    chaining methods.\n\n geo\n\n    accepts an optional geo location object or the parameters for a geo\n    location object, turns on the Geolocation API\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API\u003e and\n    returns the current value returned by calling the javascript\n    getCurrentPosition\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/API/Geolocation/getCurrentPosition\u003e\n    method. This method is further discussed in the GEO LOCATION section.\n    If the current location cannot be determined, this method will return\n    undef.\n\n    NOTE: firefox will only allow Geolocation\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/API/Geolocation\u003e calls to\n    be made from secure contexts\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts\u003e\n    and bizarrely, this does not include about:blank or similar. Therefore,\n    you will need to load a page before calling the geo method.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew( proxy =\u003e 'https://this.is.another.location:3128', geo =\u003e 1 );\n    \n        # Get geolocation for this.is.another.location (via proxy)\n    \n        $firefox-\u003egeo($firefox-\u003ejson('https://freeipapi.com/api/json/'));\n    \n        # now google maps will show us in this.is.another.location\n    \n        $firefox-\u003ego('https://maps.google.com/');\n    \n        if (my $geo = $firefox-\u003egeo()) {\n            warn \"Apparently, we're now at \" . join q[, ], $geo-\u003elatitude(), $geo-\u003elongitude();\n        } else {\n            warn \"This computer is not allowing geolocation\";\n        }\n    \n        # OR the quicker setup (run this with perl -C)\n    \n        warn \"Apparently, we're now at \" . Firefox::Marionette-\u003enew( proxy =\u003e 'https://this.is.another.location:3128', geo =\u003e 'https://freeipapi.com/api/json/' )-\u003ego('https://maps.google.com/')-\u003egeo();\n\n    NOTE: currently this call sets the location to be exactly what is\n    specified. It will also attempt to modify the current timezone (if\n    available in the geo location parameter) to match the specified\n    timezone. This function should be considered experimental. Feedback\n    welcome.\n\n    If particular, the ipgeolocation API\n    \u003chttps://ipgeolocation.io/documentation/ip-geolocation-api.html\u003e is the\n    only API that currently providing geolocation data and matching\n    timezone data in one API call. If anyone finds/develops another similar\n    API, I would be delighted to include support for it in this module.\n\n go\n\n    Navigates the current browsing context to the given URI and waits for\n    the document to load or the session's page_load duration to elapse\n    before returning, which, by default is 5 minutes.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        $firefox-\u003ego('https://metacpan.org/'); # will only return when metacpan.org is FULLY loaded (including all images / js / css)\n\n    To make the go method return quicker, you need to set the page load\n    strategy capability to an appropriate value, such as below;\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew( capabilities =\u003e Firefox::Marionette::Capabilities-\u003enew( page_load_strategy =\u003e 'eager' ));\n        $firefox-\u003ego('https://metacpan.org/'); # will return once the main document has been loaded and parsed, but BEFORE sub-resources (images/stylesheets/frames) have been loaded.\n\n    When going directly to a URL that needs to be downloaded, please see\n    BUGS AND LIMITATIONS for a necessary workaround and the download method\n    for an alternative.\n\n    This method returns itself to aid in chaining methods.\n\n get_pref\n\n    accepts a preference \u003chttp://kb.mozillazine.org/About:config\u003e name. See\n    the set_pref and clear_pref methods to set a preference value and to\n    restore it to it's original value. This method returns the current\n    value of the preference.\n\n        use Firefox::Marionette();\n        my $firefox = Firefox::Marionette-\u003enew();\n    \n        warn \"Your browser's default search engine is set to \" . $firefox-\u003eget_pref('browser.search.defaultenginename');\n\n har\n\n    returns a hashref representing the http archive\n    \u003chttps://en.wikipedia.org/wiki/HAR_(file_format)\u003e of the session. This\n    function is subject to the script timeout, which, by default is 30\n    seconds. It is also possible for the function to hang (until the script\n    timeout) if the original devtools\n    \u003chttps://developer.mozilla.org/en-US/docs/Tools\u003e window is closed. The\n    hashref has been designed to be accepted by the Archive::Har module.\n\n        use Firefox::Marionette();\n        use Archive::Har();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew(visible =\u003e 1, debug =\u003e 1, har =\u003e 1);\n    \n        $firefox-\u003ego(\"http://metacpan.org/\");\n    \n        $firefox-\u003efind('//input[@id=\"metacpan_search-input\"]')-\u003etype('Test::More');\n        $firefox-\u003eawait(sub { $firefox-\u003efind_class('autocomplete-suggestion'); })-\u003eclick();\n    \n        my $har = Archive::Har-\u003enew();\n        $har-\u003ehashref($firefox-\u003ehar());\n    \n        foreach my $entry ($har-\u003eentries()) {\n            say $entry-\u003erequest()-\u003eurl() . \" spent \" . $entry-\u003etimings()-\u003econnect() . \" ms establishing a TCP connection\";\n        }\n\n has\n\n    accepts an xpath expression \u003chttps://en.wikipedia.org/wiki/XPath\u003e as\n    the first parameter and returns the first element that matches this\n    expression.\n\n    This method is subject to the implicit timeout, which, by default is 0\n    seconds.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n    \n        if (my $element = $firefox-\u003ehas('//input[@id=\"metacpan_search-input\"]')) {\n            $element-\u003etype('Test::More');\n        }\n\n    If no elements are found, this method will return undef. For the same\n    functionality that throws a not found exception, see the find method.\n\n has_id\n\n    accepts an id\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/id\u003e\n    as the first parameter and returns the first element with a matching\n    'id' property.\n\n    This method is subject to the implicit timeout, which, by default is 0\n    seconds.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n    \n        if (my $element = $firefox-\u003ehas_id('metacpan_search-input')) {\n            $element-\u003etype('Test::More');\n        }\n\n    If no elements are found, this method will return undef. For the same\n    functionality that throws a not found exception, see the find_id\n    method.\n\n has_name\n\n    This method returns the first element with a matching 'name' property.\n\n    This method is subject to the implicit timeout, which, by default is 0\n    seconds.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        if (my $element = $firefox-\u003ehas_name('q')) {\n            $element-\u003etype('Test::More');\n        }\n\n    If no elements are found, this method will return undef. For the same\n    functionality that throws a not found exception, see the find_name\n    method.\n\n has_class\n\n    accepts a class name\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/class\u003e\n    as the first parameter and returns the first element with a matching\n    'class' property.\n\n    This method is subject to the implicit timeout, which, by default is 0\n    seconds.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        if (my $element = $firefox-\u003ehas_class('form-control home-metacpan_search-input')) {\n            $element-\u003etype('Test::More');\n        }\n\n    If no elements are found, this method will return undef. For the same\n    functionality that throws a not found exception, see the find_class\n    method.\n\n has_selector\n\n    accepts a CSS Selector\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors\u003e as the\n    first parameter and returns the first element that matches that\n    selector.\n\n    This method is subject to the implicit timeout, which, by default is 0\n    seconds.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        if (my $element = $firefox-\u003ehas_selector('input.home-metacpan_search-input')) {\n            $element-\u003etype('Test::More');\n        }\n\n    If no elements are found, this method will return undef. For the same\n    functionality that throws a not found exception, see the find_selector\n    method.\n\n has_tag\n\n    accepts a tag name\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/API/Element/tagName\u003e as\n    the first parameter and returns the first element with this tag name.\n\n    This method is subject to the implicit timeout, which, by default is 0\n    seconds.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        if (my $element = $firefox-\u003ehas_tag('input')) {\n            # do something\n        }\n\n    If no elements are found, this method will return undef. For the same\n    functionality that throws a not found exception, see the find_tag\n    method.\n\n has_link\n\n    accepts a text string as the first parameter and returns the first link\n    element that has a matching link text.\n\n    This method is subject to the implicit timeout, which, by default is 0\n    seconds.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        if (my $element = $firefox-\u003ehas_link('API')) {\n            $element-\u003eclick();\n        }\n\n    If no elements are found, this method will return undef. For the same\n    functionality that throws a not found exception, see the find_link\n    method.\n\n has_partial\n\n    accepts a text string as the first parameter and returns the first link\n    element that has a partially matching link text.\n\n    This method is subject to the implicit timeout, which, by default is 0\n    seconds.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        if (my $element = $firefox-\u003efind_partial('AP')) {\n            $element-\u003eclick();\n        }\n\n    If no elements are found, this method will return undef. For the same\n    functionality that throws a not found exception, see the find_partial\n    method.\n\n html\n\n    returns the page source of the content document. This page source can\n    be wrapped in html that firefox provides. See the json method for an\n    alternative when dealing with response content types such as\n    application/json and strip for an alternative when dealing with other\n    non-html content types such as text/plain.\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        say Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/')-\u003ehtml();\n\n import_bookmarks\n\n    accepts a filesystem path to a bookmarks file and imports all the\n    bookmarks in that file. It can deal with backups from Firefox\n    \u003chttps://support.mozilla.org/en-US/kb/export-firefox-bookmarks-to-backup-or-transfer\u003e,\n    Chrome \u003chttps://support.google.com/chrome/answer/96816?hl=en\u003e or Edge.\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003eimport_bookmarks('/path/to/bookmarks_file.html');\n\n    This method returns itself to aid in chaining methods.\n\n images\n\n    returns a list of all of the following elements;\n\n      * img \u003chttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/img\u003e\n\n      * image inputs\n      \u003chttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/image\u003e\n\n    as Firefox::Marionette::Image objects.\n\n    This method is subject to the implicit timeout, which, by default is 0\n    seconds.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        if (my $link = $firefox-\u003eimages()) {\n            say \"Found a image with width \" . $image-\u003ewidth() . \"px and height \" . $image-\u003eheight() . \"px from \" . $image-\u003eURL();\n        }\n\n    If no elements are found, this method will return undef.\n\n install\n\n    accepts the following as the first parameter;\n\n      * path to an xpi file\n      \u003chttps://developer.mozilla.org/en-US/docs/Mozilla/XPI\u003e.\n\n      * path to a directory containing firefox extension source code\n      \u003chttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension\u003e.\n      This directory will be packaged up as an unsigned xpi file.\n\n      * path to a top level file (such as manifest.json\n      \u003chttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#manifest.json\u003e)\n      in a directory containing firefox extension source code\n      \u003chttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension\u003e.\n      This directory will be packaged up as an unsigned xpi file.\n\n    and an optional true/false second parameter to indicate if the xpi file\n    should be a temporary extension\n    \u003chttps://extensionworkshop.com/documentation/develop/temporary-installation-in-firefox/\u003e\n    (just for the existence of this browser instance). Unsigned xpi files\n    may only be loaded temporarily\n    \u003chttps://wiki.mozilla.org/Add-ons/Extension_Signing\u003e (except for\n    nightly firefox installations\n    \u003chttps://www.mozilla.org/en-US/firefox/channel/desktop/#nightly\u003e). It\n    returns the GUID for the addon which may be used as a parameter to the\n    uninstall method.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n    \n        my $extension_id = $firefox-\u003einstall('/full/path/to/gnu_terry_pratchett-0.4-an+fx.xpi');\n    \n        # OR downloading and installing source code\n    \n        system { 'git' } 'git', 'clone', 'https://github.com/kkapsner/CanvasBlocker.git';\n    \n        if ($firefox-\u003enightly()) {\n    \n            $extension_id = $firefox-\u003einstall('./CanvasBlocker'); # permanent install for unsigned packages in nightly firefox\n    \n        } else {\n    \n            $extension_id = $firefox-\u003einstall('./CanvasBlocker', 1); # temp install for normal firefox\n    \n        }\n\n interactive\n\n    returns true if document.readyState === \"interactive\" or if loaded is\n    true\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        $firefox-\u003efind_id('metacpan_search-input')-\u003etype('Type::More');\n        $firefox-\u003eawait(sub { $firefox-\u003efind_class('autocomplete-suggestion'); })-\u003eclick();\n        while(!$firefox-\u003einteractive()) {\n            # redirecting to Test::More page\n        }\n\n is_displayed\n\n    accepts an element as the first parameter. This method returns true or\n    false depending on if the element is displayed\n    \u003chttps://firefox-source-docs.mozilla.org/testing/marionette/internals/interaction.html#interaction.isElementDisplayed\u003e.\n\n is_enabled\n\n    accepts an element as the first parameter. This method returns true or\n    false depending on if the element is enabled\n    \u003chttps://w3c.github.io/webdriver/#is-element-enabled\u003e.\n\n is_selected\n\n    accepts an element as the first parameter. This method returns true or\n    false depending on if the element is selected\n    \u003chttps://w3c.github.io/webdriver/#dfn-is-element-selected\u003e. Note that\n    this method only makes sense for checkbox\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/checkbox\u003e\n    or radio\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/radio\u003e\n    inputs or option\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/option\u003e\n    elements in a select\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/select\u003e\n    dropdown.\n\n is_trusted\n\n    accepts an certificate as the first parameter. This method returns true\n    or false depending on if the certificate is a trusted CA certificate in\n    the current profile.\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew( profile_name =\u003e 'default' );\n        foreach my $certificate ($firefox-\u003ecertificates()) {\n            if (($certificate-\u003eis_ca_cert()) \u0026\u0026 ($firefox-\u003eis_trusted($certificate))) {\n                say $certificate-\u003edisplay_name() . \" is a trusted CA cert in the current profile\";\n            } \n        } \n\n json\n\n    returns a JSON object that has been parsed from the page source of the\n    content document. This is a convenience method that wraps the strip\n    method.\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        say Firefox::Marionette-\u003enew()-\u003ego('https://fastapi.metacpan.org/v1/download_url/Firefox::Marionette\")-\u003ejson()-\u003e{version};\n\n    In addition, this method can accept a URI as a parameter and retrieve\n    that URI via the firefox fetch call\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/API/fetch\u003e and\n    transforming the body to JSON via firefox\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/API/Response/json_static\u003e\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        say Firefox::Marionette-\u003enew()-\u003ejson('https://freeipapi.com/api/json/')-\u003e{ipAddress};\n\n key_down\n\n    accepts a parameter describing a key and returns an action for use in\n    the perform method that corresponding with that key being depressed.\n\n        use Firefox::Marionette();\n        use Firefox::Marionette::Keys qw(:all);\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n    \n        $firefox-\u003echrome()-\u003eperform(\n                                     $firefox-\u003ekey_down(CONTROL()),\n                                     $firefox-\u003ekey_down('l'),\n                                   )-\u003erelease()-\u003econtent();\n\n key_up\n\n    accepts a parameter describing a key and returns an action for use in\n    the perform method that corresponding with that key being released.\n\n        use Firefox::Marionette();\n        use Firefox::Marionette::Keys qw(:all);\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n    \n        $firefox-\u003echrome()-\u003eperform(\n                                     $firefox-\u003ekey_down(CONTROL()),\n                                     $firefox-\u003ekey_down('l'),\n                                     $firefox-\u003epause(20),\n                                     $firefox-\u003ekey_up('l'),\n                                     $firefox-\u003ekey_up(CONTROL())\n                                   )-\u003econtent();\n\n languages\n\n    accepts an optional list of values for the Accept-Language\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language\u003e\n    header and sets this using the profile preferences. It returns the\n    current values as a list, such as ('en-US', 'en').\n\n loaded\n\n    returns true if document.readyState === \"complete\"\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        $firefox-\u003efind_id('metacpan_search-input')-\u003etype('Type::More');\n        $firefox-\u003eawait(sub { $firefox-\u003efind_class('autocomplete-suggestion'); })-\u003eclick();\n        while(!$firefox-\u003eloaded()) {\n            # redirecting to Test::More page\n        }\n\n logins\n\n    returns a list of all Firefox::Marionette::Login objects available.\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        foreach my $login ($firefox-\u003elogins()) {\n           say \"Found login for \" . $login-\u003ehost() . \" and user \" . $login-\u003euser();\n        }\n\n logins_from_csv\n\n    accepts a filehandle as a parameter and then reads the filehandle for\n    exported logins as CSV. This is known to work with the following\n    formats;\n\n      * Bitwarden CSV\n      \u003chttps://bitwarden.com/help/article/condition-bitwarden-import/\u003e\n\n      * LastPass CSV\n      \u003chttps://support.logmeininc.com/lastpass/help/how-do-i-nbsp-export-stored-data-from-lastpass-using-a-generic-csv-file\u003e\n\n      * KeePass CSV \u003chttps://keepass.info/help/base/importexport.html#csv\u003e\n\n    returns a list of Firefox::Marionette::Login objects.\n\n        use Firefox::Marionette();\n        use FileHandle();\n    \n        my $handle = FileHandle-\u003enew('/path/to/last_pass.csv');\n        my $firefox = Firefox::Marionette-\u003enew();\n        foreach my $login (Firefox::Marionette-\u003elogins_from_csv($handle)) {\n            $firefox-\u003eadd_login($login);\n        }\n\n logins_from_xml\n\n    accepts a filehandle as a parameter and then reads the filehandle for\n    exported logins as XML. This is known to work with the following\n    formats;\n\n      * KeePass 1.x XML\n      \u003chttps://keepass.info/help/base/importexport.html#xml\u003e\n\n    returns a list of Firefox::Marionette::Login objects.\n\n        use Firefox::Marionette();\n        use FileHandle();\n    \n        my $handle = FileHandle-\u003enew('/path/to/keepass1.xml');\n        my $firefox = Firefox::Marionette-\u003enew();\n        foreach my $login (Firefox::Marionette-\u003elogins_from_csv($handle)) {\n            $firefox-\u003eadd_login($login);\n        }\n\n logins_from_zip\n\n    accepts a filehandle as a parameter and then reads the filehandle for\n    exported logins as a zip file. This is known to work with the following\n    formats;\n\n      * 1Password Unencrypted Export format\n      \u003chttps://support.1password.com/1pux-format/\u003e\n\n    returns a list of Firefox::Marionette::Login objects.\n\n        use Firefox::Marionette();\n        use FileHandle();\n    \n        my $handle = FileHandle-\u003enew('/path/to/1Passwordv8.1pux');\n        my $firefox = Firefox::Marionette-\u003enew();\n        foreach my $login (Firefox::Marionette-\u003elogins_from_zip($handle)) {\n            $firefox-\u003eadd_login($login);\n        }\n\n links\n\n    returns a list of all of the following elements;\n\n      * anchor\n      \u003chttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/a\u003e\n\n      * area\n      \u003chttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/area\u003e\n\n      * frame\n      \u003chttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/frame\u003e\n\n      * iframe\n      \u003chttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe\u003e\n\n      * meta\n      \u003chttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta\u003e\n\n    as Firefox::Marionette::Link objects.\n\n    This method is subject to the implicit timeout, which, by default is 0\n    seconds.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        if (my $link = $firefox-\u003elinks()) {\n            if ($link-\u003etag() eq 'a') {\n                warn \"Found a hyperlink to \" . $link-\u003eURL();\n            }\n        }\n\n    If no elements are found, this method will return undef.\n\n macos_binary_paths\n\n    returns a list of filesystem paths that this module will check for\n    binaries that it can automate when running on MacOS\n    \u003chttps://en.wikipedia.org/wiki/MacOS\u003e. Only of interest when\n    sub-classing.\n\n marionette_protocol\n\n    returns the version for the Marionette protocol. Current most recent\n    version is '3'.\n\n maximise\n\n    maximises the firefox window. This method returns itself to aid in\n    chaining methods.\n\n mime_types\n\n    returns a list of MIME types that will be downloaded by firefox and\n    made available from the downloads method\n\n        use Firefox::Marionette();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew(mime_types =\u003e [ 'application/pkcs10' ])\n    \n        foreach my $mime_type ($firefox-\u003emime_types()) {\n            say $mime_type;\n        }\n\n minimise\n\n    minimises the firefox window. This method returns itself to aid in\n    chaining methods.\n\n mouse_down\n\n    accepts a parameter describing which mouse button the method should\n    apply to (left, middle or right) and returns an action for use in the\n    perform method that corresponding with a mouse button being depressed.\n\n mouse_move\n\n    accepts a element parameter, or a ( x =\u003e 0, y =\u003e 0 ) type hash manually\n    describing exactly where to move the mouse to and returns an action for\n    use in the perform method that corresponding with such a mouse\n    movement, either to the specified co-ordinates or to the middle of the\n    supplied element parameter. Other parameters that may be passed are\n    listed below;\n\n      * origin - the origin of the C(\u003cx =\u003e 0, y =\u003e 0)\u003e co-ordinates. Should\n      be either viewport, pointer or an element.\n\n      * duration - Number of milliseconds over which to distribute the\n      move. If not defined, the duration defaults to 0.\n\n    This method returns itself to aid in chaining methods.\n\n mouse_up\n\n    accepts a parameter describing which mouse button the method should\n    apply to (left, middle or right) and returns an action for use in the\n    perform method that corresponding with a mouse button being released.\n\n new\n\n    accepts an optional hash as a parameter. Allowed keys are below;\n\n      * addons - should any firefox extensions and themes be available in\n      this session. This defaults to \"0\".\n\n      * binary - use the specified path to the Firefox\n      \u003chttps://firefox.org/\u003e binary, rather than the default path.\n\n      * capabilities - use the supplied capabilities object, for example to\n      set whether the browser should accept insecure certs or whether the\n      browser should use a proxy.\n\n      * chatty - Firefox is extremely chatty on the network, including\n      checking for the latest malware/phishing sites, updates to\n      firefox/etc. This option is therefore off (\"0\") by default, however,\n      it can be switched on (\"1\") if required. Even with chatty switched\n      off, connections to firefox.settings.services.mozilla.com will still\n      be made \u003chttps://bugzilla.mozilla.org/show_bug.cgi?id=1598562#c13\u003e.\n      The only way to prevent this seems to be to set\n      firefox.settings.services.mozilla.com to 127.0.0.1 via /etc/hosts\n      \u003chttps://en.wikipedia.org/wiki//etc/hosts\u003e. NOTE: that this option\n      only works when profile_name/profile is not specified.\n\n      * console - show the browser console\n      \u003chttps://developer.mozilla.org/en-US/docs/Tools/Browser_Console/\u003e\n      when the browser is launched. This defaults to \"0\" (off). See CONSOLE\n      LOGGING for a discussion of how to send log messages to the console.\n\n      * debug - should firefox's debug to be available via STDERR. This\n      defaults to \"0\". Any ssh connections will also be printed to STDERR.\n      This defaults to \"0\" (off). This setting may be updated by the debug\n      method. If this option is not a boolean (0|1), the value will be\n      passed to the MOZ_LOG\n      \u003chttps://firefox-source-docs.mozilla.org/networking/http/logging.html\u003e\n      option on the command line of the firefox binary to allow extra\n      levels of debug.\n\n      * developer - only allow a developer edition\n      \u003chttps://www.mozilla.org/en-US/firefox/developer/\u003e to be launched.\n      This defaults to \"0\" (off).\n\n      * devtools - begin the session with the devtools\n      \u003chttps://developer.mozilla.org/en-US/docs/Tools\u003e window opened in a\n      separate window.\n\n      * geo - setup the browser preferences\n      \u003chttp://kb.mozillazine.org/About:config\u003e to allow the Geolocation API\n      \u003chttps://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API\u003e to\n      work. If the value for this key is a URI object or a string beginning\n      with '^(?:data|http)', this object will be retrieved using the json\n      method and the response will used to build a GeoLocation object,\n      which will be sent to the geo method. If the value for this key is a\n      hash, the hash will be used to build a GeoLocation object, which will\n      be sent to the geo method.\n\n      * height - set the height\n      \u003chttp://kb.mozillazine.org/Command_line_arguments#List_of_command_line_arguments_.28incomplete.29\u003e\n      of the initial firefox window\n\n      * har - begin the session with the devtools\n      \u003chttps://developer.mozilla.org/en-US/docs/Tools\u003e window opened in a\n      separate window. The HAR Export Trigger\n      \u003chttps://addons.mozilla.org/en-US/firefox/addon/har-export-trigger/\u003e\n      addon will be loaded into the new session automatically, which means\n      that -safe-mode\n      \u003chttp://kb.mozillazine.org/Command_line_arguments#List_of_command_line_arguments_.28incomplete.29\u003e\n      will not be activated for this session AND this functionality will\n      only be available for Firefox 61+.\n\n      * host - use ssh \u003chttps://man.openbsd.org/ssh.1\u003e to create and\n      automate firefox on the specified host. See REMOTE AUTOMATION OF\n      FIREFOX VIA SSH and NETWORK ARCHITECTURE. The user will default to\n      the current user name (see the user parameter to change this).\n      Authentication should be via public keys loaded into the local\n      ssh-agent \u003chttps://man.openbsd.org/ssh-agent\u003e.\n\n      * implicit - a shortcut to allow directly providing the implicit\n      timeout, instead of needing to use timeouts from the capabilities\n      parameter. Overrides all longer ways.\n\n      * index - a parameter to allow the user to specify a specific firefox\n      instance to survive and reconnect to. It does not do anything else at\n      the moment. See the survive parameter.\n\n      * kiosk - start the browser in kiosk\n      \u003chttps://support.mozilla.org/en-US/kb/firefox-enterprise-kiosk-mode\u003e\n      mode.\n\n      * mime_types - any MIME types that Firefox will encounter during this\n      session. MIME types that are not specified will result in a hung\n      browser (the File Download popup will appear).\n\n      * nightly - only allow a nightly release\n      \u003chttps://www.mozilla.org/en-US/firefox/channel/desktop/#nightly\u003e to\n      be launched. This defaults to \"0\" (off).\n\n      * port - if the \"host\" parameter is also set, use ssh\n      \u003chttps://man.openbsd.org/ssh.1\u003e to create and automate firefox via\n      the specified port. See REMOTE AUTOMATION OF FIREFOX VIA SSH and\n      NETWORK ARCHITECTURE.\n\n      * page_load - a shortcut to allow directly providing the page_load\n      timeout, instead of needing to use timeouts from the capabilities\n      parameter. Overrides all longer ways.\n\n      * profile - create a new profile based on the supplied profile. NOTE:\n      firefox ignores any changes made to the profile on the disk while it\n      is running, instead, use the set_pref and clear_pref methods to make\n      changes while firefox is running.\n\n      * profile_name - pick a specific existing profile to automate, rather\n      than creating a new profile. Firefox \u003chttps://firefox.com\u003e refuses to\n      allow more than one instance of a profile to run at the same time.\n      Profile names can be obtained by using the\n      Firefox::Marionette::Profile::names() method. The following\n      conditions are required to use existing profiles;\n\n\t* the preference security.webauth.webauthn_enable_softtoken must be\n\tset to true in the profile OR\n\n\t* the webauth parameter to this method must be set to 0\n\n      NOTE: firefox ignores any changes made to the profile on the disk\n      while it is running, instead, use the set_pref and clear_pref methods\n      to make changes while firefox is running.\n\n      * proxy - this is a shortcut method for setting a proxy using the\n      capabilities parameter above. It accepts a proxy URL, with the\n      following allowable schemes, 'http' and 'https'. It also allows a\n      reference to a list of proxy URLs which will function as list of\n      proxies that Firefox will try in left to right order\n      \u003chttps://developer.mozilla.org/en-US/docs/Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_PAC_file#description\u003e\n      until a working proxy is found. See REMOTE AUTOMATION OF FIREFOX VIA\n      SSH, NETWORK ARCHITECTURE and SETTING UP SOCKS SERVERS USING SSH.\n\n      * reconnect - an experimental parameter to allow a reconnection to\n      firefox that a connection has been discontinued. See the survive\n      parameter.\n\n      * scp - force the scp protocol when transferring files to remote\n      hosts via ssh. See REMOTE AUTOMATION OF FIREFOX VIA SSH and the\n      --scp-only option in the ssh-auth-cmd-marionette\n      \u003chttps://metacpan.org/pod/ssh-auth-cmd-marionette\u003e script in this\n      distribution.\n\n      * script - a shortcut to allow directly providing the script timeout,\n      instead of needing to use timeouts from the capabilities parameter.\n      Overrides all longer ways.\n\n      * seer - this option is switched off \"0\" by default. When it is\n      switched on \"1\", it will activate the various speculative and\n      pre-fetch options for firefox. NOTE: that this option only works when\n      profile_name/profile is not specified.\n\n      * sleep_time_in_ms - the amount of time (in milliseconds) that this\n      module should sleep when unsuccessfully calling the subroutine\n      provided to the await or bye methods. This defaults to \"1\"\n      millisecond.\n\n      * stealth - stops navigator.webdriver\n      \u003chttps://developer.mozilla.org/en-US/docs/Web/API/Navigator/webdriver\u003e\n      from being accessible by the current web page. This is achieved by\n      loading an extension\n      \u003chttps://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions\u003e,\n      which will automatically switch on the addons parameter for the new\n      method. This is extremely experimental. See IMITATING OTHER BROWSERS\n      for a discussion.\n\n      * survive - if this is set to a true value, firefox will not\n      automatically exit when the object goes out of scope. See the\n      reconnect parameter for an experimental technique for reconnecting.\n\n      * trust - give a path to a root certificate\n      \u003chttps://en.wikipedia.org/wiki/Root_certificate\u003e encoded as a PEM\n      encoded X.509 certificate\n      \u003chttps://datatracker.ietf.org/doc/html/rfc7468#section-5\u003e that will\n      be trusted for this session.\n\n      * timeouts - a shortcut to allow directly providing a timeout object,\n      instead of needing to use timeouts from the capabilities parameter.\n      Overrides the timeouts provided (if any) in the capabilities\n      parameter.\n\n      * trackable - if this is set, profile preferences will be set to make\n      it harder to be tracked by the browsers fingerprint\n      \u003chttps://en.wikipedia.org/wiki/Device_fingerprint#Browser_fingerprint\u003e\n      across browser restarts. This is on by default, but may be switched\n      off by setting it to 0;\n\n      * user - if the \"host\" parameter is also set, use ssh\n      \u003chttps://man.openbsd.org/ssh.1\u003e to create and automate firefox with\n      the specified user. See REMOTE AUTOMATION OF FIREFOX VIA SSH and\n      NETWORK ARCHITECTURE. The user will default to the current user name.\n      Authentication should be via public keys loaded into the local\n      ssh-agent \u003chttps://man.openbsd.org/ssh-agent\u003e.\n\n      * via - specifies a proxy jump box\n      \u003chttps://man.openbsd.org/ssh_config#ProxyJump\u003e to be used to connect\n      to a remote host. See the host parameter.\n\n      * visible - should firefox be visible on the desktop. This defaults\n      to \"0\". When moving from a X11 platform to another X11 platform, you\n      can set visible to 'local' to enable X11 forwarding\n      \u003chttps://man.openbsd.org/ssh#X\u003e. See X11 FORWARDING WITH FIREFOX.\n\n      * waterfox - only allow a binary that looks like a waterfox version\n      \u003chttps://www.waterfox.net/\u003e to be launched.\n\n      * webauthn - a boolean parameter to determine whether or not to add a\n      webauthn authenticator after the connection is established. The\n      default is to add a webauthn authenticator for Firefox after version\n      118.\n\n      * width - set the width\n      \u003chttp://kb.mozillazine.org/Command_line_arguments#List_of_command_line_arguments_.28incomplete.29\u003e\n      of the initial firefox window\n\n    This method returns a new Firefox::Marionette object, connected to an\n    instance of firefox \u003chttps://firefox.com\u003e. In a non MacOS/Win32/Cygwin\n    environment, if necessary (no DISPLAY variable can be found and the\n    visible parameter to the new method has been set to true) and possible\n    (Xvfb can be executed successfully), this method will also\n    automatically start an Xvfb \u003chttps://en.wikipedia.org/wiki/Xvfb\u003e\n    instance.\n\n        use Firefox::Marionette();\n    \n        my $remote_darwin_firefox = Firefox::Marionette-\u003enew(\n                         debug =\u003e 'timestamp,nsHttp:1',\n                         host =\u003e '10.1.2.3',\n                         trust =\u003e '/path/to/root_ca.pem',\n                         binary =\u003e '/Applications/Firefox.app/Contents/MacOS/firefox'\n                                                            ); # start a temporary profile for a remote firefox and load a new CA into the temp profile\n        ...\n    \n        foreach my $profile_name (Firefox::Marionette::Profile-\u003enames()) {\n            my $firefox_with_existing_profile = Firefox::Marionette-\u003enew( profile_name =\u003e $profile_name, visible =\u003e 1 );\n            ...\n        }\n\n new_window\n\n    accepts an optional hash as the parameter. Allowed keys are below;\n\n      * focus - a boolean field representing if the new window be opened in\n      the foreground (focused) or background (not focused). Defaults to\n      false.\n\n      * private - a boolean field representing if the new window should be\n      a private window. Defaults to false.\n\n      * type - the type of the new window. Can be one of 'tab' or 'window'.\n      Defaults to 'tab'.\n\n    Returns the window handle for the new window.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n    \n        my $window_handle = $firefox-\u003enew_window(type =\u003e 'tab');\n    \n        $firefox-\u003eswitch_to_window($window_handle);\n\n new_session\n\n    creates a new WebDriver session. It is expected that the caller\n    performs the necessary checks on the requested capabilities to be\n    WebDriver conforming. The WebDriver service offered by Marionette does\n    not match or negotiate capabilities beyond type and bounds checks.\n\n nightly\n\n    returns true if the current version of firefox is a nightly release\n    \u003chttps://www.mozilla.org/en-US/firefox/channel/desktop/#nightly\u003e (does\n    the minor version number end with an 'a1'?)\n\n paper_sizes\n\n    returns a list of all the recognised names for paper sizes, such as A4\n    or LEGAL.\n\n pause\n\n    accepts a parameter in milliseconds and returns a corresponding action\n    for the perform method that will cause a pause in the chain of actions\n    given to the perform method.\n\n pdf\n\n    accepts a optional hash as the first parameter with the following\n    allowed keys;\n\n      * landscape - Paper orientation. Boolean value. Defaults to false\n\n      * margin - A hash describing the margins. The hash may have the\n      following optional keys, 'top', 'left', 'right' and 'bottom'. All\n      these keys are in cm and default to 1 (~0.4 inches)\n\n      * page - A hash describing the page. The hash may have the following\n      keys; 'height' and 'width'. Both keys are in cm and default to US\n      letter size. See the 'size' key.\n\n      * page_ranges - A list of the pages to print. Available for Firefox\n      96\n      \u003chttps://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/96#webdriver_conformance_marionette\u003e\n      and after.\n\n      * print_background - Print background graphics. Boolean value.\n      Defaults to false.\n\n      * raw - rather than a file handle containing the PDF, the binary PDF\n      will be returned.\n\n      * scale - Scale of the webpage rendering. Defaults to 1.\n      shrink_to_fit should be disabled to make scale work.\n\n      * size - The desired size (width and height) of the pdf, specified by\n      name. See the page key for an alternative and the paper_sizes method\n      for a list of accepted page size names.\n\n      * shrink_to_fit - Whether or not to override page size as defined by\n      CSS. Boolean value. Defaults to true.\n\n    returns a File::Temp object containing a PDF encoded version of the\n    current page for printing.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        my $handle = $firefox-\u003epdf();\n        foreach my $paper_size ($firefox-\u003epaper_sizes()) {\n                $handle = $firefox-\u003epdf(size =\u003e $paper_size, landscape =\u003e 1, margin =\u003e { top =\u003e 0.5, left =\u003e 1.5 });\n                ...\n                print $firefox-\u003epdf(page =\u003e { width =\u003e 21, height =\u003e 27 }, raw =\u003e 1);\n                ...\n        }\n\n percentage_visible\n\n    accepts an element as the first parameter and returns the percentage of\n    that element that is currently visible in the viewport\n    \u003chttps://developer.mozilla.org/en-US/docs/Glossary/Viewport\u003e. It\n    achieves this by determining the co-ordinates of the DOMRect\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/API/DOMRect\u003e with a\n    getBoundingClientRect\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect\u003e\n    call and then using elementsFromPoint\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/API/Document/elementsFromPoint\u003e\n    and getComputedStyle\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle\u003e\n    calls to determine how the percentage of the DOMRect that is visible to\n    the user. The getComputedStyle call is used to determine the state of\n    the visibility\n    \u003chttps://developer.mozilla.org/en-US/docs/Web/CSS/visibility\u003e and\n    display \u003chttps://developer.mozilla.org/en-US/docs/Web/CSS/display\u003e\n    attributes.\n\n        use Firefox::Marionette();\n        use Encode();\n        use v5.10;\n    \n        my $firefox = Firefox::Marionette-\u003enew( visible =\u003e 1, kiosk =\u003e 1 )-\u003ego('http://metacpan.org');;\n        my $element = $firefox-\u003efind_id('metacpan_search-input');\n        my $totally_viewable_percentage = $firefox-\u003epercentage_visible($element); # search box is slightly hidden by different effects\n        foreach my $display ($firefox-\u003edisplays()) {\n            if ($firefox-\u003eresize($display-\u003ewidth(), $display-\u003eheight())) {\n                if ($firefox-\u003epercentage_visible($element) \u003c $totally_viewable_percentage) {\n                   say 'Search box stops being fully viewable with ' . Encode::encode('UTF-8', $display-\u003eusage());\n                   last;\n                }\n            }\n        }\n\n perform\n\n    accepts a list of actions (see mouse_up, mouse_down, mouse_move, pause,\n    key_down and key_up) and performs these actions in sequence. This\n    allows fine control over interactions, including sending right clicks\n    to the browser and sending Control, Alt and other special keys. The\n    release method will complete outstanding actions (such as mouse_up or\n    key_up actions).\n\n        use Firefox::Marionette();\n        use Firefox::Marionette::Keys qw(:all);\n        use Firefox::Marionette::Buttons qw(:all);\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n    \n        $firefox-\u003echrome()-\u003eperform(\n                                     $firefox-\u003ekey_down(CONTROL()),\n                                     $firefox-\u003ekey_down('l'),\n                                     $firefox-\u003ekey_up('l'),\n                                     $firefox-\u003ekey_up(CONTROL())\n                                   )-\u003econtent();\n    \n        $firefox-\u003ego('https://metacpan.org');\n        my $help_button = $firefox-\u003efind_class('btn search-btn help-btn');\n        $firefox-\u003eperform(\n                                      $firefox-\u003emouse_move($help_button),\n                                      $firefox-\u003emouse_down(RIGHT_BUTTON()),\n                                      $firefox-\u003epause(4),\n                                      $firefox-\u003emouse_up(RIGHT_BUTTON()),\n                    );\n\n    See the release method for an alternative for manually specifying all\n    the mouse_up and key_up methods\n\n profile_directory\n\n    returns the profile directory used by the current instance of firefox.\n    This is mainly intended for debugging firefox. Firefox is not designed\n    to cope with these files being altered while firefox is running.\n\n property\n\n    accepts an element as the first parameter and a scalar attribute name\n    as the second parameter. It returns the current value of the property\n    with the supplied name. This method will return the current content,\n    the attribute method will return the initial content from the HTML\n    source code.\n\n        use Firefox::Marionette();\n    \n        my $firefox = Firefox::Marionette-\u003enew()-\u003ego('https://metacpan.org/');\n        my $element = $firefox-\u003efind_id('metacpan_search-input');\n        $element-\u003eproperty('value') eq '' or die \"Initial property should be the empty string\";\n        $element-\u003etype('Test::More');\n        $element-\u003eproperty('value') eq 'Test::More' or die \"This property should have changed!\";\n    \n        # OR getting the innerHTML property\n    \n        my $title = $firefox-\u003efind_tag('title')-\u003eproperty('innerHTML'); # same as $firefox-\u003etitle();\n\n pwd_mgr_lock\n\n    Accepts a new primary password\n    \u003chttps://support.mozilla.org/en-US/kb/use-primary-password-protect-stored-logins\u003e\n    and locks the Password Manager\n    \u003chttps://support.mozilla.org/en-US/kb/password-manager-remember-delete-edit-logins\u003e\n    with it.\n\n        use Firefox::Marionette();\n        use IO::Prompt();\n    \n        my $firefox = Firefox::Marionette-\u003enew();\n        my $password = IO::Prompt::prompt(-echo =\u003e q[*], \"Please enter the password for the Firefox Password Manager:\");\n        $firefox-\u003epwd_mgr_lock($password);\n        $firefox-\u003epwd_mgr_logout();\n        # now no-one can access the Password Manager Database without the value in $password\n\n    This method returns itself to aid in chaining methods.\n\n pwd_mgr_login\n\n    Accepts the primary password\n    \u003chttps://support.mozilla.org/en-US/kb/use-primary-password-protect-stored-logins\u003e\n    and allows the user to access the Password Manager\n    \u003chttps://support.mozilla.org/en-US/kb/password-manager-remember-delete-edit-logins\u003e.\n\n        use Firefox::Marionette();\n        use IO::Prompt();\n    \n        my $firefox = Firefox::Marionette-\u003enew( profile_name =\u003e 'default' );\n        my $password = IO::Prompt::prompt(-echo =\u003e q[*], \"Please enter the password for the Firefox Password Manager:\");\n        $firefox-\u003epwd_mgr_login($password);\n        ...\n        # access the Password Database.\n        ...\n        $firefox-\u003epwd_mgr_logout();\n        ...\n        # no longer able to access the Password Database.\n\n    This method returns itself to aid in chaining methods.\n\n pwd_mgr_logout\n\n    Logs the user out of being able to access the Password Manager\n    \u003chttps://support.mozilla.org/en-US/kb/password-manager-remember-delete-edit-logins\u003e.\n\n        use Firefox::Marionette();\n        use IO::Prompt();\n    \n        my $firefox = Firefox::Marionette-\u003enew( profile_name =\u003e 'default' );\n        my $password = IO::Prompt::prompt(-echo =\u003e q[*], \"Please enter the password for the Firefox Password Manager:\");\n        $firefox-\u003epwd_mgr_login($password);\n        ...\n        # access the Password Database.\n        ...\n        $firefox-\u003epwd_mgr_logout();\n        ...\n        # no longer able to access the Password Database.\n\n    This method returns itself to aid in chaining methods.\n\n pwd_mgr_needs_login\n\n    returns true or false if the Password Manager\n    \u003chttps://support.mozilla.org/en-US/kb/password-manager-remember-delete-edit-logins\u003e\n    has been locked and needs a primary password\n    \u003chttps://support.mozilla.org/en-US/kb/use-primary-password-protect-stored-logins\u003e\n    to access it.\n\n        use Firefox::Marionette();\n        use IO::Prompt();\n    \n        my $firefox = Firefox::Marionette-\u003enew( profile_name =\u003e 'default' );\n        if ($firefox-\u003epwd_mgr_needs_login()) {\n          my $password = IO::Prompt::prompt(-echo =\u003e q[*], \"Please enter the password for the Firefox Password Manager:\");\n          $firefox-\u003epwd_mgr_login($password);\n        }\n\n quit\n\n    Mario","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavid-dick%2Ffirefox-marionette","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavid-dick%2Ffirefox-marionette","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavid-dick%2Ffirefox-marionette/lists"}