Abstract

This specification defines the WebDriver API, a platform and language-neutral interface and associated wire protocol that allows programs or scripts to introspect into, and control the behaviour of, a web browser. The WebDriver API is primarily intended to allow developers to write tests that automate a browser from a separate controlling process, but may also be implemented in such a way as to allow in-browser scripts to control a — possibly separate — browser.

The WebDriver API is defined by a wire protocol and a set of interfaces to discover and manipulate DOM elements on a page, and to control the behaviour of the containing browser.

This specification also includes a normative reference serialisation (to JSON over HTTP) of the interface's invocations and responses that are to be used by browser vendors to ensure interoperability.

Status of This Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

If you wish to make comments regarding this document, please email feedback to public-browser-tools-testing@w3.org. All feedback is welcome, and the editors will read and consider all feedback.

This specification is intended for implementors of the WebDriver API. It is not intended as light bed time reading. This specification is still under active development and may not be stable. Any implementors who are not actively participating in the preparation of this specification may find unexpected changes occurring. It is suggested that any implementors join the WG for this specification. Despite not being stable, it should be noted that this specification is strongly based on an existing open source project — Selenium WebDriver — and the existing implementations of the API defined within that project.

This document was published by the Browser Testing and Tools Working Group as a Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-browser-tools-testing@w3.org (subscribe, archives). All comments are welcome.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 1 August 2014 W3C Process Document.

Table of Contents

1. Conformance

All diagrams, examples, and notes in this specification are non-normative, as are all sections explicitly marked non-normative. Everything else in this specification is normative.

The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in [RFC2119]. The key word “OPTIONALLY” in the normative parts of this document is to be interpreted with the same normative meaning as “MAY” and “OPTIONAL”.

Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the end result is equivalent.

2. Terminology

The terminology most used in this specification is from HTML, DOM, and CSS. [HTML] [DOM4] [CSS21] When the specification talks about elements, this is a reference to Element nodes in the Document Object Model, unless stated otherwise.

In equations, all numbers are integers, addition is represented by “+”, subtraction is represented by “−”, and bitwise OR by “|”. The characters “(” and “)” are used to provide logical grouping in these contexts.

An ASCII string is a string in the range U+0000 to U+007F, inclusive.

This specification defines four broad conformance classes:

Local End

This represents the client side of the protocol, which is usually in the form of language-specific libraries providing an API on top of the WebDriver protocol. This specification does not place any restrictions on the details of those libraries above the level of the wire protocol.

Issue 1

Define the requirements on the local end somewhere.

Remote End
The remote end hosts the server side of the protocol. Defining the behaviour of a remote end in response to the WebDriver protocol forms the largest part of this specification.
Intermediary Node
Intermediary nodes are those that act as proxies, implementing both the client and server sides of the protocol. Intermediary nodes must be black-box indistinguishable from a remote end from the point of view of local end and so are bound by the requirements on a remote end in terms of the wire protocol. However they are not expected to implement remote end steps directly.
Endpoint Node
An endpoint node is the final remote end in a chain of nodes that is not an intermediary node. The endpoint node is implemented by a user agent or a similar program. An endpoint node must be, like intermediary nodes, indistinguishable from a remote end.

3. The WebDriver Protocol

3.1 Introduction

Issue 2

TODO

3.2 Algorithms

Various parts of this specification are written in terms of step-by-step algorithms. The details of these algorithms do not have any normative significance; implementations are free to adopt any implementation strategy that produces equivalent output to the specification. In particular algorithms in this document are optimised for readability rather than performance.

Where algorithms that return values are fallible, they are written in terms of returning either success or error. A success value has an associated data field which encapsulates the value returned, whereas an error response has an associated error code.

The result of getting a property with name name from an [ECMA-262] Object object is defined as the result of calling the [[GetOwnProperty]] internal method of object with property name name.

3.3 Commands

The WebDriver protocol is organised into commands. Each HTTP request with a method and template defined in this specification represents a single command and therefore each command produces a single HTTP response. In response to a command, a remote end will run a series of actions against the remote browser.

Each command defined in this specification has an associated list of remote end steps. This provides the sequence of actions that a remote end takes when it recieves a particular command.

3.4 Processing Model

The remote end acts as a HTTP server reading requests from the client and writing responses, typically over TCP socket. For the purposes of this specification we model the data transmission between a particular local end and remote end with a connection to which the remote end may write bytes and read bytes. However the exact details of how this connection works and how it is established are out of scope.

After such a connection has been established, a remote end MUST run the following steps:

Issue 3

Should mention what happens if it can’t be decoded as HTTP. Note that Fetch isn’t quite right because it doesn’t specify how to construct a request from network data, or serialise a response.

  1. Read bytes from the connection until a complete HTTP request can be constructed from the data. Let request be a request object constructed from the received data, according to the requirements of [RFC7230].

  2. Let request match be the result of the algorithm to match a request with request’s method and url as arguments.

  3. If request match is of type error, send an error with request match’s error code and jump to step 1.

    Otherwise, let command, session id, and element id be request match’s data.

  4. If command is not New Session:

    1. If session id is not equal to the id of any session in the list of active sessions, send an error with error code invalid session id, then jump to step 1 in this overall algorithm.

      Otherwise, let the current session be the session with id session id.

  5. If request's method is POST:

    1. Let parse result be the result of parsing as JSON with request’s body as the argument.

    2. If parse result is an error or if it is a success but its associated data is not an Object object, send an error with error code invalid argument and jump back to step 1 in this overall algorithm.

      Otherwise, let parameters be parse result’s data.

    Otherwise, let parameters be null.

  6. Let response result be the return value obtained by running the remote end steps for command with arguments element id and parameters.

  7. If response result is an error, send an error with error code equal to response result’s error code.

    Otherwise, if response result is a success, let response data be response result’s data.

  8. Send a response with status 200 and response data.

  9. Jump to step 1.

When required to send an error, with error code, a remote end must run the following steps:

  1. Let http status and name be the error response data for error code.

  2. Let message be an implementation-defined string containing a human-readable description of the reason for the error.

  3. Let stacktrace be an implementation-defined string containing a stack trace report of the active stack frames at the time when the error occurred.

  4. Issue 4

    Really need a better way to construct JSON literals.

    Let data be a new JSON Object initialised with the following properties:

    "error"
    Value of name.
    "message"
    Value of message.
    "stacktrace"
    Value of stacktrace.
  5. Send a response with status and data as arguments.

When required to send a response, with arguments status and data, a remote end must run the following steps:

  1. Let response be a new response.

  2. Set response’s status to status, and status message to the string corresponding to the description of status in the status code registry.

  3. If data is not null, let response’s body be the result of serializing as JSON with data as the argument.

  4. Let response bytes be the byte sequence resulting from serializing response according to the rules in [RFC7230].

  5. Write response bytes to the connection.

3.5 Routing Requests

Request routing is the process of going from a HTTP request to the series of steps needed to implement the command represented by that request.

A remote end has an associated URL prefix, which is used as a prefix on all WebDriver-defined URLs on that remote end. This must either be the empty string, or an absolute path relative url.

Note

For example a remote end wishing to run alongside other services on example.com might set its url prefix to /wd so that a new session command would be invoked by sending a POST request to /wd/session, rather than /session.

In order to match a request given a method and url, the following steps must be taken:

  1. Let endpoints be a list containing each row in the table of endpoints.

  2. Remove each entry in endpoints for which the concatenation of the url prefix and the production in the "url" column does not match url according to the rules in [URI-Template].

  3. If there are no entries in endpoints, return error with error code unknown command.

  4. Remove each entry in endpoints for which the "method" column is not an exact case-sensitive match for method.

  5. If there are no entries in endpoints, return error with error code unknown method.

  6. There is now exactly one entry in endpoints; let entry be this entry.

  7. Issue 5

    Check that URI-templates is being used in the right way here:

    If the match in step 2 populated a template variable called "sessionId", let session id be the value it was populated with. Otherwise let session id be null.

  8. If the match in step 2 populated a template variable called "elementId", let element id be the value it was populated with. Otherwise let element id be null.

  9. If the match in step 2 populated a template variable called "name", let name be the value it was populated with. Otherwise let name be null.

  10. Let command be the command represented by the "command" column of entry.

  11. Return success with data session id, element id, and command.

3.6 List of Endpoints

The following table of endpoints lists the method, URL, and command for each WebDriver command.

Method URL Command
POST /session New Session
DELETE /session/{session id} Delete Session
POST /session/{session id}/url Get
GET /session/{session id}/url Get Current Url
POST /session/{session id}/back Back
POST /session/{session id}/forward Forward
POST /session/{session id}/refresh Refresh
GET /session/{session id}/title Get Title
GET /session/{session id}/window/handle Get Window Handle
GET /session/{session id}/window/handles Get Window Handles
DELETE /session/{session id}/window Close Window
POST /session/{session id}/window/size Set Window Size
GET /session/{session id}/window/size Get Window Size
POST /session/{session id}/window/maximize Maximize Window
POST /session/{session id}/window/fullscreen Fullscreen Window
POST /session/{session id}/window Switch To Window
POST /session/{session id}/frame Switch To Frame
POST /session/{session id}/frame/parent Switch To Parent Frame
POST /session/{session id}/element Find Element
POST /session/{session id}/elements Find Elements
GET /session/{session id}/element/{element id}/displayed Is Element Displayed
GET /session/{session id}/element/{element id}/selected Is Element Selected
GET /session/{session id}/element/{element id}/attribute/{name} Get Element Attribute
GET /session/{session id}/element/{element id}/css/{property name} Get Element CSS Value
GET /session/{session id}/element/{element id}/text Get Element Text
GET /session/{session id}/element/{element id}/name Get Element Tag Name
GET /session/{session id}/element/{element id}/rect Get Element Rect
GET /session/{session id}/element/{element id}/enabled Is Element Enabled
POST /session/{session id}/execute Execute Script
POST /session/{session id}/execute_async Execute Async Script
GET /session/{session id}/cookie/{name} Get Cookie
POST /session/{session id}/cookie Add Cookie
DELETE /session/{session id}/cookie/{name} Delete Cookie
POST /session/{session id}/timeouts Set Timeout
POST /session/{session id}/actions Actions
POST /session/{session id}/element/{element id}/click Element Click
POST /session/{session id}/element/{element id}/tap Element Tap
POST /session/{session id}/element/{element id}/clear Element Clear
POST /session/{session id}/element/{element id}/sendKeys Element Send Keys
POST /session/{session id}/dismiss_alert Dismiss Alert
POST /session/{session id}/alert/accept Accept Alert
GET /session/{session id}/alert/text Get Alert Text
POST /session/{session id}/alert/text Send Alert Text
GET /session/{session id}/screenshot Take Screenshot
GET /session/{session id}/element/{element id}/screenshot Take Element Screenshot

3.7 Handling Errors

Errors are represented in the WebDriver protocol with a HTTP response with a HTTP status in the 4xx or 5xx range, and a JSON body containing details of the error. This JSON body has three fields: error, containing a string indicating the error type; message, containing an implementation-defined string with a human readable description of the kind of error that occured; and stacktrace, containing an implementation-defined string with a stack trace report of the active stack frames at the time when the error occurred.

The following table lists each error code, its associated HTTP status, JSON error code, and a non-normative description of the error. The error response data for a particular error code is the values of the HTTP Status and JSON Error Code columns for the row corresponding to that error code.

