1 | NAME |
1 | NAME |
2 | AnyEvent::WebDriver - control browsers using the W3C WebDriver protocol |
2 | AnyEvent::WebDriver - control browsers using the W3C WebDriver protocol |
3 | |
3 | |
4 | SYNOPSIS |
4 | SYNOPSIS |
5 | # start geckodriver or any other w3c-compatible webdriver via the shell |
5 | # start geckodriver(chromedriver or any other webdriver via the shell |
6 | $ geckdriver -b myfirefox/firefox --log trace --port 4444 |
6 | $ geckodriver -b myfirefox/firefox --log trace --port 4444 |
|
|
7 | # chromedriver --port=4444 |
7 | |
8 | |
8 | # then use it |
9 | # then use it |
9 | use AnyEvent::WebDriver; |
10 | use AnyEvent::WebDriver; |
10 | |
11 | |
11 | # create a new webdriver object |
12 | # create a new webdriver object |
… | |
… | |
30 | ->type ("some text") |
31 | ->type ("some text") |
31 | ->key ("{Enter}") |
32 | ->key ("{Enter}") |
32 | ->perform; |
33 | ->perform; |
33 | |
34 | |
34 | DESCRIPTION |
35 | DESCRIPTION |
35 | WARNING: BEFORE VERSION 1.0, API CHANGES ARE LIKELY. |
|
|
36 | |
|
|
37 | This module aims to implement the W3C WebDriver specification which is |
36 | This module aims to implement the W3C WebDriver |
|
|
37 | <https://www.w3.org/TR/webdriver1/> specification which is the |
38 | the standardised equivalent to the Selenium WebDriver API., which in |
38 | standardised equivalent to the Selenium WebDriver API, which in turn |
39 | turn aims at remotely controlling web browsers such as Firefox or |
39 | aims at remotely controlling web browsers such as Firefox or Chromium. |
40 | Chromium. |
|
|
41 | |
|
|
42 | At the time of this writing, it was so brand new that I could only get |
|
|
43 | "geckodriver" (for Firefox) to work, but that is expected to be fixed |
|
|
44 | very soon indeed. |
|
|
45 | |
40 | |
46 | One of the design goals of this module was to stay very close to the |
41 | One of the design goals of this module was to stay very close to the |
47 | language and words used in the WebDriver specification itself, so to |
42 | language and words used in the WebDriver specification itself, so to |
48 | make most of this module, or, in fact, to make any reasonable use of |
43 | make most of this module, or, in fact, to make any reasonable use of |
49 | this module, you would need to refer to the W3C WebDriver |
44 | this module, you would need to refer to the W3C WebDriver |
50 | recommendation, which can be found here |
45 | recommendation, which can be found here |
51 | <https://www.w3.org/TR/webdriver1/>: |
46 | <https://www.w3.org/TR/webdriver1/>: |
52 | |
47 | |
53 | https://www.w3.org/TR/webdriver1/ |
48 | https://www.w3.org/TR/webdriver1/ |
54 | |
49 | |
|
|
50 | Mozilla's "geckodriver" has had webdriver for a long time, while |
|
|
51 | "chromedriver" only has basic and mostly undocumented webdriver support |
|
|
52 | since release 77. |
|
|
53 | |
|
|
54 | In debian GNU/Linux, you can install the "firefoxdriver" or |
|
|
55 | "chromium-driver" packages to get the firefox/chromium webdrivers, |
|
|
56 | respectively. |
|
|
57 | |
55 | CONVENTIONS |
58 | CONVENTIONS |
56 | Unless otherwise stated, all delays and time differences in this module |
59 | Unless otherwise stated, all delays and time differences in this module |
57 | are represented as an integer number of milliseconds. |
60 | are represented as an integer number of milliseconds. |
58 | |
61 | |
59 | WEBDRIVER OBJECTS |
62 | WEBDRIVER OBJECTS |
60 | new AnyEvent::WebDriver key => value... |
63 | new AnyEvent::WebDriver key => value... |
61 | Create a new WebDriver object. Example for a remote WebDriver |
64 | Create a new WebDriver object. Example for a remote WebDriver |
62 | connection (the only type supported at the moment): |
65 | connection (the only type supported at the moment): |
63 | |
66 | |
64 | my $wd = new AnyEvent::WebDriver host => "localhost", port => 4444; |
67 | my $wd = new AnyEvent::WebDriver endpoint => "http://localhost:4444"; |
65 | |
68 | |
66 | Supported keys are: |
69 | Supported keys are: |
67 | |
70 | |
68 | endpoint => $string |
71 | endpoint => $string |
69 | For remote connections, the endpoint to connect to (defaults to |
72 | For remote connections, the endpoint to connect to (defaults to |
… | |
… | |
93 | for all requests, which assumes you have a reasonably stable |
96 | for all requests, which assumes you have a reasonably stable |
94 | connection (such as to "localhost" :) and that the WebDriver has |
97 | connection (such as to "localhost" :) and that the WebDriver has |
95 | a persistent timeout much higher than what AnyEvent::HTTP uses. |
98 | a persistent timeout much higher than what AnyEvent::HTTP uses. |
96 | |
99 | |
97 | You can force connections to be closed for non-idempotent |
100 | You can force connections to be closed for non-idempotent |
98 | requests by setting this to "undef". |
101 | requests (the safe default of AnyEvent::HTTP) by setting this to |
|
|
102 | "undef". |
99 | |
103 | |
100 | $al = $wd->actions |
104 | $al = $wd->actions |
101 | Creates an action list associated with this WebDriver. See ACTION |
105 | Creates an action list associated with this WebDriver. See ACTION |
102 | LISTS, below, for full details. |
106 | LISTS, below, for full details. |
103 | |
107 | |
… | |
… | |
122 | there for later use), while the capabilities are stored in |
126 | there for later use), while the capabilities are stored in |
123 | "$wd->{capabilities}". |
127 | "$wd->{capabilities}". |
124 | |
128 | |
125 | SIMPLIFIED API |
129 | SIMPLIFIED API |
126 | This section documents the simplified API, which is really just a very |
130 | This section documents the simplified API, which is really just a very |
127 | thin wrapper around the WebDriver protocol commands. They all block |
131 | thin wrapper around the WebDriver protocol commands. They all block the |
128 | (using AnyEvent condvars) the caller until the result is available, so |
132 | caller until the result is available (using AnyEvent condvars), so must |
129 | must not be called from an event loop callback - see "EVENT BASED API" |
133 | not be called from an event loop callback - see "EVENT BASED API" for an |
130 | for an alternative. |
134 | alternative. |
131 | |
135 | |
132 | The method names are pretty much taken directly from the W3C WebDriver |
136 | The method names are pretty much taken directly from the W3C WebDriver |
133 | specification, e.g. the request documented in the "Get All Cookies" |
137 | specification, e.g. the request documented in the "Get All Cookies" |
134 | section is implemented via the "get_all_cookies" method. |
138 | section is implemented via the "get_all_cookies" method. |
135 | |
139 | |
… | |
… | |
150 | On success, "$wd->{sid}" is set to the session ID, and |
154 | On success, "$wd->{sid}" is set to the session ID, and |
151 | "$wd->{capabilities}" is set to the returned capabilities. |
155 | "$wd->{capabilities}" is set to the returned capabilities. |
152 | |
156 | |
153 | Simple example of creating a WebDriver object and a new session: |
157 | Simple example of creating a WebDriver object and a new session: |
154 | |
158 | |
155 | my $wd = new AnyEvent::Selenium endpoint => "http://localhost:4545"; |
159 | my $wd = new AnyEvent::WebDriver endpoint => "http://localhost:4444"; |
156 | $wd->new_session ({}); |
160 | $wd->new_session ({}); |
157 | |
161 | |
158 | Real-world example with capability negotiation: |
162 | Real-world example with capability negotiation: |
159 | |
163 | |
160 | $wd->new_session ({ |
164 | $wd->new_session ({ |
… | |
… | |
167 | firstMatch => [ |
171 | firstMatch => [ |
168 | { |
172 | { |
169 | browserName => "firefox", |
173 | browserName => "firefox", |
170 | "moz:firefoxOptions" => { |
174 | "moz:firefoxOptions" => { |
171 | binary => "firefox/firefox", |
175 | binary => "firefox/firefox", |
172 | args => ["-devtools"], |
176 | args => ["-devtools", "-headless"], |
173 | prefs => { |
177 | prefs => { |
174 | "dom.webnotifications.enabled" => \0, |
178 | "dom.webnotifications.enabled" => \0, |
175 | "dom.push.enabled" => \0, |
179 | "dom.push.enabled" => \0, |
176 | "dom.disable_beforeunload" => \1, |
180 | "dom.disable_beforeunload" => \1, |
177 | "browser.link.open_newwindow" => 3, |
181 | "browser.link.open_newwindow" => 3, |
… | |
… | |
180 | "dom.disable_open_during_load" => \1, |
184 | "dom.disable_open_during_load" => \1, |
181 | }, |
185 | }, |
182 | }, |
186 | }, |
183 | }, |
187 | }, |
184 | { |
188 | { |
|
|
189 | browserName => "chrome", |
|
|
190 | "goog:chromeOptions" => { |
|
|
191 | binary => "/bin/chromium", |
|
|
192 | args => ["--no-sandbox", "--headless"], |
|
|
193 | prefs => { |
|
|
194 | # ... |
|
|
195 | }, |
|
|
196 | }, |
|
|
197 | }, |
|
|
198 | { |
185 | # generic fallback |
199 | # generic fallback |
186 | }, |
200 | }, |
187 | ], |
201 | ], |
188 | |
202 | |
189 | }, |
203 | }, |
… | |
… | |
191 | |
205 | |
192 | Firefox-specific capability documentation can be found on MDN |
206 | Firefox-specific capability documentation can be found on MDN |
193 | <https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities |
207 | <https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities |
194 | >, Chrome-specific capability documentation might be found here |
208 | >, Chrome-specific capability documentation might be found here |
195 | <http://chromedriver.chromium.org/capabilities>, but the latest |
209 | <http://chromedriver.chromium.org/capabilities>, but the latest |
196 | release at the time of this writing has effectively no WebDriver |
210 | release at the time of this writing (chromedriver 77) has |
197 | support at all, and canary releases are not freely downloadable. |
211 | essentially no webdriver documentation about chrome capabilities. |
198 | |
212 | |
199 | If you have URLs for Safari/IE/Edge etc. capabilities, feel free to |
213 | If you have URLs for Safari/IE/Edge etc. capabilities, feel free to |
200 | tell me about them. |
214 | tell me about them. |
201 | |
215 | |
202 | $wd->delete_session |
216 | $wd->delete_session |
… | |
… | |
482 | SCREEN CAPTURE |
496 | SCREEN CAPTURE |
483 | $wd->take_screenshot |
497 | $wd->take_screenshot |
484 | Create a screenshot, returning it as a PNG image in a "data:" URL. |
498 | Create a screenshot, returning it as a PNG image in a "data:" URL. |
485 | |
499 | |
486 | $wd->take_element_screenshot ($element) |
500 | $wd->take_element_screenshot ($element) |
487 | Accept a simple dialog, if present. |
501 | Similar to "take_screenshot", but only takes a screenshot of the |
|
|
502 | bounding box of a single element. |
488 | |
503 | |
489 | ACTION LISTS |
504 | ACTION LISTS |
490 | Action lists can be quite complicated. Or at least it took a while for |
505 | Action lists can be quite complicated. Or at least it took a while for |
491 | me to twist my head around them. Basically, an action list consists of a |
506 | me to twist my head around them. Basically, an action list consists of a |
492 | number of sources representing devices (such as a finger, a mouse, a pen |
507 | number of sources representing devices (such as a finger, a mouse, a pen |
… | |
… | |
740 | $elems = $wd->post (elements => { using => "css selector", value => "img" }); |
755 | $elems = $wd->post (elements => { using => "css selector", value => "img" }); |
741 | |
756 | |
742 | HISTORY |
757 | HISTORY |
743 | This module was unintentionally created (it started inside some quickly |
758 | This module was unintentionally created (it started inside some quickly |
744 | hacked-together script) simply because I couldn't get the existing |
759 | hacked-together script) simply because I couldn't get the existing |
745 | "Selenium::Remote::Driver" module to work, ever, despite multiple |
760 | "Selenium::Remote::Driver" module to work reliably, ever, despite |
746 | attempts over the years and trying to report multiple bugs, which have |
761 | multiple attempts over the years and trying to report multiple bugs, |
747 | been completely ignored. It's also not event-based, so, yeah... |
762 | which have been completely ignored. It's also not event-based, so, |
|
|
763 | yeah... |
748 | |
764 | |
749 | AUTHOR |
765 | AUTHOR |
750 | Marc Lehmann <schmorp@schmorp.de> |
766 | Marc Lehmann <schmorp@schmorp.de> |
751 | http://anyevent.schmorp.de |
767 | http://anyevent.schmorp.de |
752 | |
768 | |