WebDriver

W3C Editor's Draft

More details about this document
This version:
https://w3c.github.io/webdriver/
Latest published version:
https://www.w3.org/TR/webdriver2/
Latest editor's draft:
https://w3c.github.io/webdriver/
History:
https://www.w3.org/standards/history/webdriver2/
Commit history
Test suite:
https://wpt.live/webdriver/
Implementation report:
https://wpt.fyi/results/webdriver
Editors:
Simon Stewart (Apple)
David Burns (BrowserStack)
Feedback:
GitHub w3c/webdriver (pull requests, new issue, open issues)
Channel
#webdriver on irc.w3.org

Abstract

WebDriver is a remote control interface that enables introspection and control of user agents. It provides a platform- and language-neutral wire protocol as a way for out-of-process programs to remotely instruct the behavior of web browsers.

Provided is a set of interfaces to discover and manipulate DOM elements in web documents and to control the behavior of a user agent. It is primarily intended to allow web authors to write tests that automate a user agent from a separate controlling process, but may also be used in such a way as to allow in-browser scripts to control a — possibly separate — browser.

Status of This Document

This section describes the status of this document at the time of its publication. A list of current W3C publications and the latest revision of this technical report can be found in the W3C standards and drafts index.

This document was published by the Browser Testing and Tools Working Group as an Editor's Draft.

Publication as an Editor's Draft does not imply endorsement by W3C and its Members.

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 a work in progress.

This document was produced by a group operating under the 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 that 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 18 August 2025 W3C Process Document.

1. Design

This section is non-normative.

The WebDriver standard attempts to follow a number of design goals:

1.1 Compatibility

This specification is derived from the popular Selenium WebDriver browser automation framework. Selenium is a long-lived project, and due to its age and breadth of use it has a wide range of expected functionality. This specification uses these expectations to inform its design. Where improvements or clarifications have been made, they have been made with care to allow existing users of Selenium WebDriver to avoid unexpected breakages.

1.2 Simplicity

The largest intended group of users of this specification are software developers and testers writing automated tests and other tooling, such as monitoring or load testing, that relies on automating a browser. As such, care has been taken to provide commands that simplify common tasks such as typing into and clicking elements.

1.3 Extensions

WebDriver provides a mechanism for others to define extensions to the protocol for the purposes of automating functionality that cannot be implemented entirely in ECMAScript. This allows other web standards to support the automation of new platform features. It also allows vendors to expose functionality that is specific to their browser.

2. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the end result is equivalent. Algorithms in this document are typically written with readability, rather than performance, in mind.

3. Terminology

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

The mathematical function min(value, value[, value]) returns the smallest item of two or more values. Conversely, the function max(value, value[, value]) returns the largest item of two or more values.

The mathematical function floor(value) produces the largest integer, closest to positive infinity, that is not larger than value.

A Universally Unique Identifier (UUID) is a 128 bits long URN that requires no central registration process. Generating a UUID means Creating a UUID From Truly Random or Pseudo-Random Numbers, and converting it to the string representation. [RFC4122]

The Unix Epoch is a value that approximates the number of seconds that have elapsed since the Epoch, as described by The Open Group Base Specifications Issue 7 section 4.15 (IEEE Std 1003.1).

An integer is a Number that is unchanged under the ToInteger operation.

The initial value of an ECMAScript property is the value defined by the platform for that property, i.e. the value it would have in the absence of any shadowing by content script.

The browser chrome is a non-normative term to refer to the representation through which the user interacts with the user agent itself, as distinct from the accessed web content. Examples of browser chrome elements include, but are not limited to, toolbars (such as the bookmark toolbar), menus (such as the file or context menu), buttons (such as the back and forward buttons), door hangers (such as security and certificate indicators), and decorations (such as operating system widget borders).

4. Interface

The webdriver-active flag is set to true when the user agent is under remote control. It is initially false.

WebIDLinterface mixin NavigatorAutomationInformation {
  readonly attribute boolean webdriver;
};
Navigator includes NavigatorAutomationInformation;
Note