Error Code HTTP Status JSON Error Code Description
element not selectable 400 element not selectable An attempt was made to select an element that cannot be selected.
element not visible 400 element not visible An element command could not be completed because the element is not visible on the page.
invalid argument 400 invalid argument The arguments passed to a command are either invalid or malformed.
invalid cookie domain 400 invalid cookie domain An illegal attempt was made to set a cookie under a different domain than the current page.
invalid element coordinates 400 invalid element coordinates The coordinates provided to an interactions operation are invalid.
invalid element state 400 invalid element state An element command could not be completed because the element is in an invalid state, e.g. attempting to click an element that is no longer attached to the document.
invalid selector 400 invalid selector Argument was an invalid selector.
invalid session id 404 invalid session id Occurs if the given session id is not in the list of active sessions, meaning the session either does not exist or that it’s not active.
javascript error 500 javascript error An error occurred while executing JavaScript supplied by the user.
move target out of bounds 500 move target out of bounds The target for mouse interaction is not in the browser’s viewport and cannot be brought into that viewport.
no such alert 400 no such alert An attempt was made to operate on a modal dialog when one was not open.
no such element 404 no such element An element could not be located on the page using the given search parameters.
no such frame 400 no such frame A request to switch to a frame could not be satisfied because the frame could not be found.
no such window 400 no such window A request to switch to a window could not be satisfied because the window could not be found.
script timeout 408 script timeout A script did not complete before its timeout expired.
session not created 500 session not created A new session could not be created.
stale element reference 400 stale element reference An element command failed because the referenced element is no longer attached to the DOM.
timeout 408 timeout An operation did not complete before its timeout expired.
unable to set cookie 500 unable to set cookie A request to set a cookie’s value could not be satisfied.
unexpected alert open 500 unexpected alert open A modal dialog was open, blocking this operation.
unknown command 404 unknown command A command could not be executed because the remote end is not aware of it.
unknown error 500 unknown error An unknown error occurred in the remote end while processing the command.
unknown method 405 unknown method The requested command matched a known URL but did not match an method for that URL.
unsupported operation 500 unsupported operation Indicates that a command that should have executed properly cannot be supported for some reason.

3.8 Protocol Extensions

The protocol is designed to allow extension to meet vendor-specific needs. Commands that are specific to a user agent are called extension commands and behave no differently than other commands; each has a dedicated HTTP endpoint and a set of remote end steps.

Each extension command has an associated extension command name that is a lowercased ASCII string, and which should bear some resemblance to what the command performs. The name is used to form an extension command’s URL.

The extension command’s extension command URL is a URL composed of the extension prefix, followed by "/", and the extension command’s name. The extension command URL, along with the HTTP method and extension command, is added to the table of endpoints and thus follows the same rules for request routing as that of other built-in commands.

The remote end’s extension prefix is a lowercased ASCII string that forms a URL path element, separating extension commands from other commands to avoid potential resource conflicts with other implementations. It is suggested that vendors use their vendor prefixes without additional characters as outlined in [CSS21], notably in section 4.1.2.2 on vendor keywords, as the name for this path element.

4. Capabilities

WebDriver capabilities allow the local end to specify what features it requires the remote end to fulfill to be able to create a new session.

Processing Capabilities

When processing capabilities with argument parameters a remote end must run the following steps:

  1. Let server capabilities be a JSON Object with the following entries:

    "browserName"
    The lowercase name of the user agent.
    "browserVersion"
    The version of the user agent.
    "platformName"
    The lowercase name of the platform.
    "platformVersion"
    The version of the platform.
    "acceptSslCerts"
    Be true if the User Agent can handle Invalid SSL Certifications else let it be false.
    "takesScreenshot"
    Be true if the User Agent can capture a screenshot of the viewport described in Take Screenshot.
    "takesElementScreenshot"
    Be true if the User Agent can capture a screenshot of an element as described in Take Element Screenshot.
  2. Let required capabilities be the result of getting a property name requiredCapabilities from capabilities. If required capabilities is not a JSON Object set the value to an empty JSON Object.

  3. Let desired capabilities be the result of getting a property name desiredCapabilities from capabilities. If desired capabilities is not a JSON Object set the value to an empty JSON Object.

  4. Let length be the length of required capabilities.

  5. Let k be 0.

  6. While k < length:

    1. Let capability be the entry in required capabilities at index k.

    2. If the name of the capability is among the names of entries in desired capabilities remove the corresponding entry from desired capabilities.

    3. Increase k by 1.
  7. Let unmet capabilities be equal to an empty JSON List.

  8. Let unprocessed capabilities be a JSON Object that contains all entries from required capabilities and all entries from desired capabilities.

  9. Let j be 0.

  10. Let capabilties length be the length of unprocessed capabilities.

  11. While j < capabilities length:

    1. Let unprocessed capability be the entry at index j in unprocessed capabilities.

    2. If during the steps below the unprocessed capability equals an entry in required capabilities and name of unprocessed capability entry among the names of entries in server capabilities and the values do not match do the following:

      1. Append a string containing the property name and the differences between the values.

    3. Let browser name be the result of getting a property named browserName from unprocessed capability. If browser name is undefined move to the next step.

    4. Let browser version be the result of getting a property named browserVersion from unprocessed capability. If browser version is undefined move to the next step.

    5. Let platform name be the result of getting a property named platformName from unprocessed capability. If platform name is undefined move to the next step.

    6. Let platform version be the result of getting a property named platformVersion from unprocessed capability. If platform version is undefined move to the next step.

    7. Let proxy be the result of getting a property named proxy from unprocessed capability. If proxy is undefined move to the next step. If proxy is defined and not a map append a string saying that a JSON Object is required else call set the proxy passing in proxy.

    8. Let page load strategy be the result of getting a property named pageLoadStrategy from unprocessed capability. If page load strategy is undefined then set the entry pageLoadStrategy in server capabilities to normal.

  12. If the length of unmet capabilities is not equal to 0 return session not created with data unmet capabilities.

  13. Return server capabilities.

To set the proxy from a JSON Object proxy:

  1. Let proxy type be the result of getting a property named proxyType from proxy.

  2. Switch on proxy type:

    "pac"

    If the implementation supports proxy autoconfiguration, set the implementation's autoproxy configuration url to proxy autoconfiguration url.

    Otherwise return an error with error code invalid argument.

    "noproxy"

    Set the proxy to No Proxy using implementation defined steps. If this can not be set during this process return an error.

    "autodetect"

    Set the proxy to Auto-Detect proxy setting from the network using implementation defined steps. If this can not be set during this process return error.

    "system"

    Set the proxy to use system proxy settings using implementation defined steps. If this can not be set during this process return error.

    "manual"
    1. Let ftp proxy be the result of getting a property named ftpProxy from proxy.

    2. Let ftp proxy port be the result of getting a property named ftpProxyPort from proxy.

    3. Let http proxy be the result of getting a property named httpProxy from proxy.

    4. Let http proxy port be the result of getting a property named httpProxyPort from proxy.

    5. Let ssl proxy be the result of getting a property named sslProxy from proxy.

    6. Let ssl proxy port be the result of getting a property named sslProxyPort from proxy.

    7. Let socks proxy be the result of getting a property named socksProxy from proxy.

    8. Let socks proxy port be the result of getting a property named socksProxyPort from proxy.

    9. If socks proxy and socks proxy port is defined:

      1. Let socks version be the result of getting a property named socksVersion from proxy.

      2. Let socks username be the result of getting a property named socksUsername from proxy.

      3. Let socks password be the result of getting a property named socksPassword from proxy.

    10. Follow implementation defined steps to set the proxy using defined variables from previous steps. If there are items that can not be set during this process return error.

    Otherwise

    Return error with error code invalid argument.

5. Sessions

A session is equivalent to a single instantiation of a particular user agent, including all its child browsers. WebDriver gives each session a unique session ID that can be used to differentiate one session from another, allowing multiple user agents to be controlled from a single HTTP server, and allowing sessions to be routed via a multiplexer (known as an intermediary node).

A session is started when a New Session is invoked. It is an error to send any commands before starting a session, or to continue to send commands after the session has been closed. Maintaining session continuity between requests to the remote end requires passing a session ID.

A WebDriver session represents the connection between a local end and a specific remote end. A remote end that is not an intermediary node has at most one active session at a given time.

Issue 6

Need to explain that there must be a relationship between the current session and the browser state.

The session is set up at the invocation of a new session, and torn down at some later point; either explicitly by invoking quit, or implicitly when close is called at the last remaining top-level browsing context.

A remote end has an associated list of active sessions, which is a list of all sessions that are currently started.

Requests, except New Session requests, have an associated current session, which is the session in which that request's command will run.

A remote end has an associated maximum active sessions (an integer) that defines the number of active sessions that are supported. This may be “unlimited” for intermediary nodes, but must be exactly one for a remote end that is an endpoint node.

A session has an associated session ID (a UUID) used to uniquely identify this session. Unless stated otherwise it is null.

A session has an associated current browsing context, which is the browsing context against which commands will run.

A session has an associated current top-level browsing context, which is the current browsing context if it itself is a top-level browsing context, or the top-level browsing context for which the current browsing context is an ancestor browsing context.

The top-level browsing context is said to be no longer open if it has been discarded.

Each top-level browsing context has an associated window handle, which is a string uniquely identifying that browsing context. This string is implementation defined but MUST not be "current".

A session has an associated session script timeout that specifies a time to wait for scripts to run. Unless stated otherwise it is 30,000 milliseconds.

A session has an associated session page load timeout that specifies a time to wait for the page loading to complete. Unless stated otherwise it is 300,000 milliseconds.

A session has an associated session implicit wait timeout that specifies a time to wait for the implicit element location strategy when locating elements using find element and find elements. Unless stated otherwise it is zero milliseconds.

A session has an associated page loading strategy, which is one of none, normal, and eager. Unless stated otherwise, it is normal.

When asked to close the session, a remote end must take the following steps:

  1. Set the webdriver-active flag to false.

  2. Close any top-level browsing contexts associated with the session, without prompting to unload.

  3. Remove the current session from active sessions.

  4. Perform any implementation-specific cleanup steps.

    Note

    For example, closing the session might cause the associated browser process to be killed. It is assumed that these steps are performed after the response has been sent back to the client so that the connection is not prematurely closed.

5.1 New Session

HTTP Method Path Template
POST /session

The remote end steps for the New Session command are:

  1. If the node is an intermediate node, take implementation-defined steps that either result in returning an error with error code session not created or in returning a success with data that is isomorphic to that returned by remote ends according to the rest of this algorithm.

    Note

    This allows intermediary nodes to use the capabilities data in any way they want e.g. to select a specific browser to test based on a combination of the required and desired capabilities. Typically the new session response from the remote end selected in this process will then be relayed directly to the client.

  2. If the maximum active sessions is equal to the length of the list of active sessions:

    1. Return error with error code unsupported operation.

  3. Let capabilities be the result of getting a property named "capabilities" from the parameters argument.

  4. Let resultant capabilities be the result of processing capabilities with capabilities as an argument. If the result is an error, return error with the code session not created.

  5. Let session id be the result of generating a UUID.

  6. Let session be a new session with the session ID of session id.

  7. Set the current session to session.

  8. Append session to active sessions.

  9. Let data be an empty JSON Object initialised with:

    "sessionId"
    The value of session id.
    "capabilities"
    The value of resultant capabilities.
  10. Initialise the following if not set while processing capabilities:

    1. Set the current session’s session script timeout to 30,000 milliseconds.

    2. Set the current session’s session page load timeout to 300,000 milliseconds.

    3. Set the current session’s session implicit wait timeout to 0 (zero) milliseconds.

    4. Set the current session’s page loading strategy to normal.

    5. Set the webdriver-active flag to true.

  11. Return success with data data.

5.2 Delete Session

HTTP Method Path Template
DELETE /session/{session id}

The Delete Session command closes any top-level browsing contexts associated with the current session, terminates the connection, and finally closes the current session.

The remote end steps are:

  1. Close the session.

  2. Return success with data null.

5.3 Set Timeout

HTTP Method Path Template
POST /session/{session id}/timeouts

The Set Timeout command sets timeouts associated with the current session. The timeouts that can be controlled are the session script timeout, the session page load timeout, and the session implicit wait timeout.

The following table of session timeouts lists pairs of different timeouts that may be changed with the string codes used to identify them:

Type Identifier
session script timeout "script"
session page load timeout "page load"
session implicit wait timeout "implicit"

The remote end steps for the Set Timeout command are:

  1. For each row in the table of session timeouts, enumerated as type and identifier:

    1. If parameters does not have an own property identifier, continue to the next entry.

    2. Let timeout be the result of getting a property using identifier from parameters.

    3. If timeout is of the Number type and a non-negative integer, set the type timeout to timeout’s value in milliseconds.

      Otherwise, return error with error code invalid argument.

  2. Return success.

7. Invalid SSL Certificates

Capability NameType
secureSslboolean

WebDriver implementations MUST support users accessing sites served via HTTPS. Access to those sites using self-signed or invalid certificates, and where the certificate does not match the serving domain MUST be the same as if the HTTPS was configured properly.

Note

The reason for this is that implementations of this spec are often used for testing. It's a sorry fact that many QA engineers and testers are asked to verify that apps work on sites that have insecure HTTPS configurations

The exception to requirement is if the Capabilities used to initialize has the WebDriver session had the capability secureSsl set to true. In this case, implementations MAY choose to make accessing a site with bad HTTPS configurations cause a WebDriverException to be thrown. Remote end implementations MUST return an unknown error status in this case. If this is the case, the Capabilities describing the session MUST also set the secureSsl capability to "true".

8. Command Contexts

Many WebDriver commands happen in the context of either the current browsing context or current top-level browsing context. The current top-level browsing context is represented in the protocol by its associated window handle. A top-level browsing context is selected using the Switch To Window command. Once this is done, a specific browsing context can be selected using the Switch to Frame command.

Note

The use of the term “window” to refer to a top-level browsing context is legacy and doesn’t correspond with either the operating system notaion of a “window” or the DOM Window object.

Note

In accordance with the focus section of the [html51] specification, commands are unaffected by whether the operating system window has focus or not.

8.1 Get Window Handle

HTTP Method Path Template
GET /session/{session id}/window_handle

The Get Window Handle command returns the window handle for the current top-level browsing context. It can be used as an argument to Switch To Window.

The remote end steps are:

  1. If the current top-level browsing context is no longer open, return error with error code no such window.

  2. Let data be a new JSON Object.

  3. Set the property "value" on data to the value of the window handle associated with the current top-level browsing context.

  4. Return success with data data.

8.2 Get Window Handles

HTTP Method Path Template
GET /session/{session id}/window_handles

The Get Window Handles command returns a list of window handles for every open top-level browsing context. The order in which the window handles are returned is arbitary.

The remote end steps are:

  1. Let data be a new JSON Object.

  2. Let value be a JSON List.

  3. For each top-level browsing context in the remote end, push the associated window handle to value.

  4. Set the property "value" on data to value.

  5. Return success with data data.
Note

In order to determine whether or not a particular interaction with the browser opens a new window one can obtain the set of window handle before the interaction is performed and compare it with the set after the action is performed.

8.3 Switch To Window

HTTP Method Path Template
POST /session/{session id}/window

The Switch To Window command is used to select the current top-level browsing context for the current session, i.e. the one that will be used for processing commands.

The remote end steps are:

  1. Let handle be the result of getting a property named "handle" from the parameters argument.

  2. If handle is equal to the associated window handle for some top-level browsing context in the current session, set the session's current top-level browsing context to that browsing context, and return success with data null.

  3. Otherwise, return error with error code no such window.

8.3.1 Close Window

HTTP Method Path Template
DELETE /session/{session id}/window

The remote end steps for the Close Window command are:

  1. If the current top-level browsing context is no longer open, return error with error code no such window.

  2. Close the current top-level browsing context.

  3. If there are no more open top-level browsing contexts, then close the session.

  4. Return the result of running the remote end steps for the Get Window Handles command.

8.3.2 Switch To Frame

HTTP Method Path Template
POST /session/{session id}/frame

The Switch To Frame command is used to select the current top-level browsing context or a child browsing context of the current browsing context to use as the current browsing context for subsequent commands.

The remote end steps are:

  1. If the current browsing context is no longer open, return error with error code no such window.

  2. Let id be the result of getting a property named "id" from the parameters argument.

  3. Run the substeps of the first matching condition:

    id is null
    1. Set the current browsing context to the current top-level browsing context.

    id is a Number object
    1. If id is less than 0 or greater than 216 – 1, return error with error code no such frame.

    2. Let window be the associated window of the current browsing context’s active document.

    3. If id is not a supported property index of window, return error with error code no such frame.

    4. Let child window be the WindowProxy object obtained by determining the value of an indexed property of window with index id.

    5. Set the current browsing context to new window’s browsing context.

    id represents a web element
    1. Issue 13

      Note that representing a web element will have to do the same document checks, or something.

      Let element be the element represented by id.

    2. If element is not a frame or iframe element, return error with error code no such frame.

    3. Set the current browsing context to element’s nested browsing context.

    Otherwise
    1. Return error with error code no such frame.

  4. Return success with data null.

Note

WebDriver is not bound by the same origin policy, so it is always possible to switch into child browsing contexts, even if they are different origin to the current browsing context.

8.3.3 Switch to Parent Frame

HTTP Method Path Template
POST /session/{session id}/frame/parent

The Switch to Parent Frame command sets the current browsing context for future commands to the parent of the current browsing context.

The remote end steps for Switch to Parent Frame are:

  1. If the current browsing context is no longer open, return error with error code no such window.

  2. If the current browsing context is not equal to the current top-level browsing context, set the current browsing context to the parent browsing context of the current browsing context.

  3. Return success with data null.

8.4 Resizing and Positioning Windows

WebDriver provides commands for interacting with the operating system window containing the current browsing context. Because different operating system's window managers provide different abilities, not all of the commands in this section can be supported by all remote ends. Where a command is not supported, an unsupported operation error is returned.

8.4.1 Get Window Size

HTTP Method Path Template
GET /session/{sessionId}/window/size

The Get Window Size command returns the size of the operating system window corresponding to the current top-level browsing context.

The remote end steps are:

  1. Issue 14

    Can this whole operation be unsupported?

    If the current top-level browsing context is no longer open, return error with error code no such window.

  2. Let width be the width in CSS reference pixels of the operating system window containing the current top-level browsing context, including any browser chrome and externally drawn window decorations.

  3. Let height be the height in CSS reference pixels of the operating system window containing the current top-level browsing context, including any browser chrome and any externally drawn window decorations.

  4. Let body be a new JSON Object initialised with:

    "width"
    The value of width.
    "height"
    The value of height.
  5. Return success with data body.

Note

In some browsers the dimensions of the browser including window decorations are provided by the proprietary window.outerWidth and window.outerHeight properties.

8.4.2 Set Window Size

HTTP Method Path Template
POST /session/{session id}/window/size

The Set Window Size command alters the size of the operating system window corresponding to the current top-level browsing context.

The remote end steps are:

  1. If the current top-level browsing context is no longer open, return error with error code no such window.

  2. If the remote end does not support the Set Window Size command for the current top-level browsing context for any reason, return error with error code unsupported operation.

  3. Let width be the result of getting a property named width from the parameters argument.

  4. If width is not an integer, or is less than 0, return error with error code invalid argument.

  5. Let height be the result of getting a property named height from the parameters argument.

  6. If height is not an integer, or is less than 0, return error with error code invalid argument.

    Issue 15

    Window sizes outside the allowed range.

  7. Set the width, in CSS reference pixels, of the operating system window containing the current top-level browsing context, including any browser chrome and externally drawn window decorations to a value that is as close as possible to width.

  8. Set the height, in CSS reference pixels, of the operating system window containing the current top-level browsing context, including any browser chrome and externally drawn window decorations to a value that is as close as possible to height.

  9. Return success with data null.

Note

The specification does not guarantee that the resulting window size will exactly match that which was requested. In particular the implementation is expected to clamp values that are larger than the physical screen dimensions, or smaller than the minimum window size. Particular implemetations may have other limitations such as not being able to resize in single-pixel increments.

8.4.3 Maximize Window

HTTP Method Path Template
POST /session/{session id}/window/maximize

The Maximize Window command invokes the window manager-specific “maximize” operation, if any, on the window containing the current top-level browsing context. This typically increases the window to the maximum available size without going full-screen.

The remote end steps are:

  1. If the current top-level browsing context is no longer open, return error with error code no such window.

  2. If the remote end does not support the Maximize Window command for the current top-level browsing context for any reason, return error with error code unsupported operation.

  3. Run the implementation-specific steps to increase the dimensions of the operating system level window containing the current top-level browsing context to the maximum available size allowed by the window manager.

  4. Return success with data null.

8.4.4 Fullscreen Window

HTTP Method Path Template
POST /session/{session id}/window/fullscreen

The Fullscreen Window command invokes the window manager-specific “full screen” operation, if any, on the window containing the current top-level browsing context. This typically increases the window to the size of the physical display and can hide browser UI elements such as toolbars.

The remote end steps are:

  1. If the current top-level browsing context is no longer open, return error with error code no such window.

  2. If the remote end does not support the Fullscreen Window command for the current top-level browsing context for any reason, return error with error code unsupported operation.

  3. Run the implementation-specific steps, which should have the effect of making the dimensions of the window containing the current top-level browsing context as close as possible to the dimensions of the display containing the window, and may hide browser-provided UI such as toolbars.

  4. Return success with data null.

9. Elements

A web element is an abstraction used to identify an element when it is transported across the protocol, between remote- and local ends.

The web element identifier is a constant with the string "element-6066-11e4-a52e-4f735466cecf".

Each element has an associated web element reference (a UUID) that uniquely identifies the the element across all browsing contexts. The web element reference for every element representing the same element is the same.

An ECMAScript Object represents a web element if it has a web element identifier own property holding a UUID value.

Each browsing context has an associated list of known elements. When the browsing context is discarded, the list of known elements is discarded along with it.

When getting a known element by a UUID reference:

  1. For each element in the current browsing context’s list of known elements:

    1. If element’s web element reference matches reference, return success with data element.

  2. Return error with error code no such element.

To create a web element reference for an element element:

  1. For each known element of the current browsing context’s known elements:

    1. If known element equals element, return success with known element’s web element reference.

  2. Let new reference be the result of generating a new UUID.

  3. Set element’s web element reference to new reference.

  4. Append element to the known elements of the current browsing context.

  5. Return success with data element’s web element reference.

When asked to serialise the element element:

  1. Let object be a new JSON Object with properties:

    web element identifier

    Value of element’s web element reference.

  2. Return object.

When required to deserialise the web element by a JSON Object object that represents a web element:

  1. If object has no own property web element identifier, return error with error code invalid argument.

  2. Let reference be the result of getting the web element identifier property from object.

  3. Let element result be the result of getting a known element by reference reference.

  4. If element result is a success, let element be element result’s data.

    Otherwise, return element result.

  5. Return success with data element.

A stale element is a reference to a node that has been disconnected from the current browsing context’s DOM. To determine if an element is stale, run the following substeps:

  1. Let document be the current browsing context’s document element.

  2. If element is not in the same tree as document, return true.

  3. Otherwise return false.

9.1 Finding Elements in a document

When the findElement() or findElements() WebDriver Command is called the following must be parameters after the local end has made a request to the remote end:

  1. Let using contain the Element Location Strategy. If it is not a valid stategy:
    • Set the HTTP Response status code to 500
    • Let status be equal to Invalid Selector
    • Let value be a statement that the strategy is invalid. It MAY return a list of valid search strategies.
  2. Let value contain a string that will be passed to the Element Location Strategy call. If value is an empty string or null:
    • Set the HTTP Response status code to 500
    • Let status be equal to Invalid Selector
    • Let value to a stating that the strategy is invalid. It MAY return a list of valid search strategies.
  3. Call the relevant Element Location Strategy and return what is described in findElement() or findElements() WebDriver Command described below.

