ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-WebDriver/WebDriver.pm
(Generate patch)

Comparing AnyEvent-WebDriver/WebDriver.pm (file contents):
Revision 1.40 by root, Tue Sep 4 01:49:24 2018 UTC vs.
Revision 1.41 by root, Fri Sep 20 19:48:34 2019 UTC

2 2
3AnyEvent::WebDriver - control browsers using the W3C WebDriver protocol 3AnyEvent::WebDriver - control browsers using the W3C WebDriver protocol
4 4
5=head1 SYNOPSIS 5=head1 SYNOPSIS
6 6
7 # start geckodriver or any other w3c-compatible webdriver via the shell 7 # start geckodriver(chromedriver or any other webdriver via the shell
8 $ geckdriver -b myfirefox/firefox --log trace --port 4444 8 $ geckodriver -b myfirefox/firefox --log trace --port 4444
9 # chromedriver --port=4444
9 10
10 # then use it 11 # then use it
11 use AnyEvent::WebDriver; 12 use AnyEvent::WebDriver;
12 13
13 # create a new webdriver object 14 # create a new webdriver object
33 ->key ("{Enter}") 34 ->key ("{Enter}")
34 ->perform; 35 ->perform;
35 36
36=head1 DESCRIPTION 37=head1 DESCRIPTION
37 38
38WARNING: BEFORE VERSION 1.0, API CHANGES ARE LIKELY.
39
40This module aims to implement the L<W3C 39This module aims to implement the L<W3C
41WebDriver|https://www.w3.org/TR/webdriver1/> specification which is the 40WebDriver|https://www.w3.org/TR/webdriver1/> specification which is the
42standardised equivalent to the Selenium WebDriver API, which in turn aims 41standardised equivalent to the Selenium WebDriver API, which in turn aims
43at remotely controlling web browsers such as Firefox or Chromium. 42at remotely controlling web browsers such as Firefox or Chromium.
44
45At the time of this writing, it was so brand new that I could only get
46C<geckodriver> (for Firefox) to work, but that is expected to be fixed
47very soon indeed.
48 43
49One of the design goals of this module was to stay very close to the 44One of the design goals of this module was to stay very close to the
50language and words used in the WebDriver specification itself, so to make 45language and words used in the WebDriver specification itself, so to make
51most of this module, or, in fact, to make any reasonable use of this 46most of this module, or, in fact, to make any reasonable use of this
52module, you would need to refer to the W3C WebDriver recommendation, which 47module, you would need to refer to the W3C WebDriver recommendation, which
53can be found L<here|https://www.w3.org/TR/webdriver1/>: 48can be found L<here|https://www.w3.org/TR/webdriver1/>:
54 49
55 https://www.w3.org/TR/webdriver1/ 50 https://www.w3.org/TR/webdriver1/
51
52Mozilla's C<geckodriver> has had webdriver for a long time, while
53C<chromedriver> only has basic and mostly undocumented webdriver support
54since release 77.
55
56In debian GNU/Linux, you can install the C<firefoxdriver> or
57C<chromium-driver> packages to get the firefox/chromium webdrivers,
58respectively.
56 59
57=head2 CONVENTIONS 60=head2 CONVENTIONS
58 61
59Unless otherwise stated, all delays and time differences in this module 62Unless otherwise stated, all delays and time differences in this module
60are represented as an integer number of milliseconds. 63are represented as an integer number of milliseconds.
164=item new AnyEvent::WebDriver key => value... 167=item new AnyEvent::WebDriver key => value...
165 168
166Create a new WebDriver object. Example for a remote WebDriver connection 169Create a new WebDriver object. Example for a remote WebDriver connection
167(the only type supported at the moment): 170(the only type supported at the moment):
168 171
169 my $wd = new AnyEvent::WebDriver host => "localhost", port => 4444; 172 my $wd = new AnyEvent::WebDriver endpoint => "http://localhost:4444";
170 173
171Supported keys are: 174Supported keys are:
172 175
173=over 176=over
174 177
297=back 300=back
298 301
299=head2 SIMPLIFIED API 302=head2 SIMPLIFIED API
300 303
301This section documents the simplified API, which is really just a very 304This section documents the simplified API, which is really just a very
302thin wrapper around the WebDriver protocol commands. They all block (using 305thin wrapper around the WebDriver protocol commands. They all block the
303L<AnyEvent> condvars) the caller until the result is available, so must 306caller until the result is available (using L<AnyEvent> condvars), so must
304not be called from an event loop callback - see L<EVENT BASED API> for an 307not be called from an event loop callback - see L<EVENT BASED API> for an
305alternative. 308alternative.
306 309
307The method names are pretty much taken directly from the W3C WebDriver 310The method names are pretty much taken directly from the W3C WebDriver
308specification, e.g. the request documented in the "Get All Cookies" 311specification, e.g. the request documented in the "Get All Cookies"
330On success, C<< $wd->{sid} >> is set to the session ID, and C<< 333On success, C<< $wd->{sid} >> is set to the session ID, and C<<
331$wd->{capabilities} >> is set to the returned capabilities. 334$wd->{capabilities} >> is set to the returned capabilities.
332 335
333Simple example of creating a WebDriver object and a new session: 336Simple example of creating a WebDriver object and a new session:
334 337
335 my $wd = new AnyEvent::Selenium endpoint => "http://localhost:4545"; 338 my $wd = new AnyEvent::WebDriver endpoint => "http://localhost:4444";
336 $wd->new_session ({}); 339 $wd->new_session ({});
337 340
338Real-world example with capability negotiation: 341Real-world example with capability negotiation:
339 342
340 $wd->new_session ({ 343 $wd->new_session ({
347 firstMatch => [ 350 firstMatch => [
348 { 351 {
349 browserName => "firefox", 352 browserName => "firefox",
350 "moz:firefoxOptions" => { 353 "moz:firefoxOptions" => {
351 binary => "firefox/firefox", 354 binary => "firefox/firefox",
352 args => ["-devtools"], 355 args => ["-devtools", "-headless"],
353 prefs => { 356 prefs => {
354 "dom.webnotifications.enabled" => \0, 357 "dom.webnotifications.enabled" => \0,
355 "dom.push.enabled" => \0, 358 "dom.push.enabled" => \0,
356 "dom.disable_beforeunload" => \1, 359 "dom.disable_beforeunload" => \1,
357 "browser.link.open_newwindow" => 3, 360 "browser.link.open_newwindow" => 3,
360 "dom.disable_open_during_load" => \1, 363 "dom.disable_open_during_load" => \1,
361 }, 364 },
362 }, 365 },
363 }, 366 },
364 { 367 {
368 browserName => "chrome",
369 "goog:chromeOptions" => {
370 binary => "/bin/chromium",
371 args => ["--no-sandbox", "--headless"],
372 prefs => {
373 # ...
374 },
375 },
376 },
377 {
365 # generic fallback 378 # generic fallback
366 }, 379 },
367 ], 380 ],
368 381
369 }, 382 },
371 384
372Firefox-specific capability documentation can be found L<on 385Firefox-specific capability documentation can be found L<on
373MDN|https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities>, 386MDN|https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities>,
374Chrome-specific capability documentation might be found 387Chrome-specific capability documentation might be found
375L<here|http://chromedriver.chromium.org/capabilities>, but the latest 388L<here|http://chromedriver.chromium.org/capabilities>, but the latest
376release at the time of this writing has effectively no WebDriver support 389release at the time of this writing (chromedriver 77) has essentially no
377at all, and canary releases are not freely downloadable. 390webdriver documentation about chrome capabilities.
378 391
379If you have URLs for Safari/IE/Edge etc. capabilities, feel free to tell 392If you have URLs for Safari/IE/Edge etc. capabilities, feel free to tell
380me about them. 393me about them.
381 394
382=cut 395=cut
383 396
384sub new_session_ { 397sub new_session_ {
385 my ($self, $kv, $cb) = @_; 398 my ($self, $kv, $cb) = @_;
399
400 $kv->{capabilities} ||= {}; # required by protocol
386 401
387 local $self->{_ep} = "$self->{endpoint}/"; 402 local $self->{_ep} = "$self->{endpoint}/";
388 $self->post_ (session => $kv, sub { 403 $self->post_ (session => $kv, sub {
389 my ($status, $res) = @_; 404 my ($status, $res) = @_;
390 405
1054 1069
1055Create a screenshot, returning it as a PNG image in a C<data:> URL. 1070Create a screenshot, returning it as a PNG image in a C<data:> URL.
1056 1071
1057=item $wd->take_element_screenshot ($element) 1072=item $wd->take_element_screenshot ($element)
1058 1073
1059Accept a simple dialog, if present. 1074Similar to C<take_screenshot>, but only takes a screenshot of the bounding
1075box of a single element.
1060 1076
1061=cut 1077=cut
1062 1078
1063sub take_screenshot_ { 1079sub take_screenshot_ {
1064 $_[0]->get_ (screenshot => $_[1]); 1080 $_[0]->get_ (screenshot => $_[1]);
1673 1689
1674=head1 HISTORY 1690=head1 HISTORY
1675 1691
1676This module was unintentionally created (it started inside some quickly 1692This module was unintentionally created (it started inside some quickly
1677hacked-together script) simply because I couldn't get the existing 1693hacked-together script) simply because I couldn't get the existing
1678C<Selenium::Remote::Driver> module to work, ever, despite multiple 1694C<Selenium::Remote::Driver> module to work reliably, ever, despite
1679attempts over the years and trying to report multiple bugs, which have 1695multiple attempts over the years and trying to report multiple bugs, which
1680been completely ignored. It's also not event-based, so, yeah... 1696have been completely ignored. It's also not event-based, so, yeah...
1681 1697
1682=head1 AUTHOR 1698=head1 AUTHOR
1683 1699
1684 Marc Lehmann <schmorp@schmorp.de> 1700 Marc Lehmann <schmorp@schmorp.de>
1685 http://anyevent.schmorp.de 1701 http://anyevent.schmorp.de

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines