aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/bluetooth/Cargo.toml3
-rw-r--r--components/bluetooth/lib.rs113
-rw-r--r--components/bluetooth/test.rs501
-rw-r--r--components/bluetooth_traits/lib.rs1
-rw-r--r--components/script/dom/mod.rs1
-rw-r--r--components/script/dom/testrunner.rs53
-rw-r--r--components/script/dom/webidls/TestRunner.webidl16
-rw-r--r--components/script/dom/webidls/Window.webidl7
-rw-r--r--components/script/dom/window.rs8
-rw-r--r--components/servo/Cargo.lock19
-rw-r--r--ports/cef/Cargo.lock19
-rw-r--r--resources/gatt_blacklist.txt11
-rw-r--r--resources/package-prefs.json1
-rw-r--r--resources/prefs.json1
-rw-r--r--tests/wpt/mozilla/meta/MANIFEST.json972
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/__dir__.ini1
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/connect/device-goes-out-of-range.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/device-goes-out-of-range.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/disconnect-called-before.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/disconnect-called-during.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/get-same-characteristic.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/service-is-removed.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/blacklisted-characteristics.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/device-goes-out-of-range-with-uuid.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/device-goes-out-of-range.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-called-before-with-uuid.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-called-before.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-called-during-with-uuid.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-called-during.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/get-same-characteristics.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/service-is-removed-with-uuid.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/service-is-removed.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/characteristic-is-removed.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/device-goes-out-of-range.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/disconnect-called-before.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/disconnect-called-during.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/get-same-descriptor.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/blacklisted-descriptors.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/characteristic-is-removed-with-uuid.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/characteristic-is-removed.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/device-goes-out-of-range-with-uuid.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/device-goes-out-of-range.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/disconnect-called-before-with-uuid.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/disconnect-called-before.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/disconnect-called-during-with-uuid.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/disconnect-called-during.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/get-same-descriptors.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/device-goes-out-of-range.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/disconnect-called-before.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/disconnect-called-during.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/disconnected-device.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/get-same-service.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/blacklisted-services.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range-with-uuid.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnect-called-before-with-uuid.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnect-called-before.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnect-called-during-with-uuid.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnect-called-during.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnected-device-with-uuid.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnected-device.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/get-same-service.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/no-permission-present-service.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/characteristic/characteristic-is-removed.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/characteristic/device-goes-out-of-range.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/characteristic/service-is-removed.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/descriptor/characteristic-is-removed.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/descriptor/descriptor-is-removed.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/descriptor/device-goes-out-of-range.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/descriptor/service-is-removed.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/adapter-not-present.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/adapter-off.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-name.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-namePrefix.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-name.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-namePrefix.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/correct-uuids.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/name-empty-device-from-name-empty-filter.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/name-empty-filter.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/name-missing-device-from-name-empty-filter.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/same-device.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/characteristic/characteristic-is-removed.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/characteristic/device-goes-out-of-range.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/characteristic/service-is-removed.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/characteristic/write-updates-value.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/characteristic-is-removed.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/descriptor-is-removed.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/device-goes-out-of-range.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/service-is-removed.html.ini4
-rw-r--r--tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/write-updates-value.html.ini4
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/connect/connection-succeeds.html15
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/connect/device-goes-out-of-range.html17
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/connect/get-same-gatt-server.html15
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/disconnect/connect-disconnect-twice.html26
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/disconnect/disconnect-once.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/disconnect/disconnect-twice-in-a-row.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/blacklisted-characteristic.html16
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/characteristic-found.html32
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/characteristic-not-found.html17
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/device-goes-out-of-range.html20
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/disconnect-called-before.html22
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/disconnect-called-during.html23
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/get-same-characteristic.html27
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/invalid-characteristic-name.html17
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/service-is-removed.html20
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/blacklisted-characteristics-with-uuid.html16
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/blacklisted-characteristics.html16
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/characteristics-found-with-uuid.html28
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/characteristics-found.html22
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/characteristics-not-found-with-uuid.html16
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/characteristics-not-found.html16
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/correct-characteristics.html20
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/device-goes-out-of-range-with-uuid.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/device-goes-out-of-range.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-called-before-with-uuid.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-called-before.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-called-during-with-uuid.html23
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-called-during.html22
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/get-same-characteristics.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/invalid-characteristic-name.html17
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/service-is-removed-with-uuid.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/service-is-removed.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/blacklisted-descriptor.html18
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/characteristic-is-removed.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/descriptor-found.html33
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/descriptor-not-found.html18
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/device-goes-out-of-range.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/disconnect-called-before.html23
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/disconnect-called-during.html24
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/get-same-descriptor.html28
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/invalid-descriptor-name.html18
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/blacklisted-descriptors-with-uuid.html18
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/blacklisted-descriptors.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/characteristic-is-removed-with-uuid.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/characteristic-is-removed.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/correct-descriptors.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/descriptors-found-with-uuid.html30
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/descriptors-found.html25
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/descriptors-not-found-with-uuid.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/descriptors-not-found.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/device-goes-out-of-range-with-uuid.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/device-goes-out-of-range.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-called-before-with-uuid.html23
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-called-before.html23
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-called-during-with-uuid.html24
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-called-during.html24
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/get-same-descriptors.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/invalid-descriptor-name.html18
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/device-goes-out-of-range.html18
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/disconnect-called-before.html18
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/disconnect-called-during.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/disconnected-device.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/get-same-service.html24
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/invalid-service-name.html15
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/no-permission-absent-service.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/no-permission-present-service.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/service-found.html31
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/service-not-found.html16
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/blacklisted-services-with-uuid.html16
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/blacklisted-services.html26
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/correct-services.html22
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range-with-uuid.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-called-before-with-uuid.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-called-before.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-called-during-with-uuid.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-called-during.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnected-device-with-uuid.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnected-device.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/get-same-service.html18
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/invalid-service-name.html15
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/no-permission-absent-service-with-uuid.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/no-permission-present-service-with-uuid.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/no-permission-present-service.html15
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/services-found-with-uuid.html27
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/services-found.html25
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/services-not-found-with-uuid.html16
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/services-not-found.html16
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/blacklisted-characteristic.html20
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/characteristic-is-removed.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/device-goes-out-of-range.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/disconnect-called-before.html23
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/read-succeeds.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/read-updates-value.html22
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/service-is-removed.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/blacklisted-descriptor.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/characteristic-is-removed.html22
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/descriptor-is-removed.html22
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/device-goes-out-of-range.html22
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/disconnect-called-before.html24
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/read-succeeds.html20
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/read-updates-value.html23
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/service-is-removed.html22
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/accept-all-devices-with-filter.html15
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/accept-all-devices.html12
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/adapter-not-present.html13
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/adapter-off.html13
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/blacklisted-service-in-filter.html13
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/blacklisted-service-in-optionalServices.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-filter.html11
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-filters-member.html12
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-namePrefix.html38
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-services-member.html38
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-device-name-name.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-device-name-namePrefix.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-name.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-namePrefix.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/no-arguments.html16
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/no-filters-member.html16
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-name.html17
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-namePrefix.html17
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-name.html17
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-namePrefix.html17
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-valid-length-name-name.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-valid-length-name-namePrefix.html18
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/wrong-service-in-optionalServices-member.html38
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/wrong-service-in-services-member.html37
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/correct-uuids.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/discovery-succeeds.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/filter-does-not-match.html94
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/filter-matches.html64
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-device-from-name-empty-filter.html15
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-device-from-name-prefix-filter.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-device-from-name-wrong-filter.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-device-from-service-filter.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-filter.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-missing-device-from-name-empty-filter.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-missing-device-from-name-prefix-filter.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-missing-device-from-name-wrong-filter.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-missing-device-from-service-filter.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/no-devices.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/not-accept-all-devices-without-filter.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/same-device.html18
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/single-filter-single-service.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/single-filter-two-services-fails.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/single-filter-two-services-succeeds.html14
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/two-filters.html15
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/blacklisted-characteristic.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/characteristic-is-removed.html22
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/device-goes-out-of-range.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/disconnect-called-before.html23
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/service-is-removed.html21
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/write-succeeds.html18
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/write-updates-value.html22
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/blacklisted-descriptor.html23
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/characteristic-is-removed.html22
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/descriptor-is-removed.html22
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/device-goes-out-of-range.html22
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/disconnect-called-before.html24
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/service-is-removed.html23
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/write-succeeds.html19
-rw-r--r--tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/write-updates-value.html23
-rw-r--r--tests/wpt/web-platform-tests/bluetooth/bluetooth-helpers.js147
253 files changed, 5456 insertions, 24 deletions
diff --git a/components/bluetooth/Cargo.toml b/components/bluetooth/Cargo.toml
index e1ea441e267..7ee5f430751 100644
--- a/components/bluetooth/Cargo.toml
+++ b/components/bluetooth/Cargo.toml
@@ -12,10 +12,11 @@ path = "lib.rs"
[dependencies]
bitflags = "0.7"
bluetooth_traits = {path = "../bluetooth_traits"}
-device = {git = "https://github.com/servo/devices"}
+device = {git = "https://github.com/servo/devices", features = ["bluetooth-test"]}
ipc-channel = "0.5"
rand = "0.3"
util = {path = "../util"}
+uuid = {version = "0.3.1", features = ["v4"]}
[target.'cfg(target_os = "linux")'.dependencies]
tinyfiledialogs = {git = "https://github.com/jdm/tinyfiledialogs"}
diff --git a/components/bluetooth/lib.rs b/components/bluetooth/lib.rs
index 12ba83244be..e3d4eba1a24 100644
--- a/components/bluetooth/lib.rs
+++ b/components/bluetooth/lib.rs
@@ -11,17 +11,17 @@ extern crate rand;
#[cfg(target_os = "linux")]
extern crate tinyfiledialogs;
extern crate util;
+extern crate uuid;
+
+pub mod test;
use bluetooth_traits::{BluetoothCharacteristicMsg, BluetoothCharacteristicsMsg};
use bluetooth_traits::{BluetoothDescriptorMsg, BluetoothDescriptorsMsg};
use bluetooth_traits::{BluetoothDeviceMsg, BluetoothError, BluetoothMethodMsg};
use bluetooth_traits::{BluetoothResult, BluetoothServiceMsg, BluetoothServicesMsg};
use bluetooth_traits::scanfilter::{BluetoothScanfilter, BluetoothScanfilterSequence, RequestDeviceoptions};
-use device::bluetooth::BluetoothAdapter;
-use device::bluetooth::BluetoothDevice;
-use device::bluetooth::BluetoothGATTCharacteristic;
-use device::bluetooth::BluetoothGATTDescriptor;
-use device::bluetooth::BluetoothGATTService;
+use device::bluetooth::{BluetoothAdapter, BluetoothDevice, BluetoothGATTCharacteristic};
+use device::bluetooth::{BluetoothGATTDescriptor, BluetoothGATTService};
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use rand::Rng;
use std::borrow::ToOwned;
@@ -33,6 +33,8 @@ use util::thread::spawn_named;
const ADAPTER_ERROR: &'static str = "No adapter found";
+const ADAPTER_NOT_POWERED_ERROR: &'static str = "Bluetooth adapter not powered";
+
// A transaction not completed within 30 seconds shall time out. Such a transaction shall be considered to have failed.
// https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=286439 (Vol. 3, page 480)
const MAXIMUM_TRANSACTION_TIME: u8 = 30;
@@ -71,7 +73,12 @@ macro_rules! return_if_cached(
macro_rules! get_adapter_or_return_error(
($bl_manager:expr, $sender:expr) => (
match $bl_manager.get_or_create_adapter() {
- Some(adapter) => adapter,
+ Some(adapter) => {
+ if !adapter.is_powered().unwrap_or(false) {
+ return drop($sender.send(Err(BluetoothError::Type(ADAPTER_NOT_POWERED_ERROR.to_string()))))
+ }
+ adapter
+ },
None => return drop($sender.send(Err(BluetoothError::Type(ADAPTER_ERROR.to_string())))),
}
);
@@ -155,6 +162,13 @@ fn matches_filters(device: &BluetoothDevice, filters: &BluetoothScanfilterSequen
return filters.iter().any(|f| matches_filter(device, f))
}
+fn is_mock_adapter(adapter: &BluetoothAdapter) -> bool {
+ match adapter {
+ &BluetoothAdapter::Mock(_) => true,
+ _ => false,
+ }
+}
+
pub struct BluetoothManager {
receiver: IpcReceiver<BluetoothMethodMsg>,
adapter: Option<BluetoothAdapter>,
@@ -228,6 +242,9 @@ impl BluetoothManager {
BluetoothMethodMsg::WriteValue(id, value, sender) => {
self.write_value(id, value, sender)
},
+ BluetoothMethodMsg::Test(data_set_name, sender) => {
+ self.test(data_set_name, sender)
+ }
BluetoothMethodMsg::Exit => {
break
},
@@ -235,13 +252,46 @@ impl BluetoothManager {
}
}
+ // Test
+
+ fn test(&mut self, data_set_name: String, sender: IpcSender<BluetoothResult<()>>) {
+ self.address_to_id.clear();
+ self.service_to_device.clear();
+ self.characteristic_to_service.clear();
+ self.descriptor_to_characteristic.clear();
+ self.cached_devices.clear();
+ self.cached_services.clear();
+ self.cached_characteristics.clear();
+ self.cached_descriptors.clear();
+ self.allowed_services.clear();
+ self.adapter = BluetoothAdapter::init_mock().ok();
+ match test::test(self, data_set_name) {
+ Ok(_) => {
+ let _ = sender.send(Ok(()));
+ },
+ Err(error) => {
+ let _ = sender.send(Err(BluetoothError::Type(error.description().to_owned())));
+ },
+ }
+ }
+
// Adapter
- fn get_or_create_adapter(&mut self) -> Option<BluetoothAdapter> {
+ pub fn get_or_create_adapter(&mut self) -> Option<BluetoothAdapter> {
let adapter_valid = self.adapter.as_ref().map_or(false, |a| a.get_address().is_ok());
if !adapter_valid {
self.adapter = BluetoothAdapter::init().ok();
}
+
+ let adapter = match self.adapter.as_ref() {
+ Some(adapter) => adapter,
+ None => return None,
+ };
+
+ if is_mock_adapter(adapter) && !adapter.is_present().unwrap_or(false) {
+ return None;
+ }
+
self.adapter.clone()
}
@@ -270,7 +320,16 @@ impl BluetoothManager {
}
#[cfg(target_os = "linux")]
- fn select_device(&mut self, devices: Vec<BluetoothDevice>) -> Option<String> {
+ fn select_device(&mut self, devices: Vec<BluetoothDevice>, adapter: &BluetoothAdapter) -> Option<String> {
+ if is_mock_adapter(adapter) {
+ for device in devices {
+ if let Ok(address) = device.get_address() {
+ return Some(address);
+ }
+ }
+ return None;
+ }
+
let mut dialog_rows: Vec<String> = vec!();
for device in devices {
dialog_rows.extend_from_slice(&[device.get_address().unwrap_or("".to_string()),
@@ -291,7 +350,7 @@ impl BluetoothManager {
}
#[cfg(not(target_os = "linux"))]
- fn select_device(&mut self, devices: Vec<BluetoothDevice>) -> Option<String> {
+ fn select_device(&mut self, devices: Vec<BluetoothDevice>, _adapter: &BluetoothAdapter) -> Option<String> {
for device in devices {
if let Ok(address) = device.get_address() {
return Some(address);
@@ -312,6 +371,17 @@ impl BluetoothManager {
device_id
}
+ fn device_from_service_id(&self, service_id: &str) -> Option<BluetoothDevice> {
+ let device_id = match self.service_to_device.get(service_id) {
+ Some(id) => id,
+ None => return None,
+ };
+ match self.cached_devices.get(device_id) {
+ Some(d) => Some(d.clone()),
+ None => None,
+ }
+ }
+
// Service
fn get_and_cache_gatt_services(&mut self,
@@ -464,7 +534,9 @@ impl BluetoothManager {
let mut adapter = get_adapter_or_return_error!(self, sender);
if let Ok(ref session) = adapter.create_discovery_session() {
if session.start_discovery().is_ok() {
- thread::sleep(Duration::from_millis(DISCOVERY_TIMEOUT_MS));
+ if !is_mock_adapter(&adapter) {
+ thread::sleep(Duration::from_millis(DISCOVERY_TIMEOUT_MS));
+ }
}
let _ = session.stop_discovery();
}
@@ -481,7 +553,7 @@ impl BluetoothManager {
}
// Step 8.
- if let Some(address) = self.select_device(matched_devices) {
+ if let Some(address) = self.select_device(matched_devices, &adapter) {
let device_id = match self.address_to_id.get(&address) {
Some(id) => id.clone(),
None => return drop(sender.send(Err(BluetoothError::NotFound))),
@@ -517,7 +589,12 @@ impl BluetoothManager {
for _ in 0..MAXIMUM_TRANSACTION_TIME {
match d.is_connected().unwrap_or(false) {
true => return drop(sender.send(Ok(true))),
- false => thread::sleep(Duration::from_millis(CONNECTION_TIMEOUT_MS)),
+ false => {
+ if is_mock_adapter(&adapter) {
+ break;
+ }
+ thread::sleep(Duration::from_millis(CONNECTION_TIMEOUT_MS));
+ },
}
}
return drop(sender.send(Err(BluetoothError::Network)));
@@ -617,11 +694,15 @@ impl BluetoothManager {
Some(a) => a,
None => return drop(sender.send(Err(BluetoothError::Type(ADAPTER_ERROR.to_string())))),
};
+ let device = match self.device_from_service_id(&service_id) {
+ Some(device) => device,
+ None => return drop(sender.send(Err(BluetoothError::NotFound))),
+ };
let primary_service = match self.get_gatt_service(&mut adapter, &service_id) {
Some(s) => s,
None => return drop(sender.send(Err(BluetoothError::NotFound))),
};
- let services = primary_service.get_includes().unwrap_or(vec!());
+ let services = primary_service.get_includes(device).unwrap_or(vec!());
for service in services {
if let Ok(service_uuid) = service.get_uuid() {
if uuid == service_uuid {
@@ -644,11 +725,15 @@ impl BluetoothManager {
Some(a) => a,
None => return drop(sender.send(Err(BluetoothError::Type(ADAPTER_ERROR.to_string())))),
};
+ let device = match self.device_from_service_id(&service_id) {
+ Some(device) => device,
+ None => return drop(sender.send(Err(BluetoothError::NotFound))),
+ };
let primary_service = match self.get_gatt_service(&mut adapter, &service_id) {
Some(s) => s,
None => return drop(sender.send(Err(BluetoothError::NotFound))),
};
- let services = primary_service.get_includes().unwrap_or(vec!());
+ let services = primary_service.get_includes(device).unwrap_or(vec!());
let mut services_vec = vec!();
for service in services {
if let Ok(service_uuid) = service.get_uuid() {
diff --git a/components/bluetooth/test.rs b/components/bluetooth/test.rs
new file mode 100644
index 00000000000..ed0b296f2ba
--- /dev/null
+++ b/components/bluetooth/test.rs
@@ -0,0 +1,501 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use BluetoothManager;
+use device::bluetooth::{BluetoothAdapter, BluetoothDevice};
+use device::bluetooth::{BluetoothGATTCharacteristic, BluetoothGATTDescriptor, BluetoothGATTService};
+use std::borrow::ToOwned;
+use std::cell::RefCell;
+use std::collections::HashSet;
+use std::error::Error;
+use std::string::String;
+use uuid::Uuid;
+
+thread_local!(pub static CACHED_IDS: RefCell<HashSet<Uuid>> = RefCell::new(HashSet::new()));
+
+const ADAPTER_ERROR: &'static str = "No adapter found";
+const WRONG_DATA_SET_ERROR: &'static str = "Wrong data set name was provided";
+const READ_FLAG: &'static str = "read";
+const WRITE_FLAG: &'static str = "write";
+
+// Adapter names
+// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=65
+const NOT_PRESENT_ADAPTER: &'static str = "NotPresentAdapter";
+// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=83
+const NOT_POWERED_ADAPTER: &'static str = "NotPoweredAdapter";
+// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=118
+const EMPTY_ADAPTER: &'static str = "EmptyAdapter";
+// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=126
+const GLUCOSE_HEART_RATE_ADAPTER: &'static str = "GlucoseHeartRateAdapter";
+// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=135
+const UNICODE_DEVICE_ADAPTER: &'static str = "UnicodeDeviceAdapter";
+// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=205
+const MISSING_SERVICE_HEART_RATE_ADAPTER: &'static str = "MissingServiceHeartRateAdapter";
+// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=219
+const MISSING_CHARACTERISTIC_HEART_RATE_ADAPTER: &'static str = "MissingCharacteristicHeartRateAdapter";
+const MISSING_DESCRIPTOR_HEART_RATE_ADAPTER: &'static str = "MissingDescriptorHeartRateAdapter";
+// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=234
+const HEART_RATE_ADAPTER: &'static str = "HeartRateAdapter";
+// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=250
+const EMPTY_NAME_HEART_RATE_ADAPTER: &'static str = "EmptyNameHeartRateAdapter";
+// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=267
+const NO_NAME_HEART_RATE_ADAPTER: &'static str = "NoNameHeartRateAdapter";
+// https://cs.chromium.org/chromium/src/content/shell/browser/layout_test/layout_test_bluetooth_adapter_provider.h?l=284
+const TWO_HEART_RATE_SERVICES_ADAPTER: &'static str = "TwoHeartRateServicesAdapter";
+const BLACKLIST_TEST_ADAPTER: &'static str = "BlacklistTestAdapter";
+
+// Device names
+const CONNECTABLE_DEVICE_NAME: &'static str = "Connectable Device";
+const EMPTY_DEVICE_NAME: &'static str = "";
+// https://webbluetoothcg.github.io/web-bluetooth/tests.html#glucosedevice
+const GLUCOSE_DEVICE_NAME: &'static str = "Glucose Device";
+// https://webbluetoothcg.github.io/web-bluetooth/tests.html#heartratedevice
+const HEART_RATE_DEVICE_NAME: &'static str = "Heart Rate Device";
+const UNICODE_DEVICE_NAME: &'static str = "❤❤❤❤❤❤❤❤❤";
+
+// Device addresses
+const CONNECTABLE_DEVICE_ADDRESS: &'static str = "00:00:00:00:00:04";
+// https://webbluetoothcg.github.io/web-bluetooth/tests.html#glucosedevice
+const GLUCOSE_DEVICE_ADDRESS: &'static str = "00:00:00:00:00:02";
+// https://webbluetoothcg.github.io/web-bluetooth/tests.html#heartratedevice
+const HEART_RATE_DEVICE_ADDRESS: &'static str = "00:00:00:00:00:03";
+const UNICODE_DEVICE_ADDRESS: &'static str = "00:00:00:00:00:01";
+
+// Service UUIDs
+const BLACKLIST_TEST_SERVICE_UUID: &'static str = "611c954a-263b-4f4a-aab6-01ddb953f985";
+// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.device_information.xml
+const DEVICE_INFORMATION_UUID: &'static str = "0000180a-0000-1000-8000-00805f9b34fb";
+// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.generic_access.xml
+const GENERIC_ACCESS_SERVICE_UUID: &'static str = "00001800-0000-1000-8000-00805f9b34fb";
+// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.glucose.xml
+const GLUCOSE_SERVICE_UUID: &'static str = "00001808-0000-1000-8000-00805f9b34fb";
+// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.heart_rate.xml
+const HEART_RATE_SERVICE_UUID: &'static str = "0000180d-0000-1000-8000-00805f9b34fb";
+// https://www.bluetooth.com/specifications/gatt/
+// viewer?attributeXmlFile=org.bluetooth.service.human_interface_device.xml
+const HUMAN_INTERFACE_DEVICE_SERVICE_UUID: &'static str = "00001812-0000-1000-8000-00805f9b34fb";
+// https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.service.tx_power.xml
+const TX_POWER_SERVICE_UUID: &'static str = "00001804-0000-1000-8000-00805f9b34fb";
+
+// Characteristic UUIDs
+const BLACKLIST_EXCLUDE_READS_CHARACTERISTIC_UUID: &'static str = "bad1c9a2-9a5b-4015-8b60-1579bbbf2135";
+// https://www.bluetooth.com/specifications/gatt/
+// viewer?attributeXmlFile=org.bluetooth.characteristic.body_sensor_location.xml
+const BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID: &'static str = "00002a38-0000-1000-8000-00805f9b34fb";
+// https://www.bluetooth.com/specifications/gatt/
+// viewer?attributeXmlFile=org.bluetooth.characteristic.gap.device_name.xml
+const DEVICE_NAME_CHARACTERISTIC_UUID: &'static str = "00002a00-0000-1000-8000-00805f9b34fb";
+// https://www.bluetooth.com/specifications/gatt/
+// viewer?attributeXmlFile=org.bluetooth.characteristic.heart_rate_measurement.xml
+const HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID: &'static str = "00002a37-0000-1000-8000-00805f9b34fb";
+// https://www.bluetooth.com/specifications/gatt/
+// viewer?attributeXmlFile=org.bluetooth.characteristic.gap.peripheral_privacy_flag.xml
+const PERIPHERAL_PRIVACY_FLAG_CHARACTERISTIC_UUID: &'static str = "00002a02-0000-1000-8000-00805f9b34fb";
+// https://www.bluetooth.com/specifications/gatt/
+// viewer?attributeXmlFile=org.bluetooth.characteristic.serial_number_string.xml
+const SERIAL_NUMBER_STRING_UUID: &'static str = "00002a25-0000-1000-8000-00805f9b34fb";
+
+// Descriptor UUIDs
+const BLACKLIST_EXCLUDE_READS_DESCRIPTOR_UUID: &'static str = "aaaaaaaa-aaaa-1181-0510-810819516110";
+const BLACKLIST_DESCRIPTOR_UUID: &'static str = "07711111-6104-0970-7011-1107105110aaa";
+// https://www.bluetooth.com/specifications/gatt/
+// viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.characteristic_user_description.xml
+const CHARACTERISTIC_USER_DESCRIPTION_UUID: &'static str = "00002901-0000-1000-8000-00805f9b34fb";
+// https://www.bluetooth.com/specifications/gatt/
+// viewer?attributeXmlFile=org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
+const CLIENT_CHARACTERISTIC_CONFIGURATION_UUID: &'static str = "00002902-0000-1000-8000-00805f9b34fb";
+// https://www.bluetooth.com/specifications/gatt/
+// viewer?attributeXmlFile=org.bluetooth.descriptor.number_of_digitals.xml
+const NUMBER_OF_DIGITALS_UUID: &'static str = "00002909-0000-1000-8000-00805f9b34fb";
+
+const HEART_RATE_DEVICE_NAME_DESCRIPTION: &'static str = "The name of this device.";
+
+fn generate_id() -> Uuid {
+ let mut id = Uuid::nil();
+ let mut generated = false;
+ while !generated {
+ id = Uuid::new_v4();
+ CACHED_IDS.with(|cache|
+ if !cache.borrow().contains(&id) {
+ cache.borrow_mut().insert(id.clone());
+ generated = true;
+ }
+ );
+ }
+ id
+}
+
+// Set the adapter's name, is_powered and is_discoverable attributes
+fn set_adapter(adapter: &BluetoothAdapter, adapter_name: String) -> Result<(), Box<Error>> {
+ try!(adapter.set_name(adapter_name));
+ try!(adapter.set_powered(true));
+ try!(adapter.set_discoverable(true));
+ Ok(())
+}
+
+// Create Device
+fn create_device(adapter: &BluetoothAdapter,
+ name: String,
+ address: String)
+ -> Result<BluetoothDevice, Box<Error>> {
+ let device = try!(BluetoothDevice::create_mock_device(adapter.clone(), generate_id().to_string()));
+ try!(device.set_name(Some(name)));
+ try!(device.set_address(address));
+ try!(device.set_connectable(true));
+ Ok(device)
+}
+
+// Create Device with UUIDs
+fn create_device_with_uuids(adapter: &BluetoothAdapter,
+ name: String,
+ address: String,
+ uuids: Vec<String>)
+ -> Result<BluetoothDevice, Box<Error>> {
+ let device = try!(create_device(adapter, name, address));
+ try!(device.set_uuids(uuids));
+ Ok(device)
+}
+
+// Create Service
+fn create_service(device: &BluetoothDevice,
+ uuid: String)
+ -> Result<BluetoothGATTService, Box<Error>> {
+ let service = try!(BluetoothGATTService::create_mock_service(device.clone(), generate_id().to_string()));
+ try!(service.set_uuid(uuid));
+ Ok(service)
+}
+
+// Create Characteristic
+fn create_characteristic(service: &BluetoothGATTService,
+ uuid: String)
+ -> Result<BluetoothGATTCharacteristic, Box<Error>> {
+ let characteristic =
+ try!(BluetoothGATTCharacteristic::create_mock_characteristic(service.clone(), generate_id().to_string()));
+ try!(characteristic.set_uuid(uuid));
+ Ok(characteristic)
+}
+
+// Create Characteristic with value
+fn create_characteristic_with_value(service: &BluetoothGATTService,
+ uuid: String,
+ value: Vec<u8>)
+ -> Result<BluetoothGATTCharacteristic, Box<Error>> {
+ let characteristic = try!(create_characteristic(service, uuid));
+ try!(characteristic.set_value(value));
+ Ok(characteristic)
+}
+
+// Create Descriptor
+fn create_descriptor(characteristic: &BluetoothGATTCharacteristic,
+ uuid: String)
+ -> Result<BluetoothGATTDescriptor, Box<Error>> {
+ let descriptor =
+ try!(BluetoothGATTDescriptor::create_mock_descriptor(characteristic.clone(), generate_id().to_string()));
+ try!(descriptor.set_uuid(uuid));
+ Ok(descriptor)
+}
+
+// Create Descriptor with value
+fn create_descriptor_with_value(characteristic: &BluetoothGATTCharacteristic,
+ uuid: String,
+ value: Vec<u8>)
+ -> Result<BluetoothGATTDescriptor, Box<Error>> {
+ let descriptor = try!(create_descriptor(characteristic, uuid));
+ try!(descriptor.set_value(value));
+ Ok(descriptor)
+}
+
+fn create_heart_rate_service(device: &BluetoothDevice,
+ empty: bool)
+ -> Result<BluetoothGATTService, Box<Error>> {
+ // Heart Rate Service
+ let heart_rate_service = try!(create_service(device, HEART_RATE_SERVICE_UUID.to_owned()));
+
+ if empty {
+ return Ok(heart_rate_service)
+ }
+
+ // Heart Rate Measurement Characteristic
+ let _heart_rate_measurement_characteristic =
+ try!(create_characteristic_with_value(&heart_rate_service,
+ HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID.to_owned(),
+ vec![0]));
+
+ // Body Sensor Location Characteristic 1
+ let body_sensor_location_characteristic_1 =
+ try!(create_characteristic_with_value(&heart_rate_service,
+ BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(),
+ vec![49]));
+ try!(body_sensor_location_characteristic_1.set_flags(vec![READ_FLAG.to_string()]));
+
+ // Body Sensor Location Characteristic 2
+ let body_sensor_location_characteristic_2 =
+ try!(create_characteristic_with_value(&heart_rate_service,
+ BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(),
+ vec![50]));
+ try!(body_sensor_location_characteristic_2.set_flags(vec![READ_FLAG.to_string()]));
+ Ok(heart_rate_service)
+}
+
+fn create_generic_access_service(device: &BluetoothDevice,
+ empty: bool)
+ -> Result<BluetoothGATTService, Box<Error>> {
+ // Generic Access Service
+ let generic_access_service =
+ try!(create_service(device, GENERIC_ACCESS_SERVICE_UUID.to_owned()));
+
+ if empty {
+ return Ok(generic_access_service)
+ }
+
+ // Device Name Characteristic
+ let device_name_characteristic =
+ try!(create_characteristic_with_value(&generic_access_service,
+ DEVICE_NAME_CHARACTERISTIC_UUID.to_owned(),
+ HEART_RATE_DEVICE_NAME.as_bytes().to_vec()));
+ try!(device_name_characteristic.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()]));
+
+ // Number of Digitals descriptor
+ let number_of_digitals_descriptor_1 =
+ try!(create_descriptor_with_value(&device_name_characteristic,
+ NUMBER_OF_DIGITALS_UUID.to_owned(),
+ vec![49]));
+ try!(number_of_digitals_descriptor_1.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()]));
+
+ let number_of_digitals_descriptor_2 =
+ try!(create_descriptor_with_value(&device_name_characteristic,
+ NUMBER_OF_DIGITALS_UUID.to_owned(),
+ vec![50]));
+ try!(number_of_digitals_descriptor_2.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()]));
+
+ // Characteristic User Description Descriptor
+ let _characteristic_user_description =
+ try!(create_descriptor_with_value(&device_name_characteristic,
+ CHARACTERISTIC_USER_DESCRIPTION_UUID.to_owned(),
+ HEART_RATE_DEVICE_NAME_DESCRIPTION.as_bytes().to_vec()));
+
+ // Client Characteristic Configuration descriptor
+ let _client_characteristic_configuration =
+ try!(create_descriptor_with_value(&device_name_characteristic,
+ CLIENT_CHARACTERISTIC_CONFIGURATION_UUID.to_owned(),
+ vec![0]));
+
+ // Peripheral Privacy Flag Characteristic
+ let peripheral_privacy_flag_characteristic =
+ try!(create_characteristic(&generic_access_service, PERIPHERAL_PRIVACY_FLAG_CHARACTERISTIC_UUID.to_owned()));
+ try!(peripheral_privacy_flag_characteristic
+ .set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()]));
+ Ok(generic_access_service)
+}
+
+// Create Heart Rate Device
+fn create_heart_rate_device(adapter: &BluetoothAdapter,
+ empty: bool)
+ -> Result<BluetoothDevice, Box<Error>> {
+ // Heart Rate Device
+ let heart_rate_device =
+ try!(create_device_with_uuids(adapter,
+ HEART_RATE_DEVICE_NAME.to_owned(),
+ HEART_RATE_DEVICE_ADDRESS.to_owned(),
+ vec![GENERIC_ACCESS_SERVICE_UUID.to_owned(),
+ HEART_RATE_SERVICE_UUID.to_owned()]));
+
+ if empty {
+ return Ok(heart_rate_device);
+ }
+
+ // Generic Access Service
+ let _generic_access_service = try!(create_generic_access_service(&heart_rate_device, false));
+
+ // Heart Rate Service
+ let _heart_rate_service = try!(create_heart_rate_service(&heart_rate_device, false));
+
+ Ok(heart_rate_device)
+}
+
+fn create_missing_characterisitc_heart_rate_device(adapter: &BluetoothAdapter) -> Result<(), Box<Error>> {
+ let heart_rate_device_empty = try!(create_heart_rate_device(adapter, true));
+
+ let _generic_access_service_empty = try!(create_generic_access_service(&heart_rate_device_empty, true));
+
+ let _heart_rate_service_empty = try!(create_heart_rate_service(&heart_rate_device_empty, true));
+
+ Ok(())
+}
+
+fn create_missing_descriptor_heart_rate_device(adapter: &BluetoothAdapter) -> Result<(), Box<Error>> {
+ let heart_rate_device_empty = try!(create_heart_rate_device(adapter, true));
+
+ let generic_access_service_empty = try!(create_generic_access_service(&heart_rate_device_empty, true));
+
+ let _device_name_characteristic =
+ try!(create_characteristic_with_value(&generic_access_service_empty,
+ DEVICE_NAME_CHARACTERISTIC_UUID.to_owned(),
+ HEART_RATE_DEVICE_NAME.as_bytes().to_vec()));
+
+ let peripheral_privacy_flag_characteristic =
+ try!(create_characteristic(&generic_access_service_empty,
+ PERIPHERAL_PRIVACY_FLAG_CHARACTERISTIC_UUID.to_owned()));
+ try!(peripheral_privacy_flag_characteristic.set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()]));
+
+ let _heart_rate_service = try!(create_heart_rate_service(&heart_rate_device_empty, false));
+
+ Ok(())
+}
+
+fn create_two_heart_rate_services_device(adapter: &BluetoothAdapter) -> Result<(), Box<Error>> {
+ let heart_rate_device_empty = try!(create_heart_rate_device(adapter, true));
+
+ try!(heart_rate_device_empty.set_uuids(vec![GENERIC_ACCESS_SERVICE_UUID.to_owned(),
+ HEART_RATE_SERVICE_UUID.to_owned(),
+ HEART_RATE_SERVICE_UUID.to_owned()]));
+
+ let _generic_access_service = try!(create_generic_access_service(&heart_rate_device_empty, false));
+
+ let heart_rate_service_empty_1 = try!(create_heart_rate_service(&heart_rate_device_empty, true));
+
+ let heart_rate_service_empty_2 = try!(create_heart_rate_service(&heart_rate_device_empty, true));
+
+ let _heart_rate_measurement_characteristic =
+ try!(create_characteristic_with_value(&heart_rate_service_empty_1,
+ HEART_RATE_MEASUREMENT_CHARACTERISTIC_UUID.to_owned(),
+ vec![0]));
+
+ let _body_sensor_location_characteristic_1 =
+ try!(create_characteristic_with_value(&heart_rate_service_empty_1,
+ BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(),
+ vec![49]));
+
+ let _body_sensor_location_characteristic_2 =
+ try!(create_characteristic_with_value(&heart_rate_service_empty_2,
+ BODY_SENSOR_LOCATION_CHARACTERISTIC_UUID.to_owned(),
+ vec![50]));
+ Ok(())
+}
+
+fn create_blacklisted_device(adapter: &BluetoothAdapter) -> Result<(), Box<Error>> {
+ let connectable_device =
+ try!(create_device_with_uuids(adapter,
+ CONNECTABLE_DEVICE_NAME.to_owned(),
+ CONNECTABLE_DEVICE_ADDRESS.to_owned(),
+ vec![BLACKLIST_TEST_SERVICE_UUID.to_owned(),
+ DEVICE_INFORMATION_UUID.to_owned(),
+ GENERIC_ACCESS_SERVICE_UUID.to_owned(),
+ HEART_RATE_SERVICE_UUID.to_owned(),
+ HUMAN_INTERFACE_DEVICE_SERVICE_UUID.to_owned()]));
+
+ let blacklist_test_service = try!(create_service(&connectable_device, BLACKLIST_TEST_SERVICE_UUID.to_owned()));
+
+ let blacklist_exclude_reads_characteristic =
+ try!(create_characteristic(&blacklist_test_service,
+ BLACKLIST_EXCLUDE_READS_CHARACTERISTIC_UUID.to_owned()));
+ try!(blacklist_exclude_reads_characteristic
+ .set_flags(vec![READ_FLAG.to_string(), WRITE_FLAG.to_string()]));
+
+ let _blacklist_exclude_reads_descriptor =
+ try!(create_descriptor_with_value(&blacklist_exclude_reads_characteristic,
+ BLACKLIST_EXCLUDE_READS_DESCRIPTOR_UUID.to_owned(),
+ vec![54; 3]));
+
+ let _blacklist_descriptor =
+ try!(create_descriptor_with_value(&blacklist_exclude_reads_characteristic,
+ BLACKLIST_DESCRIPTOR_UUID.to_owned(),
+ vec![54; 3]));
+
+ let device_information_service = try!(create_service(&connectable_device, DEVICE_INFORMATION_UUID.to_owned()));
+
+ let _serial_number_string_characteristic =
+ try!(create_characteristic(&device_information_service, SERIAL_NUMBER_STRING_UUID.to_owned()));
+
+ let _generic_access_service = try!(create_generic_access_service(&connectable_device, false));
+
+ let _heart_rate_service = try!(create_heart_rate_service(&connectable_device, false));
+
+ let _human_interface_device_service =
+ try!(create_service(&connectable_device, HUMAN_INTERFACE_DEVICE_SERVICE_UUID.to_owned()));
+ Ok(())
+}
+
+pub fn test(manager: &mut BluetoothManager, data_set_name: String) -> Result<(), Box<Error>> {
+ let may_existing_adapter = manager.get_or_create_adapter();
+ let adapter = match may_existing_adapter.as_ref() {
+ Some(adapter) => adapter,
+ None => return Err(Box::from(ADAPTER_ERROR.to_string())),
+ };
+ match data_set_name.as_str() {
+ NOT_PRESENT_ADAPTER => {
+ try!(set_adapter(adapter, NOT_PRESENT_ADAPTER.to_owned()));
+ try!(adapter.set_present(false));
+ },
+ NOT_POWERED_ADAPTER => {
+ try!(set_adapter(adapter, NOT_POWERED_ADAPTER.to_owned()));
+ try!(adapter.set_powered(false));
+ },
+ EMPTY_ADAPTER => {
+ try!(set_adapter(adapter, EMPTY_ADAPTER.to_owned()));
+ },
+ GLUCOSE_HEART_RATE_ADAPTER => {
+ try!(set_adapter(adapter, GLUCOSE_HEART_RATE_ADAPTER.to_owned()));
+
+ let _glucose_devie = try!(create_device_with_uuids(adapter,
+ GLUCOSE_DEVICE_NAME.to_owned(),
+ GLUCOSE_DEVICE_ADDRESS.to_owned(),
+ vec![GLUCOSE_SERVICE_UUID.to_owned(),
+ TX_POWER_SERVICE_UUID.to_owned()]));
+
+ let _heart_rate_device_empty = try!(create_heart_rate_device(adapter, true));
+ },
+ UNICODE_DEVICE_ADAPTER => {
+ try!(set_adapter(adapter, UNICODE_DEVICE_ADAPTER.to_owned()));
+
+ let _unicode_device = try!(create_device(adapter,
+ UNICODE_DEVICE_NAME.to_owned(),
+ UNICODE_DEVICE_ADDRESS.to_owned()));
+ },
+ MISSING_SERVICE_HEART_RATE_ADAPTER => {
+ try!(set_adapter(adapter, MISSING_SERVICE_HEART_RATE_ADAPTER.to_owned()));
+
+ let _heart_rate_device_empty = try!(create_heart_rate_device(adapter, true));
+ },
+ MISSING_CHARACTERISTIC_HEART_RATE_ADAPTER => {
+ try!(set_adapter(adapter, MISSING_CHARACTERISTIC_HEART_RATE_ADAPTER.to_owned()));
+
+ let _ = try!(create_missing_characterisitc_heart_rate_device(adapter));
+ },
+ MISSING_DESCRIPTOR_HEART_RATE_ADAPTER => {
+ try!(set_adapter(adapter, MISSING_DESCRIPTOR_HEART_RATE_ADAPTER.to_owned()));
+
+ let _ = try!(create_missing_descriptor_heart_rate_device(adapter));
+ },
+ HEART_RATE_ADAPTER => {
+ try!(set_adapter(adapter, HEART_RATE_ADAPTER.to_owned()));
+
+ let _heart_rate_device = try!(create_heart_rate_device(adapter, false));
+ },
+ EMPTY_NAME_HEART_RATE_ADAPTER => {
+ try!(set_adapter(adapter, EMPTY_NAME_HEART_RATE_ADAPTER.to_owned()));
+
+ let heart_rate_device = try!(create_heart_rate_device(adapter, false));
+ try!(heart_rate_device.set_name(Some(EMPTY_DEVICE_NAME.to_owned())));
+ },
+ NO_NAME_HEART_RATE_ADAPTER => {
+ try!(set_adapter(adapter, NO_NAME_HEART_RATE_ADAPTER.to_owned()));
+
+ let heart_rate_device = try!(create_heart_rate_device(adapter, false));
+ try!(heart_rate_device.set_name(None));
+ },
+ TWO_HEART_RATE_SERVICES_ADAPTER => {
+ try!(set_adapter(adapter, TWO_HEART_RATE_SERVICES_ADAPTER.to_owned()));
+
+ let _ = try!(create_two_heart_rate_services_device(adapter));
+ },
+ BLACKLIST_TEST_ADAPTER => {
+ try!(set_adapter(adapter, BLACKLIST_TEST_ADAPTER.to_owned()));
+
+ let _ = try!(create_blacklisted_device(adapter));
+ },
+ _ => return Err(Box::from(WRONG_DATA_SET_ERROR.to_string())),
+ }
+ return Ok(());
+}
diff --git a/components/bluetooth_traits/lib.rs b/components/bluetooth_traits/lib.rs
index dcff8cead91..a1b1b41be6e 100644
--- a/components/bluetooth_traits/lib.rs
+++ b/components/bluetooth_traits/lib.rs
@@ -86,5 +86,6 @@ pub enum BluetoothMethodMsg {
GetDescriptors(String, Option<String>, IpcSender<BluetoothResult<BluetoothDescriptorsMsg>>),
ReadValue(String, IpcSender<BluetoothResult<Vec<u8>>>),
WriteValue(String, Vec<u8>, IpcSender<BluetoothResult<bool>>),
+ Test(String, IpcSender<BluetoothResult<()>>),
Exit,
}
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index 14498823424..d419d41ec61 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -399,6 +399,7 @@ pub mod testbinding;
pub mod testbindingiterable;
pub mod testbindingpairiterable;
pub mod testbindingproxy;
+pub mod testrunner;
pub mod text;
pub mod textdecoder;
pub mod textencoder;
diff --git a/components/script/dom/testrunner.rs b/components/script/dom/testrunner.rs
new file mode 100644
index 00000000000..f96ab6dbf65
--- /dev/null
+++ b/components/script/dom/testrunner.rs
@@ -0,0 +1,53 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use bluetooth_traits::BluetoothMethodMsg;
+use dom::bindings::codegen::Bindings::TestRunnerBinding;
+use dom::bindings::codegen::Bindings::TestRunnerBinding::TestRunnerMethods;
+use dom::bindings::error::{Error, ErrorResult};
+use dom::bindings::js::Root;
+use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
+use dom::bindings::str::DOMString;
+use dom::globalscope::GlobalScope;
+use ipc_channel::ipc::{self, IpcSender};
+
+// https://webbluetoothcg.github.io/web-bluetooth/tests#test-runner
+ #[dom_struct]
+pub struct TestRunner {
+ reflector_: Reflector,
+}
+
+impl TestRunner {
+ pub fn new_inherited() -> TestRunner {
+ TestRunner {
+ reflector_: Reflector::new(),
+ }
+ }
+
+ pub fn new(global: &GlobalScope) -> Root<TestRunner> {
+ reflect_dom_object(box TestRunner::new_inherited(),
+ global,
+ TestRunnerBinding::Wrap)
+ }
+
+ fn get_bluetooth_thread(&self) -> IpcSender<BluetoothMethodMsg> {
+ self.global().as_window().bluetooth_thread()
+ }
+}
+
+impl TestRunnerMethods for TestRunner {
+ // https://webbluetoothcg.github.io/web-bluetooth/tests#setBluetoothMockDataSet
+ fn SetBluetoothMockDataSet(&self, dataSetName: DOMString) -> ErrorResult {
+ let (sender, receiver) = ipc::channel().unwrap();
+ self.get_bluetooth_thread().send(BluetoothMethodMsg::Test(String::from(dataSetName), sender)).unwrap();
+ match receiver.recv().unwrap().into() {
+ Ok(()) => {
+ Ok(())
+ },
+ Err(error) => {
+ Err(Error::from(error))
+ },
+ }
+ }
+}
diff --git a/components/script/dom/webidls/TestRunner.webidl b/components/script/dom/webidls/TestRunner.webidl
new file mode 100644
index 00000000000..0326c14dbec
--- /dev/null
+++ b/components/script/dom/webidls/TestRunner.webidl
@@ -0,0 +1,16 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// https://webbluetoothcg.github.io/web-bluetooth/tests#test-runner
+
+// callback BluetoothManualChooserEventsCallback = void(sequence<DOMString> events);
+
+[Pref="dom.bluetooth.testing.enabled", Exposed=Window]
+interface TestRunner {
+ [Throws]
+ void setBluetoothMockDataSet(DOMString dataSetName);
+ // void setBluetoothManualChooser();
+ // void getBluetoothManualChooserEvents(BluetoothManualChooserEventsCallback callback);
+ // void sendBluetoothManualChooserEvent(DOMString event, DOMString argument);
+};
diff --git a/components/script/dom/webidls/Window.webidl b/components/script/dom/webidls/Window.webidl
index ad3494b6f5f..5e7e08d4b18 100644
--- a/components/script/dom/webidls/Window.webidl
+++ b/components/script/dom/webidls/Window.webidl
@@ -185,3 +185,10 @@ Window implements WindowLocalStorage;
// http://w3c.github.io/animation-timing/#framerequestcallback
callback FrameRequestCallback = void (DOMHighResTimeStamp time);
+
+// https://webbluetoothcg.github.io/web-bluetooth/tests#test-interfaces
+partial interface Window {
+ [Pref="dom.bluetooth.testing.enabled", Exposed=Window]
+ readonly attribute TestRunner testRunner;
+ //readonly attribute EventSender eventSender;
+};
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index c77ed80cff9..3d3d7dde2a7 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -45,6 +45,7 @@ use dom::performance::Performance;
use dom::promise::Promise;
use dom::screen::Screen;
use dom::storage::Storage;
+use dom::testrunner::TestRunner;
use euclid::{Point2D, Rect, Size2D};
use fetch;
use ipc_channel::ipc::{self, IpcSender};
@@ -239,6 +240,8 @@ pub struct Window {
/// All the MediaQueryLists we need to update
media_query_lists: WeakMediaQueryListVec,
+
+ test_runner: MutNullableHeap<JS<TestRunner>>,
}
impl Window {
@@ -881,6 +884,10 @@ impl WindowMethods for Window {
fn Fetch(&self, input: RequestOrUSVString, init: &RequestInit) -> Rc<Promise> {
fetch::Fetch(&self.upcast(), input, init)
}
+
+ fn TestRunner(&self) -> Root<TestRunner> {
+ self.test_runner.or_init(|| TestRunner::new(self.upcast()))
+ }
}
impl Window {
@@ -1588,6 +1595,7 @@ impl Window {
error_reporter: error_reporter,
scroll_offsets: DOMRefCell::new(HashMap::new()),
media_query_lists: WeakMediaQueryListVec::new(),
+ test_runner: Default::default(),
};
WindowBinding::Wrap(runtime.cx(), win)
diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock
index c3263e06541..3ae065e88eb 100644
--- a/components/servo/Cargo.lock
+++ b/components/servo/Cargo.lock
@@ -199,6 +199,7 @@ dependencies = [
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"tinyfiledialogs 0.1.0 (git+https://github.com/jdm/tinyfiledialogs)",
"util 0.0.1",
+ "uuid 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -216,8 +217,16 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "blurmock"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "blurz"
-version = "0.2.0"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dbus 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -515,10 +524,11 @@ dependencies = [
[[package]]
name = "device"
version = "0.0.1"
-source = "git+https://github.com/servo/devices#6d40b1412fb496b0d9434ee2f46e9dfc4dc67ae7"
+source = "git+https://github.com/servo/devices#4a6ab4be0de229fafa6aa3657a5702646832ba08"
dependencies = [
"blurdroid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "blurz 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "blurmock 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "blurz 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2905,7 +2915,8 @@ dependencies = [
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
"checksum blurdroid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5fce4ea3366b583e9d49e1aa3a42252e53b42911bccd06f31c3e81c48ccfc79e"
-"checksum blurz 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96134f6ac62fa6925761dbdb4096617d65d7c1d383d90e5c2d4c489919f773dc"
+"checksum blurmock 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c3034c7372bc7951e0a916b7e952b0043cd4ccb5112cd30827f0e1708e05c2b1"
+"checksum blurz 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d49796c8d5a1b5f6b2b8686e46ed4ab842987c477f765b69f1d3e8df6072608"
"checksum brotli 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "bff2d5511b5ba5840f46cc3f9c0c3ab09db20e9b9a4db344ef7df3fb547a627a"
"checksum browserhtml 0.1.17 (git+https://github.com/browserhtml/browserhtml?branch=crate)" = "<none>"
"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock
index 16d18f46f4a..a0e1dc4b6f7 100644
--- a/ports/cef/Cargo.lock
+++ b/ports/cef/Cargo.lock
@@ -170,6 +170,7 @@ dependencies = [
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"tinyfiledialogs 0.1.0 (git+https://github.com/jdm/tinyfiledialogs)",
"util 0.0.1",
+ "uuid 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -187,8 +188,16 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
+name = "blurmock"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "blurz"
-version = "0.2.0"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dbus 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -470,10 +479,11 @@ dependencies = [
[[package]]
name = "device"
version = "0.0.1"
-source = "git+https://github.com/servo/devices#6d40b1412fb496b0d9434ee2f46e9dfc4dc67ae7"
+source = "git+https://github.com/servo/devices#4a6ab4be0de229fafa6aa3657a5702646832ba08"
dependencies = [
"blurdroid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "blurz 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "blurmock 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "blurz 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2763,7 +2773,8 @@ dependencies = [
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
"checksum block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
"checksum blurdroid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5fce4ea3366b583e9d49e1aa3a42252e53b42911bccd06f31c3e81c48ccfc79e"
-"checksum blurz 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96134f6ac62fa6925761dbdb4096617d65d7c1d383d90e5c2d4c489919f773dc"
+"checksum blurmock 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c3034c7372bc7951e0a916b7e952b0043cd4ccb5112cd30827f0e1708e05c2b1"
+"checksum blurz 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d49796c8d5a1b5f6b2b8686e46ed4ab842987c477f765b69f1d3e8df6072608"
"checksum brotli 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "bff2d5511b5ba5840f46cc3f9c0c3ab09db20e9b9a4db344ef7df3fb547a627a"
"checksum browserhtml 0.1.17 (git+https://github.com/browserhtml/browserhtml?branch=crate)" = "<none>"
"checksum byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"
diff --git a/resources/gatt_blacklist.txt b/resources/gatt_blacklist.txt
index d238bcf8924..4218811b189 100644
--- a/resources/gatt_blacklist.txt
+++ b/resources/gatt_blacklist.txt
@@ -40,6 +40,9 @@ f000ffc0-0451-4000-b000-000000000000
# Block access to standardized unique identifiers, for privacy reasons.
00002a25-0000-1000-8000-00805f9b34fb
+# Blacklisted characteristic used to test readValue function.
+bad1c9a2-9a5b-4015-8b60-1579bbbf2135 exclude-reads
+
## Descriptors
@@ -50,4 +53,10 @@ f000ffc0-0451-4000-b000-000000000000
# org.bluetooth.descriptor.gatt.server_characteristic_configuration
# Writing to this would let a web page interfere with the broadcasted services.
-00002903-0000-1000-8000-00805f9b34fb exclude-writes \ No newline at end of file
+00002903-0000-1000-8000-00805f9b34fb exclude-writes
+
+# Blacklisted descriptor used to test.
+07711111-6104-0970-7011-1107105110aaa
+
+# Blacklisted descriptor used to test.
+aaaaaaaa-aaaa-1181-0510-810819516110 exclude-reads \ No newline at end of file
diff --git a/resources/package-prefs.json b/resources/package-prefs.json
index 62c13fe617f..aa5d1d83303 100644
--- a/resources/package-prefs.json
+++ b/resources/package-prefs.json
@@ -1,5 +1,6 @@
{
"dom.bluetooth.enabled": false,
+ "dom.bluetooth.testing.enabled": false,
"dom.forcetouch.enabled": true,
"dom.mouseevent.which.enabled": false,
"dom.mozbrowser.enabled": true,
diff --git a/resources/prefs.json b/resources/prefs.json
index 7c7fdabb61c..26b832385c7 100644
--- a/resources/prefs.json
+++ b/resources/prefs.json
@@ -1,5 +1,6 @@
{
"dom.bluetooth.enabled": false,
+ "dom.bluetooth.testing.enabled": false,
"dom.forcetouch.enabled": false,
"dom.mouseevent.which.enabled": false,
"dom.mozbrowser.enabled": false,
diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json
index 9a3d311ad01..626f628c173 100644
--- a/tests/wpt/mozilla/meta/MANIFEST.json
+++ b/tests/wpt/mozilla/meta/MANIFEST.json
@@ -6674,6 +6674,978 @@
"url": "/_mozilla/mozilla/binding_keyword.html"
}
],
+ "mozilla/bluetooth/connect/connection-succeeds.html": [
+ {
+ "path": "mozilla/bluetooth/connect/connection-succeeds.html",
+ "url": "/_mozilla/mozilla/bluetooth/connect/connection-succeeds.html"
+ }
+ ],
+ "mozilla/bluetooth/connect/device-goes-out-of-range.html": [
+ {
+ "path": "mozilla/bluetooth/connect/device-goes-out-of-range.html",
+ "url": "/_mozilla/mozilla/bluetooth/connect/device-goes-out-of-range.html"
+ }
+ ],
+ "mozilla/bluetooth/connect/get-same-gatt-server.html": [
+ {
+ "path": "mozilla/bluetooth/connect/get-same-gatt-server.html",
+ "url": "/_mozilla/mozilla/bluetooth/connect/get-same-gatt-server.html"
+ }
+ ],
+ "mozilla/bluetooth/disconnect/connect-disconnect-twice.html": [
+ {
+ "path": "mozilla/bluetooth/disconnect/connect-disconnect-twice.html",
+ "url": "/_mozilla/mozilla/bluetooth/disconnect/connect-disconnect-twice.html"
+ }
+ ],
+ "mozilla/bluetooth/disconnect/disconnect-once.html": [
+ {
+ "path": "mozilla/bluetooth/disconnect/disconnect-once.html",
+ "url": "/_mozilla/mozilla/bluetooth/disconnect/disconnect-once.html"
+ }
+ ],
+ "mozilla/bluetooth/disconnect/disconnect-twice-in-a-row.html": [
+ {
+ "path": "mozilla/bluetooth/disconnect/disconnect-twice-in-a-row.html",
+ "url": "/_mozilla/mozilla/bluetooth/disconnect/disconnect-twice-in-a-row.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristic/blacklisted-characteristic.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristic/blacklisted-characteristic.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristic/blacklisted-characteristic.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristic/characteristic-found.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristic/characteristic-found.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristic/characteristic-found.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristic/characteristic-not-found.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristic/characteristic-not-found.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristic/characteristic-not-found.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristic/device-goes-out-of-range.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristic/device-goes-out-of-range.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristic/device-goes-out-of-range.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristic/disconnect-called-before.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristic/disconnect-called-before.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristic/disconnect-called-before.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristic/disconnect-called-during.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristic/disconnect-called-during.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristic/disconnect-called-during.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristic/get-same-characteristic.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristic/get-same-characteristic.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristic/get-same-characteristic.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristic/invalid-characteristic-name.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristic/invalid-characteristic-name.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristic/invalid-characteristic-name.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristic/service-is-removed.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristic/service-is-removed.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristic/service-is-removed.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristics/blacklisted-characteristics-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristics/blacklisted-characteristics-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/blacklisted-characteristics-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristics/blacklisted-characteristics.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristics/blacklisted-characteristics.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/blacklisted-characteristics.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristics/characteristics-found-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristics/characteristics-found-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/characteristics-found-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristics/characteristics-found.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristics/characteristics-found.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/characteristics-found.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristics/characteristics-not-found-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristics/characteristics-not-found-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/characteristics-not-found-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristics/characteristics-not-found.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristics/characteristics-not-found.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/characteristics-not-found.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristics/correct-characteristics.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristics/correct-characteristics.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/correct-characteristics.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristics/device-goes-out-of-range-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristics/device-goes-out-of-range-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/device-goes-out-of-range-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristics/device-goes-out-of-range.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristics/device-goes-out-of-range.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/device-goes-out-of-range.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristics/disconnect-called-before-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristics/disconnect-called-before-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/disconnect-called-before-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristics/disconnect-called-before.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristics/disconnect-called-before.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/disconnect-called-before.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristics/disconnect-called-during-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristics/disconnect-called-during-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/disconnect-called-during-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristics/disconnect-called-during.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristics/disconnect-called-during.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/disconnect-called-during.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristics/get-same-characteristics.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristics/get-same-characteristics.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/get-same-characteristics.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristics/invalid-characteristic-name.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristics/invalid-characteristic-name.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/invalid-characteristic-name.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristics/service-is-removed-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristics/service-is-removed-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/service-is-removed-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getCharacteristics/service-is-removed.html": [
+ {
+ "path": "mozilla/bluetooth/getCharacteristics/service-is-removed.html",
+ "url": "/_mozilla/mozilla/bluetooth/getCharacteristics/service-is-removed.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptor/blacklisted-descriptor.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptor/blacklisted-descriptor.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptor/blacklisted-descriptor.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptor/characteristic-is-removed.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptor/characteristic-is-removed.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptor/characteristic-is-removed.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptor/descriptor-found.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptor/descriptor-found.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptor/descriptor-found.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptor/descriptor-not-found.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptor/descriptor-not-found.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptor/descriptor-not-found.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptor/device-goes-out-of-range.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptor/device-goes-out-of-range.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptor/device-goes-out-of-range.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptor/disconnect-called-before.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptor/disconnect-called-before.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptor/disconnect-called-before.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptor/disconnect-called-during.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptor/disconnect-called-during.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptor/disconnect-called-during.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptor/get-same-descriptor.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptor/get-same-descriptor.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptor/get-same-descriptor.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptor/invalid-descriptor-name.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptor/invalid-descriptor-name.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptor/invalid-descriptor-name.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptors/blacklisted-descriptors-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptors/blacklisted-descriptors-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptors/blacklisted-descriptors-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptors/blacklisted-descriptors.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptors/blacklisted-descriptors.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptors/blacklisted-descriptors.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptors/characteristic-is-removed-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptors/characteristic-is-removed-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptors/characteristic-is-removed-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptors/characteristic-is-removed.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptors/characteristic-is-removed.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptors/characteristic-is-removed.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptors/correct-descriptors.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptors/correct-descriptors.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptors/correct-descriptors.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptors/descriptors-found-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptors/descriptors-found-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptors/descriptors-found-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptors/descriptors-found.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptors/descriptors-found.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptors/descriptors-found.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptors/descriptors-not-found-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptors/descriptors-not-found-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptors/descriptors-not-found-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptors/descriptors-not-found.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptors/descriptors-not-found.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptors/descriptors-not-found.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptors/device-goes-out-of-range-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptors/device-goes-out-of-range-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptors/device-goes-out-of-range-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptors/device-goes-out-of-range.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptors/device-goes-out-of-range.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptors/device-goes-out-of-range.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptors/disconnect-called-before-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptors/disconnect-called-before-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptors/disconnect-called-before-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptors/disconnect-called-before.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptors/disconnect-called-before.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptors/disconnect-called-before.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptors/disconnect-called-during-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptors/disconnect-called-during-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptors/disconnect-called-during-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptors/disconnect-called-during.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptors/disconnect-called-during.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptors/disconnect-called-during.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptors/get-same-descriptors.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptors/get-same-descriptors.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptors/get-same-descriptors.html"
+ }
+ ],
+ "mozilla/bluetooth/getDescriptors/invalid-descriptor-name.html": [
+ {
+ "path": "mozilla/bluetooth/getDescriptors/invalid-descriptor-name.html",
+ "url": "/_mozilla/mozilla/bluetooth/getDescriptors/invalid-descriptor-name.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryService/device-goes-out-of-range.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryService/device-goes-out-of-range.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryService/device-goes-out-of-range.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryService/disconnect-called-before.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryService/disconnect-called-before.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryService/disconnect-called-before.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryService/disconnect-called-during.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryService/disconnect-called-during.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryService/disconnect-called-during.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryService/disconnected-device.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryService/disconnected-device.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryService/disconnected-device.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryService/get-same-service.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryService/get-same-service.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryService/get-same-service.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryService/invalid-service-name.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryService/invalid-service-name.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryService/invalid-service-name.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryService/no-permission-absent-service.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryService/no-permission-absent-service.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryService/no-permission-absent-service.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryService/no-permission-present-service.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryService/no-permission-present-service.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryService/no-permission-present-service.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryService/service-found.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryService/service-found.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryService/service-found.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryService/service-not-found.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryService/service-not-found.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryService/service-not-found.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/blacklisted-services-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/blacklisted-services-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/blacklisted-services-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/blacklisted-services.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/blacklisted-services.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/blacklisted-services.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/correct-services.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/correct-services.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/correct-services.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/disconnect-called-before-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/disconnect-called-before-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/disconnect-called-before-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/disconnect-called-before.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/disconnect-called-before.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/disconnect-called-before.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/disconnect-called-during-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/disconnect-called-during-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/disconnect-called-during-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/disconnect-called-during.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/disconnect-called-during.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/disconnect-called-during.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/disconnected-device-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/disconnected-device-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/disconnected-device-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/disconnected-device.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/disconnected-device.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/disconnected-device.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/get-same-service.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/get-same-service.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/get-same-service.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/invalid-service-name.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/invalid-service-name.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/invalid-service-name.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/no-permission-absent-service-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/no-permission-absent-service-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/no-permission-absent-service-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/no-permission-present-service-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/no-permission-present-service-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/no-permission-present-service-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/no-permission-present-service.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/no-permission-present-service.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/no-permission-present-service.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/services-found-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/services-found-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/services-found-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/services-found.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/services-found.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/services-found.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/services-not-found-with-uuid.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/services-not-found-with-uuid.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/services-not-found-with-uuid.html"
+ }
+ ],
+ "mozilla/bluetooth/getPrimaryServices/services-not-found.html": [
+ {
+ "path": "mozilla/bluetooth/getPrimaryServices/services-not-found.html",
+ "url": "/_mozilla/mozilla/bluetooth/getPrimaryServices/services-not-found.html"
+ }
+ ],
+ "mozilla/bluetooth/readValue/characteristic/blacklisted-characteristic.html": [
+ {
+ "path": "mozilla/bluetooth/readValue/characteristic/blacklisted-characteristic.html",
+ "url": "/_mozilla/mozilla/bluetooth/readValue/characteristic/blacklisted-characteristic.html"
+ }
+ ],
+ "mozilla/bluetooth/readValue/characteristic/characteristic-is-removed.html": [
+ {
+ "path": "mozilla/bluetooth/readValue/characteristic/characteristic-is-removed.html",
+ "url": "/_mozilla/mozilla/bluetooth/readValue/characteristic/characteristic-is-removed.html"
+ }
+ ],
+ "mozilla/bluetooth/readValue/characteristic/device-goes-out-of-range.html": [
+ {
+ "path": "mozilla/bluetooth/readValue/characteristic/device-goes-out-of-range.html",
+ "url": "/_mozilla/mozilla/bluetooth/readValue/characteristic/device-goes-out-of-range.html"
+ }
+ ],
+ "mozilla/bluetooth/readValue/characteristic/disconnect-called-before.html": [
+ {
+ "path": "mozilla/bluetooth/readValue/characteristic/disconnect-called-before.html",
+ "url": "/_mozilla/mozilla/bluetooth/readValue/characteristic/disconnect-called-before.html"
+ }
+ ],
+ "mozilla/bluetooth/readValue/characteristic/read-succeeds.html": [
+ {
+ "path": "mozilla/bluetooth/readValue/characteristic/read-succeeds.html",
+ "url": "/_mozilla/mozilla/bluetooth/readValue/characteristic/read-succeeds.html"
+ }
+ ],
+ "mozilla/bluetooth/readValue/characteristic/read-updates-value.html": [
+ {
+ "path": "mozilla/bluetooth/readValue/characteristic/read-updates-value.html",
+ "url": "/_mozilla/mozilla/bluetooth/readValue/characteristic/read-updates-value.html"
+ }
+ ],
+ "mozilla/bluetooth/readValue/characteristic/service-is-removed.html": [
+ {
+ "path": "mozilla/bluetooth/readValue/characteristic/service-is-removed.html",
+ "url": "/_mozilla/mozilla/bluetooth/readValue/characteristic/service-is-removed.html"
+ }
+ ],
+ "mozilla/bluetooth/readValue/descriptor/blacklisted-descriptor.html": [
+ {
+ "path": "mozilla/bluetooth/readValue/descriptor/blacklisted-descriptor.html",
+ "url": "/_mozilla/mozilla/bluetooth/readValue/descriptor/blacklisted-descriptor.html"
+ }
+ ],
+ "mozilla/bluetooth/readValue/descriptor/characteristic-is-removed.html": [
+ {
+ "path": "mozilla/bluetooth/readValue/descriptor/characteristic-is-removed.html",
+ "url": "/_mozilla/mozilla/bluetooth/readValue/descriptor/characteristic-is-removed.html"
+ }
+ ],
+ "mozilla/bluetooth/readValue/descriptor/descriptor-is-removed.html": [
+ {
+ "path": "mozilla/bluetooth/readValue/descriptor/descriptor-is-removed.html",
+ "url": "/_mozilla/mozilla/bluetooth/readValue/descriptor/descriptor-is-removed.html"
+ }
+ ],
+ "mozilla/bluetooth/readValue/descriptor/device-goes-out-of-range.html": [
+ {
+ "path": "mozilla/bluetooth/readValue/descriptor/device-goes-out-of-range.html",
+ "url": "/_mozilla/mozilla/bluetooth/readValue/descriptor/device-goes-out-of-range.html"
+ }
+ ],
+ "mozilla/bluetooth/readValue/descriptor/disconnect-called-before.html": [
+ {
+ "path": "mozilla/bluetooth/readValue/descriptor/disconnect-called-before.html",
+ "url": "/_mozilla/mozilla/bluetooth/readValue/descriptor/disconnect-called-before.html"
+ }
+ ],
+ "mozilla/bluetooth/readValue/descriptor/read-succeeds.html": [
+ {
+ "path": "mozilla/bluetooth/readValue/descriptor/read-succeeds.html",
+ "url": "/_mozilla/mozilla/bluetooth/readValue/descriptor/read-succeeds.html"
+ }
+ ],
+ "mozilla/bluetooth/readValue/descriptor/read-updates-value.html": [
+ {
+ "path": "mozilla/bluetooth/readValue/descriptor/read-updates-value.html",
+ "url": "/_mozilla/mozilla/bluetooth/readValue/descriptor/read-updates-value.html"
+ }
+ ],
+ "mozilla/bluetooth/readValue/descriptor/service-is-removed.html": [
+ {
+ "path": "mozilla/bluetooth/readValue/descriptor/service-is-removed.html",
+ "url": "/_mozilla/mozilla/bluetooth/readValue/descriptor/service-is-removed.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/accept-all-devices-with-filter.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/accept-all-devices-with-filter.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/accept-all-devices-with-filter.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/accept-all-devices.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/accept-all-devices.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/accept-all-devices.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/adapter-not-present.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/adapter-not-present.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/adapter-not-present.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/adapter-off.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/adapter-off.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/adapter-off.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/blacklisted-service-in-filter.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/blacklisted-service-in-filter.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/blacklisted-service-in-filter.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/blacklisted-service-in-optionalServices.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/blacklisted-service-in-optionalServices.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/blacklisted-service-in-optionalServices.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-filter.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-filter.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-filter.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-filters-member.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-filters-member.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-filters-member.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-namePrefix.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-namePrefix.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-namePrefix.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-services-member.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-services-member.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-services-member.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-device-name-name.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-device-name-name.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-device-name-name.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-device-name-namePrefix.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-device-name-namePrefix.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-device-name-namePrefix.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-name.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-name.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-name.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-namePrefix.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-namePrefix.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-namePrefix.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/canonicalizeFilter/no-arguments.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/no-arguments.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/no-arguments.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/canonicalizeFilter/no-filters-member.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/no-filters-member.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/no-filters-member.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-name.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-name.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-name.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-namePrefix.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-namePrefix.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-namePrefix.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-name.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-name.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-name.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-namePrefix.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-namePrefix.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-namePrefix.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-valid-length-name-name.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-valid-length-name-name.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-valid-length-name-name.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-valid-length-name-namePrefix.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-valid-length-name-namePrefix.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-valid-length-name-namePrefix.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/canonicalizeFilter/wrong-service-in-optionalServices-member.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/wrong-service-in-optionalServices-member.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/wrong-service-in-optionalServices-member.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/canonicalizeFilter/wrong-service-in-services-member.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/canonicalizeFilter/wrong-service-in-services-member.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/canonicalizeFilter/wrong-service-in-services-member.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/correct-uuids.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/correct-uuids.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/correct-uuids.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/discovery-succeeds.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/discovery-succeeds.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/discovery-succeeds.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/filter-does-not-match.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/filter-does-not-match.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/filter-does-not-match.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/filter-matches.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/filter-matches.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/filter-matches.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/name-empty-device-from-name-empty-filter.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/name-empty-device-from-name-empty-filter.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/name-empty-device-from-name-empty-filter.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/name-empty-device-from-name-prefix-filter.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/name-empty-device-from-name-prefix-filter.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/name-empty-device-from-name-prefix-filter.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/name-empty-device-from-name-wrong-filter.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/name-empty-device-from-name-wrong-filter.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/name-empty-device-from-name-wrong-filter.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/name-empty-device-from-service-filter.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/name-empty-device-from-service-filter.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/name-empty-device-from-service-filter.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/name-empty-filter.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/name-empty-filter.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/name-empty-filter.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/name-missing-device-from-name-empty-filter.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/name-missing-device-from-name-empty-filter.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/name-missing-device-from-name-empty-filter.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/name-missing-device-from-name-prefix-filter.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/name-missing-device-from-name-prefix-filter.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/name-missing-device-from-name-prefix-filter.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/name-missing-device-from-name-wrong-filter.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/name-missing-device-from-name-wrong-filter.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/name-missing-device-from-name-wrong-filter.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/name-missing-device-from-service-filter.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/name-missing-device-from-service-filter.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/name-missing-device-from-service-filter.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/no-devices.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/no-devices.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/no-devices.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/not-accept-all-devices-without-filter.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/not-accept-all-devices-without-filter.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/not-accept-all-devices-without-filter.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/same-device.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/same-device.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/same-device.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/single-filter-single-service.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/single-filter-single-service.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/single-filter-single-service.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/single-filter-two-services-fails.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/single-filter-two-services-fails.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/single-filter-two-services-fails.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/single-filter-two-services-succeeds.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/single-filter-two-services-succeeds.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/single-filter-two-services-succeeds.html"
+ }
+ ],
+ "mozilla/bluetooth/requestDevice/two-filters.html": [
+ {
+ "path": "mozilla/bluetooth/requestDevice/two-filters.html",
+ "url": "/_mozilla/mozilla/bluetooth/requestDevice/two-filters.html"
+ }
+ ],
+ "mozilla/bluetooth/writeValue/characteristic/blacklisted-characteristic.html": [
+ {
+ "path": "mozilla/bluetooth/writeValue/characteristic/blacklisted-characteristic.html",
+ "url": "/_mozilla/mozilla/bluetooth/writeValue/characteristic/blacklisted-characteristic.html"
+ }
+ ],
+ "mozilla/bluetooth/writeValue/characteristic/characteristic-is-removed.html": [
+ {
+ "path": "mozilla/bluetooth/writeValue/characteristic/characteristic-is-removed.html",
+ "url": "/_mozilla/mozilla/bluetooth/writeValue/characteristic/characteristic-is-removed.html"
+ }
+ ],
+ "mozilla/bluetooth/writeValue/characteristic/device-goes-out-of-range.html": [
+ {
+ "path": "mozilla/bluetooth/writeValue/characteristic/device-goes-out-of-range.html",
+ "url": "/_mozilla/mozilla/bluetooth/writeValue/characteristic/device-goes-out-of-range.html"
+ }
+ ],
+ "mozilla/bluetooth/writeValue/characteristic/disconnect-called-before.html": [
+ {
+ "path": "mozilla/bluetooth/writeValue/characteristic/disconnect-called-before.html",
+ "url": "/_mozilla/mozilla/bluetooth/writeValue/characteristic/disconnect-called-before.html"
+ }
+ ],
+ "mozilla/bluetooth/writeValue/characteristic/service-is-removed.html": [
+ {
+ "path": "mozilla/bluetooth/writeValue/characteristic/service-is-removed.html",
+ "url": "/_mozilla/mozilla/bluetooth/writeValue/characteristic/service-is-removed.html"
+ }
+ ],
+ "mozilla/bluetooth/writeValue/characteristic/write-succeeds.html": [
+ {
+ "path": "mozilla/bluetooth/writeValue/characteristic/write-succeeds.html",
+ "url": "/_mozilla/mozilla/bluetooth/writeValue/characteristic/write-succeeds.html"
+ }
+ ],
+ "mozilla/bluetooth/writeValue/characteristic/write-updates-value.html": [
+ {
+ "path": "mozilla/bluetooth/writeValue/characteristic/write-updates-value.html",
+ "url": "/_mozilla/mozilla/bluetooth/writeValue/characteristic/write-updates-value.html"
+ }
+ ],
+ "mozilla/bluetooth/writeValue/descriptor/blacklisted-descriptor.html": [
+ {
+ "path": "mozilla/bluetooth/writeValue/descriptor/blacklisted-descriptor.html",
+ "url": "/_mozilla/mozilla/bluetooth/writeValue/descriptor/blacklisted-descriptor.html"
+ }
+ ],
+ "mozilla/bluetooth/writeValue/descriptor/characteristic-is-removed.html": [
+ {
+ "path": "mozilla/bluetooth/writeValue/descriptor/characteristic-is-removed.html",
+ "url": "/_mozilla/mozilla/bluetooth/writeValue/descriptor/characteristic-is-removed.html"
+ }
+ ],
+ "mozilla/bluetooth/writeValue/descriptor/descriptor-is-removed.html": [
+ {
+ "path": "mozilla/bluetooth/writeValue/descriptor/descriptor-is-removed.html",
+ "url": "/_mozilla/mozilla/bluetooth/writeValue/descriptor/descriptor-is-removed.html"
+ }
+ ],
+ "mozilla/bluetooth/writeValue/descriptor/device-goes-out-of-range.html": [
+ {
+ "path": "mozilla/bluetooth/writeValue/descriptor/device-goes-out-of-range.html",
+ "url": "/_mozilla/mozilla/bluetooth/writeValue/descriptor/device-goes-out-of-range.html"
+ }
+ ],
+ "mozilla/bluetooth/writeValue/descriptor/disconnect-called-before.html": [
+ {
+ "path": "mozilla/bluetooth/writeValue/descriptor/disconnect-called-before.html",
+ "url": "/_mozilla/mozilla/bluetooth/writeValue/descriptor/disconnect-called-before.html"
+ }
+ ],
+ "mozilla/bluetooth/writeValue/descriptor/service-is-removed.html": [
+ {
+ "path": "mozilla/bluetooth/writeValue/descriptor/service-is-removed.html",
+ "url": "/_mozilla/mozilla/bluetooth/writeValue/descriptor/service-is-removed.html"
+ }
+ ],
+ "mozilla/bluetooth/writeValue/descriptor/write-succeeds.html": [
+ {
+ "path": "mozilla/bluetooth/writeValue/descriptor/write-succeeds.html",
+ "url": "/_mozilla/mozilla/bluetooth/writeValue/descriptor/write-succeeds.html"
+ }
+ ],
+ "mozilla/bluetooth/writeValue/descriptor/write-updates-value.html": [
+ {
+ "path": "mozilla/bluetooth/writeValue/descriptor/write-updates-value.html",
+ "url": "/_mozilla/mozilla/bluetooth/writeValue/descriptor/write-updates-value.html"
+ }
+ ],
"mozilla/body_listener.html": [
{
"path": "mozilla/body_listener.html",
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/__dir__.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/__dir__.ini
new file mode 100644
index 00000000000..dbe637be21c
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/__dir__.ini
@@ -0,0 +1 @@
+prefs: [dom.bluetooth.testing.enabled:true]
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/connect/device-goes-out-of-range.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/connect/device-goes-out-of-range.html.ini
new file mode 100644
index 00000000000..45a9d5dbde9
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/connect/device-goes-out-of-range.html.ini
@@ -0,0 +1,4 @@
+[device-goes-out-of-range.html]
+ type: testharness
+ [Device goes out of range. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/device-goes-out-of-range.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/device-goes-out-of-range.html.ini
new file mode 100644
index 00000000000..45a9d5dbde9
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/device-goes-out-of-range.html.ini
@@ -0,0 +1,4 @@
+[device-goes-out-of-range.html]
+ type: testharness
+ [Device goes out of range. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/disconnect-called-before.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/disconnect-called-before.html.ini
new file mode 100644
index 00000000000..5530d529555
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/disconnect-called-before.html.ini
@@ -0,0 +1,4 @@
+[disconnect-called-before.html]
+ type: testharness
+ [disconnect() called before getCharacteristic. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/disconnect-called-during.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/disconnect-called-during.html.ini
new file mode 100644
index 00000000000..1a2657fcbbf
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/disconnect-called-during.html.ini
@@ -0,0 +1,4 @@
+[disconnect-called-during.html]
+ type: testharness
+ [disconnect() called during getCharacteristic. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/get-same-characteristic.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/get-same-characteristic.html.ini
new file mode 100644
index 00000000000..f8695a4fbd3
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/get-same-characteristic.html.ini
@@ -0,0 +1,4 @@
+[get-same-characteristic.html]
+ type: testharness
+ [Calls to get the same characteristic should return the same object.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/service-is-removed.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/service-is-removed.html.ini
new file mode 100644
index 00000000000..a53d4c55402
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristic/service-is-removed.html.ini
@@ -0,0 +1,4 @@
+[service-is-removed.html]
+ type: testharness
+ [Service is removed. Reject with InvalidStateError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/blacklisted-characteristics.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/blacklisted-characteristics.html.ini
new file mode 100644
index 00000000000..0361a4f320d
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/blacklisted-characteristics.html.ini
@@ -0,0 +1,4 @@
+[blacklisted-characteristics.html]
+ type: testharness
+ [The Device Information service is composed of blacklisted characteristics so we shouldn't find any.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/device-goes-out-of-range-with-uuid.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/device-goes-out-of-range-with-uuid.html.ini
new file mode 100644
index 00000000000..806be3b9264
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/device-goes-out-of-range-with-uuid.html.ini
@@ -0,0 +1,4 @@
+[device-goes-out-of-range-with-uuid.html]
+ type: testharness
+ [Device goes out of range with UUID. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/device-goes-out-of-range.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/device-goes-out-of-range.html.ini
new file mode 100644
index 00000000000..45a9d5dbde9
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/device-goes-out-of-range.html.ini
@@ -0,0 +1,4 @@
+[device-goes-out-of-range.html]
+ type: testharness
+ [Device goes out of range. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-called-before-with-uuid.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-called-before-with-uuid.html.ini
new file mode 100644
index 00000000000..964190d4d88
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-called-before-with-uuid.html.ini
@@ -0,0 +1,4 @@
+[disconnect-called-before-with-uuid.html]
+ type: testharness
+ [disconnect() called before getCharacteristics. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-called-before.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-called-before.html.ini
new file mode 100644
index 00000000000..5999c62bbda
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-called-before.html.ini
@@ -0,0 +1,4 @@
+[disconnect-called-before.html]
+ type: testharness
+ [disconnect() called before getCharacteristics. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-called-during-with-uuid.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-called-during-with-uuid.html.ini
new file mode 100644
index 00000000000..28fd369e511
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-called-during-with-uuid.html.ini
@@ -0,0 +1,4 @@
+[disconnect-called-during-with-uuid.html]
+ type: testharness
+ [disconnect() called during getCharacteristics. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-called-during.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-called-during.html.ini
new file mode 100644
index 00000000000..69f6ca74231
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/disconnect-called-during.html.ini
@@ -0,0 +1,4 @@
+[disconnect-called-during.html]
+ type: testharness
+ [disconnect() called during getCharacteristics. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/get-same-characteristics.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/get-same-characteristics.html.ini
new file mode 100644
index 00000000000..a18e6fe0a04
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/get-same-characteristics.html.ini
@@ -0,0 +1,4 @@
+[get-same-characteristics.html]
+ type: testharness
+ [Calls to get the same characteristics should return the same objects.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/service-is-removed-with-uuid.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/service-is-removed-with-uuid.html.ini
new file mode 100644
index 00000000000..9224f668cff
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/service-is-removed-with-uuid.html.ini
@@ -0,0 +1,4 @@
+[service-is-removed-with-uuid.html]
+ type: testharness
+ [Service is removed. Reject with InvalidStateError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/service-is-removed.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/service-is-removed.html.ini
new file mode 100644
index 00000000000..a53d4c55402
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getCharacteristics/service-is-removed.html.ini
@@ -0,0 +1,4 @@
+[service-is-removed.html]
+ type: testharness
+ [Service is removed. Reject with InvalidStateError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/characteristic-is-removed.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/characteristic-is-removed.html.ini
new file mode 100644
index 00000000000..0eefaf13656
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/characteristic-is-removed.html.ini
@@ -0,0 +1,4 @@
+[characteristic-is-removed.html]
+ type: testharness
+ [Characteristic is removed. Reject with InvalidStateError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/device-goes-out-of-range.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/device-goes-out-of-range.html.ini
new file mode 100644
index 00000000000..45a9d5dbde9
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/device-goes-out-of-range.html.ini
@@ -0,0 +1,4 @@
+[device-goes-out-of-range.html]
+ type: testharness
+ [Device goes out of range. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/disconnect-called-before.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/disconnect-called-before.html.ini
new file mode 100644
index 00000000000..6754770f361
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/disconnect-called-before.html.ini
@@ -0,0 +1,4 @@
+[disconnect-called-before.html]
+ type: testharness
+ [disconnect() called before getDescriptor. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/disconnect-called-during.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/disconnect-called-during.html.ini
new file mode 100644
index 00000000000..af8f78fb97e
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/disconnect-called-during.html.ini
@@ -0,0 +1,4 @@
+[disconnect-called-during.html]
+ type: testharness
+ [disconnect() called during getDescriptor. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/get-same-descriptor.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/get-same-descriptor.html.ini
new file mode 100644
index 00000000000..135888ec1b1
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptor/get-same-descriptor.html.ini
@@ -0,0 +1,4 @@
+[get-same-descriptor.html]
+ type: testharness
+ [Calls to get the same descriptor should return the same object.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/blacklisted-descriptors.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/blacklisted-descriptors.html.ini
new file mode 100644
index 00000000000..45cb3b6e316
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/blacklisted-descriptors.html.ini
@@ -0,0 +1,4 @@
+[blacklisted-descriptors.html]
+ type: testharness
+ [The descriptors are blacklisted.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/characteristic-is-removed-with-uuid.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/characteristic-is-removed-with-uuid.html.ini
new file mode 100644
index 00000000000..ac0e362efc1
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/characteristic-is-removed-with-uuid.html.ini
@@ -0,0 +1,4 @@
+[characteristic-is-removed-with-uuid.html]
+ type: testharness
+ [Characteristic is removed. Reject with InvalidStateError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/characteristic-is-removed.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/characteristic-is-removed.html.ini
new file mode 100644
index 00000000000..0eefaf13656
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/characteristic-is-removed.html.ini
@@ -0,0 +1,4 @@
+[characteristic-is-removed.html]
+ type: testharness
+ [Characteristic is removed. Reject with InvalidStateError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/device-goes-out-of-range-with-uuid.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/device-goes-out-of-range-with-uuid.html.ini
new file mode 100644
index 00000000000..1008ff322ba
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/device-goes-out-of-range-with-uuid.html.ini
@@ -0,0 +1,4 @@
+[device-goes-out-of-range-with-uuid.html]
+ type: testharness
+ [Device goes out of range. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/device-goes-out-of-range.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/device-goes-out-of-range.html.ini
new file mode 100644
index 00000000000..45a9d5dbde9
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/device-goes-out-of-range.html.ini
@@ -0,0 +1,4 @@
+[device-goes-out-of-range.html]
+ type: testharness
+ [Device goes out of range. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/disconnect-called-before-with-uuid.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/disconnect-called-before-with-uuid.html.ini
new file mode 100644
index 00000000000..2ef92759456
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/disconnect-called-before-with-uuid.html.ini
@@ -0,0 +1,4 @@
+[disconnect-called-before-with-uuid.html]
+ type: testharness
+ [disconnect() called before getDescriptors. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/disconnect-called-before.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/disconnect-called-before.html.ini
new file mode 100644
index 00000000000..85d9bc4fba0
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/disconnect-called-before.html.ini
@@ -0,0 +1,4 @@
+[disconnect-called-before.html]
+ type: testharness
+ [disconnect() called before getDescriptors. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/disconnect-called-during-with-uuid.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/disconnect-called-during-with-uuid.html.ini
new file mode 100644
index 00000000000..da39583d21c
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/disconnect-called-during-with-uuid.html.ini
@@ -0,0 +1,4 @@
+[disconnect-called-during-with-uuid.html]
+ type: testharness
+ [disconnect() called during getDescriptors. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/disconnect-called-during.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/disconnect-called-during.html.ini
new file mode 100644
index 00000000000..bb5eb54229a
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/disconnect-called-during.html.ini
@@ -0,0 +1,4 @@
+[disconnect-called-during.html]
+ type: testharness
+ [disconnect() called during getDescriptors. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/get-same-descriptors.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/get-same-descriptors.html.ini
new file mode 100644
index 00000000000..4b1fcfa08bf
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getDescriptors/get-same-descriptors.html.ini
@@ -0,0 +1,4 @@
+[get-same-descriptors.html]
+ type: testharness
+ [Calls to get the same descriptor should return the same object.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/device-goes-out-of-range.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/device-goes-out-of-range.html.ini
new file mode 100644
index 00000000000..45a9d5dbde9
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/device-goes-out-of-range.html.ini
@@ -0,0 +1,4 @@
+[device-goes-out-of-range.html]
+ type: testharness
+ [Device goes out of range. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/disconnect-called-before.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/disconnect-called-before.html.ini
new file mode 100644
index 00000000000..7bffa89c3f4
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/disconnect-called-before.html.ini
@@ -0,0 +1,4 @@
+[disconnect-called-before.html]
+ type: testharness
+ [disconnect() called before getPrimaryService. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/disconnect-called-during.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/disconnect-called-during.html.ini
new file mode 100644
index 00000000000..b258f7a5893
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/disconnect-called-during.html.ini
@@ -0,0 +1,4 @@
+[disconnect-called-during.html]
+ type: testharness
+ [disconnect() called during getPrimaryService. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/disconnected-device.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/disconnected-device.html.ini
new file mode 100644
index 00000000000..e8641d4018e
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/disconnected-device.html.ini
@@ -0,0 +1,4 @@
+[disconnected-device.html]
+ type: testharness
+ [getPrimaryService called before connecting. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/get-same-service.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/get-same-service.html.ini
new file mode 100644
index 00000000000..d0a29707776
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryService/get-same-service.html.ini
@@ -0,0 +1,4 @@
+[get-same-service.html]
+ type: testharness
+ [Calls to get the same service should return the same object.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/blacklisted-services.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/blacklisted-services.html.ini
new file mode 100644
index 00000000000..4cc7d7067e4
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/blacklisted-services.html.ini
@@ -0,0 +1,4 @@
+[blacklisted-services.html]
+ type: testharness
+ [Request for services. Does not return blacklisted service.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range-with-uuid.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range-with-uuid.html.ini
new file mode 100644
index 00000000000..1008ff322ba
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range-with-uuid.html.ini
@@ -0,0 +1,4 @@
+[device-goes-out-of-range-with-uuid.html]
+ type: testharness
+ [Device goes out of range. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range.html.ini
new file mode 100644
index 00000000000..45a9d5dbde9
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range.html.ini
@@ -0,0 +1,4 @@
+[device-goes-out-of-range.html]
+ type: testharness
+ [Device goes out of range. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnect-called-before-with-uuid.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnect-called-before-with-uuid.html.ini
new file mode 100644
index 00000000000..70c8240fe4e
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnect-called-before-with-uuid.html.ini
@@ -0,0 +1,4 @@
+[disconnect-called-before-with-uuid.html]
+ type: testharness
+ [disconnect() called before getPrimaryServices. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnect-called-before.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnect-called-before.html.ini
new file mode 100644
index 00000000000..fd52ad11a12
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnect-called-before.html.ini
@@ -0,0 +1,4 @@
+[disconnect-called-before.html]
+ type: testharness
+ [disconnect() called before getPrimaryServices. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnect-called-during-with-uuid.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnect-called-during-with-uuid.html.ini
new file mode 100644
index 00000000000..74d4cfd37a7
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnect-called-during-with-uuid.html.ini
@@ -0,0 +1,4 @@
+[disconnect-called-during-with-uuid.html]
+ type: testharness
+ [disconnect() called during getPrimaryServices. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnect-called-during.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnect-called-during.html.ini
new file mode 100644
index 00000000000..9b3e3ba70cd
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnect-called-during.html.ini
@@ -0,0 +1,4 @@
+[disconnect-called-during.html]
+ type: testharness
+ [disconnect() called during getPrimaryServices. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnected-device-with-uuid.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnected-device-with-uuid.html.ini
new file mode 100644
index 00000000000..8ce91b03bea
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnected-device-with-uuid.html.ini
@@ -0,0 +1,4 @@
+[disconnected-device-with-uuid.html]
+ type: testharness
+ [getPrimaryServices called before connecting. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnected-device.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnected-device.html.ini
new file mode 100644
index 00000000000..2916ee4842e
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/disconnected-device.html.ini
@@ -0,0 +1,4 @@
+[disconnected-device.html]
+ type: testharness
+ [getPrimaryServices called before connecting. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/get-same-service.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/get-same-service.html.ini
new file mode 100644
index 00000000000..d0a29707776
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/get-same-service.html.ini
@@ -0,0 +1,4 @@
+[get-same-service.html]
+ type: testharness
+ [Calls to get the same service should return the same object.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/no-permission-present-service.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/no-permission-present-service.html.ini
new file mode 100644
index 00000000000..e7abcfb7c1f
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/getPrimaryServices/no-permission-present-service.html.ini
@@ -0,0 +1,4 @@
+[no-permission-present-service.html]
+ type: testharness
+ [Request for present service without permission. Reject with NotFoundError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/characteristic/characteristic-is-removed.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/characteristic/characteristic-is-removed.html.ini
new file mode 100644
index 00000000000..5d421d6b8c7
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/characteristic/characteristic-is-removed.html.ini
@@ -0,0 +1,4 @@
+[characteristic-is-removed.html]
+ type: testharness
+ [Characteristic gets removed. Reject with InvalidStateError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/characteristic/device-goes-out-of-range.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/characteristic/device-goes-out-of-range.html.ini
new file mode 100644
index 00000000000..45a9d5dbde9
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/characteristic/device-goes-out-of-range.html.ini
@@ -0,0 +1,4 @@
+[device-goes-out-of-range.html]
+ type: testharness
+ [Device goes out of range. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/characteristic/service-is-removed.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/characteristic/service-is-removed.html.ini
new file mode 100644
index 00000000000..d4ab00c8d6f
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/characteristic/service-is-removed.html.ini
@@ -0,0 +1,4 @@
+[service-is-removed.html]
+ type: testharness
+ [Service gets removed. Reject with InvalidStateError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/descriptor/characteristic-is-removed.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/descriptor/characteristic-is-removed.html.ini
new file mode 100644
index 00000000000..5d421d6b8c7
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/descriptor/characteristic-is-removed.html.ini
@@ -0,0 +1,4 @@
+[characteristic-is-removed.html]
+ type: testharness
+ [Characteristic gets removed. Reject with InvalidStateError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/descriptor/descriptor-is-removed.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/descriptor/descriptor-is-removed.html.ini
new file mode 100644
index 00000000000..c59e14a44dc
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/descriptor/descriptor-is-removed.html.ini
@@ -0,0 +1,4 @@
+[descriptor-is-removed.html]
+ type: testharness
+ [Descriptor gets removed. Reject with InvalidStateError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/descriptor/device-goes-out-of-range.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/descriptor/device-goes-out-of-range.html.ini
new file mode 100644
index 00000000000..45a9d5dbde9
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/descriptor/device-goes-out-of-range.html.ini
@@ -0,0 +1,4 @@
+[device-goes-out-of-range.html]
+ type: testharness
+ [Device goes out of range. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/descriptor/service-is-removed.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/descriptor/service-is-removed.html.ini
new file mode 100644
index 00000000000..d4ab00c8d6f
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/readValue/descriptor/service-is-removed.html.ini
@@ -0,0 +1,4 @@
+[service-is-removed.html]
+ type: testharness
+ [Service gets removed. Reject with InvalidStateError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/adapter-not-present.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/adapter-not-present.html.ini
new file mode 100644
index 00000000000..e3387360d4a
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/adapter-not-present.html.ini
@@ -0,0 +1,4 @@
+[adapter-not-present.html]
+ type: testharness
+ [Reject with NotFoundError if the adapter is not present.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/adapter-off.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/adapter-off.html.ini
new file mode 100644
index 00000000000..b1efda59017
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/adapter-off.html.ini
@@ -0,0 +1,4 @@
+[adapter-off.html]
+ type: testharness
+ [Reject with NotFoundError if the adapter is off.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-name.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-name.html.ini
new file mode 100644
index 00000000000..fef1f01d99d
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-name.html.ini
@@ -0,0 +1,4 @@
+[max-length-for-name-in-adv-name.html]
+ type: testharness
+ [A device name longer than 29 must reject.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-namePrefix.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-namePrefix.html.ini
new file mode 100644
index 00000000000..1edd39d02f3
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-namePrefix.html.ini
@@ -0,0 +1,4 @@
+[max-length-for-name-in-adv-namePrefix.html]
+ type: testharness
+ [A device name prefix longer than 29 must reject.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-name.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-name.html.ini
new file mode 100644
index 00000000000..983a50d4896
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-name.html.ini
@@ -0,0 +1,4 @@
+[unicode-max-length-for-name-in-adv-name.html]
+ type: testharness
+ [Unicode string with utf8 representation between (29, 248\] bytes in 'name' must throw NotFoundError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-namePrefix.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-namePrefix.html.ini
new file mode 100644
index 00000000000..b940588a8cd
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-namePrefix.html.ini
@@ -0,0 +1,4 @@
+[unicode-max-length-for-name-in-adv-namePrefix.html]
+ type: testharness
+ [Unicode string with utf8 representation between (29, 248\] bytes in 'namePrefix' must throw NotFoundError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/correct-uuids.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/correct-uuids.html.ini
new file mode 100644
index 00000000000..722de77f833
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/correct-uuids.html.ini
@@ -0,0 +1,4 @@
+[correct-uuids.html]
+ type: testharness
+ [We should only see UUID's that we've been given permission for.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/name-empty-device-from-name-empty-filter.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/name-empty-device-from-name-empty-filter.html.ini
new file mode 100644
index 00000000000..1abfe05362f
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/name-empty-device-from-name-empty-filter.html.ini
@@ -0,0 +1,4 @@
+[name-empty-device-from-name-empty-filter.html]
+ type: testharness
+ [An empty name device can be obtained by empty name filter.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/name-empty-filter.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/name-empty-filter.html.ini
new file mode 100644
index 00000000000..9d60059908f
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/name-empty-filter.html.ini
@@ -0,0 +1,4 @@
+[name-empty-filter.html]
+ type: testharness
+ [A named device is not matched by a filter with an empty name.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/name-missing-device-from-name-empty-filter.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/name-missing-device-from-name-empty-filter.html.ini
new file mode 100644
index 00000000000..7737a256495
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/name-missing-device-from-name-empty-filter.html.ini
@@ -0,0 +1,4 @@
+[name-missing-device-from-name-empty-filter.html]
+ type: testharness
+ [An unnamed device can not be obtained by empty name filter.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/same-device.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/same-device.html.ini
new file mode 100644
index 00000000000..cadf49ab858
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/requestDevice/same-device.html.ini
@@ -0,0 +1,4 @@
+[same-device.html]
+ type: testharness
+ [Returned device should always be the same.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/characteristic/characteristic-is-removed.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/characteristic/characteristic-is-removed.html.ini
new file mode 100644
index 00000000000..5d421d6b8c7
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/characteristic/characteristic-is-removed.html.ini
@@ -0,0 +1,4 @@
+[characteristic-is-removed.html]
+ type: testharness
+ [Characteristic gets removed. Reject with InvalidStateError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/characteristic/device-goes-out-of-range.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/characteristic/device-goes-out-of-range.html.ini
new file mode 100644
index 00000000000..45a9d5dbde9
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/characteristic/device-goes-out-of-range.html.ini
@@ -0,0 +1,4 @@
+[device-goes-out-of-range.html]
+ type: testharness
+ [Device goes out of range. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/characteristic/service-is-removed.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/characteristic/service-is-removed.html.ini
new file mode 100644
index 00000000000..d4ab00c8d6f
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/characteristic/service-is-removed.html.ini
@@ -0,0 +1,4 @@
+[service-is-removed.html]
+ type: testharness
+ [Service gets removed. Reject with InvalidStateError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/characteristic/write-updates-value.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/characteristic/write-updates-value.html.ini
new file mode 100644
index 00000000000..a61aadb0883
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/characteristic/write-updates-value.html.ini
@@ -0,0 +1,4 @@
+[write-updates-value.html]
+ type: testharness
+ [A regular write request to a writable characteristic should update value.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/characteristic-is-removed.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/characteristic-is-removed.html.ini
new file mode 100644
index 00000000000..5d421d6b8c7
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/characteristic-is-removed.html.ini
@@ -0,0 +1,4 @@
+[characteristic-is-removed.html]
+ type: testharness
+ [Characteristic gets removed. Reject with InvalidStateError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/descriptor-is-removed.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/descriptor-is-removed.html.ini
new file mode 100644
index 00000000000..c59e14a44dc
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/descriptor-is-removed.html.ini
@@ -0,0 +1,4 @@
+[descriptor-is-removed.html]
+ type: testharness
+ [Descriptor gets removed. Reject with InvalidStateError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/device-goes-out-of-range.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/device-goes-out-of-range.html.ini
new file mode 100644
index 00000000000..45a9d5dbde9
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/device-goes-out-of-range.html.ini
@@ -0,0 +1,4 @@
+[device-goes-out-of-range.html]
+ type: testharness
+ [Device goes out of range. Reject with NetworkError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/service-is-removed.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/service-is-removed.html.ini
new file mode 100644
index 00000000000..d4ab00c8d6f
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/service-is-removed.html.ini
@@ -0,0 +1,4 @@
+[service-is-removed.html]
+ type: testharness
+ [Service gets removed. Reject with InvalidStateError.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/write-updates-value.html.ini b/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/write-updates-value.html.ini
new file mode 100644
index 00000000000..f96edea6781
--- /dev/null
+++ b/tests/wpt/mozilla/meta/mozilla/bluetooth/writeValue/descriptor/write-updates-value.html.ini
@@ -0,0 +1,4 @@
+[write-updates-value.html]
+ type: testharness
+ [A regular write request to a writable descriptor should update value.]
+ expected: FAIL
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/connect/connection-succeeds.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/connect/connection-succeeds.html
new file mode 100644
index 00000000000..34747ba93a6
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/connect/connection-succeeds.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => assert_true(gattServer.connected));
+}, 'Device will connect');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/connect/device-goes-out-of-range.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/connect/device-goes-out-of-range.html
new file mode 100644
index 00000000000..063bcb6b009
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/connect/device-goes-out-of-range.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(t, 'NetworkError', device.gatt.connect());
+ });
+}, 'Device goes out of range. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/connect/get-same-gatt-server.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/connect/get-same-gatt-server.html
new file mode 100644
index 00000000000..85dab11927f
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/connect/get-same-gatt-server.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => Promise.all([device.gatt.connect(), device.gatt.connect()]))
+ .then(gattServers => assert_equals(gattServers[0], gattServers[1]));
+}, 'Multiple connects should return the same gatt object.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/disconnect/connect-disconnect-twice.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/disconnect/connect-disconnect-twice.html
new file mode 100644
index 00000000000..51cac67b626
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/disconnect/connect-disconnect-twice.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => {
+ return device.gatt.connect()
+ .then(gattServer => {
+ assert_true(gattServer.connected);
+ gattServer.disconnect();
+ assert_false(gattServer.connected);
+ })
+ .then(() => device.gatt.connect()).then(gattServer => {
+ assert_true(gattServer.connected);
+ gattServer.disconnect();
+ assert_false(gattServer.connected);
+ });
+ });
+}, 'Connect + Disconnect twice still results in \'connected\' being false.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/disconnect/disconnect-once.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/disconnect/disconnect-once.html
new file mode 100644
index 00000000000..1e13b354d7b
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/disconnect/disconnect-once.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ assert_true(gattServer.connected);
+ gattServer.disconnect();
+ assert_false(gattServer.connected);
+ });
+}, '\'connected\' is set to false after disconnect is called.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/disconnect/disconnect-twice-in-a-row.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/disconnect/disconnect-twice-in-a-row.html
new file mode 100644
index 00000000000..0fa63704779
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/disconnect/disconnect-twice-in-a-row.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ assert_true(gattServer.connected);
+ gattServer.disconnect();
+ assert_false(gattServer.connected);
+ gattServer.disconnect();
+ assert_false(gattServer.connected);
+ });
+}, 'Calling disconnect twice in a row still results in \'connected\' ' + 'being false.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/blacklisted-characteristic.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/blacklisted-characteristic.html
new file mode 100644
index 00000000000..131c7fa3afd
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/blacklisted-characteristic.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.blacklist);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [device_information.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(device_information.name))
+ .then(service => promise_rejects(t, 'SecurityError', service.getCharacteristic(serial_number_string.name)));
+}, 'Serial Number String characteristic is blacklisted.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/characteristic-found.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/characteristic-found.html
new file mode 100644
index 00000000000..10754eaad3d
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/characteristic-found.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => {
+ return Promise.all([
+ service.getCharacteristic(device_name.alias),
+ service.getCharacteristic(device_name.name),
+ service.getCharacteristic(device_name.uuid)])
+ .then(characteristics => {
+ characteristics.forEach(characteristic => {
+ assert_equals(
+ characteristic.uuid, device_name.uuid,
+ 'Characteristic UUID should be the same as requested UUID.');
+ assert_equals(
+ characteristic.service, service,
+ 'Characteristic service should be the same as service.');
+ });
+ });
+ });
+}, 'Request for characteristic. Should return right characteristic');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/characteristic-not-found.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/characteristic-not-found.html
new file mode 100644
index 00000000000..a7360567a22
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/characteristic-not-found.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => promise_rejects(t, 'NotFoundError', service.getCharacteristic(battery_level.name)));
+}, 'Request for absent characteristic. Reject with NotFoundError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/device-goes-out-of-range.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/device-goes-out-of-range.html
new file mode 100644
index 00000000000..87491e03439
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/device-goes-out-of-range.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(t, 'NetworkError', service.getCharacteristic(device_name.uuid));
+ });
+}, 'Device goes out of range. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/disconnect-called-before.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/disconnect-called-before.html
new file mode 100644
index 00000000000..63f00e2c6c8
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/disconnect-called-before.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ return gattServer.getPrimaryService(generic_access.name)
+ .then(service => {
+ gattServer.disconnect();
+ return promise_rejects(t, 'NetworkError', service.getCharacteristic(device_name.uuid));
+ });
+ });
+}, 'disconnect() called before getCharacteristic. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/disconnect-called-during.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/disconnect-called-during.html
new file mode 100644
index 00000000000..983c191b616
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/disconnect-called-during.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ return gattServer.getPrimaryService(generic_access.name)
+ .then(service => {
+ let promise = promise_rejects(t, 'NetworkError', service.getCharacteristic(device_name.uuid));
+ gattServer.disconnect();
+ return promise;
+ });
+ });
+}, 'disconnect() called during getCharacteristic. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/get-same-characteristic.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/get-same-characteristic.html
new file mode 100644
index 00000000000..f749e8e2ccb
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/get-same-characteristic.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => {
+ return Promise.all([
+ service.getCharacteristic(device_name.name),
+ service.getCharacteristic(device_name.name)])
+ .then(characteristics => {
+ for (let i = 1; i < characteristics.length; i++) {
+ assert_equals(characteristics[0], characteristics[i],
+ 'Should return the same characteristic as the first call.');
+ }
+ });
+ });
+}, 'Calls to get the same characteristic should return the same object.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/invalid-characteristic-name.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/invalid-characteristic-name.html
new file mode 100644
index 00000000000..418603ea43d
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/invalid-characteristic-name.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => promise_rejects(t, 'SyntaxError', service.getCharacteristic(wrong.name)));
+}, 'Wrong Characteristic name. Reject with SyntaxError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/service-is-removed.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/service-is-removed.html
new file mode 100644
index 00000000000..9a10c745ab4
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristic/service-is-removed.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_service_heart_rate);
+ return promise_rejects(t, 'InvalidStateError', service.getCharacteristic(device_name.uuid));
+ });
+}, 'Service is removed. Reject with InvalidStateError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/blacklisted-characteristics-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/blacklisted-characteristics-with-uuid.html
new file mode 100644
index 00000000000..9957fa98b31
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/blacklisted-characteristics-with-uuid.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.blacklist);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [device_information.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(device_information.name))
+ .then(service => promise_rejects(t, 'SecurityError', service.getCharacteristics(serial_number_string.name)));
+}, 'Serial Number String characteristic is blacklisted. Should reject with SecurityError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/blacklisted-characteristics.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/blacklisted-characteristics.html
new file mode 100644
index 00000000000..f4701ac77ca
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/blacklisted-characteristics.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.blacklist);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [device_information.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(device_information.name))
+ .then(service => promise_rejects(t, 'NotFoundError', service.getCharacteristics()));
+}, 'The Device Information service is composed of blacklisted characteristics so we shouldn\'t find any.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/characteristics-found-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/characteristics-found-with-uuid.html
new file mode 100644
index 00000000000..d078623642f
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/characteristics-found-with-uuid.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(heart_rate.name))
+ .then(service => {
+ return Promise.all([
+ service.getCharacteristics(body_sensor_location.alias),
+ service.getCharacteristics(body_sensor_location.name),
+ service.getCharacteristics(body_sensor_location.uuid)])
+ .then(characteristics_arrays => {
+ characteristics_arrays.forEach(characteristics => {
+ assert_equals(characteristics.length, 2);
+ assert_equals(characteristics[0].uuid, body_sensor_location.uuid);
+ assert_equals(characteristics[1].uuid, body_sensor_location.uuid);
+ });
+ });
+ });
+}, 'Find characteristics with UUID in service.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/characteristics-found.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/characteristics-found.html
new file mode 100644
index 00000000000..d50e8e44921
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/characteristics-found.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(heart_rate.name))
+ .then(service => service.getCharacteristics())
+ .then(characteristics => {
+ assert_equals(characteristics.length, 3);
+ assert_equals(characteristics[0].uuid, heart_rate_measurement.uuid);
+ assert_equals(characteristics[1].uuid, body_sensor_location.uuid);
+ assert_equals(characteristics[2].uuid, body_sensor_location.uuid);
+ });
+}, 'Find all characteristics in a service.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/characteristics-not-found-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/characteristics-not-found-with-uuid.html
new file mode 100644
index 00000000000..9c4f0bcd310
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/characteristics-not-found-with-uuid.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(heart_rate.name))
+ .then(service => promise_rejects(t, 'NotFoundError', service.getCharacteristics(battery_level.name)));
+}, 'Request for absent characteristics with UUID. Reject with NotFoundError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/characteristics-not-found.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/characteristics-not-found.html
new file mode 100644
index 00000000000..029d20c48da
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/characteristics-not-found.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_characteristic_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(heart_rate.name))
+ .then(service => promise_rejects(t, 'NotFoundError', service.getCharacteristics()));
+}, 'Request for absent characteristics. Reject with NotFoundError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/correct-characteristics.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/correct-characteristics.html
new file mode 100644
index 00000000000..f3a1f88649f
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/correct-characteristics.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(heart_rate.name))
+ .then(service => service.getCharacteristics(body_sensor_location.name))
+ .then(characteristics => Promise.all([
+ characteristics[0].readValue(),
+ characteristics[1].readValue()]))
+ .then(value_arrays => assert_array_equals(value_arrays, ['1', '2']));
+}, 'Find characteristics with UUID in service.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/device-goes-out-of-range-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/device-goes-out-of-range-with-uuid.html
new file mode 100644
index 00000000000..735e2c63a95
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/device-goes-out-of-range-with-uuid.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(heart_rate.name))
+ .then(service => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(t, 'NetworkError', service.getCharacteristics(heart_rate_measurement.name));
+ });
+}, 'Device goes out of range with UUID. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/device-goes-out-of-range.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/device-goes-out-of-range.html
new file mode 100644
index 00000000000..b852d85f492
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/device-goes-out-of-range.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(heart_rate.name))
+ .then(service => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(t, 'NetworkError', service.getCharacteristics());
+ });
+}, 'Device goes out of range. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-called-before-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-called-before-with-uuid.html
new file mode 100644
index 00000000000..02f3cace850
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-called-before-with-uuid.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ return gattServer.getPrimaryService(heart_rate.name)
+ .then(service => {
+ gattServer.disconnect();
+ return promise_rejects(t, 'NetworkError', service.getCharacteristics(body_sensor_location.alias));
+ });
+ });
+}, 'disconnect() called before getCharacteristics. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-called-before.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-called-before.html
new file mode 100644
index 00000000000..a4462a8a8ae
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-called-before.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ return gattServer.getPrimaryService(heart_rate.name)
+ .then(service => {
+ gattServer.disconnect();
+ return promise_rejects(t, 'NetworkError', service.getCharacteristics());
+ });
+ });
+}, 'disconnect() called before getCharacteristics. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-called-during-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-called-during-with-uuid.html
new file mode 100644
index 00000000000..f54500fa844
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-called-during-with-uuid.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ return gattServer.getPrimaryService(heart_rate.name)
+ .then(service => {
+ let promise = promise_rejects(t, 'NetworkError', service.getCharacteristics(body_sensor_location.alias));
+ gattServer.disconnect();
+ return promise;
+ });
+ });
+}, 'disconnect() called during getCharacteristics. Reject with NetworkError.');
+</script>
+
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-called-during.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-called-during.html
new file mode 100644
index 00000000000..9905336ec64
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/disconnect-called-during.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ return gattServer.getPrimaryService(heart_rate.name)
+ .then(service => {
+ let promise = promise_rejects(t, 'NetworkError', service.getCharacteristics());
+ gattServer.disconnect();
+ return promise;
+ });
+ });
+}, 'disconnect() called during getCharacteristics. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/get-same-characteristics.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/get-same-characteristics.html
new file mode 100644
index 00000000000..4911bce432c
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/get-same-characteristics.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(heart_rate.name))
+ .then(service => Promise.all([
+ service.getCharacteristics(body_sensor_location.name),
+ service.getCharacteristics(body_sensor_location.name)]))
+ .then(characteristics => assert_array_equals(characteristics[0], characteristics[1]));
+}, 'Calls to get the same characteristics should return the same objects.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/invalid-characteristic-name.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/invalid-characteristic-name.html
new file mode 100644
index 00000000000..ea960f6af10
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/invalid-characteristic-name.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => promise_rejects(t, 'SyntaxError', service.getCharacteristics(wrong.name)));
+}, 'Invalid Characteristic name. Reject with SyntaxError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/service-is-removed-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/service-is-removed-with-uuid.html
new file mode 100644
index 00000000000..d6a4e546e7f
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/service-is-removed-with-uuid.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(heart_rate.name))
+ .then(service => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_service_heart_rate);
+ return promise_rejects(t, 'InvalidStateError', service.getCharacteristic(heart_rate_measurement.name));
+ });
+}, 'Service is removed. Reject with InvalidStateError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/service-is-removed.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/service-is-removed.html
new file mode 100644
index 00000000000..1847acf7db4
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getCharacteristics/service-is-removed.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(heart_rate.name))
+ .then(service => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_service_heart_rate);
+ return promise_rejects(t, 'InvalidStateError', service.getCharacteristics());
+ });
+}, 'Service is removed. Reject with InvalidStateError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/blacklisted-descriptor.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/blacklisted-descriptor.html
new file mode 100644
index 00000000000..69487ee04a4
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/blacklisted-descriptor.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.blacklist);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [blacklist_test_service_uuid]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(blacklist_test_service_uuid))
+ .then(service => service.getCharacteristic(blacklist_exclude_reads_characteristic_uuid))
+ .then(characteristic => promise_rejects(t, 'SecurityError',
+ characteristic.getDescriptor(blacklist_descriptor_uuid)));
+}, 'The descriptor is blacklisted.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/characteristic-is-removed.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/characteristic-is-removed.html
new file mode 100644
index 00000000000..7af5169917c
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/characteristic-is-removed.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_characteristic_heart_rate);
+ return promise_rejects(t, 'InvalidStateError', characteristic.getDescriptor(number_of_digitals.name));
+ });
+}, 'Characteristic is removed. Reject with InvalidStateError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/descriptor-found.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/descriptor-found.html
new file mode 100644
index 00000000000..4ae4ec1f93f
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/descriptor-found.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ return Promise.all([
+ characteristic.getDescriptor(number_of_digitals.alias),
+ characteristic.getDescriptor(number_of_digitals.name),
+ characteristic.getDescriptor(number_of_digitals.uuid)])
+ .then(descriptors => {
+ descriptors.forEach(descriptor => {
+ assert_equals(
+ descriptor.uuid, number_of_digitals.uuid,
+ 'Descriptor UUID should be the same as requested UUID.');
+ assert_equals(
+ descriptor.characteristic, characteristic,
+ 'Descriptor characteristic should be the same as characteristic.');
+ });
+ });
+ });
+}, 'Request for descriptor. Should return right descriptor');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/descriptor-not-found.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/descriptor-not-found.html
new file mode 100644
index 00000000000..ac1673956a1
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/descriptor-not-found.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_descriptor_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => promise_rejects(t, 'NotFoundError', characteristic.getDescriptor(number_of_digitals.name)));
+}, 'Request for absent descriptor. Reject with NotFoundError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/device-goes-out-of-range.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/device-goes-out-of-range.html
new file mode 100644
index 00000000000..f766aab8a04
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/device-goes-out-of-range.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(t, 'NetworkError', characteristic.getDescriptor(number_of_digitals.name));
+ });
+}, 'Device goes out of range. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/disconnect-called-before.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/disconnect-called-before.html
new file mode 100644
index 00000000000..da515ef859c
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/disconnect-called-before.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ return gattServer.getPrimaryService(generic_access.name)
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ gattServer.disconnect();
+ return promise_rejects(t, 'NetworkError', characteristic.getDescriptor(number_of_digitals.name));
+ });
+ });
+}, 'disconnect() called before getDescriptor. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/disconnect-called-during.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/disconnect-called-during.html
new file mode 100644
index 00000000000..812d506a9ff
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/disconnect-called-during.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ return gattServer.getPrimaryService(generic_access.name)
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ let promise = promise_rejects(t, 'NetworkError', characteristic.getDescriptor(number_of_digitals.name));
+ gattServer.disconnect();
+ return promise;
+ });
+ });
+}, 'disconnect() called during getDescriptor. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/get-same-descriptor.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/get-same-descriptor.html
new file mode 100644
index 00000000000..9a64c293309
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/get-same-descriptor.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ return Promise.all([
+ characteristic.getDescriptor(number_of_digitals.name),
+ characteristic.getDescriptor(number_of_digitals.name)])
+ .then(descriptors => {
+ for (let i = 1; i < descriptors.length; i++) {
+ assert_equals(descriptors[0], descriptors[i],
+ 'Should return the same descriptor as the first call.');
+ }
+ });
+ });
+}, 'Calls to get the same descriptor should return the same object.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/invalid-descriptor-name.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/invalid-descriptor-name.html
new file mode 100644
index 00000000000..c2b29c3fc99
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptor/invalid-descriptor-name.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => promise_rejects(t, 'SyntaxError', characteristic.getDescriptor(wrong.name)));
+}, 'Wrong descriptor name. Reject with SyntaxError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/blacklisted-descriptors-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/blacklisted-descriptors-with-uuid.html
new file mode 100644
index 00000000000..5798594c9fb
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/blacklisted-descriptors-with-uuid.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.blacklist);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [blacklist_test_service_uuid]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(blacklist_test_service_uuid))
+ .then(service => service.getCharacteristic(blacklist_exclude_reads_characteristic_uuid))
+ .then(characteristic => promise_rejects(t, 'SecurityError',
+ characteristic.getDescriptors(blacklist_descriptor_uuid)));
+}, 'The descriptor is blacklisted. Should reject with SecurityError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/blacklisted-descriptors.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/blacklisted-descriptors.html
new file mode 100644
index 00000000000..7859376a64c
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/blacklisted-descriptors.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.blacklist);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [blacklist_test_service_uuid]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(blacklist_test_service_uuid))
+ .then(service => service.getCharacteristic(blacklist_exclude_reads_characteristic_uuid))
+ .then(characteristic => characteristic.getDescriptors())
+ .then(descriptors => {
+ assert_equals(descriptors.length, 1);
+ assert_equals(descriptors[0].uuid, blacklist_exclude_reads_descriptor_uuid);
+ });
+}, 'The descriptors are blacklisted.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/characteristic-is-removed-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/characteristic-is-removed-with-uuid.html
new file mode 100644
index 00000000000..ca343b558b0
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/characteristic-is-removed-with-uuid.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_characteristic_heart_rate);
+ return promise_rejects(t, 'InvalidStateError', characteristic.getDescriptors(number_of_digitals.name));
+ });
+}, 'Characteristic is removed. Reject with InvalidStateError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/characteristic-is-removed.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/characteristic-is-removed.html
new file mode 100644
index 00000000000..37d549da975
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/characteristic-is-removed.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_characteristic_heart_rate);
+ return promise_rejects(t, 'InvalidStateError', characteristic.getDescriptors());
+ });
+}, 'Characteristic is removed. Reject with InvalidStateError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/correct-descriptors.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/correct-descriptors.html
new file mode 100644
index 00000000000..99742f1c74b
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/correct-descriptors.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [generic_access.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.getDescriptors(number_of_digitals.name))
+ .then(descriptors => Promise.all([
+ descriptors[0].readValue(),
+ descriptors[1].readValue()]))
+ .then(value_arrays => assert_array_equals(value_arrays, ['1', '2']));
+}, 'Find descriptors with UUID in service.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/descriptors-found-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/descriptors-found-with-uuid.html
new file mode 100644
index 00000000000..77066e1af4e
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/descriptors-found-with-uuid.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ return Promise.all([
+ characteristic.getDescriptors(number_of_digitals.alias),
+ characteristic.getDescriptors(number_of_digitals.name),
+ characteristic.getDescriptors(number_of_digitals.uuid)])
+ .then(descriptors_arrays => {
+ descriptors_arrays.forEach(descriptors => {
+ assert_equals(descriptors.length, 2);
+ assert_equals(descriptors[0].uuid, number_of_digitals.uuid);
+ assert_equals(descriptors[1].uuid, number_of_digitals.uuid);
+ });
+ });
+ });
+}, 'Find descriptors with UUID in service.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/descriptors-found.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/descriptors-found.html
new file mode 100644
index 00000000000..537b7da3c20
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/descriptors-found.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.getDescriptors())
+ .then(descriptors => {
+ assert_equals(descriptors.length, 4);
+ assert_equals(descriptors[0].uuid, number_of_digitals.uuid);
+ assert_equals(descriptors[1].uuid, number_of_digitals.uuid);
+ assert_equals(descriptors[2].uuid, characteristic_user_description_uuid);
+ assert_equals(descriptors[3].uuid, client_characteristic_configuration.uuid);
+ });
+}, 'Find descriptors with UUID in service.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/descriptors-not-found-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/descriptors-not-found-with-uuid.html
new file mode 100644
index 00000000000..7a1aff27fd1
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/descriptors-not-found-with-uuid.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_descriptor_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => promise_rejects(t, 'NotFoundError',
+ characteristic.getDescriptors(number_of_digitals.name)));
+}, 'Request for absent descriptors with UUID. Reject with NotFoundError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/descriptors-not-found.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/descriptors-not-found.html
new file mode 100644
index 00000000000..dd1f7937459
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/descriptors-not-found.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_descriptor_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => promise_rejects(t, 'NotFoundError',
+ characteristic.getDescriptors()));
+}, 'Request for absent descriptors with UUID. Reject with NotFoundError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/device-goes-out-of-range-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/device-goes-out-of-range-with-uuid.html
new file mode 100644
index 00000000000..3e4b5cc7a75
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/device-goes-out-of-range-with-uuid.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(t, 'NetworkError', characteristic.getDescriptors(number_of_digitals.name));
+ });
+}, 'Device goes out of range. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/device-goes-out-of-range.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/device-goes-out-of-range.html
new file mode 100644
index 00000000000..4f62af9447c
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/device-goes-out-of-range.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(t, 'NetworkError', characteristic.getDescriptors());
+ });
+}, 'Device goes out of range. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-called-before-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-called-before-with-uuid.html
new file mode 100644
index 00000000000..f3ae8ba674b
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-called-before-with-uuid.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ return gattServer.getPrimaryService(generic_access.name)
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ gattServer.disconnect();
+ return promise_rejects(t, 'NetworkError', characteristic.getDescriptors(number_of_digitals.alias));
+ });
+ });
+}, 'disconnect() called before getDescriptors. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-called-before.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-called-before.html
new file mode 100644
index 00000000000..a18710484cd
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-called-before.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ return gattServer.getPrimaryService(generic_access.name)
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ gattServer.disconnect();
+ return promise_rejects(t, 'NetworkError', characteristic.getDescriptors());
+ });
+ });
+}, 'disconnect() called before getDescriptors. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-called-during-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-called-during-with-uuid.html
new file mode 100644
index 00000000000..7994b46d281
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-called-during-with-uuid.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ return gattServer.getPrimaryService(generic_access.name)
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ let promise = promise_rejects(t, 'NetworkError', characteristic.getDescriptors(number_of_digitals.alias));
+ gattServer.disconnect();
+ return promise;
+ });
+ });
+}, 'disconnect() called during getDescriptors. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-called-during.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-called-during.html
new file mode 100644
index 00000000000..67f8394b9f8
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/disconnect-called-during.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ return gattServer.getPrimaryService(generic_access.name)
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ let promise = promise_rejects(t, 'NetworkError', characteristic.getDescriptors());
+ gattServer.disconnect();
+ return promise;
+ });
+ });
+}, 'disconnect() called during getDescriptors. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/get-same-descriptors.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/get-same-descriptors.html
new file mode 100644
index 00000000000..b0f761c5dff
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/get-same-descriptors.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => Promise.all([
+ characteristic.getDescriptors(number_of_digitals.name),
+ characteristic.getDescriptors(number_of_digitals.name)]))
+ .then(descriptors => assert_array_equals(descriptors[0], descriptors[1]));
+}, 'Calls to get the same descriptor should return the same object.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/invalid-descriptor-name.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/invalid-descriptor-name.html
new file mode 100644
index 00000000000..573bf7627c0
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getDescriptors/invalid-descriptor-name.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => promise_rejects(t, 'SyntaxError', characteristic.getDescriptors(wrong.name)));
+}, 'Wrong descriptor name. Reject with SyntaxError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/device-goes-out-of-range.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/device-goes-out-of-range.html
new file mode 100644
index 00000000000..0de62861621
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/device-goes-out-of-range.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(t, 'NetworkError', gattServer.getPrimaryService(generic_access.name));
+ });
+}, 'Device goes out of range. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/disconnect-called-before.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/disconnect-called-before.html
new file mode 100644
index 00000000000..f13e494febe
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/disconnect-called-before.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ gattServer.disconnect();
+ return promise_rejects(t, 'NetworkError', gattServer.getPrimaryService(heart_rate.name));
+ });
+}, 'disconnect() called before getPrimaryService. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/disconnect-called-during.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/disconnect-called-during.html
new file mode 100644
index 00000000000..35463ca94e3
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/disconnect-called-during.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ let promise = promise_rejects(t, 'NetworkError', gattServer.getPrimaryService(heart_rate.name));
+ gattServer.disconnect();
+ return promise;
+ });
+}, 'disconnect() called during getPrimaryService. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/disconnected-device.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/disconnected-device.html
new file mode 100644
index 00000000000..4de7ea326c2
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/disconnected-device.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => promise_rejects(t, 'NetworkError', device.gatt.getPrimaryService(heart_rate.name)));
+}, 'getPrimaryService called before connecting. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/get-same-service.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/get-same-service.html
new file mode 100644
index 00000000000..752b929a845
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/get-same-service.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => Promise.all([
+ gattServer.getPrimaryService(generic_access.name),
+ gattServer.getPrimaryService(generic_access.name)]))
+ .then(services => {
+ for (let i = 1; i < services.length; i++) {
+ assert_equals(services[0], services[i],
+ 'Should return the same service as the first call.');
+ }
+ });
+}, 'Calls to get the same service should return the same object.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/invalid-service-name.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/invalid-service-name.html
new file mode 100644
index 00000000000..a4406338c39
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/invalid-service-name.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => promise_rejects(t, 'SyntaxError', gattServer.getPrimaryService(wrong.name)));
+}, 'Wrong Service name. Reject with SyntaxError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/no-permission-absent-service.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/no-permission-absent-service.html
new file mode 100644
index 00000000000..bb431828536
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/no-permission-absent-service.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ let expected = 'SecurityError';
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => Promise.all([
+ promise_rejects(t, expected, gattServer.getPrimaryService(glucose.alias)),
+ promise_rejects(t, expected, gattServer.getPrimaryService(glucose.name)),
+ promise_rejects(t, expected, gattServer.getPrimaryService(glucose.uuid))]));
+}, 'Request for absent service without permission. Reject with SecurityError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/no-permission-present-service.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/no-permission-present-service.html
new file mode 100644
index 00000000000..63a22fc519b
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/no-permission-present-service.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ let expected = 'SecurityError';
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => Promise.all([
+ promise_rejects(t, expected, gattServer.getPrimaryService(generic_access.alias)),
+ promise_rejects(t, expected, gattServer.getPrimaryService(generic_access.name)),
+ promise_rejects(t, expected, gattServer.getPrimaryService(generic_access.uuid))]));
+}, 'Request for present service without permission. Reject with SecurityError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/service-found.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/service-found.html
new file mode 100644
index 00000000000..a9656dcbc47
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/service-found.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => {
+ return device.gatt.connect()
+ .then(gattServer => Promise.all([
+ gattServer.getPrimaryService(generic_access.alias),
+ gattServer.getPrimaryService(generic_access.name),
+ gattServer.getPrimaryService(generic_access.uuid)]))
+ .then(services => {
+ services.forEach(service => {
+ assert_equals(service.uuid, generic_access.uuid,
+ 'Service UUID should be the same as requested UUID.');
+ assert_true(service.isPrimary,
+ 'getPrimaryService should return a primary service.');
+ assert_equals(service.device, device,
+ 'Service device should be the same as device.');
+ });
+ });
+ });
+}, 'Request for service. Should return right service');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/service-not-found.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/service-not-found.html
new file mode 100644
index 00000000000..6009f09a5fd
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryService/service-not-found.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [glucose.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => promise_rejects(t, 'NotFoundError', gattServer.getPrimaryService(glucose.name)));
+}, 'Request for absent service. Reject with NotFoundError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/blacklisted-services-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/blacklisted-services-with-uuid.html
new file mode 100644
index 00000000000..988b6dea840
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/blacklisted-services-with-uuid.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.blacklist);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [device_information.name]}],
+ optionalServices: [human_interface_device.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => promise_rejects(t, 'SecurityError', gattServer.getPrimaryServices(human_interface_device.name)));
+}, 'Request for services. Does not return blacklisted service.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/blacklisted-services.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/blacklisted-services.html
new file mode 100644
index 00000000000..f5e0317e7be
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/blacklisted-services.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.blacklist);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [device_information.name]}],
+ optionalServices: [
+ blacklist_test_service_uuid, generic_access.name,
+ heart_rate.name, human_interface_device.name
+ ]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryServices())
+ .then(services => {
+ assert_equals(services.length, 4);
+ assert_equals(services[0].uuid, blacklist_test_service_uuid);
+ assert_equals(services[1].uuid, device_information.uuid);
+ assert_equals(services[2].uuid, generic_access.uuid);
+ assert_equals(services[3].uuid, heart_rate.uuid);
+ });
+}, 'Request for services. Does not return blacklisted service.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/correct-services.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/correct-services.html
new file mode 100644
index 00000000000..3b14e7e257f
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/correct-services.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.two_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryServices(heart_rate.name))
+ .then(services => Promise.all([
+ services[0].getCharacteristics(),
+ services[1].getCharacteristics()]))
+ .then(characteristics_arrays => {
+ assert_equals(characteristics_arrays[0].length, 2);
+ assert_equals(characteristics_arrays[1].length, 1);
+ });
+}, 'Find correct services with UUID.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range-with-uuid.html
new file mode 100644
index 00000000000..cb001e7366d
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range-with-uuid.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(t, 'NetworkError', gattServer.getPrimaryServices(generic_access.name));
+ });
+}, 'Device goes out of range. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range.html
new file mode 100644
index 00000000000..068c38ecdeb
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/device-goes-out-of-range.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(t, 'NetworkError', gattServer.getPrimaryServices());
+ });
+}, 'Device goes out of range. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-called-before-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-called-before-with-uuid.html
new file mode 100644
index 00000000000..05db5f52c54
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-called-before-with-uuid.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.two_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ gattServer.disconnect();
+ return promise_rejects(t, 'NetworkError', gattServer.getPrimaryServices(heart_rate.name));
+ });
+}, 'disconnect() called before getPrimaryServices. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-called-before.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-called-before.html
new file mode 100644
index 00000000000..87d8a362eeb
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-called-before.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.two_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ gattServer.disconnect();
+ return promise_rejects(t, 'NetworkError', gattServer.getPrimaryServices());
+ });
+}, 'disconnect() called before getPrimaryServices. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-called-during-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-called-during-with-uuid.html
new file mode 100644
index 00000000000..9b43949f924
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-called-during-with-uuid.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ let promise = promise_rejects(t, 'NetworkError', gattServer.getPrimaryServices(heart_rate.name));
+ gattServer.disconnect();
+ return promise;
+ });
+}, 'disconnect() called during getPrimaryServices. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-called-during.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-called-during.html
new file mode 100644
index 00000000000..229e4de7f40
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnect-called-during.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ let promise = promise_rejects(t, 'NetworkError', gattServer.getPrimaryServices());
+ gattServer.disconnect();
+ return promise;
+ });
+}, 'disconnect() called during getPrimaryServices. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnected-device-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnected-device-with-uuid.html
new file mode 100644
index 00000000000..54bb8f6ac14
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnected-device-with-uuid.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => promise_rejects(t, 'NetworkError', device.gatt.getPrimaryServices(heart_rate.name)));
+}, 'getPrimaryServices called before connecting. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnected-device.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnected-device.html
new file mode 100644
index 00000000000..37700135f81
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/disconnected-device.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => promise_rejects(t, 'NetworkError', device.gatt.getPrimaryServices()));
+}, 'getPrimaryServices called before connecting. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/get-same-service.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/get-same-service.html
new file mode 100644
index 00000000000..889951315e0
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/get-same-service.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.two_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => Promise.all([
+ gattServer.getPrimaryServices(heart_rate.name),
+ gattServer.getPrimaryServices(heart_rate.name)]))
+ .then(services => assert_array_equals(services[0], services[1]));
+}, 'Calls to get the same service should return the same object.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/invalid-service-name.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/invalid-service-name.html
new file mode 100644
index 00000000000..dfae1d89a2b
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/invalid-service-name.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => promise_rejects(t, 'SyntaxError', gattServer.getPrimaryServices(wrong.name)));
+}, 'Wrong Service name. Reject with SyntaxError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/no-permission-absent-service-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/no-permission-absent-service-with-uuid.html
new file mode 100644
index 00000000000..6f23bb9217b
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/no-permission-absent-service-with-uuid.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ let expected = 'SecurityError';
+ window.testRunner.setBluetoothMockDataSet(adapter_type.glucose_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => Promise.all([
+ promise_rejects(t, expected, gattServer.getPrimaryServices(glucose.alias)),
+ promise_rejects(t, expected, gattServer.getPrimaryServices(glucose.name)),
+ promise_rejects(t, expected, gattServer.getPrimaryServices(glucose.uuid))]));
+}, 'Request for absent service without permission. Reject with SecurityError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/no-permission-present-service-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/no-permission-present-service-with-uuid.html
new file mode 100644
index 00000000000..9ed16d2a3a0
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/no-permission-present-service-with-uuid.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ let expected = 'SecurityError';
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => Promise.all([
+ promise_rejects(t, expected, gattServer.getPrimaryServices(generic_access.alias)),
+ promise_rejects(t, expected, gattServer.getPrimaryServices(generic_access.name)),
+ promise_rejects(t, expected, gattServer.getPrimaryServices(generic_access.uuid))]));
+}, 'Request for present service without permission. Reject with SecurityError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/no-permission-present-service.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/no-permission-present-service.html
new file mode 100644
index 00000000000..d56f7b4e167
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/no-permission-present-service.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{name: mock_device_name.heart_rate}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => promise_rejects(t, 'NotFoundError', gattServer.getPrimaryServices()));
+}, 'Request for present service without permission. Reject with NotFoundError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/services-found-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/services-found-with-uuid.html
new file mode 100644
index 00000000000..7b262688706
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/services-found-with-uuid.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.two_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => Promise.all([
+ gattServer.getPrimaryServices(heart_rate.alias),
+ gattServer.getPrimaryServices(heart_rate.name),
+ gattServer.getPrimaryServices(heart_rate.uuid)]))
+ .then(services_arrays => {
+ services_arrays.forEach(services => {
+ assert_equals(services.length, 2);
+ assert_equals(services[0].uuid, heart_rate.uuid);
+ assert_equals(services[1].uuid, heart_rate.uuid);
+ assert_true(services[0].isPrimary);
+ assert_true(services[1].isPrimary);
+ });
+ });
+}, 'Request for service. Should return right service');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/services-found.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/services-found.html
new file mode 100644
index 00000000000..d5286126f27
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/services-found.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.two_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryServices())
+ .then(services => {
+ assert_equals(services.length, 3);
+ assert_equals(services[0].uuid, generic_access.uuid);
+ assert_equals(services[1].uuid, heart_rate.uuid);
+ assert_equals(services[2].uuid, heart_rate.uuid);
+ assert_true(services[0].isPrimary);
+ assert_true(services[1].isPrimary);
+ assert_true(services[2].isPrimary);
+ });
+}, 'Find all services in a device.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/services-not-found-with-uuid.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/services-not-found-with-uuid.html
new file mode 100644
index 00000000000..42ebb2c48a6
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/services-not-found-with-uuid.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [glucose.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => promise_rejects(t, 'NotFoundError', gattServer.getPrimaryServices(glucose.name)));
+}, 'Request for absent service. Reject with NotFoundError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/services-not-found.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/services-not-found.html
new file mode 100644
index 00000000000..d7be5d8d005
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/getPrimaryServices/services-not-found.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_service_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => promise_rejects(t, 'NotFoundError', gattServer.getPrimaryServices()));
+}, 'Request for absent service. Reject with NotFoundError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/blacklisted-characteristic.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/blacklisted-characteristic.html
new file mode 100644
index 00000000000..fda94bf4f1f
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/blacklisted-characteristic.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.blacklist);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [blacklist_test_service_uuid]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(blacklist_test_service_uuid))
+ .then(service => service.getCharacteristic(blacklist_exclude_reads_characteristic_uuid))
+ .then(characteristic => {
+ return characteristic.writeValue(new Uint8Array(1))
+ .then(() => promise_rejects(t, 'SecurityError', characteristic.readValue()));
+ });
+}, 'Characteristic with exclude-reads fullfills write and rejects read.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/characteristic-is-removed.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/characteristic-is-removed.html
new file mode 100644
index 00000000000..235a1252689
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/characteristic-is-removed.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_characteristic_heart_rate);
+ return promise_rejects(t, 'InvalidStateError', characteristic.readValue());
+ });
+}, 'Characteristic gets removed. Reject with InvalidStateError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/device-goes-out-of-range.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/device-goes-out-of-range.html
new file mode 100644
index 00000000000..c122101ab0f
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/device-goes-out-of-range.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(t, 'NetworkError', characteristic.readValue());
+ });
+}, 'Device goes out of range. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/disconnect-called-before.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/disconnect-called-before.html
new file mode 100644
index 00000000000..b3bfcb71726
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/disconnect-called-before.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ return gattServer.getPrimaryService(generic_access.name)
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ gattServer.disconnect();
+ return promise_rejects(t, 'NetworkError', characteristic.readValue());
+ });
+ });
+}, 'disconnect() called before readValue. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/read-succeeds.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/read-succeeds.html
new file mode 100644
index 00000000000..47c67838856
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/read-succeeds.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.readValue())
+ .then(value => assert_equals(value, mock_device_name.heart_rate));
+}, 'A read request succeeds and returns the characteristic\'s value.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/read-updates-value.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/read-updates-value.html
new file mode 100644
index 00000000000..e9ccdc037a8
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/read-updates-value.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ assert_equals(characteristic.value, null);
+ return characteristic.readValue()
+ .then(() => assert_equals(characteristic.value, mock_device_name.heart_rate));
+ });
+}, 'Succesful read should update characteristic.value');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/service-is-removed.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/service-is-removed.html
new file mode 100644
index 00000000000..de072c5309e
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/characteristic/service-is-removed.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_service_heart_rate);
+ return promise_rejects(t, 'InvalidStateError', characteristic.readValue());
+ });
+}, 'Service gets removed. Reject with InvalidStateError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/blacklisted-descriptor.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/blacklisted-descriptor.html
new file mode 100644
index 00000000000..a64633ed004
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/blacklisted-descriptor.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.blacklist);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [blacklist_test_service_uuid]}]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(blacklist_test_service_uuid))
+ .then(service => service.getCharacteristic(blacklist_exclude_reads_characteristic_uuid))
+ .then(characteristic => characteristic.getDescriptor(blacklist_exclude_reads_descriptor_uuid))
+ .then(descriptor => {
+ return descriptor.writeValue(new Uint8Array(1))
+ .then(() => promise_rejects(t, 'SecurityError', descriptor.readValue()));
+ });
+}, 'Descriptor with exclude-reads fullfills write and rejects read.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/characteristic-is-removed.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/characteristic-is-removed.html
new file mode 100644
index 00000000000..6914f6950de
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/characteristic-is-removed.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.getDescriptor(number_of_digitals.name))
+ .then(descriptor => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_characteristic_heart_rate);
+ return promise_rejects(t, 'InvalidStateError', descriptor.readValue());
+ });
+}, 'Characteristic gets removed. Reject with InvalidStateError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/descriptor-is-removed.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/descriptor-is-removed.html
new file mode 100644
index 00000000000..cbd91f011b5
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/descriptor-is-removed.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.getDescriptor(number_of_digitals.name))
+ .then(descriptor => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_descriptor_heart_rate);
+ return promise_rejects(t, 'InvalidStateError', descriptor.readValue());
+ });
+}, 'Descriptor gets removed. Reject with InvalidStateError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/device-goes-out-of-range.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/device-goes-out-of-range.html
new file mode 100644
index 00000000000..ab300b2249a
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/device-goes-out-of-range.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.getDescriptor(number_of_digitals.name))
+ .then(descriptor => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(t, 'NetworkError', descriptor.readValue());
+ });
+}, 'Device goes out of range. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/disconnect-called-before.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/disconnect-called-before.html
new file mode 100644
index 00000000000..5641a22aa9e
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/disconnect-called-before.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ return gattServer.getPrimaryService(generic_access.name)
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.getDescriptor(number_of_digitals.name))
+ .then(descriptor => {
+ gattServer.disconnect();
+ return promise_rejects(t, 'NetworkError', descriptor.readValue());
+ });
+ });
+}, 'disconnect() called before readValue. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/read-succeeds.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/read-succeeds.html
new file mode 100644
index 00000000000..1b810c67983
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/read-succeeds.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.getDescriptor(number_of_digitals.name))
+ .then(descriptor => descriptor.readValue())
+ .then(value => assert_equals(value, '1'));
+}, 'A read request succeeds and returns the descriptor\'s value.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/read-updates-value.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/read-updates-value.html
new file mode 100644
index 00000000000..376cde92168
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/read-updates-value.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.getDescriptor(number_of_digitals.name))
+ .then(descriptor => {
+ assert_equals(descriptor.value, null);
+ return descriptor.readValue()
+ .then(() => assert_equals(descriptor.value, '1'));
+ });
+}, 'Succesful read should update descriptor.value');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/service-is-removed.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/service-is-removed.html
new file mode 100644
index 00000000000..fb0d1f95ff5
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/readValue/descriptor/service-is-removed.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.getDescriptor(number_of_digitals.name))
+ .then(descriptor => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_service_heart_rate);
+ return promise_rejects(t, 'InvalidStateError', descriptor.readValue());
+ });
+}, 'Service gets removed. Reject with InvalidStateError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/accept-all-devices-with-filter.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/accept-all-devices-with-filter.html
new file mode 100644
index 00000000000..e8eba04ae8f
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/accept-all-devices-with-filter.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.glucose_heart_rate);
+ return promise_rejects(
+ t, new TypeError(),
+ window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ acceptAllDevices: true}));
+}, 'Reject with TypeError if filters present and acceptAllDevices is true.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/accept-all-devices.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/accept-all-devices.html
new file mode 100644
index 00000000000..0c2e16db957
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/accept-all-devices.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.glucose_heart_rate);
+ return window.navigator.bluetooth.requestDevice({acceptAllDevices: true})
+ .then(device => assert_true([mock_device_name.heart_rate, mock_device_name.glucose].includes(device.name)));
+}, 'Requesting all devices without filters must return all the devices.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/adapter-not-present.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/adapter-not-present.html
new file mode 100644
index 00000000000..9f5a419bad5
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/adapter-not-present.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.not_present);
+ return promise_rejects(
+ t, 'NotFoundError', window.navigator.bluetooth.requestDevice({filters: [{services: [generic_access.name]}]}),
+ 'Bluetooth adapter is not present.');
+}, 'Reject with NotFoundError if the adapter is not present.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/adapter-off.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/adapter-off.html
new file mode 100644
index 00000000000..06e7d804856
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/adapter-off.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.not_powered);
+ return promise_rejects(
+ t, 'NotFoundError', window.navigator.bluetooth.requestDevice({filters: [{services: [generic_access.name]}]}),
+ 'Bluetooth adapter is not powered.');
+}, 'Reject with NotFoundError if the adapter is off.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/blacklisted-service-in-filter.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/blacklisted-service-in-filter.html
new file mode 100644
index 00000000000..73ba18855e2
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/blacklisted-service-in-filter.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.blacklist);
+ return promise_rejects(
+ t, 'SecurityError', window.navigator.bluetooth.requestDevice({filters: [{services: [human_interface_device.name]}]}),
+ 'Requesting blacklisted service rejects.');
+}, 'Reject with SecurityError if requesting a blacklisted service.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/blacklisted-service-in-optionalServices.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/blacklisted-service-in-optionalServices.html
new file mode 100644
index 00000000000..a1ef467cd11
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/blacklisted-service-in-optionalServices.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ let expected = 'SecurityError';
+ window.testRunner.setBluetoothMockDataSet(adapter_type.blacklist);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [blacklist_test_service_uuid]}],
+ optionalServices: [human_interface_device.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => Promise.all([
+ promise_rejects(t, expected, gattServer.getPrimaryService(human_interface_device.name)),
+ promise_rejects(t, expected, gattServer.getPrimaryServices(human_interface_device.name))]));
+}, 'Blacklisted UUID in optionalServices is removed and access not granted.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-filter.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-filter.html
new file mode 100644
index 00000000000..e78165b2d75
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-filter.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(t, new TypeError(), window.navigator.bluetooth.requestDevice({filters: [{}]}));
+}, 'A filter must restrict the devices in some way.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-filters-member.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-filters-member.html
new file mode 100644
index 00000000000..4acfedef2bf
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-filters-member.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.glucose_heart_rate);
+ return promise_rejects(t, new TypeError(), window.navigator.bluetooth.requestDevice({filters: []}),
+ 'An empty |filters| member should result in a TypeError');
+}, 'An empty |filters| member should result in a TypeError');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-namePrefix.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-namePrefix.html
new file mode 100644
index 00000000000..b296fe7a29a
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-namePrefix.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+
+let test_specs = [{
+ filters: [{ namePrefix: ''}]
+}, {
+ filters: [{ namePrefix: '', name: 'Name'}]
+}, {
+ filters: [{ namePrefix: '', services: [heart_rate.name]}]
+}, {
+ filters: [{ namePrefix: '', name: 'Name', services: [heart_rate.name]}]
+}, {
+ filters: [{ namePrefix: ''}],
+ optionalServices: [heart_rate.name]
+}, {
+ filters: [{ namePrefix: '', name: 'Name'}],
+ optionalServices: [heart_rate.name]
+}, {
+ filters: [{ namePrefix: '', services: [heart_rate.name]}],
+ optionalServices: [heart_rate.name]
+}, {
+ filters: [{ namePrefix: '', name: 'Name', services: [heart_rate.name]}],
+ optionalServices: [heart_rate.name]
+}];
+
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ let promises = [];
+ test_specs.forEach(args => {
+ promises.push(promise_rejects(t, new TypeError(), window.navigator.bluetooth.requestDevice(args)));
+ });
+ return Promise.all(promises);
+}, 'requestDevice with empty namePrefix. Should reject with TypeError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-services-member.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-services-member.html
new file mode 100644
index 00000000000..9176cc76626
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/empty-services-member.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+
+let test_specs = [{
+ filters: [{ services: [] }]
+}, {
+ filters: [{ services: [], name: 'Name' }]
+}, {
+ filters: [{ services: [], namePrefix: 'Pre' }]
+}, {
+ filters: [{ services: [], name: 'Name', namePrefix: 'Pre' }]
+}, {
+ filters: [{ services: [] }],
+ optionalServices: [heart_rate.name]
+}, {
+ filters: [{ services: [], name: 'Name' }],
+ optionalServices: [heart_rate.name]
+}, {
+ filters: [{ services: [], namePrefix: 'Pre' }],
+ optionalServices: [heart_rate.name]
+}, {
+ filters: [{ services: [], name: 'Name', namePrefix: 'Pre' }],
+ optionalServices: [heart_rate.name]
+}];
+
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ let promises = [];
+ test_specs.forEach(args => {
+ promises.push(promise_rejects(t, new TypeError(), window.navigator.bluetooth.requestDevice(args)));
+ });
+ return Promise.all(promises);
+}, 'Services member must contain at least one service.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-device-name-name.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-device-name-name.html
new file mode 100644
index 00000000000..9b35a48ac92
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-device-name-name.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ let name_too_long = 'a'.repeat(249);
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(
+ t, new TypeError(), window.navigator.bluetooth.requestDevice({filters: [{name: name_too_long}]}),
+ 'Device name longer than 248 bytes');
+}, 'A device name longer than 248 must reject.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-device-name-namePrefix.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-device-name-namePrefix.html
new file mode 100644
index 00000000000..c2321712ced
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-device-name-namePrefix.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ let name_too_long = 'a'.repeat(249);
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(
+ t, new TypeError(), window.navigator.bluetooth.requestDevice({filters: [{namePrefix: name_too_long}]}),
+ 'Device name longer than 248 bytes');
+}, 'A device name prefix longer than 248 must reject.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-name.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-name.html
new file mode 100644
index 00000000000..7ea0dafa53e
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-name.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ let name_too_long = 'a'.repeat(30);
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(
+ t, 'NotFoundError', window.navigator.bluetooth.requestDevice({filters: [{name: name_too_long}]}),
+ 'Device name longer than 29');
+}, 'A device name longer than 29 must reject.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-namePrefix.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-namePrefix.html
new file mode 100644
index 00000000000..7b8d7ced422
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/max-length-for-name-in-adv-namePrefix.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ let name_too_long = 'a'.repeat(30);
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(
+ t, 'NotFoundError', window.navigator.bluetooth.requestDevice({filters: [{namePrefix: name_too_long}]}),
+ 'Device name longer than 29');
+}, 'A device name prefix longer than 29 must reject.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/no-arguments.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/no-arguments.html
new file mode 100644
index 00000000000..3e59141ad09
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/no-arguments.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ try {
+ window.navigator.bluetooth.requestDevice()
+ .then(() => assert_unreached('requestDevice() should have thrown an error'));
+ } catch(error) {
+ assert_equals('TypeError', error.name);
+ }
+}, 'requestDevice() requires an argument.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/no-filters-member.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/no-filters-member.html
new file mode 100644
index 00000000000..0763557d308
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/no-filters-member.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ try {
+ window.navigator.bluetooth.requestDevice([{}, {optionalServices: ['wrong_service']}])
+ .then(() => assert_unreached('requestDevice() should have thrown an error'));
+ } catch(error) {
+ assert_equals('TypeError', error.name);
+ }
+}, 'RequestDeviceOptions requires a |filters| member.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-name.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-name.html
new file mode 100644
index 00000000000..3a5ca1fe042
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-name.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ // \u2764's UTF-8 respresentation is 3 bytes long.
+ // 83 chars * 3 bytes/char = 249 bytes
+ let unicode_name = '\u2764'.repeat(83);
+ window.testRunner.setBluetoothMockDataSet(adapter_type.unicode_device);
+ return promise_rejects(
+ t, new TypeError(), window.navigator.bluetooth.requestDevice({filters: [{name: unicode_name}]}),
+ 'Device name longer than 248 bytes');
+}, 'Unicode string in \'name\' with utf8 representation greater than 248 ' +
+ 'bytes must throw TypeError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-namePrefix.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-namePrefix.html
new file mode 100644
index 00000000000..978d58e8de3
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-device-name-namePrefix.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ // \u2764's UTF-8 respresentation is 3 bytes long.
+ // 83 chars * 3 bytes/char = 249 bytes
+ let unicode_name = '\u2764'.repeat(83);
+ window.testRunner.setBluetoothMockDataSet(adapter_type.unicode_device);
+ return promise_rejects(
+ t, new TypeError(), window.navigator.bluetooth.requestDevice({filters: [{namePrefix: unicode_name}]}),
+ 'Device name longer than 29 bytes');
+}, 'Unicode string in \'namePrefix\' with utf8 representation greater than 248 ' +
+ 'bytes must throw TypeError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-name.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-name.html
new file mode 100644
index 00000000000..f32a26929d6
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-name.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ // \u2764's UTF-8 respresentation is 3 bytes long.
+ // 10 chars * 3 bytes/char = 30 bytes
+ let unicode_name = '\u2764'.repeat(10);
+ window.testRunner.setBluetoothMockDataSet(adapter_type.unicode_device);
+ return promise_rejects(
+ t, 'NotFoundError', window.navigator.bluetooth.requestDevice({filters: [{name: unicode_name}]}),
+ 'Device name longer than 29 bytes');
+}, 'Unicode string with utf8 representation between (29, 248] bytes in ' +
+ '\'name\' must throw NotFoundError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-namePrefix.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-namePrefix.html
new file mode 100644
index 00000000000..46a0c8072ae
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-max-length-for-name-in-adv-namePrefix.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ // \u2764's UTF-8 respresentation is 3 bytes long.
+ // 10 chars * 3 bytes/char = 30 bytes
+ let unicode_name = '\u2764'.repeat(10);
+ window.testRunner.setBluetoothMockDataSet(adapter_type.unicode_device);
+ return promise_rejects(
+ t, 'NotFoundError', window.navigator.bluetooth.requestDevice({filters: [{namePrefix: unicode_name}]}),
+ 'Device name longer than 29 bytes');
+}, 'Unicode string with utf8 representation between (29, 248] bytes in ' +
+ '\'namePrefix\' must throw NotFoundError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-valid-length-name-name.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-valid-length-name-name.html
new file mode 100644
index 00000000000..6bead355297
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-valid-length-name-name.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ // \u2764's UTF-8 representation is 3 bytes long.
+ // 9 chars * 3 bytes/char = 27 bytes
+ let valid_unicode_name = '\u2764'.repeat(9);
+ window.testRunner.setBluetoothMockDataSet(adapter_type.unicode_device);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{name: valid_unicode_name}]
+ })
+ .then(device => assert_equals(device.name, valid_unicode_name));
+}, 'A name containing unicode characters whose utf8 length is less than 30 ' +
+ 'must not throw an error.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-valid-length-name-namePrefix.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-valid-length-name-namePrefix.html
new file mode 100644
index 00000000000..e02e4b3a19c
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/unicode-valid-length-name-namePrefix.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ // \u2764's UTF-8 representation is 3 bytes long.
+ // 9 chars * 3 bytes/char = 27 bytes
+ let valid_unicode_name = '\u2764'.repeat(9);
+ window.testRunner.setBluetoothMockDataSet(adapter_type.unicode_device);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{namePrefix: valid_unicode_name}]
+ })
+ .then(device => assert_equals(device.name, valid_unicode_name));
+}, 'A name containing unicode characters whose utf8 length is less than 30 ' +
+ 'must not throw an error.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/wrong-service-in-optionalServices-member.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/wrong-service-in-optionalServices-member.html
new file mode 100644
index 00000000000..dd6a5d7317e
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/wrong-service-in-optionalServices-member.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+
+let test_specs = [{
+ optionalServices: [wrong.service],
+ filters: [{services: [heart_rate.name]}]
+}, {
+ optionalServices: [wrong.service],
+ filters: [{ services: [heart_rate.name], name: 'Name'}]
+}, {
+ optionalServices: [wrong.service],
+ filters: [{ services: [heart_rate.name], namePrefix: 'Pre'}]
+}, {
+ optionalServices: [wrong.service],
+ filters: [{ services: [heart_rate.name], name: 'Name', namePrefix: 'Pre'}]
+}, {
+ optionalServices: [wrong.service],
+ filters: [{ name: 'Name'}]
+}, {
+ optionalServices: [wrong.service],
+ filters: [{ name: 'Name', namePrefix: 'Pre'}]
+}, {
+ optionalServices: [wrong.service],
+ filters: [{ namePrefix: 'Pre'}]
+}];
+
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ let promises = [];
+ test_specs.forEach(args => {
+ promises.push(promise_rejects(t, 'SyntaxError', window.navigator.bluetooth.requestDevice(args)));
+ });
+ return Promise.all(promises);
+}, 'Invalid optional service must reject the promise.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/wrong-service-in-services-member.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/wrong-service-in-services-member.html
new file mode 100644
index 00000000000..cb84b955fa2
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/canonicalizeFilter/wrong-service-in-services-member.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+
+let test_specs = [{
+ filters: [{services: [heart_rate.name, wrong.service]}]
+}, {
+ filters: [{ services: [heart_rate.name, wrong.service], name: 'Name'}]
+}, {
+ filters: [{ services: [heart_rate.name, wrong.service], namePrefix: 'Pre'}]
+}, {
+ filters: [{ services: [heart_rate.name, wrong.service], name: 'Name', namePrefix: 'Pre'}]
+}, {
+ optionalServices: [heart_rate.name],
+ filters: [{ services: [wrong.service], name: 'Name', namePrefix: 'Pre'}]
+}, {
+ optionalServices: [heart_rate.name],
+ filters: [{ services: [wrong.service], name: 'Name'}]
+}, {
+ optionalServices: [heart_rate.name],
+ filters: [{ services: [wrong.service], name: 'Name', namePrefix: 'Pre'}]
+}, {
+ optionalServices: [heart_rate.name],
+ filters: [{ services: [wrong.service], namePrefix: 'Pre'}]
+}];
+
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ let promises = [];
+ test_specs.forEach(args => {
+ promises.push(promise_rejects(t, 'SyntaxError', window.navigator.bluetooth.requestDevice(args)));
+ });
+ return Promise.all(promises);
+}, 'Invalid optional service must reject the promise.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/correct-uuids.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/correct-uuids.html
new file mode 100644
index 00000000000..86eee7f2307
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/correct-uuids.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.glucose_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [glucose.name]}],
+ optionalServices: [tx_power.name]
+ })
+ .then(device => {
+ assert_equals(device.uuids.length, 2);
+ assert_in_array(glucose.uuid, device.uuids);
+ assert_in_array(tx_power.uuid, device.uuids);
+ });
+}, 'We should only see UUID\'s that we\'ve been given permission for.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/discovery-succeeds.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/discovery-succeeds.html
new file mode 100644
index 00000000000..bb5b669c431
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/discovery-succeeds.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.glucose_heart_rate);
+ return Promise.all([
+ window.navigator.bluetooth.requestDevice({filters: [{services: [heart_rate.alias]}]}),
+ window.navigator.bluetooth.requestDevice({filters: [{services: [heart_rate.name]}]}),
+ window.navigator.bluetooth.requestDevice({filters: [{services: [heart_rate.uuid]}]})])
+ .then(devices => {
+ devices.forEach(device => {
+ assert_true(device instanceof BluetoothDevice);
+ });
+ });
+}, 'Mock will resolve.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/filter-does-not-match.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/filter-does-not-match.html
new file mode 100644
index 00000000000..d9066068a1f
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/filter-does-not-match.html
@@ -0,0 +1,94 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+let matching_services = [heart_rate.uuid];
+let matching_name = mock_device_name.heart_rate;
+let matching_namePrefix = 'Heart';
+
+let non_matching_services = [battery_service.name];
+let non_matching_name = 'Some Device';
+let non_matching_namePrefix = 'Some';
+
+let test_specs = [{
+ filters: [{
+ services: non_matching_services,
+ name: non_matching_name,
+ namePrefix: non_matching_namePrefix
+ }]
+}, {
+ filters: [{
+ services: matching_services,
+ name: non_matching_name,
+ namePrefix: non_matching_namePrefix
+ }]
+}, {
+ filters: [{
+ services: non_matching_services,
+ name: matching_name,
+ namePrefix: non_matching_namePrefix
+ }]
+}, {
+ filters: [{
+ services: matching_services,
+ name: matching_name,
+ namePrefix: non_matching_namePrefix
+ }]
+}, {
+ filters: [{
+ services: non_matching_services,
+ name: non_matching_name,
+ namePrefix: matching_namePrefix
+ }]
+}, {
+ filters: [{
+ services: matching_services,
+ name: non_matching_name,
+ namePrefix: matching_namePrefix
+ }]
+}, {
+ filters: [{
+ services: non_matching_services,
+ name: matching_name,
+ namePrefix: matching_namePrefix
+ }]
+}, {
+ filters: [{
+ services: non_matching_services,
+ }]
+}, {
+ filters: [{
+ services: non_matching_services,
+ name: non_matching_name,
+ }]
+}, {
+ filters: [{
+ services: non_matching_services,
+ namePrefix: non_matching_namePrefix
+ }]
+}, {
+ filters: [{
+ name: non_matching_name,
+ }]
+}, {
+ filters: [{
+ name: non_matching_name,
+ namePrefix: non_matching_namePrefix
+ }]
+}, {
+ filters: [{
+ namePrefix: non_matching_namePrefix
+ }]
+}];
+
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.glucose_heart_rate);
+ let promises = [];
+ test_specs.forEach(args => {
+ promises.push(promise_rejects(t, 'NotFoundError', window.navigator.bluetooth.requestDevice(args)));
+ });
+ return Promise.all(promises);
+}, 'If at least one filter member doesn\'t match the promise must reject.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/filter-matches.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/filter-matches.html
new file mode 100644
index 00000000000..f137d541fdf
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/filter-matches.html
@@ -0,0 +1,64 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+
+let matching_services = [heart_rate.uuid];
+let matching_name = mock_device_name.heart_rate;
+let matching_namePrefix = 'Heart';
+
+let test_specs = [{
+ filters: [{
+ services: matching_services,
+ }]
+}, {
+ filters: [{
+ services: matching_services,
+ name: matching_name,
+ }]
+}, {
+ filters: [{
+ services: matching_services,
+ namePrefix: matching_namePrefix
+ }]
+}, {
+ filters: [{
+ name: matching_name,
+ }],
+ optionalServices: matching_services
+}, {
+ filters: [{
+ name: matching_name,
+ namePrefix: matching_namePrefix
+ }],
+ optionalServices: matching_services
+}, {
+ filters: [{
+ namePrefix: matching_namePrefix
+ }],
+ optionalServices: matching_services
+}, {
+ filters: [{
+ services: matching_services,
+ name: matching_name,
+ namePrefix: matching_namePrefix
+ }]
+}];
+
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.glucose_heart_rate);
+ let promises = [];
+ test_specs.forEach(args => {
+ promises.push(
+ window.navigator.bluetooth.requestDevice(args)
+ .then(device => {
+ assert_equals(device.name, matching_name);
+ assert_true(device.name.startsWith(matching_namePrefix));
+ })
+ );
+ });
+ return Promise.all(promises);
+}, 'Matches a filter if all present members match.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-device-from-name-empty-filter.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-device-from-name-empty-filter.html
new file mode 100644
index 00000000000..5fc093ba4e9
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-device-from-name-empty-filter.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty_name_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{name: ''}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => assert_equals(device.name, ''));
+}, 'An empty name device can be obtained by empty name filter.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-device-from-name-prefix-filter.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-device-from-name-prefix-filter.html
new file mode 100644
index 00000000000..553d5cf8367
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-device-from-name-prefix-filter.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty_name_heart_rate);
+ return promise_rejects(
+ t, 'NotFoundError',
+ window.navigator.bluetooth.requestDevice({
+ filters: [{namePrefix: 'a', services: [heart_rate.name] }]}));
+}, 'An empty name device is not matched by a filter with a namePrefix.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-device-from-name-wrong-filter.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-device-from-name-wrong-filter.html
new file mode 100644
index 00000000000..17454b7a40a
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-device-from-name-wrong-filter.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty_name_heart_rate);
+ return promise_rejects(
+ t, 'NotFoundError',
+ window.navigator.bluetooth.requestDevice({
+ filters: [{name: 'a', services: [heart_rate.name] }]}));
+}, 'An empty name device is not matched by a filter with a name.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-device-from-service-filter.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-device-from-service-filter.html
new file mode 100644
index 00000000000..0c8ad3eff6d
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-device-from-service-filter.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty_name_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => assert_equals(device.name, ''));
+}, 'An empty name device can be obtained by advertised service UUID.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-filter.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-filter.html
new file mode 100644
index 00000000000..85e9c94a59f
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-empty-filter.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return promise_rejects(
+ t, 'NotFoundError',
+ window.navigator.bluetooth.requestDevice({
+ filters: [{name: '', services: [heart_rate.name] }]}));
+}, 'A named device is not matched by a filter with an empty name.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-missing-device-from-name-empty-filter.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-missing-device-from-name-empty-filter.html
new file mode 100644
index 00000000000..8477b5a1da9
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-missing-device-from-name-empty-filter.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.no_name_heart_rate);
+ return promise_rejects(
+ t, 'NotFoundError',
+ window.navigator.bluetooth.requestDevice({
+ filters: [{name: '', services: [heart_rate.name] }]}));
+}, 'An unnamed device can not be obtained by empty name filter.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-missing-device-from-name-prefix-filter.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-missing-device-from-name-prefix-filter.html
new file mode 100644
index 00000000000..e34fa4fa9ff
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-missing-device-from-name-prefix-filter.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.no_name_heart_rate);
+ return promise_rejects(
+ t, 'NotFoundError',
+ window.navigator.bluetooth.requestDevice({
+ filters: [{namePrefix: 'a', services: [heart_rate.name] }]}));
+}, 'An unnamed device can not be obtained by namePrefix filter.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-missing-device-from-name-wrong-filter.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-missing-device-from-name-wrong-filter.html
new file mode 100644
index 00000000000..1686d48f132
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-missing-device-from-name-wrong-filter.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.no_name_heart_rate);
+ return promise_rejects(
+ t, 'NotFoundError',
+ window.navigator.bluetooth.requestDevice({
+ filters: [{name: 'a', services: [heart_rate.name] }]}));
+}, 'An unnamed device can not be obtained by name filter.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-missing-device-from-service-filter.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-missing-device-from-service-filter.html
new file mode 100644
index 00000000000..1073fc5f465
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/name-missing-device-from-service-filter.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.no_name_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}]
+ })
+ .then(device => assert_equals(device.name, null));
+}, 'An unnamed device can be obtained by advertised service UUID.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/no-devices.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/no-devices.html
new file mode 100644
index 00000000000..5ef8848b9b2
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/no-devices.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(
+ t, 'NotFoundError',
+ window.navigator.bluetooth.requestDevice({
+ filters: [{ services: [generic_access.name] }]}));
+}, 'Reject with NotFoundError if there are no devices around.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/not-accept-all-devices-without-filter.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/not-accept-all-devices-without-filter.html
new file mode 100644
index 00000000000..013432047ad
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/not-accept-all-devices-without-filter.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.glucose_heart_rate);
+ return promise_rejects(
+ t, new TypeError(),
+ window.navigator.bluetooth.requestDevice({acceptAllDevices: false}),
+ 'Filters member is empty');
+}, 'Reject with TypeError if `filters` not present and `acceptAllDevices` is false.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/same-device.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/same-device.html
new file mode 100644
index 00000000000..ead68342ee9
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/same-device.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return Promise.all([
+ window.navigator.bluetooth.requestDevice({filters: [{services: [heart_rate.alias]}]}),
+ window.navigator.bluetooth.requestDevice({filters: [{services: [heart_rate.name]}]}),
+ window.navigator.bluetooth.requestDevice({filters: [{services: [heart_rate.uuid]}]})])
+ .then(devices => {
+ assert_equals(devices[0], devices[1]);
+ assert_equals(devices[1], devices[2]);
+ });
+}, 'Returned device should always be the same.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/single-filter-single-service.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/single-filter-single-service.html
new file mode 100644
index 00000000000..10ffd492447
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/single-filter-single-service.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.glucose_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [glucose.name]}]
+ })
+ .then(device => assert_equals(device.name, mock_device_name.glucose));
+}, 'Simple filter selects matching device.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/single-filter-two-services-fails.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/single-filter-two-services-fails.html
new file mode 100644
index 00000000000..5c49545d14f
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/single-filter-two-services-fails.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.glucose_heart_rate);
+ return promise_rejects(
+ t, 'NotFoundError',
+ window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name, battery_service.name]}]}));
+}, 'Too-strict filters do prevent matching.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/single-filter-two-services-succeeds.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/single-filter-two-services-succeeds.html
new file mode 100644
index 00000000000..3da018861c5
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/single-filter-two-services-succeeds.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.glucose_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [glucose.name, tx_power.name]}]
+ })
+ .then(device => assert_equals(device.name, mock_device_name.glucose));
+}, 'Filter with 2 services returns a matching device.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/two-filters.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/two-filters.html
new file mode 100644
index 00000000000..c5dd766f898
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/requestDevice/two-filters.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.glucose_heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [battery_service.name]},
+ {services: [heart_rate.name]}]
+ })
+ .then(glucose_device => assert_equals(glucose_device.name, mock_device_name.heart_rate));
+}, 'An extra filter doesn\'t prevent matching.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/blacklisted-characteristic.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/blacklisted-characteristic.html
new file mode 100644
index 00000000000..cd591ccd056
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/blacklisted-characteristic.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.blacklist);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [blacklist_test_service_uuid]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(peripherial_privacy_flag.name))
+ .then(characteristic => {
+ return characteristic.readValue()
+ .then(() => promise_rejects(t, 'SecurityError', characteristic.writeValue(new Uint8Array(1))));
+ });
+}, 'Characteristic with exclude-writes fullfills read and rejects write.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/characteristic-is-removed.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/characteristic-is-removed.html
new file mode 100644
index 00000000000..35d002c07c1
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/characteristic-is-removed.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_characteristic_heart_rate);
+ return promise_rejects(t, 'InvalidStateError',
+ characteristic.writeValue(new Uint8Array(1)));
+ });
+}, 'Characteristic gets removed. Reject with InvalidStateError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/device-goes-out-of-range.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/device-goes-out-of-range.html
new file mode 100644
index 00000000000..45a3076ae91
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/device-goes-out-of-range.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(t, 'NetworkError', characteristic.writeValue(new Uint8Array(1)));
+ });
+}, 'Device goes out of range. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/disconnect-called-before.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/disconnect-called-before.html
new file mode 100644
index 00000000000..1ebe8ca7696
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/disconnect-called-before.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ return gattServer.getPrimaryService(generic_access.name)
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ gattServer.disconnect();
+ return promise_rejects(t, 'NetworkError', characteristic.writeValue(new Uint8Array(1)));
+ });
+ });
+}, 'disconnect() called before writeValue. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/service-is-removed.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/service-is-removed.html
new file mode 100644
index 00000000000..f51bfe44a4e
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/service-is-removed.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_service_heart_rate);
+ return promise_rejects(t, 'InvalidStateError', characteristic.writeValue(new Uint8Array(1)));
+ });
+}, 'Service gets removed. Reject with InvalidStateError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/write-succeeds.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/write-succeeds.html
new file mode 100644
index 00000000000..0344c2c2d21
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/write-succeeds.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.writeValue(new Uint8Array(1)));
+}, 'A regular write request to a writable characteristic should succeed.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/write-updates-value.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/write-updates-value.html
new file mode 100644
index 00000000000..d49dc2933c3
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/characteristic/write-updates-value.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => {
+ assert_equals(characteristic.value, null);
+ return characteristic.writeValue(asciiToDecimal('foo'))
+ .then(() => assert_equals(characteristic.value, 'foo'));
+ });
+}, 'A regular write request to a writable characteristic should update value.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/blacklisted-descriptor.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/blacklisted-descriptor.html
new file mode 100644
index 00000000000..709053449a9
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/blacklisted-descriptor.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [generic_access.name], }],
+ optionalServices: ['generic_access']
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.getDescriptor(
+ client_characteristic_configuration.name))
+ .then(descriptor => {
+ return descriptor.readValue()
+ .then(() => promise_rejects(t, 'SecurityError', descriptor.writeValue(new Uint8Array(1))));
+ });
+}, 'Descriptor with exclude-writes fullfills read and rejects write.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/characteristic-is-removed.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/characteristic-is-removed.html
new file mode 100644
index 00000000000..0ab4aa51a14
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/characteristic-is-removed.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.getDescriptor(number_of_digitals.name))
+ .then(descriptor => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_characteristic_heart_rate);
+ return promise_rejects(t, 'InvalidStateError', descriptor.writeValue(new Uint8Array(1)));
+ });
+}, 'Characteristic gets removed. Reject with InvalidStateError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/descriptor-is-removed.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/descriptor-is-removed.html
new file mode 100644
index 00000000000..68e48930a72
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/descriptor-is-removed.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.getDescriptor(number_of_digitals.name))
+ .then(descriptor => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_descriptor_heart_rate);
+ return promise_rejects(t, 'InvalidStateError', descriptor.writeValue(new Uint8Array(1)));
+ });
+}, 'Descriptor gets removed. Reject with InvalidStateError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/device-goes-out-of-range.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/device-goes-out-of-range.html
new file mode 100644
index 00000000000..6bae889ac15
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/device-goes-out-of-range.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.getDescriptor(number_of_digitals.name))
+ .then(descriptor => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.empty);
+ return promise_rejects(t, 'NetworkError', descriptor.writeValue(new Uint8Array(1)));
+ });
+}, 'Device goes out of range. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/disconnect-called-before.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/disconnect-called-before.html
new file mode 100644
index 00000000000..939f9e4be36
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/disconnect-called-before.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => {
+ return gattServer.getPrimaryService(generic_access.name)
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.getDescriptor(number_of_digitals.name))
+ .then(descriptor => {
+ gattServer.disconnect();
+ return promise_rejects(t, 'NetworkError', descriptor.writeValue(new Uint8Array(1)));
+ });
+ });
+}, 'disconnect() called before writeValue. Reject with NetworkError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/service-is-removed.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/service-is-removed.html
new file mode 100644
index 00000000000..36d38d44d2c
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/service-is-removed.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.getDescriptor(number_of_digitals.name))
+ .then(descriptor => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.missing_service_heart_rate);
+ return promise_rejects(t, 'InvalidStateError',
+ descriptor.writeValue(new Uint8Array(1)));
+ });
+}, 'Service gets removed. Reject with InvalidStateError.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/write-succeeds.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/write-succeeds.html
new file mode 100644
index 00000000000..9a0c3c66127
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/write-succeeds.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(t => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.getDescriptor(number_of_digitals.name))
+ .then(descriptor => descriptor.writeValue(new Uint8Array(1)));
+}, 'A regular write request to a writable descriptor should succeed.');
+</script>
diff --git a/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/write-updates-value.html b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/write-updates-value.html
new file mode 100644
index 00000000000..9fb5adf749d
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/bluetooth/writeValue/descriptor/write-updates-value.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/bluetooth/bluetooth-helpers.js"></script>
+<script>
+'use strict';
+promise_test(() => {
+ window.testRunner.setBluetoothMockDataSet(adapter_type.heart_rate);
+ return window.navigator.bluetooth.requestDevice({
+ filters: [{services: [heart_rate.name]}],
+ optionalServices: [generic_access.name]
+ })
+ .then(device => device.gatt.connect())
+ .then(gattServer => gattServer.getPrimaryService(generic_access.name))
+ .then(service => service.getCharacteristic(device_name.name))
+ .then(characteristic => characteristic.getDescriptor(number_of_digitals.name))
+ .then(descriptor => {
+ assert_equals(descriptor.value, null);
+ return descriptor.writeValue(asciiToDecimal('foo'))
+ .then(() => assert_equals(descriptor.value, 'foo'));
+ });
+}, 'A regular write request to a writable descriptor should update value.');
+</script>
diff --git a/tests/wpt/web-platform-tests/bluetooth/bluetooth-helpers.js b/tests/wpt/web-platform-tests/bluetooth/bluetooth-helpers.js
new file mode 100644
index 00000000000..14ed7d66d85
--- /dev/null
+++ b/tests/wpt/web-platform-tests/bluetooth/bluetooth-helpers.js
@@ -0,0 +1,147 @@
+'use strict';
+
+// Bluetooth UUID constants:
+// Services:
+var blacklist_test_service_uuid = "611c954a-263b-4f4a-aab6-01ddb953f985";
+var request_disconnection_service_uuid = "01d7d889-7451-419f-aeb8-d65e7b9277af";
+// Characteristics:
+var blacklist_exclude_reads_characteristic_uuid = "bad1c9a2-9a5b-4015-8b60-1579bbbf2135";
+var request_disconnection_characteristic_uuid = "01d7d88a-7451-419f-aeb8-d65e7b9277af";
+// Descriptors:
+var blacklist_exclude_reads_descriptor_uuid = "aaaaaaaa-aaaa-1181-0510-810819516110";
+var blacklist_descriptor_uuid = "07711111-6104-0970-7011-1107105110aaa";
+var characteristic_user_description_uuid = "00002901-0000-1000-8000-00805f9b34fb";
+
+// Bluetooth Adapter types:
+var adapter_type = {
+ not_present: 'NotPresentAdapter',
+ not_powered: 'NotPoweredAdapter',
+ empty: 'EmptyAdapter',
+ heart_rate: 'HeartRateAdapter',
+ two_heart_rate: 'TwoHeartRateServicesAdapter',
+ empty_name_heart_rate: 'EmptyNameHeartRateAdapter',
+ no_name_heart_rate: 'NoNameHeartRateAdapter',
+ glucose_heart_rate: 'GlucoseHeartRateAdapter',
+ unicode_device: 'UnicodeDeviceAdapter',
+ blacklist: 'BlacklistTestAdapter',
+ missing_characteristic_heart_rate: 'MissingCharacteristicHeartRateAdapter',
+ missing_service_heart_rate: 'MissingServiceHeartRateAdapter',
+ missing_descriptor_heart_rate: 'MissingDescriptorHeartRateAdapter'
+};
+
+var mock_device_name = {
+ heart_rate: 'Heart Rate Device',
+ glucose: 'Glucose Device'
+};
+
+var wrong = {
+ name: 'wrong_name',
+ service: 'wrong_service'
+};
+
+// Sometimes we need to test that using either the name, alias, or UUID
+// produces the same result. The following objects help us do that.
+var generic_access = {
+ alias: 0x1800,
+ name: 'generic_access',
+ uuid: '00001800-0000-1000-8000-00805f9b34fb'
+};
+
+var device_name = {
+ alias: 0x2a00,
+ name: 'gap.device_name',
+ uuid: '00002a00-0000-1000-8000-00805f9b34fb'
+};
+
+var reconnection_address = {
+ alias: 0x2a03,
+ name: 'gap.reconnection_address',
+ uuid: '00002a03-0000-1000-8000-00805f9b34fb'
+};
+
+var heart_rate = {
+ alias: 0x180d,
+ name: 'heart_rate',
+ uuid: '0000180d-0000-1000-8000-00805f9b34fb'
+};
+
+var heart_rate_measurement = {
+ alias: 0x2a37,
+ name: 'heart_rate_measurement',
+ uuid: '00002a37-0000-1000-8000-00805f9b34fb'
+};
+
+var body_sensor_location = {
+ alias: 0x2a38,
+ name: 'body_sensor_location',
+ uuid: '00002a38-0000-1000-8000-00805f9b34fb'
+};
+
+var glucose = {
+ alias: 0x1808,
+ name: 'glucose',
+ uuid: '00001808-0000-1000-8000-00805f9b34fb'
+};
+
+var battery_service = {
+ alias: 0x180f,
+ name: 'battery_service',
+ uuid: '0000180f-0000-1000-8000-00805f9b34fb'
+};
+
+var battery_level = {
+ alias: 0x2a19,
+ name: 'battery_level',
+ uuid: '00002a19-0000-1000-8000-00805f9b34fb'
+};
+
+var tx_power = {
+ alias: 0x1804,
+ name: 'tx_power',
+ uuid: '00001804-0000-1000-8000-00805f9b34fb'
+};
+
+var human_interface_device = {
+ alias: 0x1812,
+ name: 'human_interface_device',
+ uuid: '00001812-0000-1000-8000-00805f9b34fb'
+};
+
+var device_information = {
+ alias: 0x180a,
+ name: 'device_information',
+ uuid: '0000180a-0000-1000-8000-00805f9b34fb'
+};
+
+var peripherial_privacy_flag = {
+ alias: 0x2a02,
+ name: 'gap.peripheral_privacy_flag',
+ uuid: '00002a02-0000-1000-8000-00805f9b34fb'
+};
+
+var serial_number_string = {
+ alias: 0x2a25,
+ name: 'serial_number_string',
+ uuid: '00002a25-0000-1000-8000-00805f9b34fb'
+};
+
+var client_characteristic_configuration = {
+ alias: 0x2902,
+ name: 'gatt.client_characteristic_configuration',
+ uuid: '00002902-0000-1000-8000-00805f9b34fb'
+};
+
+var number_of_digitals = {
+ alias: 0x2909,
+ name: 'number_of_digitals',
+ uuid: '00002909-0000-1000-8000-00805f9b34fb'
+};
+
+// Helper function for converting strings to an array of bytes.
+function asciiToDecimal(bytestr) {
+ var result = [];
+ for(var i = 0; i < bytestr.length; i++) {
+ result[i] = bytestr.charCodeAt(i) ;
+ }
+ return result;
+}