9.1.1 findElements()

When there is a need to find multiple elements on a document that we can return to the local end we use the following algorithm:

HTTP Method Path Template
POST /session/{session id}/elements
  1. Let result be equal to an empty list
  2. Let queryResult be a NodeList returned from Element Location Strategy
  3. Repeat for every value in queryResult if not an empty set else return result
    1. Let id be the unique identifier for the DOMElement.
    2. Append {"element-6066-11e4-a52e-4f735466cecf": id} to result
  4. Return result. The object returned will look like the following:
    {
      "value": [{"element-6066-11e4-a52e-4f735466cecf": id}, {"element-6066-11e4-a52e-4f735466cecf": id}]
    }

When there is a need to search from an element to find the next WebElement we use the following algorithm:

HTTP Method Path Template
POST /session/{session id}/element/{element id}/elements
  1. Let result be equal to an empty list.
  2. Let element be the start node for the query in the Element Location Strategy
  3. Let queryResult be a NodeList returned from Element Location Strategy
  4. Repeat for every value in queryResult if not an empty set else return result
    1. Let id be the unique identifier for the DOMElement.
    2. Append {"element-6066-11e4-a52e-4f735466cecf": id} to result
  5. Return result. The object returned will look like the following:
    {
      "value": [{"element-6066-11e4-a52e-4f735466cecf": id}, {"element-6066-11e4-a52e-4f735466cecf": id}]
    }

9.1.2 findElement()

HTTP Method Path Template
POST /session/{session id}/element
  1. Let id be an identifier for a DOMElement returned from Element Location Strategy. If a NodeList is returned, the first element in the NodeList MUST be used.

    If id is empty:

    • Let the HTTP response status code be 501
    • Let status contain the error no such element
    • Let value contain the details of the search contained in using and value above.

    If an error is returned from Element Location Strategy do the following.(todo describe how the error is returned)

    • Let the HTTP response status code be 501
    • Let status contain the error invalid selector
    • Let value contain the details of the search contained in using and value above.
  2. Let result be equal to {"element-6066-11e4-a52e-4f735466cecf": id}
  3. Return result. The object returned will look like the following:
    {
      "value": {"element-6066-11e4-a52e-4f735466cecf": id}
    }

When searching from an element from another element the following algorithm should be used:

HTTP Method Path Template
POST /session/{session id}/element/{element id}/element
  1. Let element be the start node for the query in the Element Location Strategy
  2. Let id be a unique identifier for the DOMElement returned from Element Location Strategy. If a NodeList is returned, the first DOMElement in the NodeList MUST be used.

    If id is empty:

    • Let the HTTP response status code be 501
    • Let status contain the error no such element
    • Let value contain the details of the search contained in using and value above.

    If an error is returned from Element Location Strategy do the following.(todo describe how the error is returned)

    • Let the HTTP response status code be 501
    • Let status contain the error invalid selector
    • Let value contain the details of the search contained in using and value above.
  3. Let result be equal to {"element-6066-11e4-a52e-4f735466cecf": id}
  4. Return result. The object returned will look like the following:
    {
      "value": {"element-6066-11e4-a52e-4f735466cecf": id}
    }

9.1.3 Get Active Element

HTTP Method Path Template
GET /session/{session id}/element/active

Get Active Element returns the active element of the current browsing context’s document element.

The remote end steps are:

  1. If the current top-level browsing context is no longer open, return error with error code no such window.

  2. Let active element be the activeElement attribute of the the current browsing context’s document element.

  3. Serialise the element that is active element and let it be known as active web element.

  4. Return success with data active web element.

9.2 Element Location Strategies

All element location strategies MUST return elements in the order in which they appear in the current document.

9.2.1 CSS Selectors

Strategy name: css selector

If a browser supports the CSS Selectors API ([SELECTORS-API]) it MUST support locating elements by CSS Selector. If the browser does not support the browser CSS Selector spec it MAY choose to implement locating by this mechanism. If the browser can support locating elements by CSS Selector, it MUST set the "cssSelector" capability to boolean true when responding to the newSession(). Elements MUST be returned in the same order as if "querySelectorAll" had been called with the Locator's value. Compound selectors are allowed.

9.2.2 ECMAScript

Finding elements by ecmascript is covered in the ecmascript part of this spec.

9.2.5 XPath

Strategy name: xpath

All WebDriver implementations MUST support finding elements by XPath 1.0 [XPATH] with the edits from section 3.3 of the [html51] specification made. If no native support is present in the browser, a pure JS implementation MAY be used. When called, the returned values MUST be equivalent of calling "evaluate" function from [DOM-LEVEL-3-XPATH] with the result type set to ORDERED_NODE_SNAPSHOT_TYPE (7).

9.3 Element Displayedness

The visibility of an element is guided by what is perceptually visible to the human eye. In this context, an element's displayedness does not relate to the visibility or display style properties [CSS3BOX].

The approach used by WebDriver to ascertain an element's visibility is based on crude approximations about its nature and relationship in the tree. An element is in general to be considered visible if any part of it is drawn on the canvas within the bounderies of the viewport.

When asked to normalize style pixel values to floating point for a value s of the type string:

  1. Let trimmed string be a substring of s where the suffix "px" is removed.

  2. Let pixels be the result of parsing trimmed string as a float.

  3. If pixels is not a valid float or the previous operation did not succeed, return 0.0.

  4. Round off pixels using a ceiling function so that it has no more than four decimals.

  5. Return pixels.

Note

To normalize style pixel values to floating point is almost equivalent to calling parseFloat from [ECMA-262] with the exception that non-valid float return values are returned as 0.0.

The element displayed algorithm is a boolean state where true signifies that the element is displayed and false signifies that the element is not displayed. To compute the state on element:

  1. If the attribute hidden is set, return false.

  2. If the computed value of the display style property is "none", return false.

  3. Issue 16

    Not really sure what this means, needs review:

    If it has a [CSS3-2D-TRANSFORMS] or [CSS3-3D-TRANSFORMS] style property that gives a negative X or Y coordinates to the canvas, return false.

  4. If element is the document's root element, that is document.documentElement:

    1. If the computed value of the background-color property is "transparent", run these substeps:

      1. If element is an HTML HTML element [html51], and the computed value of the background-color style property of the first BODY element descendant of the element in tree order, relative to that element, is also "transparent", return false. Otherwise return true.

  5. If element is an option or optgroup element, and element's parent node is a select element:

    1. Apply the element displayed algorithm on element's parent node.

    2. If the return value is false, abort these steps and return that value.

  6. If element is a map element:

    1. Let any images visible be a boolean initially set to false.

    2. For each img element, image element, in the document with a name attribute matching the value of element's usemap attribute, run these substeps:

      1. Run the element displayed algorithm on image element and set any images visible to any images visible bitwise OR its return value.

    3. If any images visible is true, abort these steps and return its value.

  7. If element is an area element:

    1. For each ancestral element parent, in tree order:

      1. If parent is a map element, apply the element displayed algorithm on it.

      2. If the return value is false, abort these steps and return that value.

      3. Otherwise apply step 7.1 on parent.

  8. If element is a [DOM4] text node, return true.

  9. If it has equal to or more than one direct descendant elements:

    1. Let visible children be a boolean initially set to false.

    2. For each direct descendant element child:

      1. Let rectangle be the DOMRect returned by calling getBoundingClientRect on child.

      2. If the value of the height property of rectangle is greater than zero CSS reference pixels, and the value of the width property of rectangle is greater than zero CSS reference pixels:

        1. Set visible children to visible children bitwise OR true.

  10. For each ancestral element parent, in tree order:

    1. Apply the element displayed algorithm to parent.

    2. If the return value is false, abort these steps and return that value.

    3. If parent is a block element box and the computed values of either overflow-x or overflow-y is "hidden":

      1. Let parent dimensions be the DOMRect that is the first element of the DOMRectList array returned by calling getClientRects on parent.

      2. Let element dimensions be the DOMRect that is the first element of the DOMRectList array returned by calling getClientRects on element.

      3. Let parent style be the computed style of parent.

      4. Return false if any the following conditions evaluate to false:

      5. Run step 10 on the parent elements of parent, if any.

  11. Return true.

10. Element State

To calculate the absolute position of an element, element:

  1. Let x be 0.

  2. Let y be 0.

  3. While element’s offsetParent is not null:

    1. Set x to (x + element’s offsetLeft).

    2. Set y to (y + element’s offsetTop).

    3. Set element to element’s offsetParent.

  4. Return a pair of (x, y).

When a node is said to be not in the same tree as another node, other, the following steps must be taken on node:

  1. If node’s ownerDocument attribute is not other, return true.

  2. If the result of calling node’s compareDocumentPosition with other as argument is DOCUMENT_POSITION_DISCONNECTED (1), return true.

  3. Return false.

10.1 Is Element Displayed

HTTP Method Path Template
GET /session/{session id}/element/{element id}/displayed

The Is Element Displayed command is used to determine the element displayedness of a web element.

The remote end steps are:

  1. If the current top-level browsing context is no longer open, return error with error code no such window.

  2. Let visible be a boolean initially set to false.

  3. Let element result be the result of getting a known element by parameter element id.

  4. If element result is a success, let element be element result’s data.

    Otherwise, return element result.

  5. If element is stale, return error with error code stale element reference.

  6. Apply the element displayed algorithm to element and set visible to its return value.

  7. Let body be a new JSON Object with the "value" member set to element displayed.

  8. Return success with data body.

10.2 Is Element Selected

HTTP Method Path Template
GET /session/{session id}/element/{element id}/selected

Is Element Selected determines if the referenced element is selected or not. This operation only makes sense on input elements of the Checkbox- and Radio Button states, or option elements.

The remote end steps are:

  1. If the current top-level browsing context is no longer open, return error with error code no such window.

  2. Let element result be the result of getting a known element by reference element id.

  3. If element result is a success, let element be element result’s data.

    Otherwise, return element result.

  4. If element is stale, return error with error code stale element reference.

  5. Let selected be the value corresponding to the first matching statement:

    element is an input with a type attribute in the Checkbox- or Radio Button state

    The result of element’s checkedness.

    element is an option element

    The result of element’s selectedness.

    Otherwise
    False.
  6. Let body be a JSON Object with the "value" member set to selected.

  7. Return success with data body.

10.3 getElementAttribute()

HTTP Method Path Template
GET /session/{session id}/element/{element id}/attribute/{name}
Note

Although the [html51] spec is very clear about the difference between the properties and attributes of a Document element, users are frequently confused between the two. Because of thisend point which covers the case of returning either of the value of a Document element property or attribute. If a user wishes to refer specifically to an attribute or a property, they should evaluate Javascript in order to be unambiguous.

The end result of this algorithm are values that can be passed to other commands within this specification. Notably, this means that URLs that are returned can be passed to get and the expected URL will be navigated to.

To determine the value of the response, the following steps must be taken where name is the name property on the parameters dictionary in Command, and element is the Document element modeled by the ELEMENT parameter.:

  1. Initially set result to null.
  2. Handle special-cases:
    1. If "name" case insensitively matches "style", then store the value of the computed value of the style property of element, serialized as defined in the [CSSOM-VIEW] spec, as result. Notably, CSS property names must be cased as specified in in section 6.5.1 of the [CSSOM-VIEW] spec. In addition, color property values must be standardized to RGBA color format as described in [css3-color]. If a user agent does not support RGBA then it MUST return a value as 1 for opacity.
    2. If "name" case insensitively matches "selected" or "checked", and the element is selectable:
      1. If the element supports neither a selectedness or checkedness check, then store null as result.
      2. For an option element, store the element's selectedness as result.
      3. In all other cases, store the element's checkedness as result.
    3. If any of the above steps have been executed, go to the result coercion step of this algorithm.
  3. Obtain the property indexed by "name" from the element and store this as result. If name case insensitively matches "class" set result to be element's className property. Similarly, if name case insensitively matches "readonly", set result to be the element's readOnly property.
  4. If result is null or undefined, or if it is an object, set the value of result to be the value of the Attr node obtained by calling getAttributeNode on element iff that Attr is specified. That is, result is the equivalent of executing the following Ecmascript: var attr = element.getAttributeNode(name); var result = (attr && attr.specified) ? attr.value : null;
  5. Coerce the return value to a DOMString:
    1. If result is a boolean value, use the value "true" if result is true, or null otherwise.
    2. if result is null or undefined, set result to be null.
    3. In all other cases, coerce result to a DOMString.
