… | |
… | |
28 | This module aims to implement the W3C WebDriver specification which is |
28 | This module aims to implement the W3C WebDriver specification which is |
29 | the standardised equivalent to the Selenium WebDriver API., which in |
29 | the standardised equivalent to the Selenium WebDriver API., which in |
30 | turn aims at remotely controlling web browsers such as Firefox or |
30 | turn aims at remotely controlling web browsers such as Firefox or |
31 | Chromium. |
31 | Chromium. |
32 | |
32 | |
33 | At the time of this writing, it was so brand new that I ciould only get |
33 | At the time of this writing, it was so brand new that I could only get |
34 | "geckodriver" (For Firefox) to work, but that is expected to be fioxed |
34 | "geckodriver" (For Firefox) to work, but that is expected to be fixed |
35 | very soon indeed. |
35 | very soon indeed. |
36 | |
36 | |
37 | To make most of this module, or, in fact, to make any reasonable use of |
37 | To make most of this module, or, in fact, to make any reasonable use of |
38 | this module, you would need to refer to the W3C WebDriver |
38 | this module, you would need to refer to the W3C WebDriver |
39 | recommendation, which can be found here |
39 | recommendation, which can be found here |
… | |
… | |
75 | this will likely drastically reduce). This timeout is reset on |
75 | this will likely drastically reduce). This timeout is reset on |
76 | any activity, so it is not an overall request timeout. Also, |
76 | any activity, so it is not an overall request timeout. Also, |
77 | individual requests might extend this timeout if they are known |
77 | individual requests might extend this timeout if they are known |
78 | to take longer. |
78 | to take longer. |
79 | |
79 | |
|
|
80 | persistent => 1 | "undef" |
|
|
81 | If true (the default) then persistent connections will be used |
|
|
82 | for all requests, which assumes you have a reasonably stable |
|
|
83 | connection (such as to "localhost" :) and that the WebDriver has |
|
|
84 | a persistent timeout much higher than what AnyEvent::HTTP uses. |
|
|
85 | |
|
|
86 | You can force connections to be closed for non-idempotent |
|
|
87 | requests by setting this to "undef". |
|
|
88 | |
80 | $al = $wd->actions |
89 | $al = $wd->actions |
81 | Creates an action list associated with this WebDriver. See ACTION |
90 | Creates an action list associated with this WebDriver. See ACTION |
82 | LISTS, below, for full details. |
91 | LISTS, below, for full details. |
83 | |
92 | |
84 | $sessionstring = $wd->save_session |
93 | $sessionstring = $wd->save_session |
… | |
… | |
87 | (currently the session id and capabilities), not the endpoint |
96 | (currently the session id and capabilities), not the endpoint |
88 | information itself. |
97 | information itself. |
89 | |
98 | |
90 | The main use of this function is in conjunction with disabled |
99 | The main use of this function is in conjunction with disabled |
91 | "autodelete", to save a session to e.g., and restore it later. It |
100 | "autodelete", to save a session to e.g., and restore it later. It |
92 | could presumably used for other applications, suhc as using the same |
101 | could presumably used for other applications, such as using the same |
93 | sssion from multiple processes and so on. |
102 | session from multiple processes and so on. |
94 | |
103 | |
95 | $wd->load_session ($sessionstring) |
104 | $wd->load_session ($sessionstring) |
96 | $wd->set_session ($sessionid, $capabilities) |
105 | $wd->set_session ($sessionid, $capabilities) |
97 | Starts using the given session, as identified by $sessionid. |
106 | Starts using the given session, as identified by $sessionid. |
98 | $capabilities should be the original session capabilities, although |
107 | $capabilities should be the original session capabilities, although |
… | |
… | |
128 | WebDriver object. |
137 | WebDriver object. |
129 | |
138 | |
130 | On success, "$wd->{sid}" is set to the session ID, and |
139 | On success, "$wd->{sid}" is set to the session ID, and |
131 | "$wd->{capabilities}" is set to the returned capabilities. |
140 | "$wd->{capabilities}" is set to the returned capabilities. |
132 | |
141 | |
133 | Simple example of creatring a WebDriver object and a new session: |
142 | Simple example of creating a WebDriver object and a new session: |
134 | |
143 | |
135 | my $wd = new AnyEvent::Selenium endpoint => "http://localhost:4545"; |
144 | my $wd = new AnyEvent::Selenium endpoint => "http://localhost:4545"; |
136 | $wd->new_session ({}); |
145 | $wd->new_session ({}); |
137 | |
146 | |
138 | Real-world example with capability negotiation: |
147 | Real-world example with capability negotiation: |
… | |
… | |
150 | "moz:firefoxOptions" => { |
159 | "moz:firefoxOptions" => { |
151 | binary => "firefox/firefox", |
160 | binary => "firefox/firefox", |
152 | args => ["-devtools"], |
161 | args => ["-devtools"], |
153 | prefs => { |
162 | prefs => { |
154 | "dom.webnotifications.enabled" => \0, |
163 | "dom.webnotifications.enabled" => \0, |
|
|
164 | "dom.push.enabled" => \0, |
155 | "dom.disable_beforeunload" => \1, |
165 | "dom.disable_beforeunload" => \1, |
156 | "browser.link.open_newwindow" => 3, |
166 | "browser.link.open_newwindow" => 3, |
157 | "browser.link.open_newwindow.restrictions" => 0, |
167 | "browser.link.open_newwindow.restrictions" => 0, |
158 | "dom.popup_allowed_events" => "", |
168 | "dom.popup_allowed_events" => "", |
159 | "dom.disable_open_during_load" => \1, |
169 | "dom.disable_open_during_load" => \1, |
… | |
… | |
232 | |
242 | |
233 | $handles = $wd->switch_to_parent_frame |
243 | $handles = $wd->switch_to_parent_frame |
234 | Switch to the parent frame. |
244 | Switch to the parent frame. |
235 | |
245 | |
236 | $rect = $wd->get_window_rect |
246 | $rect = $wd->get_window_rect |
237 | Return the current window rect, e.g.: |
247 | Return the current window rect(angle), e.g.: |
238 | |
248 | |
239 | $rect = $wd->get_window_rect |
249 | $rect = $wd->get_window_rect |
240 | => { height => 1040, width => 540, x => 0, y => 0 } |
250 | => { height => 1040, width => 540, x => 0, y => 0 } |
241 | |
251 | |
242 | $wd->set_window_rect ($rect) |
252 | $wd->set_window_rect ($rect) |
243 | Sets the window rect. |
253 | Sets the window rect(angle). |
244 | |
254 | |
245 | $wd->maximize_window |
255 | $wd->maximize_window |
246 | $wd->minimize_window |
256 | $wd->minimize_window |
247 | $wd->fullscreen_window |
257 | $wd->fullscreen_window |
248 | Changes the window size by either maximising, minimising or making |
258 | Changes the window size by either maximising, minimising or making |
… | |
… | |
262 | |
272 | |
263 | $element = $wd->find_element ($locator_strategy, $selector) |
273 | $element = $wd->find_element ($locator_strategy, $selector) |
264 | Finds the first element specified by the given selector and returns |
274 | Finds the first element specified by the given selector and returns |
265 | its element object. Raises an error when no element was found. |
275 | its element object. Raises an error when no element was found. |
266 | |
276 | |
|
|
277 | Examples showing all standard locator strategies: |
|
|
278 | |
267 | $element = $wd->find_element ("css selector" => "body a"); |
279 | $element = $wd->find_element ("css selector" => "body a"); |
268 | $element = $wd->find_element ("link text" => "Click Here For Porn"); |
280 | $element = $wd->find_element ("link text" => "Click Here For Porn"); |
269 | $element = $wd->find_element ("partial link text" => "orn"); |
281 | $element = $wd->find_element ("partial link text" => "orn"); |
270 | $element = $wd->find_element ("tag name" => "input"); |
282 | $element = $wd->find_element ("tag name" => "input"); |
271 | $element = $wd->find_element ("xpath" => '//input[@type="text"]'); |
283 | $element = $wd->find_element ("xpath" => '//input[@type="text"]'); |
272 | => e.g. { "element-6066-11e4-a52e-4f735466cecf" => "decddca8-5986-4e1d-8c93-efe952505a5f" } |
284 | => e.g. { "element-6066-11e4-a52e-4f735466cecf" => "decddca8-5986-4e1d-8c93-efe952505a5f" } |
|
|
285 | |
|
|
286 | Same examples using aliases provided by this module: |
|
|
287 | |
|
|
288 | $element = $wd->find_element (css => "body a"); |
|
|
289 | $element = $wd->find_element (link => "Click Here For Porn"); |
|
|
290 | $element = $wd->find_element (substr => "orn"); |
|
|
291 | $element = $wd->find_element (tag => "input"); |
273 | |
292 | |
274 | $elements = $wd->find_elements ($locator_strategy, $selector) |
293 | $elements = $wd->find_elements ($locator_strategy, $selector) |
275 | As above, but returns an arrayref of all found element objects. |
294 | As above, but returns an arrayref of all found element objects. |
276 | |
295 | |
277 | $element = $wd->find_element_from_element ($element, $locator_strategy, |
296 | $element = $wd->find_element_from_element ($element, $locator_strategy, |
… | |
… | |
419 | |
438 | |
420 | $wd->navigate_to ("https://duckduckgo.com/html"); |
439 | $wd->navigate_to ("https://duckduckgo.com/html"); |
421 | my $input = $wd->find_element ("css selector", 'input[type="text"]'); |
440 | my $input = $wd->find_element ("css selector", 'input[type="text"]'); |
422 | $wd->actions |
441 | $wd->actions |
423 | ->move ($input, 40, 5, "touch1") |
442 | ->move ($input, 40, 5, "touch1") |
424 | ->click; |
443 | ->click |
425 | ->key ("a"); |
444 | ->key ("a") |
426 | ->key ("b"); |
445 | ->key ("b") |
427 | ->pause (2000); |
446 | ->pause (2000) |
428 | ->key ("\x{E007}") |
447 | ->key ("\x{E007}") |
429 | ->pause (5000); |
448 | ->pause (5000) |
430 | ->perform; |
449 | ->perform; |
431 | |
450 | |
432 | $wd->release_actions |
451 | $wd->release_actions |
433 | Release all keys and pointer buttons currently depressed. |
452 | Release all keys and pointer buttons currently depressed. |
434 | |
453 | |
… | |
… | |
489 | By default, keyboard and mouse input sources are provided. You can |
508 | By default, keyboard and mouse input sources are provided. You can |
490 | create your own sources and use them when adding events. The above |
509 | create your own sources and use them when adding events. The above |
491 | example could be more verbosely written like this: |
510 | example could be more verbosely written like this: |
492 | |
511 | |
493 | $wd->actions |
512 | $wd->actions |
|
|
513 | ->source ("mouse", "pointer", pointerType => "mouse") |
|
|
514 | ->source ("kbd", "key") |
494 | ->click (1, 100, "mouse") |
515 | ->click (1, 100, "mouse") |
495 | ->type ("some text") |
516 | ->type ("some text", "kbd") |
496 | ->key ("{Enter}") |
517 | ->key ("{Enter}", "kbd") |
497 | ->perform; |
518 | ->perform; |
498 | |
519 | |
499 | When you specify the event source expliticly it will switch the current |
520 | When you specify the event source explicitly it will switch the current |
500 | "focus" for this class of device (all keyboards are in one class, all |
521 | "focus" for this class of device (all keyboards are in one class, all |
501 | pointer-like devices such as mice/fingers/pens are in one class), so you |
522 | pointer-like devices such as mice/fingers/pens are in one class), so you |
502 | don't have to specify the source for subsequent actions. |
523 | don't have to specify the source for subsequent actions. |
503 | |
524 | |
504 | When you use the sources "keyboard", "mouse", "touch1".."touch3", "pen" |
525 | When you use the sources "keyboard", "mouse", "touch1".."touch3", "pen" |
… | |
… | |
509 | Create a new empty action list object. More often you would use the |
530 | Create a new empty action list object. More often you would use the |
510 | "$wd->action_list" method to create one that is already associated |
531 | "$wd->action_list" method to create one that is already associated |
511 | with a given web driver. |
532 | with a given web driver. |
512 | |
533 | |
513 | $al = $al->source ($id, $type, key => value...) |
534 | $al = $al->source ($id, $type, key => value...) |
514 | The first time you call this with a givne ID, this defines the event |
535 | The first time you call this with a given ID, this defines the event |
515 | source using the extra parameters. Subsequent calls merely switch |
536 | source using the extra parameters. Subsequent calls merely switch |
516 | the current source for its event class. |
537 | the current source for its event class. |
517 | |
538 | |
518 | It's not an error to define built-in sources (such as "keyboard" or |
539 | It's not an error to define built-in sources (such as "keyboard" or |
519 | "touch1") differently then the defaults. |
540 | "touch1") differently then the defaults. |
520 | |
541 | |
521 | Example: define a new touch device called "fatfinger". |
542 | Example: define a new touch device called "fatfinger". |
522 | |
543 | |
523 | $al->source (fatfinger => "pointer", pointerType => "touch"); |
544 | $al->source (fatfinger => "pointer", pointerType => "touch"); |
524 | |
545 | |
525 | Example: switchdefine a new touch device called "fatfinger". |
546 | Example: define a new touch device called "fatfinger". |
526 | |
547 | |
527 | $al->source (fatfinger => "pointer", pointerType => "touch"); |
548 | $al->source (fatfinger => "pointer", pointerType => "touch"); |
|
|
549 | |
|
|
550 | Example: switch default keyboard source to "kbd1", assuming it is of |
|
|
551 | "key" class. |
|
|
552 | |
|
|
553 | $al->source ("kbd1"); |
528 | |
554 | |
529 | $al = $al->pause ($duration) |
555 | $al = $al->pause ($duration) |
530 | Creates a pause with the given duration. Makes sure that time |
556 | Creates a pause with the given duration. Makes sure that time |
531 | progresses in any case, even when $duration is 0. |
557 | progresses in any case, even when $duration is 0. |
532 | |
558 | |
… | |
… | |
576 | Convenience method to simulate a series of key press and release |
602 | Convenience method to simulate a series of key press and release |
577 | events for the keys in $string. There is no syntax for special keys, |
603 | events for the keys in $string. There is no syntax for special keys, |
578 | everything will be typed "as-is" if possible. |
604 | everything will be typed "as-is" if possible. |
579 | |
605 | |
580 | $al->perform ($wd) |
606 | $al->perform ($wd) |
581 | Finaluses and compiles the list, if not done yet, and calls |
607 | Finalises and compiles the list, if not done yet, and calls |
582 | "$wd->perform" with it. |
608 | "$wd->perform" with it. |
583 | |
609 | |
584 | If $wd is undef, and the action list was created using the |
610 | If $wd is undef, and the action list was created using the |
585 | "$wd->actions" method, then perform it against that WebDriver |
611 | "$wd->actions" method, then perform it against that WebDriver |
586 | object. |
612 | object. |