// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library webdriver;

import 'dart:async';
import 'dart:io';
import 'dart:json' as json;

part 'src/base64decoder.dart';

/**
 * WebDriver bindings for Dart.
 *
* ## Installing ##
 *
 * Use [pub][] to install this package. Add the following to your `pubspec.yaml`
 * file.
 *
 *     dependencies:
 *       webdriver: any
 *
 * Then run `pub install`.
 *
 * For more information, see the
 * [webdriver package on pub.dartlang.org][pkg].
 *
 * ## Using ##
 *
 * These bindings are based on the WebDriver JSON wire protocol spec
 * (http://code.google.com/p/selenium/wiki/JsonWireProtocol). Not
 * all of these commands are implemented yet by WebDriver itself.
 * Nontheless this is a complete implementation of the spec as the
 * unsupported commands may be supported in the future. Currently,
 * there are known issues with local and session storage, script
 * execution, and log access.
 *
 * To use these bindings, the Selenium standalone server must be running.
 * You can download it at http://code.google.com/p/selenium/downloads/list.
 *
 * There are a number of commands that use ids to access page elements.
 * These ids are not the HTML ids; they are opaque ids internal to
 * WebDriver. To get the id for an element you would first need to do
 * a search, get the results, and extract the WebDriver id from the returned
 * [Map] using the 'ELEMENT' key. For example:
 *
 *     String id;
 *     WebDriverSession session;
 *     Future f = web_driver.newSession('chrome');
 *     f.then((_session) {
 *       session = _session;
 *       return session.setUrl('http://my.web.site.com');
 *    }).then((_) {
 *      return session.findElement('id', 'username');
 *    }).then((element) {
 *      id = element['ELEMENT'];
 *      return session.sendKeyStrokesToElement(id,
 *          [ 'j', 'o', 'e', ' ', 'u', 's', 'e', 'r' ]);
 *    }).then((_) {
 *      return session.submit(id);
 *    }).then((_) {
 *      return session.close();
 *    }).then((_) {
 *      session = null;
 *    });
 *
 * [pub]: http://pub.dartlang.org
 * [pkg]: http://pub.dartlang.org/packages/webdriver
 */

void writeStringToFile(String fileName, String contents) {
  new File(fileName).writeAsStringSync(contents);
}

void writeBytesToFile(String fileName, List<int> contents) {
  new File(fileName).writeAsBytesSync(contents);
}

class WebDriverError {
  static List _errorTypes = null;
  static List _errorDetails = null;
  int statusCode;
  String type;
  String message;
  String details;
  String results;

  WebDriverError(this.statusCode, this.message, [this.results = '']) {
    /** These correspond to WebDrive exception types. */
    if (_errorTypes == null) {
      _errorTypes = [
        null,
        'IndexOutOfBounds',
        'NoCollection',
        'NoString',
        'NoStringLength',
        'NoStringWrapper',
        'NoSuchDriver',
        'NoSuchElement',
        'NoSuchFrame',
        'UnknownCommand',
        'ObsoleteElement',
        'ElementNotDisplayed',
        'InvalidElementState',
        'Unhandled',
        'Expected',
        'ElementNotSelectable',
        'NoSuchDocument',
        'UnexpectedJavascript',
        'NoScriptResult',
        'XPathLookup',
        'NoSuchCollection',
        'TimeOut',
        'NullPointer',
        'NoSuchWindow',
        'InvalidCookieDomain',
        'UnableToSetCookie',
        'UnexpectedAlertOpen',
        'NoAlertOpen',
        'ScriptTimeout',
        'InvalidElementCoordinates',
        'IMENotAvailable',
        'IMEEngineActivationFailed',
        'InvalidSelector',
        'SessionNotCreatedException',
        'MoveTargetOutOfBounds'
      ];
      // Explanations of the eror types. In thoses cases where the
      // explanation is the same as the type (e.g. NoCollection), that is an
      // error type used by an old version of the IE driver and is deprecated.
      _errorDetails = [
        null,
        'IndexOutOfBounds',
        'NoCollection',
        'NoString',
        'NoStringLength',
        'NoStringWrapper',
        'NoSuchDriver',
        'An element could not be located on the page using the given '
            'search parameters.',
        'A request to switch to a frame could not be satisfied because the '
            'frame could not be found.',
        'The requested resource could not be found, or a request was '
            'received using an HTTP method that is not supported by the '
            'mapped resource.',
        'An element command failed because the referenced element is no '
            'longer attached to the DOM.',
        'An element command could not be completed because the element '
            'is not visible on the page.',
        'An element command could not be completed because the element is in '
            'an invalid state (e.g. attempting to click a disabled element).',
        'An unknown server-side error occurred while processing the command.',
        'Expected',
        'An attempt was made to select an element that cannot be selected.',
        'NoSuchDocument',
        'An error occurred while executing user supplied JavaScript.',
        'NoScriptResult',
        'An error occurred while searching for an element by XPath.',
        'NoSuchCollection',
        'An operation did not complete before its timeout expired.',
        'NullPointer',
        'A request to switch to a different window could not be satisfied '
            'because the window could not be found.',
        'An illegal attempt was made to set a cookie under a different '
            'domain than the current page.',
        'A request to set a cookie\'s value could not be satisfied.',
        'A modal dialog was open, blocking this operation.',
        'An attempt was made to operate on a modal dialog when one was '
            'not open.',
        'A script did not complete before its timeout expired.',
        'The coordinates provided to an interactions operation are invalid.',
        'IME was not available.',
        'An IME engine could not be started.',
        'Argument was an invalid selector (e.g. XPath/CSS).',
        'A new session could not be created.',
        'Target provided for a move action is out of bounds.'
      ];
    }
    if (statusCode < 0 || statusCode > 32) {
      type = 'External';
      details = '';
    } else {
      type = _errorTypes[statusCode];
      details = _errorDetails[statusCode];
    }
  }

  String toString() {
    return '$statusCode $type: $message $results\n$details';
  }
}

/**
 * Base class for all WebDriver request classes. This class wraps up
 * an URL prefix (host, port, and initial path), and provides a client
 * function for doing HTTP requests with JSON payloads.
 */
class WebDriverBase {

  String _host;
  int _port;
  String _path;
  String _url;

  String get path => _path;
  String get url => _url;

  /**
   * The default URL for WebDriver remote server is
   * http://localhost:4444/wd/hub.
   */
  WebDriverBase.fromUrl([this._url = 'http://localhost:4444/wd/hub']) {
    // Break out the URL components.
    var re = new RegExp('[^:/]+://([^/]+)(/.*)');
    var matches = re.firstMatch(_url);
    _host = matches[1];
    _path = matches[2];
    var idx = _host.indexOf(':');
    if (idx >= 0) {
      _port = int.parse(_host.substring(idx+1));
      _host = _host.substring(0, idx);
    } else {
      _port = 80;
    }
  }

  WebDriverBase([
      this._host = 'localhost',
      this._port = 4444,
      this._path = '/wd/hub']) {
    _url = 'http://$_host:$_port$_path';
  }

  void _failRequest(Completer completer, error, [stackTrace]) {
    if (completer != null) {
      var trace = stackTrace != null ? stackTrace : getAttachedStackTrace(error);
      completer.completeError(new WebDriverError(-1, error), trace);
    }
  }

  /**
   * Execute a request to the WebDriver server. [http_method] should be
   * one of 'GET', 'POST', or 'DELETE'. [command] is the text to append
   * to the base URL path to get the full URL. [params] are the additional
   * parameters. If a [List] or [Map] they will be posted as JSON parameters.
   * If a number or string, "/params" is appended to the URL.
   */
  void _serverRequest(String http_method, String command, Completer completer,
                      {List successCodes, params, Function customHandler}) {
    var status = 0;
    var results = null;
    var message = null;
    if (successCodes == null) {
      successCodes = [ 200, 204 ];
    }
    try {
      var path = command;
      if (params != null) {
        if (params is num || params is String) {
          path = '$path/$params';
          params = null;
        } else if (http_method != 'POST') {
          throw new Exception(
            'The http method called for ${command} is ${http_method} but it '
            'must be POST if you want to pass the JSON params '
            '${json.stringify(params)}');
        }
      }

      var client = new HttpClient();
      client.open(http_method, _host, _port, path).then((req) {
        req.followRedirects = false;
        req.headers.add(HttpHeaders.ACCEPT, "application/json");
        req.headers.add(
            HttpHeaders.CONTENT_TYPE, 'application/json;charset=UTF-8');
        if (params != null) {
          var body = json.stringify(params);
          req.write(body);
        }
        req.close().then((rsp) {
          List<int> body = new List<int>();
          rsp.listen(body.addAll, onDone: () {
            var value = null;
            // For some reason we get a bunch of NULs on the end
            // of the text and the json.parse blows up on these, so
            // strip them.
            // These NULs can be seen in the TCP packet, so it is not
            // an issue with character encoding; it seems to be a bug
            // in WebDriver stack.
            results = new String.fromCharCodes(body)
                .replaceAll(new RegExp('\u{0}*\$'), '');
            if (!successCodes.contains(rsp.statusCode)) {
              _failRequest(completer, 
                  'Unexpected response ${rsp.statusCode}; $results');
              completer = null;
              return;
            }
            if (status == 0 && results.length > 0) {
              // 4xx responses send plain text; others send JSON.
              if (rsp.statusCode < 400) {
                results = json.parse(results);
                status = results['status'];
              }
              if (results is Map && (results as Map).containsKey('value')) {
                value = results['value'];
              }
              if (value is Map && value.containsKey('message')) {
                message = value['message'];
              }
            }
            if (status == 0) {
              if (customHandler != null) {
                customHandler(rsp, value);
              } else if (completer != null) {
                completer.complete(value);
              }
            }
          }, onError: (error) {
            _failRequest(completer, error);
            completer = null;
          });
        })
        .catchError((error) {
          _failRequest(completer, error);
          completer = null;
        });
      })
      .catchError((error) {
        _failRequest(completer, error);
        completer = null;
      });
    } catch (e, s) {
      _failRequest(completer, e, s);
      completer = null;
    }
  }

  Future _get(String extraPath,
      [Completer completer, Function customHandler]) {
    if (completer == null) completer = new Completer();
    _serverRequest('GET', '${_path}/$extraPath', completer,
        customHandler: customHandler);
    return completer.future;
  }

  Future _post(String extraPath, [params]) {
    var completer = new Completer();
    _serverRequest('POST', '${_path}/$extraPath', completer,
        params: params);
    return completer.future;
  }

  Future _delete(String extraPath) {
    var completer = new Completer();
    _serverRequest('DELETE', '${_path}/$extraPath', completer);
    return completer.future;
  }
}

class WebDriver extends WebDriverBase {

  WebDriver(host, port, path) : super(host, port, path);

  /**
   * Create a new session. The server will attempt to create a session that
   * most closely matches the desired and required capabilities. Required
   * capabilities have higher priority than desired capabilities and must be
   * set for the session to be created.
   *
   * The capabilities are:
   *
   * - browserName (String)  The name of the browser being used; should be one
   *   of chrome|firefox|htmlunit|internet explorer|iphone.
   *
   * - version (String) The browser version, or the empty string if unknown.
   *
   * - platform (String) A key specifying which platform the browser is
   *   running on. This value should be one of WINDOWS|XP|VISTA|MAC|LINUX|UNIX.
   *   When requesting a new session, the client may specify ANY to indicate
   *   any available platform may be used.
   *
   * - javascriptEnabled (bool) Whether the session supports executing user
   *   supplied JavaScript in the context of the current page.
   *
   * - takesScreenshot (bool) Whether the session supports taking screenshots
   *   of the current page.
   *
   * - handlesAlerts (bool) Whether the session can interact with modal popups,
   *   such as window.alert and window.confirm.
   *
   * - databaseEnabled (bool) Whether the session can interact database storage.
   *
   * - locationContextEnabled (bool) Whether the session can set and query the
   *   browser's location context.
   *
   * - applicationCacheEnabled (bool) Whether the session can interact with
   *   the application cache.
   *
   * - browserConnectionEnabled (bool) Whether the session can query for the
   *   browser's connectivity and disable it if desired.
   *
   * - cssSelectorsEnabled (bool) Whether the session supports CSS selectors
   *   when searching for elements.
   *
   * - webStorageEnabled (bool) Whether the session supports interactions with
   *   storage objects.
   *
   * - rotatable (bool) Whether the session can rotate the current page's
   *   current layout between portrait and landscape orientations (only applies
   *   to mobile platforms).
   *
   * - acceptSslCerts (bool) Whether the session should accept all SSL certs
   *   by default.
   *
   * - nativeEvents (bool) Whether the session is capable of generating native
   *   events when simulating user input.
   *
   * - proxy (proxy object) Details of any proxy to use. If no proxy is
   *   specified, whatever the system's current or default state is used.
   *
   * The format of the proxy object is:
   *
   * - proxyType (String) The type of proxy being used. Possible values are:
   *
   *   direct - A direct connection - no proxy in use,
   *
   *   manual - Manual proxy settings configured,
   *
   *   pac - Proxy autoconfiguration from a URL),
   *
   *   autodetect (proxy autodetection, probably with WPAD),
   *
   *   system - Use system settings
   *
   * - proxyAutoconfigUrl (String) Required if proxyType == pac, Ignored
   *   otherwise. Specifies the URL to be used for proxy autoconfiguration.
   *
   * - ftpProxy, httpProxy, sslProxy (String) (Optional, Ignored if
   *   proxyType != manual) Specifies the proxies to be used for FTP, HTTP
   *   and HTTPS requests respectively. Behaviour is undefined if a request
   *   is made, where the proxy for the particular protocol is undefined,
   *   if proxyType is manual.
   *
   * Potential Errors: SessionNotCreatedException (if a required capability
   * could not be set).
   */
  Future<WebDriverSession> newSession([
      browser = 'chrome', Map additional_capabilities]) {
    var completer = new Completer();
    if (additional_capabilities == null) {
      additional_capabilities = {};
    }

    additional_capabilities['browserName'] = browser;

    _serverRequest('POST', '${_path}/session', completer,
        successCodes: [ 302 ],
        customHandler: (r, v) {
          var url = r.headers.value(HttpHeaders.LOCATION);
          var session = new WebDriverSession.fromUrl(url);
          completer.complete(session);
        },
        params: { 'desiredCapabilities': additional_capabilities });
    return completer.future;
  }

  /** Get the set of currently active sessions. */
  Future<List<WebDriverSession>> getSessions() {
    var completer = new Completer();
    return _get('sessions', completer, (r, v) {
      var _sessions = [];
      for (var session in v) {
        var url = 'http://${this._host}:${this._port}${this._path}/'
            'session/${session["id"]}';
        _sessions.add(new WebDriverSession.fromUrl(url));
      }
      completer.complete(_sessions);
    });
  }

  /** Query the server's current status. */
  Future<Map> getStatus() => _get('status');
}

class WebDriverWindow extends WebDriverBase {
  WebDriverWindow.fromUrl(url) : super.fromUrl(url);

  /** Get the window size. */
  Future<Map> getSize() => _get('size');

  /**
   * Set the window size. Note that this is flaky and often
   * has no effect.
   *
   * Potential Errors:
   *   NoSuchWindow - If the specified window cannot be found.
   */
  Future<String> setSize(int width, int height) =>
      _post('size', { 'width': width, 'height': height });

  /** Get the window position. */
  Future<Map> getPosition() => _get('position');

  /**
   * Set the window position. Note that this is flaky and often
   * has no effect.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future setPosition(int x, int y) =>
      _post('position', { 'x': x, 'y': y });

  /** Maximize the specified window if not already maximized. */
  Future maximize() => _post('maximize');
}

class WebDriverSession extends WebDriverBase {
  WebDriverSession.fromUrl(url) : super.fromUrl(url);

  /** Close the session. */
  Future close() => _delete('');

  /** Get the session capabilities. See [newSession] for details. */
  Future<Map> getCapabilities() => _get('');

  /**
   * Configure the amount of time in milliseconds that a script can execute
   * for before it is aborted and a Timeout error is returned to the client.
   */
  Future setScriptTimeout(t) =>
      _post('timeouts', { 'type': 'script', 'ms': t });

  /*Future<String> setImplicitWaitTimeout(t) =>
      simplePost('timeouts', { 'type': 'implicit', 'ms': t });*/

  /**
   * Configure the amount of time in milliseconds that a page can load for
   * before it is aborted and a Timeout error is returned to the client.
   */
  Future setPageLoadTimeout(t) =>
      _post('timeouts', { 'type': 'page load', 'ms': t });

  /**
   * Set the amount of time, in milliseconds, that asynchronous scripts
   * executed by /session/:sessionId/execute_async are permitted to run
   * before they are aborted and a Timeout error is returned to the client.
   */
  Future setAsyncScriptTimeout(t) =>
      _post('timeouts/async_script', { 'ms': t });

  /**
   * Set the amount of time the driver should wait when searching for elements.
   * When searching for a single element, the driver should poll the page until
   * an element is found or the timeout expires, whichever occurs first. When
   * searching for multiple elements, the driver should poll the page until at
   * least one element is found or the timeout expires, at which point it should
   * return an empty list.
   *
   * If this command is never sent, the driver should default to an implicit
   * wait of 0ms.
   */
  Future setImplicitWaitTimeout(t) =>
      _post('timeouts/implicit_wait', { 'ms': t });

  /**
   * Retrieve the current window handle.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future<String> getWindowHandle() => _get('window_handle');

  /**
   * Retrieve a [WebDriverWindow] for the specified window. We don't
   * have to use a Future here but do so to be consistent.
   */
  Future<WebDriverWindow> getWindow([handle = 'current']) {
    var completer = new Completer();
    completer.complete(new WebDriverWindow.fromUrl('${_url}/window/$handle'));
    return completer.future;
  }

  /** Retrieve the list of all window handles available to the session. */
  Future<List<String>> getWindowHandles() => _get('window_handles');

  /**
   * Retrieve the URL of the current page.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future<String> getUrl() => _get('url');

  /**
   * Navigate to a new URL.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future setUrl(String url) => _post('url', { 'url': url });

  /**
   * Navigate forwards in the browser history, if possible.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future navigateForward() => _post('forward');

  /**
   * Navigate backwards in the browser history, if possible.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future navigateBack() => _post('back');

  /**
   * Refresh the current page.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future refresh() => _post('refresh');

  /**
   * Inject a snippet of JavaScript into the page for execution in the context
   * of the currently selected frame. The executed script is assumed to be
   * synchronous and the result of evaluating the script is returned to the
   * client.
   *
   * The script argument defines the script to execute in the form of a
   * function body. The value returned by that function will be returned to
   * the client. The function will be invoked with the provided args array
   * and the values may be accessed via the arguments object in the order
   * specified.
   *
   * Arguments may be any JSON-primitive, array, or JSON object. JSON objects
   * that define a WebElement reference will be converted to the corresponding
   * DOM element. Likewise, any WebElements in the script result will be
   * returned to the client as WebElement JSON objects.
   *
   * Potential Errors: NoSuchWindow, StaleElementReference, JavaScriptError.
   */
  Future execute(String script, [List args]) {
    if (args == null) args = [];
    return _post('execute', { 'script': script, 'args': args });
  }

  /**
   * Inject a snippet of JavaScript into the page for execution in the context
   * of the currently selected frame. The executed script is assumed to be
   * asynchronous and must signal that it is done by invoking the provided
   * callback, which is always provided as the final argument to the function.
   * The value to this callback will be returned to the client.
   *
   * Asynchronous script commands may not span page loads. If an unload event
   * is fired while waiting for a script result, an error should be returned
   * to the client.
   *
   * The script argument defines the script to execute in the form of a function
   * body. The function will be invoked with the provided args array and the
   * values may be accessed via the arguments object in the order specified.
   * The final argument will always be a callback function that must be invoked
   * to signal that the script has finished.
   *
   * Arguments may be any JSON-primitive, array, or JSON object. JSON objects
   * that define a WebElement reference will be converted to the corresponding
   * DOM element. Likewise, any WebElements in the script result will be
   * returned to the client as WebElement JSON objects.
   *
   * Potential Errors: NoSuchWindow, StaleElementReference, Timeout (controlled
   * by the [setAsyncScriptTimeout] command), JavaScriptError (if the script
   * callback is not invoked before the timout expires).
   */
  Future executeAsync(String script, [List args]) {
    if (args == null) args = [];
    return _post('execute_async', { 'script': script, 'args': args });
  }

  /**
   * Take a screenshot of the current page (PNG).
   *
   * Potential Errors: NoSuchWindow.
   */
  Future<List<int>> getScreenshot([fname]) {
    var completer = new Completer();
    return _get('screenshot', completer, (r, v) {
      var image = Base64Decoder.decode(v);
      if (fname != null) {
        writeBytesToFile(fname, image);
      }
      completer.complete(image);
    });
  }

  /**
   * List all available IME (Input Method Editor) engines on the machine.
   * To use an engine, it has to be present in this list.
   *
   * Potential Errors: ImeNotAvailableException.
   */
  Future<List<String>> getAvailableImeEngines() =>
      _get('ime/available_engines');

  /**
   * Get the name of the active IME engine. The name string is
   * platform specific.
   *
   * Potential Errors: ImeNotAvailableException.
   */
  Future<String> getActiveImeEngine() => _get('ime/active_engine');

  /**
   * Indicates whether IME input is active at the moment (not if
   * it's available).
   *
   * Potential Errors: ImeNotAvailableException.
   */
  Future<bool> getIsImeActive() => _get('ime/activated');

  /**
   * De-activates the currently-active IME engine.
   *
   * Potential Errors: ImeNotAvailableException.
   */
  Future deactivateIme() => _post('ime/deactivate');

  /**
   * Make an engine that is available (appears on the list returned by
   * getAvailableEngines) active. After this call, the engine will be added
   * to the list of engines loaded in the IME daemon and the input sent using
   * sendKeys will be converted by the active engine. Note that this is a
   * platform-independent method of activating IME (the platform-specific way
   * being using keyboard shortcuts).
   *
   * Potential Errors: ImeActivationFailedException, ImeNotAvailableException.
   */
  Future activateIme(String engine) =>
      _post('ime/activate', { 'engine': engine });

  /**
   * Change focus to another frame on the page. If the frame id is null,
   * the server should switch to the page's default content.
   * [id] is the Identifier for the frame to change focus to, and can be
   * a string, number, null, or JSON Object.
   *
   * Potential Errors: NoSuchWindow, NoSuchFrame.
   */
  Future setFrameFocus(id) => _post('frame', { 'id': id });

  /**
   * Change focus to another window. The window to change focus to may be
   * specified by [name], which is its server assigned window handle, or
   * the value of its name attribute.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future setWindowFocus(name) => _post('window', { 'name': name });

  /**
   * Close the current window.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future closeWindow() => _delete('window');

  /**
   * Retrieve all cookies visible to the current page.
   *
   * The returned List contains Maps with the following keys:
   *
   * 'name' - The name of the cookie.
   *
   * 'value' - The cookie value.
   *
   * The following keys may optionally be present:
   *
   * 'path' - The cookie path.
   *
   * 'domain' - The domain the cookie is visible to.
   *
   * 'secure' - Whether the cookie is a secure cookie.
   *
   * 'expiry' - When the cookie expires, seconds since midnight, 1/1/1970 UTC.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future<List<Map>> getCookies() => _get('cookie');

  /**
   * Set a cookie. If the cookie path is not specified, it should be set
   * to "/". Likewise, if the domain is omitted, it should default to the
   * current page's domain. See [getCookies] for the structure of a cookie
   * Map.
   */
  Future setCookie(Map cookie) => _post('cookie', { 'cookie': cookie });

  /**
   * Delete all cookies visible to the current page.
   *
   * Potential Errors: InvalidCookieDomain (the cookie's domain is not
   * visible from the current page), NoSuchWindow, UnableToSetCookie (if
   * attempting to set a cookie on a page that does not support cookies,
   * e.g. pages with mime-type text/plain).
   */
  Future deleteCookies() => _delete('cookie');

  /**
   * Delete the cookie with the given [name]. This command should be a no-op
   * if there is no such cookie visible to the current page.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future deleteCookie(String name) => _delete('cookie/$name');

  /**
   * Get the current page source.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future<String> getPageSource() => _get('source');

  /**
   * Get the current page title.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future<String> getPageTitle() => _get('title');

  /**
   * Search for an element on the page, starting from the document root. The
   * first matching located element will be returned as a WebElement JSON
   * object (a [Map] with an 'ELEMENT' key whose value should be used to
   * identify the element in further requests). The [strategy] should be
   * one of:
   *
   * 'class name' - Returns an element whose class name contains the search
   *    value; compound class names are not permitted.
   *
   * 'css selector' - Returns an element matching a CSS selector.
   *
   * 'id' - Returns an element whose ID attribute matches the search value.
   *
   * 'name' - Returns an element whose NAME attribute matches the search value.
   *
   * 'link text' - Returns an anchor element whose visible text matches the
   *   search value.
   *
   * 'partial link text' - Returns an anchor element whose visible text
   *   partially matches the search value.
   *
   * 'tag name' - Returns an element whose tag name matches the search value.
   *
   * 'xpath' - Returns an element matching an XPath expression.
   *
   * Potential Errors: NoSuchWindow, NoSuchElement, XPathLookupError (if
   * using XPath and the input expression is invalid).
   */
  Future<String> findElement(String strategy, String searchValue) =>
      _post('element', { 'using': strategy, 'value' : searchValue });

  /**
   * Search for multiple elements on the page, starting from the document root.
   * The located elements will be returned as WebElement JSON objects. See
   * [findElement] for the locator strategies that each server supports.
   * Elements are be returned in the order located in the DOM.
   *
   * Potential Errors: NoSuchWindow, XPathLookupError.
   */
  Future<List<String>> findElements(String strategy, String searchValue) =>
      _post('elements', { 'using': strategy, 'value' : searchValue });

  /**
   * Get the element on the page that currently has focus. The element will
   * be returned as a WebElement JSON object.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future<String> getElementWithFocus() => _post('element/active');

  /**
   * Search for an element on the page, starting from element with id [id].
   * The located element will be returned as WebElement JSON objects. See
   * [findElement] for the locator strategies that each server supports.
   *
   * Potential Errors: NoSuchWindow, XPathLookupError.
   */
  Future<String>
      findElementFromId(String id, String strategy, String searchValue) {
    _post('element/$id/element', { 'using': strategy, 'value' : searchValue });
  }

  /**
   * Search for multiple elements on the page, starting from the element with
   * id [id].The located elements will be returned as WebElement JSON objects.
   * See [findElement] for the locator strategies that each server supports.
   * Elements are be returned in the order located in the DOM.
   *
   * Potential Errors: NoSuchWindow, XPathLookupError.
   */
  Future<List<String>>
      findElementsFromId(String id, String strategy, String searchValue) =>
          _post('element/$id/elements',
              params: { 'using': strategy, 'value' : searchValue });

  /**
   * Click on an element specified by [id].
   *
   * Potential Errors: NoSuchWindow, StaleElementReference, ElementNotVisible
   * (if the referenced element is not visible on the page, either hidden
   * by CSS, or has 0-width or 0-height).
   */
  Future clickElement(String id) => _post('element/$id/click');

  /**
   * Submit a FORM element. The submit command may also be applied to any
   * element that is a descendant of a FORM element.
   *
   * Potential Errors: NoSuchWindow, StaleElementReference.
   */
  Future submit(String id) => _post('element/$id/submit');

  /** Returns the visible text for the element.
   *
   * Potential Errors: NoSuchWindow, StaleElementReference.
   */
  Future<String> getElementText(String id) => _get('element/$id/text');

  /**
   * Send a sequence of key strokes to an element.
   *
   * Any UTF-8 character may be specified, however, if the server does not
   * support native key events, it will simulate key strokes for a standard
   * US keyboard layout. The Unicode Private Use Area code points,
   * 0xE000-0xF8FF, are used to represent pressable, non-text keys:
   *
   * NULL - U+E000
   *
   * Cancel - U+E001
   *
   * Help - U+E002
   *
   * Backspace - U+E003
   *
   * Tab - U+E004
   *
   * Clear - U+E005
   *
   * Return - U+E006
   *
   * Enter - U+E007
   *
   * Shift - U+E008
   *
   * Control - U+E009
   *
   * Alt - U+E00A
   *
   * Pause - U+E00B
   *
   * Escape - U+E00C
   *
   * Space - U+E00D
   *
   * Pageup - U+E00E
   *
   * Pagedown - U+E00F
   *
   * End - U+E010
   *
   * Home - U+E011
   *
   * Left arrow - U+E012
   *
   * Up arrow - U+E013
   *
   * Right arrow - U+E014
   *
   * Down arrow - U+E015
   *
   * Insert - U+E016
   *
   * Delete - U+E017
   *
   * Semicolon - U+E018
   *
   * Equals - U+E019
   *
   * Numpad 0..9 - U+E01A..U+E023
   *
   * Multiply - U+E024
   *
   * Add - U+E025
   *
   * Separator - U+E026
   *
   * Subtract - U+E027
   *
   * Decimal - U+E028
   *
   * Divide - U+E029
   *
   * F1..F12 - U+E031..U+E03C
   *
   * Command/Meta U+E03D
   *
   * The server processes the key sequence as follows:
   *
   * - Each key that appears on the keyboard without requiring modifiers is
   *   sent as a keydown followed by a key up.
   *
   * - If the server does not support native events and must simulate key
   *   strokes with JavaScript, it will generate keydown, keypress, and keyup
   *   events, in that order. The keypress event is only fired when the
   *   corresponding key is for a printable character.
   *
   * - If a key requires a modifier key (e.g. "!" on a standard US keyboard),
   *   the sequence is: modifier down, key down, key up, modifier up, where
   *   key is the ideal unmodified key value (using the previous example,
   *   a "1").
   *
   * - Modifier keys (Ctrl, Shift, Alt, and Command/Meta) are assumed to be
   *  "sticky"; each modifier is held down (e.g. only a keydown event) until
   *   either the modifier is encountered again in the sequence, or the NULL
   *   (U+E000) key is encountered.
   *
   * - Each key sequence is terminated with an implicit NULL key.
   *   Subsequently, all depressed modifier keys are released (with
   *   corresponding keyup events) at the end of the sequence.
   *
   * Potential Errors: NoSuchWindow, StaleElementReference, ElementNotVisible.
   */
  Future sendKeyStrokesToElement(String id, List<String> keys) =>
      _post('element/$id/value', { 'value': keys });

  /**
   * Send a sequence of key strokes to the active element. This command is
   * similar to [sendKeyStrokesToElement] command in every aspect except the
   * implicit termination: The modifiers are not released at the end of the
   * call. Rather, the state of the modifier keys is kept between calls,
   * so mouse interactions can be performed while modifier keys are depressed.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future sendKeyStrokes(List<String> keys) => _post('keys', { 'value': keys });

  /**
   * Query for an element's tag name, as a lower-case string.
   *
   * Potential Errors: NoSuchWindow, StaleElementReference.
   */
  Future<String> getElementTagName(String id) => _get('element/$id/name');

  /**
   * Clear a TEXTAREA or text INPUT element's value.
   *
   * Potential Errors: NoSuchWindow, StaleElementReference, ElementNotVisible,
   * InvalidElementState.
   */
  Future clearValue(String id) => _post('/element/$id/clear');

  /**
   * Determine if an OPTION element, or an INPUT element of type checkbox
   * or radiobutton is currently selected.
   *
   * Potential Errors: NoSuchWindow, StaleElementReference.
   */
  Future<bool> isSelected(String id) => _get('element/$id/selected');

  /**
   * Determine if an element is currently enabled.
   *
   * Potential Errors: NoSuchWindow, StaleElementReference.
   */
  Future<bool> isEnabled(String id) => _get('element/$id/enabled');

  /**
   * Get the value of an element's attribute, or null if it has no such
   * attribute.
   *
   * Potential Errors: NoSuchWindow, StaleElementReference.
   */
  Future<String> getAttribute(String id, String attribute) =>
      _get('element/$id/attribute/$attribute');

  /**
   * Test if two element IDs refer to the same DOM element.
   *
   * Potential Errors: NoSuchWindow, StaleElementReference.
   */
  Future<bool> areSameElement(String id, String other) =>
      _get('element/$id/equals/$other');

  /**
   * Determine if an element is currently displayed.
   *
   * Potential Errors: NoSuchWindow, StaleElementReference.
   */
  Future<bool> isDiplayed(String id) => _get('element/$id/displayed');