The NavigatorAutomationInformation interface should not be exposed on WorkerNavigator.

webdriver

Returns true if webdriver-active flag is set, false otherwise.

It is acknowledged that this is complementary to the Evil Bit [RFC3514].

5. Nodes

The WebDriver protocol consists of communication between:

Local end

The local end 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.

Remote end
The remote end hosts the server side of the protocol. Defining the behavior of a remote end in response to the WebDriver protocol forms the largest part of this specification.

For remote ends the standard defines two broad conformance classes, known as node types:

Intermediary node
Intermediary nodes are those that act as proxies, implementing both the local end and remote end of the protocol. However they are not expected to implement remote end steps directly. Nodes between a specific intermediary node and an endpoint node are said to be upstream of the endpoint node.
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.

All remote end node types 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.

The readiness state of a remote end indicates whether it is free to accept new connections. It must be false if the implementation is an endpoint node and the list of active HTTP sessions is not empty, or otherwise if the remote end is known to be in a state in which attempting to create new sessions would fail. In all other cases it must be true.

If the intermediary node is a multiplexer that manages multiple endpoint nodes, this might indicate its ability to purvey more sessions, for example if it has hit its maximum capacity.

6. Protocol

WebDriver remote ends must provide an HTTP compliant wire protocol where the endpoints map to different commands.

As this standard only defines the remote end protocol, it puts no demands to how local ends should be implemented. Local ends are only expected to be compatible to the extent that they can speak the remote end's protocol; no requirements are made upon their exposed user-facing API.

6.1 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 optimized 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 value has an associated error code.

When calling a fallible algorithm, the construct “Let result be the result of trying to call algorithm” is equivalent to

  1. Let temp be the result of calling algorithm.

  2. If temp is an error return temp, otherwise let result be temp's data field.

The result of getting a property with name from object is defined as being the same as the result of calling Object.[[GetOwnProperty]](name) on object.

The result of getting a property with default with arguments name and default from object is defined as being the same as the result of calling Object.[[GetOwnProperty]](name) on object if that results in a value other than undefined and default otherwise.

Setting a property with arguments name and value on object is defined as being the same as calling Object.[[Put]](name, value) on object.

The result of JSON serialization with object of type JSON Object is defined as the result of calling stringify(object).

The result of JSON deserialization with text is defined as the result of calling parse(text).

6.2 Commands

The WebDriver protocol is organized 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 known as remote end steps. These provide the sequences of actions that a remote end takes when it receives a particular command.

6.3 Processing model

The remote end is an HTTP server reading requests from the client and writing responses, typically over a 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 a connection is established, the remote end must run the following steps:

  1. While the connection is not closed:

    1. Read bytes from the connection until a complete HTTP request can be constructed from the data. Let request be a request constructed from the received data, according to the requirements of [RFC7230]. If it is not possible to construct a complete HTTP request, the remote end must either close the connection, return an HTTP response with status code 500, or return an error with error code unknown error.

    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 continue.

      Otherwise, let command and URL variables be request match's data.

    4. Let session be null.

    5. If URL variables contains "session id":

      Note

      This condition is intended to exclude the New Session and Status commands and any extension commands which do not operate on a particular session.

      1. Let session id be URL variables["session id"].

      2. For each active session in the list of active sessions:

        1. If active session's session ID is equal to session id, then let session be active session, and break.

      3. If the session is null send an error with error code invalid session id, then continue.

    6. Enqueue a task on remote end's request queue to run the following steps:

      1. If session is no longer in the list of active sessions, then send an error with error code invalid session id and return.
      2. Let parameters be null.

      3. If request's method is POST:

        1. Let parse result be the result of parsing as JSON with request's body as the argument. If this process throws an exception, return an error with error code invalid argument and jump back to step 1 in this overall algorithm.

        2. If parse result is not an 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.

      4. Let navigate result be the result of wait for navigation to complete with session.

      5. If navigate result is an error, send an error with error code equal to navigate result's error code and return.

      6. Let response result be the return value obtained by running the remote end steps for command with session, URL variables, and parameters.

      7. If response result is an error, send an error with error code equal to response result's error code and return.

      8. Assert: response result is a success.

      9. Let response data be response result's data.

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

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

  1. Let 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.

    Let body be a new JSON Object initialized with the following properties:

    "error"
    name
    "message"
    message
    "stacktrace"
    stacktrace
  4. If the error data dictionary contains any entries, set the "data" field on body to a new JSON Object populated with the dictionary.

  5. Send a response with status and body 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 HTTP status to status, and status message to the string corresponding to the description of status in the status code registry.

  3. Set the response's header with name and value with the following values:

    Content-Type
    "application/json; charset=utf-8"
    Cache-Control
    "no-cache"
  4. Let response's body be the UTF-8 encoded JSON serialization of a JSON Object with a key "value" set to data.

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

  6. Write response bytes to the connection.

