… | |
… | |
13 | |
13 | |
14 | # create a new session with default capabilities. |
14 | # create a new session with default capabilities. |
15 | $wd->new_session ({}); |
15 | $wd->new_session ({}); |
16 | |
16 | |
17 | $wd->navigate_to ("https://duckduckgo.com/html"); |
17 | $wd->navigate_to ("https://duckduckgo.com/html"); |
18 | my $searchbox = $wd->find_element ("css selector" => 'input[type="text"]'); |
18 | my $searchbox = $wd->find_element (css => 'input[type="text"]'); |
19 | |
19 | |
20 | $wd->element_send_keys ($searchbox => "free software"); |
20 | $wd->element_send_keys ($searchbox => "free software"); |
21 | $wd->element_click ($wd->find_element ("css selector" => 'input[type="submit"]')); |
21 | $wd->element_click ($wd->find_element (css => 'input[type="submit"]')); |
22 | |
22 | |
|
|
23 | # session gets autodeleted by default, so wait a bit |
23 | sleep 10; |
24 | sleep 10; |
24 | |
25 | |
|
|
26 | # this is an example of an action sequence |
|
|
27 | $wd->actions |
|
|
28 | ->move ($wd->find_element (...), 40, 5) |
|
|
29 | ->click |
|
|
30 | ->type ("some text") |
|
|
31 | ->key ("{Enter}") |
|
|
32 | ->perform; |
|
|
33 | |
25 | DESCRIPTION |
34 | DESCRIPTION |
26 | WARNING: THE API IS NOT GUARANTEED TO BE STABLE UNTIL VERSION 1.0. |
35 | WARNING: BEFORE VERSION 1.0, API CHANGES ARE LIKELY. |
27 | |
36 | |
28 | This module aims to implement the W3C WebDriver specification which is |
37 | This module aims to implement the W3C WebDriver specification which is |
29 | the standardised equivalent to the Selenium WebDriver API., which in |
38 | the standardised equivalent to the Selenium WebDriver API., which in |
30 | turn aims at remotely controlling web browsers such as Firefox or |
39 | turn aims at remotely controlling web browsers such as Firefox or |
31 | Chromium. |
40 | Chromium. |
32 | |
41 | |
33 | At the time of this writing, it was so brand new that I could only get |
42 | 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 fixed |
43 | "geckodriver" (for Firefox) to work, but that is expected to be fixed |
35 | very soon indeed. |
44 | very soon indeed. |
36 | |
45 | |
|
|
46 | 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 |
37 | To make most of this module, or, in fact, to make any reasonable use of |
48 | 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 |
49 | this module, you would need to refer to the W3C WebDriver |
39 | recommendation, which can be found here |
50 | recommendation, which can be found here |
40 | <https://www.w3.org/TR/webdriver1/>: |
51 | <https://www.w3.org/TR/webdriver1/>: |
41 | |
52 | |
42 | https://www.w3.org/TR/webdriver1/ |
53 | https://www.w3.org/TR/webdriver1/ |
… | |
… | |
248 | |
259 | |
249 | $rect = $wd->get_window_rect |
260 | $rect = $wd->get_window_rect |
250 | => { height => 1040, width => 540, x => 0, y => 0 } |
261 | => { height => 1040, width => 540, x => 0, y => 0 } |
251 | |
262 | |
252 | $wd->set_window_rect ($rect) |
263 | $wd->set_window_rect ($rect) |
253 | Sets the window rect(angle). |
264 | Sets the window rect(angle), e.g.: |
|
|
265 | |
|
|
266 | $wd->set_window_rect ({ width => 780, height => 560 }); |
|
|
267 | $wd->set_window_rect ({ x => 0, y => 0, width => 780, height => 560 }); |
254 | |
268 | |
255 | $wd->maximize_window |
269 | $wd->maximize_window |
256 | $wd->minimize_window |
270 | $wd->minimize_window |
257 | $wd->fullscreen_window |
271 | $wd->fullscreen_window |
258 | Changes the window size by either maximising, minimising or making |
272 | Changes the window size by either maximising, minimising or making |
… | |
… | |
339 | |
353 | |
340 | $wd->element_clear ($element) |
354 | $wd->element_clear ($element) |
341 | Clear the contents of the given element. |
355 | Clear the contents of the given element. |
342 | |
356 | |
343 | $wd->element_send_keys ($element, $text) |
357 | $wd->element_send_keys ($element, $text) |
344 | Sends the given text as key events to the given element. |
358 | Sends the given text as key events to the given element. Key input |
|
|
359 | state can be cleared by embedding "\x{e000}" in $text. Presumably, |
|
|
360 | you can embed modifiers using their unicode codepoints, but the |
|
|
361 | specification is less than clear to mein this area. |
345 | |
362 | |
346 | DOCUMENT HANDLING |
363 | DOCUMENT HANDLING |
347 | $source = $wd->get_page_source |
364 | $source = $wd->get_page_source |
348 | Returns the (HTML/XML) page source of the current document. |
365 | Returns the (HTML/XML) page source of the current document. |
349 | |
366 | |
… | |
… | |
400 | id => "myfatfinger", |
417 | id => "myfatfinger", |
401 | type => "pointer", |
418 | type => "pointer", |
402 | pointerType => "touch", |
419 | pointerType => "touch", |
403 | actions => [ |
420 | actions => [ |
404 | { type => "pointerMove", duration => 100, origin => $input, x => 40, y => 5 }, |
421 | { type => "pointerMove", duration => 100, origin => $input, x => 40, y => 5 }, |
405 | { type => "pointerDown", button => 1 }, |
422 | { type => "pointerDown", button => 0 }, |
406 | { type => "pause", duration => 40 }, |
423 | { type => "pause", duration => 40 }, |
407 | { type => "pointerUp", button => 1 }, |
424 | { type => "pointerUp", button => 0 }, |
408 | ], |
425 | ], |
409 | }, |
426 | }, |
410 | { |
427 | { |
411 | id => "mykeyboard", |
428 | id => "mykeyboard", |
412 | type => "key", |
429 | type => "key", |
… | |
… | |
430 | ], |
447 | ], |
431 | }, |
448 | }, |
432 | ]); |
449 | ]); |
433 | |
450 | |
434 | And here is essentially the same (except for fewer pauses) example |
451 | And here is essentially the same (except for fewer pauses) example |
435 | as above, using the much simpler "AnyEvent::WebDriver::Actions" API. |
452 | as above, using the much simpler "AnyEvent::WebDriver::Actions" API: |
436 | Note that the pointer up and key down event happen concurrently in |
|
|
437 | this example: |
|
|
438 | |
453 | |
439 | $wd->navigate_to ("https://duckduckgo.com/html"); |
454 | $wd->navigate_to ("https://duckduckgo.com/html"); |
440 | my $input = $wd->find_element ("css selector", 'input[type="text"]'); |
455 | my $input = $wd->find_element ("css selector", 'input[type="text"]'); |
441 | $wd->actions |
456 | $wd->actions |
442 | ->move ($input, 40, 5, "touch1") |
457 | ->move ($input, 40, 5, "touch1") |
443 | ->click |
458 | ->click |
444 | ->key ("a") |
459 | ->key ("a") |
445 | ->key ("b") |
460 | ->key ("b") |
446 | ->pause (2000) |
461 | ->pause (2000) # so you can watch leisurely |
447 | ->key ("\x{E007}") |
462 | ->key ("{Enter}") |
448 | ->pause (5000) |
463 | ->pause (5000) # so you can see the result |
449 | ->perform; |
464 | ->perform; |
450 | |
465 | |
451 | $wd->release_actions |
466 | $wd->release_actions |
452 | Release all keys and pointer buttons currently depressed. |
467 | Release all keys and pointer buttons currently depressed. |
453 | |
468 | |
… | |
… | |
476 | me to twist my head around them. Basically, an action list consists of a |
491 | me to twist my head around them. Basically, an action list consists of a |
477 | number of sources representing devices (such as a finger, a mouse, a pen |
492 | number of sources representing devices (such as a finger, a mouse, a pen |
478 | or a keyboard) and a list of actions for each source. |
493 | or a keyboard) and a list of actions for each source. |
479 | |
494 | |
480 | An action can be a key press, a pointer move or a pause (time delay). |
495 | An action can be a key press, a pointer move or a pause (time delay). |
481 | Actions from different sources can happen "at the same time", while |
|
|
482 | actions from a single source are executed in order. |
|
|
483 | |
496 | |
484 | While you can provide an action list manually, it is (hopefully) less |
497 | While you can provide these action lists manually, it is (hopefully) |
485 | cumbersome to use the API described in this section to create them. |
498 | less cumbersome to use the API described in this section to create them. |
486 | |
499 | |
487 | The basic process of creating and performing actions is to create a new |
500 | The basic process of creating and performing actions is to create a new |
488 | action list, adding action sources, followed by adding actions. Finally |
501 | action list, adding action sources, followed by adding actions. Finally |
489 | you would "perform" those actions on the WebDriver. |
502 | you would "perform" those actions on the WebDriver. |
490 | |
503 | |
491 | Virtual time progresses as long as you add actions to the same event |
|
|
492 | source. Adding events to different sources are considered to happen |
|
|
493 | concurrently. If you want to force time to progress, you can do this |
|
|
494 | using a call to "->pause (0)". |
|
|
495 | |
|
|
496 | Most methods here are designed to chain, i.e. they return the web |
504 | Most methods here are designed to chain, i.e. they return the web |
497 | actions object, to simplify multiple calls. |
505 | actions object, to simplify multiple calls. |
498 | |
506 | |
|
|
507 | Also, while actions from different sources can happen "at the same time" |
|
|
508 | in the WebDriver protocol, this class ensures that actions will execute |
|
|
509 | in the order specified. |
|
|
510 | |
499 | For example, to simulate a mouse click to an input element, followed by |
511 | For example, to simulate a mouse click to an input element, followed by |
500 | entering some text and pressing enter, you can use this: |
512 | entering some text and pressing enter, you can use this: |
501 | |
513 | |
502 | $wd->actions |
514 | $wd->actions |
503 | ->click (1, 100) |
515 | ->click (0, 100) |
504 | ->type ("some text") |
516 | ->type ("some text") |
505 | ->key ("{Enter}") |
517 | ->key ("{Enter}") |
506 | ->perform; |
518 | ->perform; |
507 | |
519 | |
508 | By default, keyboard and mouse input sources are provided. You can |
520 | By default, keyboard and mouse input sources are provided. You can |
… | |
… | |
510 | example could be more verbosely written like this: |
522 | example could be more verbosely written like this: |
511 | |
523 | |
512 | $wd->actions |
524 | $wd->actions |
513 | ->source ("mouse", "pointer", pointerType => "mouse") |
525 | ->source ("mouse", "pointer", pointerType => "mouse") |
514 | ->source ("kbd", "key") |
526 | ->source ("kbd", "key") |
515 | ->click (1, 100, "mouse") |
527 | ->click (0, 100, "mouse") |
516 | ->type ("some text", "kbd") |
528 | ->type ("some text", "kbd") |
517 | ->key ("{Enter}", "kbd") |
529 | ->key ("{Enter}", "kbd") |
518 | ->perform; |
530 | ->perform; |
519 | |
531 | |
520 | When you specify the event source explicitly it will switch the current |
532 | When you specify the event source explicitly it will switch the current |
… | |
… | |
556 | Creates a pause with the given duration. Makes sure that time |
568 | Creates a pause with the given duration. Makes sure that time |
557 | progresses in any case, even when $duration is 0. |
569 | progresses in any case, even when $duration is 0. |
558 | |
570 | |
559 | $al = $al->pointer_down ($button, $source) |
571 | $al = $al->pointer_down ($button, $source) |
560 | $al = $al->pointer_up ($button, $source) |
572 | $al = $al->pointer_up ($button, $source) |
561 | Press or release the given button. $button defaults to 1. |
573 | Press or release the given button. $button defaults to 0. |
562 | |
574 | |
563 | $al = $al->click ($button, $source) |
575 | $al = $al->click ($button, $source) |
564 | Convenience function that creates a button press and release action |
576 | Convenience function that creates a button press and release action |
565 | without any delay between them. $button defaults to 1. |
577 | without any delay between them. $button defaults to 0. |
566 | |
578 | |
567 | $al = $al->doubleclick ($button, $source) |
579 | $al = $al->doubleclick ($button, $source) |
568 | Convenience function that creates two button press and release |
580 | Convenience function that creates two button press and release |
569 | action pairs in a row, with no unnecessary delay between them. |
581 | action pairs in a row, with no unnecessary delay between them. |
570 | $button defaults to 1. |
582 | $button defaults to 0. |
571 | |
583 | |
572 | $al = $al->move ($button, $origin, $x, $y, $duration, $source) |
584 | $al = $al->move ($button, $origin, $x, $y, $duration, $source) |
573 | Moves a pointer to the given position, relative to origin (either |
585 | Moves a pointer to the given position, relative to origin (either |
574 | "viewport", "pointer" or an element object. |
586 | "viewport", "pointer" or an element object. |
|
|
587 | |
|
|
588 | $al = $al->cancel ($source) |
|
|
589 | Executes a pointer cancel action. |
575 | |
590 | |
576 | $al = $al->keyDown ($key, $source) |
591 | $al = $al->keyDown ($key, $source) |
577 | $al = $al->keyUp ($key, $source) |
592 | $al = $al->keyUp ($key, $source) |
578 | Press or release the given key. |
593 | Press or release the given key. |
579 | |
594 | |
… | |
… | |
598 | |
613 | |
599 | $al->key ("{Enter}"); |
614 | $al->key ("{Enter}"); |
600 | |
615 | |
601 | $al = $al->type ($string, $source) |
616 | $al = $al->type ($string, $source) |
602 | Convenience method to simulate a series of key press and release |
617 | Convenience method to simulate a series of key press and release |
603 | events for the keys in $string. There is no syntax for special keys, |
618 | events for the keys in $string, one pair per extended unicode |
|
|
619 | grapheme cluster. There is no syntax for special keys, everything |
604 | everything will be typed "as-is" if possible. |
620 | will be typed "as-is" if possible. |
605 | |
621 | |
606 | $al->perform ($wd) |
622 | $al->perform ($wd) |
607 | Finalises and compiles the list, if not done yet, and calls |
623 | Finalises and compiles the list, if not done yet, and calls |
608 | "$wd->perform" with it. |
624 | "$wd->perform" with it. |
609 | |
625 | |
… | |
… | |
676 | identical. |
692 | identical. |
677 | |
693 | |
678 | LOW LEVEL API |
694 | LOW LEVEL API |
679 | All the simplified API methods are very thin wrappers around WebDriver |
695 | All the simplified API methods are very thin wrappers around WebDriver |
680 | commands of the same name. They are all implemented in terms of the |
696 | commands of the same name. They are all implemented in terms of the |
681 | low-level methods ("req", "get", "post" and "delete"), which exists in |
697 | low-level methods ("req", "get", "post" and "delete"), which exist in |
682 | blocking and callback-based variants ("req_", "get_", "post_" and |
698 | blocking and callback-based variants ("req_", "get_", "post_" and |
683 | "delete_"). |
699 | "delete_"). |
684 | |
700 | |
685 | Examples are after the function descriptions. |
701 | Examples are after the function descriptions. |
686 | |
702 | |