ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-WebDriver/README
Revision: 1.7
Committed: Tue Sep 4 01:21:21 2018 UTC (5 years, 10 months ago) by root
Branch: MAIN
CVS Tags: rel-0_91
Changes since 1.6: +48 -32 lines
Log Message:
0.91

File Contents

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