Testing Web Bluetooth

Draft Community Group Report,

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

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.

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 Chromium’s repository, will be moved to this repository soon, and will eventually live in the W3C’s Web Platform Tests.

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#callbackdef-bluetoothmanualchoosereventscallbackReferenced in:4. testRunner = void(sequence<DOMString> events);

interface TestRunner#testrunnerReferenced in:3. Testing interfaces {
  void setBluetoothMockDataSet(DOMString dataSetName#dom-testrunner-setbluetoothmockdataset-datasetname-datasetnameReferenced in:4.1. setBluetoothMockDataSet);
  void setBluetoothManualChooser();
  void getBluetoothManualChooserEvents(BluetoothManualChooserEventsCallback callback);
  void sendBluetoothManualChooserEvent(DOMString event#dom-testrunner-sendbluetoothmanualchooserevent-event-argument-eventReferenced in:4.4. sendBluetoothManualChooserEvent(event, argument), DOMString argument#dom-testrunner-sendbluetoothmanualchooserevent-event-argument-argumentReferenced in:4.4. sendBluetoothManualChooserEvent(event, argument));
};

4.1. setBluetoothMockDataSet

When invoked, setBluetoothMockDataSet(dataSetName)#dom-testrunner-setbluetoothmockdatasetReferenced in:4. testRunner 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. BaseDevice#basedeviceReferenced in:4.1.2. BatteryDevice4.1.3. GlucoseDevice4.1.4. HeartRateDevice4.1.5. MissingServiceGenericAccessDevice4.1.9. FailingGATTOperationsDevice

A device with a vendorIDSource of "bluetooth", a vendorID of 0xFFFF, a productID of 1, and a productVersion of 2.

4.1.2. BatteryDevice#batterydeviceReferenced in:4.1. setBluetoothMockDataSet

In addition to the properties of a BaseDevice, has a MAC address of 00:00:00:00:00:01, the name "Battery Device", and advertises org.bluetooth.service.battery_service.

4.1.3. GlucoseDevice#glucosedeviceReferenced in:4.1. setBluetoothMockDataSet

In addition to the properties of a BaseDevice, has a MAC address of 00:00:00:00:00:02, the name "Glucose Device", and advertises org.bluetooth.service.glucose.

4.1.4. HeartRateDevice#heartratedeviceReferenced in:4.1. setBluetoothMockDataSet (2)

In addition to the properties of a BaseDevice, 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.5. MissingServiceGenericAccessDevice#missingservicegenericaccessdeviceReferenced in:4.1. setBluetoothMockDataSet4.1.6. MissingCharacteristicGenericAccessDevice

In addition to the properties of a BaseDevice, 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.6. MissingCharacteristicGenericAccessDevice#missingcharacteristicgenericaccessdeviceReferenced in:4.1. setBluetoothMockDataSet4.1.7. MissingDescriptorGenericAccessDevice

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.7. MissingDescriptorGenericAccessDevice#missingdescriptorgenericaccessdeviceReferenced in:4.1. setBluetoothMockDataSet4.1.8. GenericAccessDevice

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.8. GenericAccessDevice#genericaccessdeviceReferenced in:4.1. setBluetoothMockDataSet

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.9. FailingGATTOperationsDevice#failinggattoperationsdeviceReferenced in:4.1. setBluetoothMockDataSet4.1.9. 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.)

In addition to the properties of a BaseDevice, 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()#dom-testrunner-setbluetoothmanualchooserReferenced in:4. testRunner4.2. setBluetoothManualChooser()

When invoked, setBluetoothManualChooser() MUST replace the user prompt used in requestDevice() with a "manual chooser#manual-chooserReferenced in:4.3. getBluetoothManualChooserEvents()4.4. sendBluetoothManualChooserEvent(event, argument)" 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()#dom-testrunner-getbluetoothmanualchoosereventsReferenced in:4. testRunner4.2. setBluetoothManualChooser()4.3. getBluetoothManualChooserEvents() (2)

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)#dom-testrunner-sendbluetoothmanualchoosereventReferenced in:4. testRunner4.2. setBluetoothManualChooser()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#eventsenderReferenced in:3. Testing interfaces {
  void keyDown(DOMString code#dom-eventsender-keydown-code-codeReferenced in:5. eventSender);
};

keyDown(code)#dom-eventsender-keydownReferenced in:5. eventSender dispatches a trusted 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

Terms defined by reference

References

Normative References

[BLUETOOTH-ASSIGNED]
Assigned Numbers. Living Standard. URL: https://www.bluetooth.org/en-us/specification/assigned-numbers
[BLUETOOTH42]
BLUETOOTH SPECIFICATION Version 4.2. 2 December 2014. URL: https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=286439
[HTML]
Ian Hickson. 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. UI Events Specification. 15 December 2015. WD. URL: https://w3c.github.io/uievents/
[WEB-BLUETOOTH]
Jeffrey Yasskin. Web Bluetooth. Draft Community Group Report. URL: https://webbluetoothcg.github.io/web-bluetooth/

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);
};