-
Notifications
You must be signed in to change notification settings - Fork 3
/
README
3973 lines (2785 loc) · 150 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
NAME
Firefox::Marionette - Automate the Firefox browser with the Marionette
protocol
VERSION
Version 1.62
SYNOPSIS
use Firefox::Marionette();
use v5.10;
my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/');
say $firefox->find_tag('title')->property('innerHTML'); # same as $firefox->title();
say $firefox->html();
$firefox->find_class('page-content')->find_id('metacpan_search-input')->type('Test::More');
say "Height of page-content div is " . $firefox->find_class('page-content')->css('height');
my $file_handle = $firefox->selfie();
$firefox->await(sub { $firefox->find_class('autocomplete-suggestion'); })->click();
$firefox->find_partial('Download')->click();
DESCRIPTION
This is a client module to automate the Mozilla Firefox browser via the
Marionette protocol
<https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/Protocol>
CONSTANTS
BCD_PATH
returns the local path used for storing the brower compability data for
the agent method when the stealth parameter is supplied to the new
method. This database is built by the build-bcd-for-firefox
<https://metacpan.org/pod/build-bcd-for-firefox> binary.
SUBROUTINES/METHODS
accept_alert
accepts a currently displayed modal message box
accept_connections
Enables or disables accepting new socket connections. By calling this
method with false the server will not accept any further connections,
but existing connections will not be forcible closed. Use true to
re-enable accepting connections.
Please note that when closing the connection via the client you can
end-up in a non-recoverable state if it hasn't been enabled before.
active_element
returns the active element of the current browsing context's document
element, if the document element is non-null.
add_bookmark
accepts a bookmark as a parameter and adds the specified bookmark to
the Firefox places database.
use Firefox::Marionette();
my $bookmark = Firefox::Marionette::Bookmark->new(
url => 'https://metacpan.org',
title => 'This is MetaCPAN!'
);
my $firefox = Firefox::Marionette->new()->add_bookmark($bookmark);
This method returns itself to aid in chaining methods.
add_certificate
accepts a hash as a parameter and adds the specified certificate to the
Firefox database with the supplied or default trust. Allowed keys are
below;
* path - a file system path to a single PEM encoded X.509 certificate
<https://datatracker.ietf.org/doc/html/rfc7468#section-5>.
* string - a string containing a single PEM encoded X.509 certificate
<https://datatracker.ietf.org/doc/html/rfc7468#section-5>
* trust - This is the trustargs
<https://www.mankier.com/1/certutil#-t> value for NSS
<https://wiki.mozilla.org/NSS>. If defaults to 'C,,';
This method returns itself to aid in chaining methods.
use Firefox::Marionette();
my $pem_encoded_string = <<'_PEM_';
-----BEGIN CERTIFICATE-----
MII..
-----END CERTIFICATE-----
_PEM_
my $firefox = Firefox::Marionette->new()->add_certificate(string => $pem_encoded_string);
add_cookie
accepts a single cookie object as the first parameter and adds it to
the current cookie jar. This method returns itself to aid in chaining
methods.
This method throws an exception if you try to add a cookie for a
different domain than the current document
<https://developer.mozilla.org/en-US/docs/Web/WebDriver/Errors/InvalidCookieDomain>.
add_header
accepts a hash of HTTP headers to include in every future HTTP Request.
use Firefox::Marionette();
use UUID();
my $firefox = Firefox::Marionette->new();
my $uuid = UUID::uuid();
$firefox->add_header( 'Track-my-automated-tests' => $uuid );
$firefox->go('https://metacpan.org/');
these headers are added to any existing headers. To clear headers, see
the delete_header method
use Firefox::Marionette();
my $firefox = Firefox::Marionette->new()->delete_header( 'Accept' )->add_header( 'Accept' => 'text/perl' )->go('https://metacpan.org/');
will only send out an Accept
<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept>
header that looks like Accept: text/perl.
use Firefox::Marionette();
my $firefox = Firefox::Marionette->new()->add_header( 'Accept' => 'text/perl' )->go('https://metacpan.org/');
by itself, will send out an Accept
<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept>
header that may resemble Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8,
text/perl. This method returns itself to aid in chaining methods.
add_login
accepts a hash of the following keys;
* host - The scheme + hostname of the page where the login applies,
for example 'https://www.example.org'.
* user - The username for the login.
* password - The password for the login.
* origin - The scheme + hostname that the form-based login was
submitted to
<https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-action>.
Forms with no action attribute default to submitting to the URL of
the page containing the login form, so that is stored here. This
field should be omitted (it will be set to undef) for http auth type
authentications and "" means to match against any form action.
* realm - The HTTP Realm for which the login was requested. When an
HTTP server sends a 401 result, the WWW-Authenticate header includes
a realm. See RFC 2617
<https://datatracker.ietf.org/doc/html/rfc2617>. If the realm is not
specified, or it was blank, the hostname is used instead. For HTML
form logins, this field should not be specified.
* user_field - The name attribute for the username input in a form.
Non-form logins should not specify this field.
* password_field - The name attribute for the password input in a
form. Non-form logins should not specify this field.
or a Firefox::Marionette::Login object as the first parameter and adds
the login to the Firefox login database.
use Firefox::Marionette();
use UUID();
my $firefox = Firefox::Marionette->new();
# for http auth logins
my $http_auth_login = Firefox::Marionette::Login->new(host => 'https://pause.perl.org', user => 'AUSER', password => 'qwerty', realm => 'PAUSE');
$firefox->add_login($http_auth_login);
$firefox->go('https://pause.perl.org/pause/authenquery')->accept_alert(); # this goes to the page and submits the http auth popup
# for form based login
my $form_login = Firefox::Marionette::Login(host => 'https://github.com', user => 'me2@example.org', password => 'uiop[]', user_field => 'login', password_field => 'password');
$firefox->add_login($form_login);
# or just directly
$firefox->add_login(host => 'https://github.com', user => 'me2@example.org', password => 'uiop[]', user_field => 'login', password_field => 'password');
Note for HTTP Authentication, the realm
<https://datatracker.ietf.org/doc/html/rfc2617#section-2> must
perfectly match the correct realm supplied by the server.
This method returns itself to aid in chaining methods.
add_site_header
accepts a host name and a hash of HTTP headers to include in every
future HTTP Request that is being sent to that particular host.
use Firefox::Marionette();
use UUID();
my $firefox = Firefox::Marionette->new();
my $uuid = UUID::uuid();
$firefox->add_site_header( 'metacpan.org', 'Track-my-automated-tests' => $uuid );
$firefox->go('https://metacpan.org/');
these headers are added to any existing headers going to the
metacpan.org site, but no other site. To clear site headers, see the
delete_site_header method
add_webauthn_authenticator
accepts a hash of the following keys;
* has_resident_key - boolean value to indicate if the authenticator
will support client side discoverable credentials
<https://www.w3.org/TR/webauthn-2/#client-side-discoverable-credential>
* has_user_verification - boolean value to determine if the
authenticator
<https://www.w3.org/TR/webauthn-2/#virtual-authenticators> supports
user verification
<https://www.w3.org/TR/webauthn-2/#user-verification>.
* is_user_consenting - boolean value to determine the result of all
user consent <https://www.w3.org/TR/webauthn-2/#user-consent>
authorization gestures
<https://www.w3.org/TR/webauthn-2/#authorization-gesture>, and by
extension, any test of user presence
<https://www.w3.org/TR/webauthn-2/#test-of-user-presence> performed
on the Virtual Authenticator
<https://www.w3.org/TR/webauthn-2/#virtual-authenticators>. If set to
true, a user consent will always be granted. If set to false, it will
not be granted.
* is_user_verified - boolean value to determine the result of User
Verification <https://www.w3.org/TR/webauthn-2/#user-verification>
performed on the Virtual Authenticator
<https://www.w3.org/TR/webauthn-2/#virtual-authenticators>. If set to
true, User Verification will always succeed. If set to false, it will
fail.
* protocol - the protocol spoken by the authenticator. This may be
CTAP1_U2F, CTAP2 or CTAP2_1.
* transport - the transport simulated by the authenticator. This may
be BLE, HYBRID, INTERNAL, NFC, SMART_CARD or USB.
It returns the newly created authenticator.
use Firefox::Marionette();
use Crypt::URandom();
my $user_name = MIME::Base64::encode_base64( Crypt::URandom::urandom( 10 ), q[] ) . q[@example.com];
my $firefox = Firefox::Marionette->new( webauthn => 0 );
my $authenticator = $firefox->add_webauthn_authenticator( transport => Firefox::Marionette::WebAuthn::Authenticator::INTERNAL(), protocol => Firefox::Marionette::WebAuthn::Authenticator::CTAP2() );
$firefox->go('https://webauthn.io');
$firefox->find_id('input-email')->type($user_name);
$firefox->find_id('register-button')->click();
$firefox->await(sub { sleep 1; $firefox->find_class('alert-success'); });
$firefox->find_id('login-button')->click();
$firefox->await(sub { sleep 1; $firefox->find_class('hero confetti'); });
add_webauthn_credential
accepts a hash of the following keys;
* authenticator - contains the authenticator that the credential will
be added to. If this parameter is not supplied, the credential will
be added to the default authenticator, if one exists.
* host - contains the domain that this credential is to be used for.
In the language of WebAuthn <https://www.w3.org/TR/webauthn-2>, this
field is referred to as the relying party identifier
<https://www.w3.org/TR/webauthn-2/#relying-party-identifier> or RP ID
<https://www.w3.org/TR/webauthn-2/#rp-id>.
* id - contains the unique id for this credential, also known as the
Credential ID <https://www.w3.org/TR/webauthn-2/#credential-id>. If
this is not supplied, one will be generated.
* is_resident - contains a boolean that if set to true, a client-side
discoverable credential
<https://w3c.github.io/webauthn/#client-side-discoverable-credential>
is created. If set to false, a server-side credential
<https://w3c.github.io/webauthn/#server-side-credential> is created
instead.
* private_key - either a RFC5958
<https://www.rfc-editor.org/rfc/rfc5958> encoded private key encoded
using encode_base64url or a hash containing the following keys;
* name - contains the name of the private key algorithm, such as
"RSA-PSS" (the default), "RSASSA-PKCS1-v1_5", "ECDSA" or "ECDH".
* size - contains the modulus length of the private key. This is
only valid for "RSA-PSS" or "RSASSA-PKCS1-v1_5" private keys.
* hash - contains the name of the hash algorithm, such as "SHA-512"
(the default). This is only valid for "RSA-PSS" or
"RSASSA-PKCS1-v1_5" private keys.
* curve - contains the name of the curve for the private key, such
as "P-384" (the default). This is only valid for "ECDSA" or "ECDH"
private keys.
* sign_count - contains the initial value for a signature counter
<https://w3c.github.io/webauthn/#signature-counter> associated to the
public key credential source
<https://w3c.github.io/webauthn/#public-key-credential-source>. It
will default to 0 (zero).
* user - contains the userHandle
<https://w3c.github.io/webauthn/#public-key-credential-source-userhandle>
associated to the credential encoded using encode_base64url. This
property is optional.
It returns the newly created credential. If of course, the credential
is just created, it probably won't be much good by itself. However, you
can use it to recreate a credential, so long as you know all the
parameters.
use Firefox::Marionette();
use Crypt::URandom();
my $user_name = MIME::Base64::encode_base64( Crypt::URandom::urandom( 10 ), q[] ) . q[@example.com];
my $firefox = Firefox::Marionette->new();
$firefox->go('https://webauthn.io');
$firefox->find_id('input-email')->type($user_name);
$firefox->find_id('register-button')->click();
$firefox->await(sub { sleep 1; $firefox->find_class('alert-success'); });
$firefox->find_id('login-button')->click();
$firefox->await(sub { sleep 1; $firefox->find_class('hero confetti'); });
foreach my $credential ($firefox->webauthn_credentials()) {
$firefox->delete_webauthn_credential($credential);
# ... time passes ...
$firefox->add_webauthn_credential(
id => $credential->id(),
host => $credential->host(),
user => $credential->user(),
private_key => $credential->private_key(),
is_resident => $credential->is_resident(),
sign_count => $credential->sign_count(),
);
}
$firefox->go('about:blank');
$firefox->clear_cache(Firefox::Marionette::Cache::CLEAR_COOKIES());
$firefox->go('https://webauthn.io');
$firefox->find_id('input-email')->type($user_name);
$firefox->find_id('login-button')->click();
$firefox->await(sub { sleep 1; $firefox->find_class('hero confetti'); });
addons
returns if pre-existing addons (extensions/themes) are allowed to run.
This will be true for Firefox versions less than 55, as -safe-mode
<http://kb.mozillazine.org/Command_line_arguments#List_of_command_line_arguments_.28incomplete.29>
cannot be automated.
agent
accepts an optional value for the User-Agent
<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent>
header and sets this using the profile preferences and inserting
javascript into the current page. It returns the current value, such as
'Mozilla/5.0 (<system-information>) <platform> (<platform-details>)
<extensions>'. This value is retrieved with navigator.userAgent
<https://developer.mozilla.org/en-US/docs/Web/API/Navigator/userAgent>.
This method can be used to set a user agent string like so;
use Firefox::Marionette();
use strict;
# useragents.me should only be queried once a month or less.
# these UA strings should be cached locally.
my %user_agent_strings = map { $_->{ua} => $_->{pct} } @{$firefox->json("https://www.useragents.me/api")->{data}};
my ($user_agent) = reverse sort { $user_agent_strings{$a} <=> $user_agent_strings{$b} } keys %user_agent_strings;
my $firefox = Firefox::Marionette->new();
$firefox->agent($user_agent); # agent is now the most popular agent from useragents.me
If the user agent string that is passed as a parameter looks like a
Chrome <https://www.google.com/chrome/>, Edge
<https://microsoft.com/edge> or Safari <https://www.apple.com/safari/>
user agent string, then this method will also try and change other
profile preferences to match the new agent string. These parameters
are;
* general.appversion.override
* general.oscpu.override
* general.platform.override
* network.http.accept
* network.http.accept-encoding
* network.http.accept-encoding.secure
* privacy.donottrackheader.enabled
In addition, this method will accept a hash of values as parameters as
well. When a hash is provided, this method will alter specific parts of
the normal Firefox User Agent. These hash parameters are;
* os - The desired operating system, known values are "linux",
"win32", "darwin", "freebsd", "netbsd", "openbsd" and "dragonfly"
* version - A specific version of firefox, such as 120.
* arch - A specific version of the architecture, such as "x86_64" or
"aarch64" or "s390x".
* increment - A specific offset from the actual version of firefox,
such as -5
These parameters can be used to set a user agent string like so;
use Firefox::Marionette();
use strict;
my $firefox = Firefox::Marionette->new();
$firefox->agent(os => 'freebsd', version => 118);
# user agent is now equal to
# Mozilla/5.0 (X11; FreeBSD amd64; rv:109.0) Gecko/20100101 Firefox/118.0
$firefox->agent(os => 'linux', arch => 's390x', version => 115);
# user agent is now equal to
# Mozilla/5.0 (X11; Linux s390x; rv:109.0) Gecko/20100101 Firefox/115.0
If the stealth parameter has supplied to the new method, it will also
attempt to create known specific javascript functions to imitate the
required browser. If the database built by build-bcd-for-firefox
<https://metacpan.org/pod/build-bcd-for-firefox> is accessible, then it
will also attempt to delete/provide dummy implementations for the
corresponding javascript attributes
<https://github.com/mdn/browser-compat-data> for the desired browser.
The following websites have been very useful in testing these ideas;
* https://browserleaks.com/javascript
* https://www.amiunique.org/fingerprint
* https://bot.sannysoft.com/
* https://lraj22.github.io/browserfeatcl/
Importantly, this will break feature detection
<https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Feature_detection>
for any website that relies on it.
See IMITATING OTHER BROWSERS a discussion of these types of techniques.
These changes are not foolproof, but it is interesting to see what can
be done with modern browsers. All this behaviour should be regarded as
extremely experimental and subject to change. Feedback welcome.
alert_text
Returns the message shown in a currently displayed modal message box
alive
This method returns true or false depending on if the Firefox process
is still running.
application_type
returns the application type for the Marionette protocol. Should be
'gecko'.
arch
returns the architecture of the machine running firefox. Should be
something like 'x86_64' or 'arm'. This is only intended for test suite
support.
aria_label
accepts an element as the parameter. It returns the ARIA label
<https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label>
for the element.
aria_role
accepts an element as the parameter. It returns the ARIA role
<https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles>
for the element.
async_script
accepts a scalar containing a javascript function that is executed in
the browser. This method returns itself to aid in chaining methods.
The executing javascript is subject to the script timeout, which, by
default is 30 seconds.
attribute
accepts an element as the first parameter and a scalar attribute name
as the second parameter. It returns the initial value of the attribute
with the supplied name. This method will return the initial content
from the HTML source code, the property method will return the current
content.
use Firefox::Marionette();
my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/');
my $element = $firefox->find_id('metacpan_search-input');
!defined $element->attribute('value') or die "attribute is defined but did not exist in the html source!";
$element->type('Test::More');
!defined $element->attribute('value') or die "attribute has changed but only the property should have changed!";
await
accepts a subroutine reference as a parameter and then executes the
subroutine. If a not found exception is thrown, this method will sleep
for sleep_time_in_ms milliseconds and then execute the subroutine
again. When the subroutine executes successfully, it will return what
the subroutine returns.
use Firefox::Marionette();
my $firefox = Firefox::Marionette->new(sleep_time_in_ms => 5)->go('https://metacpan.org/');
$firefox->find_id('metacpan_search-input')->type('Test::More');
$firefox->await(sub { $firefox->find_class('autocomplete-suggestion'); })->click();
back
causes the browser to traverse one step backward in the joint history
of the current browsing context. The browser will wait for the one step
backward to complete or the session's page_load duration to elapse
before returning, which, by default is 5 minutes. This method returns
itself to aid in chaining methods.
debug
accept a boolean and return the current value of the debug setting.
This allows the dynamic setting of debug.
default_binary_name
just returns the string 'firefox'. Only of interest when sub-classing.
download
accepts a URI and an optional timeout in seconds (the default is 5
minutes) as parameters and downloads the URI in the background and
returns a handle to the downloaded file.
use Firefox::Marionette();
use v5.10;
my $firefox = Firefox::Marionette->new();
my $handle = $firefox->download('https://raw.githubusercontent.com/david-dick/firefox-marionette/master/t/data/keepassxs.csv');
foreach my $line (<$handle>) {
print $line;
}
bookmarks
accepts either a scalar or a hash as a parameter. The scalar may by the
title of a bookmark or the URL of the bookmark. The hash may have the
following keys;
* title - The title of the bookmark.
* url - The url of the bookmark.
returns a list of all Firefox::Marionette::Bookmark objects that match
the supplied parameters (if any).
use Firefox::Marionette();
use v5.10;
my $firefox = Firefox::Marionette->new();
foreach my $bookmark ($firefox->bookmarks(title => 'This is MetaCPAN!')) {
say "Bookmark found";
}
# OR
foreach my $bookmark ($firefox->bookmarks()) {
say "Bookmark found with URL " . $bookmark->url();
}
# OR
foreach my $bookmark ($firefox->bookmarks('https://metacpan.org')) {
say "Bookmark found";
}
browser_version
This method returns the current version of firefox.
bye
accepts a subroutine reference as a parameter and then executes the
subroutine. If the subroutine executes successfully, this method will
sleep for sleep_time_in_ms milliseconds and then execute the subroutine
again. When a not found exception is thrown, this method will return
itself to aid in chaining methods.
use Firefox::Marionette();
my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/');
$firefox->find_id('metacpan_search-input')->type('Test::More');
$firefox->await(sub { $firefox->find_class('autocomplete-suggestion'); })->click();
$firefox->bye(sub { $firefox->find_name('metacpan_search-input') })->await(sub { $firefox->interactive() && $firefox->find_partial('Download') })->click();
cache_keys
returns the set of all cache keys from Firefox::Marionette::Cache.
use Firefox::Marionette();
my $firefox = Firefox::Marionette->new();
foreach my $key_name ($firefox->cache_keys()) {
my $key_value = $firefox->check_cache_key($key_name);
if (Firefox::Marionette::Cache->$key_name() != $key_value) {
warn "This module this the value of $key_name is " . Firefox::Marionette::Cache->$key_name();
warn "Firefox thinks the value of $key_name is $key_value";
}
}
capabilities
returns the capabilities of the current firefox binary. You can
retrieve timeouts or a proxy with this method.
certificate_as_pem
accepts a certificate stored in the Firefox database as a parameter and
returns a PEM encoded X.509 certificate
<https://datatracker.ietf.org/doc/html/rfc7468#section-5> as a string.
use Firefox::Marionette();
my $firefox = Firefox::Marionette->new();
# Generating a ca-bundle.crt to STDOUT from the current firefox instance
foreach my $certificate (sort { $a->display_name() cmp $b->display_name } $firefox->certificates()) {
if ($certificate->is_ca_cert()) {
print '# ' . $certificate->display_name() . "\n" . $firefox->certificate_as_pem($certificate) . "\n";
}
}
The ca-bundle-for-firefox
<https://metacpan.org/pod/ca-bundle-for-firefox> command that is
provided as part of this distribution does this.
certificates
returns a list of all known certificates in the Firefox database.
use Firefox::Marionette();
use v5.10;
# Sometimes firefox can neglect old certificates. See https://bugzilla.mozilla.org/show_bug.cgi?id=1710716
my $firefox = Firefox::Marionette->new();
foreach my $certificate (grep { $_->is_ca_cert() && $_->not_valid_after() < time } $firefox->certificates()) {
say "The " . $certificate->display_name() " . certificate has expired and should be removed";
print 'PEM Encoded Certificate ' . "\n" . $firefox->certificate_as_pem($certificate) . "\n";
}
This method returns itself to aid in chaining methods.
check_cache_key
accepts a cache_key as a parameter.
use Firefox::Marionette();
my $firefox = Firefox::Marionette->new();
foreach my $key_name ($firefox->cache_keys()) {
my $key_value = $firefox->check_cache_key($key_name);
if (Firefox::Marionette::Cache->$key_name() != $key_value) {
warn "This module this the value of $key_name is " . Firefox::Marionette::Cache->$key_name();
warn "Firefox thinks the value of $key_name is $key_value";
}
}
This method returns the cache_key's actual value from firefox as a
number. This may differ from the current value of the key from
Firefox::Marionette::Cache as these values have changed as firefox has
evolved.
child_error
This method returns the $? (CHILD_ERROR) for the Firefox process, or
undefined if the process has not yet exited.
chrome
changes the scope of subsequent commands to chrome context. This allows
things like interacting with firefox menu's and buttons outside of the
browser window.
use Firefox::Marionette();
use v5.10;
my $firefox = Firefox::Marionette->new()->chrome();
$firefox->script(...); # running script in chrome context
$firefox->content();
See the context method for an alternative methods for changing the
context.
chrome_window_handle
returns a server-assigned identifier for the current chrome window that
uniquely identifies it within this Marionette instance. This can be
used to switch to this window at a later point. This corresponds to a
window that may itself contain tabs. This method is replaced by
window_handle and appropriate context calls for Firefox 94 and after
<https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/94#webdriver_conformance_marionette>.
chrome_window_handles
returns identifiers for each open chrome window for tests interested in
managing a set of chrome windows and tabs separately. This method is
replaced by window_handles and appropriate context calls for Firefox 94
and after
<https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/94#webdriver_conformance_marionette>.
clear
accepts a element as the first parameter and clears any user supplied
input
clear_cache
accepts a single flag parameter, which can be an ORed set of keys from
Firefox::Marionette::Cache and clears the appropriate sections of the
cache. If no flags parameter is supplied, the default is CLEAR_ALL.
Note that this method, unlike delete_cookies will actually delete all
cookies for all hosts, not just the current webpage.
use Firefox::Marionette();
use Firefox::Marionette::Cache qw(:all);
my $firefox = Firefox::Marionette->new()->go('https://do.lots.of.evil/')->clear_cache(); # default clear all
$firefox->go('https://cookies.r.us')->clear_cache(CLEAR_COOKIES());
This method returns itself to aid in chaining methods.
clear_pref
accepts a preference <http://kb.mozillazine.org/About:config> name and
restores it to the original value. See the get_pref and set_pref
methods to get a preference value and to set to it to a particular
value. This method returns itself to aid in chaining methods.
use Firefox::Marionette();
my $firefox = Firefox::Marionette->new();
$firefox->clear_pref('browser.search.defaultenginename');
click
accepts a element as the first parameter and sends a 'click' to it. The
browser will wait for any page load to complete or the session's
page_load duration to elapse before returning, which, by default is 5
minutes. The click method is also used to choose an option in a select
dropdown.
use Firefox::Marionette();
my $firefox = Firefox::Marionette->new(visible => 1)->go('https://ebay.com');
my $select = $firefox->find_tag('select');
foreach my $option ($select->find_tag('option')) {
if ($option->property('value') == 58058) { # Computers/Tablets & Networking
$option->click();
}
}
close_current_chrome_window_handle
closes the current chrome window (that is the entire window, not just
the tabs). It returns a list of still available chrome window handles.
You will need to switch_to_window to use another window.
close_current_window_handle
closes the current window/tab. It returns a list of still available
window/tab handles.
content
changes the scope of subsequent commands to browsing context. This is
the default for when firefox starts and restricts commands to operating
in the browser window only.
use Firefox::Marionette();
use v5.10;
my $firefox = Firefox::Marionette->new()->chrome();
$firefox->script(...); # running script in chrome context
$firefox->content();
See the context method for an alternative methods for changing the
context.
context
accepts a string as the first parameter, which may be either 'content'
or 'chrome'. It returns the context type that is Marionette's current
target for browsing context scoped commands.
use Firefox::Marionette();
use v5.10;
my $firefox = Firefox::Marionette->new();
if ($firefox->context() eq 'content') {
say "I knew that was going to happen";
}
my $old_context = $firefox->context('chrome');
$firefox->script(...); # running script in chrome context
$firefox->context($old_context);
See the content and chrome methods for alternative methods for changing
the context.
cookies
returns the contents of the cookie jar in scalar or list context.
use Firefox::Marionette();
use v5.10;
my $firefox = Firefox::Marionette->new()->go('https://github.com');
foreach my $cookie ($firefox->cookies()) {
if (defined $cookie->same_site()) {
say "Cookie " . $cookie->name() . " has a SameSite of " . $cookie->same_site();
} else {
warn "Cookie " . $cookie->name() . " does not have the SameSite attribute defined";
}
}
css
accepts an element as the first parameter and a scalar CSS property
name as the second parameter. It returns the value of the computed
style for that property.
use Firefox::Marionette();
use v5.10;
my $firefox = Firefox::Marionette->new()->go('https://metacpan.org/');
say $firefox->find_id('metacpan_search-input')->css('height');
current_chrome_window_handle
see chrome_window_handle.
delete_bookmark
accepts a bookmark as a parameter and deletes the bookmark from the
Firefox database.
use Firefox::Marionette();
use v5.10;
my $firefox = Firefox::Marionette->new();
foreach my $bookmark (reverse $firefox->bookmarks()) {
if ($bookmark->parent_guid() ne Firefox::Marionette::Bookmark::ROOT()) {
$firefox->delete_bookmark($bookmark);
}
}
say "Bookmarks? We don't need no stinking bookmarks!";
This method returns itself to aid in chaining methods.
delete_certificate
accepts a certificate stored in the Firefox database as a parameter and
deletes/distrusts the certificate from the Firefox database.
use Firefox::Marionette();
use v5.10;
my $firefox = Firefox::Marionette->new();
foreach my $certificate ($firefox->certificates()) {
if ($certificate->is_ca_cert()) {
$firefox->delete_certificate($certificate);
} else {
say "This " . $certificate->display_name() " certificate is NOT a certificate authority, therefore it is not being deleted";
}
}
say "Good luck visiting a HTTPS website!";
This method returns itself to aid in chaining methods.
delete_cookie
deletes a single cookie by name. Accepts a scalar containing the cookie
name as a parameter. This method returns itself to aid in chaining
methods.
use Firefox::Marionette();
my $firefox = Firefox::Marionette->new()->go('https://github.com');
foreach my $cookie ($firefox->cookies()) {
warn "Cookie " . $cookie->name() . " is being deleted";
$firefox->delete_cookie($cookie->name());
}
foreach my $cookie ($firefox->cookies()) {
die "Should be no cookies here now";
}
delete_cookies
Here be cookie monsters! Note that this method will only delete cookies
for the current site. See clear_cache for an alternative. This method
returns itself to aid in chaining methods.
delete_header
accepts a list of HTTP header names to delete from future HTTP
Requests.
use Firefox::Marionette();
my $firefox = Firefox::Marionette->new();
$firefox->delete_header( 'User-Agent', 'Accept', 'Accept-Encoding' );
will remove the User-Agent
<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent>,
Accept
<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept> and
Accept-Encoding
<https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding>
headers from all future requests
This method returns itself to aid in chaining methods.
delete_login
accepts a login as a parameter.
use Firefox::Marionette();
my $firefox = Firefox::Marionette->new();
foreach my $login ($firefox->logins()) {
if ($login->user() eq 'me@example.org') {
$firefox->delete_login($login);
}
}
will remove the logins with the username matching 'me@example.org'.
This method returns itself to aid in chaining methods.
delete_logins
This method empties the password database.
use Firefox::Marionette();
my $firefox = Firefox::Marionette->new();
$firefox->delete_logins();
This method returns itself to aid in chaining methods.