ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-WebDriver/README
Revision: 1.9
Committed: Fri Sep 27 03:31:02 2019 UTC (4 years, 8 months ago) by root
Branch: MAIN
CVS Tags: rel-1_01
Changes since 1.8: +19 -14 lines
Log Message:
1.01

File Contents

# Content
1 NAME
2 AnyEvent::WebDriver - control browsers using the W3C WebDriver protocol
3
4 SYNOPSIS
5 # start geckodriver(chromedriver or any other webdriver via the shell
6 $ geckodriver -b myfirefox/firefox --log trace --port 4444
7 # chromedriver --port=4444
8
9 # then use it
10 use AnyEvent::WebDriver;
11
12 # create a new webdriver object
13 my $wd = new AnyEvent::WebDriver;
14
15 # create a new session with default capabilities.
16 $wd->new_session ({});
17
18 $wd->navigate_to ("https://duckduckgo.com/html");
19 my $searchbox = $wd->find_element (css => 'input[type="text"]');
20
21 $wd->element_send_keys ($searchbox => "free software");
22 $wd->element_click ($wd->find_element (css => 'input[type="submit"]'));
23
24 # session gets autodeleted by default, so wait a bit
25 sleep 10;
26
27 # this is an example of an action sequence
28 $wd->actions
29 ->move ($wd->find_element (...), 40, 5)
30 ->click
31 ->type ("some text")
32 ->key ("{Enter}")
33 ->perform;
34
35 DESCRIPTION
36 This module aims to implement the W3C WebDriver
37 <https://www.w3.org/TR/webdriver1/> specification which is the
38 standardised equivalent to the Selenium WebDriver API, which in turn
39 aims at remotely controlling web browsers such as Firefox or Chromium.
40
41 One of the design goals of this module was to stay very close to the
42 language and words used in the WebDriver specification itself, so to
43 make most of this module, or, in fact, to make any reasonable use of
44 this module, you would need to refer to the W3C WebDriver
45 recommendation, which can be found here
46 <https://www.w3.org/TR/webdriver1/>:
47
48 https://www.w3.org/TR/webdriver1/
49
50 Mozilla's "geckodriver" has had webdriver for a long time, while
51 "chromedriver" only has basic and mostly undocumented webdriver support
52 as of release 77.
53
54 CONVENTIONS
55 Unless otherwise stated, all delays and time differences in this module
56 are represented as an integer number of milliseconds.
57
58 WEBDRIVER OBJECTS
59 new AnyEvent::WebDriver key => value...
60 Create a new WebDriver object. Example for a remote WebDriver
61 connection (the only type supported at the moment):
62
63 my $wd = new AnyEvent::WebDriver endpoint => "http://localhost:4444";
64
65 Supported keys are:
66
67 endpoint => $string
68 For remote connections, the endpoint to connect to (defaults to
69 "http://localhost:4444").
70
71 proxy => $proxyspec
72 The proxy to use (same as the "proxy" argument used by
73 AnyEvent::HTTP). The default is "undef", which disables proxies.
74 To use the system-provided proxy (e.g. "http_proxy" environment
75 variable), specify a value of "default".
76
77 autodelete => $boolean
78 If true (the default), then automatically execute
79 "delete_session" when the WebDriver object is destroyed with an
80 active session. If set to a false value, then the session will
81 continue to exist.
82
83 Note that due to bugs in perl that are unlikely to get fixed,
84 "autodelete" is likely ineffective during global destruction and
85 might even crash your process, so you should ensure objects go
86 out of scope before that, or explicitly call "delete_session",
87 if you want the session to be cleaned up.
88
89 timeout => $seconds
90 The HTTP timeout, in (fractional) seconds (default: 300). This
91 timeout is reset on any activity, so it is not an overall
92 request timeout. Also, individual requests might extend this
93 timeout if they are known to take longer.
94
95 persistent => 1 | "undef"
96 If true (the default) then persistent connections will be used
97 for all requests, which assumes you have a reasonably stable
98 connection (such as to "localhost" :) and that the WebDriver has
99 a persistent timeout much higher than what AnyEvent::HTTP uses.
100
101 You can force connections to be closed for non-idempotent
102 requests (the safe default of AnyEvent::HTTP) by setting this to
103 "undef".
104
105 $al = $wd->actions
106 Creates an action list associated with this WebDriver. See ACTION
107 LISTS, below, for full details.
108
109 $sessionstring = $wd->save_session
110 Save the current session in a string so it can be restored load with
111 "load_session". Note that only the session data itself is stored
112 (currently the session id and capabilities), not the endpoint
113 information itself.
114
115 The main use of this function is in conjunction with disabled
116 "autodelete", to save a session to e.g., and restore it later. It
117 could presumably used for other applications, such as using the same
118 session from multiple processes and so on.
119
120 $wd->load_session ($sessionstring)
121 $wd->set_session ($sessionid, $capabilities)
122 Starts using the given session, as identified by $sessionid.
123 $capabilities should be the original session capabilities, although
124 the current version of this module does not make any use of it.
125
126 The $sessionid is stored in "$wd->{sid}" (and could be fetched form
127 there for later use), while the capabilities are stored in
128 "$wd->{capabilities}".
129
130 SIMPLIFIED API
131 This section documents the simplified API, which is really just a very
132 thin wrapper around the WebDriver protocol commands. They all block the
133 caller until the result is available (using AnyEvent condvars), so must
134 not be called from an event loop callback - see "EVENT BASED API" for an
135 alternative.
136
137 The method names are pretty much taken directly from the W3C WebDriver
138 specification, e.g. the request documented in the "Get All Cookies"
139 section is implemented via the "get_all_cookies" method.
140
141 The order is the same as in the WebDriver draft at the time of this
142 writing, and only minimal massaging is done to request parameters and
143 results.
144
145 SESSIONS
146 $wd->new_session ({ key => value... })
147 Try to connect to the WebDriver and initialize a new session with a
148 "new session" command, passing the given key-value pairs as value
149 (e.g. "capabilities").
150
151 No session-dependent methods must be called before this function
152 returns successfully, and only one session can be created per
153 WebDriver object.
154
155 On success, "$wd->{sid}" is set to the session ID, and
156 "$wd->{capabilities}" is set to the returned capabilities.
157
158 Simple example of creating a WebDriver object and a new session:
159
160 my $wd = new AnyEvent::WebDriver endpoint => "http://localhost:4444";
161 $wd->new_session ({});
162
163 Real-world example with capability negotiation:
164
165 $wd->new_session ({
166 capabilities => {
167 alwaysMatch => {
168 pageLoadStrategy => "eager",
169 unhandledPromptBehavior => "dismiss",
170 # proxy => { proxyType => "manual", httpProxy => "1.2.3.4:56", sslProxy => "1.2.3.4:56" },
171 },
172 firstMatch => [
173 {
174 browserName => "firefox",
175 "moz:firefoxOptions" => {
176 binary => "firefox/firefox",
177 args => ["-devtools", "-headless"],
178 prefs => {
179 "dom.webnotifications.enabled" => \0,
180 "dom.push.enabled" => \0,
181 "dom.disable_beforeunload" => \1,
182 "browser.link.open_newwindow" => 3,
183 "browser.link.open_newwindow.restrictions" => 0,
184 "dom.popup_allowed_events" => "",
185 "dom.disable_open_during_load" => \1,
186 },
187 },
188 },
189 {
190 browserName => "chrome",
191 "goog:chromeOptions" => {
192 binary => "/bin/chromium",
193 args => ["--no-sandbox", "--headless"],
194 prefs => {
195 # ...
196 },
197 },
198 },
199 {
200 # generic fallback
201 },
202 ],
203
204 },
205 });
206
207 Firefox-specific capability documentation can be found on MDN
208 <https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities
209 >, Chrome-specific capability documentation might be found here
210 <http://chromedriver.chromium.org/capabilities>, but the latest
211 release at the time of this writing (chromedriver 77) has
212 essentially no documentation about webdriver capabilities (even MDN
213 has better documentation about chromwedriver!)
214
215 If you have URLs for Safari/IE/Edge etc. capabilities, feel free to
216 tell me about them.
217
218 $wd->delete_session
219 Deletes the session - the WebDriver object must not be used after
220 this call (except for calling this method).
221
222 This method is always safe to call and will not do anything if there
223 is no active session.
224
225 $timeouts = $wd->get_timeouts
226 Get the current timeouts, e.g.:
227
228 my $timeouts = $wd->get_timeouts;
229 => { implicit => 0, pageLoad => 300000, script => 30000 }
230
231 $wd->set_timeouts ($timeouts)
232 Sets one or more timeouts, e.g.:
233
234 $wd->set_timeouts ({ script => 60000 });
235
236 NAVIGATION
237 $wd->navigate_to ($url)
238 Navigates to the specified URL.
239
240 $url = $wd->get_current_url
241 Queries the current page URL as set by "navigate_to".
242
243 $wd->back
244 The equivalent of pressing "back" in the browser.
245
246 $wd->forward
247 The equivalent of pressing "forward" in the browser.
248
249 $wd->refresh
250 The equivalent of pressing "refresh" in the browser.
251
252 $title = $wd->get_title
253 Returns the current document title.
254
255 COMMAND CONTEXTS
256 $handle = $wd->get_window_handle
257 Returns the current window handle.
258
259 $wd->close_window
260 Closes the current browsing context.
261
262 $wd->switch_to_window ($handle)
263 Changes the current browsing context to the given window.
264
265 $handles = $wd->get_window_handles
266 Return the current window handles as an array-ref of handle IDs.
267
268 $handles = $wd->switch_to_frame ($frame)
269 Switch to the given frame identified by $frame, which must be either
270 "undef" to go back to the top-level browsing context, an integer to
271 select the nth subframe, or an element object.
272
273 $handles = $wd->switch_to_parent_frame
274 Switch to the parent frame.
275
276 $rect = $wd->get_window_rect
277 Return the current window rect(angle), e.g.:
278
279 $rect = $wd->get_window_rect
280 => { height => 1040, width => 540, x => 0, y => 0 }
281
282 $wd->set_window_rect ($rect)
283 Sets the window rect(angle), e.g.:
284
285 $wd->set_window_rect ({ width => 780, height => 560 });
286 $wd->set_window_rect ({ x => 0, y => 0, width => 780, height => 560 });
287
288 $wd->maximize_window
289 $wd->minimize_window
290 $wd->fullscreen_window
291 Changes the window size by either maximising, minimising or making
292 it fullscreen. In my experience, this will timeout if no window
293 manager is running.
294
295 ELEMENT RETRIEVAL
296 To reduce typing and memory strain, the element finding functions accept
297 some shorter and hopefully easier to remember aliases for the standard
298 locator strategy values, as follows:
299
300 Alias Locator Strategy
301 css css selector
302 link link text
303 substr partial link text
304 tag tag name
305
306 $element = $wd->find_element ($locator_strategy, $selector)
307 Finds the first element specified by the given selector and returns
308 its element object. Raises an error when no element was found.
309
310 Examples showing all standard locator strategies:
311
312 $element = $wd->find_element ("css selector" => "body a");
313 $element = $wd->find_element ("link text" => "Click Here For Porn");
314 $element = $wd->find_element ("partial link text" => "orn");
315 $element = $wd->find_element ("tag name" => "input");
316 $element = $wd->find_element ("xpath" => '//input[@type="text"]');
317 => e.g. { "element-6066-11e4-a52e-4f735466cecf" => "decddca8-5986-4e1d-8c93-efe952505a5f" }
318
319 Same examples using aliases provided by this module:
320
321 $element = $wd->find_element (css => "body a");
322 $element = $wd->find_element (link => "Click Here For Porn");
323 $element = $wd->find_element (substr => "orn");
324 $element = $wd->find_element (tag => "input");
325
326 $elements = $wd->find_elements ($locator_strategy, $selector)
327 As above, but returns an arrayref of all found element objects.
328
329 $element = $wd->find_element_from_element ($element, $locator_strategy,
330 $selector)
331 Like "find_element", but looks only inside the specified $element.
332
333 $elements = $wd->find_elements_from_element ($element,
334 $locator_strategy, $selector)
335 Like "find_elements", but looks only inside the specified $element.
336
337 my $head = $wd->find_element ("tag name" => "head");
338 my $links = $wd->find_elements_from_element ($head, "tag name", "link");
339
340 $element = $wd->get_active_element
341 Returns the active element.
342
343 ELEMENT STATE
344 $bool = $wd->is_element_selected
345 Returns whether the given input or option element is selected or
346 not.
347
348 $string = $wd->get_element_attribute ($element, $name)
349 Returns the value of the given attribute.
350
351 $string = $wd->get_element_property ($element, $name)
352 Returns the value of the given property.
353
354 $string = $wd->get_element_css_value ($element, $name)
355 Returns the value of the given CSS value.
356
357 $string = $wd->get_element_text ($element)
358 Returns the (rendered) text content of the given element.
359
360 $string = $wd->get_element_tag_name ($element)
361 Returns the tag of the given element.
362
363 $rect = $wd->get_element_rect ($element)
364 Returns the element rect(angle) of the given element.
365
366 $bool = $wd->is_element_enabled
367 Returns whether the element is enabled or not.
368
369 ELEMENT INTERACTION
370 $wd->element_click ($element)
371 Clicks the given element.
372
373 $wd->element_clear ($element)
374 Clear the contents of the given element.
375
376 $wd->element_send_keys ($element, $text)
377 Sends the given text as key events to the given element. Key input
378 state can be cleared by embedding "\x{e000}" in $text. Presumably,
379 you can embed modifiers using their unicode codepoints, but the
380 specification is less than clear to mein this area.
381
382 DOCUMENT HANDLING
383 $source = $wd->get_page_source
384 Returns the (HTML/XML) page source of the current document.
385
386 $results = $wd->execute_script ($javascript, $args)
387 Synchronously execute the given script with given arguments and
388 return its results ($args can be "undef" if no arguments are
389 wanted/needed).
390
391 $ten = $wd->execute_script ("return arguments[0]+arguments[1]", [3, 7]);
392
393 $results = $wd->execute_async_script ($javascript, $args)
394 Similar to "execute_script", but doesn't wait for script to return,
395 but instead waits for the script to call its last argument, which is
396 added to $args automatically.
397
398 $twenty = $wd->execute_async_script ("arguments[0](20)", undef);
399
400 COOKIES
401 $cookies = $wd->get_all_cookies
402 Returns all cookies, as an arrayref of hashrefs.
403
404 # google surely sets a lot of cookies without my consent
405 $wd->navigate_to ("http://google.com");
406 use Data::Dump;
407 ddx $wd->get_all_cookies;
408
409 $cookie = $wd->get_named_cookie ($name)
410 Returns a single cookie as a hashref.
411
412 $wd->add_cookie ($cookie)
413 Adds the given cookie hashref.
414
415 $wd->delete_cookie ($name)
416 Delete the named cookie.
417
418 $wd->delete_all_cookies
419 Delete all cookies.
420
421 ACTIONS
422 $wd->perform_actions ($actions)
423 Perform the given actions (an arrayref of action specifications
424 simulating user activity, or an "AnyEvent::WebDriver::Actions"
425 object). For further details, read the spec or the section "ACTION
426 LISTS", below.
427
428 An example to get you started (see the next example for a mostly
429 equivalent example using the "AnyEvent::WebDriver::Actions" helper
430 API):
431
432 $wd->navigate_to ("https://duckduckgo.com/html");
433 my $input = $wd->find_element ("css selector", 'input[type="text"]');
434 $wd->perform_actions ([
435 {
436 id => "myfatfinger",
437 type => "pointer",
438 pointerType => "touch",
439 actions => [
440 { type => "pointerMove", duration => 100, origin => $input, x => 40, y => 5 },
441 { type => "pointerDown", button => 0 },
442 { type => "pause", duration => 40 },
443 { type => "pointerUp", button => 0 },
444 ],
445 },
446 {
447 id => "mykeyboard",
448 type => "key",
449 actions => [
450 { type => "pause" },
451 { type => "pause" },
452 { type => "pause" },
453 { type => "pause" },
454 { type => "keyDown", value => "a" },
455 { type => "pause", duration => 100 },
456 { type => "keyUp", value => "a" },
457 { type => "pause", duration => 100 },
458 { type => "keyDown", value => "b" },
459 { type => "pause", duration => 100 },
460 { type => "keyUp", value => "b" },
461 { type => "pause", duration => 2000 },
462 { type => "keyDown", value => "\x{E007}" }, # enter
463 { type => "pause", duration => 100 },
464 { type => "keyUp", value => "\x{E007}" }, # enter
465 { type => "pause", duration => 5000 },
466 ],
467 },
468 ]);
469
470 And here is essentially the same (except for fewer pauses) example
471 as above, using the much simpler "AnyEvent::WebDriver::Actions" API:
472
473 $wd->navigate_to ("https://duckduckgo.com/html");
474 my $input = $wd->find_element ("css selector", 'input[type="text"]');
475 $wd->actions
476 ->move ($input, 40, 5, "touch1")
477 ->click
478 ->key ("a")
479 ->key ("b")
480 ->pause (2000) # so you can watch leisurely
481 ->key ("{Enter}")
482 ->pause (5000) # so you can see the result
483 ->perform;
484
485 $wd->release_actions
486 Release all keys and pointer buttons currently depressed.
487
488 USER PROMPTS
489 $wd->dismiss_alert
490 Dismiss a simple dialog, if present.
491
492 $wd->accept_alert
493 Accept a simple dialog, if present.
494
495 $text = $wd->get_alert_text
496 Returns the text of any simple dialog.
497
498 $text = $wd->send_alert_text
499 Fills in the user prompt with the given text.
500
501 SCREEN CAPTURE
502 $wd->take_screenshot
503 Create a screenshot, returning it as a PNG image in a "data:" URL.
504
505 $wd->take_element_screenshot ($element)
506 Similar to "take_screenshot", but only takes a screenshot of the
507 bounding box of a single element.
508
509 ACTION LISTS
510 Action lists can be quite complicated. Or at least it took a while for
511 me to twist my head around them. Basically, an action list consists of a
512 number of sources representing devices (such as a finger, a mouse, a pen
513 or a keyboard) and a list of actions for each source.
514
515 An action can be a key press, a pointer move or a pause (time delay).
516
517 While you can provide these action lists manually, it is (hopefully)
518 less cumbersome to use the API described in this section to create them.
519
520 The basic process of creating and performing actions is to create a new
521 action list, adding action sources, followed by adding actions. Finally
522 you would "perform" those actions on the WebDriver.
523
524 Most methods here are designed to chain, i.e. they return the web
525 actions object, to simplify multiple calls.
526
527 Also, while actions from different sources can happen "at the same time"
528 in the WebDriver protocol, this class ensures that actions will execute
529 in the order specified.
530
531 For example, to simulate a mouse click to an input element, followed by
532 entering some text and pressing enter, you can use this:
533
534 $wd->actions
535 ->click (0, 100)
536 ->type ("some text")
537 ->key ("{Enter}")
538 ->perform;
539
540 By default, keyboard and mouse input sources are provided. You can
541 create your own sources and use them when adding events. The above
542 example could be more verbosely written like this:
543
544 $wd->actions
545 ->source ("mouse", "pointer", pointerType => "mouse")
546 ->source ("kbd", "key")
547 ->click (0, 100, "mouse")
548 ->type ("some text", "kbd")
549 ->key ("{Enter}", "kbd")
550 ->perform;
551
552 When you specify the event source explicitly it will switch the current
553 "focus" for this class of device (all keyboards are in one class, all
554 pointer-like devices such as mice/fingers/pens are in one class), so you
555 don't have to specify the source for subsequent actions.
556
557 When you use the sources "keyboard", "mouse", "touch1".."touch3", "pen"
558 without defining them, then a suitable default source will be created
559 for them.
560
561 $al = new AnyEvent::WebDriver::Actions
562 Create a new empty action list object. More often you would use the
563 "$wd->action_list" method to create one that is already associated
564 with a given web driver.
565
566 $al = $al->source ($id, $type, key => value...)
567 The first time you call this with a given ID, this defines the event
568 source using the extra parameters. Subsequent calls merely switch
569 the current source for its event class.
570
571 It's not an error to define built-in sources (such as "keyboard" or
572 "touch1") differently then the defaults.
573
574 Example: define a new touch device called "fatfinger".
575
576 $al->source (fatfinger => "pointer", pointerType => "touch");
577
578 Example: define a new touch device called "fatfinger".
579
580 $al->source (fatfinger => "pointer", pointerType => "touch");
581
582 Example: switch default keyboard source to "kbd1", assuming it is of
583 "key" class.
584
585 $al->source ("kbd1");
586
587 $al = $al->pause ($duration)
588 Creates a pause with the given duration. Makes sure that time
589 progresses in any case, even when $duration is 0.
590
591 $al = $al->pointer_down ($button, $source)
592 $al = $al->pointer_up ($button, $source)
593 Press or release the given button. $button defaults to 0.
594
595 $al = $al->click ($button, $source)
596 Convenience function that creates a button press and release action
597 without any delay between them. $button defaults to 0.
598
599 $al = $al->doubleclick ($button, $source)
600 Convenience function that creates two button press and release
601 action pairs in a row, with no unnecessary delay between them.
602 $button defaults to 0.
603
604 $al = $al->move ($button, $origin, $x, $y, $duration, $source)
605 Moves a pointer to the given position, relative to origin (either
606 "viewport", "pointer" or an element object.
607
608 $al = $al->cancel ($source)
609 Executes a pointer cancel action.
610
611 $al = $al->keyDown ($key, $source)
612 $al = $al->keyUp ($key, $source)
613 Press or release the given key.
614
615 $al = $al->key ($key, $source)
616 Peess and release the given key, without unnecessary delay.
617
618 A special syntax, "{keyname}" can be used for special keys - all the
619 special key names from section 17.4.2
620 <https://www.w3.org/TR/webdriver1/#keyboard-actions> of the
621 WebDriver recommendation can be used.
622
623 Example: press and release "a".
624
625 $al->key ("a");
626
627 Example: press and release the "Enter" key:
628
629 $al->key ("\x{e007}");
630
631 Example: press and release the "enter" key using the special key
632 name syntax:
633
634 $al->key ("{Enter}");
635
636 $al = $al->type ($string, $source)
637 Convenience method to simulate a series of key press and release
638 events for the keys in $string, one pair per extended unicode
639 grapheme cluster. There is no syntax for special keys, everything
640 will be typed "as-is" if possible.
641
642 $al->perform ($wd)
643 Finalises and compiles the list, if not done yet, and calls
644 "$wd->perform" with it.
645
646 If $wd is undef, and the action list was created using the
647 "$wd->actions" method, then perform it against that WebDriver
648 object.
649
650 There is no underscore variant - call the "perform_actions_" method
651 with the action object instead.
652
653 $al->perform_release ($wd)
654 Exactly like "perform", but additionally call "release_actions"
655 afterwards.
656
657 ($actions, $duration) = $al->compile
658 Finalises and compiles the list, if not done yet, and returns an
659 actions object suitable for calls to "$wd->perform_actions". When
660 called in list context, additionally returns the total duration of
661 the action list.
662
663 Since building large action lists can take nontrivial amounts of
664 time, it can make sense to build an action list only once and then
665 perform it multiple times.
666
667 No additional actions must be added after compiling an action list.
668
669 EVENT BASED API
670 This module wouldn't be a good AnyEvent citizen if it didn't have a true
671 event-based API.
672
673 In fact, the simplified API, as documented above, is emulated via the
674 event-based API and an "AUTOLOAD" function that automatically provides
675 blocking wrappers around the callback-based API.
676
677 Every method documented in the "SIMPLIFIED API" section has an
678 equivalent event-based method that is formed by appending a underscore
679 ("_") to the method name, and appending a callback to the argument list
680 (mnemonic: the underscore indicates the "the action is not yet finished"
681 after the call returns).
682
683 For example, instead of a blocking calls to "new_session", "navigate_to"
684 and "back", you can make a callback-based ones:
685
686 my $cv = AE::cv;
687
688 $wd->new_session ({}, sub {
689 my ($status, $value) = @_,
690
691 die "error $value->{error}" if $status ne "200";
692
693 $wd->navigate_to_ ("http://www.nethype.de", sub {
694
695 $wd->back_ (sub {
696 print "all done\n";
697 $cv->send;
698 });
699
700 });
701 });
702
703 $cv->recv;
704
705 While the blocking methods "croak" on errors, the callback-based ones
706 all pass two values to the callback, $status and $res, where $status is
707 the HTTP status code (200 for successful requests, typically 4xx or 5xx
708 for errors), and $res is the value of the "value" key in the JSON
709 response object.
710
711 Other than that, the underscore variants and the blocking variants are
712 identical.
713
714 LOW LEVEL API
715 All the simplified API methods are very thin wrappers around WebDriver
716 commands of the same name. They are all implemented in terms of the
717 low-level methods ("req", "get", "post" and "delete"), which exist in
718 blocking and callback-based variants ("req_", "get_", "post_" and
719 "delete_").
720
721 Examples are after the function descriptions.
722
723 $wd->req_ ($method, $uri, $body, $cb->($status, $value))
724 $value = $wd->req ($method, $uri, $body)
725 Appends the $uri to the "endpoint/session/{sessionid}/" URL and
726 makes a HTTP $method request ("GET", "POST" etc.). "POST" requests
727 can provide a UTF-8-encoded JSON text as HTTP request body, or the
728 empty string to indicate no body is used.
729
730 For the callback version, the callback gets passed the HTTP status
731 code (200 for every successful request), and the value of the
732 "value" key in the JSON response object as second argument.
733
734 $wd->get_ ($uri, $cb->($status, $value))
735 $value = $wd->get ($uri)
736 Simply a call to "req_" with $method set to "GET" and an empty body.
737
738 $wd->post_ ($uri, $data, $cb->($status, $value))
739 $value = $wd->post ($uri, $data)
740 Simply a call to "req_" with $method set to "POST" - if $body is
741 "undef", then an empty object is send, otherwise, $data must be a
742 valid request object, which gets encoded into JSON for you.
743
744 $wd->delete_ ($uri, $cb->($status, $value))
745 $value = $wd->delete ($uri)
746 Simply a call to "req_" with $method set to "DELETE" and an empty
747 body.
748
749 Example: implement "get_all_cookies", which is a simple "GET" request
750 without any parameters:
751
752 $cookies = $wd->get ("cookie");
753
754 Example: implement "execute_script", which needs some parameters:
755
756 $results = $wd->post ("execute/sync" => { script => "$javascript", args => [] });
757
758 Example: call "find_elements" to find all "IMG" elements:
759
760 $elems = $wd->post (elements => { using => "css selector", value => "img" });
761
762 HISTORY
763 This module was unintentionally created (it started inside some quickly
764 hacked-together script) simply because I couldn't get the existing
765 "Selenium::Remote::Driver" module to work reliably, ever, despite
766 multiple attempts over the years and trying to report multiple bugs,
767 which have been completely ignored. It's also not event-based, so,
768 yeah...
769
770 AUTHOR
771 Marc Lehmann <schmorp@schmorp.de>
772 http://anyevent.schmorp.de
773