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

static 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

static 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. The test must not depend on the window.name property being unset on the target window.

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

static 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

static test_driver.bless(intent, action, context)

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

See Tracking 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

static 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 WindowRect value, after the window is minimized.

static 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:
  • rect (Object) – A WindowRect

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

Returns:

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

Cookies

static 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

static test_driver.get_all_cookies(context)

Get details for all cookies in the current context. See https://w3c.github.io/webdriver/#get-all-cookies

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

Returns:

Promise – Returns an array of cookies objects as defined in the spec: https://w3c.github.io/webdriver/#cookies

Get details for a cookie in the current context by name if it exists. See https://w3c.github.io/webdriver/#get-named-cookie

Arguments:
  • name (String) – The name of the cookie to get.

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

Returns:

Promise – Returns the matching cookie as defined in the spec: https://w3c.github.io/webdriver/#cookies Rejected if no such cookie exists.

Permissions

static test_driver.set_permission(descriptor, state, context)

Sets the state of a permission

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.

Matches the Set Permission WebDriver command.

Arguments:
  • descriptor (PermissionDescriptor) – a PermissionDescriptor or derived object.

  • state (PermissionState) – a PermissionState value.

  • 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");

Authentication

static 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

static 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

static 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

static 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

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

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

static 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

static 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

static 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

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

Accessibility

static test_driver.get_computed_label(element)

Get Computed Label for an element.

This matches the behaviour of the Get Computed Label WebDriver command.

Arguments:
  • element (Element) –

Returns:

Promise – fulfilled after the computed label is returned, or rejected in the cases the WebDriver command errors

static test_driver.get_computed_role(element)

Get Computed Role for an element.

This matches the behaviour of the Get Computed Label WebDriver command.

Arguments:
  • element (Element) –

Returns:

Promise – fulfilled after the computed role is returned, or rejected in the cases the WebDriver command errors

Secure Payment Confirmation

static 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();

Federated Credential Management

static test_driver.cancel_fedcm_dialog(context)

Cancels the Federated Credential Management dialog

Matches the Cancel dialog 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 dialog is canceled, or rejected in case the WebDriver command errors

static test_driver.click_fedcm_dialog_button(dialog_button, context)

Clicks a button on the Federated Credential Management dialog

Matches the Click dialog button WebDriver command.

Arguments:
  • dialog_button (String) – String enum representing the dialog button to click.

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

Returns:

Promise – Fulfilled after the button is clicked, or rejected in case the WebDriver command errors

static test_driver.select_fedcm_account(account_index, context)

Selects an account from the Federated Credential Management dialog

Matches the Select account WebDriver command.

Arguments:
  • account_index (number) – Index of the account to select.

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

Returns:

Promise – Fulfilled after the account is selected, or rejected in case the WebDriver command errors

static test_driver.get_fedcm_account_list(context)

Gets the account list from the Federated Credential Management dialog

Matches the Account list 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 account list is returned, or rejected in case the WebDriver command errors

static test_driver.get_fedcm_dialog_title(context)

Gets the title of the Federated Credential Management dialog

Matches the Get title 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 title is returned, or rejected in case the WebDriver command errors

static test_driver.get_fedcm_dialog_type(context)

Gets the type of the Federated Credential Management dialog

Matches the Get dialog type 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 dialog type is returned, or rejected in case the WebDriver command errors

static test_driver.set_fedcm_delay_enabled(enabled, context)

Sets whether promise rejection delay is enabled for the Federated Credential Management dialog

Matches the Set delay enabled WebDriver command.

Arguments:
  • enabled (boolean) – Whether to delay FedCM promise rejection.

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

Returns:

Promise – Fulfilled after the delay has been enabled or disabled, or rejected in case the WebDriver command errors

static test_driver.reset_fedcm_cooldown(context)

Resets the Federated Credential Management dialog’s cooldown

Matches the Reset cooldown 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 cooldown has been reset, or rejected in case the WebDriver command errors

Sensors

static test_driver.create_virtual_sensor(sensor_type, sensor_params={}, context=null)

Creates a virtual sensor for use with the Generic Sensors APIs.

Matches the Create Virtual Sensor WebDriver command.

Once created, a virtual sensor is available to all navigables under the same top-level traversable (i.e. all frames in the same page, regardless of origin).

Arguments:
  • sensor_type (String) – A virtual sensor type such as “accelerometer”.

  • sensor_params (Object) –

    Optional parameters described in Create Virtual Sensor.

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

Returns:

Promise – Fulfilled when virtual sensor is created. Rejected in case the WebDriver command errors out (including if a virtual sensor of the same type already exists).

static test_driver.update_virtual_sensor(sensor_type, reading, context=null)

Causes a virtual sensor to report a new reading to any connected platform sensor.

Matches the Update Virtual Sensor Reading WebDriver command.

Note: The Promise it returns may fulfill before or after a “reading” event is fired. When using EventWatcher.wait_for(), it is necessary to take this into account:

Note: New values may also be discarded due to the checks in update latest reading.

Arguments:
  • sensor_type (String) – A virtual sensor type such as “accelerometer”.

  • reading (Object) – An Object describing a reading in a format dependent on sensor_type (e.g. {x: 1, y: 2, z: 3} or { illuminance: 42 }).

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

Returns:

Promise – Fulfilled after the reading update reaches the virtual sensor. Rejected in case the WebDriver command errors out (including if a virtual sensor of the given type does not exist).

Examples:

// Avoid races between EventWatcher and update_virtual_sensor().
// This assumes you are sure this reading will be processed (see
// the example below otherwise).
const reading = { x: 1, y: 2, z: 3 };
await Promise.all([
  test_driver.update_virtual_sensor('gyroscope', reading),
  watcher.wait_for('reading')
]);
// Do not wait forever if you are not sure the reading will be
// processed.
const readingPromise = watcher.wait_for('reading');
const timeoutPromise = new Promise(resolve => {
    t.step_timeout(() => resolve('TIMEOUT', 3000))
});

const reading = { x: 1, y: 2, z: 3 };
await test_driver.update_virtual_sensor('gyroscope', 'reading');

const value =
    await Promise.race([timeoutPromise, readingPromise]);
if (value !== 'TIMEOUT') {
  // Do something. The "reading" event was fired.
}
static test_driver.remove_virtual_sensor(sensor_type, context=null)

Triggers the removal of a virtual sensor if it exists.

Matches the Delete Virtual Sensor WebDriver command.

Arguments:
  • sensor_type (String) – A virtual sensor type such as “accelerometer”.

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

Returns:

Promise – Fulfilled after the virtual sensor has been removed or if a sensor of the given type does not exist. Rejected in case the WebDriver command errors out.

static test_driver.get_virtual_sensor_information(sensor_type, context=null)

Returns information about a virtual sensor.

Matches the Get Virtual Sensor Information WebDriver command.

Arguments:
  • sensor_type (String) – A virtual sensor type such as “accelerometer”.

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

Returns:

Promise – Fulfilled with an Object with the properties described in Get Virtual Sensor Information. Rejected in case the WebDriver command errors out (including if a virtual sensor of the given type does not exist).

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);
}
static test_driver.set_test_context(context)

Set the context in which testharness.js is loaded

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

static 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 arbitrary messages to the test window. For example, in an auxillary browsing context:

test_driver.set_test_context(window.opener)
await test_driver.click(document.getElementsByTagName("button")[0])
test_driver.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 explicitly set context. Using elements in multiple contexts in a single action chain is not supported.