  /**
   * Determine an element's location on the page. The point (0, 0) refers to
   * the upper-left corner of the page. The element's coordinates are returned
   * as a [Map] object with x and y properties.
   *
   * Potential Errors: NoSuchWindow, StaleElementReference.
   */
  Future<Map> getElementLocation(String id) => _get('element/$id/location');

  /**
   * Determine an element's size in pixels. The size will be returned as a
   * [Map] object with width and height properties.
   *
   * Potential Errors: NoSuchWindow, StalElementReference.
   */
  Future<Map> getElementSize(String id) => _get('element/$id/size');

  /**
   * Query the value of an element's computed CSS property. The CSS property
   * to query should be specified using the CSS property name, not the
   * JavaScript property name (e.g. background-color instead of
   * backgroundColor).
   *
   * Potential Errors: NoSuchWindow, StaleElementReference.
   */
  Future<String> getElementCssProperty(String id, String property) =>
      _get('element/$id/css/$property');

  /**
   * Get the current browser orientation ('LANDSCAPE' or 'PORTRAIT').
   *
   * Potential Errors: NoSuchWindow.
   */
  Future<String> getBrowserOrientation() => _get('orientation');

  /**
   * Gets the text of the currently displayed JavaScript alert(), confirm(),
   * or prompt() dialog.
   *
   * Potential Errors: NoAlertPresent.
   */
  Future<String> getAlertText() => _get('alert_text');

  /**
   * Sends keystrokes to a JavaScript prompt() dialog.
   *
   * Potential Errors: NoAlertPresent.
   */
  Future sendKeyStrokesToPrompt(String text) =>
      _post('alert_text', { 'text': text });

  /**
   * Accepts the currently displayed alert dialog. Usually, this is equivalent
   * to clicking on the 'OK' button in the dialog.
   *
   * Potential Errors: NoAlertPresent.
   */
  Future acceptAlert() => _post('accept_alert');

  /**
   * Dismisses the currently displayed alert dialog. For confirm() and prompt()
   * dialogs, this is equivalent to clicking the 'Cancel' button. For alert()
   * dialogs, this is equivalent to clicking the 'OK' button.
   *
   * Potential Errors: NoAlertPresent.
   */
  Future dismissAlert() => _post('dismiss_alert');

  /**
   * Move the mouse by an offset of the specificed element. If no element is
   * specified, the move is relative to the current mouse cursor. If an
   * element is provided but no offset, the mouse will be moved to the center
   * of the element. If the element is not visible, it will be scrolled
   * into view.
   */
  Future moveTo(String id, int x, int y) =>
      _post('moveto', { 'element': id, 'xoffset': x, 'yoffset' : y});

  /**
   * Click a mouse button (at the coordinates set by the last [moveTo] command).
   * Note that calling this command after calling [buttonDown] and before
   * calling [buttonUp] (or any out-of-order interactions sequence) will yield
   * undefined behaviour).
   *
   * [button] should be 0 for left, 1 for middle, or 2 for right.
   */
  Future clickMouse([button = 0]) => _post('click', { 'button' : button });

  /**
   * Click and hold the left mouse button (at the coordinates set by the last
   * [moveTo] command). Note that the next mouse-related command that should
   * follow is [buttonDown]. Any other mouse command (such as [click] or
   * another call to [buttonDown]) will yield undefined behaviour.
   *
   * [button] should be 0 for left, 1 for middle, or 2 for right.
   */
  Future buttonDown([button = 0]) => _post('click', { 'button' : button });

  /**
   * Releases the mouse button previously held (where the mouse is currently
   * at). Must be called once for every [buttonDown] command issued. See the
   * note in [click] and [buttonDown] about implications of out-of-order
   * commands.
   *
   * [button] should be 0 for left, 1 for middle, or 2 for right.
   */
  Future buttonUp([button = 0]) => _post('click', { 'button' : button });

  /** Double-clicks at the current mouse coordinates (set by [moveTo]). */
  Future doubleClick() => _post('doubleclick');

  /** Single tap on the touch enabled device on the element with id [id]. */
  Future touchClick(String id) => _post('touch/click', { 'element': id });

  /** Finger down on the screen. */
  Future touchDown(int x, int y) => _post('touch/down', { 'x': x, 'y': y });

  /** Finger up on the screen. */
  Future touchUp(int x, int y) => _post('touch/up', { 'x': x, 'y': y }); 

  /** Finger move on the screen. */
  Future touchMove(int x, int y) => _post('touch/move', { 'x': x, 'y': y });

  /**
   * Scroll on the touch screen using finger based motion events. If [id] is
   * specified, scrolling will start at a particular screen location.
   */
  Future touchScroll(int xOffset, int yOffset, [String id = null]) {
    if (id == null) {
      return _post('touch/scroll', { 'xoffset': xOffset, 'yoffset': yOffset });
    } else {
      return _post('touch/scroll',
          { 'element': id, 'xoffset': xOffset, 'yoffset': yOffset });
    }
  }

  /** Double tap on the touch screen using finger motion events. */
  Future touchDoubleClick(String id) =>
      _post('touch/doubleclick', { 'element': id });

  /** Long press on the touch screen using finger motion events. */
  Future touchLongClick(String id) =>
      _post('touch/longclick', { 'element': id });

  /**
   * Flick on the touch screen using finger based motion events, starting
   * at a particular screen location. [speed] is in pixels-per-second.
   */
  Future touchFlickFrom(String id, int xOffset, int yOffset, int speed) =>
          _post('touch/flick',
              { 'element': id, 'xoffset': xOffset, 'yoffset': yOffset,
                        'speed': speed });