DOMString name
The name of the property or attribute to return.

If the ELEMENT does not represent a Document element, or it represents a Document element that is no longer attached to the document's node tree, then the WebDriver implementation MUST immediately abort the command and return a stale element reference error. If the top level browsing context currently receiving commands is no longer open a no such window error MUST be raised.

10.4 Get Element CSS Value

HTTP Method Path Template
GET /session/{session id}/element/{element id}/css/{property name}

The Get Element CSS Value command retrieves the computed value of the given CSS property of the given web element.

The remote end steps are:

  1. If the current top-level browsing context is no longer open, return error with error code no such window.

  2. Let element result be the result of getting a known element by parameter element id.

  3. If element result is a success, let element be element result’s data.

    Otherwise, return element result.

  4. If element is stale, return error with error code stale element reference.

  5. Let computed value be the computed value of parameter property name from element’s style declarations.

  6. Let body be a JSON Object with the "value" member set to computed value.

  7. Return success with data body.

10.5 getElementText()

HTTP Method Path Template
GET /session/{session id}/element/{element id}/text

The following definitions are used in this section:

Whitespace
Any text that matches the ECMAScript regular expression class \s.
Whitespace excluding non-breaking spaces
Any text that matches the ECMAScript regular expression [^\S\xa0]
Block level element
A block-level element is one which is not a table cell, and whose effective CSS display style is not in the set ['inline', 'inline-block', 'inline-table', 'none', 'table-cell', 'table-column', 'table-column-group']
Horizontal whitespace characters
Horizontal whitespace characters are defined by the ECMAScript regular expression [\x20\t\u2028\u2029].

The expected return value is roughly what a text-only browser would display. The algorithm for determining this text is as follows:

Let lines equal an empty array. Then:

  1. if the element is in the head element of the document, return an empty string otherwise carry on with the algorithm below.
  2. For each descendent of node, at time of execution, in order:
    1. Get whitespace, text-transform, and then, if descendent is:
      • a node which is not displayed, do nothing
      • a [DOM4] text node let text equal the nodeValue property of descendent. Then:
        1. Remove any zero-width spaces (\u200b, \u200e, \u200f), form feeds (\f) or vertical tab feeds (\v) from text.
        2. Canonicalize any recognized single newline sequence in text to a single newline (greedily matching (\r\n|\r|\n) to a single \n)
        3. If the parent's effective CSS whitespace style is 'normal' or 'nowrap' replace each newline (\n) in text with a single space character (\x20). If the parent's effective CSS whitespace style is 'pre' or 'pre-wrap' replace each horizontal whitespace character with a non-breaking space character (\xa0). Otherwise replace each sequence of horizontal whitespace characters except non-breaking spaces (\xa0) with a single space character
        4. Apply the parent's effective CSS text-transform style as per the CSS 2.1 specification ([CSS21])
        5. If last(lines) ends with a space character and text starts with a space character, trim the first character of text.
        6. Append text to last(lines) in-place
      • an element which is displayed. If the element is a:
        • BR element: Push '' to lines and continue
        • Block-level element and if last(lines) is not '', push '' to lines.
        And then recurse depth-first to step 1 at the beginning of the algorithm with descendent set to the current element
      • If element is a TD element, or the effective CSS display style is 'table-cell', and last(lines) is not '', and last(lines) does not end with whitespace append a single space character to last(lines) [Note: Most innerText implementations append a \t here]
      • If element is a block-level element: push '' to lines
  3. The string MUST then have the white space normalised as defined in the [XPATH] normalize-space function which is then returned.

If the ELEMENT does not represent a Document element, or it represents a Document element that is no longer attached to the document's node tree, then the WebDriver implementation MUST immediately abort the command and return a stale element reference error. If the top level browsing context currently receiving commands is no longer open a no such window error MUST be raised.

10.6 Get Element Tag Name

HTTP Method Path Template
GET /session/{session id}/element/{element id}/name

The Get Element Tag Name command returns the qualified tag name name of the given web element.

The remote end steps are:

  1. If the current top-level browsing context is no longer open, return error with error code no such window.

  2. Deserialise the web element from parameters, and let it be known as element result.

  3. If element result is an error, return it with its error code.

  4. Let element be element result’s data.

  5. If element is stale, return error with error code stale element reference.

  6. Let qualified name be the result of getting element’s tagName content attribute.

  7. Let body be a JSON Object with the "value" member set to qualified name.

  8. Return success with data body.

10.7 Get Element Rect

HTTP Method Path Template
GET /session/{session id}/element/{element id}/rect

The Get Element Rect command returns the dimensions and coordinates of the given web element. The returned value is a dictionary with the following members:

x
X axis position of the top-left corner of the web element relative to the current browsing context’s document element in CSS pixels.
y
Y axis position of the top-left corner of the web element relative to the current browsing context’s document element in CSS pixels.
height
Height of the web element’s rectangle in CSS pixels.
width
Width of the web element’s rectangle in CSS pixels.

The remote end steps are:

  1. If the current top-level browsing context is no longer open, return error with error code no such window.

  2. Deserialise the web element from parameters, and let it be known as element result.

  3. If element result is an error, return it with its error code.

  4. Let element be element result’s data.

  5. If the element is stale, return error with error code stale element reference.

  6. Calculate the absolute position of element and let it be coordinates.

  7. Let rect be element’s DOMRect.

  8. Let body be a new JSON Object initialised with:

    "x"
    The first value of coordinates.
    "y"
    The second value of coordinates.
    "height"
    Value of rect’s height.
    "width"
    Value of rect’s width.
  9. Return success with data body.

10.8 Is Element Enabled

HTTP Method Path Template
GET /session/{session id}/element/{element id}/enabled

Is Element Enabled determines if the referenced element is enabled or not. This operation only makes sense on form controls.

The remote end steps are:

  1. If the current top-level browsing context is no longer open, return error with error code no such window.

  2. Let element result be the result of getting a known element by reference element id.

  3. If element result is a success, let element be element result’s data.

    Otherwise, return element result.

  4. If element is stale, return error with error code stale element reference.

  5. Let enabled be a boolean initially set to true.

  6. Set enabled to false if a form control is disabled.

  7. Let body be a JSON object with the "value" member set to enabled.

  8. Return success with data body.

11. Executing Script

Issue 17

Open questions: What happens if a user's JS triggers a modal dialog? Blocking seems like a reasonable idea, but there is an assumption that WebDriver is not threadsafe. What happens to unhandled JS errors? Caused by a user's JS? Caused by JS on a page? How does a user of the API obtain the list of errors? Is that list cleared upon read?

When required to JSON deserialize with argument value, and optional argument seen, a remote end must run the following steps:

  1. If seen was not provided, let seen be an empty set.

  2. Jump to the first appropriate step below:

    If value is null, or has type Boolean, Number or String:

    Return success with data value.

    If value is an Object that represents a web element:

    Return the result of running the deserialize the web element algorithm with object value.

    If value if value is an Array object or an Object object:

    Return the result of running the clone an object algorithm with arguments value and seen, and the JSON deserialize algorithm as the clone algorithm.

    Otherwise:

    Return error with error code javascript error.

When required to make a JSON clone with argument value, a remote end must run the following steps:

  1. Let seen be an empty set.

  2. Return the result of calling the internal JSON clone algorithm with arguments value and seen.

When required to run the internal JSON clone algorithm with arguments value and seen, a remote end must run the following algorithm:

  1. Run the substeps of the first matching statement:

    value is undefined or null

    Return success with data null.

    value has type Boolean, Number, or String

    Return success with data value.

    value is an Element Node

    Return the result of creating a web element with argument value.

    1. If value is in seen, return error with error code javascript error.

    2. Add value to seen.

    value is a NodeList, HTMLCollection, Array object, or Objectobject
    1. If value is in seen, return error with error code javascript error.

    2. Add value to seen.

    3. Return the result of running the clone an object algorithm with arguments value and seen, and the internal JSON clone algorithm as the clone algorithm.

    Otherwise

    Return error with error code javascript error.

When required to clone an object with arguments value and seen and clone algorithm clone algorithm, run the following steps:

  1. Let result be the value of the first matching statement:

    value is a NodeList, HTMLCollection, or ECMAScript Array object

    A new Array object, which length property has the result of getting a property named "length" from value.

    Otherwise

    A new Object object.

  2. For each enumerable own property in value, run the following substeps:

    1. Let name be the name of the property.

    2. Let source property value be the result of getting a property named name from value. If doing so causes script to be run, and that script throws an exception, return error with error code javascript error.

    3. Let cloned property result be the result of calling the clone algorithm with arguments source property value and seen.

    4. If cloned property result is a success, set a property of result with name name and value equal to cloned property result’s data.

    5. Otherwise, return cloned property result.

The steps for extracting the script arguments from a request, are:

  1. If the current browsing context is no longer open, return error with error code no such window.

  2. Let script be the result of getting a property named script from the parameters argument.

  3. If script is not a String, return error with error code invalid argument.

  4. Let args be the result of getting a property named args from the parameters argument.

  5. If args is not an Object or its [[Class]] internal property is not Array or Object, return error with error code invalid argument.

  6. Let arguments be a List consisting of a json deserialization of each item in args with the order preserved.

  7. Return success with data script and arguments.

When required to execute a function body with arguments body and arguments, a remote end must run the following steps:

  1. Let window be the associated window of the current browsing context's active document.

  2. Let environment settings be the environment settings object for window.

  3. Let script environment be the script execution environment for JavaScript obtained from environment settings.

  4. If body is not parsable as a FunctionBody or if parsing detects an early error, return error with error code javascript error.

  5. If body begins with a Directive Prologue that contains a Use Strict Directive then let strict be true, otherwise let strict be false.

  6. Using the script execution environment script environment, let function be the result of calling create a function object with parameter list of an empty List, body body, scope of the global environment and strict flag strict.

  7. Let script be a new script.

  8. Let script's code entry-point be function.

  9. Let script's settings object object be script settings.

  10. Invoke the [[Call]] internal method of function, providing window as the this value and parameters as the argument values. If doing so does not produce an exception, let result be success with data set to the return value from this function call. Otherwise let result be error with code javascript error.

  11. If result is an error, return result.

  12. Otherwise let json data be a JSON clone of result's data.

  13. Return success with data json data.

11.1 Execute Script

HTTP Method Path Template
POST /session/{session id}/execute

The Execute Script command executes a JavaScript function in the context of the current browsing context and returns the return value of the function.

The remote end steps are:

  1. Let script arguments be the result of extracting the script arguments from a request with argument parameters.

  2. If script arguments is an error, return script arguments.

  3. Let body and arguments be script arguments’ data.

  4. Let result be the result of calling execute a function body, with arguments body and arguments.

  5. If result is an error, return result.

    Otherwise let value be result’s data.

  6. Let data be a new Object.

  7. Set the property value of data to value.

  8. Return success with data data.

11.2 Execute Async Script

HTTP Method Path Template
POST /session/{session id}/execute_async

The Execute Async Script command causes JavaScript to execute as an anonymous function. Unlike the Execute Script command, the result of the function is ignored. Instead an additional argument is provided as the final argument to the function. This is a function that, when called, returns its first argument as the response.

