# WebUSB Testing API

## Editor’s Draft, 1 January 1970

This version:
  https://wicg.github.io/webusb/test/
Editors:
  Reilly Grant (Google LLC)
  Ovidio Henriquez (Google LLC)
Participate:
  Join the W3C Community Group
  IRC: #webusb on W3C’s IRC (Stay around for an answer, it make take a while)

Copyright © 1970 the Contributors to the WebUSB Testing API Specification, published by the Web Platform Incubator Community Group under the W3C Community Contributor License Agreement (CLA). A human-readable summary is available.

## Abstract

This document describes an API for testing a User Agent’s implementation of the WebUSB API.

## Status of this document

This specification was published by the Web Platform Incubator Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups.

## 1. Introduction

This section is non-normative.

Standards such as [WebUSB] pose a challenge to test authors because to fully exercise their interfaces requires physical hardware devices that respond in predictable ways. To address this challenge this specification defines an interface for controlling a simulation of the USB subsystem on the host the User Agent (UA) is running on. With this interface devices with particular properties can be created and their responses to requests are well defined.

The purpose if this interface is to assist the developers of UAs and so this interface does not permit arbitrary control over the behavior of devices. Some parameters are configurable and some are specified.

The only intended client of this API are tests in Web Platform Tests. This testing API will be changed as needed to support the evolution of those tests.

Testing applications that use WebUSB is specifically not in scope for this API. It not designed for that purpose. And, the ability to make breaking changes to this API has higher priority.

### 1.1. Examples

This example, expressed as a W3C testharness.js-based test, demonstrates initializing this API and using it to verify that devices can be added and removed.

    let fakeDeviceInit = {
      usbVersionMajor: 2,
      usbVersionMinor: 0,
      usbVersionSubminor: 0,
      deviceClass: 0xFF,
      deviceSubclass: 0xFF,
      deviceProtocol: 0xFF,
      vendorId: 0x1234,
      productId: 0xABCD,
      deviceVersionMajor: 1,
      deviceVersionMinor: 0,
      deviceVersionSubminor: 0,
      configurations: []
    };

    function promiseForEvent(eventTarget, eventType) {
      return new Promise(resolve => {
        let eventHandler = evt => {
          resolve(evt);
          eventTarget.removeEventListener(eventTarget, eventHandler);
        };
        eventTarget.addEventListener(eventType);
      });
    }

    promise_test(async () => {
      await navigator.usb.test.initialize();

      let fakeDevice = navigator.usb.addFakeDevice(fakeDeviceInit);
      let connectEvent = await promiseForEvent(navigator.usb, 'connect');
      let device = connectEvent.device;
      assert_equals(device.usbVersionMajor, fakeDeviceInit.usbVersionMajor);
      assert_equals(device.usbVersionMinor, fakeDeviceInit.usbVersionMinor);
      assert_equals(device.usbVersionSubminor, fakeDeviceInit.usbVersionSubminor);
      assert_equals(device.deviceClass, fakeDeviceInit.deviceClass);
      assert_equals(device.deviceSubclass, fakeDeviceInit.deviceSubclass);
      assert_equals(device.deviceProtocol, fakeDeviceInit.deviceProtocol);
      assert_equals(device.vendorId, fakeDeviceInit.vendorId);
      assert_equals(device.productId, fakeDeviceInit.productId);
      assert_equals(device.deviceVersionMajor, fakeDeviceInit.deviceVersionMajor);
      assert_equals(device.deviceVersionMinor, fakeDeviceInit.deviceVersionMinor);
      assert_equals(device.deviceVersionSubminor, fakeDeviceInit.deviceVersionSubminor);
      assert_equals(device.configuration, null);
      assert_equals(device.configurations.length, 0);

      let devices = await navigator.usb.getDevices();
      assert_array_equals(devices, [device]);

      fakeDevice.disconnect();
      let disconnectEvent = await promiseForEvent(navigator.usb, 'disconnect');
      assert_equals(disconnectEvent.device, device);
    });

