Testing Web Bluetooth

Draft Community Group Report,

More details about this document
This version:
https://webbluetoothcg.github.io/web-bluetooth/tests
Issue Tracking:
GitHub
Inline In Spec
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.

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 considerations

See § 3 Privacy considerations section. [Issue #575]

3. Privacy considerations

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

4. Testing interfaces

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

5. testRunner

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

[Exposed=Window, SecureContext]
interface TestRunner {
  undefined setBluetoothMockDataSet(DOMString dataSetName);
  undefined setBluetoothManualChooser();
  undefined getBluetoothManualChooserEvents(BluetoothManualChooserEventsCallback callback);
  undefined sendBluetoothManualChooserEvent(DOMString event, DOMString argument);
};

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

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

5.1.2. GlucoseDevice

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

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

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

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

5.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).

5.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).

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

5.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()).

5.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)"

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

6. eventSender

[Exposed=Window, SecureContext]
interface EventSender {
  undefined keyDown(DOMString code);
};

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

Conformance

Document conventions

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

[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://datatracker.ietf.org/doc/html/rfc2119
[UIEVENTS]
Gary Kacmarcik; Travis Leithead. UI Events. URL: https://w3c.github.io/uievents/
[WEB-BLUETOOTH]
Jeffrey Yasskin. Web Bluetooth. URL: https://webbluetoothcg.github.io/web-bluetooth/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

IDL Index

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

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

[Exposed=Window, SecureContext]
interface TestRunner {
  undefined setBluetoothMockDataSet(DOMString dataSetName);
  undefined setBluetoothManualChooser();
  undefined getBluetoothManualChooserEvents(BluetoothManualChooserEventsCallback callback);
  undefined sendBluetoothManualChooserEvent(DOMString event, DOMString argument);
};

[Exposed=Window, SecureContext]
interface EventSender {
  undefined 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.
See § 3 Privacy considerations section. [Issue #575]