# Testing Web Bluetooth

## Draft Community Group Report, 1 January 1970

This version:
  https://webbluetoothcg.github.io/web-bluetooth/tests
Editor:
  See contributors on GitHub

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

## Abstract

This document describes functions used in testing the Web Bluetooth API.

## Status of this document

This specification was published by the Web Bluetooth 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.

Changes to this document may be tracked at https://github.com/WebBluetoothCG/web-bluetooth/commits/gh-pages.

If you wish to make comments regarding this document, please send them to public-web-bluetooth@w3.org (subscribe, archives).

This specification does not yet reflect the consensus of the Web Bluetooth CG. It is presented by the Chromium developers in the hope that other implementers will find it useful. It may be withdrawn if they don’t.

This document is out of date. It is a snapshot of the testing API as of late 2015. A test API redesign is under active design and development as of August 2017. Chromium developers are interested in updating and collaborating on this document when the next tested implementation begins development.

## 1. Introduction

This section is non-normative.

Writing cross-browser tests for the Web Bluetooth API is difficult because it interacts with devices that live outside the browser. This document describes APIs that aid in this testing, and can be implemented by each browser to either mock out the external interaction, or to configure an external test device to behave as the test needs.

Tests using these functions are currently in web-platform-tests and in Chromium’s repository.

## 2. Security and privacy considerations

These functions MUST NOT be exposed to web content. Only trusted testing code may access them.

## 3. Testing interfaces

    partial interface Window {
      readonly attribute TestRunner testRunner;
      readonly attribute EventSender eventSender;
    };

## 4. testRunner

    callback BluetoothManualChooserEventsCallback = void(sequence<DOMString> events);

    interface TestRunner {
      void setBluetoothMockDataSet(DOMString dataSetName);
      void setBluetoothManualChooser();
      void getBluetoothManualChooserEvents(BluetoothManualChooserEventsCallback callback);
      void sendBluetoothManualChooserEvent(DOMString event, DOMString argument);
    };

### 4.1. setBluetoothMockDataSet

When invoked, `setBluetoothMockDataSet(dataSetName)` MUST replace the user prompt used in `requestDevice()` with one that resolves the promise with the first discovered device, or rejects the promise if discovery can’t start or times out. Then it must configure the UA’s Bluetooth system to respond depending on the `dataSetName`:

`"NotPresentAdapter"`

  The UA has no Bluetooth implementation at all.

`"NotPoweredAdapter"`

  The UA’s Bluetooth radio is disabled.

`"ScanFilterCheckingAdapter"`

  The UA may fail the test unless the test asks the adapter to start a Bluetooth scan filtered to the `org.bluetooth.service.glucose`, `org.bluetooth.service.heart_rate`, and `org.bluetooth.service.battery_service` Service UUIDs. The adapter discovers a BatteryDevice.

`"EmptyAdapter"`

  No devices are nearby.

`"FailStartDiscoveryAdapter"`

  The UA fails to start a scan for devices.

`"FailStopDiscoveryAdapter"`

  Behaves like a GenericAccessAdapter, but the UA fails to stop the scan for devices.

`"GlucoseHeartRateAdapter"`

  The UA discovers a HeartRateDevice and a GlucoseDevice.

`"SecondDiscoveryFindsHeartRateAdapter"`

  In the first discovery session, the UA finds no devices. In the second, it discovers a HeartRateDevice.

`"MissingServiceGenericAccessAdapter"`

  The UA discovers a MissingServiceGenericAccessDevice.

`"MissingCharacteristicGenericAccessAdapter"`

  The UA discovers a MissingCharacteristicGenericAccessDevice.

`"MissingDescriptorGenericAccessAdapter"`

  The UA discovers a MissingDescriptorGenericAccessDevice.

`"GenericAccessAdapter"`

  The UA discovers a GenericAccessDevice.

`"FailingGATTOperationsAdapter"`

  The UA discovers a FailingGATTOperationsDevice.

#### 4.1.1. BatteryDevice

Has a MAC address of `00:00:00:00:00:01`, the name `"Battery Device"`, and advertises `org.bluetooth.service.battery_service`.

#### 4.1.2. GlucoseDevice