This example, which reuses definitions from the previous example and is also expressed as a W3C testharness.js-based test, demonstrates a test of the `navigator.usb.requestDevice()` method.

    promise_test(async () => {
      await navigator.usb.test.initialize();
      let fakeDevice = navigator.usb.addFakeDevice(fakeDeviceInit);
      let connectEvent = await promiseForEvent(navigator.usb, 'connect');
      navigator.usb.test.onrequestdevice = () => connectEvent.device;

      let options = { filters: [{ vendorId: 0x1234 }] };
      let device = await navigator.usb.requestDevice(options);
      assert_array_equals(navigator.usb.test.lastFilters, options.filters);
      assert_equals(device, connectEvent.device);
    }

Note: If multiple tests are run in the same document then the test harness should invoke `reset()` and wait until the `Promise` it returns is resolved before executing the next test.

## 2. Availability

This specification defines an interface that is not intended be used by non-testing-related web content. The UA MAY choose to expose this interface only when a runtime or compile-time flag has been set.

Note, as an example, in the Chromium Project this specification is implemented by a JavaScript polyfill on top of a lower-level interface. This interface is only available in a binary explicitly built for running web platform test cases. A runtime flag is also necessary to enable this testing mode. This design has two benefits,

1. The risk of introducing a security vulnerability in the default configuration is mitigated.

2. The polyfill is not shipped with the production application and so there is no increase in binary size to support an API that will rarely be used.

## 3. Global Testing Interface

    partial interface USB {
      [SameObject] readonly attribute USBTest test;
    };

    interface USBDeviceRequestEvent : Event {
      attribute FrozenArray<USBDeviceFilter> filters;

      void respondWith(Promise<FakeUSBDevice> result);
    };

    interface USBTest {
      attribute EventHandler onrequestdevice;

      Promise<void> initialize();
      Promise<void> attachToContext((HTMLIFrameElement or Worker) context);
      FakeUSBDevice addFakeDevice(FakeUSBDeviceInit deviceInit);
      Promise<void> reset();
    };

By default, a UA SHALL NOT alter the behavior of a `USB` instance usb in any global object until it is reconfigured so that usb is controlled by a `USBTest` instance test. At that point the behavior of usb is defined by this specification.

Instances of `USBTest` are created with an internal slot `[[initializationPromise]]` with an initial value of `null`.

When invoked, the `initialize()` method MUST run these steps:

1. Let test be the `USBTest` instance on which this method was invoked.

2. If test.`[[initializationPromise]]` is `null` then set test.`[[initializationPromise]]` to a new `Promise` and run these sub-steps in parallel:

   1. Reconfigure the UA’s internal implementation of the `usb` object in the current global object so that it is controlled by test.

   2. Resolve test.`[[initializationPromise]]`.

3. Return test.`[[initializationPromise]]`.

When invoked, the `attachToContext(context)` method MUST return a new `Promise` promise and run these steps in parallel:

1. Let test be the `USBTest` instance on which this method was invoked.

2. If test.`[[initializationPromise]]` is not in the resolved state, reject promise with an `InvalidStateError` and abort these steps.

3. Reconfigure the UA’s internal implementation of `usb` in the global object associated with context so that it is controlled by test.

4. Resolve promise.

When invoked, the `addFakeDevice(deviceInit)` method MUST run these steps:

1. Let test be the `USBTest` instance on which this method was invoked.

2. If test.`[[initializationPromise]]` is not in the resolved state, raise an `InvalidStateError` and abort these steps.

3. Let fakeDevice be a new `FakeUSBDevice`.

4. Queue a task to, for each `USB` instance controlled by test, perform the steps described in [WebUSB] for handling a new device that is connected to the system.

5. Return fakeDevice.

When invoked, the `reset()` method MUST return a new `Promise` promise and run the following steps in parallel:

1. Let test be the `USBTest` instance on which this method was invoked.

2. For each `FakeUSBDevice` fakeDevice previously returned by `addFakeDevice()`, invoke fakeDevice.`disconnect()`.

3. Resolve promise.

`USBDeviceRequestEvent` instances have an internal slot `[[promise]]` that holds a `Promise`.

When invoked, the `respondWith(result)` method MUST run the following steps in parallel:

1. Wait until result settles.

2. Let event be the `USBDeviceRequestEvent` instance on which this method was invoked.

3. If result resolved with response and response is an instance of `FakeUSBDevice` resolve event@`[[promise]]` with device.

4. Otherwise, reject event@`[[promise]]` with a `NotFoundError`.

### 3.1. `USB` Behavior

When `requestDevice(options)` is invoked on a `USB` instance controlled by a `USBTest` test the UA MUST return a new `Promise` promise and perform the following steps in parallel:

1. Let event be a new `USBDeviceRequestEvent`.

2. Set event.filters to a new `FrozenArray`.

3. Copy the members of options.`filters` into event.filters.

4. Set event@`[[promise]]` to promise.

5. Fire an event named requestdevice on test, using event as the event object.

### 3.2. Events

requestdevice: Fired on a `USBTest` object when `requestDevice(options)` is invoked after `initialize()` has been called.

## 4. Fake Devices

To permit testing without physical hardware this specification defines a method for tests to add simulated USB devices by calling `addFakeDevice()` with an instance of `FakeUSBDeviceInit` containing the properties of the device to be added.

    interface FakeUSBDevice : EventTarget {
      attribute EventHandler onclose;

      void disconnect();
    };

    dictionary FakeUSBDeviceInit {
      required octet usbVersionMajor;
      required octet usbVersionMinor;
      required octet usbVersionSubminor;
      required octet deviceClass;
      required octet deviceSubclass;
      required octet deviceProtocol;
      required unsigned short vendorId;
      required unsigned short productId;
      required octet deviceVersionMajor;
      required octet deviceVersionMinor;
      required octet deviceVersionSubminor;
      DOMString? manufacturerName;
      DOMString? productName;
      DOMString? serialNumber;
      octet activeConfigurationValue = 0;
      sequence<FakeUSBConfigurationInit> configurations;
    };

    dictionary FakeUSBConfigurationInit {
      required octet configurationValue;
      DOMString? configurationName;
      sequence<FakeUSBInterfaceInit> interfaces;
    };

    dictionary FakeUSBInterfaceInit {
      required octet interfaceNumber;
      sequence<FakeUSBAlternateInterfaceInit> alternates;
    };

    dictionary FakeUSBAlternateInterfaceInit {
      required octet alternateSetting;
      required octet interfaceClass;
      required octet interfaceSubclass;
      required octet interfaceProtocol;
      DOMString? interfaceName;
      sequence<FakeUSBEndpointInit> endpoints;
    };

    dictionary FakeUSBEndpointInit {
      required octet endpointNumber;
      required USBDirection direction;
      required USBEndpointType type;
      required unsigned long packetSize;
    };

When a `USBDevice` device is initialized from an fake USB device described by a `FakeUSBDeviceInit` init passed to `addFakeDevice()` the attributes of device SHALL be initialized as follows and device will correspond to the `FakeUSBDevice` returned by `addFakeDevice()`:

1. For each non-sequence attribute of init other than `activeConfigurationValue` the attribute of device with the same name SHALL be set to its value.

2. For each sequence of `FakeUSBConfigurationInit`, `FakeUSBInterfaceInit` `FakeUSBAlternateInterfaceInit` and `FakeUSBEndpointInit` objects corresponding `USBConfiguration`, `USBInterface`, `USBAlternateInterface` and `USBEndpoint` objects SHALL be created by similarly copying attributes with the same names and be used to build an identical hierarchy of objects in the `configurations`, `interfaces`, `alternates` and `endpoints` `FrozenArray`s.

3. If a `USBConfiguration` instance config with `configurationValue` equal to init.`activeConfigurationValue` then device.`configuration` SHALL be set to config, otherwise `null`.

When invoked, the `disconnect()` method MUST, queue a task to, for each `USB` instance controlled by the `USBTest` instance from which target of this invocation was returned, perform the steps described in [WebUSB] for handling the removal of a device that was connected to the system.

### 4.1. `USBDevice` Behavior

When the `open()`, `close()`, `selectConfiguration()`, `claimInterface()`, `releaseInterface()`, `selectAlternateInterface()`, `clearHalt()` and `reset()` methods are invoked on a `USBDevice` device corresponding to a `FakeUSBDevice` the UA MUST behave as though device contains the configurations, interfaces and endpoints described in the `FakeUSBDeviceInit` from which device was initialized exist and can be claimed by the caller.

When `close()` is invoked on a `USBDevice` device the UA MUST fire an event named `close` at the `FakeUSBDevice` instance corresponding to device, if one exists.

When `controlTransferIn(setup, length)` is invoked on a `USBDevice` device corresponding to a `FakeUSBDevice` the UA MUST, assuming all other pre-conditions for the operation are satisfied, behave as though the device responded with a packet containing the bytes `[length >> 8, length & 0xFF, setup.`request`, setup.`value` >> 8, setup.`value` & 0xFF, setup.`index` >> 8, setup.`index` & 0xFF]`, truncated to length bytes.

When `controlTransferOut(setup, data)` is invoked on a `USBDevice` device corresponding to a `FakeUSBDevice` the UA MUST, assuming all other pre-conditions for the operation are satisfied, behave as though the transfer succeeded in sending data.`length` bytes.

When `transferIn(endpointNumber, length)` is invoked on a `USBDevice` device corresponding to a `FakeUSBDevice` the UA MUST, assuming all other pre-conditions for the operation are satisfied, behave as though the device responded with length bytes of data consisting of the values `0` through `255` repeated as necessary.

When `transferOut(endpointNumber, data)` is invoked on a `USBDevice` device corresponding to a `FakeUSBDevice` the UA MUST, assuming all other pre-conditions for the operation are satisfied, behave as though the transfer succeeded in sending data.`length` bytes.

When `isochronousTransferIn(endpointNumber, packetLengths)` is invoked on a `USBDevice` device corresponding to a `FakeUSBDevice` the UA MUST, assuming all other pre-conditions for the operation are satisfied, behave as though the device responded with packetLengths.`length` packets, each containing packetLengths`[i]` bytes of data consisting of the values `0` through `255` repeated as necessary.

When `isochronousTransferOut(endpointNumber, data, packetLengths)` is invoked on a `USBDevice` device corresponding to a `FakeUSBDevice` the UA MUST, assuming all other pre-conditions for the operation are satisfied, behave as though the transfer succeeded in sending packetLengths.`length` packets, each containing packetLengths`[i]` bytes.

## Conformance

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with `class="example"`, like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with `class="note"`, like this:

Note, this is an informative note.

## Index

### Terms defined by this specification

- activeConfigurationValue, in §4
- addFakeDevice(deviceInit), in §3
- alternates, in §4
- alternateSetting, in §4
- attachToContext(context), in §3
- configurationName, in §4
- configurations, in §4
- configurationValue, in §4
- controlled by, in §3
- corresponding to, in §4
- correspond to, in §4
- deviceClass, in §4
- deviceProtocol, in §4
- deviceSubclass, in §4
- deviceVersionMajor, in §4
- deviceVersionMinor, in §4
- deviceVersionSubminor, in §4
- direction, in §4
- disconnect(), in §4
- endpointNumber, in §4
- endpoints, in §4
- FakeUSBAlternateInterfaceInit, in §4
- FakeUSBConfigurationInit, in §4
- FakeUSBDevice, in §4
- FakeUSBDeviceInit, in §4
- FakeUSBEndpointInit, in §4
- FakeUSBInterfaceInit, in §4
- filters, in §3
- [[initializationPromise]], in §3
- initialize(), in §3
- interfaceClass, in §4
- interfaceName, in §4
- interfaceNumber, in §4
- interfaceProtocol, in §4
- interfaces, in §4
- interfaceSubclass, in §4
- manufacturerName, in §4
- onclose, in §4
- onrequestdevice, in §3
- packetSize, in §4
- productId, in §4
- productName, in §4
- [[promise]], in §3
- requestdevice, in §3.2
- reset(), in §3
- respondWith(result), in §3
- serialNumber, in §4
- test, in §3
- type, in §4
- USBDeviceRequestEvent, in §3
- USBTest, in §3
- usbVersionMajor, in §4
- usbVersionMinor, in §4
- usbVersionSubminor, in §4
- vendorId, in §4

https://dom.spec.whatwg.org/#event Referenced in:

- 3. Global Testing Interface

https://dom.spec.whatwg.org/#eventtarget Referenced in:

- 4. Fake Devices

https://dom.spec.whatwg.org/#concept-event-fire Referenced in:

- 3.1. USB Behavior
- 4.1. USBDevice Behavior

https://tc39.github.io/ecma262/#sec-object-internal-methods-and-internal-slots Referenced in:

- 3. Global Testing Interface (2)

https://html.spec.whatwg.org/multipage/webappapis.html#eventhandler Referenced in:

- 3. Global Testing Interface
- 4. Fake Devices

https://html.spec.whatwg.org/multipage/iframe-embed-object.html#htmliframeelement Referenced in:

- 3. Global Testing Interface

https://html.spec.whatwg.org/multipage/workers.html#worker Referenced in:

- 3. Global Testing Interface

https://html.spec.whatwg.org/multipage/webappapis.html#current-global-object Referenced in:

- 3. Global Testing Interface

https://html.spec.whatwg.org/multipage/webappapis.html#global-object Referenced in:

- 3. Global Testing Interface (2)

https://html.spec.whatwg.org/multipage/infrastructure.html#in-parallel Referenced in:

- 3. Global Testing Interface (2) (3) (4)
- 3.1. USB Behavior

https://html.spec.whatwg.org/multipage/webappapis.html#queue-a-task Referenced in:

- 3. Global Testing Interface
- 4. Fake Devices

https://heycam.github.io/webidl/#idl-DOMString Referenced in:

- 4. Fake Devices (2) (3) (4) (5)

https://heycam.github.io/webidl/#idl-frozen-array Referenced in:

- 3.1. USB Behavior
- 4. Fake Devices

https://heycam.github.io/webidl/#invalidstateerror Referenced in:

- 3. Global Testing Interface (2)

https://heycam.github.io/webidl/#notfounderror Referenced in:

- 3. Global Testing Interface

https://heycam.github.io/webidl/#idl-promise Referenced in:

- 1.1. Examples
- 3. Global Testing Interface (2) (3) (4)
- 3.1. USB Behavior

https://heycam.github.io/webidl/#SameObject Referenced in:

- 3. Global Testing Interface

https://heycam.github.io/webidl/#idl-octet Referenced in:

- 4. Fake Devices (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) (15) (16) (17)

https://heycam.github.io/webidl/#idl-unsigned-long Referenced in:

- 4. Fake Devices

https://heycam.github.io/webidl/#idl-unsigned-short Referenced in:

- 4. Fake Devices (2)

https://wicg.github.io/webusb/#usb Referenced in:

- 3. Global Testing Interface (2) (3)
- 3.1. USB Behavior (2)
- 4. Fake Devices

https://wicg.github.io/webusb/#usbalternateinterface Referenced in:

- 4. Fake Devices

https://wicg.github.io/webusb/#usbconfiguration Referenced in:

- 4. Fake Devices (2)

https://wicg.github.io/webusb/#usbdevice Referenced in:

- 4. Fake Devices
- 4.1. USBDevice Behavior (2) (3) (4) (5) (6) (7) (8) (9)

https://wicg.github.io/webusb/#dictdef-usbdevicefilter Referenced in:

- 3. Global Testing Interface

https://wicg.github.io/webusb/#enumdef-usbdirection Referenced in:

- 4. Fake Devices

https://wicg.github.io/webusb/#usbendpoint Referenced in:

- 4. Fake Devices

https://wicg.github.io/webusb/#enumdef-usbendpointtype Referenced in:

- 4. Fake Devices

https://wicg.github.io/webusb/#usbinterface Referenced in:

- 4. Fake Devices

https://wicg.github.io/webusb/#dom-usbinterface-alternates Referenced in:

- 4. Fake Devices

https://wicg.github.io/webusb/#dom-usbdevice-claiminterface Referenced in:

- 4.1. USBDevice Behavior

https://wicg.github.io/webusb/#dom-usbdevice-clearhalt Referenced in:

- 4.1. USBDevice Behavior

https://wicg.github.io/webusb/#dom-usbdevice-close Referenced in:

- 4.1. USBDevice Behavior (2)

https://wicg.github.io/webusb/#dom-usbdevice-configuration Referenced in:

- 4. Fake Devices

https://wicg.github.io/webusb/#dom-usbconfiguration-configurationvalue Referenced in:

- 4. Fake Devices

https://wicg.github.io/webusb/#dom-usbdevice-configurations Referenced in:

- 4. Fake Devices

https://wicg.github.io/webusb/#dom-usbdevice-controltransferin Referenced in:

- 4.1. USBDevice Behavior

https://wicg.github.io/webusb/#dom-usbdevice-controltransferout Referenced in:

- 4.1. USBDevice Behavior

https://wicg.github.io/webusb/#dom-usbalternateinterface-endpoints Referenced in:

- 4. Fake Devices

https://wicg.github.io/webusb/#dom-usbdevicerequestoptions-filters Referenced in:

- 3.1. USB Behavior

https://wicg.github.io/webusb/#dom-usbcontroltransferparameters-index Referenced in:

- 4.1. USBDevice Behavior (2)

https://wicg.github.io/webusb/#dom-usbconfiguration-interfaces Referenced in:

- 4. Fake Devices

https://wicg.github.io/webusb/#dom-usbdevice-isochronoustransferin Referenced in:

- 4.1. USBDevice Behavior

https://wicg.github.io/webusb/#dom-usbdevice-isochronoustransferout Referenced in:

- 4.1. USBDevice Behavior

https://wicg.github.io/webusb/#dom-usbdevice-open Referenced in:

- 4.1. USBDevice Behavior

https://wicg.github.io/webusb/#dom-usbdevice-releaseinterface Referenced in:

- 4.1. USBDevice Behavior

https://wicg.github.io/webusb/#dom-usbcontroltransferparameters-request Referenced in:

- 4.1. USBDevice Behavior

https://wicg.github.io/webusb/#dom-usb-requestdevice Referenced in:

- 3.1. USB Behavior
- 3.2. Events

https://wicg.github.io/webusb/#dom-usbdevice-reset Referenced in:

- 4.1. USBDevice Behavior

https://wicg.github.io/webusb/#dom-usbdevice-selectalternateinterface Referenced in:

- 4.1. USBDevice Behavior

https://wicg.github.io/webusb/#dom-usbdevice-selectconfiguration Referenced in:

- 4.1. USBDevice Behavior

https://wicg.github.io/webusb/#dom-usbdevice-transferin Referenced in:

- 4.1. USBDevice Behavior

https://wicg.github.io/webusb/#dom-usbdevice-transferout Referenced in:

- 4.1. USBDevice Behavior

https://wicg.github.io/webusb/#dom-navigator-usb Referenced in:

- 3. Global Testing Interface (2)

https://wicg.github.io/webusb/#dom-usbcontroltransferparameters-value Referenced in:

- 4.1. USBDevice Behavior (2)

### Terms defined by reference

- [DOM] defines the following terms:
  - Event
  - EventTarget
  - fire an event
- [ECMASCRIPT] defines the following terms:
  - internal slot
- [HTML] defines the following terms:
  - EventHandler
  - HTMLIFrameElement
  - Worker
  - current global object
  - global object
  - in parallel
  - queue a task
- [WebIDL] defines the following terms:
  - DOMString
  - FrozenArray
  - InvalidStateError
  - NotFoundError
  - Promise
  - SameObject
  - octet
  - unsigned long
  - unsigned short
- [WebUSB] defines the following terms:
  - USB
  - USBAlternateInterface
  - USBConfiguration
  - USBDevice
  - USBDeviceFilter
  - USBDirection
  - USBEndpoint
  - USBEndpointType
  - USBInterface
  - alternates
  - claimInterface(interfaceNumber)
  - clearHalt(direction, endpointNumber)
  - close()
  - configuration
  - configurationValue
  - configurations
  - controlTransferIn(setup, length)
  - controlTransferOut(setup, data)
  - endpoints
  - filters
  - index
  - interfaces
  - isochronousTransferIn(endpointNumber, packetLengths)
  - isochronousTransferOut(endpointNumber, data, packetLengths)
  - open()
  - releaseInterface(interfaceNumber)
  - request
  - requestDevice(options)
  - reset()
  - selectAlternateInterface(interfaceNumber, alternateSetting)
  - selectConfiguration(configurationValue)
  - transferIn(endpointNumber, length)
  - transferOut(endpointNumber, data)
  - usb
  - value

## References

### Normative References

[DOM]
  Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
  ECMAScript Language Specification. URL: https://tc39.github.io/ecma262/
[HTML]
  Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[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
[WebIDL]
  Boris Zbarsky. Web IDL. 15 December 2016. ED. URL: https://heycam.github.io/webidl/
[WebUSB]
  WebUSB API. Living Standard. URL: https://wicg.github.io/webusb/

## IDL Index

    partial interface USB {
      [SameObject] readonly attribute USBTest test;
    };

    interface USBDeviceRequestEvent : Event {
      attribute FrozenArray<USBDeviceFilter> filters;

      void respondWith(Promise<FakeUSBDevice> result);
    };

    interface USBTest {
      attribute EventHandler onrequestdevice;

      Promise<void> initialize();
      Promise<void> attachToContext((HTMLIFrameElement or Worker) context);
      FakeUSBDevice addFakeDevice(FakeUSBDeviceInit deviceInit);
      Promise<void> reset();
    };

    interface FakeUSBDevice : EventTarget {
      attribute EventHandler onclose;

      void disconnect();
    };

    dictionary FakeUSBDeviceInit {
      required octet usbVersionMajor;
      required octet usbVersionMinor;
      required octet usbVersionSubminor;
      required octet deviceClass;
      required octet deviceSubclass;
      required octet deviceProtocol;
      required unsigned short vendorId;
      required unsigned short productId;
      required octet deviceVersionMajor;
      required octet deviceVersionMinor;
      required octet deviceVersionSubminor;
      DOMString? manufacturerName;
      DOMString? productName;
      DOMString? serialNumber;
      octet activeConfigurationValue = 0;
      sequence<FakeUSBConfigurationInit> configurations;
    };

    dictionary FakeUSBConfigurationInit {
      required octet configurationValue;
      DOMString? configurationName;
      sequence<FakeUSBInterfaceInit> interfaces;
    };

    dictionary FakeUSBInterfaceInit {
      required octet interfaceNumber;
      sequence<FakeUSBAlternateInterfaceInit> alternates;
    };

    dictionary FakeUSBAlternateInterfaceInit {
      required octet alternateSetting;
      required octet interfaceClass;
      required octet interfaceSubclass;
      required octet interfaceProtocol;
      DOMString? interfaceName;
      sequence<FakeUSBEndpointInit> endpoints;
    };

    dictionary FakeUSBEndpointInit {
      required octet endpointNumber;
      required USBDirection direction;
      required USBEndpointType type;
      required unsigned long packetSize;
    };

#usbdevicerequestevent Referenced in:

- 3. Global Testing Interface (2)
- 3.1. USB Behavior

#dom-usbdevicerequestevent-respondwith Referenced in:

- 3. Global Testing Interface

#usbtest Referenced in:

- 3. Global Testing Interface (2) (3) (4) (5) (6) (7)
- 3.1. USB Behavior
- 3.2. Events
- 4. Fake Devices

#dom-usbtest-initialize Referenced in:

- 3. Global Testing Interface
- 3.2. Events

#dom-usbtest-attachtocontext Referenced in:

- 3. Global Testing Interface

#dom-usbtest-addfakedevice Referenced in:

- 3. Global Testing Interface (2)
- 4. Fake Devices (2) (3)

#dom-usbtest-reset Referenced in:

- 1.1. Examples
- 3. Global Testing Interface

#controlled-by Referenced in:

- 3. Global Testing Interface (2) (3)
- 3.1. USB Behavior
- 4. Fake Devices

#dom-usbtest-initializationpromise-slot Referenced in:

- 3. Global Testing Interface (2) (3) (4) (5) (6)

#dom-usbdevicerequestevent-promise-slot Referenced in:

- 3. Global Testing Interface (2)
- 3.1. USB Behavior

#requestdevice Referenced in:

- 3.1. USB Behavior

#fakeusbdevice Referenced in:

- 3. Global Testing Interface (2) (3) (4) (5)
- 4. Fake Devices
- 4.1. USBDevice Behavior (2) (3) (4) (5) (6) (7) (8)

#dom-fakeusbdevice-disconnect Referenced in:

- 3. Global Testing Interface
- 4. Fake Devices

#dictdef-fakeusbdeviceinit Referenced in:

- 3. Global Testing Interface
- 4. Fake Devices (2)
- 4.1. USBDevice Behavior

#dom-fakeusbdeviceinit-activeconfigurationvalue Referenced in:

- 4. Fake Devices (2)

#dictdef-fakeusbconfigurationinit Referenced in:

- 4. Fake Devices (2)

#dictdef-fakeusbinterfaceinit Referenced in:

- 4. Fake Devices (2)

#dictdef-fakeusbalternateinterfaceinit Referenced in:

- 4. Fake Devices (2)

#dictdef-fakeusbendpointinit Referenced in:

- 4. Fake Devices (2)

#correspond-to Referenced in:

- 4.1. USBDevice Behavior (2) (3) (4) (5) (6) (7) (8)