testdriver.js Automation

testdriver.js provides a means to automate tests that cannot be written purely using web platform APIs. Outside of automation contexts, it allows human operators to provide expected input manually (for operations which may be described in simple terms).

It is currently supported only for testharness.js tests.

Markup

The testdriver.js and testdriver-vendor.js must both be included in any document that uses testdriver (and in the top-level test document when using testdriver from a different context):

<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>

API

testdriver.js exposes its API through the test_driver variable in the global scope.

User Interaction

test_driver.click(element)

Triggers a user-initiated click

If element isn’t inside the viewport, it will be scrolled into view before the click occurs.

If element is from a different browsing context, the command will be run in that context.

Matches the behaviour of the Element Click WebDriver command.

Note: If the element to be clicked does not have a unique ID, the document must not have any DOM mutations made between the function being called and the promise settling.

Arguments
  • element (Element()) – element to be clicked

Returns

Promise – fulfilled after click occurs, or rejected in the cases the WebDriver command errors

test_driver.send_keys(element, keys)

Send keys to an element.

If element isn’t inside the viewport, it will be scrolled into view before the click occurs.

If element is from a different browsing context, the command will be run in that context.

To send special keys, send the respective key’s codepoint, as defined by WebDriver. For example, the “tab” key is represented as “\uE004”.

Note: these special-key codepoints are not necessarily what you would expect. For example, <kbd>Esc</kbd> is the invalid Unicode character \uE00C, not the \u001B Escape character from ASCII.

This matches the behaviour of the Send Keys WebDriver command.

Note: If the element to be clicked does not have a unique ID, the document must not have any DOM mutations made between the function being called and the promise settling.

Arguments
  • element (Element()) – element to send keys to

  • keys (String()) – keys to send to the element

Returns

Promise – fulfilled after keys are sent, or rejected in the cases the WebDriver command errors

test_driver.action_sequence(actions, context)

Send a sequence of actions

This function sends a sequence of actions to perform.

Matches the behaviour of the Actions feature in WebDriver.

Authors are encouraged to use the test_driver.Actions() builder rather than invoking this API directly.

Arguments
  • actions (Array()) – an array of actions. The format is the same as the actions property of the Perform Actions WebDriver command. Each element is an object representing an input source and each input source itself has an actions property detailing the behaviour of that source at each timestep (or tick). Authors are not expected to construct the actions sequence by hand, but to use the builder api provided in testdriver-actions.js

  • context (WindowProxy()) – Browsing context in which to run the call, or null for the current browsing context.

Returns

Promise – fulfilled after the actions are performed, or rejected in the cases the WebDriver command errors

test_driver.bless(intent, action, context)

Trigger user interaction in order to grant additional privileges to a provided function.

See triggered by user activation.

Arguments
  • intent (String()) – a description of the action which must be triggered by user interaction

  • action (function()) – code requiring escalated privileges

  • context (WindowProxy()) – Browsing context in which to run the call, or null for the current browsing context.

Returns

Promise – fulfilled following user interaction and execution of the provided action function; rejected if interaction fails or the provided function throws an error

Examples:

var mediaElement = document.createElement('video');

test_driver.bless('initiate media playback', function () {
  mediaElement.play();
});

Window State

test_driver.minimize_window(context)

Minimizes the browser window.

Matches the the behaviour of the Minimize WebDriver command

Arguments
  • context (WindowProxy()) – Browsing context in which to run the call, or null for the current browsing context.

Returns