Has a MAC address of `00:00:00:00:00:02`, the name `"Glucose Device"`, and advertises `org.bluetooth.service.glucose`.

#### 4.1.3. HeartRateDevice

Has a MAC address of `00:00:00:00:00:03`, the name `"Heart Rate Device"`, and advertises `org.bluetooth.service.heart_rate`.

#### 4.1.4. MissingServiceGenericAccessDevice

Has a MAC address of `00:00:00:00:00:00`, the name `"Generic Access Device"`, and accepts GATT connections. Its GATT Server is empty.

#### 4.1.5. MissingCharacteristicGenericAccessDevice

In addition to the properties of a MissingServiceGenericAccessDevice, its GATT Server contains a primary `org.bluetooth.service.generic_access` service. This service contains no characteristics.

#### 4.1.6. MissingDescriptorGenericAccessDevice

In addition to the properties of a MissingCharacteristicGenericAccessDevice, its `org.bluetooth.service.generic_access` service contains the `org.bluetooth.characteristic.gap.device_name` characteristic. This characteristic returns `"GenericAccessDevice"` when read, and responds that writes have succeeded (without changing the value read).

#### 4.1.7. GenericAccessDevice

In addition to the properties of a MissingDescriptorGenericAccessDevice, its `org.bluetooth.characteristic.gap.device_name` characteristic contains the following descriptors:

`org.bluetooth.descriptor.gatt.characteristic_extended_properties`

  Has the Writable Auxiliaries bit set.

`org.bluetooth.descriptor.gatt.characteristic_user_description`

  Returns `"Device Name"` when read, and responds that writes have succeeded (without changing the value read).

#### 4.1.8. FailingGATTOperationsDevice

Let `errorUUID(unsigned long id)` be the valid UUID consisting of `id.toString(16)` left-padded with `"0"`s to 8 characters, and then concatenated with `"-97e5-4cd7-b9f1-f5a427670c59"`. (These lower 96 bits were generated as a type 4 (random) UUID.)

The FailingGATTOperationsDevice has a MAC address of `00:00:00:00:00:00`, the name `"Errors Device"`, and accepts GATT connections. Its GATT Server contains one service with UUID `errorUUID(0x100)`. This service contains 255 characteristics with UUIDs `errorUUID(0x101)` through `errorUUID(0x1ff)`. When read or written, the characteristic with UUID `errorUUID(which)` returns an Error Response ([BLUETOOTH42] 3.F.3.4.1.1) with an error code of `which - 0x100`.

### 4.2. setBluetoothManualChooser()

When invoked, `setBluetoothManualChooser()` MUST replace the user prompt used in `requestDevice()` with a "manual chooser" that records events that would otherwise be shown to the user (see `getBluetoothManualChooserEvents()`), and which can simulate user interaction with the prompt (see `sendBluetoothManualChooserEvent()`).

### 4.3. getBluetoothManualChooserEvents(callback)

When invoked, `getBluetoothManualChooserEvents(callback)` MUST call `callback` with the list of events that have been recorded by the manual chooser since `getBluetoothManualChooserEvents()` was last called. Each event is encoded as string, as follows:

The chooser is opened following a request by origin O.

  `"chooser-opened(O)"`

The Bluetooth adapter is removed from the UA.

  `"adapter-removed"`

The Bluetooth adapter becomes present but disabled.

  `"adapter-disabled"`

The Bluetooth adapter becomes present and enabled.

  `"adapter-enabled"`

The Bluetooth adapter begins scanning for nearby devices.

  `"discovering"`

The Bluetooth adapter stops scanning for nearby devices.

  `"discovery-idle"`

The Bluetooth adapter attempts to begin scanning for nearby devices, but fails.

  `"discovery-failed-to-start"`

A device is added to the user prompt with `id` device-id and `name` device-name.

  `"add-device(device-name)=device-id"`

  Note: The device-id might not be the device’s MAC address. For example, MacOS and iOS generate a random ID when testing against physical devices.

The UA discovers that a device with `id` device-id is no longer nearby.

  `"remove-device(device-id)"`

### 4.4. sendBluetoothManualChooserEvent(event, argument)

When invoked, `sendBluetoothManualChooserEvent(event, argument)` MUST cause the manual chooser to inform the UA that the user has taken an action corresponding to the `event`:

