… | |
… | |
21 | $wd->element_click ($wd->find_element ("css selector" => 'input[type="submit"]')); |
21 | $wd->element_click ($wd->find_element ("css selector" => 'input[type="submit"]')); |
22 | |
22 | |
23 | sleep 10; |
23 | sleep 10; |
24 | |
24 | |
25 | DESCRIPTION |
25 | DESCRIPTION |
|
|
26 | WARNING: THE API IS NOT GUARANTEED TO BE STABLE UNTIL VERSION 1.0. |
|
|
27 | |
26 | This module aims to implement the W3C WebDriver specification which is |
28 | This module aims to implement the W3C WebDriver specification which is |
27 | the standardised equivalent to the Selenium WebDriver API., which in |
29 | the standardised equivalent to the Selenium WebDriver API., which in |
28 | turn aims at remotely controlling web browsers such as Firefox or |
30 | turn aims at remotely controlling web browsers such as Firefox or |
29 | Chromium. |
31 | Chromium. |
30 | |
32 | |
… | |
… | |
77 | |
79 | |
78 | $al = $wd->actions |
80 | $al = $wd->actions |
79 | Creates an action list associated with this WebDriver. See ACTION |
81 | Creates an action list associated with this WebDriver. See ACTION |
80 | LISTS, below, for full details. |
82 | LISTS, below, for full details. |
81 | |
83 | |
|
|
84 | $sessionstring = $wd->save_session |
|
|
85 | Save the current session in a string so it can be restored load with |
|
|
86 | "load_session". Note that only the session data itself is stored |
|
|
87 | (currently the session id and capabilities), not the endpoint |
|
|
88 | information itself. |
|
|
89 | |
|
|
90 | 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 |
|
|
92 | could presumably used for other applications, suhc as using the same |
|
|
93 | sssion from multiple processes and so on. |
|
|
94 | |
|
|
95 | $wd->load_session ($sessionstring) |
|
|
96 | $wd->set_session ($sessionid, $capabilities) |
|
|
97 | Starts using the given session, as identified by $sessionid. |
|
|
98 | $capabilities should be the original session capabilities, although |
|
|
99 | the current version of this module does not make any use of it. |
|
|
100 | |
|
|
101 | The $sessionid is stored in "$wd->{sid}" (and could be fetched form |
|
|
102 | there for later use), while the capabilities are stored in |
|
|
103 | "$wd->{capabilities}". |
|
|
104 | |
82 | SIMPLIFIED API |
105 | SIMPLIFIED API |
83 | This section documents the simplified API, which is really just a very |
106 | This section documents the simplified API, which is really just a very |
84 | thin wrapper around the WebDriver protocol commands. They all block |
107 | thin wrapper around the WebDriver protocol commands. They all block |
85 | (using AnyEvent condvars) the caller until the result is available, so |
108 | (using AnyEvent condvars) the caller until the result is available, so |
86 | must not be called from an event loop callback - see "EVENT BASED API" |
109 | must not be called from an event loop callback - see "EVENT BASED API" |
… | |
… | |
105 | WebDriver object. |
128 | WebDriver object. |
106 | |
129 | |
107 | On success, "$wd->{sid}" is set to the session ID, and |
130 | On success, "$wd->{sid}" is set to the session ID, and |
108 | "$wd->{capabilities}" is set to the returned capabilities. |
131 | "$wd->{capabilities}" is set to the returned capabilities. |
109 | |
132 | |
|
|
133 | Simple example of creatring a WebDriver object and a new session: |
|
|
134 | |
110 | my $wd = new AnyEvent::Selenium endpoint => "http://localhost:4545"; |
135 | my $wd = new AnyEvent::Selenium endpoint => "http://localhost:4545"; |
|
|
136 | $wd->new_session ({}); |
|
|
137 | |
|
|
138 | Real-world example with capability negotiation: |
111 | |
139 | |
112 | $wd->new_session ({ |
140 | $wd->new_session ({ |
113 | capabilities => { |
141 | capabilities => { |
|
|
142 | alwaysMatch => { |
114 | pageLoadStrategy => "normal", |
143 | pageLoadStrategy => "eager", |
|
|
144 | unhandledPromptBehavior => "dismiss", |
|
|
145 | # proxy => { proxyType => "manual", httpProxy => "1.2.3.4:56", sslProxy => "1.2.3.4:56" }, |
|
|
146 | }, |
|
|
147 | firstMatch => [ |
|
|
148 | { |
|
|
149 | browserName => "firefox", |
|
|
150 | "moz:firefoxOptions" => { |
|
|
151 | binary => "firefox/firefox", |
|
|
152 | args => ["-devtools"], |
|
|
153 | prefs => { |
|
|
154 | "dom.webnotifications.enabled" => \0, |
|
|
155 | "dom.disable_beforeunload" => \1, |
|
|
156 | "browser.link.open_newwindow" => 3, |
|
|
157 | "browser.link.open_newwindow.restrictions" => 0, |
|
|
158 | "dom.popup_allowed_events" => "", |
|
|
159 | "dom.disable_open_during_load" => \1, |
|
|
160 | }, |
|
|
161 | }, |
|
|
162 | }, |
|
|
163 | { |
|
|
164 | # generic fallback |
|
|
165 | }, |
|
|
166 | ], |
|
|
167 | |
115 | }. |
168 | }, |
116 | }); |
169 | }); |
|
|
170 | |
|
|
171 | Firefox-specific capability documentation can be found on MDN |
|
|
172 | <https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities |
|
|
173 | >, Chrome-specific capability documentation might be found here |
|
|
174 | <http://chromedriver.chromium.org/capabilities>, but the latest |
|
|
175 | release at the time of this writing has effectively no WebDriver |
|
|
176 | support at all, and canary releases are not freely downloadable. |
|
|
177 | |
|
|
178 | If you have URLs for Safari/IE/Edge etc. capabilities, feel free to |
|
|
179 | tell me about them. |
117 | |
180 | |
118 | $wd->delete_session |
181 | $wd->delete_session |
119 | Deletes the session - the WebDriver object must not be used after |
182 | Deletes the session - the WebDriver object must not be used after |
120 | this call. |
183 | this call. |
121 | |
184 | |
… | |
… | |
185 | Changes the window size by either maximising, minimising or making |
248 | Changes the window size by either maximising, minimising or making |
186 | it fullscreen. In my experience, this will timeout if no window |
249 | it fullscreen. In my experience, this will timeout if no window |
187 | manager is running. |
250 | manager is running. |
188 | |
251 | |
189 | ELEMENT RETRIEVAL |
252 | ELEMENT RETRIEVAL |
|
|
253 | To reduce typing and memory strain, the element finding functions accept |
|
|
254 | some shorter and hopefully easier to remember aliases for the standard |
|
|
255 | locator strategy values, as follows: |
|
|
256 | |
|
|
257 | Alias Locator Strategy |
|
|
258 | css css selector |
|
|
259 | link link text |
|
|
260 | substr partial link text |
|
|
261 | tag tag name |
|
|
262 | |
190 | $element = $wd->find_element ($location_strategy, $selector) |
263 | $element = $wd->find_element ($locator_strategy, $selector) |
191 | Finds the first element specified by the given selector and returns |
264 | Finds the first element specified by the given selector and returns |
192 | its element object. Raises an error when no element was found. |
265 | its element object. Raises an error when no element was found. |
193 | |
266 | |
194 | $element = $wd->find_element ("css selector" => "body a"); |
267 | $element = $wd->find_element ("css selector" => "body a"); |
195 | $element = $wd->find_element ("link text" => "Click Here For Porn"); |
268 | $element = $wd->find_element ("link text" => "Click Here For Porn"); |
196 | $element = $wd->find_element ("partial link text" => "orn"); |
269 | $element = $wd->find_element ("partial link text" => "orn"); |
197 | $element = $wd->find_element ("tag name" => "input"); |
270 | $element = $wd->find_element ("tag name" => "input"); |
198 | $element = $wd->find_element ("xpath" => '//input[@type="text"]'); |
271 | $element = $wd->find_element ("xpath" => '//input[@type="text"]'); |
199 | => e.g. { "element-6066-11e4-a52e-4f735466cecf" => "decddca8-5986-4e1d-8c93-efe952505a5f" } |
272 | => e.g. { "element-6066-11e4-a52e-4f735466cecf" => "decddca8-5986-4e1d-8c93-efe952505a5f" } |
200 | |
273 | |
201 | $elements = $wd->find_elements ($location_strategy, $selector) |
274 | $elements = $wd->find_elements ($locator_strategy, $selector) |
202 | As above, but returns an arrayref of all found element objects. |
275 | As above, but returns an arrayref of all found element objects. |
203 | |
276 | |
204 | $element = $wd->find_element_from_element ($element, $location_strategy, |
277 | $element = $wd->find_element_from_element ($element, $locator_strategy, |
205 | $selector) |
278 | $selector) |
206 | Like "find_element", but looks only inside the specified $element. |
279 | Like "find_element", but looks only inside the specified $element. |
207 | |
280 | |
208 | $elements = $wd->find_elements_from_element ($element, |
281 | $elements = $wd->find_elements_from_element ($element, |
209 | $location_strategy, $selector) |
282 | $locator_strategy, $selector) |
210 | Like "find_elements", but looks only inside the specified $element. |
283 | Like "find_elements", but looks only inside the specified $element. |
211 | |
284 | |
212 | my $head = $wd->find_element ("tag name" => "head"); |
285 | my $head = $wd->find_element ("tag name" => "head"); |
213 | my $links = $wd->find_elements_from_element ($head, "tag name", "link"); |
286 | my $links = $wd->find_elements_from_element ($head, "tag name", "link"); |
214 | |
287 | |
… | |
… | |
408 | entering some text and pressing enter, you can use this: |
481 | entering some text and pressing enter, you can use this: |
409 | |
482 | |
410 | $wd->actions |
483 | $wd->actions |
411 | ->click (1, 100) |
484 | ->click (1, 100) |
412 | ->type ("some text") |
485 | ->type ("some text") |
413 | ->key ("Enter") |
486 | ->key ("{Enter}") |
414 | ->perform; |
487 | ->perform; |
415 | |
488 | |
416 | By default, keyboard and mouse input sources are provided. You can |
489 | By default, keyboard and mouse input sources are provided. You can |
417 | create your own sources and use them when adding events. The above |
490 | create your own sources and use them when adding events. The above |
418 | example could be more verbosely written like this: |
491 | example could be more verbosely written like this: |
419 | |
492 | |
420 | $wd->actions |
493 | $wd->actions |
421 | ->click (1, 100, "mouse") |
494 | ->click (1, 100, "mouse") |
422 | ->type ("some text") |
495 | ->type ("some text") |
423 | ->key ("Enter") |
496 | ->key ("{Enter}") |
424 | ->perform; |
497 | ->perform; |
425 | |
|
|
426 | #TODO verboser example |
|
|
427 | |
498 | |
428 | When you specify the event source expliticly it will switch the current |
499 | When you specify the event source expliticly it will switch the current |
429 | "focus" for this class of device (all keyboards are in one class, all |
500 | "focus" for this class of device (all keyboards are in one class, all |
430 | pointer-like devices such as mice/fingers/pens are in one class), so you |
501 | pointer-like devices such as mice/fingers/pens are in one class), so you |
431 | don't have to specify the source for subsequent actions. |
502 | don't have to specify the source for subsequent actions. |
… | |
… | |
434 | without defining them, then a suitable default source will be created |
505 | without defining them, then a suitable default source will be created |
435 | for them. |
506 | for them. |
436 | |
507 | |
437 | $al = new AnyEvent::WebDriver::Actions |
508 | $al = new AnyEvent::WebDriver::Actions |
438 | Create a new empty action list object. More often you would use the |
509 | Create a new empty action list object. More often you would use the |
439 | "$sel->action_list" method to create one that is already associated |
510 | "$wd->action_list" method to create one that is already associated |
440 | with a given web driver. |
511 | with a given web driver. |
441 | |
512 | |
442 | $al = $al->source ($id, $type, key => value...) |
513 | $al = $al->source ($id, $type, key => value...) |
443 | The first time you call this with a givne ID, this defines the event |
514 | The first time you call this with a givne ID, this defines the event |
444 | source using the extra parameters. Subsequent calls merely switch |
515 | source using the extra parameters. Subsequent calls merely switch |
… | |
… | |
477 | "viewport", "pointer" or an element object. |
548 | "viewport", "pointer" or an element object. |
478 | |
549 | |
479 | $al = $al->keyDown ($key, $source) |
550 | $al = $al->keyDown ($key, $source) |
480 | $al = $al->keyUp ($key, $source) |
551 | $al = $al->keyUp ($key, $source) |
481 | Press or release the given key. |
552 | Press or release the given key. |
|
|
553 | |
|
|
554 | $al = $al->key ($key, $source) |
|
|
555 | Peess and release the given key, without unnecessary delay. |
|
|
556 | |
|
|
557 | A special syntax, "{keyname}" can be used for special keys - all the |
|
|
558 | special key names from section 17.4.2 |
|
|
559 | <https://www.w3.org/TR/webdriver1/#keyboard-actions> of the |
|
|
560 | WebDriver recommendation can be used. |
|
|
561 | |
|
|
562 | Example: press and release "a". |
|
|
563 | |
|
|
564 | $al->key ("a"); |
|
|
565 | |
|
|
566 | Example: press and release the "Enter" key: |
|
|
567 | |
|
|
568 | $al->key ("\x{e007}"); |
|
|
569 | |
|
|
570 | Example: press and release the "enter" key using the special key |
|
|
571 | name syntax: |
|
|
572 | |
|
|
573 | $al->key ("{Enter}"); |
|
|
574 | |
|
|
575 | $al = $al->type ($string, $source) |
|
|
576 | 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, |
|
|
578 | everything will be typed "as-is" if possible. |
482 | |
579 | |
483 | $al->perform ($wd) |
580 | $al->perform ($wd) |
484 | Finaluses and compiles the list, if not done yet, and calls |
581 | Finaluses and compiles the list, if not done yet, and calls |
485 | "$wd->perform" with it. |
582 | "$wd->perform" with it. |
486 | |
583 | |