Promise – fulfilled with the previous {@link https://www.w3.org/TR/webdriver/#dfn-windowrect-object|WindowRect} value, after the window is minimized.

test_driver.set_window_rect(rect, context)

Restore the window from minimized/maximized state to a given rect.

Matches the behaviour of the Set Window Rect WebDriver command

Arguments
Returns

Promise – fulfilled after the window is restored to the given rect.

Cookies

test_driver.delete_all_cookies(context)

Deletes all cookies.

Matches the behaviour of the Delete All Cookies WebDriver command.

Arguments
  • context (WindowProxy()) – Browsing context in which to run the call, or null for the current browsing context.

Returns

Promise – fulfilled after cookies are deleted, or rejected in the cases the WebDriver command errors

Permissions

test_driver.set_permission(descriptor, state, one_realm, context)

Sets the state of a permission

This function simulates a user setting a permission into a particular state.

Matches the Set Permission WebDriver command.

Arguments
  • descriptor (Object()) – a PermissionDescriptor object

  • state (String()) – the state of the permission

  • one_realm (boolean()) – Optional. Whether the permission applies to only one realm

  • context (WindowProxy()) – Browsing context in which to run the call, or null for the current browsing context.

Returns

Promise – fulfilled after the permission is set, or rejected if setting the permission fails

Examples:

await test_driver.set_permission({ name: "background-fetch" }, "denied");
await test_driver.set_permission({ name: "push", userVisibleOnly: true }, "granted", true);

Authentication

test_driver.add_virtual_authenticator(config, context)

Creates a virtual authenticator

This function creates a virtual authenticator for use with the U2F and WebAuthn APIs.

Matches the Add Virtual Authenticator WebDriver command.

Arguments
  • config (Object()) – an Authenticator Configuration object

  • context (WindowProxy()) – Browsing context in which to run the call, or null for the current browsing context.

Returns

Promise – fulfilled after the authenticator is added, or rejected in the cases the WebDriver command errors. Returns the ID of the authenticator

test_driver.remove_virtual_authenticator(authenticator_id, context)

Removes a virtual authenticator

This function removes a virtual authenticator that has been created by add_virtual_authenticator().

Matches the Remove Virtual Authenticator WebDriver command.

Arguments
  • authenticator_id (String()) – the ID of the authenticator to be removed.

  • context (WindowProxy()) – Browsing context in which to run the call, or null for the current browsing context.

Returns

Promise – fulfilled after the authenticator is removed, or rejected in the cases the WebDriver command errors

test_driver.add_credential(authenticator_id, credential, context)

Adds a credential to a virtual authenticator

Matches the Add Credential WebDriver command.

Arguments
  • authenticator_id (String()) – the ID of the authenticator

  • credential (Object()) – A Credential Parameters object

  • context (WindowProxy()) – Browsing context in which to run the call, or null for the current browsing context.

Returns

Promise – fulfilled after the credential is added, or rejected in the cases the WebDriver command errors

test_driver.get_credentials(authenticator_id, context)

Gets all the credentials stored in an authenticator

This function retrieves all the credentials (added via the U2F API, WebAuthn, or the add_credential function) stored in a virtual authenticator

Matches the Get Credentials WebDriver command.

Arguments
  • authenticator_id (String()) – the ID of the authenticator

  • context (WindowProxy()) – Browsing context in which to run the call, or null for the current browsing context.

Returns

Promise – fulfilled after the credentials are returned, or rejected in the cases the WebDriver command errors. Returns an array of Credential Parameters

test_driver.remove_credential(authenticator_id, credential_id, context)

Remove a credential stored in an authenticator

Matches the Remove Credential WebDriver command.

Arguments
  • authenticator_id (String()) – the ID of the authenticator

  • credential_id (String()) – the ID of the credential

  • context (WindowProxy()) – Browsing context in which to run the call, or null for the current browsing context.

Returns

Promise – fulfilled after the credential is removed, or rejected in the cases the WebDriver command errors.

test_driver.remove_all_credentials(authenticator_id, context)

Removes all the credentials stored in a virtual authenticator

Matches the Remove All Credentials WebDriver command.

Arguments
  • authenticator_id (String()) – the ID of the authenticator

  • context (WindowProxy()) – Browsing context in which to run the call, or null for the current browsing context.

Returns

Promise – fulfilled after the credentials are removed, or rejected in the cases the WebDriver command errors.

test_driver.set_user_verified(authenticator_id, uv, context)

Sets the User Verified flag on an authenticator

Sets whether requests requiring user verification will succeed or fail on a given virtual authenticator

Matches the Set User Verified WebDriver command.

Arguments
  • authenticator_id (String()) – the ID of the authenticator

  • uv (boolean()) – the User Verified flag

  • context (WindowProxy()) – Browsing context in which to run the call, or null for the current browsing context.

Page Lifecycle

test_driver.freeze(context)

Freeze the current page

The freeze function transitions the page from the HIDDEN state to the FROZEN state as described in Lifecycle API for Web Pages.

Arguments
  • context (WindowProxy()) – Browsing context in which to run the call, or null for the current browsing context.

Returns

Promise – fulfilled after the freeze request is sent, or rejected in case the WebDriver command errors

Reporting Observer

test_driver.generate_test_report(context)

Generates a test report on the current page

The generate_test_report function generates a report (to be observed by ReportingObserver) for testing purposes.

Matches the Generate Test Report WebDriver command.

Arguments
  • context (WindowProxy()) – Browsing context in which to run the call, or null for the current browsing context.

Returns

Promise – fulfilled after the report is generated, or rejected if the report generation fails

Storage

test_driver.set_storage_access(origin, embedding_origin, state, context)

Sets the storage access rule for an origin when embedded in a third-party context.

Matches the Set Storage Access WebDriver command.

Arguments
  • origin (String()) – A third-party origin to block or allow. May be “*” to indicate all origins.

  • embedding_origin (String()) – an embedding (first-party) origin on which {origin}’s access should be blocked or allowed. May be “*” to indicate all origins.

  • state (String()) – The storage access setting. Must be either “allowed” or “blocked”.

  • context (WindowProxy()) – Browsing context in which to run the call, or null for the current browsing context.

Returns

Promise – Fulfilled after the storage access rule has been set, or rejected if setting the rule fails.

Seure Payment Confirmation

test_driver.set_spc_transaction_mode(mode, context)

Sets the current transaction automation mode for Secure Payment Confirmation.

This function places Secure Payment Confirmation into an automated ‘autoaccept’ or ‘autoreject’ mode, to allow testing without user interaction with the transaction UX prompt.

Matches the Set SPC Transaction Mode WebDriver command.

Arguments
  • mode (String()) – The transaction mode to set. Must be one of “none”, “autoaccept”, or “autoreject”.

  • context (WindowProxy()) – Browsing context in which to run the call, or null for the current browsing context.

Returns

Promise – Fulfilled after the transaction mode has been set, or rejected if setting the mode fails.

Examples:

await test_driver.set_spc_transaction_mode("autoaccept");
test.add_cleanup(() => {
  return test_driver.set_spc_transaction_mode("none");
});

// Assumption: `request` is a PaymentRequest with a secure-payment-confirmation
// payment method.
const response = await request.show();

Using test_driver in other browsing contexts

Testdriver can be used in browsing contexts (i.e. windows or frames) from which it’s possible to get a reference to the top-level test context. There are two basic approaches depending on whether the context in which testdriver is used is same-origin with the test context, or different origin.

For same-origin contexts, the context can be passed directly into the testdriver API calls. For functions that take an element argument this is done implicitly using the owner document of the element. For functions that don’t take an element, this is done via an explicit context argument, which takes a WindowProxy object.

Example:

let win = window.open("example.html")
win.onload = () => {
  await test_driver.set_permission({ name: "background-fetch" }, "denied", win);
}
test_driver.set_test_context(context)

Set the context in which testharness.js is loaded

Arguments
  • context (WindowProxy()) – the window containing testharness.js

test_driver.message_test(msg)

postMessage to the context containing testharness.js

Arguments
  • msg (Object()) – the data to POST

For cross-origin cases, passing in the context doesn’t work because of limitations in the WebDriver protocol used to implement testdriver in a cross-browser fashion. Instead one may include the testdriver scripts directly in the relevant document, and use the test_driver.set_test_context API to specify the browsing context containing testharness.js. Commands are then sent via postMessage to the test context. For convenience there is also a test_driver.message_test function that can be used to send arbitary messages to the test window. For example, in an auxillary browsing context:

testdriver.set_test_context(window.opener)
await testdriver.click(document.getElementsByTagName("button")[0])
testdriver.message_test("click complete")

The requirement to have a handle to the test window does mean it’s currently not possible to write tests where such handles can’t be obtained e.g. in the case of rel=noopener.

Actions

Markup

To use the Actions API testdriver-actions.js must be included in the document, in addition to testdriver.js:

<script src="/resources/testdriver-actions.js"></script>

API

class Actions(defaultTickDuration=16)

Builder for creating a sequence of actions

The actions are dispatched once test_driver.Actions.send() is called. This returns a promise which resolves once the actions are complete.

The other methods on test_driver.Actions() object are used to build the sequence of actions that will be sent. These return the Actions object itself, so the actions sequence can be constructed by chaining method calls.

Internally test_driver.Actions.send() invokes test_driver.action_sequence().

Arguments
  • defaultTickDuration (number()) – The default duration of a tick. Be default this is set ot 16ms, which is one frame time based on 60Hz display.

Examples:

let text_box = document.getElementById("text");

let actions = new test_driver.Actions()
   .pointerMove(0, 0, {origin: text_box})
   .pointerDown()
   .pointerUp()
   .addTick()
   .keyDown("p")
   .keyUp("p");

await actions.send();
Actions.addKeyboard(name, set)

Add a new key input source with the given name

Arguments
  • name (String()) – Name of the key source

  • set (Bool()) – Set source as the default key source

Returns

Actions

Actions.addPointer(type, pointerType, set)

Add a new pointer input source with the given name

Arguments
  • type (String()) – Name of the pointer source

  • pointerType (String()) – Type of pointing device

  • set (Bool()) – Set source as the default pointer source

Returns

Actions

Actions.addTick(duration)

Insert a new actions tick

Arguments
  • duration (Number()) – Minimum length of the tick in ms.

Returns

Actions

Actions.addWheel(type, set)

Add a new wheel input source with the given name

Arguments
  • type (String()) – Name of the wheel source

  • set (Bool()) – Set source as the default wheel source

Returns

Actions

Actions.getSource(type, name)

Get the action source with a particular source type and name. If no name is passed, a new source with the given type is created.

Arguments
  • type (String()) – Source type (‘none’, ‘key’, ‘pointer’, or ‘wheel’)

  • name (String()) – Name of the source

Returns

Source – Source object for that source.

Actions.keyDown(key, sourceName)

Create a keyDown event for the current default key source

Arguments
  • key (String()) – Key to press

  • sourceName (String()) – Named key source to use or null for the default key source

Returns

Actions

Actions.keyUp(key, sourceName)

Create a keyDown event for the current default key source

Arguments
  • key (String()) – Key to release

  • sourceName (String()) – Named key source to use or null for the default key source

Returns

Actions

Actions.pause(duration, sourceType, sourceName)

Add a pause to the current tick

Arguments
  • duration (Number()) – Minimum length of the tick in ms.

  • sourceType (String()) – source type

  • sourceName (String()) – Named key, pointer or wheel source to use or null for the default key, pointer or wheel source

Returns

Actions

Actions.pointerDown(button, sourceName)

Create a pointerDown event for the current default pointer source

Arguments
  • button (String()) – Button to press

  • sourceName (String()) – Named pointer source to use or null for the default pointer source

Returns

Actions

Actions.pointerMove(x, y, origin, duration, sourceName)

Create a move event for the current default pointer source

Arguments
  • x (Number()) – Destination x coordinate

  • y (Number()) – Destination y coordinate

  • origin (String|Element()) – Origin of the coordinate system. Either “pointer”, “viewport” or an Element

  • duration (Number()) – Time in ms for the move

  • sourceName (String()) – Named pointer source to use or null for the default pointer source

Returns

Actions

Actions.pointerUp(button, sourceName)

Create a pointerUp event for the current default pointer source

Arguments
  • button (String()) – Button to release

  • sourceName (String()) – Named pointer source to use or null for the default pointer source

Returns

Actions

Actions.scroll(x, y, deltaX, deltaY, origin, duration, sourceName)

Create a scroll event for the current default wheel source

Arguments
  • x (Number()) – mouse cursor x coordinate

  • y (Number()) – mouse cursor y coordinate

  • deltaX (Number()) – scroll delta value along the x-axis in pixels

  • deltaY (Number()) – scroll delta value along the y-axis in pixels

  • origin (String|Element()) – Origin of the coordinate system. Either “viewport” or an Element

  • duration (Number()) – Time in ms for the scroll

  • sourceName (String()) – Named wheel source to use or null for the default wheel source

Returns

Actions

Actions.send()

Generate and send the action sequence

Returns

Promise – fulfilled after the sequence is executed, rejected if any actions fail.

Actions.serialize()

Generate the action sequence suitable for passing to test_driver.action_sequence

Returns

Array – Array of WebDriver-compatible actions sequences

Actions.setContext(context)

Set the context for the actions

Arguments
  • context (WindowProxy()) – Context in which to run the action sequence

Actions.setKeyboard(name)

Set the current default key source

Arguments
  • name (String()) – Name of the key source

Returns

Actions

Actions.setPointer(name)

Set the current default pointer source

Arguments
  • name (String()) – Name of the pointer source

Returns

Actions

Actions.setWheel(name)

Set the current default wheel source

Arguments
  • name (String()) – Name of the wheel source

Returns

Actions

Using in other browsing contexts

For the actions API, the context can be set using the setContext method on the builder:

let actions = new test_driver.Actions()
    .setContext(frames[0])
    .keyDown("p")
    .keyUp("p");
await actions.send();

Note that if an action uses an element reference, the context will be derived from that element, and must match any explictly set context. Using elements in multiple contexts in a single action chain is not supported.

send_keys

Usage: test_driver.send_keys(element, keys)

  • element: a DOM Element object

  • keys: string to send to the element

This function causes the string keys to be sent to the target element (an Element object), potentially scrolling the document to make it possible to send keys. It returns a promise that resolves after the keys have been sent, or rejects if the keys cannot be sent to the element.

This works with elements in other frames/windows as long as they are same-origin with the test, and the test does not depend on the window.name property remaining unset on the target window.

Note that if the element that the keys need to be sent to does not have a unique ID, the document must not have any DOM mutations made between the function being called and the promise settling.

To send special keys, one must send the respective key’s codepoint. Since this uses the WebDriver protocol, you can find a list for code points to special keys in the spec. For example, to send the tab key you would send “\uE004”.

Note: these special-key codepoints are not necessarily what you would expect. For example, Esc is the invalid Unicode character \uE00C, not the \u001B Escape character from ASCII.

set_permission

Usage: test_driver.set_permission(descriptor, state, one_realm=false, context=null)

  • descriptor: a PermissionDescriptor or derived object

  • state: a PermissionState value

  • one_realm: a boolean that indicates whether the permission settings apply to only one realm

  • context: a WindowProxy for the browsing context in which to perform the call

This function causes permission requests and queries for the status of a certain permission type (e.g. “push”, or “background-fetch”) to always return state. It returns a promise that resolves after the permission has been set to be overridden with state.

Example:

await test_driver.set_permission({ name: "background-fetch" }, "denied");
await test_driver.set_permission({ name: "push", userVisibleOnly: true }, "granted", true);