The remote end steps are:

  1. Let script arguments be the result of extracting the script arguments from a request with argument parameters.

  2. If script arguments is an error, return script arguments.

  3. Let body and arguments be script arguments’ data.

  4. Issue 18

    This next step might not quite set up all the right machinery.

    Let webdriver callback result be a flag which can have three values: unset, expired, or set, with the set value having associated data. Initially it is in the unset state.

  5. Let callback be a function whose [[Call]] internal method runs the execute async script callback algorithm initialized with argument webdriver callback result.

  6. Append callback to arguments.

  7. Let result be the result of calling execute a function body with arguments body and arguments.

  8. If result is an error, return result.

  9. Wait for webdriver callback result to enter the set state, or for session script timeout milliseconds to expire, whichever happens sooner.

  10. If the previous step completed due the session script timeout being reached, set webdriver callback result to expired and return error with error code script timeout.

  11. Otherwise, let result be webdriver callback result’s data.

  12. If result is an error, return result.

  13. Let value be result’s data.

  14. Let data be a new Object.

  15. Set the property value of data to value.

  16. Return success with data data.

The execute async script callback algorithm is initialized with a single argument webdriver callback state. It defines a function with a single optional argument result. When this function is called, the following steps are run:

  1. If webdriver callback state is not in the unset state, return undefined.

  2. If result is not present, let result be null.

  3. Let json result be a JSON clone of result.

  4. Set the webdriver callback state to set with data json result.

  5. Return undefined.

12. Cookies

This section describes the interaction with cookies as described in the [html51]. When retrieving and setting a cookie it MUST be in the format of a Cookie.

Note

Conformance tests for this section can be found in the webdriver module under the "cookies" folder.

When returning Cookie objects, the server SHOULD include all optional fields it is capable of providing the information for.

13. Interactions


The WebDriver API offers two ways of interacting with elements, either with a set of low-level "do as I say" actions, or a high-level "do as I mean" set of actions. The former are offered to allow precise emulation of user input. The latter are offered as a convenience to cover the common case, and can conceivably be implemented on top of the lower level primitive operations.
Interactions can be used to emulate single input actions as well as multiple, simultaneous actions.

Terms:


(NOTE: these are by no means the final terms, I needed them to make the prose easier to follow)

low-level action: The smallest operation an input source can do. These are used to build chains of actions. Example: keyDown
action chain: A chain of low-level actions
input source: The source from which the inputs will originate. MUST support 'keyboard', 'mouse' and 'touch'
source: The object currently acting on the source. For example, in a 'touch' environment, if two fingers are acting on a touchscreen, you will have two sources of input.

13.1 Interactable elements

User actions that operate on an element require the element to be interactable. The following conditions must be met for the element to be considered interactable:

13.2 Low-Level Actions


The low level actions provide a mechanism for precisely stating how a user can interact with the browser. This is achieved by sending a chain of low-level commands to a single endpoint. For example, if you wish to automate a drag and drop action in a browser, you would chain the pointerDown, pointerMove, pointerUp and release commands together.

The remote end will receive the action chain, execute them, and will return a response to the local end once the entire action sequence has been dispatched.

The set of actions available to you is depending on the input source. For example, on a keyboard you want to have a keyDown action to simulate pressing a specific key on the keyboard, but this is not a valid action on a touchscreen, where we care about pointer actions relative to coordinates or webelements.
Note

Activation triggers generated by the WebDriver API User SHOULD be indistinguishable from those generated by a real user interacting with the browser. In particular, the dispatched events will have the isTrusted attribute set to true. The most robust way to dispatch these events is by creating them in the browser implementation itself. Sending OS-specific input messages to the browser's window has the disadvantage that the browser being automated may not be properly isolated from a user accidentally modifying input source state; use of an OS-level accessibility API has the disadvantage that the browser's window must be focused, and as a result, multiple tests cannot run in parallel.


13.2.1 Actions Endpoint

13.2.1.1 Sending an Action
HTTP Method Path Template
POST /session/{session id}/actions

The 'actions' endpoint expects a list of objects as input. Each object in this list MUST contain the fellowing members:

Source

Issue 19

Use symbols?

The "source" member will hold a string value to represent the input source. Implementations MUST support "keyboard", "mouse", and "touch", and can be extended for any other input source.

id

This is a locally-assigned unique identifier. It will be used by the remote end to differentiate dispatched actions. For example, if you have a "touch" action with id "1" to represent one finger actively pressed on a screen, then you can dispatch another "touch" action with id "2" to represent a second finger on a screen, acting simultaneously.

actions

This holds a list of objects, where each object represents a low-level command. The list order dictates the order in which each command will be dispatched. Each command MUST have a 'name' member, whose value will hold the name of the command. More information on each command is in the action commands section.

So the structure will look as follows:

            [
              {
                "source": "string",
                "id": "string",
                "actions": [
                          { "name": "string: name of action primitive",
                            ... parameters to action commands...
                          },
                ]
              }
            ]
          

A list of dictionary objects are used so that we may use this same endpoint for parallel actions.
There is one endpoint for all input source's action chains.
13.2.1.2 Releasing all actions
HTTP Method Path Template
DELETE /session/{session id}/actions


Use this command to clear all actions that are currently being performed. ALL actions currently being performed MUST be cancelled via pointerCancel if it is a "mouse" or "touch" source or via keyUp if it is a "keyboard" source.

NOTE: 'release' as a single command was removed since 'keyUp' and 'pointerUp'/'pointerCancel' exist and 'release' conflates them
13.2.1.3 Actions
This section describes the objects that are part of the "actions" member of the JSON structure sent to the "actions" endpoint.
13.2.1.3.1 General Actions
All input sources MUST implement the following action:

pause

Issue 20

Or MAY, since we can default to 0 on remote end?

The "pause" action MUST take in a parameter named "duration" which will be the time to wait either in milliseconds or using a symbol. This action is used to indicate a period of time to wait between actions, and will also be used to indicate a period of inaction in parallel action chains.

If you wish to use a system specific wait period, please use the following symbols:

  • "CONTEXT" - wait for contextmenu
  • "CHAINED_EVENT" - wait period to join related events. For example, this should be used to join events for doubleclicking.

The remote end is responsible for translating these symbols to the platform specific periods.
13.2.1.3.2 Keyboard Actions
The following are actions that must be implemented for the "keyboard" input source. Their names will be used as the value to the "name" member of the data sent to the 'actions' endpoint. Each actions parameters are additional members to the object that "name" is a member of.

keyDown

The "keyDown" requires a parameter named "code" whose value will be one of the codes from the character types table. This action will send a "keyDown" event, with the specified key as a target.

keyUp

The "keyUp" requires a parameter named "code" whose value will be one of the codes from the character types table. This action will send a "keyUp" event, with the specified key as a target.
13.2.1.3.3 Pointer Actions

The following are actions that must be implemented for both "mouse" and "touch" input sources. Any future pointer-based source must implement these actions.

NOTE: conflating mouse and touch causes the pointerMove/pointerDown to events to be confusing and lacks verisimilitude: If you want to tap at element1, then that would mean 'put finger down on element1, remove finger from element1', for a tap, we have to decide if we want to send 'pointerMove, pointerDown, pointerUp' or 'pointerDown, pointerUp'. The latter matches the touch events sent (touchStart,touchEnd), and makes sense for touchscreens because there is no active button state (http://www.w3.org/TR/pointerevents/#glossary) until you dispatch a touchstart. sending a JSON structure with pointerMove, pointerDown, pointerUp for something that gets mapped to touchstart/touchend feels inelegant. We can enforce the following instead:

  • if the "source" is mouse, then pointerMove,pointerDown,pointerUp is sent over the wire
  • if the "source" is touch, then pointerDown,pointerUp is sent over the wire.
  • if the "source" is anything else (stylus, or other), it will be defined later.

The ramifications of this proposal would be that pointerDown must accept the parameters that pointerMove does (ie: ELEMENT, etc.).

pointerMove

The "pointerMove" action is used to move the pointer to a specific location on a page. In "mouse" sources, this would dispatch a "mouseMove" event. In "touch" sources, then if there is an active pointerDown action, this will generate a "touchmove" or "pointermove" event. For "touch" sources, pointerMove must not be called before pointerDown, since pointer sources only have move events once they are active on the screen.

When sending a "pointerMove", one of the following parameter sets MUST be used:

  • "ELEMENT" - "ELEMENT" will hold a WebElement's id, and this will dispatch the event to the center of that element, unless the following set of parameters is also included:
    • "x" - Integer, the x-coordinate relative to the top-left corner of the target WebElement. If this is not specifed, the midpoint of the width is used
    • "y" - Integer, the y-coordinate relative to the top-left corner of the target WebElement. If this is not specifed, the midpoint of the height is used
    • "x" and "y" - Integers, the coordinates relative to the top-left corner of the ???.
    Issue 21

    Viewport, or top-left of root element?

pointerDown

The "pointerDown" action is used to start an interaction on the page. In "mouse" sources, this would mean "mouseDown", in "touch" sources, this would mean "touchstart" or "pointerdown".

For "touch" sources, the following parameters must be passed:

  • "ELEMENT" - "ELEMENT" will hold a WebElement's id, and this will dispatch the event to the center of that element, unless the following optional set of parameters is also included:
    • "x" - Integer, the x-coordinate relative to the top-left corner of the target WebElement. If this is not specifed, the midpoint of the width is used
    • "y" - Integer, the y-coordinate relative to the top-left corner of the target WebElement. If this is not specifed, the midpoint of the height is used

For "mouse" sources, the following parameter must be passed:

  • "BUTTON" - "BUTTON" will hold a value describing which mouse button should be depressed.

    Link to button chart

pointerUp

The "pointerUp" action is used to start an interaction on the page. In "mouse" sources, this would mean "mouseUp", in "touch" sources, this would mean dispatching an event like "touchend" or "pointerup".

Takes no parameters

pointerCancel

The "pointerMove" action is used to cancel an active pointer on the page. In "mouse" sources, this would mean "mouseUp", in "touch" sources, it implies cancelling the current action if possible by dispatching an event like "touchcancel" or "pointercancel".

13.2.1.3.4 Parallel Actions

Parallel actions are those that have more than one action acting simultaneously on the browser. An example of this is using multiple fingers to operate on a tablet screen at the same time.

Dispatching a parallel action also uses the actions endpoint. In order to send a parallel action, append multiple dictionaries to the list of dictionary objects. Each dictionary will hold all the actions from one input source. The list of actions each dictionary contains will be executed together in ticks, by stepping through each input source's action list in order and executing each step simultaneously.

The best way to understand this is through an example. Imagine we have two fingers acting on a touchscreen. One finger will press down on element1 at the same moment that another finger presses down on element2. Once these actions are done, the first finger will wait 5 seconds while the other finger moves to element3. Then both fingers release from the touchscreen.

To execute these actions, we must send the "actions" endpoint two dictionary objects in the JSON list of dictionaries, one for each finger. We must use the "id" key of each object to uniquely identify each finger. The "actions" key will hold all the actions the input source will take.

The JSON for this set of actions is as follows:

[
  {
    "source": "touch",
    "id": "1",
    "actions": [
              { "name": "pointerDown",
                "ELEMENT": "element1"
              },
              { "name": "pause",
                "duration": 0
              },
              { "name": "pointerUp"
              }
    ]
  },
  {
    "source": "touch",
    "id": "2",
    "actions": [
              { "name": "pointerDown",
                "ELEMENT": "element2"
              },
              { "name": "pointerMove",
                "ELEMENT": "element3"
              },
              { "name": "pointerUp"
              }
    ]
  }
]

When the remote end receives this, it will look at each input source's action lists. It will dispatch the first action of each source together, then the second actions together, and lastly, the final actions together.

The diagram below displays when each action gets executed. "Source 1" is the first finger, and "source 2" is the second.

There is no limit to the number of input sources, and there is no restriction regarding the length of each input's action list. Meaning, there is no requirement that all action lists have to be the same length. It is possible for one input source's action list may have more actions than another. As an example, imagine having two fingers on a touchscreen. The first finger will press on element1 while the second presses on element2, then the first will release the touchscreen while the second finger moves to element3, and finally the second finger releases from the touchscreen. In this case, the action list for the first finger contains 2 actions (pointerDown, pointerUp), and the action list for the second finger contains 3 (pointerDown, pointerMove, pointerUp). In this case, the JSON will look like this:

[
  {
    "source": "touch",
    "id": "1",
    "actions": [
              { "name": "pointerDown",
                "ELEMENT": "element1"
              },
              { "name": "pointerUp"
              }
    ]
  },
  {
    "source": "touch",
    "id": "2",
    "actions": [
              { "name": "pointerDown",
                "ELEMENT": "element2"
              },
              { "name": "pointerMove",
                "ELEMENT": "element3"
              },
              { "name": "pointerUp"
              }
    ]
  }
]

And the execution of each action will be done as follows:

Specific timing for the actions can also be expressed. The "pause" action can be used to either a) indicate a specific amount of time an input source must wait, or b) can be used to signify that the current input source must wait until all other actions in the tick are completed. For the former case, the current tick being executed must wait for the longest pause to complete. For example, in this diagram:

