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

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

Issue 12413012: Bring webdriver up to date with SDK changes, and a bit of refactoring. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 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
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library webdriver; 5 library webdriver;
6 6
7 import 'dart:json' as json; 7 import 'dart:json' as json;
8 import 'dart:uri'; 8 import 'dart:uri';
9 import 'dart:io'; 9 import 'dart:io';
10 import 'dart:async';
10 11
11 part 'src/base64decoder.dart'; 12 part 'src/base64decoder.dart';
12 13
13 /** 14 /**
14 * WebDriver bindings for Dart. 15 * WebDriver bindings for Dart.
15 * 16 *
16 * These bindings are based on the WebDriver JSON wire protocol spec 17 * These bindings are based on the WebDriver JSON wire protocol spec
17 * (http://code.google.com/p/selenium/wiki/JsonWireProtocol). Not 18 * (http://code.google.com/p/selenium/wiki/JsonWireProtocol). Not
18 * all of these commands are implemented yet by WebDriver itself. 19 * all of these commands are implemented yet by WebDriver itself.
19 * Nontheless this is a complete implementation of the spec as the 20 * Nontheless this is a complete implementation of the spec as the
20 * unsupported commands may be supported in the future. Currently, 21 * unsupported commands may be supported in the future. Currently,
21 * there are known issues with local and session storage, script 22 * there are known issues with local and session storage, script
22 * execution, and log access. 23 * execution, and log access.
23 * 24 *
24 * To use these bindings, the Selenium standalone server must be running. 25 * To use these bindings, the Selenium standalone server must be running.
25 * You can download it at http://code.google.com/p/selenium/downloads/list. 26 * You can download it at http://code.google.com/p/selenium/downloads/list.
26 * 27 *
27 * There are a number of commands that use ids to access page elements. 28 * There are a number of commands that use ids to access page elements.
28 * These ids are not the HTML ids; they are opaque ids internal to 29 * These ids are not the HTML ids; they are opaque ids internal to
29 * WebDriver. To get the id for an element you would first need to do 30 * WebDriver. To get the id for an element you would first need to do
30 * a search, get the results, and extract the WebDriver id from the returned 31 * a search, get the results, and extract the WebDriver id from the returned
31 * [Map] using the 'ELEMENT' key. For example: 32 * [Map] using the 'ELEMENT' key. For example:
32 * 33 *
33 * String id; 34 * String id;
34 * WebDriverSession session; 35 * WebDriverSession session;
35 * Future f = web_driver.newSession('chrome'); 36 * Future f = web_driver.newSession('chrome');
36 * f.chain((_session) { 37 * f.then((_session) {
37 * session = _session; 38 * session = _session;
38 * return session.setUrl('http://my.web.site.com'); 39 * return session.setUrl('http://my.web.site.com');
39 * }).chain((_) { 40 * }).then((_) {
40 * return session.findElement('id', 'username'); 41 * return session.findElement('id', 'username');
41 * }).chain((element) { 42 * }).then((element) {
42 * id = element['ELEMENT']; 43 * id = element['ELEMENT'];
43 * return session.sendKeyStrokesToElement(id, 44 * return session.sendKeyStrokesToElement(id,
44 * [ 'j', 'o', 'e', ' ', 'u', 's', 'e', 'r' ]); 45 * [ 'j', 'o', 'e', ' ', 'u', 's', 'e', 'r' ]);
45 * }).chain((_) { 46 * }).then((_) {
46 * return session.submit(id); 47 * return session.submit(id);
47 * }).chain((_) { 48 * }).then((_) {
48 * return session.close(); 49 * return session.close();
49 * }).then((_) { 50 * }).then((_) {
50 * session = null; 51 * session = null;
51 * }); 52 * });
52 */ 53 */
53 54
54 void writeStringToFile(String fileName, String contents) { 55 void writeStringToFile(String fileName, String contents) {
55 new File(fileName).writeAsStringSync(contents); 56 new File(fileName).writeAsStringSync(contents);
56 } 57 }
57 58
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 } 216 }
216 217
217 /** 218 /**
218 * Execute a request to the WebDriver server. [http_method] should be 219 * Execute a request to the WebDriver server. [http_method] should be
219 * one of 'GET', 'POST', or 'DELETE'. [command] is the text to append 220 * one of 'GET', 'POST', or 'DELETE'. [command] is the text to append
220 * to the base URL path to get the full URL. [params] are the additional 221 * to the base URL path to get the full URL. [params] are the additional
221 * parameters. If a [List] or [Map] they will be posted as JSON parameters. 222 * parameters. If a [List] or [Map] they will be posted as JSON parameters.
222 * If a number or string, "/params" is appended to the URL. 223 * If a number or string, "/params" is appended to the URL.
223 */ 224 */
224 void _serverRequest(String http_method, String command, Completer completer, 225 void _serverRequest(String http_method, String command, Completer completer,
225 [List successCodes, Map params, Function customHandler]) { 226 {List successCodes, Map params, Function customHandler}) {
226 var status = 0; 227 var status = 0;
227 var results = null; 228 var results = null;
228 var message = null; 229 var message = null;
229 if (successCodes == null) { 230 if (successCodes == null) {
230 successCodes = [ 200, 204 ]; 231 successCodes = [ 200, 204 ];
231 } 232 }
232 try { 233 try {
233 if (params != null && params is List && http_method != 'POST') {
234 throw new Exception(
235 'The http method called for ${command} is ${http_method} but it has '
236 'to be POST if you want to pass the JSON params '
237 '${json.stringify(params)}');
238 }
239
240 var path = command; 234 var path = command;
241 if (params != null && (params is num || params is String)) { 235 if (params != null) {
242 path = '$path/$params'; 236 if (params is num || params is String) {
237 path = '$path/$params';
238 params = null;
239 } else if (http_method != 'POST') {
240 throw new Exception(
241 'The http method called for ${command} is ${http_method} but it has '
242 'to be POST if you want to pass the JSON params '
243 '${json.stringify(params)}');
244 }
243 } 245 }
244 246
245 var client = new HttpClient(); 247 var client = new HttpClient();
246 var connection = client.open(http_method, _host, _port, path); 248 client.open(http_method, _host, _port, path).then((req) {
247 249 req.followRedirects = false;
248 connection.onRequest = (r) { 250 req.headers.add(HttpHeaders.ACCEPT, "application/json");
249 r.headers.add(HttpHeaders.ACCEPT, "application/json"); 251 req.headers.add(
250 r.headers.add(
251 HttpHeaders.CONTENT_TYPE, 'application/json;charset=UTF-8'); 252 HttpHeaders.CONTENT_TYPE, 'application/json;charset=UTF-8');
252 OutputStream s = r.outputStream; 253 if (params != null) {
253 if (params != null && params is Map) { 254 var body = json.stringify(params);
254 s.writeString(json.stringify(params)); 255 req.write(body);
255 } 256 }
256 s.close(); 257 req.close().then((rsp) {
257 }; 258 List<int> body = new List<int>();
258 connection.onError = (e) { 259 rsp.listen(body.addAll, onDone: () {
260 var value = null;
261 results = new String.fromCharCodes(body);
262 // For some reason we get a bunch of NULs on the end
263 // of the text and the json.parse blows up on these, so
264 // strip them.
265 // These NULs can be seen in the TCP packet, so it is not
266 // an issue with character encoding; it seems to be a bug
267 // in WebDriver stack.
268 for (var i = results.length; --i >= 0;) {
269 var code = results.codeUnitAt(i);
270 if (code != 0) {
271 results = results.substring(0, i + 1);
272 break;
273 }
274 }
275 if (successCodes.indexOf(rsp.statusCode) < 0) {
276 throw 'Unexpected response ${rsp.statusCode}; $results';
277 }
278 if (status == 0 && results.length > 0) {
279 // 4xx responses send plain text; others send JSON.
280 if (rsp.statusCode < 400) {
281 results = json.parse(results);
282 status = results['status'];
283 }
284 if (results is Map && (results as Map).containsKey('value')) {
285 value = results['value'];
286 }
287 if (value is Map && value.containsKey('message')) {
288 message = value['message'];
289 }
290 }
291 if (status == 0) {
292 if (customHandler != null) {
293 customHandler(rsp, value);
294 } else if (completer != null) {
295 completer.complete(value);
296 }
297 }
298 });
299 })
300 .catchError((e) {
301 if (completer != null) {
302 completer.completeError(new WebDriverError(-1, e));
303 completer = null;
304 }
305 });
306 })
307 .catchError((e) {
259 if (completer != null) { 308 if (completer != null) {
260 completer.completeError(new WebDriverError(-1, e)); 309 completer.completeError(new WebDriverError(-1, e));
261 completer = null; 310 completer = null;
262 } 311 }
263 }; 312 });
264 connection.followRedirects = false;
265 connection.onResponse = (r) {
266 StringInputStream s = new StringInputStream(r.inputStream);
267 StringBuffer sbuf = new StringBuffer();
268 s.onData = () {
269 var data = s.read();
270 if (data != null) {
271 sbuf.write(data);
272 }
273 };
274 s.onClosed = () {
275 var value = null;
276 results = sbuf.toString().trim();
277 // For some reason we get a bunch of NULs on the end
278 // of the text and the json.parse blows up on these, so
279 // strip them.
280 // These NULs can be seen in the TCP packet, so it is not
281 // an issue with character encoding; it seems to be a bug
282 // in WebDriver stack.
283 for (var i = results.length; --i >= 0;) {
284 var code = results.codeUnitAt(i);
285 if (code != 0) {
286 results = results.substring(0, i + 1);
287 break;
288 }
289 }
290 if (successCodes.indexOf(r.statusCode) < 0) {
291 throw 'Unexpected response ${r.statusCode}';
292 }
293 if (status == 0 && results.length > 0) {
294 // 4xx responses send plain text; others send JSON.
295 if (r.statusCode < 400) {
296 results = json.parse(results);
297 status = results['status'];
298 }
299 if (results is Map && (results as Map).containsKey('value')) {
300 value = results['value'];
301 }
302 if (value is Map && value.containsKey('message')) {
303 message = value['message'];
304 }
305 }
306 if (status == 0) {
307 if (customHandler != null) {
308 customHandler(r, value);
309 } else if (completer != null) {
310 completer.complete(value);
311 }
312 }
313 };
314 };
315 } catch (e, s) { 313 } catch (e, s) {
316 completer.completeError( 314 completer.completeError(
317 new WebDriverError(-1, e), s); 315 new WebDriverError(-1, e), s);
318 completer = null; 316 completer = null;
319 } 317 }
320 } 318 }
321 319
322 Future _simpleCommand(method, extraPath, [successCodes, params]) { 320 Future _get(String extraPath) {
323 var completer = new Completer(); 321 var completer = new Completer();
324 _serverRequest(method, '${_path}/$extraPath', completer, 322 _serverRequest('GET', '${_path}/$extraPath', completer);
325 successCodes, params: params);
326 return completer.future; 323 return completer.future;
327 } 324 }
328 325
329 Future _get(extraPath, [successCodes]) => 326 Future _getCustom(String extraPath, Function customHandler) =>
330 _simpleCommand('GET', extraPath, successCodes); 327 _serverRequest('GET', '${_path}/$extraPath', null,
328 customHandler: customHandler);
331 329
332 Future _post(extraPath, [successCodes, params]) => 330 Future _post(String extraPath, [String params]) {
333 _simpleCommand('POST', extraPath, successCodes, params); 331 var completer = new Completer();
332 _serverRequest('POST', '${_path}/$extraPath', completer,
333 params: params);
334 return completer.future;
335 }
334 336
335 Future _delete(extraPath, [successCodes]) => 337 Future _delete(String extraPath) {
336 _simpleCommand('DELETE', extraPath, successCodes); 338 var completer = new Completer();
339 _serverRequest('DELETE', '${_path}/$extraPath', completer);
340 return completer.future;
341 }
337 } 342 }
338 343
339 class WebDriver extends WebDriverBase { 344 class WebDriver extends WebDriverBase {
340 345
341 WebDriver(host, port, path) : super(host, port, path); 346 WebDriver(host, port, path) : super(host, port, path);
342 347
343 /** 348 /**
344 * Create a new session. The server will attempt to create a session that 349 * Create a new session. The server will attempt to create a session that
345 * most closely matches the desired and required capabilities. Required 350 * most closely matches the desired and required capabilities. Required
346 * capabilities have higher priority than desired capabilities and must be 351 * capabilities have higher priority than desired capabilities and must be
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 */ 430 */
426 Future<WebDriverSession> newSession([ 431 Future<WebDriverSession> newSession([
427 browser = 'chrome', Map additional_capabilities]) { 432 browser = 'chrome', Map additional_capabilities]) {
428 var completer = new Completer(); 433 var completer = new Completer();
429 if (additional_capabilities == null) { 434 if (additional_capabilities == null) {
430 additional_capabilities = {}; 435 additional_capabilities = {};
431 } 436 }
432 437
433 additional_capabilities['browserName'] = browser; 438 additional_capabilities['browserName'] = browser;
434 439
435 _serverRequest('POST', '${_path}/session', null, [ 302 ], 440 _serverRequest('POST', '${_path}/session', null,
441 successCodes: [ 302 ],
436 customHandler: (r, v) { 442 customHandler: (r, v) {
437 var url = r.headers.value(HttpHeaders.LOCATION); 443 var url = r.headers.value(HttpHeaders.LOCATION);
438 var session = new WebDriverSession.fromUrl(url); 444 var session = new WebDriverSession.fromUrl(url);
439 completer.complete(session); 445 completer.complete(session);
440 }, params: { 'desiredCapabilities': additional_capabilities }); 446 },
447 params: { 'desiredCapabilities': additional_capabilities });
441 return completer.future; 448 return completer.future;
442 } 449 }
443 450
444 /** Get the set of currently active sessions. */ 451 /** Get the set of currently active sessions. */
445 Future<List<WebDriverSession>> getSessions() { 452 Future<List<WebDriverSession>> getSessions() {
446 var completer = new Completer(); 453 var completer = new Completer();
447 _get('sessions', (result) { 454 _getCustom('sessions', (r, v) {
448 var _sessions = []; 455 var _sessions = [];
449 for (var session in result) { 456 for (var session in v) {
450 _sessions.add(new WebDriverSession.fromUrl( 457 var url = 'http://${this._host}:${this._port}${this._path}/'
451 '${this._path}/session/${session["id"]}')); 458 'session/${session["id"]}';
459 _sessions.add(new WebDriverSession.fromUrl(url));
452 } 460 }
453 completer.complete(_sessions); 461 completer.complete(_sessions);
454 }); 462 });
455 return completer.future; 463 return completer.future;
456 } 464 }
457 465
458 /** Query the server's current status. */ 466 /** Query the server's current status. */
459 Future<Map> getStatus() => _get('status'); 467 Future<Map> getStatus() => _get('status');
460 } 468 }
461 469
462 class WebDriverWindow extends WebDriverBase { 470 class WebDriverWindow extends WebDriverBase {
463 WebDriverWindow.fromUrl(url) : super.fromUrl(url); 471 WebDriverWindow.fromUrl(url) : super.fromUrl(url);
464 472
465 /** Get the window size. */ 473 /** Get the window size. */
466 Future<Map> getSize() => _get('size'); 474 Future<Map> getSize() => _get('size');
467 475
468 /** 476 /**
469 * Set the window size. 477 * Set the window size.
470 * 478 *
471 * Potential Errors: 479 * Potential Errors:
472 * NoSuchWindow - If the specified window cannot be found. 480 * NoSuchWindow - If the specified window cannot be found.
473 */ 481 */
474 Future<String> setSize(int width, int height) => 482 Future<String> setSize(int width, int height) =>
475 _post('size', params: { 'width': width, 'height': height }); 483 _post('size', { 'width': width, 'height': height });
476 484
477 /** Get the window position. */ 485 /** Get the window position. */
478 Future<Map> getPosition() => _get('position'); 486 Future<Map> getPosition() => _get('position');
479 487
480 /** 488 /**
481 * Set the window position. 489 * Set the window position.
482 * 490 *
483 * Potential Errors: NoSuchWindow. 491 * Potential Errors: NoSuchWindow.
484 */ 492 */
485 Future setPosition(int x, int y) => 493 Future setPosition(int x, int y) =>
486 _post('position', params: { 'x': x, 'y': y }); 494 _post('position', { 'x': x, 'y': y });
487 495
488 /** Maximize the specified window if not already maximized. */ 496 /** Maximize the specified window if not already maximized. */
489 Future maximize() => _post('maximize'); 497 Future maximize() => _post('maximize');
490 } 498 }
491 499
492 class WebDriverSession extends WebDriverBase { 500 class WebDriverSession extends WebDriverBase {
493 WebDriverSession.fromUrl(url) : super.fromUrl(url); 501 WebDriverSession.fromUrl(url) : super.fromUrl(url);
494 502
495 /** Close the session. */ 503 /** Close the session. */
496 Future close() => _delete(''); 504 Future close() => _delete('');
497 505
498 /** Get the session capabilities. See [newSession] for details. */ 506 /** Get the session capabilities. See [newSession] for details. */
499 Future<Map> getCapabilities() => _get(''); 507 Future<Map> getCapabilities() => _get('');
500 508
501 /** 509 /**
502 * Configure the amount of time in milliseconds that a script can execute 510 * Configure the amount of time in milliseconds that a script can execute
503 * for before it is aborted and a Timeout error is returned to the client. 511 * for before it is aborted and a Timeout error is returned to the client.
504 */ 512 */
505 Future setScriptTimeout(t) => 513 Future setScriptTimeout(t) =>
506 _post('timeouts', params: { 'type': 'script', 'ms': t }); 514 _post('timeouts', { 'type': 'script', 'ms': t });
507 515
508 /*Future<String> setImplicitWaitTimeout(t) => 516 /*Future<String> setImplicitWaitTimeout(t) =>
509 simplePost('timeouts', { 'type': 'implicit', 'ms': t });*/ 517 simplePost('timeouts', { 'type': 'implicit', 'ms': t });*/
510 518
511 /** 519 /**
512 * Configure the amount of time in milliseconds that a page can load for 520 * Configure the amount of time in milliseconds that a page can load for
513 * before it is aborted and a Timeout error is returned to the client. 521 * before it is aborted and a Timeout error is returned to the client.
514 */ 522 */
515 Future setPageLoadTimeout(t) => 523 Future setPageLoadTimeout(t) =>
516 _post('timeouts', params: { 'type': 'page load', 'ms': t }); 524 _post('timeouts', { 'type': 'page load', 'ms': t });
517 525
518 /** 526 /**
519 * Set the amount of time, in milliseconds, that asynchronous scripts 527 * Set the amount of time, in milliseconds, that asynchronous scripts
520 * executed by /session/:sessionId/execute_async are permitted to run 528 * executed by /session/:sessionId/execute_async are permitted to run
521 * before they are aborted and a Timeout error is returned to the client. 529 * before they are aborted and a Timeout error is returned to the client.
522 */ 530 */
523 Future setAsyncScriptTimeout(t) => 531 Future setAsyncScriptTimeout(t) =>
524 _post('timeouts/async_script', params: { 'ms': t }); 532 _post('timeouts/async_script', { 'ms': t });
525 533
526 /** 534 /**
527 * Set the amount of time the driver should wait when searching for elements. 535 * Set the amount of time the driver should wait when searching for elements.
528 * When searching for a single element, the driver should poll the page until 536 * When searching for a single element, the driver should poll the page until
529 * an element is found or the timeout expires, whichever occurs first. When 537 * an element is found or the timeout expires, whichever occurs first. When
530 * searching for multiple elements, the driver should poll the page until at 538 * searching for multiple elements, the driver should poll the page until at
531 * least one element is found or the timeout expires, at which point it should 539 * least one element is found or the timeout expires, at which point it should
532 * return an empty list. 540 * return an empty list.
533 * 541 *
534 * If this command is never sent, the driver should default to an implicit 542 * If this command is never sent, the driver should default to an implicit
535 * wait of 0ms. 543 * wait of 0ms.
536 */ 544 */
537 Future setImplicitWaitTimeout(t) => 545 Future setImplicitWaitTimeout(t) =>
538 _post('timeouts/implicit_wait', params: { 'ms': t }); 546 _post('timeouts/implicit_wait', { 'ms': t });
539 547
540 /** 548 /**
541 * Retrieve the current window handle. 549 * Retrieve the current window handle.
542 * 550 *
543 * Potential Errors: NoSuchWindow. 551 * Potential Errors: NoSuchWindow.
544 */ 552 */
545 Future<String> getWindowHandle() => _get('window_handle'); 553 Future<String> getWindowHandle() => _get('window_handle');
546 554
547 /** 555 /**
548 * Retrieve a [WebDriverWindow] for the specified window. We don't 556 * Retrieve a [WebDriverWindow] for the specified window. We don't
(...skipping 13 matching lines...) Expand all
562 * 570 *
563 * Potential Errors: NoSuchWindow. 571 * Potential Errors: NoSuchWindow.
564 */ 572 */
565 Future<String> getUrl() => _get('url'); 573 Future<String> getUrl() => _get('url');
566 574
567 /** 575 /**
568 * Navigate to a new URL. 576 * Navigate to a new URL.
569 * 577 *
570 * Potential Errors: NoSuchWindow. 578 * Potential Errors: NoSuchWindow.
571 */ 579 */
572 Future setUrl(String url) => _post('url', params: { 'url': url }); 580 Future setUrl(String url) => _post('url', { 'url': url });
573 581
574 /** 582 /**
575 * Navigate forwards in the browser history, if possible. 583 * Navigate forwards in the browser history, if possible.
576 * 584 *
577 * Potential Errors: NoSuchWindow. 585 * Potential Errors: NoSuchWindow.
578 */ 586 */
579 Future navigateForward() => _post('forward'); 587 Future navigateForward() => _post('forward');
580 588
581 /** 589 /**
582 * Navigate backwards in the browser history, if possible. 590 * Navigate backwards in the browser history, if possible.
(...skipping 22 matching lines...) Expand all
605 * specified. 613 * specified.
606 * 614 *
607 * Arguments may be any JSON-primitive, array, or JSON object. JSON objects 615 * Arguments may be any JSON-primitive, array, or JSON object. JSON objects
608 * that define a WebElement reference will be converted to the corresponding 616 * that define a WebElement reference will be converted to the corresponding
609 * DOM element. Likewise, any WebElements in the script result will be 617 * DOM element. Likewise, any WebElements in the script result will be
610 * returned to the client as WebElement JSON objects. 618 * returned to the client as WebElement JSON objects.
611 * 619 *
612 * Potential Errors: NoSuchWindow, StaleElementReference, JavaScriptError. 620 * Potential Errors: NoSuchWindow, StaleElementReference, JavaScriptError.
613 */ 621 */
614 Future execute(String script, [List args]) => 622 Future execute(String script, [List args]) =>
615 _post('execute', params: { 'script': script, 'args': args }); 623 _post('execute', { 'script': script, 'args': args });
616 624
617 /** 625 /**
618 * Inject a snippet of JavaScript into the page for execution in the context 626 * Inject a snippet of JavaScript into the page for execution in the context
619 * of the currently selected frame. The executed script is assumed to be 627 * of the currently selected frame. The executed script is assumed to be
620 * asynchronous and must signal that it is done by invoking the provided 628 * asynchronous and must signal that it is done by invoking the provided
621 * callback, which is always provided as the final argument to the function. 629 * callback, which is always provided as the final argument to the function.
622 * The value to this callback will be returned to the client. 630 * The value to this callback will be returned to the client.
623 * 631 *
624 * Asynchronous script commands may not span page loads. If an unload event 632 * Asynchronous script commands may not span page loads. If an unload event
625 * is fired while waiting for a script result, an error should be returned 633 * is fired while waiting for a script result, an error should be returned
626 * to the client. 634 * to the client.
627 * 635 *
628 * The script argument defines the script to execute in the form of a function 636 * The script argument defines the script to execute in the form of a function
629 * body. The function will be invoked with the provided args array and the 637 * body. The function will be invoked with the provided args array and the
630 * values may be accessed via the arguments object in the order specified. 638 * values may be accessed via the arguments object in the order specified.
631 * The final argument will always be a callback function that must be invoked 639 * The final argument will always be a callback function that must be invoked
632 * to signal that the script has finished. 640 * to signal that the script has finished.
633 * 641 *
634 * Arguments may be any JSON-primitive, array, or JSON object. JSON objects 642 * Arguments may be any JSON-primitive, array, or JSON object. JSON objects
635 * that define a WebElement reference will be converted to the corresponding 643 * that define a WebElement reference will be converted to the corresponding
636 * DOM element. Likewise, any WebElements in the script result will be 644 * DOM element. Likewise, any WebElements in the script result will be
637 * returned to the client as WebElement JSON objects. 645 * returned to the client as WebElement JSON objects.
638 * 646 *
639 * Potential Errors: NoSuchWindow, StaleElementReference, Timeout (controlled 647 * Potential Errors: NoSuchWindow, StaleElementReference, Timeout (controlled
640 * by the [setAsyncScriptTimeout] command), JavaScriptError (if the script 648 * by the [setAsyncScriptTimeout] command), JavaScriptError (if the script
641 * callback is not invoked before the timout expires). 649 * callback is not invoked before the timout expires).
642 */ 650 */
643 Future executeAsync(String script, [List args]) => 651 Future executeAsync(String script, [List args]) =>
644 _post('execute_async', params: { 'script': script, 'args': args }); 652 _post('execute_async', { 'script': script, 'args': args });
645 653
646 /** 654 /**
647 * Take a screenshot of the current page (PNG). 655 * Take a screenshot of the current page (PNG).
648 * 656 *
649 * Potential Errors: NoSuchWindow. 657 * Potential Errors: NoSuchWindow.
650 */ 658 */
651 Future<List<int>> getScreenshot([fname]) { 659 Future<List<int>> getScreenshot([fname]) {
652 var completer = new Completer(); 660 var completer = new Completer();
653 var result = _serverRequest('GET', '$_path/screenshot', completer, 661 var result = _serverRequest('GET', '$_path/screenshot', completer,
654 customHandler: (r, v) { 662 customHandler: (r, v) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 * Make an engine that is available (appears on the list returned by 705 * Make an engine that is available (appears on the list returned by
698 * getAvailableEngines) active. After this call, the engine will be added 706 * getAvailableEngines) active. After this call, the engine will be added
699 * to the list of engines loaded in the IME daemon and the input sent using 707 * to the list of engines loaded in the IME daemon and the input sent using
700 * sendKeys will be converted by the active engine. Note that this is a 708 * sendKeys will be converted by the active engine. Note that this is a
701 * platform-independent method of activating IME (the platform-specific way 709 * platform-independent method of activating IME (the platform-specific way
702 * being using keyboard shortcuts). 710 * being using keyboard shortcuts).
703 * 711 *
704 * Potential Errors: ImeActivationFailedException, ImeNotAvailableException. 712 * Potential Errors: ImeActivationFailedException, ImeNotAvailableException.
705 */ 713 */
706 Future activateIme(String engine) => 714 Future activateIme(String engine) =>
707 _post('ime/activate', params: { 'engine': engine }); 715 _post('ime/activate', { 'engine': engine });
708 716
709 /** 717 /**
710 * Change focus to another frame on the page. If the frame id is null, 718 * Change focus to another frame on the page. If the frame id is null,
711 * the server should switch to the page's default content. 719 * the server should switch to the page's default content.
712 * [id] is the Identifier for the frame to change focus to, and can be 720 * [id] is the Identifier for the frame to change focus to, and can be
713 * a string, number, null, or JSON Object. 721 * a string, number, null, or JSON Object.
714 * 722 *
715 * Potential Errors: NoSuchWindow, NoSuchFrame. 723 * Potential Errors: NoSuchWindow, NoSuchFrame.
716 */ 724 */
717 Future setFrameFocus(id) => _post('frame', params: { 'id': id }); 725 Future setFrameFocus(id) => _post('frame', { 'id': id });
718 726
719 /** 727 /**
720 * Change focus to another window. The window to change focus to may be 728 * Change focus to another window. The window to change focus to may be
721 * specified by [name], which is its server assigned window handle, or 729 * specified by [name], which is its server assigned window handle, or
722 * the value of its name attribute. 730 * the value of its name attribute.
723 * 731 *
724 * Potential Errors: NoSuchWindow. 732 * Potential Errors: NoSuchWindow.
725 */ 733 */
726 Future setWindowFocus(name) => 734 Future setWindowFocus(name) => _post('window', { 'name': name });
727 _post('window', params: { 'name': name });
728 735
729 /** 736 /**
730 * Close the current window. 737 * Close the current window.
731 * 738 *
732 * Potential Errors: NoSuchWindow. 739 * Potential Errors: NoSuchWindow.
733 */ 740 */
734 Future closeWindow() => _delete('window'); 741 Future closeWindow() => _delete('window');
735 742
736 /** 743 /**
737 * Retrieve all cookies visible to the current page. 744 * Retrieve all cookies visible to the current page.
(...skipping 17 matching lines...) Expand all
755 * Potential Errors: NoSuchWindow. 762 * Potential Errors: NoSuchWindow.
756 */ 763 */
757 Future<List<Map>> getCookies() => _get('cookie'); 764 Future<List<Map>> getCookies() => _get('cookie');
758 765
759 /** 766 /**
760 * Set a cookie. If the cookie path is not specified, it should be set 767 * Set a cookie. If the cookie path is not specified, it should be set
761 * to "/". Likewise, if the domain is omitted, it should default to the 768 * to "/". Likewise, if the domain is omitted, it should default to the
762 * current page's domain. See [getCookies] for the structure of a cookie 769 * current page's domain. See [getCookies] for the structure of a cookie
763 * Map. 770 * Map.
764 */ 771 */
765 Future setCookie(Map cookie) => 772 Future setCookie(Map cookie) => _post('cookie', { 'cookie': cookie });
766 _post('cookie', params: { 'cookie': cookie });
767 773
768 /** 774 /**
769 * Delete all cookies visible to the current page. 775 * Delete all cookies visible to the current page.
770 * 776 *
771 * Potential Errors: InvalidCookieDomain (the cookie's domain is not 777 * Potential Errors: InvalidCookieDomain (the cookie's domain is not
772 * visible from the current page), NoSuchWindow, UnableToSetCookie (if 778 * visible from the current page), NoSuchWindow, UnableToSetCookie (if
773 * attempting to set a cookie on a page that does not support cookies, 779 * attempting to set a cookie on a page that does not support cookies,
774 * e.g. pages with mime-type text/plain). 780 * e.g. pages with mime-type text/plain).
775 */ 781 */
776 Future deleteCookies() => _delete('cookie'); 782 Future deleteCookies() => _delete('cookie');
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
820 * partially matches the search value. 826 * partially matches the search value.
821 * 827 *
822 * 'tag name' - Returns an element whose tag name matches the search value. 828 * 'tag name' - Returns an element whose tag name matches the search value.
823 * 829 *
824 * 'xpath' - Returns an element matching an XPath expression. 830 * 'xpath' - Returns an element matching an XPath expression.
825 * 831 *
826 * Potential Errors: NoSuchWindow, NoSuchElement, XPathLookupError (if 832 * Potential Errors: NoSuchWindow, NoSuchElement, XPathLookupError (if
827 * using XPath and the input expression is invalid). 833 * using XPath and the input expression is invalid).
828 */ 834 */
829 Future<String> findElement(String strategy, String searchValue) => 835 Future<String> findElement(String strategy, String searchValue) =>
830 _post('element', params: { 'using': strategy, 'value' : searchValue }); 836 _post('element', { 'using': strategy, 'value' : searchValue });
831 837
832 /** 838 /**
833 * Search for multiple elements on the page, starting from the document root. 839 * Search for multiple elements on the page, starting from the document root.
834 * The located elements will be returned as WebElement JSON objects. See 840 * The located elements will be returned as WebElement JSON objects. See
835 * [findElement] for the locator strategies that each server supports. 841 * [findElement] for the locator strategies that each server supports.
836 * Elements are be returned in the order located in the DOM. 842 * Elements are be returned in the order located in the DOM.
837 * 843 *
838 * Potential Errors: NoSuchWindow, XPathLookupError. 844 * Potential Errors: NoSuchWindow, XPathLookupError.
839 */ 845 */
840 Future<List<String>> findElements(String strategy, String searchValue) => 846 Future<List<String>> findElements(String strategy, String searchValue) =>
841 _post('elements', params: { 'using': strategy, 'value' : searchValue }); 847 _post('elements', { 'using': strategy, 'value' : searchValue });
842 848
843 /** 849 /**
844 * Get the element on the page that currently has focus. The element will 850 * Get the element on the page that currently has focus. The element will
845 * be returned as a WebElement JSON object. 851 * be returned as a WebElement JSON object.
846 * 852 *
847 * Potential Errors: NoSuchWindow. 853 * Potential Errors: NoSuchWindow.
848 */ 854 */
849 Future<String> getElementWithFocus() => _post('element/active'); 855 Future<String> getElementWithFocus() => _post('element/active');
850 856
851 /** 857 /**
852 * Search for an element on the page, starting from element with id [id]. 858 * Search for an element on the page, starting from element with id [id].
853 * The located element will be returned as WebElement JSON objects. See 859 * The located element will be returned as WebElement JSON objects. See
854 * [findElement] for the locator strategies that each server supports. 860 * [findElement] for the locator strategies that each server supports.
855 * 861 *
856 * Potential Errors: NoSuchWindow, XPathLookupError. 862 * Potential Errors: NoSuchWindow, XPathLookupError.
857 */ 863 */
858 Future<String> 864 Future<String>
859 findElementFromId(String id, String strategy, String searchValue) { 865 findElementFromId(String id, String strategy, String searchValue) {
860 _post('element/$id/element', 866 _post('element/$id/element', { 'using': strategy, 'value' : searchValue });
861 params: { 'using': strategy, 'value' : searchValue });
862 } 867 }
863 868
864 /** 869 /**
865 * Search for multiple elements on the page, starting from the element with 870 * Search for multiple elements on the page, starting from the element with
866 * id [id].The located elements will be returned as WebElement JSON objects. 871 * id [id].The located elements will be returned as WebElement JSON objects.
867 * See [findElement] for the locator strategies that each server supports. 872 * See [findElement] for the locator strategies that each server supports.
868 * Elements are be returned in the order located in the DOM. 873 * Elements are be returned in the order located in the DOM.
869 * 874 *
870 * Potential Errors: NoSuchWindow, XPathLookupError. 875 * Potential Errors: NoSuchWindow, XPathLookupError.
871 */ 876 */
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 * either the modifier is encountered again in the sequence, or the NULL 1000 * either the modifier is encountered again in the sequence, or the NULL
996 * (U+E000) key is encountered. 1001 * (U+E000) key is encountered.
997 * 1002 *
998 * - Each key sequence is terminated with an implicit NULL key. 1003 * - Each key sequence is terminated with an implicit NULL key.
999 * Subsequently, all depressed modifier keys are released (with 1004 * Subsequently, all depressed modifier keys are released (with
1000 * corresponding keyup events) at the end of the sequence. 1005 * corresponding keyup events) at the end of the sequence.
1001 * 1006 *
1002 * Potential Errors: NoSuchWindow, StaleElementReference, ElementNotVisible. 1007 * Potential Errors: NoSuchWindow, StaleElementReference, ElementNotVisible.
1003 */ 1008 */
1004 Future sendKeyStrokesToElement(String id, List<String> keys) => 1009 Future sendKeyStrokesToElement(String id, List<String> keys) =>
1005 _post('element/$id/value', params: { 'value': keys }); 1010 _post('element/$id/value', { 'value': keys });
1006 1011
1007 /** 1012 /**
1008 * Send a sequence of key strokes to the active element. This command is 1013 * Send a sequence of key strokes to the active element. This command is
1009 * similar to [sendKeyStrokesToElement] command in every aspect except the 1014 * similar to [sendKeyStrokesToElement] command in every aspect except the
1010 * implicit termination: The modifiers are not released at the end of the 1015 * implicit termination: The modifiers are not released at the end of the
1011 * call. Rather, the state of the modifier keys is kept between calls, 1016 * call. Rather, the state of the modifier keys is kept between calls,
1012 * so mouse interactions can be performed while modifier keys are depressed. 1017 * so mouse interactions can be performed while modifier keys are depressed.
1013 * 1018 *
1014 * Potential Errors: NoSuchWindow. 1019 * Potential Errors: NoSuchWindow.
1015 */ 1020 */
1016 Future sendKeyStrokes(List<String> keys) => 1021 Future sendKeyStrokes(List<String> keys) => _post('keys', { 'value': keys });
1017 _post('keys', params: { 'value': keys });
1018 1022
1019 /** 1023 /**
1020 * Query for an element's tag name, as a lower-case string. 1024 * Query for an element's tag name, as a lower-case string.
1021 * 1025 *
1022 * Potential Errors: NoSuchWindow, StaleElementReference. 1026 * Potential Errors: NoSuchWindow, StaleElementReference.
1023 */ 1027 */
1024 Future<String> getElementTagName(String id) => _get('element/$id/name'); 1028 Future<String> getElementTagName(String id) => _get('element/$id/name');
1025 1029
1026 /** 1030 /**
1027 * Clear a TEXTAREA or text INPUT element's value. 1031 * Clear a TEXTAREA or text INPUT element's value.
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 * Potential Errors: NoAlertPresent. 1116 * Potential Errors: NoAlertPresent.
1113 */ 1117 */
1114 Future<String> getAlertText() => _get('alert_text'); 1118 Future<String> getAlertText() => _get('alert_text');
1115 1119
1116 /** 1120 /**
1117 * Sends keystrokes to a JavaScript prompt() dialog. 1121 * Sends keystrokes to a JavaScript prompt() dialog.
1118 * 1122 *
1119 * Potential Errors: NoAlertPresent. 1123 * Potential Errors: NoAlertPresent.
1120 */ 1124 */
1121 Future sendKeyStrokesToPrompt(String text) => 1125 Future sendKeyStrokesToPrompt(String text) =>
1122 _post('alert_text', params: { 'text': text }); 1126 _post('alert_text', { 'text': text });
1123 1127
1124 /** 1128 /**
1125 * Accepts the currently displayed alert dialog. Usually, this is equivalent 1129 * Accepts the currently displayed alert dialog. Usually, this is equivalent
1126 * to clicking on the 'OK' button in the dialog. 1130 * to clicking on the 'OK' button in the dialog.
1127 * 1131 *
1128 * Potential Errors: NoAlertPresent. 1132 * Potential Errors: NoAlertPresent.
1129 */ 1133 */
1130 Future acceptAlert() => _post('accept_alert'); 1134 Future acceptAlert() => _post('accept_alert');
1131 1135
1132 /** 1136 /**
1133 * Dismisses the currently displayed alert dialog. For confirm() and prompt() 1137 * Dismisses the currently displayed alert dialog. For confirm() and prompt()
1134 * dialogs, this is equivalent to clicking the 'Cancel' button. For alert() 1138 * dialogs, this is equivalent to clicking the 'Cancel' button. For alert()
1135 * dialogs, this is equivalent to clicking the 'OK' button. 1139 * dialogs, this is equivalent to clicking the 'OK' button.
1136 * 1140 *
1137 * Potential Errors: NoAlertPresent. 1141 * Potential Errors: NoAlertPresent.
1138 */ 1142 */
1139 Future dismissAlert() => _post('dismiss_alert'); 1143 Future dismissAlert() => _post('dismiss_alert');
1140 1144
1141 /** 1145 /**
1142 * Move the mouse by an offset of the specificed element. If no element is 1146 * Move the mouse by an offset of the specificed element. If no element is
1143 * specified, the move is relative to the current mouse cursor. If an 1147 * specified, the move is relative to the current mouse cursor. If an
1144 * element is provided but no offset, the mouse will be moved to the center 1148 * element is provided but no offset, the mouse will be moved to the center
1145 * of the element. If the element is not visible, it will be scrolled 1149 * of the element. If the element is not visible, it will be scrolled
1146 * into view. 1150 * into view.
1147 */ 1151 */
1148 Future moveTo(String id, int x, int y) => 1152 Future moveTo(String id, int x, int y) =>
1149 _post('moveto', params: { 'element': id, 'xoffset': x, 'yoffset' : y}); 1153 _post('moveto', { 'element': id, 'xoffset': x, 'yoffset' : y});
1150 1154
1151 /** 1155 /**
1152 * Click a mouse button (at the coordinates set by the last [moveTo] command). 1156 * Click a mouse button (at the coordinates set by the last [moveTo] command).
1153 * Note that calling this command after calling [buttonDown] and before 1157 * Note that calling this command after calling [buttonDown] and before
1154 * calling [buttonUp] (or any out-of-order interactions sequence) will yield 1158 * calling [buttonUp] (or any out-of-order interactions sequence) will yield
1155 * undefined behaviour). 1159 * undefined behaviour).
1156 * 1160 *
1157 * [button] should be 0 for left, 1 for middle, or 2 for right. 1161 * [button] should be 0 for left, 1 for middle, or 2 for right.
1158 */ 1162 */
1159 Future clickMouse([button = 0]) => 1163 Future clickMouse([button = 0]) => _post('click', { 'button' : button });
1160 _post('click', params: { 'button' : button });
1161 1164
1162 /** 1165 /**
1163 * Click and hold the left mouse button (at the coordinates set by the last 1166 * Click and hold the left mouse button (at the coordinates set by the last
1164 * [moveTo] command). Note that the next mouse-related command that should 1167 * [moveTo] command). Note that the next mouse-related command that should
1165 * follow is [buttonDown]. Any other mouse command (such as [click] or 1168 * follow is [buttonDown]. Any other mouse command (such as [click] or
1166 * another call to [buttonDown]) will yield undefined behaviour. 1169 * another call to [buttonDown]) will yield undefined behaviour.
1167 * 1170 *
1168 * [button] should be 0 for left, 1 for middle, or 2 for right. 1171 * [button] should be 0 for left, 1 for middle, or 2 for right.
1169 */ 1172 */
1170 Future buttonDown([button = 0]) => 1173 Future buttonDown([button = 0]) => _post('click', { 'button' : button });
1171 _post('click', params: { 'button' : button });
1172 1174
1173 /** 1175 /**
1174 * Releases the mouse button previously held (where the mouse is currently 1176 * Releases the mouse button previously held (where the mouse is currently
1175 * at). Must be called once for every [buttonDown] command issued. See the 1177 * at). Must be called once for every [buttonDown] command issued. See the
1176 * note in [click] and [buttonDown] about implications of out-of-order 1178 * note in [click] and [buttonDown] about implications of out-of-order
1177 * commands. 1179 * commands.
1178 * 1180 *
1179 * [button] should be 0 for left, 1 for middle, or 2 for right. 1181 * [button] should be 0 for left, 1 for middle, or 2 for right.
1180 */ 1182 */
1181 Future buttonUp([button = 0]) => 1183 Future buttonUp([button = 0]) => _post('click', { 'button' : button });
1182 _post('click', params: { 'button' : button });
1183 1184
1184 /** Double-clicks at the current mouse coordinates (set by [moveTo]). */ 1185 /** Double-clicks at the current mouse coordinates (set by [moveTo]). */
1185 Future doubleClick() => _post('doubleclick'); 1186 Future doubleClick() => _post('doubleclick');
1186 1187
1187 /** Single tap on the touch enabled device on the element with id [id]. */ 1188 /** Single tap on the touch enabled device on the element with id [id]. */
1188 Future touchClick(String id) => 1189 Future touchClick(String id) => _post('touch/click', { 'element': id });
1189 _post('touch/click', params: { 'element': id });
1190 1190
1191 /** Finger down on the screen. */ 1191 /** Finger down on the screen. */
1192 Future touchDown(int x, int y) => 1192 Future touchDown(int x, int y) => _post('touch/down', { 'x': x, 'y': y });
1193 _post('touch/down', params: { 'x': x, 'y': y });
1194 1193
1195 /** Finger up on the screen. */ 1194 /** Finger up on the screen. */
1196 Future touchUp(int x, int y) => 1195 Future touchUp(int x, int y) => _post('touch/up', { 'x': x, 'y': y });
1197 _post('touch/up', params: { 'x': x, 'y': y });
1198 1196
1199 /** Finger move on the screen. */ 1197 /** Finger move on the screen. */
1200 Future touchMove(int x, int y) => 1198 Future touchMove(int x, int y) => _post('touch/move', { 'x': x, 'y': y });
1201 _post('touch/move', params: { 'x': x, 'y': y });
1202 1199
1203 /** 1200 /**
1204 * Scroll on the touch screen using finger based motion events. If [id] is 1201 * Scroll on the touch screen using finger based motion events. If [id] is
1205 * specified, scrolling will start at a particular screen location. 1202 * specified, scrolling will start at a particular screen location.
1206 */ 1203 */
1207 Future touchScroll(int xOffset, int yOffset, [String id = null]) { 1204 Future touchScroll(int xOffset, int yOffset, [String id = null]) {
1208 if (id == null) { 1205 if (id == null) {
1209 return _post('touch/scroll', 1206 return _post('touch/scroll', { 'xoffset': xOffset, 'yoffset': yOffset });
1210 params: { 'xoffset': xOffset, 'yoffset': yOffset });
1211 } else { 1207 } else {
1212 return _post('touch/scroll', 1208 return _post('touch/scroll',
1213 params: { 'element': id, 'xoffset': xOffset, 'yoffset': yOffset }); 1209 { 'element': id, 'xoffset': xOffset, 'yoffset': yOffset });
1214 } 1210 }
1215 } 1211 }
1216 1212
1217 /** Double tap on the touch screen using finger motion events. */ 1213 /** Double tap on the touch screen using finger motion events. */
1218 Future touchDoubleClick(String id) => 1214 Future touchDoubleClick(String id) =>
1219 _post('touch/doubleclick', params: { 'element': id }); 1215 _post('touch/doubleclick', { 'element': id });
1220 1216
1221 /** Long press on the touch screen using finger motion events. */ 1217 /** Long press on the touch screen using finger motion events. */
1222 Future touchLongClick(String id) => 1218 Future touchLongClick(String id) =>
1223 _post('touch/longclick', params: { 'element': id }); 1219 _post('touch/longclick', { 'element': id });
1224 1220
1225 /** 1221 /**
1226 * Flick on the touch screen using finger based motion events, starting 1222 * Flick on the touch screen using finger based motion events, starting
1227 * at a particular screen location. [speed] is in pixels-per-second. 1223 * at a particular screen location. [speed] is in pixels-per-second.
1228 */ 1224 */
1229 Future touchFlickFrom(String id, int xOffset, int yOffset, int speed) => 1225 Future touchFlickFrom(String id, int xOffset, int yOffset, int speed) =>
1230 _post('touch/flick', 1226 _post('touch/flick',
1231 params: { 'element': id, 'xoffset': xOffset, 'yoffset': yOffset, 1227 { 'element': id, 'xoffset': xOffset, 'yoffset': yOffset,
1232 'speed': speed }); 1228 'speed': speed });
1233 1229
1234 /** 1230 /**
1235 * Flick on the touch screen using finger based motion events. Use this 1231 * Flick on the touch screen using finger based motion events. Use this
1236 * instead of [touchFlickFrom] if you don'tr care where the flick starts. 1232 * instead of [touchFlickFrom] if you don'tr care where the flick starts.
1237 */ 1233 */
1238 Future touchFlick(int xSpeed, int ySpeed) => 1234 Future touchFlick(int xSpeed, int ySpeed) =>
1239 _post('touch/flick', params: { 'xSpeed': xSpeed, 'ySpeed': ySpeed }); 1235 _post('touch/flick', { 'xSpeed': xSpeed, 'ySpeed': ySpeed });
1240 1236
1241 /** 1237 /**
1242 * Get the current geo location. Returns a [Map] with latitude, 1238 * Get the current geo location. Returns a [Map] with latitude,
1243 * longitude and altitude properties. 1239 * longitude and altitude properties.
1244 */ 1240 */
1245 Future<Map> getGeolocation() => _get('location'); 1241 Future<Map> getGeolocation() => _get('location');
1246 1242
1247 /** Set the current geo location. */ 1243 /** Set the current geo location. */
1248 Future setLocation(double latitude, double longitude, double altitude) => 1244 Future setLocation(double latitude, double longitude, double altitude) =>
1249 _post('location', params: 1245 _post('location',
1250 { 'latitude': latitude, 1246 { 'latitude': latitude,
1251 'longitude': longitude, 1247 'longitude': longitude,
1252 'altitude': altitude }); 1248 'altitude': altitude });
1253 1249
1254 /** 1250 /**
1255 * Get all keys of the local storage. Completes with [null] if there 1251 * Get all keys of the local storage. Completes with [null] if there
1256 * are no keys or the keys could not be retrieved. 1252 * are no keys or the keys could not be retrieved.
1257 * 1253 *
1258 * Potential Errors: NoSuchWindow. 1254 * Potential Errors: NoSuchWindow.
1259 */ 1255 */
1260 Future<List<String>> getLocalStorageKeys() => _get('local_storage'); 1256 Future<List<String>> getLocalStorageKeys() => _get('local_storage');
1261 1257
1262 /** 1258 /**
1263 * Set the local storage item for the given key. 1259 * Set the local storage item for the given key.
1264 * 1260 *
1265 * Potential Errors: NoSuchWindow. 1261 * Potential Errors: NoSuchWindow.
1266 */ 1262 */
1267 Future setLocalStorageItem(String key, String value) => 1263 Future setLocalStorageItem(String key, String value) =>
1268 _post('local_storage', params: { 'key': key, 'value': value }); 1264 _post('local_storage', { 'key': key, 'value': value });
1269 1265
1270 /** 1266 /**
1271 * Clear the local storage. 1267 * Clear the local storage.
1272 * 1268 *
1273 * Potential Errors: NoSuchWindow. 1269 * Potential Errors: NoSuchWindow.
1274 */ 1270 */
1275 Future clearLocalStorage() => _delete('local_storage'); 1271 Future clearLocalStorage() => _delete('local_storage');
1276 1272
1277 /** 1273 /**
1278 * Get the local storage item for the given key. 1274 * Get the local storage item for the given key.
(...skipping 24 matching lines...) Expand all
1303 * Potential Errors: NoSuchWindow. 1299 * Potential Errors: NoSuchWindow.
1304 */ 1300 */
1305 Future<List<String>> getSessionStorageKeys() => _get('session_storage'); 1301 Future<List<String>> getSessionStorageKeys() => _get('session_storage');
1306 1302
1307 /** 1303 /**
1308 * Set the sessionstorage item for the given key. 1304 * Set the sessionstorage item for the given key.
1309 * 1305 *
1310 * Potential Errors: NoSuchWindow. 1306 * Potential Errors: NoSuchWindow.
1311 */ 1307 */
1312 Future setSessionStorageItem(String key, String value) => 1308 Future setSessionStorageItem(String key, String value) =>
1313 _post('session_storage', params: { 'key': key, 'value': value }); 1309 _post('session_storage', { 'key': key, 'value': value });
1314 1310
1315 /** 1311 /**
1316 * Clear the session storage. 1312 * Clear the session storage.
1317 * 1313 *
1318 * Potential Errors: NoSuchWindow. 1314 * Potential Errors: NoSuchWindow.
1319 */ 1315 */
1320 Future clearSessionStorage() => _delete('session_storage'); 1316 Future clearSessionStorage() => _delete('session_storage');
1321 1317
1322 /** 1318 /**
1323 * Get the session storage item for the given key. 1319 * Get the session storage item for the given key.
(...skipping 22 matching lines...) Expand all
1346 Future<List<String>> getLogTypes() => _get('log/types'); 1342 Future<List<String>> getLogTypes() => _get('log/types');
1347 1343
1348 /** 1344 /**
1349 * Get the log for a given log type. Log buffer is reset after each request. 1345 * Get the log for a given log type. Log buffer is reset after each request.
1350 * Each log entry is a [Map] with these fields: 1346 * Each log entry is a [Map] with these fields:
1351 * 1347 *
1352 * 'timestamp' (int) - The timestamp of the entry. 1348 * 'timestamp' (int) - The timestamp of the entry.
1353 * 'level' (String) - The log level of the entry, for example, "INFO". 1349 * 'level' (String) - The log level of the entry, for example, "INFO".
1354 * 'message' (String) - The log message. 1350 * 'message' (String) - The log message.
1355 */ 1351 */
1356 Future<List<Map>> getLogs(String type) => 1352 Future<List<Map>> getLogs(String type) => _post('log', { 'type': type });
1357 _post('log', params: { 'type': type });
1358 } 1353 }
OLDNEW
« no previous file with comments | « no previous file | pkg/webdriver/test/webdriver_test.dart » ('j') | pkg/webdriver/test/webdriver_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698