ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-WebDriver/README
Revision: 1.6
Committed: Fri Aug 31 02:44:31 2018 UTC (5 years, 9 months ago) by root
Branch: MAIN
CVS Tags: rel-0_9
Changes since 1.5: +44 -18 lines
Log Message:
0.9

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