`"cancelled"`

  The user cancelled the prompt.

`"selected"`

  The user selected the device with an `id` of `argument`.

`"rescan"`

  The user requested another bluetooth scan.

## 5. eventSender

    interface EventSender {
      void keyDown(DOMString code);
    };

`keyDown(code)` must fire an event named `keypress` to the body element, with its `key` attribute initialized to `code`.

## 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

- BatteryDevice, in §4.1
- BluetoothManualChooserEventsCallback, in §4
- errorUUID, in §4.1.8
- EventSender, in §5
- eventSender, in §3
- FailingGATTOperationsDevice, in §4.1.7
- GenericAccessDevice, in §4.1.6
- getBluetoothManualChooserEvents(callback), in §4.2
- GlucoseDevice, in §4.1.1
- HeartRateDevice, in §4.1.2
- keyDown(code), in §5
- manual chooser, in §4.2
- MissingCharacteristicGenericAccessDevice, in §4.1.4
- MissingDescriptorGenericAccessDevice, in §4.1.5
- MissingServiceGenericAccessDevice, in §4.1.3
- sendBluetoothManualChooserEvent(event, argument), in §4.3
- setBluetoothManualChooser(), in §4.1.8
- setBluetoothMockDataSet(dataSetName), in §4.1
- TestRunner, in §4
- testRunner, in §3

https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.device_name.xml#Referenced in:

- 4.1.6. MissingDescriptorGenericAccessDevice
- 4.1.7. GenericAccessDevice

https://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_extended_properties.xml#Referenced in:

- 4.1.7. GenericAccessDevice

https://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_user_description.xml#Referenced in:

- 4.1.7. GenericAccessDevice

https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.battery_service.xml#Referenced in:

- 4.1. setBluetoothMockDataSet
- 4.1.1. BatteryDevice

https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.generic_access.xml#Referenced in:

- 4.1.5. MissingCharacteristicGenericAccessDevice
- 4.1.6. MissingDescriptorGenericAccessDevice

https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.glucose.xml#Referenced in:

- 4.1. setBluetoothMockDataSet
- 4.1.2. GlucoseDevice

https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.heart_rate.xml#Referenced in:

- 4.1. setBluetoothMockDataSet
- 4.1.3. HeartRateDevice

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

- 5. eventSender

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

- 3. Testing interfaces

https://html.spec.whatwg.org/multipage/dom.html#the-body-element-2 Referenced in:

- 5. eventSender

https://www.w3.org/TR/uievents/#widl-KeyboardEvent-key Referenced in:

- 5. eventSender

https://www.w3.org/TR/uievents/#event-type-keypress Referenced in:

- 5. eventSender

https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-id Referenced in:

- 4.3. getBluetoothManualChooserEvents(callback) (2)
- 4.4. sendBluetoothManualChooserEvent(event, argument)

https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-name Referenced in:

- 4.3. getBluetoothManualChooserEvents(callback)

https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice Referenced in:

- 4.1. setBluetoothMockDataSet
- 4.2. setBluetoothManualChooser()

https://webbluetoothcg.github.io/web-bluetooth/#valid-uuid Referenced in:

- 4.1.8. FailingGATTOperationsDevice

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

- 4. testRunner (2) (3) (4)
- 5. eventSender

### Terms defined by reference

- [bluetooth-assigned] defines the following terms:
  - org.bluetooth.characteristic.gap.device_name
  - org.bluetooth.descriptor.gatt.characteristic_extended_properties
  - org.bluetooth.descriptor.gatt.characteristic_user_description
  - org.bluetooth.service.battery_service
  - org.bluetooth.service.generic_access
  - org.bluetooth.service.glucose
  - org.bluetooth.service.heart_rate
- [DOM] defines the following terms:
  - fire an event
- [HTML] defines the following terms:
  - Window
  - the body element
- [uievents] defines the following terms:
  - key
  - keypress
- [web-bluetooth] defines the following terms:
  - id
  - name
  - requestDevice(options)
  - valid uuid
- [WebIDL] defines the following terms:
  - DOMString

## References

### Normative References

[BLUETOOTH42]
  BLUETOOTH SPECIFICATION Version 4.2. 2 December 2014. URL: https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=286439