The remote end will dispatch the pointerDown actions in the first tick. In the second tick, since source 1 declares a pause of 5 seconds, the remote end will dispatch the pointerUp event for source 2, and will wait 5 seconds before moving on to executing the third tick.

In the event that one tick contains multiple pause durations, the remote end will wait the maximum duration before moving on to executing the next tick.

As noted before, "pause" can be used to signify inaction during a tick. If "pause" is declared without a time period, then the input source will not have any actions executed in the containing tick. As an example:

During tick 2, source 1 will have its pointerMove action dispatched, while source 2 will do nothing.

13.3 High Level Commands

These higher level commands SHOULD be built on top of the low level commands, and implement a user friendly way of interacting with a page in a way that models common user expectations.

13.3.1 Clicking

13.3.1.1 click()
HTTP Method Path Template
POST /session/{session id}/element/{element id}/click

Click in the middle of the WebElement instance. The middle of the element is defined as the middle of the box returned by calling getBoundingClientRect on the underlying document Element, according to the [CSSOM-VIEW] spec. If the element is outside the viewport (according to the [CSS21] spec), the implementation SHOULD bring the element into view first. The implementation MAY invoke scrollIntoView on the underlying document Element. The element MUST be displayed. See the note below for when the element is obscured by another element. Exceptions:

  • Links (A elements): Clicking happens in the middle of the first displayed bounding client rectangle. This is to overcome overflowing links where the middle of the bounding client rectangle does not actually fall on a clickable part of the link.
  • SELECT elements without the "multiple" attribute set. Clicking on the select element SHOULD open the drop down menu. The next click, on any element, MUST close this menu.
  • Clicking directly on an OPTION element (without clicking on the parent SELECT element previously) MUST open a selection menu, as if the SELECT option was clicked first, then click on the OPTION before finally closing the SELECT element's menu. The SELECT menu MUST be closed once the action is complete.

The possible errors for this command:

This command MUST use either the mouse or touch mechanisms for emulating the user input. In the case where the browser being automated supports only mouse input or both mouse and touch input, the low-level mouse mechanisms MUST be used. If the browser only supports touch input, the low level touch inputs MUST be used.

Note

As the goal is to emulate users as closely as possible, the implementation SHOULD NOT allow clicking on elements that are obscured by other elements. If the implementation forbids clicking on obscured elements, an element not visible response MUST be returned and this SHOULD have an explantory message explaining the reason. The implementation SHOULD try to scroll the element into view, but in case it is fully obscured, it SHOULD NOT be clickable.

Issue 22

Add details of interactable

13.3.2 Touch

This section defines the low level commands used when manipulating touch-enabled devices. These are the building blocks of touch interaction chains.

Capability NameType
touchEnabledboolean


13.3.2.1 void tap ()
HTTP Method Path Template
POST /session/{session id}/element/{element id}/tap

Tap in the middle of the WebElement. The middle of the element is defined as the middle of the box returned by calling getBoundingClientRect on the underlying document Element, according to the [CSSOM-VIEW] spec. If the element is outside the viewport (according to the [CSS21] spec), the implementation SHOULD bring the element into view first. The implementation MAY invoke scrollIntoView on the underlying document Element. Exceptions:

  • Links (A elements): Clicking happens in the middle of the first displayed bounding client rectangle. This is to overcome overflowing links where the middle of the bounding client rectangle does not actually fall on a clickable part of the link.
  • SELECT elements without the "multiple" attribute set. Clicking on the select element SHOULD open the drop down menu. The next click, on any element, MUST close this menu.
  • Clicking directly on an OPTION element (without clicking on the parent SELECT element previously) MUST open a selection menu, as if the SELECT option was clicked first, then click on the OPTION before finally closing the SELECT element's menu. The SELECT menu MUST be closed once the action is complete.

The possible errors for this command:

13.3.3 Typing keys

A requirement for key-based interaction with an element is that it is interactable. Typing into an element is permitted if one of the following conditions is met:

  • The element is focusable as defined in the editing section of the [html51] spec.
  • The element is allowed to be the activeElement. In addition to focusable elements, this allows typing to the BODY element.
  • In an HTML document, the element is editable as a result of having its contentEditable attribute set or the containing document is in designMode.
  • The underlying browser implementation would allow keyboard input to directed to the element (eg. an HTML document with a DIV marked as being contentEditable)

Prior to any keyboard interaction, an attempt to shift focus to the element MUST be attempted if the element does not currently have the focus. This is the case if one of the following holds:

  • The element is not already the document's activeElement.
  • The owner document of the element to be interacted with is not the focused document.

In case focusing is needed, the implementation MUST follow the focusing steps as described in the focus management section of the [html51] spec. The focus MUST NOT leave the element at the end of the interaction, other than as a result of the interaction itself (i.e. when the tab key is sent).

13.3.3.1 clear()

Clear a TEXTAREA or text INPUT element's value.

HTTP Method Path Template
POST /session/{session id}/element/{element id}/clear
13.3.3.2 sendKeys()

HTTP Method Path Template
POST /session/{session id}/element/{element id}/value

Let value be an array of characters that will be typed into a WebElement.

Sends a sequence of keyboard events representing the keys in the value parameter.

Caret positioning: If focusing was needed, after following the focusing steps, the caret MUST be positioned at the end of the text currently in the element. At the end of the interaction, the caret MUST be positioned at the end of the typed text sequence, unless the keys sent position it otherwise (e.g. using the LEFT key).

There are four different types of keys that are emulated:

  • Character literals - lower-case symbols.
  • Uppercase letters and symbols requiring the SHIFT key for typing.
  • Modifier keys
  • Special keys
The rest of this section details the values used to represent the different keys, as well as the expected behaviour for each key type.

When emulating user input, the implementation MUST generate the same sequence of events that would have been produced if a real user was sitting in front of the keyboard and typing the sequence of characters. In cases where there is more than one way to type this sequence, the implementation MUST choose one of the valid ways. For example, typing AB may be achieved by:

  • Holding down the Shift key
  • Pressing the letter 'a'
  • Pressing the letter 'b'
  • Releasing the Shift key
Alternatively, it can be achieved by:
  • Holding down the Shift key
  • Pressing the letter 'a'
  • Releasing the Shift key
  • Holding down the Shift key
  • Pressing the letter 'b'
  • Releasing the Shift key

Or by simply turning on the CAPS LOCK first.

The implementation MAY use the following algorithm to generate the events. If the implementation is using a different algorithm, it MUST adhere to the requirements listed below.

For each key, key in value, do

  1. If key is a lower-case symbol:
    1. If the Shift key is not pressed:
      1. Generate a sequence of keydown, keypress and keyup events with key as the character to emulate
    2. else (The Shift key is pressed)
      1. let uppercaseKey be the upper-case character matching key
      2. Generate a sequence of keydown, keypress and keyup events with uppercaseKey as the character to emulate
  2. Else if key is an upper-case symbol:
    1. If the Shift key is not pressed:
      1. Generate a keydown event of the Shift key.
      2. Generate a sequence of keydown, keypress and keyup events with key as the character to emulate
      3. Generate a keyup event of the Shift key.
    2. else (The Shift key is pressed)
      1. Generate a sequence of keydown, keypress and keyup events with key as the character to emulate
  3. Else if key represents a modifier key:
    1. let modifier be the modifier key represented by key
    2. If modifier is currently held down:
      1. Generate a keyup event of modifier
    3. Else:
      1. Generate a keydown event of modifier
    4. Maintain this key state and use it to modify the input until it is pressed again.
  4. Else if key represents the NULL key:
    1. Generate keyup events of all modifier keys currently held down.
    2. All modifier keys are now assumed to be released.
  5. Else if key represents a special key:
    1. Translate key to the special key it represents
    2. Generate a sequence of keydown, keypress and keyup events for the special key.

Once keyboard input is complete, an implicit NULL key is sent unless the final character is the NULL key.

Any implementation MUST comply with these requirements:

  • For uppercase letters and symbols that require the Shift key to be pressed, there are two options:
    • A single Shift keydown event is generated before the entire sequence of uppercase letters.
    • Before each such letter or symbol, a Shift keydown event is generated. After each letter or symbol, a Shift keyup event is generated.
  • A user-specified Shift press implies capitalization of all following characters.
  • If a user-specified Shift press precedes uppercase letters and symbols, a second Shift keydown event MUST NOT be generated. In that case, a Shift keyup event MUST NOT be generated implicitly by the implementation.
  • The NULL key releases all currently held down modifier keys.
  • The state of all modifier keys must be reset at the end of each sendKeys call and the appropriate keyup events generated

Character types

The value parameter contains a mix of printable characters and pressable keys that aren't text. Pressable keys that aren't text are stored in the Unicode PUA (Private Use Area) code points, 0xE000-0xF8FF. The following table describes the mapping between PUA and key:

Key Code Type
NULL\uE000NULL
CANCEL\uE001Special key
HELP\uE002Special key
BACK_SPACE\uE003Special key
TAB\uE004Special key
CLEAR\uE005Special key
RETURN\uE006Special key
ENTER\uE007Special key
SHIFT\uE008Modifier
CONTROL\uE009Modifier
ALT\uE00AModifier
PAUSE\uE00BSpecial key
ESCAPE\uE00CSpecial key
SPACE\uE00DSpecial key
PAGE_UP\uE00ESpecial key
PAGE_DOWN\uE00FSpecial key
END\uE010Special key
HOME\uE011Special key
ARROW_LEFT\uE012Special key
ARROW_UP\uE013Special key
ARROW_RIGHT\uE014Special key
ARROW_DOWN\uE015Special key
INSERT\uE016Special key
DELETE\uE017Special key
SEMICOLON\uE018Special key
EQUALS\uE019Special key
NUMPAD0\uE01ASpecial key
NUMPAD1\uE01BSpecial key
NUMPAD2\uE01CSpecial key
NUMPAD3\uE01DSpecial key
NUMPAD4\uE01ESpecial key
NUMPAD5\uE01FSpecial key
NUMPAD6\uE020Special key
NUMPAD7\uE021Special key
NUMPAD8\uE022Special key
NUMPAD9\uE023Special key
MULTIPLY\uE024Special key
ADD\uE025Special key
SEPARATOR\uE026Special key
SUBTRACT\uE027Special key
DECIMAL\uE028Special key
DIVIDE\uE029Special key
F1\uE031Special key
F2\uE032Special key
F3\uE033Special key
F4\uE034Special key
F5\uE035Special key
F6\uE036Special key
F7\uE037Special key
F8\uE038Special key
F9\uE039Special key
F10\uE03ASpecial key
F11\uE03BSpecial key
F12\uE03CSpecial key
META\uE03DSpecial key
COMMAND\uE03DSpecial key
ZENKAKU_HANKAKU\uE040Special key