  /**
   * Flick on the touch screen using finger based motion events. Use this
   * instead of [touchFlickFrom] if you don'tr care where the flick starts.
   */
  Future touchFlick(int xSpeed, int ySpeed) =>
      _post('touch/flick', { 'xSpeed': xSpeed, 'ySpeed': ySpeed });

  /**
   * Get the current geo location. Returns a [Map] with latitude,
   * longitude and altitude properties.
   */
  Future<Map> getGeolocation() => _get('location');

  /** Set the current geo location. */
  Future setLocation(double latitude, double longitude, double altitude) =>
          _post('location',
              { 'latitude': latitude,
                'longitude': longitude,
                'altitude': altitude });

  /**
   * Only a few drivers actually support the JSON storage commands.
   * Currently it looks like this is the Android and iPhone drivers only.
   * For the rest, we can achieve a similar effect with Javascript
   * execution. The flag below is used to control whether to do this.
   */
  bool useJavascriptForStorageAPIs = true;

  /**
   * Get all keys of the local storage. Completes with [null] if there
   * are no keys or the keys could not be retrieved.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future<List<String>> getLocalStorageKeys() {
    if (useJavascriptForStorageAPIs) {
      return execute(
          'var rtn = [];'
          'for (var i = 0; i < window.localStorage.length; i++)'
          '  rtn.push(window.localStorage.key(i));'
          'return rtn;'); 
    } else {
      return _get('local_storage');
    }
  }

  /**
   * Set the local storage item for the given key.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future setLocalStorageItem(String key, String value) {
    if (useJavascriptForStorageAPIs) {
      return execute('window.localStorage.setItem(arguments[0], arguments[1]);',
          [key, value]); 
    } else {
      return _post('local_storage', { 'key': key, 'value': value });
    }
  }

  /**
   * Clear the local storage.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future clearLocalStorage() {
    if (useJavascriptForStorageAPIs) {
      return execute('return window.localStorage.clear();');
    } else {
      return _delete('local_storage');
    }
  }

  /**
   * Get the local storage item for the given key.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future<String> getLocalStorageValue(String key) {
    if (useJavascriptForStorageAPIs) {
      return execute('return window.localStorage.getItem(arguments[0]);',
          [key]); 
    } else {
      return _get('local_storage/key/$key');
    }
  }

  /**
   * Delete the local storage item for the given key.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future deleteLocalStorageValue(String key) {
    if (useJavascriptForStorageAPIs) {
      return execute('return window.localStorage.removeItem(arguments[0]);',
          [key]); 
    } else {
      return _delete('local_storage/key/$key');
    }
  }

  /**
   * Get the number of items in the local storage.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future<int> getLocalStorageCount() {
    if (useJavascriptForStorageAPIs) {
      return execute('return window.localStorage.length;'); 
    } else {
      return _get('local_storage/size');
    }
  }

  /**
   * Get all keys of the session storage.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future<List<String>> getSessionStorageKeys() {
    if (useJavascriptForStorageAPIs) {
      return execute(
          'var rtn = [];'
          'for (var i = 0; i < window.sessionStorage.length; i++)'
          '  rtn.push(window.sessionStorage.key(i));'
          'return rtn;'); 
    } else {
      return _get('session_storage');
    }
  }

  /**
   * Set the sessionstorage item for the given key.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future setSessionStorageItem(String key, String value) {
    if (useJavascriptForStorageAPIs) {
      return execute(
          'window.sessionStorage.setItem(arguments[0], arguments[1]);',
              [key, value]); 
    } else {
      return _post('session_storage', { 'key': key, 'value': value });
    }
  }

  /**
   * Clear the session storage.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future clearSessionStorage() {
    if (useJavascriptForStorageAPIs) {
      return execute('window.sessionStorage.clear();');
    } else {
      return _delete('session_storage');
    }
  }

  /**
   * Get the session storage item for the given key.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future<String> getSessionStorageValue(String key) {
    if (useJavascriptForStorageAPIs) {
      return execute('return window.sessionStorage.getItem(arguments[0]);',
          [key]); 
    } else {
      return _get('session_storage/key/$key');
    }
  }

  /**
   * Delete the session storage item for the given key.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future deleteSessionStorageValue(String key) {
    if (useJavascriptForStorageAPIs) {
      return execute('return window.sessionStorage.removeItem(arguments[0]);',
          [key]); 
    } else {
      return _delete('session_storage/key/$key');
    }
  }

  /**
   * Get the number of items in the session storage.
   *
   * Potential Errors: NoSuchWindow.
   */
  Future<String> getSessionStorageCount() {
    if (useJavascriptForStorageAPIs) {
      return execute('return window.sessionStorage.length;');
    } else {
      return _get('session_storage/size');
    }
  }

  /**
   * Get available log types ('client', 'driver', 'browser', 'server').
   * This works with Firefox but Chrome returns a 500 response due to a 
   * bad cast.
   */
  Future<List<String>> getLogTypes() => _get('log/types');

  /**
   * Get the log for a given log type. Log buffer is reset after each request.
   * Each log entry is a [Map] with these fields:
   *
   * 'timestamp' (int) - The timestamp of the entry.
   * 'level' (String) - The log level of the entry, for example, "INFO".
   * 'message' (String) - The log message.
   *
   * This works with Firefox but Chrome returns a 500 response due to a 
   * bad cast.
   */
  Future<List<Map>> getLogs(String type) => _post('log', { 'type': type });
}