6.4 Routing requests

Request routing is the process of going from an 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 undefined or a path-absolute URL.

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 from endpoints for which the concatenation of the URL prefix and the entry's URI template does not have a valid expansion equal to URL's path.

  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 equal to 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. Let URI template be the concatenation of URL prefix with entry's URI template.

  8. Let command be entry's command.

  9. Let URL variables be a map with one entry for each variable defined in URI template, with the entry name equal to the template variable name, and the entry value being the variable value required to expand the URI template to match URL's path.

  10. Return success with data command and URL variables.

6.5 Endpoints

The following table of endpoints lists the method and URI template for each endpoint node command. Extension commands are implicitly appended to this table.

Method URI Template Command
POST /session New Session
DELETE /session/{session id} Delete Session
GET /status Status
GET /session/{session id}/timeouts Get Timeouts
POST /session/{session id}/timeouts Set Timeouts
POST /session/{session id}/url Navigate To
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 Get Window Handle
DELETE /session/{session id}/window Close Window
POST /session/{session id}/window Switch To Window
GET /session/{session id}/window/handles Get Window Handles
POST /session/{session id}/window/new New Window
POST /session/{session id}/frame Switch To Frame
POST /session/{session id}/frame/parent Switch To Parent Frame
GET /session/{session id}/window/rect Get Window Rect
POST /session/{session id}/window/rect Set Window Rect
POST /session/{session id}/window/maximize Maximize Window
POST /session/{session id}/window/minimize Minimize Window
POST /session/{session id}/window/fullscreen Fullscreen Window
GET /session/{session id}/element/active Get Active Element
GET /session/{session id}/element/{element id}/shadow Get Element Shadow Root
POST /session/{session id}/element Find Element
POST /session/{session id}/elements Find Elements
POST /session/{session id}/element/{element id}/element Find Element From Element
POST /session/{session id}/element/{element id}/elements Find Elements From Element
POST /session/{session id}/shadow/{shadow id}/element Find Element From Shadow Root
POST /session/{session id}/shadow/{shadow id}/elements Find Elements From Shadow Root
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}/property/{name} Get Element Property
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
GET /session/{session id}/element/{element id}/computedrole Get Computed Role
GET /session/{session id}/element/{element id}/computedlabel Get Computed Label
POST /session/{session id}/element/{element id}/click Element Click
POST /session/{session id}/element/{element id}/clear Element Clear
POST /session/{session id}/element/{element id}/value Element Send Keys
GET /session/{session id}/source Get Page Source
POST /session/{session id}/execute/sync Execute Script
POST /session/{session id}/execute/async Execute Async Script
GET /session/{session id}/cookie Get All Cookies
GET /session/{session id}/cookie/{name} Get Named Cookie
POST /session/{session id}/cookie Add Cookie
DELETE /session/{session id}/cookie/{name} Delete Cookie
DELETE /session/{session id}/cookie Delete All Cookies
POST /session/{session id}/actions Perform Actions
DELETE /session/{session id}/actions Release Actions
POST /session/{session id}/alert/dismiss 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
POST /session/{session id}/print Print Page

6.6 Errors

Errors are represented in the WebDriver protocol by an HTTP response with an HTTP status in the 4xx or 5xx range, and a JSON body containing details of the error. The body is a JSON