The keys considered upper-case symbols are either defined by the current keyboard locale or are derived from the US 104 keys Microsoft Windows keyboard layout, which are:

  • A - Z
  • !$^*()+{}:?|~@#%_\" & < >

When the user input is emulated natively (see note below), the implementation SHOULD use the current keyboard locale to determine which symbols are upper case. In all other cases, the implementation MUST use the US 104 key Microsoft Windows keyboard layout to determine those symbols.

The state of the physical keyboard MUST NOT affect emulated user input.

Internationalized input

Non-latin symbols: TBD

Complex scripts using Input Method Editor (IME): TBD

14. Modals

This section describes how modal dialogs should be handled using the WebDriver API.
Note

Conformance tests for this section can be found in the webdriver module under the "modals" folder.

14.1 window.alert, window.prompt and window.confirm

When the remote end has a modal dialog such as those produced from window.alert, window.prompt and window.confirm it SHOULD allow the interrogation of the dialogues using the following interface.

14.1.1 dismiss()

HTTP Method Path Template
POST /session/{session id}/dismiss_alert

This will dismiss the modal. If the modal is an alert, this MUST be equivalent to calling accept() on the dialog. If no alert is present a no such alert error MUST be raised.

14.1.2 accept()

HTTP Method Path Template
POST /session/{session id}/accept_alert

This will accept the modal. If the modal is from a window.prompt it is the equivalent of clicking the OK button. If no modal is present then a no such alert error MUST be raised.

14.1.3 getText()

HTTP Method Path Template
GET /session/{session id}/alert_text

This will return the message shown in the modal. If no modal is present then a no such alert error MUST be raised.

14.1.4 sendKeys()

HTTP Method Path Template
POST /session/{session id}/alert_text

This MUST act in the same manner as in sendKeys to an element. If the modal has no means for text input it should throw a Element not visible error. If no modal is present then a no such alert error MUST be raised.

Let value be an array of characters that will be typed into a WebElement. If the modal has no means of acceptiing text input it MUST raise a element not visible error

If a modal dialog is created from a onbeforeunload event the remote end MUST handle the dialog by either using accept or dismiss. These calls should either come from the local end or should be handled as an unexpected modal dialog as described below.

The remote end SHOULD have a mechanism to allow unexpected modal dialogs to be closed to prevent the remote end from becoming unusable. The default for this should be dismiss. The local end SHOULD allow a capability to be set that allows the default value to be overridden with accept. The local end SHOULD also allow setting the default behaviour to wait for a command to handle the modal. If the next command does not interact with the modal it MUST return a Unexpected alert open error to the local end.

15. Screenshots

Screenshots are a powerful mechanism for providing information to users of WebDriver, particularly once a particular WebDriver instance has been disposed of. In different circumstances, users want different types of screenshots. Note that the WebDriver spec does not provide a mechanism for taking a screenshot of the entire screen.

In all cases, screenshots MUST be returned as lossless PNG images encoded using Base64. Local ends MUST provide the user with access to the PNG images without requiring the user to decode the Base64. This access MUST be via at least one of a binary blob or a file.

All commands within this section are implemented using the "TakesScreenshot" interface:

15.1 Take Screenshot

HTTP Method Path Template
GET /session/{session id}/screenshot

The Take Screenshot command takes a screenshot and return a lossless PNG encoded using Base64. If element is not populated or is null then the User Agent MUST return the screenshot of the current state of the document at the top level browsing context.

This command will return the screenshot of the current state of the document at the top level browsing context. Implementations of the remote end SHOULD capture the entire document, even if this would require a user to scroll the browser window. That is, the returned PNG SHOULD have the same width and height as returned by a call to getSize of the BODY element and MUST contain all visible content on the page, and this SHOULD be done without resizing the browser window. If the remote end is unable to capture the entire Document, then the part of the Document currently displayed in UI of the browser MUST be captured without additional chrome such as scrollbars and browser chrome.

Note

One way to think of capturing the entire Document is that the user has an infinitely large monitor and has resized the window to allow all content to be visible. One of those monitors would be very cool.

Nested frames MUST be sized as if the user has resized the window to the dimensions of the PNG being returned. This often means that not all potentially visible content within the nested frames is captured.

Remote ends MUST NOT attempt to track changes in window size as the screenshot is being taken. In particular this means that in the case of a page that makes use of "infinite scrolling" (where an AJAX call is used to populate additional content as the user scrolls down) or in some other way resizes content as the window size is changed only the content that was originally contained in the Document when the command is executed will be captured.

15.2 Take Element Screenshot

HTTP Method Path Template
GET /session/{session id}/element/{element id}/screenshot

The Take Element Screenshot command takes a screenshot of the region encompassed by the bounding rectangle of an element, and returns it as a PNG file.

16. The WebDriver Interface

partial interface Navigator {
    readonly    attribute boolean webdriver;
};

The navigator property must return the value of the webdriver-active flag, which is initially false.

This property allows websites to determine that the user agent is being scripted by WebDriver, and can be used to help mitigate denial of service attacks.

17. Handling non-HTML Content

Non-HTML content MUST be treated in the same manner as HTML content if the browser creates a Document object for the content of the document. If a Document Object is not created then how it is handled is non-normative.

17.1 XML

This section describes XML documents as described in [XML10]. For XHTML documents the remote end should treat them as HTML documents and not have the caveats, below, applied.

Since Browsers create a Document object for XML pages it is expected that we can interogate them as a normal HTML document however the following differences should be noted:

17.2 SVG

This section described SVG documents in a browser as described by [SVG2]. Since browsers create a Document tree for SVG documents it is expected that WebDriver can interrogate the Document as a normal HTML document.

17.3 Working with Accessibility APIs

Many accessibility APIs represent the UI as a series of nested nodes. It is possible to map these nodes to WebElement instances. In order to function properly, it is likely that additional element locating strategies will be required.

Note

This is one way in which it might be possible to test mobile applications that marry a native wrapper around a series of HTML views.

A. Thread Safety

There is no requirement for local or remote implementations to be thread safe. Local ends SHOULD support serialized access from multiple threads.

B. Privacy

The following section is non-normative.

The local end SHOULD create a new profile when creating a new session. If a new profile can be created it MUST NOT copy the profile in use and MUST create a fresh profile. By creating a new profile the user agent will prevent any unexpected behaviour when the remote end is accessing content.

C. Security

The following section is non-normative.

The remote end SHOULD have a specific command line argument when starting the browser up if it is connecting to a browser (e.g. firefox.exe --webdriver) and SHOULD have user agent configuration preference that is tested when the user agent starts up.

When the remote end starts up, it MUST include a flag or setting to limit the IP addesses allowed to connect and create sessions. The default value for this setting SHOULD limit connections to be from 127.0.0.1 IPV4 address or ::1 IPV6 address. This will prevent arbitrary machines from connecting and creating WebDriver sessions unless specifically configured to allow them, while still supporting use-cases where the local end runs on a different machine from the remote end.

If any of these fail then a session not created error MUST be thrown when the local end tries to create a new session.

D. Acknowledgements

Many thanks to Robin Berjon for making our lives so much easier with his cool tool. Thanks to Jason Leyba, Malcolm Rowe, Ross Patterson, and Andrey Botalov for proof reading and suggesting areas for improvement. Thanks to Jason Leyba, Eran Messeri, Daniel Wagner-Hall, Malini Das, Luke Inman-Semerau, Andreas Tolfsen, James Graham, and John Jansen for contributing sections to this document. Also thanks to the following people for their contribution of patches and test cases:

Select text and or view bugs filed

E. References

E.1 Normative references

[CSS21]
Bert Bos; Tantek Çelik; Ian Hickson; Håkon Wium Lie et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 7 June 2011. W3C Recommendation. URL: http://www.w3.org/TR/CSS2
[CSS3-2D-TRANSFORMS]
Simon Fraser; Dean Jackson; David Hyatt; Chris Marrin; Edward O'Connor. CSS 2D Transforms. 15 December 2011. W3C Working Draft. URL: http://www.w3.org/TR/css3-2d-transforms/
[CSS3-3D-TRANSFORMS]
Dean Jackson; David Hyatt; Chris Marrin. CSS 3D Transforms Module Level 3. 20 March 2009. W3C Working Draft. URL: http://www.w3.org/TR/css3-3d-transforms
[CSS3BOX]
Bert Bos. CSS basic box model. 9 August 2007. W3C Working Draft. URL: http://www.w3.org/TR/css3-box
[CSSOM-VIEW]
Simon Pieters; Glenn Adams. CSSOM View Module. 17 December 2013. W3C Working Draft. URL: http://www.w3.org/TR/cssom-view/
[DOM4]
Anne van Kesteren; Aryeh Gregor; Ms2ger; Alex Russell; Robin Berjon. W3C DOM4. 18 June 2015. W3C Last Call Working Draft. URL: http://www.w3.org/TR/dom/
[ECMA-262]
Allen Wirfs-Brock. ECMA-262 6th Edition, The ECMAScript 2015 Language Specification. June 2015. Standard. URL: http://www.ecma-international.org/ecma-262/6.0/
[HTML]
Ian Hickson. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[RFC1123]
R. Braden, Ed.. Requirements for Internet Hosts - Application and Support. October 1989. Internet Standard. URL: https://tools.ietf.org/html/rfc1123
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[RFC6265]
A. Barth. HTTP State Management Mechanism. April 2011. Proposed Standard. URL: https://tools.ietf.org/html/rfc6265
[RFC7230]
R. Fielding, Ed.; J. Reschke, Ed.. Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing. June 2014. Proposed Standard. URL: https://tools.ietf.org/html/rfc7230
[SELECTORS-API]
Anne van Kesteren; Lachlan Hunt. Selectors API Level 1. 21 February 2013. W3C Recommendation. URL: http://www.w3.org/TR/selectors-api/
[URI-Template]
J. Gregorio; R. Fielding; M. Hadley; M. Nottingham; D. Orchard. URI Template. March 2012. Proposed Standard. URL: https://tools.ietf.org/html/rfc6570
[XPATH]
James Clark; Steven DeRose. XML Path Language (XPath) Version 1.0. 16 November 1999. W3C Recommendation. URL: http://www.w3.org/TR/xpath
[css3-color]
Tantek Çelik; Chris Lilley; David Baron. CSS Color Module Level 3. 7 June 2011. W3C Recommendation. URL: http://www.w3.org/TR/css3-color
[html51]
Ian Hickson; Robin Berjon; Steve Faulkner; Travis Leithead; Erika Doyle Navara; Edward O'Connor; Tab Atkins Jr.; Simon Pieters; Yoav Weiss; Marcos Caceres; Mathew Marquis. HTML 5.1. 9 July 2015. W3C Working Draft. URL: http://www.w3.org/TR/html51/

E.2 Informative references

[DOM-LEVEL-3-XPATH]
Ray Whitmer. Document Object Model (DOM) Level 3 XPath Specification. 26 February 2004. W3C Note. URL: http://www.w3.org/TR/DOM-Level-3-XPath/
[SVG2]
Nikos Andronikos; Rossen Atanassov; Tavmjong Bah; Amelia Bellamy-Royds; Brian Birtles; Bogdan Brinza; Cyril Concolato; Erik Dahlström; Chris Lilley; Cameron McCormack; Doug Schepers; Dirk Schulze; Richard Schwerdtfeger; Satoru Takagi; Jonathan Watt. Scalable Vector Graphics (SVG) 2. 9 July 2015. W3C Working Draft. URL: http://www.w3.org/TR/SVG2/
[XML10]
Tim Bray; Jean Paoli; Michael Sperberg-McQueen; Eve Maler; François Yergeau et al. Extensible Markup Language (XML) 1.0 (Fifth Edition). 26 November 2008. W3C Recommendation. URL: http://www.w3.org/TR/xml