[DOM]
  Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[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
[UIEVENTS]
  Gary Kacmarcik; Travis Leithead; Doug Schepers. UI Events. 30 May 2019. WD. URL: https://www.w3.org/TR/uievents/
[WEB-BLUETOOTH]
  Jeffrey Yasskin. Web Bluetooth. Draft Community Group Report. URL: https://webbluetoothcg.github.io/web-bluetooth/
[WebIDL]
  Boris Zbarsky. Web IDL. 15 December 2016. ED. URL: https://heycam.github.io/webidl/

## IDL Index

    partial interface Window {
      readonly attribute TestRunner testRunner;
      readonly attribute EventSender eventSender;
    };

    callback BluetoothManualChooserEventsCallback = void(sequence<DOMString> events);

    interface TestRunner {
      void setBluetoothMockDataSet(DOMString dataSetName);
      void setBluetoothManualChooser();
      void getBluetoothManualChooserEvents(BluetoothManualChooserEventsCallback callback);
      void sendBluetoothManualChooserEvent(DOMString event, DOMString argument);
    };

    interface EventSender {
      void keyDown(DOMString code);
    };

## Issues Index

This document is out of date. It is a snapshot of the testing API as of late 2015. A test API redesign is under active design and development as of August 2017. Chromium developers are interested in updating and collaborating on this document when the next tested implementation begins development. ↵
#callbackdef-bluetoothmanualchoosereventscallback Referenced in:

- 4. testRunner

#testrunner Referenced in:

- 3. Testing interfaces

#dom-testrunner-setbluetoothmockdataset-datasetname-datasetname Referenced in:

- 4.1. setBluetoothMockDataSet

#dom-testrunner-sendbluetoothmanualchooserevent-event-argument-event Referenced in:

- 4.4. sendBluetoothManualChooserEvent(event, argument)

#dom-testrunner-sendbluetoothmanualchooserevent-event-argument-argument Referenced in:

- 4.4. sendBluetoothManualChooserEvent(event, argument)

#dom-testrunner-setbluetoothmockdataset Referenced in:

- 4. testRunner

#batterydevice Referenced in:

- 4.1. setBluetoothMockDataSet

#glucosedevice Referenced in:

- 4.1. setBluetoothMockDataSet

#heartratedevice Referenced in:

- 4.1. setBluetoothMockDataSet (2)

#missingservicegenericaccessdevice Referenced in:

- 4.1. setBluetoothMockDataSet
- 4.1.5. MissingCharacteristicGenericAccessDevice

#missingcharacteristicgenericaccessdevice Referenced in:

- 4.1. setBluetoothMockDataSet
- 4.1.6. MissingDescriptorGenericAccessDevice

#missingdescriptorgenericaccessdevice Referenced in:

- 4.1. setBluetoothMockDataSet
- 4.1.7. GenericAccessDevice

#genericaccessdevice Referenced in:

- 4.1. setBluetoothMockDataSet

#failinggattoperationsdevice Referenced in:

- 4.1. setBluetoothMockDataSet
- 4.1.8. FailingGATTOperationsDevice

#abstract-opdef-erroruuid Referenced in:

- 4.1.8. FailingGATTOperationsDevice (2) (3) (4)

#dom-testrunner-setbluetoothmanualchooser Referenced in:

- 4. testRunner
- 4.2. setBluetoothManualChooser()

#manual-chooser Referenced in:

- 4.3. getBluetoothManualChooserEvents(callback)
- 4.4. sendBluetoothManualChooserEvent(event, argument)

#dom-testrunner-getbluetoothmanualchooserevents Referenced in:

- 4. testRunner
- 4.2. setBluetoothManualChooser()
- 4.3. getBluetoothManualChooserEvents(callback) (2)

#dom-testrunner-sendbluetoothmanualchooserevent Referenced in:

- 4. testRunner
- 4.2. setBluetoothManualChooser()
- 4.4. sendBluetoothManualChooserEvent(event, argument)

#eventsender Referenced in:

- 3. Testing interfaces

#dom-eventsender-keydown-code-code Referenced in:

- 5. eventSender

#dom-eventsender-keydown Referenced in:

- 5. eventSender