Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(424)

Side by Side Diff: pkg/webdriver/webdriver.dart

Issue 10933051: WebDriver bindings. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/webdriver/test/webdrivertest.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #library('webdriver');
2 #import('dart:json');
3 #import('dart:uri');
4 #import('dart:io');
5 #import('dart:math');
6 #source('base64decoder.dart');
7
8 /**
9 * WebDriver bindings for Dart.
10 *
11 * These bindings are based on the WebDriver JSON wire protocol spec
12 * (http://code.google.com/p/selenium/wiki/JsonWireProtocol). Not
13 * all of these commands are implemented yet by WebDriver itself.
14 * Nontheless this is a complete implementation of the spec as the
15 * unsupported commands may be supported in the future. Currently,
16 * there are known issues with local and session storage, script
17 * execution, and log access.
18 *
19 * To use these bindings, the Selenium standalone server must be running.
20 * You can download it at http://code.google.com/p/selenium/downloads/list.
21 *
22 * There are a number of commands that use ids to access page elements.
23 * These ids are not the HTML ids; they are opaque ids internal to
24 * WebDriver. To get the id for an element yuou would first need to do
Emily Fortuna 2012/09/12 20:15:53 typo: you
gram 2012/09/12 22:42:09 Done.
25 * a search, get the results, and extract the WebDriver id from the returned
26 * [Map] using the 'ELEMENT' key. For example:
27 *
28 * String id;
29 * WebDriverSession session;
30 * Future f = web_driver.newSession('chrome');
31 * f.chain((_session) {
32 * session = _session;
33 * return session.setUrl('http://my.web.site.com');
34 * }).chain((_) {
35 * return session.findElement('id', 'username');
36 * }).chain((element) {
37 * id = element['ELEMENT'];
38 * return session.sendKeyStrokesToElement(id,
39 * [ 'j', 'o', 'e', ' ', 'u', 's', 'e', 'r' ]);
40 * }).chain((_) {
41 * return session.submit(id);
42 * }).chain((_) {
Emily Fortuna 2012/09/12 20:15:53 Can we have synchronous versions of these calls in
gram 2012/09/12 22:42:09 I don't believe so. The HTTP client APIs that Dart
Emily Fortuna 2012/09/13 00:03:14 I understand, but inside our implementation of set
43 * return session.close();
44 * }).then((_) {
45 * session = null;
46 * });
47 */
48
49 void writeStringToFile(String fileName, String contents) {
50 var file = new File(fileName);
51 var ostream = file.openOutputStream(FileMode.WRITE);
52 ostream.writeString(contents);
53 ostream.close();
54 }
55
56 void writeBytesToFile(String fileName, List<int> contents) {
57 var file = new File(fileName);
58 var ostream = file.openOutputStream(FileMode.WRITE);
59 ostream.write(contents);
60 ostream.close();
61 }
62
63 class WebDriverError {
64 int statusCode;
65 String type;
Emily Fortuna 2012/09/12 20:15:53 One of the biggest challenges with the current Web
gram 2012/09/12 22:42:09 I added an error details field which should help.
66 String message;
67 String results;
68
69 WebDriverError(this.statusCode, this.type, this.message,
70 [this.results = '']);
71
72 String toString() {
73 return '$statusCode $type: $message $results';
74 }
75
76 static WebDriverError makeException(statusCode, message, [results = '']) {
77 var type = null;
78 if (statusCode < 0 || statusCode > 32) {
79 type = 'External';
80 } else {
81 type = [
Emily Fortuna 2012/09/12 20:15:53 consider making this type array a static constant
gram 2012/09/12 22:42:09 As far as I can tell Dart can't do this (yet) with
82 null,
83 'IndexOutOfBounds',
84 'NoCollection',
85 'NoString',
86 'NoStringLength',
87 'NoStringWrapper',
88 'NoSuchDriver',
89 'NoSuchElement',
90 'NoSuchFrame',
91 'UnknownCommand',
92 'ObsoleteElement',
93 'ElementNotDisplayed',
94 'InvalidElementState',
95 'Unhandled',
96 'Expected',
97 'ElementNotSelectable',
98 'NoSuchDocument',
99 'UnexpectedJavascript',
100 'NoScriptResult',
101 'XPathLookup',
102 'NoSuchCollection',
103 'TimeOut',
104 'NullPointer',
105 'NoSuchWindow',
106 'InvalidCookieDomain',
107 'UnableToSetCookie',
108 'UnexpectedAlertOpen',
109 'NoAlertOpen',
110 'ScriptTimeout',
111 'InvalidElementCoordinates',
112 'IMENotAvailable',
113 'IMEEngineActivationFailed',
114 'InvalidSelector',
115 'SessionNotCreatedException',
116 'MoveTargetOutOfBounds'
117 ][statusCode];
118 }
119 return new WebDriverError(statusCode, type, message, results);
120 }
121 }
122
123 class WebDriverBase {
Emily Fortuna 2012/09/12 20:15:53 The Documentation Santa should visit here.
gram 2012/09/12 22:42:09 Done.
124
125 Map methods;
126 String _host;
127 int _port;
128 String _path;
129 String _url;
130
131 String get path => _path;
132 String get url => _url;
133
134 WebDriverBase.fromUrl([this._url = 'http://localhost:4444/wd/hub']) {
135 var re = const RegExp('[^:/]+://([^/]+)(/.*)');
136 var matches = re.firstMatch(_url);
137 _host = matches[1];
138 _path = matches[2];
139 var idx = _host.indexOf(':');
140 if (idx >= 0) {
141 _port = parseInt(_host.substring(idx+1));
142 _host = _host.substring(0, idx);
143 } else {
144 _port = 80;
145 }
146 }
147
148 WebDriverBase([
149 this._host = 'localhost',
150 this._port = 4444,
151 this._path = '/wd/hub']) {
152 _url = 'http://${_host}:${_port}${_path}';
Emily Fortuna 2012/09/12 20:15:53 nit, but I'm pretty sure this can just be written
gram 2012/09/12 22:42:09 I'll change it, although I find the use of {} make
Emily Fortuna 2012/09/13 00:03:14 Okay. Feel free to disregard that advice of mine
153 }
154
155 /**
156 * Request to webdriver server.
157 *
158 * http_method 'GET', 'POST', or 'DELETE'
159 * command If not defined in methods() this function will throw.
Emily Fortuna 2012/09/12 20:15:53 use markdown syntax to link to the parameters: [co
gram 2012/09/12 22:42:09 Done.
160 * params If an array(), they will be posted as JSON parameters
161 * If a number or string, "/params" is appended to url
162 */
163 void _serverRequest(String http_method, String command, Completer completer,
164 [List successCodes, Map params, Function customHandler]) {
165 var status = 0;
166 var results = null;
167 var message = null;
168 if (successCodes == null) {
169 successCodes = [ 200, 204 ];
Emily Fortuna 2012/09/12 20:15:53 can you move this up to the first line in the func
gram 2012/09/12 22:42:09 It would be nice, but the Dart parser barfs on tha
170 }
171 try {
172 if (params != null && params is List && http_method != 'POST') {
173 throw new Exception(
174 'The http method called for ${command} is ${http_method} but it has '
175 'to be POST if you want to pass the JSON params '
176 '${JSON.stringify(params)}');
177 }
178
179 var path = command;
180 if (params != null && (params is num || params is String)) {
181 path = '$path/$params';
182 }
183
184 var client = new HttpClient();
185 var connection = client.open(http_method, _host, _port, path);
186
187 connection.onRequest = (r) {
188 r.headers.add(HttpHeaders.ACCEPT, "application/json");
189 r.headers.add(
190 HttpHeaders.CONTENT_TYPE, 'application/json;charset=UTF-8');
191 OutputStream s = r.outputStream;
192 if (params != null && params is Map) {
193 s.writeString(JSON.stringify(params));
194 }
195 s.close();
196 };
197 connection.onError = (e) {
198 if (completer != null) {
199 completer.completeException(WebDriverError.makeException(-1, e));
200 completer = null;
201 }
202 };
203 connection.followRedirects = false;
204 connection.onResponse = (r) {
205 StringInputStream s = new StringInputStream(r.inputStream);
206 StringBuffer sbuf = new StringBuffer();
207 s.onData = () {
208 var data = s.read();
209 if (data != null) {
210 sbuf.add(data);
211 }
212 };
213 s.onClosed = () {
214 var value = null;
215 results = sbuf.toString().trim();
216 // For some reason we get a bunch of NULs on the end
217 // of the text and the JSON parser blows up on these, so
218 // strip them. We have to do this the hard way as
219 // replaceAll('\0', '') does not work.
220 // These NULs can be seen in the TCP packet, so it is not
221 // an issue with character encoding; it seems to be a bug
222 // in WebDriver stack.
223 for (var i = results.length; --i >= 0;) {
224 var code = results.charCodeAt(i);
225 if (code != 0) {
226 results = results.substring(0, i+1);
227 break;
228 }
229 }
230 if (successCodes.indexOf(r.statusCode) < 0) {
231 throw 'Unexpected response ${r.statusCode}';
232 }
233 if (status == 0 && results.length > 0) {
234 writeStringToFile('debug.txt', results); // TODO - remove
Emily Fortuna 2012/09/12 20:15:53 change to TODO(gram): Remove.
gram 2012/09/12 22:42:09 Done.
235 // 4xx responses send plain text; others send JSON.
236 if (r.statusCode < 400) {
237 results = JSON.parse(results);
238 status = results['status'];
239 }
240 if (results is Map && (results as Map).containsKey('value')) {
241 value = results['value'];
242 }
243 if (value is Map && value.containsKey('message')) {
244 message = value['message'];
245 }
246 }
247 if (status == 0) {
248 if (customHandler != null) {
249 customHandler(r, value);
250 } else if (completer != null) {
251 completer.complete(value);
252 }
253 }
254 };
255 };
256 } catch (e, s) {
257 completer.completeException(
258 WebDriverError.makeException(-1, e), s);
259 completer = null;
260 }
261 }
262
263 Future _simpleCommand(method, extraPath, [successCodes, params]) {
264 var completer = new Completer();
265 _serverRequest(method, '${_path}/$extraPath', completer,
266 successCodes, params: params);
267 return completer.future;
268 }
269
270 Future _get(extraPath, [successCodes]) =>
271 _simpleCommand('GET', extraPath, successCodes);
272
273 Future _post(extraPath, [successCodes, params]) =>
274 _simpleCommand('POST', extraPath, successCodes, params);
275
276 Future _delete(extraPath, [successCodes]) =>
277 _simpleCommand('DELETE', extraPath, successCodes);
278 }
279
280 class WebDriver extends WebDriverBase {
281
282 WebDriver(host, port, path) : super(host, port, path) {
283 methods = { 'status' : 'GET' };
284 }
285
286 /**
287 * Create a new session. The server will attempt to create a session that
288 * most closely matches the desired and required capabilities. Required
289 * capabilities have higher priority than desired capabilities and must be
290 * set for the session to be created.
291 *
292 * The capabilities are:
293 *
294 * - browserName (String) The name of the browser being used; should be one
295 * of {chrome|firefox|htmlunit|internet explorer|iphone}.
Emily Fortuna 2012/09/12 20:15:53 safari or opera?
gram 2012/09/12 22:42:09 I'm not sure. I am just quoting the WebDriver docs
296 * - version (String) The browser version, or the empty string if unknown.
297 * - platform (String) A key specifying which platform the browser is
298 * running on. This value should be one of {WINDOWS|XP|VISTA|MAC|LINUX|UNIX}
299 * When requesting a new session, the client may specify ANY to indicate
300 * any available platform may be used.
301 * - javascriptEnabled (bool) Whether the session supports executing user
302 * supplied JavaScript in the context of the current page.
303 * - takesScreenshot (bool) Whether the session supports taking screenshots
304 * of the current page.
305 * - handlesAlerts (bool) Whether the session can interact with modal popups,
306 * such as window.alert and window.confirm.
307 * - databaseEnabled (bool) Whether the session can interact database storage.
308 * - locationContextEnabled (bool) Whether the session can set and query the
309 * browser's location context.
310 * - applicationCacheEnabled (bool) Whether the session can interact with
311 * the application cache.
312 * - browserConnectionEnabled (bool) Whether the session can query for the
313 * browser's connectivity and disable it if desired.
314 * - cssSelectorsEnabled (bool) Whether the session supports CSS selectors
315 * when searching for elements.
316 * - webStorageEnabled (bool) Whether the session supports interactions with
317 * storage objects.
318 * - rotatable (bool) Whether the session can rotate the current page's
319 * current layout between portrait and landscape orientations (only applies
320 * to mobile platforms).
321 * - acceptSslCerts (bool) Whether the session should accept all SSL certs
322 * by default.
323 * - nativeEvents (bool) Whether the session is capable of generating native
324 * events when simulating user input.
325 * - proxy (proxy object) Details of any proxy to use. If no proxy is
326 * specified, whatever the system's current or default state is used. The
327 * format is:
328 *
329 * - proxyType (String) The type of proxy being used. Possible values are:
330 * direct - A direct connection - no proxy in use,
331 * manual - Manual proxy settings configured,
332 * pac - Proxy autoconfiguration from a URL),
333 * autodetect (proxy autodetection, probably with WPAD),
334 * system - Use system settings
335 * - proxyAutoconfigUrl (String) Required if proxyType == pac, Ignored
336 * otherwise. Specifies the URL to be used for proxy autoconfiguration.
337 * - ftpProxy, httpProxy, sslProxy (String) (Optional, Ignored if
338 * proxyType != manual) Specifies the proxies to be used for FTP, HTTP
339 * and HTTPS requests respectively. Behaviour is undefined if a request
340 * is made, where the proxy for the particular protocol is undefined,
341 * if proxyType is manual.
342 *
343 * Potential Errors:
344 * SessionNotCreatedException - If a required capability could not be set.
345 */
346 Future<WebDriverSession> newSession([
347 browser = 'chrome', Map additional_capabilities]) {
348 var completer = new Completer();
349 if (additional_capabilities == null) {
350 additional_capabilities = {};
351 }
352
353 additional_capabilities['browserName'] = browser;
354
355 _serverRequest('POST', '${_path}/session', null, [ 302 ],
356 customHandler: (r, v) {
357 var url = r.headers.value(HttpHeaders.LOCATION);
358 var session = new WebDriverSession.fromUrl(url);
359 completer.complete(session);
360 }, params: { 'desiredCapabilities': additional_capabilities });
361 return completer.future;
362 }
363
364 /** Get the set of currently active sessions. */
365 Future<List<WebDriverSession>> getSessions() {
366 var completer = new Completer();
367 _get('sessions', (result) {
368 var _sessions = [];
369 for (var session in result) {
370 _sessions.add(new WebDriverSession.fromUrl(
371 '${this._path}/session/${session["id"]}'));
372 }
373 completer.complete(_sessions);
374 });
375 return completer.future;
376 }
377
378 /** Query the server's current status. */
379 Future<Map> getStatus() => _get('status');
380 }
381
382 class WebDriverWindow extends WebDriverBase {
383 WebDriverWindow.fromUrl(url) : super.fromUrl(url);
384
385 /** Get the window size. */
386 Future<Map> getSize() => _get('size');
387
388 /**
389 * Set the window size.
390 *
391 * Potential Errors:
392 * NoSuchWindow - If the specified window cannot be found.
393 */
394 Future<String> setSize(int width, int height) =>
395 _post('size', params: { 'width': width, 'height': height });
396
397 /** Get the window position. */
398 Future<Map> getPosition() => _get('position');
399
400 /**
401 * Set the window position.
402 *
403 * Potential Errors:
404 * NoSuchWindow - If the specified window cannot be found.
405 */
406 Future setPosition(int x, int y) =>
407 _post('position', params: { 'x': x, 'y': y });
408
409 /** Maximize the specified window if not already maximized. */
410 Future maximize() => _post('maximize');
411 }
412
413 class WebDriverSession extends WebDriverBase {
414 WebDriverSession.fromUrl(url) : super.fromUrl(url);
415
416 /** Close the session. */
417 Future close() => _delete('');
418
419 /** Get the session capabilities. See [newSession] for details. */
420 Future<Map> getCapabilities() => _get('');
421
422 /**
423 * Configure the amount of time in milliseconds that a script can execute
424 * for before it is aborted and a Timeout error is returned to the client.
425 */
426 Future setScriptTimeout(t) =>
427 _post('timeouts', params: { 'type': 'script', 'ms': t });
428
429 /*Future<String> setImplicitWaitTimeout(t) =>
430 simplePost('timeouts', { 'type': 'implicit', 'ms': t });*/
431
432 /**
433 * Configure the amount of time in milliseconds that a page can load for
434 * before it is aborted and a Timeout error is returned to the client.
435 */
436 Future setPageLoadTimeout(t) =>
437 _post('timeouts', params: { 'type': 'page load', 'ms': t });
438
439 /**
440 * Set the amount of time, in milliseconds, that asynchronous scripts
441 * executed by /session/:sessionId/execute_async are permitted to run
442 * before they are aborted and a Timeout error is returned to the client.
443 */
444 Future setAsyncScriptTimeout(t) =>
445 _post('timeouts/async_script', params: { 'ms': t });
446
447 /**
448 * Set the amount of time the driver should wait when searching for elements.
449 * When searching for a single element, the driver should poll the page until
450 * an element is found or the timeout expires, whichever occurs first. When
451 * searching for multiple elements, the driver should poll the page until at
452 * least one element is found or the timeout expires, at which point it should
453 * return an empty list.
454 * If this command is never sent, the driver should default to an implicit
455 * wait of 0ms.
456 */
457 Future setImplicitWaitTimeout(t) =>
458 _post('timeouts/implicit_wait', params: { 'ms': t });
459
460 /**
461 * Retrieve the current window handle.
462 *
463 * Potential Errors:
464 * NoSuchWindow - If the currently selected window has been closed.
465 */
466 Future<String> getWindowHandle() => _get('window_handle');
467
468 /**
469 * Retrieve a [WebDriverWindow] for the specified window. We don't
470 * have to use a Future here but do so to be consistent.
471 */
472 Future<WebDriverWindow> getWindow([handle = 'current']) {
473 var completer = new Completer();
474 completer.complete(new WebDriverWindow.fromUrl('${_url}/window/$handle'));
475 return completer.future;
476 }
477
478 /** Retrieve the list of all window handles available to the session. */
479 Future<List<String>> getWindowHandles() => _get('window_handles');
480
481 /**
482 * Retrieve the URL of the current page.
483 *
484 * Potential Errors:
485 * NoSuchWindow - If the currently selected window has been closed.
486 */
487 Future<String> getUrl() => _get('url');
488
489 /**
490 * Navigate to a new URL.
491 *
492 * Potential Errors:
493 * NoSuchWindow - If the currently selected window has been closed.
494 */
495 Future setUrl(String url) => _post('url', params: { 'url': url });
496
497 /**
498 * Navigate forwards in the browser history, if possible.
499 *
500 * Potential Errors:
501 * NoSuchWindow - If the currently selected window has been closed.
502 */
503 Future navigateForward() => _post('forward');
504
505 /**
506 * Navigate backwards in the browser history, if possible.
507 *
508 * Potential Errors:
509 * NoSuchWindow - If the currently selected window has been closed.
510 */
511 Future navigateBack() => _post('back');
512
513 /**
514 * Refresh the current page.
515 *
516 * Potential Errors:
517 * NoSuchWindow - If the currently selected window has been closed.
518 */
519 Future refresh() => _post('refresh');
520
521 /**
522 * Inject a snippet of JavaScript into the page for execution in the context
523 * of the currently selected frame. The executed script is assumed to be
524 * synchronous and the result of evaluating the script is returned to the
525 * client.
526 * The script argument defines the script to execute in the form of a
527 * function body. The value returned by that function will be returned to
528 * the client. The function will be invoked with the provided args array
529 * and the values may be accessed via the arguments object in the order
530 * specified.
531 * Arguments may be any JSON-primitive, array, or JSON object. JSON objects
532 * that define a WebElement reference will be converted to the corresponding
533 * DOM element. Likewise, any WebElements in the script result will be
534 * returned to the client as WebElement JSON objects.
535 *
536 * Potential Errors:
537 * NoSuchWindow - If the currently selected window has been closed.
538 * StaleElementReference - If one of the script arguments is a WebElement
Emily Fortuna 2012/09/12 20:15:53 These comments have a very javadoc-y feel. I think
gram 2012/09/12 22:42:09 I've tried to reformat things in a way that will w
Emily Fortuna 2012/09/13 00:03:14 awesome!
539 * that is not attached to the page's DOM.
540 * JavaScriptError - If the script throws an Error.
541 */
542 Future execute(String script, [List args]) =>
543 _post('execute', params: { 'script': script, 'args': args });
544
545 /**
546 * Inject a snippet of JavaScript into the page for execution in the context
547 * of the currently selected frame. The executed script is assumed to be
548 * asynchronous and must signal that is done by invoking the provided
Emily Fortuna 2012/09/12 20:15:53 missing word "that it is"
gram 2012/09/12 22:42:09 Done.
549 * callback, which is always provided as the final argument to the function.
550 * The value to this callback will be returned to the client.
551 * Asynchronous script commands may not span page loads. If an unload event
552 * is fired while waiting for a script result, an error should be returned
553 * to the client.
554 * The script argument defines the script to execute in teh form of a function
555 * body. The function will be invoked with the provided args array and the
556 * values may be accessed via the arguments object in the order specified.
557 * The final argument will always be a callback function that must be invoked
558 * to signal that the script has finished.
559 * Arguments may be any JSON-primitive, array, or JSON object. JSON objects
560 * that define a WebElement reference will be converted to the corresponding
561 * DOM element. Likewise, any WebElements in the script result will be
562 * returned to the client as WebElement JSON objects.
563 *
564 * Potential Errors:
565 * NoSuchWindow - If the currently selected window has been closed.
566 * StaleElementReference - If one of the script arguments is a WebElement
567 * that is not attached to the page's DOM.
568 * Timeout - If the script callback is not invoked before the timout expires.
569 * Timeouts are controlled by the [setAsyncScriptTimeout] command.
570 * JavaScriptError - If the script throws an Error or if an unload event is
571 * fired while waiting for the script to finish.
572 */
573 Future executeAsync(String script, [List args]) =>
574 _post('execute_async', params: { 'script': script, 'args': args });
575
576 /**
577 * Take a screenshot of the current page (PNG).
578 *
579 * Potential Errors:
580 * NoSuchWindow - If the currently selected window has been closed.
581 */
582 Future<List<int>> getScreenshot([fname]) {
583 var completer = new Completer();
584 var result = _serverRequest('GET', '$_path/screenshot', completer,
585 customHandler: (r, v) {
586 var image = Base64Decoder.decode(v);
587 if (fname != null) {
588 writeBytesToFile(fname, image);
589 }
590 completer.complete(image);
591 });
592 return completer.future;
593 }
594
595 /**
596 * List all available engines on the machine. To use an engine, it has to
597 * be present in this list.
598 *
599 * Potential Errors:
600 * ImeNotAvailableException - If the host does not support IME.
601 */
Emily Fortuna 2012/09/12 20:15:53 noob question: can we spell out the acronym for IM
gram 2012/09/12 22:42:09 Done.
602 Future<List<String>> getAvailableImeEngines() =>
603 _get('ime/available_engines');
604
605 /**
606 * Get the name of the active IME engine. The name string is
607 * platform specific.
608 *
609 * Potential Errors:
610 * ImeNotAvailableException - If the host does not support IME.
611 */
612 Future<String> getActiveImeEngine() => _get('ime/active_engine');
613
614 /**
615 * Indicates whether IME input is active at the moment (not if
616 * it's available).
617 *
618 * Potential Errors:
619 * ImeNotAvailableException - If the host does not support IME.
620 */
621 Future<bool> getIsImeActive() => _get('ime/activated');
622
623 /**
624 * De-activates the currently-active IME engine.
625 *
626 * Potential Errors:
627 * ImeNotAvailableException - If the host does not support IME.
628 */
629 Future deactivateIme() => _post('ime/deactivate');
630
631 /**
632 * Make an engine that is available (appears on the list returned by
633 * getAvailableEngines) active. After this call, the engine will be added
634 * to the list of engines loaded in the IME daemon and the input sent using
635 * sendKeys will be converted by the active engine. Note that this is a
636 * platform-independent method of activating IME (the platform-specific way
637 * being using keyboard shortcuts).
638 *
639 * Potential Errors:
640 * ImeActivationFailedException - If the engine is not available or
641 * if the activation fails for other reasons.
642 * ImeNotAvailableException - If the host does not support IME.
643 */
644 Future activateIme(String engine) =>
645 _post('ime/activate', params: { 'engine': engine });
646
647 /**
648 * Change focus to another frame on the page. If the frame id is null,
649 * the server should switch to the page's default content.
650 * [id] is the Identifier for the frame to change focus to, and can be
651 * a string, number, null, or JSON Object.
652 *
653 * Potential Errors:
654 * NoSuchWindow - If the currently selected window has been closed.
655 * NoSuchFrame - If the frame specified by id cannot be found.
656 */
657 Future setFrameFocus(id) => _post('frame', params: { 'id': id });
658
659 /**
660 * Change focus to another window. The window to change focus to may be
661 * specified by [name], which is its server assigned window handle, or
662 * the value of its name attribute.
663 *
664 * Potential Errors:
665 * NoSuchWindow - If the window specified by name cannot be found.
666 */
667 Future setWindowFocus(name) =>
668 _post('window', params: { 'name': name });
669
670 /**
671 * Close the current window.
672 *
673 * Potential Errors:
674 * NoSuchWindow - If the currently selected window is already closed
675 */
676 Future closeWindow() => _delete('window');
677
678 /**
679 * Retrieve all cookies visible to the current page.
680 *
681 * The returned List contains Maps with the following keys:
682 *
683 * 'name' (String) The name of the cookie.
684 * 'value' (String The cookie value.
685 *
686 * The following keys may optionally be present:
687 *
688 * 'path' (String) The cookie path.
689 * 'domain' (String) The domain the cookie is visible to.
690 * 'secure' (bool) Whether the cookie is a secure cookie.
691 * 'expiry' (int) When the cookie expires, specified in seconds
692 * since midnight, January 1, 1970 UTC.
693 *
694 * Potential Errors:
695 * NoSuchWindow - If the currently selected window has been closed.
696 */
697 Future<List<Map>> getCookies() => _get('cookie');
698
699 /**
700 * Set a cookie. If the cookie path is not specified, it should be set
701 * to "/". Likewise, if the domain is omitted, it should default to the
702 * current page's domain. See [getCookies] for the structure of a cookie
703 * Map.
704 */
705 Future setCookie(Map cookie) =>
706 _post('cookie', params: { 'cookie': cookie });
707
708 /**
709 * Delete all cookies visible to the current page.
710 *
711 * Potential Errors:
712 * InvalidCookieDomain - If the cookie's domain is not visible from the
713 * current page.
714 * NoSuchWindow - If the currently selected window has been closed.
715 * UnableToSetCookie - If attempting to set a cookie on a page that does
716 * not support cookies (e.g. pages with mime-type text/plain).
717 */
718 Future deleteCookies() => _delete('cookie');
719
720 /**
721 * Delete the cookie with the given [name]. This command should be a no-op
722 * if there is no such cookie visible to the current page.
723 *
724 * Potential Errors:
725 * NoSuchWindow - If the currently selected window has been closed.
726 */
727 Future deleteCookie(String name) => _delete('cookie/$name');
728
729 /**
730 * Get the current page source.
731 *
732 * Potential Errors:
733 * NoSuchWindow - If the currently selected window has been closed.
734 */
735 Future<String> getPageSource() => _get('source');
736
737 /**
738 * Get the current page title.
739 *
740 * Potential Errors:
741 * NoSuchWindow - If the currently selected window has been closed.
742 */
743 Future<String> getPageTitle() => _get('title');
744
745 /**
746 * Search for an element on the page, starting from the document root. The
747 * first matching located element will be returned as a WebElement JSON
748 * object (a [Map] with an 'ELEMENT' key whose value should be used to
749 * identify the element in further requests). The table below lists the
750 * locator strategies that each server supports.
Emily Fortuna 2012/09/12 20:15:53 "The table below lists possible values for [strate
gram 2012/09/12 22:42:09 Done.
751 *
752 * 'class name' Returns an element whose class name contains the search
753 * value; compound class names are not permitted.
754 * 'css selector' Returns an element matching a CSS selector.
755 * 'id' Returns an element whose ID attribute matches the
756 * search value.
757 * 'name' Returns an element whose NAME attribute matches the
758 * search value.
759 * 'link text' Returns an anchor element whose visible text matches the
760 * search value.
761 * 'partial link text' Returns an anchor element whose visible text
762 * partially matches the search value.
763 * 'tag name' Returns an element whose tag name matches the search value.
764 * 'xpath' Returns an element matching an XPath expression.
765 *
766 * Potential Errors:
767 * NoSuchWindow - If the currently selected window has been closed.
768 * NoSuchElement - If the element cannot be found.
769 * XPathLookupError - If using XPath and the input expression is invalid.
770 */
771 Future<String> findElement(String strategy, String searchValue) =>
772 _post('element', params: { 'using': strategy, 'value' : searchValue });
773
774 /**
775 * Search for multiple elements on the page, starting from the document root.
776 * The located elements will be returned as WebElement JSON objects. See
777 * [findElement] for the locator strategies that each server supports.
778 * Elements are be returned in the order located in the DOM.
779 *
780 * Potential Errors:
781 * NoSuchWindow - If the currently selected window has been closed.
782 * XPathLookupError - If using XPath and the input expression is invalid.
783 */
784 Future<List<String>> findElements(String strategy, String searchValue) =>
785 _post('elements', params: { 'using': strategy, 'value' : searchValue });
786
787 /**
788 * Get the element on the page that currently has focus. The element will
789 * be returned as a WebElement JSON object.
790 *
791 * Potential Errors:
792 * NoSuchWindow - If the currently selected window has been closed.
793 */
794 Future<String> getElementWithFocus() => _post('element/active');
795
796 /**
797 * Search for an element on the page, starting from element with id [id].
798 * The located element will be returned as WebElement JSON objects. See
799 * [findElement] for the locator strategies that each server supports.
800 *
801 * Potential Errors:
802 * NoSuchWindow - If the currently selected window has been closed.
803 * XPathLookupError - If using XPath and the input expression is invalid.
804 */
805 Future<String>
806 findElementFromId(String id, String strategy, String searchValue) =>
Emily Fortuna 2012/09/12 20:15:53 this has crossed the => limit. I'd make it a funct
gram 2012/09/12 22:42:09 Done.
807 _post('element/$id/element',
808 params: { 'using': strategy, 'value' : searchValue });
809
810 /**
811 * Search for multiple elements on the page, starting from the element with
812 * id [id].The located elements will be returned as WebElement JSON objects.
813 * See [findElement] for the locator strategies that each server supports.
814 * Elements are be returned in the order located in the DOM.
815 *
816 * Potential Errors:
817 * NoSuchWindow - If the currently selected window has been closed.
818 * XPathLookupError - If using XPath and the input expression is invalid.
819 */
820 Future<List<String>>
821 findElementsFromId(String id, String strategy, String searchValue) =>
822 _post('element/$id/elements',
823 params: { 'using': strategy, 'value' : searchValue });
824
825 /**
826 * Click on an element.
Emily Fortuna 2012/09/12 20:15:53 "Click on an element that has the specified [id] n
gram 2012/09/12 22:42:09 Done.
827 *
828 * Potential Errors:
829 * NoSuchWindow - If the currently selected window has been closed.
830 * StaleElementReference - If the element referenced by [id] is no longer
831 * attached to the page's DOM.
832 * ElementNotVisible - If the referenced element is not visible on the page
833 * (either is hidden by CSS, has 0-width, or has 0-height)
834 */
835 Future clickElement(String id) => _post('element/$id/click');
836
837 /**
838 * Submit a FORM element. The submit command may also be applied to any
839 * element that is a descendant of a FORM element.
840 *
841 * Potential Errors:
842 * NoSuchWindow - If the currently selected window has been closed.
843 * StaleElementReference - If the element referenced by [id] is no longer
844 * attached to the page's DOM.
845 */
846 Future submit(String id) => _post('element/$id/submit');
847
848 /** Returns the visible text for the element.
849 *
850 * Potential Errors:
851 * NoSuchWindow - If the currently selected window has been closed.
852 * StaleElementReference - If the element referenced by [id] is no
853 * longer attached to the page's DOM.
854 */
855 Future<String> getElementText(String id) => _get('element/$id/text');
856
857 /**
858 * Send a sequence of key strokes to an element.
859 * Any UTF-8 character may be specified, however, if the server does not
860 * support native key events, it will simulate key strokes for a standard
861 * US keyboard layout. The Unicode Private Use Area code points,
862 * 0xE000-0xF8FF, are used to represent pressable, non-text keys:
863 *
864 * NULL U+E000
865 * Cancel U+E001
866 * Help U+E002
867 * Back space U+E003
868 * Tab U+E004
869 * Clear U+E005
870 * Return1 U+E006
871 * Enter1 U+E007
872 * Shift U+E008
873 * Control U+E009
874 * Alt U+E00A
875 * Pause U+E00B
876 * Escape U+E00C
877 * Space U+E00D
878 * Pageup U+E00E
879 * Pagedown U+E00F
880 * End U+E010
881 * Home U+E011
882 * Left arrow U+E012
883 * Up arrow U+E013
884 * Right arrow U+E014
885 * Down arrow U+E015
886 * Insert U+E016
887 * Delete U+E017
888 * Semicolon U+E018
889 * Equals U+E019
890 * Numpad 0 U+E01A
891 * Numpad 1 U+E01B
892 * Numpad 2 U+E01C
893 * Numpad 3 U+E01D
894 * Numpad 4 U+E01E
895 * Numpad 5 U+E01F
896 * Numpad 6 U+E020
897 * Numpad 7 U+E021
898 * Numpad 8 U+E022
899 * Numpad 9 U+E023
900 * Multiply U+E024
901 * Add U+E025
902 * Separator U+E026
903 * Subtract U+E027
904 * Decimal U+E028
905 * Divide U+E029
906 * F1 U+E031
907 * F2 U+E032
908 * F3 U+E033
909 * F4 U+E034
910 * F5 U+E035
911 * F6 U+E036
912 * F7 U+E037
913 * F8 U+E038
914 * F9 U+E039
915 * F10 U+E03A
916 * F11 U+E03B
917 * F12 U+E03C
918 * Command/Meta U+E03D
919 *
920 * The server processes the key sequence as follows:
921 *
922 * - Each key that appears on the keyboard without requiring modifiers is
923 * sent as a keydown followed by a key up.
924 * - If the server does not support native events and must simulate key
925 * strokes with JavaScript, it will generate keydown, keypress, and keyup
926 * events, in that order. The keypress event is only fired when the
927 * corresponding key is for a printable character.
928 * - If a key requires a modifier key (e.g. "!" on a standard US keyboard),
929 * the sequence is: modifier down, key down, key up, modifier up, where
930 * key is the ideal unmodified key value (using the previous example,
931 * a "1").
932 * - Modifier keys (Ctrl, Shift, Alt, and Command/Meta) are assumed to be
933 * "sticky"; each modifier is held down (e.g. only a keydown event) until
934 * either the modifier is encountered again in the sequence, or the NULL
935 * (U+E000) key is encountered.
936 * - Each key sequence is terminated with an implicit NULL key.
937 * Subsequently, all depressed modifier keys are released (with
938 * corresponding keyup events) at the end of the sequence.
939 *
940 * Potential Errors:
941 * NoSuchWindow - If the currently selected window has been closed.
942 * StaleElementReference - If the element referenced by [id] is no longer
943 * attached to the page's DOM.
944 * ElementNotVisible - If the referenced element is not visible on the page
945 * (either is hidden by CSS, has 0-width, or has 0-height).
946 */
947 Future sendKeyStrokesToElement(String id, List<String> keys) =>
948 _post('element/$id/value', params: { 'value': keys });
949
950 /**
951 * Send a sequence of key strokes to the active element. This command is
952 * similar to [sendKeyStrokesToElement] command in every aspect except the
953 * implicit termination: The modifiers are not released at the end of the
954 * call. Rather, the state of the modifier keys is kept between calls,
955 * so mouse interactions can be performed while modifier keys are depressed.
956 *
957 * Potential Errors:
958 * NoSuchWindow - If the currently selected window has been closed.
959 */
960 Future sendKeyStrokes(List<String> keys) =>
961 _post('keys', params: { 'value': keys });
962
963 /**
964 * Query for an element's tag name, as a lower-case string.
965 *
966 * Potential Errors:
967 * NoSuchWindow - If the currently selected window has been closed.
968 * StaleElementReference - If the element referenced by [id] is no longer
969 * attached to the page's DOM.
970 */
971 Future<String> getElementTagName(String id) => _get('element/$id/name');
972
973 /**
974 * Clear a TEXTAREA or text INPUT element's value.
975 *
976 * Potential Errors:
977 * NoSuchWindow - If the currently selected window has been closed.
978 * StaleElementReference - If the element referenced by [id] is no longer
979 * attached to the page's DOM.
980 * ElementNotVisible - If the referenced element is not visible on the page
981 * (either is hidden by CSS, has 0-width, or has 0-height)
982 * InvalidElementState - If the referenced element is disabled.
983 */
984 Future clearValue(String id) => _post('/element/$id/clear');
985
986 /**
987 * Determine if an OPTION element, or an INPUT element of type checkbox
988 * or radiobutton is currently selected.
989 *
990 * Potential Errors:
991 * NoSuchWindow - If the currently selected window has been closed.
992 * StaleElementReference - If the element referenced by [id] is no longer
993 * attached to the page's DOM.
994 */
995 Future<bool> isSelected(String id) => _get('element/$id/selected');
996
997 /**
998 * Determine if an element is currently enabled.
999 *
1000 * Potential Errors:
1001 * NoSuchWindow - If the currently selected window has been closed.
1002 * StaleElementReference - If the element referenced by [id] is no longer
1003 * attached to the page's DOM.
1004 */
1005 Future<bool> isEnabled(String id) => _get('element/$id/enabled');
1006
1007 /**
1008 * Get the value of an element's attribute, or null if it has no such
1009 * attribute.
1010 *
1011 * Potential Errors:
1012 * NoSuchWindow - If the currently selected window has been closed.
1013 * StaleElementReference - If the element referenced by [id] is no longer
1014 * attached to the page's DOM.
1015 */
1016 Future<String> getAttribute(String id, String attribute) =>
1017 _get('element/$id/attribute/$attribute');
1018
1019 /**
1020 * Test if two element IDs refer to the same DOM element.
1021 *
1022 * Potential Errors:
1023 * NoSuchWindow - If the currently selected window has been closed.
1024 * StaleElementReference - If either the element refered to by [id] or
1025 * [other] is no longer attached to the page's DOM.
1026 */
1027 Future<bool> areSameElement(String id, String other) =>
1028 _get('element/$id/equals/$other');
1029
1030 /**
1031 * Determine if an element is currently displayed.
1032 *
1033 * Potential Errors:
1034 * NoSuchWindow - If the currently selected window has been closed.
1035 * StaleElementReference - If the element referenced by [id] is no longer
1036 * attached to the page's DOM.
1037 */
1038 Future<bool> isDiplayed(String id) => _get('element/$id/displayed');
1039
1040 /**
1041 * Determine an element's location on the page. The point (0, 0) refers to
1042 * the upper-left corner of the page. The element's coordinates are returned
1043 * as a [Map] object with x and y properties.
1044 *
1045 * Potential Errors:
1046 * NoSuchWindow - If the currently selected window has been closed.
1047 * StaleElementReference - If the element referenced by [id] is no longer
1048 * attached to the page's DOM.
1049 */
1050 Future<Map> getElementLocation(String id) => _get('element/$id/location');
1051
1052 /**
1053 * Determine an element's size in pixels. The size will be returned as a
1054 * [Map] object with width and height properties.
1055 *
1056 * Potential Errors:
1057 * NoSuchWindow - If the currently selected window has been closed.
1058 * StaleElementReference - If the element referenced by [id] is no longer
1059 * attached to the page's DOM.
1060 */
1061 Future<Map> getElementSize(String id) => _get('element/$id/size');
1062
1063 /**
1064 * Query the value of an element's computed CSS property. The CSS property
1065 * to query should be specified using the CSS property name, not the
1066 * JavaScript property name (e.g. background-color instead of
1067 * backgroundColor).
1068 *
1069 * Potential Errors:
1070 * NoSuchWindow - If the currently selected window has been closed.
1071 * StaleElementReference - If the element referenced by [id] is no longer
1072 * attached to the page's DOM.
1073 */
1074 Future<String> getElementCssProperty(String id, String property) =>
1075 _get('element/$id/css/$property');
1076
1077 /**
1078 * Get the current browser orientation ('LANDSCAPE' or 'PORTRAIT').
1079 *
1080 * Potential Errors:
1081 * NoSuchWindow - If the currently selected window has been closed.
1082 */
1083 Future<String> getBrowserOrientation() => _get('orientation');
1084
1085 /**
1086 * Gets the text of the currently displayed JavaScript alert(), confirm(),
1087 * or prompt() dialog.
1088 *
1089 * Potential Errors:
1090 * NoAlertPresent - If there is no alert displayed.
1091 */
1092 Future<String> getAlertText() => _get('alert_text');
1093
1094 /**
1095 * Sends keystrokes to a JavaScript prompt() dialog.
1096 *
1097 * Potential Errors:
1098 * NoAlertPresent - If there is no alert displayed.
1099 */
1100 Future sendKeyStrokesToPrompt(String text) =>
1101 _post('alert_text', params: { 'text': text });
1102
1103 /**
1104 * Accepts the currently displayed alert dialog. Usually, this is equivalent
1105 * to clicking on the 'OK' button in the dialog.
1106 *
1107 * Potential Errors:
1108 * NoAlertPresent - If there is no alert displayed.
1109 */
1110 Future acceptAlert() => _post('accept_alert');
1111
1112 /**
1113 * Dismisses the currently displayed alert dialog. For confirm() and prompt()
1114 * dialogs, this is equivalent to clicking the 'Cancel' button. For alert()
1115 * dialogs, this is equivalent to clicking the 'OK' button.
1116 *
1117 * Potential Errors:
1118 * NoAlertPresent - If there is no alert displayed.
1119 */
1120 Future dismissAlert() => _post('dismiss_alert');
1121
1122 /**
1123 * Move the mouse by an offset of the specificed element. If no element is
1124 * specified, the move is relative to the current mouse cursor. If an
1125 * element is provided but no offset, the mouse will be moved to the center
1126 * of the element. If the element is not visible, it will be scrolled
1127 * into view.
1128 */
1129 Future moveTo(String id, int x, int y) =>
1130 _post('moveto', params: { 'element': id, 'xoffset': x, 'yoffset' : y});
1131
1132 /**
1133 * Click a mouse button (at the coordinates set by the last [moveTo] command).
1134 * Note that calling this command after calling [buttonDown] and before
1135 * calling [buttonUp] (or any out-of-order interactions sequence) will yield
1136 * undefined behaviour).
1137 *
1138 * [button] should be 0 for left, 1 for middle, or 2 for right.
1139 */
1140 Future clickMouse([button = 0]) =>
1141 _post('click', params: { 'button' : button });
1142
1143 /**
1144 * Click and hold the left mouse button (at the coordinates set by the last
1145 * [moveTo] command). Note that the next mouse-related command that should
1146 * follow is [buttonDown]. Any other mouse command (such as [click] or
1147 * another call to [buttonDown]) will yield undefined behaviour.
1148 *
1149 * [button] should be 0 for left, 1 for middle, or 2 for right.
1150 */
1151 Future buttonDown([button = 0]) =>
1152 _post('click', params: { 'button' : button });
1153
1154 /**
1155 * Releases the mouse button previously held (where the mouse is currently
1156 * at). Must be called once for every [buttonDown] command issued. See the
1157 * note in [click] and [buttonDown] about implications of out-of-order
1158 * commands.
1159 *
1160 * [button] should be 0 for left, 1 for middle, or 2 for right.
1161 */
1162 Future buttonUp([button = 0]) =>
1163 _post('click', params: { 'button' : button });
1164
1165 /** Double-clicks at the current mouse coordinates (set by [moveTo]). */
1166 Future doubleClick() => _post('doubleclick');
1167
1168 /** Single tap on the touch enabled device on the element with id [id]. */
1169 Future touchClick(String id) =>
1170 _post('touch/click', params: { 'element': id });
1171
1172 /** Finger down on the screen. */
1173 Future touchDown(int x, int y) =>
1174 _post('touch/down', params: { 'x': x, 'y': y });
1175
1176 /** Finger up on the screen. */
1177 Future touchUp(int x, int y) =>
1178 _post('touch/up', params: { 'x': x, 'y': y });
1179
1180 /** Finger move on the screen. */
1181 Future touchMove(int x, int y) =>
1182 _post('touch/move', params: { 'x': x, 'y': y });
1183
1184 /**
1185 * Scroll on the touch screen using finger based motion events. If [id] is
1186 * specified, scrolling will start at a particular screen location.
1187 */
1188 Future touchScroll(int xOffset, int yOffset, [String id = null]) {
1189 if (id == null) {
1190 return _post('touch/scroll',
1191 params: { 'xoffset': xOffset, 'yoffset': yOffset });
1192 } else {
1193 return _post('touch/scroll',
1194 params: { 'element': id, 'xoffset': xOffset, 'yoffset': yOffset });
1195 }
1196 }
1197
1198 /** Double tap on the touch screen using finger motion events. */
1199 Future touchDoubleClick(String id) =>
1200 _post('touch/doubleclick', params: { 'element': id });
1201
1202 /** Long press on the touch screen using finger motion events. */
1203 Future touchLongClick(String id) =>
1204 _post('touch/longclick', params: { 'element': id });
1205
1206 /**
1207 * Flick on the touch screen using finger based motion events, starting
1208 * at a particular screen location. [speed] is in pixels-per-second.
1209 */
1210 Future touchFlickFrom(String id, int xOffset, int yOffset, int speed) =>
1211 _post('touch/flick',
1212 params: { 'element': id, 'xoffset': xOffset, 'yoffset': yOffset,
1213 'speed': speed });
1214
1215 /**
1216 * Flick on the touch screen using finger based motion events. Use this
1217 * instead of [touchFlickFrom] if you don'tr care where the flick starts.
1218 */
1219 Future touchFlick(int xSpeed, int ySpeed) =>
1220 _post('touch/flick', params: { 'xSpeed': xSpeed, 'ySpeed': ySpeed });
1221
1222 /**
1223 * Get the current geo location. Returns a [Map] with latitude,
1224 * longitude and altitude properties.
1225 */
1226 Future<Map> getGeolocation() => _get('location');
1227
1228 /** Set the current geo location. */
1229 Future setLocation(double latitude, double longitude, double altitude) =>
1230 _post('location', params:
1231 { 'latitude': latitude,
1232 'longitude': longitude,
1233 'altitude': altitude });
1234
1235 /**
1236 * Get all keys of the local storage. Completes with [null] if there
1237 * are no keys or the keys could not be retrieved.
1238 *
1239 * Potential Errors:
1240 * NoSuchWindow - If the currently selected window has been closed.
1241 */
1242 Future<List<String>> getLocalStorageKeys() => _get('local_storage');
1243
1244 /**
1245 * Set the local storage item for the given key.
1246 *
1247 * Potential Errors:
1248 * NoSuchWindow - If the currently selected window has been closed.
1249 */
1250 Future setLocalStorageItem(String key, String value) =>
1251 _post('local_storage', params: { 'key': key, 'value': value });
1252
1253 /**
1254 * Clear the local storage.
1255 *
1256 * Potential Errors:
1257 * NoSuchWindow - If the currently selected window has been closed.
1258 */
1259 Future clearLocalStorage() => _delete('local_storage');
1260
1261 /**
1262 * Get the local storage item for the given key.
1263 *
1264 * Potential Errors:
1265 * NoSuchWindow - If the currently selected window has been closed.
1266 */
1267 Future<String> getLocalStorageValue(String key) =>
1268 _get('local_storage/key/$key');
1269
1270 /**
1271 * Delete the local storage item for the given key.
1272 *
1273 * Potential Errors:
1274 * NoSuchWindow - If the currently selected window has been closed.
1275 */
1276 Future deleteLocalStorageValue(String key) =>
1277 _delete('local_storage/key/$key');
1278
1279 /**
1280 * Get the number of items in the local storage.
1281 *
1282 * Potential Errors:
1283 * NoSuchWindow - If the currently selected window has been closed.
1284 */
1285 Future<int> getLocalStorageCount() => _get('local_storage/size');
1286
1287 /**
1288 * Get all keys of the session storage.
1289 *
1290 * Potential Errors:
1291 * NoSuchWindow - If the currently selected window has been closed.
1292 */
1293 Future<List<String>> getSessionStorageKeys() => _get('session_storage');
1294
1295 /**
1296 * Set the sessionstorage item for the given key.
1297 *
1298 * Potential Errors:
1299 * NoSuchWindow - If the currently selected window has been closed.
1300 */
1301 Future setSessionStorageItem(String key, String value) =>
1302 _post('session_storage', params: { 'key': key, 'value': value });
1303
1304 /**
1305 * Clear the session storage.
1306 *
1307 * Potential Errors:
1308 * NoSuchWindow - If the currently selected window has been closed.
1309 */
1310 Future clearSessionStorage() => _delete('session_storage');
1311
1312 /**
1313 * Get the session storage item for the given key.
1314 *
1315 * Potential Errors:
1316 * NoSuchWindow - If the currently selected window has been closed.
1317 */
1318 Future<String> getSessionStorageValue(String key) =>
1319 _get('session_storage/key/$key');
1320
1321 /**
1322 * Delete the session storage item for the given key.
1323 *
1324 * Potential Errors:
1325 * NoSuchWindow - If the currently selected window has been closed.
1326 */
1327 Future deleteSessionStorageValue(String key) =>
1328 _delete('session_storage/key/$key');
1329
1330 /**
1331 * Get the number of items in the session storage.
1332 *
1333 * Potential Errors:
1334 * NoSuchWindow - If the currently selected window has been closed.
1335 */
1336 Future<String> getSessionStorageCount() => _get('session_storage/size');
1337
1338 /** Get available log types ('client', 'driver', 'browser', 'server'). */
1339 Future<List<String>> getLogTypes() => _get('log/types');
1340
1341 /**
1342 * Get the log for a given log type. Log buffer is reset after each request.
1343 * Each log entry is a [Map] with these fields:
1344 *
1345 * 'timestamp' (int) - The timestamp of the entry.
1346 * 'level' (String) - The log level of the entry, for example, "INFO".
1347 * 'message' (String) - The log message.
1348 */
1349 Future<List<Map>> getLogs(String type) =>
1350 _post('log', params: { 'type': type });
1351 }
1352
1353
Emily Fortuna 2012/09/12 20:15:53 delete extra lines down here
OLDNEW
« no previous file with comments | « pkg/webdriver/test/webdrivertest.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698