mirror of
https://github.com/servo/servo.git
synced 2025-08-26 07:38:21 +01:00
Update web-platform-tests to revision 10168e9a5d44efbc6e7d416d1d454eb9c9f1396c
This commit is contained in:
parent
c88dc51d03
commit
0e1caebaf4
791 changed files with 23381 additions and 5501 deletions
|
@ -43,14 +43,29 @@ function makeVideo() {
|
|||
});
|
||||
}
|
||||
|
||||
function makeImage() {
|
||||
return new Promise(resolve => {
|
||||
var img = new Image();
|
||||
img.onload = function() {
|
||||
resolve(img);
|
||||
};
|
||||
img.src = "/images/pattern.png";
|
||||
});
|
||||
function makeMakeHTMLImage(src) {
|
||||
return function() {
|
||||
return new Promise(resolve => {
|
||||
var img = new Image();
|
||||
img.onload = function() {
|
||||
resolve(img);
|
||||
};
|
||||
img.src = src;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function makeMakeSVGImage(src) {
|
||||
return function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
var image = document.createElementNS(NAMESPACES.svg, "image");
|
||||
image.onload = () => resolve(image);
|
||||
image.onerror = reject;
|
||||
image.setAttribute("externalResourcesRequired", "true");
|
||||
image.setAttributeNS(NAMESPACES.xlink, 'xlink:href', src);
|
||||
document.body.appendChild(image);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function makeImageData() {
|
||||
|
@ -100,7 +115,10 @@ function makeBlob() {
|
|||
var imageSourceTypes = [
|
||||
{ name: 'an HTMLCanvasElement', factory: makeCanvas },
|
||||
{ name: 'an HTMLVideoElement', factory: makeVideo },
|
||||
{ name: 'an HTMLImageElement', factory: makeImage },
|
||||
{ name: 'a bitmap HTMLImageElement', factory: makeMakeHTMLImage("/images/pattern.png") },
|
||||
{ name: 'a vector HTMLImageElement', factory: makeMakeHTMLImage("/images/pattern.svg") },
|
||||
{ name: 'a bitmap SVGImageElement', factory: makeMakeSVGImage("/images/pattern.png") },
|
||||
{ name: 'a vector SVGImageElement', factory: makeMakeSVGImage("/images/pattern.svg") },
|
||||
{ name: 'an OffscreenCanvas', factory: makeOffscreenCanvas },
|
||||
{ name: 'an ImageData', factory: makeImageData },
|
||||
{ name: 'an ImageBitmap', factory: makeImageBitmap },
|
|
@ -5,7 +5,8 @@
|
|||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/common/canvas-tests.js"></script>
|
||||
<script src="/common/media.js"></script>
|
||||
<script src="common.js"></script>
|
||||
<script src="/common/namespaces.js"></script>
|
||||
<script src="common.sub.js"></script>
|
||||
<link rel="stylesheet" href="/common/canvas-tests.css">
|
||||
<body>
|
||||
<script>
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/common/media.js"></script>
|
||||
<script src="common.js"></script>
|
||||
<script src="/common/namespaces.js"></script>
|
||||
<script src="common.sub.js"></script>
|
||||
<script>
|
||||
|
||||
function makeOversizedCanvas() {
|
||||
|
@ -29,17 +30,18 @@ function makeInvalidBlob() {
|
|||
}
|
||||
|
||||
function makeBrokenImage() {
|
||||
return new Promise(resolve => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const image = new Image();
|
||||
image.src = "data:,x";
|
||||
image.onload = reject;
|
||||
image.onerror = () => resolve(image);
|
||||
});
|
||||
}
|
||||
|
||||
function makeAvailableButBrokenImage() {
|
||||
function makeAvailableButBrokenImage(path) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const image = new Image();
|
||||
image.src = "/images/broken.png";
|
||||
image.src = path;
|
||||
image.onload = () => resolve(image);
|
||||
image.onerror = reject;
|
||||
});
|
||||
|
@ -99,6 +101,26 @@ promise_test( t => {
|
|||
return promise_rejects(t, new TypeError(), createImageBitmap(null));
|
||||
}, "createImageBitmap with null image source.");
|
||||
|
||||
promise_test( t => {
|
||||
var context = document.createElement("canvas").getContext("2d");
|
||||
return promise_rejects(t, new TypeError(), createImageBitmap(context));
|
||||
}, "createImageBitmap with CanvasRenderingContext2D image source.");
|
||||
|
||||
promise_test( t => {
|
||||
var context = document.createElement("canvas").getContext("webgl");
|
||||
return promise_rejects(t, new TypeError(), createImageBitmap(context));
|
||||
}, "createImageBitmap with WebGLRenderingContext image source.");
|
||||
|
||||
promise_test( t => {
|
||||
var buffer = new Uint8Array();
|
||||
return promise_rejects(t, new TypeError(), createImageBitmap(buffer));
|
||||
}, "createImageBitmap with Uint8Array image source.");
|
||||
|
||||
promise_test( t => {
|
||||
var buffer = new ArrayBuffer(8);
|
||||
return promise_rejects(t, new TypeError(), createImageBitmap(buffer));
|
||||
}, "createImageBitmap with ArrayBuffer image source.");
|
||||
|
||||
promise_test( t => {
|
||||
return promise_rejects(t, "InvalidStateError",
|
||||
createImageBitmap(new Image()));
|
||||
|
@ -138,12 +160,26 @@ promise_test( t => {
|
|||
}, "createImageBitmap with a broken image source.");
|
||||
|
||||
promise_test( t => {
|
||||
return makeAvailableButBrokenImage().then(image => {
|
||||
return makeAvailableButBrokenImage("/images/broken.png").then(image => {
|
||||
return promise_rejects(t, "InvalidStateError",
|
||||
createImageBitmap(image));
|
||||
});
|
||||
}, "createImageBitmap with an available but undecodable image source.");
|
||||
|
||||
promise_test( t => {
|
||||
return makeAvailableButBrokenImage("/images/red-zeroheight.svg").then(image => {
|
||||
return promise_rejects(t, "InvalidStateError",
|
||||
createImageBitmap(image));
|
||||
});
|
||||
}, "createImageBitmap with an available but zero height image source.");
|
||||
|
||||
promise_test( t => {
|
||||
return makeAvailableButBrokenImage("/images/red-zerowidth.svg").then(image => {
|
||||
return promise_rejects(t, "InvalidStateError",
|
||||
createImageBitmap(image));
|
||||
});
|
||||
}, "createImageBitmap with an available but zero width image source.");
|
||||
|
||||
promise_test( t => {
|
||||
return makeImageBitmap().then(bitmap => {
|
||||
bitmap.close()
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>createImageBitmap: origin-clean flag</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/common/media.js"></script>
|
||||
<script src="/common/namespaces.js"></script>
|
||||
<div id=log></div>
|
||||
<script>
|
||||
const crossOriginImageUrl = "http://{{domains[www1]}}:{{ports[http][0]}}/images/red.png";
|
||||
|
||||
function assert_origin_unclean(bitmap) {
|
||||
const context = document.createElement("canvas").getContext("2d");
|
||||
context.drawImage(bitmap, 0, 0);
|
||||
assert_throws("SecurityError", () => {
|
||||
context.getImageData(0, 0, 1, 1);
|
||||
});
|
||||
}
|
||||
|
||||
function makeImage() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const image = new Image();
|
||||
image.onload = () => resolve(image);
|
||||
image.onerror = reject;
|
||||
image.src = crossOriginImageUrl;
|
||||
});
|
||||
}
|
||||
|
||||
const arguments = [
|
||||
{
|
||||
name: "cross-origin HTMLImageElement",
|
||||
factory: makeImage,
|
||||
},
|
||||
|
||||
{
|
||||
name: "cross-origin SVGImageElement",
|
||||
factory: () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const image = document.createElementNS(NAMESPACES.svg, "image");
|
||||
image.onload = () => resolve(image);
|
||||
image.onerror = reject;
|
||||
image.setAttribute("externalResourcesRequired", "true");
|
||||
image.setAttributeNS(NAMESPACES.xlink, 'xlink:href', crossOriginImageUrl);
|
||||
document.body.appendChild(image);
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "cross-origin HTMLVideoElement",
|
||||
factory: () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const video = document.createElement("video");
|
||||
video.oncanplaythrough = () => resolve(video);
|
||||
video.onerror = reject;
|
||||
video.src = getVideoURI("http://{{domains[www1]}}:{{ports[http][0]}}/media/movie_300");
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "unclean HTMLCanvasElement",
|
||||
factory: () => {
|
||||
return makeImage().then(image => {
|
||||
const canvas = document.createElement("canvas");
|
||||
const context = canvas.getContext("2d");
|
||||
context.drawImage(image, 0, 0);
|
||||
return canvas;
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "unclean ImageBitmap",
|
||||
factory: () => {
|
||||
return makeImage().then(createImageBitmap);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
for (let { name, factory } of arguments) {
|
||||
promise_test(function() {
|
||||
return factory().then(createImageBitmap).then(assert_origin_unclean);
|
||||
}, name);
|
||||
}
|
||||
</script>
|
27
tests/wpt/web-platform-tests/acid/acid3/numbered-tests.html
Normal file
27
tests/wpt/web-platform-tests/acid/acid3/numbered-tests.html
Normal file
|
@ -0,0 +1,27 @@
|
|||
<!doctype html>
|
||||
<title>Acid3 numbered tests</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
var tests = undefined;
|
||||
|
||||
function gotMessage(e) {
|
||||
var m = e.data;
|
||||
if (tests === undefined && "num_tests" in m) {
|
||||
tests = [];
|
||||
for (var i = 0; i < m.num_tests; i++) {
|
||||
tests.push(async_test("Test " + i));
|
||||
}
|
||||
} else if ("result" in m) {
|
||||
var test = m.test;
|
||||
var passed = m.result === "pass";
|
||||
var message = m.message;
|
||||
tests[test].step(function() {
|
||||
assert_true(passed, message);
|
||||
});
|
||||
tests[test].done();
|
||||
}
|
||||
}
|
||||
window.addEventListener("message", gotMessage, false);
|
||||
</script>
|
||||
<iframe src="test.html"></iframe>
|
|
@ -3419,6 +3419,7 @@
|
|||
}
|
||||
|
||||
];
|
||||
window.parent.postMessage({num_tests: tests.length}, "*");
|
||||
var log = '';
|
||||
var delay = 10;
|
||||
var score = 0, index = 0, retry = 0, errors = 0;
|
||||
|
@ -3456,6 +3457,7 @@
|
|||
} else {
|
||||
fail("no error message");
|
||||
}
|
||||
window.parent.postMessage({test: index, result: "pass"}, "*");
|
||||
} catch (e) {
|
||||
var s;
|
||||
if (e.message)
|
||||
|
@ -3464,6 +3466,7 @@
|
|||
s = e;
|
||||
errors += 1;
|
||||
log += "Test " + zeroPaddedIndex + " failed: " + s + "\n";
|
||||
window.parent.postMessage({test: index, result: "fail", message: s}, "*");
|
||||
};
|
||||
retry = 0;
|
||||
index += 1;
|
||||
|
|
|
@ -24,16 +24,25 @@ test(function() {
|
|||
}, "Verify calling 'navigator.sendBeacon()' with a URL that is not a http(s) scheme throws an exception.");
|
||||
|
||||
// We'll validate that we can send one beacon that uses our entire Quota and then fail to send one that is just one char.
|
||||
test(function () {
|
||||
var destinationURL = "/fetch/api/resources/trickle.py?count=1&ms=1000";
|
||||
|
||||
var firstSuccess = navigator.sendBeacon(destinationURL, maxPayload);
|
||||
assert_true(firstSuccess, "calling 'navigator.sendBeacon()' with our max payload size should succeed.");
|
||||
promise_test(async () => {
|
||||
function wait(ms) {
|
||||
return new Promise(res => step_timeout(res, ms));
|
||||
}
|
||||
const url = '/fetch/api/resources/trickle.py?count=1&ms=0';
|
||||
assert_true(navigator.sendBeacon(url, maxPayload),
|
||||
"calling 'navigator.sendBeacon()' with our max payload size should succeed.");
|
||||
|
||||
// Now we'll send just one character.
|
||||
var secondSuccess = navigator.sendBeacon(destinationURL, "1");
|
||||
assert_false(secondSuccess, "calling 'navigator.sendBeacon()' with just one char should fail while our Quota is used up.");
|
||||
assert_false(navigator.sendBeacon(url, '1'),
|
||||
"calling 'navigator.sendBeacon()' with just one char should fail while our Quota is used up.");
|
||||
|
||||
}, "Verify calling 'navigator.sendBeacon()' with a small payload fails while Quota is completely utilized.");
|
||||
for (let i = 0; i < 20; ++i) {
|
||||
await wait(100);
|
||||
if (navigator.sendBeacon(url, maxPayload)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert_unreached('The quota should recover after fetching.');
|
||||
}, "Verify the behavior after the quota is exhausted.");
|
||||
|
||||
done();
|
||||
|
|
|
@ -9,6 +9,19 @@ the API to be loaded as needed.
|
|||
The Chromium implementation is provided by
|
||||
`../resources/chromium/web-bluetooth-test.js`.
|
||||
|
||||
The Chromium implementation is not included in stable Chrome builds since it
|
||||
would add too much to the binary size. On Chromium infrastructure, it is run
|
||||
using the `content_shell` executable.
|
||||
|
||||
In the future, Chromium `src/device/bluetooth` may be refactored into a Mojo
|
||||
service. At this point, it would be possible to add the necessary testing hooks
|
||||
into stable Chrome without substantially increasing the binary size, similar to
|
||||
WebUSB.
|
||||
|
||||
These bluetooth tests are upstreamed here because other browsers can reuse them
|
||||
by implementing the [Web Bluetooth Testing API], even if only on their internal
|
||||
infrastructure.
|
||||
|
||||
[Web Bluetooth Testing API]: https://docs.google.com/document/d/1Nhv_oVDCodd1pEH_jj9k8gF4rPGb_84VYaZ9IG8M_WY/
|
||||
|
||||
# Generated gen-* files from generator.py
|
||||
|
@ -45,4 +58,4 @@ Usage:
|
|||
$ python generate.py
|
||||
```
|
||||
|
||||
More details documented in `generate.py`.
|
||||
More details documented in `generate.py`.
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Reject with SecurityError if requesting a blocklisted ' +
|
||||
'service.';
|
||||
const expected = new DOMException(
|
||||
'requestDevice() called with a filter containing a blocklisted UUID. ' +
|
||||
'https://goo.gl/4NeimX',
|
||||
'SecurityError');
|
||||
|
||||
bluetooth_test(() => setUpPreconnectedDevice({
|
||||
knownServiceUUIDs: ['human_interface_device']
|
||||
})
|
||||
.then(() => assert_promise_rejects_with_message(
|
||||
requestDeviceWithTrustedClick({
|
||||
filters: [{services: ['human_interface_device']}]
|
||||
}),
|
||||
expected, 'Requesting blocklisted service rejects.')),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Blocklisted UUID in optionalServices is removed and ' +
|
||||
'access not granted.';
|
||||
const expected = new DOMException('Origin is not allowed to access the ' +
|
||||
'service. Tip: Add the service UUID to \'optionalServices\' in ' +
|
||||
'requestDevice() options. https://goo.gl/HxfxSQ',
|
||||
'SecurityError');
|
||||
let device, fake_peripheral;
|
||||
|
||||
bluetooth_test(() => getDiscoveredHealthThermometerDevice({
|
||||
filters: [{services: ['health_thermometer']}],
|
||||
optionalServices: ['human_interface_device']
|
||||
})
|
||||
.then(_ => ({device, fake_peripheral} = _))
|
||||
.then(() =>
|
||||
fake_peripheral.setNextGATTConnectionResponse({code: HCI_SUCCESS}))
|
||||
.then(() => device.gatt.connect())
|
||||
.then(() =>
|
||||
fake_peripheral.setNextGATTDiscoveryResponse({code: HCI_SUCCESS}))
|
||||
.then(() => Promise.all([
|
||||
assert_promise_rejects_with_message(
|
||||
device.gatt.getPrimaryService('human_interface_device'),
|
||||
expected, 'Blocklisted service not accessible.'),
|
||||
assert_promise_rejects_with_message(
|
||||
device.gatt.getPrimaryServices('human_interface_device'),
|
||||
expected, 'Blocklisted services not accessible.')])),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'A device name between 29 and 248 bytes is valid.';
|
||||
const DEVICE_NAME = 'a_device_name_that_is_longer_than_29_bytes_but_' +
|
||||
'shorter_than_248_bytes';
|
||||
|
||||
bluetooth_test(() => setUpPreconnectedDevice({name: DEVICE_NAME})
|
||||
.then(() => requestDeviceWithTrustedClick({
|
||||
filters: [{name: DEVICE_NAME}]
|
||||
}))
|
||||
.then(device => assert_equals(device.name, DEVICE_NAME)),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'A filter must restrict the devices in some way.';
|
||||
const expected = new TypeError();
|
||||
|
||||
bluetooth_test(() => assert_promise_rejects_with_message(
|
||||
requestDeviceWithTrustedClick({filters: [{}]}),
|
||||
expected),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'An empty |filters| member should result in a TypeError';
|
||||
const expected = new DOMException('Failed to execute \'requestDevice\' on ' +
|
||||
'\'Bluetooth\': \'filters\' member must be non-empty to find any devices.',
|
||||
new TypeError());
|
||||
|
||||
bluetooth_test(() => assert_promise_rejects_with_message(
|
||||
requestDeviceWithTrustedClick({filters: []}),
|
||||
expected),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'requestDevice with empty namePrefix. ' +
|
||||
'Should reject with TypeError.';
|
||||
const expected = new TypeError();
|
||||
const test_specs = [{
|
||||
filters: [{ namePrefix: ''}]
|
||||
}, {
|
||||
filters: [{ namePrefix: '', name: 'Name'}]
|
||||
}, {
|
||||
filters: [{ namePrefix: '', services: ['heart_rate']}]
|
||||
}, {
|
||||
filters: [{ namePrefix: '', name: 'Name', services: ['heart_rate']}]
|
||||
}, {
|
||||
filters: [{ namePrefix: ''}],
|
||||
optionalServices: ['heart_rate']
|
||||
}, {
|
||||
filters: [{ namePrefix: '', name: 'Name'}],
|
||||
optionalServices: ['heart_rate']
|
||||
}, {
|
||||
filters: [{ namePrefix: '', services: ['heart_rate']}],
|
||||
optionalServices: ['heart_rate']
|
||||
}, {
|
||||
filters: [{ namePrefix: '', name: 'Name', services: ['heart_rate']}],
|
||||
optionalServices: ['heart_rate']
|
||||
}];
|
||||
|
||||
bluetooth_test(() => {
|
||||
let test_promises = Promise.resolve();
|
||||
test_specs.forEach(args => {
|
||||
test_promises = test_promises
|
||||
.then(() => assert_promise_rejects_with_message(
|
||||
requestDeviceWithTrustedClick(args),
|
||||
expected));
|
||||
});
|
||||
return test_promises;
|
||||
}, test_desc);
|
||||
</script>
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Services member must contain at least one service.';
|
||||
const expected = new TypeError();
|
||||
|
||||
bluetooth_test(() => {
|
||||
let test_promises = Promise.resolve();
|
||||
generateRequestDeviceArgsWithServices([]).forEach(args => {
|
||||
test_promises = test_promises.then(() =>
|
||||
assert_promise_rejects_with_message(
|
||||
requestDeviceWithTrustedClick(args),
|
||||
expected,
|
||||
'Services member must contain at least one service'))
|
||||
});
|
||||
return test_promises;
|
||||
}, test_desc);
|
||||
</script>
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = "RequestDeviceOptions should have exactly one of " +
|
||||
"'filters' or 'acceptAllDevices:true'. Reject with TypeError if not.";
|
||||
const expected = new DOMException(
|
||||
"Failed to execute 'requestDevice' on 'Bluetooth': " +
|
||||
"Either 'filters' should be present or " +
|
||||
"'acceptAllDevices' should be true, but not both.",
|
||||
new TypeError());
|
||||
const test_specs = [
|
||||
{},
|
||||
{optionalServices: ['heart_rate']},
|
||||
{filters: [], acceptAllDevices: true},
|
||||
{filters: [], acceptAllDevices: true, optionalServices: ['heart_rate']}
|
||||
];
|
||||
|
||||
bluetooth_test(() => {
|
||||
let test_promises = Promise.resolve();
|
||||
test_specs.forEach(args => {
|
||||
test_promises = test_promises
|
||||
.then(() => assert_promise_rejects_with_message(
|
||||
requestDeviceWithTrustedClick(args),
|
||||
expected))
|
||||
});
|
||||
return test_promises;
|
||||
}, test_desc);
|
||||
</script>
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Unicode string with utf8 representation longer than 248 ' +
|
||||
'bytes in \'name\' must throw TypeError.';
|
||||
const expected = new DOMException(
|
||||
"Failed to execute 'requestDevice' on 'Bluetooth': " +
|
||||
"A device name can't be longer than 248 bytes.",
|
||||
new TypeError());
|
||||
// \u2764's UTF-8 respresentation is 3 bytes long.
|
||||
// 83 chars * 3 bytes/char = 249 bytes
|
||||
const unicode_name = '\u2764'.repeat(83);
|
||||
|
||||
bluetooth_test(() => assert_promise_rejects_with_message(
|
||||
requestDeviceWithTrustedClick({filters: [{name: unicode_name}]}),
|
||||
expected),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'A device name longer than 248 must reject.';
|
||||
const expected = new DOMException(
|
||||
"Failed to execute 'requestDevice' on 'Bluetooth': A device " +
|
||||
"name can't be longer than 248 bytes.",
|
||||
new TypeError());
|
||||
const name_too_long = 'a'.repeat(249);
|
||||
|
||||
bluetooth_test(() => assert_promise_rejects_with_message(
|
||||
requestDeviceWithTrustedClick({filters: [{name: name_too_long}]}),
|
||||
expected,
|
||||
'Device name longer than 248'),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Unicode string with utf8 representation longer than 248 ' +
|
||||
'bytes in \'namePrefix\' must throw NotFoundError.';
|
||||
const expected = new DOMException(
|
||||
"Failed to execute 'requestDevice' on 'Bluetooth': " +
|
||||
"A device name can't be longer than 248 bytes.",
|
||||
new TypeError());
|
||||
// \u2764's UTF-8 respresentation is 3 bytes long.
|
||||
// 83 chars * 3 bytes/char = 249 bytes
|
||||
const unicode_name = '\u2764'.repeat(83);
|
||||
|
||||
bluetooth_test(() => assert_promise_rejects_with_message(
|
||||
requestDeviceWithTrustedClick({filters: [{namePrefix: unicode_name}]}),
|
||||
expected),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'A device name prefix longer than 248 must reject.';
|
||||
const expected = new DOMException(
|
||||
"Failed to execute 'requestDevice' on 'Bluetooth': A device " +
|
||||
"name can't be longer than 248 bytes.",
|
||||
new TypeError());
|
||||
const name_too_long = 'a'.repeat(249);
|
||||
|
||||
bluetooth_test(() => assert_promise_rejects_with_message(
|
||||
requestDeviceWithTrustedClick({filters: [{namePrefix: name_too_long}]}),
|
||||
expected,
|
||||
'Device name longer than 248'),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'A unicode device name of 248 bytes is valid.';
|
||||
// \u00A1's UTF-8 respresentation is 2 bytes long.
|
||||
// 124 chars * 2 bytes/char = 248 bytes
|
||||
const DEVICE_NAME = '\u00A1'.repeat(124);
|
||||
|
||||
bluetooth_test(() => setUpPreconnectedDevice({name: DEVICE_NAME})
|
||||
.then(() => requestDeviceWithTrustedClick({ filters: [{name: DEVICE_NAME}]}))
|
||||
.then(device => assert_equals(device.name, DEVICE_NAME)),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'A device name of 248 bytes is valid.';
|
||||
const DEVICE_NAME = 'a'.repeat(248);
|
||||
|
||||
bluetooth_test(() => setUpPreconnectedDevice({name: DEVICE_NAME})
|
||||
.then(() => requestDeviceWithTrustedClick({ filters: [{name: DEVICE_NAME}]}))
|
||||
.then(device => assert_equals(device.name, DEVICE_NAME)),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'A unicode device namePrefix of 248 bytes is valid.';
|
||||
// \u00A1's UTF-8 respresentation is 2 bytes long.
|
||||
// 124 chars * 2 bytes/char = 248 bytes
|
||||
const DEVICE_NAME = '\u00A1'.repeat(124);
|
||||
|
||||
bluetooth_test(() => setUpPreconnectedDevice({name: DEVICE_NAME})
|
||||
.then(() => requestDeviceWithTrustedClick({
|
||||
filters: [{namePrefix: DEVICE_NAME}]
|
||||
}))
|
||||
.then(device => assert_equals(device.name, DEVICE_NAME)),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'A device namePrefix of 248 bytes is valid.';
|
||||
const DEVICE_NAME = 'a'.repeat(248);
|
||||
|
||||
bluetooth_test(() => setUpPreconnectedDevice({name: DEVICE_NAME})
|
||||
.then(() => requestDeviceWithTrustedClick({
|
||||
filters: [{namePrefix: DEVICE_NAME}]
|
||||
}))
|
||||
.then(device => assert_equals(device.name, DEVICE_NAME)),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharness-helpers.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'requestDevice() requires an argument.';
|
||||
const expected = new TypeError();
|
||||
|
||||
promise_test(() => assert_promise_rejects_with_message(
|
||||
requestDeviceWithTrustedClick(),
|
||||
expected),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'A name containing unicode characters whose utf8 length ' +
|
||||
'is less than 30 must not throw an error.';
|
||||
// \u2764's UTF-8 representation is 3 bytes long.
|
||||
// 9 chars * 3 bytes/char = 27 bytes
|
||||
const valid_unicode_name = '\u2764'.repeat(9);
|
||||
|
||||
bluetooth_test(() => setUpPreconnectedDevice({name: valid_unicode_name})
|
||||
.then(() => requestDeviceWithTrustedClick({
|
||||
filters: [{name: valid_unicode_name}]
|
||||
}))
|
||||
.then(device => assert_equals(device.name, valid_unicode_name)),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'A namePrefix containing unicode characters whose utf8 ' +
|
||||
'length is less than 30 must not throw an error.';
|
||||
// \u2764's UTF-8 representation is 3 bytes long.
|
||||
// 9 chars * 3 bytes/char = 27 bytes
|
||||
const valid_unicode_name = '\u2764'.repeat(9);
|
||||
|
||||
bluetooth_test(() => setUpPreconnectedDevice({name: valid_unicode_name})
|
||||
.then(() => requestDeviceWithTrustedClick({
|
||||
filters: [{namePrefix: valid_unicode_name}]
|
||||
}))
|
||||
.then(device => assert_equals(device.name, valid_unicode_name)),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Invalid optional service must reject the promise.';
|
||||
const expected = new TypeError();
|
||||
const test_specs = [{
|
||||
optionalServices: ['wrong_service'],
|
||||
filters: [{services: ['heart_rate']}]
|
||||
}, {
|
||||
optionalServices: ['wrong_service'],
|
||||
filters: [{ services: ['heart_rate'], name: 'Name'}]
|
||||
}, {
|
||||
optionalServices: ['wrong_service'],
|
||||
filters: [{ services: ['heart_rate'], namePrefix: 'Pre'}]
|
||||
}, {
|
||||
optionalServices: ['wrong_service'],
|
||||
filters: [{ services: ['heart_rate'], name: 'Name', namePrefix: 'Pre'}]
|
||||
}, {
|
||||
optionalServices: ['wrong_service'],
|
||||
filters: [{ name: 'Name'}]
|
||||
}, {
|
||||
optionalServices: ['wrong_service'],
|
||||
filters: [{ name: 'Name', namePrefix: 'Pre'}]
|
||||
}, {
|
||||
optionalServices: ['wrong_service'],
|
||||
filters: [{ namePrefix: 'Pre'}]
|
||||
}];
|
||||
|
||||
bluetooth_test(() => {
|
||||
let test_promises = Promise.resolve();
|
||||
test_specs.forEach(args => {
|
||||
test_promises =
|
||||
test_promises.then(() => assert_promise_rejects_with_message(
|
||||
requestDeviceWithTrustedClick(args),
|
||||
expected));
|
||||
});
|
||||
return test_promises;
|
||||
}, test_desc);
|
||||
</script>
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Invalid service must reject the promise.';
|
||||
const expected = new TypeError();
|
||||
|
||||
bluetooth_test(() => {
|
||||
let test_promises = Promise.resolve();
|
||||
generateRequestDeviceArgsWithServices(['wrong_service']).forEach(args => {
|
||||
test_promises = test_promises.then(() =>
|
||||
assert_promise_rejects_with_message(
|
||||
requestDeviceWithTrustedClick(args),
|
||||
expected));
|
||||
});
|
||||
return test_promises;
|
||||
}, test_desc);
|
||||
</script>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Consumes a user gesture.';
|
||||
const expected = new DOMException(
|
||||
'Must be handling a user gesture to show a permission request.',
|
||||
'SecurityError');
|
||||
|
||||
bluetooth_test(() => setUpHealthThermometerAndHeartRateDevices()
|
||||
.then(() => callWithTrustedClick(() => {
|
||||
let first = navigator.bluetooth.requestDevice({
|
||||
filters: [{services: ['heart_rate']}]});
|
||||
let second = navigator.bluetooth.requestDevice({
|
||||
filters: [{services: ['heart_rate']}]});
|
||||
return Promise.all([
|
||||
first.then(device => assert_equals(
|
||||
device.constructor.name, 'BluetoothDevice')),
|
||||
assert_promise_rejects_with_message(second,
|
||||
expected, 'A request should consume a user gesture')
|
||||
]);
|
||||
})), test_desc);
|
||||
</script>
|
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Discover a device using alias, name, or UUID.';
|
||||
|
||||
bluetooth_test(() => getHealthThermometerDevice()
|
||||
// Chrome will always close the previous chooser in the process of handling
|
||||
// a user gesture for the next request, so these need to be done
|
||||
// sequentially.
|
||||
.then(() => requestDeviceWithTrustedClick({
|
||||
filters: [{services: [health_thermometer.alias]}]
|
||||
}))
|
||||
.then(device => assert_equals(device.constructor.name, 'BluetoothDevice'))
|
||||
.then(() => requestDeviceWithTrustedClick({
|
||||
filters: [{services: [health_thermometer.name]}]
|
||||
}))
|
||||
.then(device => assert_equals(device.constructor.name, 'BluetoothDevice'))
|
||||
.then(() => requestDeviceWithTrustedClick({
|
||||
filters: [{services: [health_thermometer.uuid]}]
|
||||
}))
|
||||
.then(device => assert_equals(device.constructor.name, 'BluetoothDevice')),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,67 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Matches a filter if all present members match.';
|
||||
let matching_services = [health_thermometer.uuid];
|
||||
let matching_name = 'Health Thermometer';
|
||||
let matching_namePrefix = 'Health';
|
||||
|
||||
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
|
||||
}]
|
||||
}];
|
||||
|
||||
bluetooth_test(() => setUpHealthThermometerDevice()
|
||||
.then(() => {
|
||||
let test_promises = Promise.resolve();
|
||||
test_specs.forEach(args => {
|
||||
test_promises = test_promises
|
||||
.then(() => requestDeviceWithTrustedClick(args))
|
||||
.then(device => {
|
||||
// We always have access to the services in matching_services
|
||||
// because we include them in a filter or in optionalServices.
|
||||
assert_equals(device.name, matching_name);
|
||||
assert_true(device.name.startsWith(matching_namePrefix));
|
||||
});
|
||||
});
|
||||
return test_promises;
|
||||
}), test_desc);
|
||||
</script>
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Reject with NotFoundError if Bluetooth is not supported.';
|
||||
const expected = new DOMException('Bluetooth Low Energy not available.',
|
||||
'NotFoundError');
|
||||
|
||||
bluetooth_test(() => navigator.bluetooth.test.setLESupported(false)
|
||||
.then(() => assert_promise_rejects_with_message(
|
||||
requestDeviceWithTrustedClick({acceptAllDevices: true}),
|
||||
expected, 'Bluetooth Low Energy is not supported.')),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'An empty name device can be obtained by empty name filter.'
|
||||
|
||||
bluetooth_test(() => setUpPreconnectedDevice({name: ''})
|
||||
.then(() => requestDeviceWithTrustedClick({filters: [{name: ''}]}))
|
||||
.then(device => assert_equals(device.name, '')),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Requires a user gesture.';
|
||||
const expected = new DOMException(
|
||||
'Must be handling a user gesture to show a permission request.',
|
||||
'SecurityError');
|
||||
|
||||
bluetooth_test(() => setUpHealthThermometerAndHeartRateDevices()
|
||||
.then(() => assert_promise_rejects_with_message(
|
||||
navigator.bluetooth.requestDevice({filters:[{services:['heart_rate']}]}),
|
||||
expected, 'User gesture is required')),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Reject with NotFoundError if there is no BT radio present.';
|
||||
const expected = new DOMException('Bluetooth adapter not available.',
|
||||
'NotFoundError');
|
||||
|
||||
bluetooth_test(() => navigator.bluetooth.test.simulateCentral({state: 'absent'})
|
||||
.then(() => assert_promise_rejects_with_message(
|
||||
requestDeviceWithTrustedClick({
|
||||
filters: [{services: ['generic_access']}]
|
||||
}),
|
||||
expected, 'Bluetooth adapter is not present.')),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Concurrent requestDevice calls in iframes work.';
|
||||
const iframes = [];
|
||||
for (let i = 0; i < 5; i++) {
|
||||
iframes.push(document.createElement('iframe'));
|
||||
}
|
||||
|
||||
bluetooth_test(() => setUpHealthThermometerAndHeartRateDevices()
|
||||
// 1. Load the iframes.
|
||||
.then(() => {
|
||||
let promises = [];
|
||||
for (let iframe of iframes) {
|
||||
iframe.src = '/bluetooth/resources/health-thermometer-iframe.html';
|
||||
document.body.appendChild(iframe);
|
||||
promises.push(new Promise(resolve =>
|
||||
iframe.addEventListener('load', resolve)));
|
||||
}
|
||||
return Promise.all(promises);
|
||||
})
|
||||
// 2. Request the device from the iframes.
|
||||
.then(() => new Promise(async (resolve) => {
|
||||
let numMessages = 0;
|
||||
window.onmessage = messageEvent => {
|
||||
assert_equals(messageEvent.data, 'Success');
|
||||
if (++numMessages === iframes.length) {
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
|
||||
for (let iframe of iframes) {
|
||||
await callWithTrustedClick(() => iframe.contentWindow.postMessage({
|
||||
type: 'RequestDevice'
|
||||
}, '*'));
|
||||
}
|
||||
})), test_desc);
|
||||
</script>
|
|
@ -0,0 +1,39 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Request device from a unique origin. ' +
|
||||
'Should reject with SecurityError.';
|
||||
const expected = 'SecurityError: requestDevice() called from cross-origin ' +
|
||||
'iframe.';
|
||||
|
||||
let iframe = document.createElement('iframe');
|
||||
|
||||
bluetooth_test(() => getHealthThermometerDevice()
|
||||
// 1. Load the iframe.
|
||||
.then(() => new Promise(resolve => {
|
||||
iframe.sandbox.add('allow-scripts');
|
||||
iframe.src = '/bluetooth/resources/health-thermometer-iframe.html';
|
||||
document.body.appendChild(iframe);
|
||||
iframe.addEventListener('load', resolve);
|
||||
}))
|
||||
// 2. Request the device from the iframe.
|
||||
.then(() => new Promise(resolve => {
|
||||
callWithTrustedClick(() => {
|
||||
iframe.contentWindow.postMessage({
|
||||
type: 'RequestDevice'
|
||||
}, '*');
|
||||
});
|
||||
|
||||
window.onmessage = messageEvent => {
|
||||
assert_equals(messageEvent.data, expected);
|
||||
resolve();
|
||||
}
|
||||
})), test_desc);
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Returned device should always be the same.';
|
||||
let devices = [];
|
||||
let push = device => devices.push(device);
|
||||
|
||||
bluetooth_test(() => setUpHealthThermometerAndHeartRateDevices()
|
||||
.then(() => requestDeviceWithTrustedClick({
|
||||
filters: [{services: [heart_rate.alias]}]
|
||||
}))
|
||||
.then(push)
|
||||
.then(() => requestDeviceWithTrustedClick({
|
||||
filters: [{services: [heart_rate.name]}]
|
||||
}))
|
||||
.then(push)
|
||||
.then(() => requestDeviceWithTrustedClick({
|
||||
filters: [{services: [heart_rate.uuid]}]
|
||||
}))
|
||||
.then(push)
|
||||
.then(() => {
|
||||
assert_equals(devices[0], devices[1]);
|
||||
assert_equals(devices[1], devices[2]);
|
||||
}), test_desc);
|
||||
</script>
|
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Simple filter selects matching device.';
|
||||
|
||||
bluetooth_test(() => setUpHealthThermometerAndHeartRateDevices()
|
||||
.then(() => requestDeviceWithTrustedClick({
|
||||
filters: [{services: ['health_thermometer']}]
|
||||
}))
|
||||
.then(device => assert_equals(device.name, 'Health Thermometer')),
|
||||
test_desc);
|
||||
</script>
|
|
@ -218,22 +218,36 @@ var gatt_errors_tests = [{
|
|||
'NotSupportedError')
|
||||
}];
|
||||
|
||||
function callWithTrustedClick(callback) {
|
||||
// Waits until the document has finished loading.
|
||||
function waitForDocumentReady() {
|
||||
return new Promise(resolve => {
|
||||
let button = document.createElement('button');
|
||||
button.textContent = 'click to continue test';
|
||||
button.style.display = 'block';
|
||||
button.style.fontSize = '20px';
|
||||
button.style.padding = '10px';
|
||||
button.onclick = () => {
|
||||
document.body.removeChild(button);
|
||||
resolve(callback());
|
||||
};
|
||||
document.body.appendChild(button);
|
||||
test_driver.click(button);
|
||||
if (document.readyState === 'complete') {
|
||||
resolve();
|
||||
}
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
resolve();
|
||||
}, {once: true});
|
||||
});
|
||||
}
|
||||
|
||||
function callWithTrustedClick(callback) {
|
||||
return waitForDocumentReady()
|
||||
.then(() => new Promise(resolve => {
|
||||
let button = document.createElement('button');
|
||||
button.textContent = 'click to continue test';
|
||||
button.style.display = 'block';
|
||||
button.style.fontSize = '20px';
|
||||
button.style.padding = '10px';
|
||||
button.onclick = () => {
|
||||
document.body.removeChild(button);
|
||||
resolve(callback());
|
||||
};
|
||||
document.body.appendChild(button);
|
||||
test_driver.click(button);
|
||||
}));
|
||||
}
|
||||
|
||||
// Calls requestDevice() in a context that's 'allowed to show a popup'.
|
||||
function requestDeviceWithTrustedClick() {
|
||||
let args = arguments;
|
||||
|
|
|
@ -1,17 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<script>
|
||||
let device;
|
||||
let device, gatt;
|
||||
|
||||
function requestDeviceWithOptionsAndConnect(options) {
|
||||
return navigator.bluetooth.requestDevice(options)
|
||||
.then(device => device.gatt.connect());
|
||||
}
|
||||
|
||||
window.onmessage = messageEvent => {
|
||||
window.addEventListener('message', (messageEvent) => {
|
||||
switch (messageEvent.data.type) {
|
||||
case 'RequestDevice':
|
||||
navigator.bluetooth.requestDevice({
|
||||
filters: [{services: ['generic_access']}]
|
||||
})
|
||||
.then(device => {
|
||||
if (device.constructor.name === 'BluetoothDevice') {
|
||||
parent.postMessage('Success', '*');
|
||||
} else {
|
||||
parent.postMessage(
|
||||
`FAIL: requestDevice in iframe returned ${device.name}`, '*');
|
||||
}}).catch(err => parent.postMessage(`${err.name}: ${err.message}`,
|
||||
'*'));
|
||||
break;
|
||||
case 'RequestAndConnect':
|
||||
requestDeviceWithOptionsAndConnect(messageEvent.data.options)
|
||||
.then(gatt => {
|
||||
.then(_ => {
|
||||
gatt = _;
|
||||
device = gatt.device;
|
||||
parent.postMessage('Connected', '*');
|
||||
}).catch(err => {
|
||||
|
@ -26,9 +40,18 @@ window.onmessage = messageEvent => {
|
|||
parent.postMessage(`FAIL: ${err}`, '*');
|
||||
});
|
||||
break;
|
||||
case 'GetService':
|
||||
if (typeof gatt === 'undefined') {
|
||||
parent.postMessage('FAIL: no GATT server', '*');
|
||||
break;
|
||||
}
|
||||
gatt.getPrimaryService(messageEvent.data.options)
|
||||
.then(() => parent.postMessage('ServiceReceived', '*'))
|
||||
.catch(err => parent.postMessage(`FAIL: ${err}`, '*'));
|
||||
break;
|
||||
default:
|
||||
parent.postMessage(`FAIL: Bad message type: ${messageEvent.data.type}`,
|
||||
'*');
|
||||
'*');
|
||||
}
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
'use strict';
|
||||
const test_desc = 'Serial Number String characteristic is blocklisted. ' +
|
||||
'Should reject with SecurityError.';
|
||||
const expected = new DOMException(
|
||||
'getCharacteristic(s) called with blocklisted UUID. https://goo.gl/4NeimX',
|
||||
'SecurityError');
|
||||
|
||||
bluetooth_test(() => getHIDDevice({
|
||||
filters: [{services: ['device_information']}]
|
||||
})
|
||||
.then(({device}) => device.gatt.getPrimaryService('device_information'))
|
||||
.then(service => assert_promise_rejects_with_message(
|
||||
service.CALLS([
|
||||
getCharacteristic('serial_number_string')|
|
||||
getCharacteristics('serial_number_string')[UUID]
|
||||
]),
|
||||
expected,
|
||||
'Serial Number String characteristic is blocklisted.')),
|
||||
test_desc);
|
|
@ -0,0 +1,15 @@
|
|||
'use strict';
|
||||
const test_desc = 'Request for absent characteristics with UUID. ' +
|
||||
'Reject with NotFoundError.';
|
||||
|
||||
bluetooth_test(() => getEmptyHealthThermometerService()
|
||||
.then(({service}) => assert_promise_rejects_with_message(
|
||||
service.CALLS([
|
||||
getCharacteristic('battery_level')|
|
||||
getCharacteristics('battery_level')[UUID]
|
||||
]),
|
||||
new DOMException(
|
||||
`No Characteristics matching UUID ${battery_level.uuid} found ` +
|
||||
`in Service with UUID ${health_thermometer.uuid}.`,
|
||||
'NotFoundError'))),
|
||||
test_desc);
|
|
@ -0,0 +1,24 @@
|
|||
'use strict';
|
||||
const test_desc = 'Garbage Collection ran during FUNCTION_NAME ' +
|
||||
'call that fails. Should not crash';
|
||||
const expected = new DOMException(
|
||||
'GATT Server is disconnected. Cannot retrieve characteristics. ' +
|
||||
'(Re)connect first with `device.gatt.connect`.',
|
||||
'NetworkError');
|
||||
let promise;
|
||||
|
||||
bluetooth_test(() => getHealthThermometerService()
|
||||
.then(({service}) => {
|
||||
promise = assert_promise_rejects_with_message(
|
||||
service.CALLS([
|
||||
getCharacteristic('measurement_interval')|
|
||||
getCharacteristics()|
|
||||
getCharacteristics('measurement_interval')[UUID]
|
||||
]), expected);
|
||||
// Disconnect called to clear attributeInstanceMap and allow the object to
|
||||
// get garbage collected.
|
||||
service.device.gatt.disconnect();
|
||||
})
|
||||
.then(runGarbageCollection)
|
||||
.then(() => promise),
|
||||
test_desc);
|
|
@ -0,0 +1,24 @@
|
|||
'use strict';
|
||||
const test_desc = 'Calls to FUNCTION_NAME should return the same object.';
|
||||
|
||||
bluetooth_test(() => getHealthThermometerService()
|
||||
.then(({service}) => Promise.all([
|
||||
service.CALLS([
|
||||
getCharacteristic('measurement_interval')|
|
||||
getCharacteristics()|
|
||||
getCharacteristics('measurement_interval')[UUID]]),
|
||||
service.PREVIOUS_CALL]))
|
||||
.then(([characteristics_first_call, characteristics_second_call]) => {
|
||||
// Convert to arrays if necessary.
|
||||
characteristics_first_call = [].concat(characteristics_first_call);
|
||||
characteristics_second_call = [].concat(characteristics_second_call);
|
||||
|
||||
let first_call_set = new Set(characteristics_first_call);
|
||||
assert_equals(characteristics_first_call.length, first_call_set.size);
|
||||
let second_call_set = new Set(characteristics_second_call);
|
||||
assert_equals(characteristics_second_call.length, second_call_set.size);
|
||||
|
||||
characteristics_first_call.forEach(characteristic => {
|
||||
assert_true(second_call_set.has(characteristic));
|
||||
});
|
||||
}), test_desc);
|
|
@ -0,0 +1,23 @@
|
|||
'use strict';
|
||||
const test_desc = 'Wrong Characteristic name. Reject with TypeError.';
|
||||
const expected = new DOMException(
|
||||
"Failed to execute 'FUNCTION_NAME' on " +
|
||||
"'BluetoothRemoteGATTService': Invalid Characteristic name: " +
|
||||
"'wrong_name'. " +
|
||||
"It must be a valid UUID alias (e.g. 0x1234), " +
|
||||
"UUID (lowercase hex characters e.g. " +
|
||||
"'00001234-0000-1000-8000-00805f9b34fb'), " +
|
||||
"or recognized standard name from " +
|
||||
"https://www.bluetooth.com/specifications/gatt/characteristics" +
|
||||
" e.g. 'aerobic_heart_rate_lower_limit'.",
|
||||
'TypeError');
|
||||
|
||||
bluetooth_test(() => getHealthThermometerService()
|
||||
.then(({service}) => assert_promise_rejects_with_message(
|
||||
service.CALLS([
|
||||
getCharacteristic('wrong_name')|
|
||||
getCharacteristics('wrong_name')
|
||||
]),
|
||||
expected,
|
||||
'Wrong Characteristic name passed.')),
|
||||
test_desc);
|
|
@ -0,0 +1,36 @@
|
|||
'use strict';
|
||||
const test_desc = 'disconnect() and connect() called during ' +
|
||||
'FUNCTION_NAME. Reject with NetworkError.';
|
||||
const expected = new DOMException(
|
||||
'GATT Server is disconnected. Cannot retrieve characteristics. ' +
|
||||
'(Re)connect first with `device.gatt.connect`.',
|
||||
'NetworkError');
|
||||
let device;
|
||||
|
||||
bluetooth_test(() => getHealthThermometerDeviceWithServicesDiscovered({
|
||||
filters: [{services: [health_thermometer.name]}],
|
||||
})
|
||||
.then(_ => ({device} = _))
|
||||
.then(() => device.gatt.getPrimaryService(health_thermometer.name))
|
||||
.then(service => Promise.all([
|
||||
// 1. Make a call to service.FUNCTION_NAME, while the service is still
|
||||
// valid.
|
||||
assert_promise_rejects_with_message(service.CALLS([
|
||||
getCharacteristic(measurement_interval.name)|
|
||||
getCharacteristics()|
|
||||
getCharacteristics(measurement_interval.name)[UUID]
|
||||
]), expected),
|
||||
|
||||
// 2. disconnect() and connect before the initial call completes.
|
||||
// This is accomplished by making the calls without waiting for the
|
||||
// earlier promises to resolve.
|
||||
// connect() guarantees on OS-level connection, but disconnect()
|
||||
// only disconnects the current instance.
|
||||
// getHealthThermometerDeviceWithServicesDiscovered holds another
|
||||
// connection in an iframe, so disconnect() and connect() are certain to
|
||||
// reconnect. However, disconnect() will invalidate the service object so
|
||||
// the subsequent calls made to it will fail, even after reconnecting.
|
||||
device.gatt.disconnect(),
|
||||
device.gatt.connect()
|
||||
])),
|
||||
test_desc);
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Request for service. Should return right service';
|
||||
let device;
|
||||
|
||||
bluetooth_test(() => getHealthThermometerDevice({
|
||||
filters: [{services: ['health_thermometer']}],
|
||||
optionalServices: ['generic_access']
|
||||
})
|
||||
.then(_ => ({device} = _))
|
||||
.then(() => Promise.all([
|
||||
device.gatt.getPrimaryService(generic_access.alias),
|
||||
device.gatt.getPrimaryService(generic_access.name),
|
||||
device.gatt.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.');
|
||||
})
|
||||
}), test_desc);
|
||||
</script>
|
|
@ -0,0 +1,80 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
"use strict";
|
||||
const test_desc = 'Two iframes in the same origin should be able to access ' +
|
||||
'each other\'s services';
|
||||
|
||||
const iframe1 = document.createElement('iframe');
|
||||
const iframe2 = document.createElement('iframe');
|
||||
|
||||
function add_iframe(iframe) {
|
||||
let promise = new Promise(resolve => iframe.addEventListener('load', resolve));
|
||||
iframe.src = '/bluetooth/resources/health-thermometer-iframe.html';
|
||||
document.body.appendChild(iframe);
|
||||
return promise;
|
||||
}
|
||||
|
||||
function send_message(iframe, command, arg, assert_func) {
|
||||
let promise = new Promise((resolve, reject) => {
|
||||
window.addEventListener('message', (messageEvent) => {
|
||||
try {
|
||||
assert_func(messageEvent.data);
|
||||
} catch (e) {
|
||||
reject(e);
|
||||
}
|
||||
resolve();
|
||||
}, { once: true });
|
||||
});
|
||||
if (command === 'RequestAndConnect') {
|
||||
arg = {filters: [{services: [arg]}]};
|
||||
}
|
||||
callWithTrustedClick(() => iframe.contentWindow.postMessage({
|
||||
type: command,
|
||||
options: arg,
|
||||
}, '*'));
|
||||
return promise;
|
||||
}
|
||||
|
||||
bluetooth_test(() => getHealthThermometerDevice()
|
||||
// 1. Add the first iframe.
|
||||
.then(() => add_iframe(iframe1))
|
||||
// 2. Connect with the first iframe, requesting the health thermometer
|
||||
// service.
|
||||
.then(() => send_message(iframe1, 'RequestAndConnect', 'health_thermometer',
|
||||
msg => assert_equals(msg, 'Connected')))
|
||||
// 3. Access the health thermometer service with the first iframe
|
||||
// (successfully).
|
||||
.then(() => send_message(iframe1, 'GetService', 'health_thermometer',
|
||||
msg => assert_equals(msg, 'ServiceReceived')))
|
||||
// 4. Access the generic access service with the first iframe
|
||||
// (unsuccessfully).
|
||||
.then(() => send_message(iframe1, 'GetService', 'generic_access', msg => {
|
||||
let split_msg = msg.split(': ');
|
||||
assert_equals(split_msg[0], 'FAIL');
|
||||
assert_equals(split_msg[1], 'SecurityError');
|
||||
}))
|
||||
// 5. Add the second iframe.
|
||||
.then(() => add_iframe(iframe2))
|
||||
// 6. Connect with the second iframe, requesting the generic access service.
|
||||
.then(() => send_message(iframe2, 'RequestAndConnect', 'generic_access',
|
||||
msg => assert_equals(msg, 'Connected')))
|
||||
// 7. Access the health thermometer service with the second iframe
|
||||
// (successfully). Both iframes should have access to both services at this
|
||||
// point since they have the same origin.
|
||||
.then(() => send_message(iframe2, 'GetService', 'health_thermometer',
|
||||
msg => assert_equals(msg, 'ServiceReceived')))
|
||||
// 8. Access the generic access service with the second iframe
|
||||
// (unsuccessfully).
|
||||
.then(() => send_message(iframe2, 'GetService', 'generic_access',
|
||||
msg => assert_equals(msg, 'ServiceReceived')))
|
||||
// 9. Access the generic access service with the first iframe
|
||||
// (successfully).
|
||||
.then(() => send_message(iframe1, 'GetService', 'generic_access',
|
||||
msg => assert_equals(msg, 'ServiceReceived'))),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Request for services. Does not return blocklisted service.';
|
||||
const expected = new DOMException(
|
||||
'Origin is not allowed to access the service. Tip: Add the service ' +
|
||||
'UUID to \'optionalServices\' in requestDevice() options. ' +
|
||||
'https://goo.gl/HxfxSQ', 'SecurityError');
|
||||
|
||||
bluetooth_test(() => getHIDDevice({
|
||||
filters: [{services: ['device_information']}],
|
||||
optionalServices: ['human_interface_device']
|
||||
})
|
||||
.then(({device}) => assert_promise_rejects_with_message(
|
||||
device.gatt.getPrimaryServices('human_interface_device'),
|
||||
expected)),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Request for services. Does not return blocklisted service.';
|
||||
|
||||
bluetooth_test(() => getHIDDevice({
|
||||
filters: [{services: ['device_information']}],
|
||||
optionalServices: ['generic_access', 'human_interface_device']
|
||||
})
|
||||
.then(({device}) => device.gatt.getPrimaryServices())
|
||||
.then(services => {
|
||||
assert_equals(services.length, 2);
|
||||
let uuid_set = new Set(services.map(s => s.uuid));
|
||||
|
||||
assert_equals(uuid_set.size, 2);
|
||||
assert_true(uuid_set.has(BluetoothUUID.getService('generic_access')));
|
||||
assert_true(uuid_set.has(BluetoothUUID.getService('device_information')));
|
||||
assert_false(
|
||||
uuid_set.has(BluetoothUUID.getService('human_interface_device')));
|
||||
}), test_desc);
|
||||
</script>
|
|
@ -0,0 +1,36 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Find correct services with UUID.';
|
||||
let device, fake_peripheral;
|
||||
|
||||
bluetooth_test(() => getConnectedHealthThermometerDevice({
|
||||
filters: [{services: ['health_thermometer']}]
|
||||
})
|
||||
.then(_ => ({device, fake_peripheral} = _))
|
||||
.then(() => fake_peripheral.addFakeService({uuid: 'health_thermometer'}))
|
||||
.then(fake_service => Promise.all([
|
||||
fake_service.addFakeCharacteristic({
|
||||
uuid: 'temperature_measurement', properties: ['indicate']}),
|
||||
fake_service.addFakeCharacteristic({
|
||||
uuid: 'temperature_measurement', properties: ['indicate']})
|
||||
]))
|
||||
.then(() => fake_peripheral.setNextGATTDiscoveryResponse({code:HCI_SUCCESS}))
|
||||
.then(() => device.gatt.getPrimaryServices('health_thermometer'))
|
||||
.then(services => Promise.all([
|
||||
services[0].getCharacteristics(),
|
||||
services[1].getCharacteristics()]))
|
||||
.then(([characteristics1, characteristics2]) => {
|
||||
if (characteristics1.length === 2)
|
||||
assert_equals(characteristics2.length, 3);
|
||||
else if (characteristics2.length === 2)
|
||||
assert_equals(characteristics1.length, 3);
|
||||
else
|
||||
assert_unreached('Invalid lengths.');
|
||||
}), test_desc);
|
||||
</script>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Request for services. Should return right number of ' +
|
||||
'services.';
|
||||
|
||||
bluetooth_test(() => getTwoHealthThermometerServicesDevice({
|
||||
filters: [{services: ['health_thermometer']}]
|
||||
})
|
||||
.then(({device}) => Promise.all([
|
||||
device.gatt.getPrimaryServices(health_thermometer.alias),
|
||||
device.gatt.getPrimaryServices(health_thermometer.name),
|
||||
device.gatt.getPrimaryServices(health_thermometer.uuid)]))
|
||||
.then(services_arrays => services_arrays.forEach(services => {
|
||||
assert_equals(services.length, 2);
|
||||
services.forEach(service => {
|
||||
assert_equals(service.uuid,
|
||||
BluetoothUUID.getService('health_thermometer'));
|
||||
assert_true(service.isPrimary);
|
||||
});
|
||||
})), test_desc);
|
||||
</script>
|
|
@ -0,0 +1,29 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Find all services in a device.';
|
||||
|
||||
bluetooth_test(() => getTwoHealthThermometerServicesDevice({
|
||||
filters: [{services: ['health_thermometer']}],
|
||||
optionalServices: ['generic_access']
|
||||
})
|
||||
.then(({device}) => device.gatt.getPrimaryServices())
|
||||
.then(services => {
|
||||
// Expect three service instances.
|
||||
assert_equals(services.length, 3);
|
||||
services.forEach(s => assert_true(s.isPrimary));
|
||||
|
||||
let uuid_set = new Set(services.map(s => s.uuid));
|
||||
// Two of the expected services are 'health_thermometer', so
|
||||
// only 2 unique UUIDs.
|
||||
assert_equals(uuid_set.size, 2);
|
||||
|
||||
assert_true(uuid_set.has(BluetoothUUID.getService('generic_access')));
|
||||
assert_true(uuid_set.has(BluetoothUUID.getService('health_thermometer')));
|
||||
}), test_desc);
|
||||
</script>
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Request for services in a device with no services. Reject ' +
|
||||
'with NotFoundError.';
|
||||
const expected = new DOMException('No Services found in device.',
|
||||
'NotFoundError');
|
||||
|
||||
bluetooth_test(() => getEmptyHealthThermometerDevice()
|
||||
.then(({device}) => assert_promise_rejects_with_message(
|
||||
device.gatt.getPrimaryServices(),
|
||||
expected)),
|
||||
test_desc);
|
||||
</script>
|
|
@ -0,0 +1,26 @@
|
|||
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
|
||||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Serial Number String characteristic is blocklisted. ' +
|
||||
'Should reject with SecurityError.';
|
||||
const expected = new DOMException(
|
||||
'getCharacteristic(s) called with blocklisted UUID. https://goo.gl/4NeimX',
|
||||
'SecurityError');
|
||||
|
||||
bluetooth_test(() => getHIDDevice({
|
||||
filters: [{services: ['device_information']}]
|
||||
})
|
||||
.then(({device}) => device.gatt.getPrimaryService('device_information'))
|
||||
.then(service => assert_promise_rejects_with_message(
|
||||
service.getCharacteristic('serial_number_string'),
|
||||
expected,
|
||||
'Serial Number String characteristic is blocklisted.')),
|
||||
test_desc);
|
||||
|
||||
</script>
|
|
@ -0,0 +1,22 @@
|
|||
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
|
||||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Request for absent characteristics with UUID. ' +
|
||||
'Reject with NotFoundError.';
|
||||
|
||||
bluetooth_test(() => getEmptyHealthThermometerService()
|
||||
.then(({service}) => assert_promise_rejects_with_message(
|
||||
service.getCharacteristic('battery_level'),
|
||||
new DOMException(
|
||||
`No Characteristics matching UUID ${battery_level.uuid} found ` +
|
||||
`in Service with UUID ${health_thermometer.uuid}.`,
|
||||
'NotFoundError'))),
|
||||
test_desc);
|
||||
|
||||
</script>
|
|
@ -0,0 +1,30 @@
|
|||
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
|
||||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Garbage Collection ran during getCharacteristic ' +
|
||||
'call that fails. Should not crash';
|
||||
const expected = new DOMException(
|
||||
'GATT Server is disconnected. Cannot retrieve characteristics. ' +
|
||||
'(Re)connect first with `device.gatt.connect`.',
|
||||
'NetworkError');
|
||||
let promise;
|
||||
|
||||
bluetooth_test(() => getHealthThermometerService()
|
||||
.then(({service}) => {
|
||||
promise = assert_promise_rejects_with_message(
|
||||
service.getCharacteristic('measurement_interval'), expected);
|
||||
// Disconnect called to clear attributeInstanceMap and allow the object to
|
||||
// get garbage collected.
|
||||
service.device.gatt.disconnect();
|
||||
})
|
||||
.then(runGarbageCollection)
|
||||
.then(() => promise),
|
||||
test_desc);
|
||||
|
||||
</script>
|
|
@ -0,0 +1,31 @@
|
|||
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
|
||||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Calls to getCharacteristic should return the same object.';
|
||||
|
||||
bluetooth_test(() => getHealthThermometerService()
|
||||
.then(({service}) => Promise.all([
|
||||
service.getCharacteristic('measurement_interval'),
|
||||
service.getCharacteristic('measurement_interval')]))
|
||||
.then(([characteristics_first_call, characteristics_second_call]) => {
|
||||
// Convert to arrays if necessary.
|
||||
characteristics_first_call = [].concat(characteristics_first_call);
|
||||
characteristics_second_call = [].concat(characteristics_second_call);
|
||||
|
||||
let first_call_set = new Set(characteristics_first_call);
|
||||
assert_equals(characteristics_first_call.length, first_call_set.size);
|
||||
let second_call_set = new Set(characteristics_second_call);
|
||||
assert_equals(characteristics_second_call.length, second_call_set.size);
|
||||
|
||||
characteristics_first_call.forEach(characteristic => {
|
||||
assert_true(second_call_set.has(characteristic));
|
||||
});
|
||||
}), test_desc);
|
||||
|
||||
</script>
|
|
@ -0,0 +1,30 @@
|
|||
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
|
||||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Wrong Characteristic name. Reject with TypeError.';
|
||||
const expected = new DOMException(
|
||||
"Failed to execute 'getCharacteristic' on " +
|
||||
"'BluetoothRemoteGATTService': Invalid Characteristic name: " +
|
||||
"'wrong_name'. " +
|
||||
"It must be a valid UUID alias (e.g. 0x1234), " +
|
||||
"UUID (lowercase hex characters e.g. " +
|
||||
"'00001234-0000-1000-8000-00805f9b34fb'), " +
|
||||
"or recognized standard name from " +
|
||||
"https://www.bluetooth.com/specifications/gatt/characteristics" +
|
||||
" e.g. 'aerobic_heart_rate_lower_limit'.",
|
||||
'TypeError');
|
||||
|
||||
bluetooth_test(() => getHealthThermometerService()
|
||||
.then(({service}) => assert_promise_rejects_with_message(
|
||||
service.getCharacteristic('wrong_name'),
|
||||
expected,
|
||||
'Wrong Characteristic name passed.')),
|
||||
test_desc);
|
||||
|
||||
</script>
|
|
@ -0,0 +1,42 @@
|
|||
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
|
||||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'disconnect() and connect() called during ' +
|
||||
'getCharacteristic. Reject with NetworkError.';
|
||||
const expected = new DOMException(
|
||||
'GATT Server is disconnected. Cannot retrieve characteristics. ' +
|
||||
'(Re)connect first with `device.gatt.connect`.',
|
||||
'NetworkError');
|
||||
let device;
|
||||
|
||||
bluetooth_test(() => getHealthThermometerDeviceWithServicesDiscovered({
|
||||
filters: [{services: [health_thermometer.name]}],
|
||||
})
|
||||
.then(_ => ({device} = _))
|
||||
.then(() => device.gatt.getPrimaryService(health_thermometer.name))
|
||||
.then(service => Promise.all([
|
||||
// 1. Make a call to service.getCharacteristic, while the service is still
|
||||
// valid.
|
||||
assert_promise_rejects_with_message(service.getCharacteristic(measurement_interval.name), expected),
|
||||
|
||||
// 2. disconnect() and connect before the initial call completes.
|
||||
// This is accomplished by making the calls without waiting for the
|
||||
// earlier promises to resolve.
|
||||
// connect() guarantees on OS-level connection, but disconnect()
|
||||
// only disconnects the current instance.
|
||||
// getHealthThermometerDeviceWithServicesDiscovered holds another
|
||||
// connection in an iframe, so disconnect() and connect() are certain to
|
||||
// reconnect. However, disconnect() will invalidate the service object so
|
||||
// the subsequent calls made to it will fail, even after reconnecting.
|
||||
device.gatt.disconnect(),
|
||||
device.gatt.connect()
|
||||
])),
|
||||
test_desc);
|
||||
|
||||
</script>
|
|
@ -0,0 +1,26 @@
|
|||
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
|
||||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Serial Number String characteristic is blocklisted. ' +
|
||||
'Should reject with SecurityError.';
|
||||
const expected = new DOMException(
|
||||
'getCharacteristic(s) called with blocklisted UUID. https://goo.gl/4NeimX',
|
||||
'SecurityError');
|
||||
|
||||
bluetooth_test(() => getHIDDevice({
|
||||
filters: [{services: ['device_information']}]
|
||||
})
|
||||
.then(({device}) => device.gatt.getPrimaryService('device_information'))
|
||||
.then(service => assert_promise_rejects_with_message(
|
||||
service.getCharacteristics('serial_number_string'),
|
||||
expected,
|
||||
'Serial Number String characteristic is blocklisted.')),
|
||||
test_desc);
|
||||
|
||||
</script>
|
|
@ -0,0 +1,22 @@
|
|||
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
|
||||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Request for absent characteristics with UUID. ' +
|
||||
'Reject with NotFoundError.';
|
||||
|
||||
bluetooth_test(() => getEmptyHealthThermometerService()
|
||||
.then(({service}) => assert_promise_rejects_with_message(
|
||||
service.getCharacteristics('battery_level'),
|
||||
new DOMException(
|
||||
`No Characteristics matching UUID ${battery_level.uuid} found ` +
|
||||
`in Service with UUID ${health_thermometer.uuid}.`,
|
||||
'NotFoundError'))),
|
||||
test_desc);
|
||||
|
||||
</script>
|
|
@ -0,0 +1,30 @@
|
|||
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
|
||||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Garbage Collection ran during getCharacteristics ' +
|
||||
'call that fails. Should not crash';
|
||||
const expected = new DOMException(
|
||||
'GATT Server is disconnected. Cannot retrieve characteristics. ' +
|
||||
'(Re)connect first with `device.gatt.connect`.',
|
||||
'NetworkError');
|
||||
let promise;
|
||||
|
||||
bluetooth_test(() => getHealthThermometerService()
|
||||
.then(({service}) => {
|
||||
promise = assert_promise_rejects_with_message(
|
||||
service.getCharacteristics('measurement_interval'), expected);
|
||||
// Disconnect called to clear attributeInstanceMap and allow the object to
|
||||
// get garbage collected.
|
||||
service.device.gatt.disconnect();
|
||||
})
|
||||
.then(runGarbageCollection)
|
||||
.then(() => promise),
|
||||
test_desc);
|
||||
|
||||
</script>
|
|
@ -0,0 +1,30 @@
|
|||
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
|
||||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Garbage Collection ran during getCharacteristics ' +
|
||||
'call that fails. Should not crash';
|
||||
const expected = new DOMException(
|
||||
'GATT Server is disconnected. Cannot retrieve characteristics. ' +
|
||||
'(Re)connect first with `device.gatt.connect`.',
|
||||
'NetworkError');
|
||||
let promise;
|
||||
|
||||
bluetooth_test(() => getHealthThermometerService()
|
||||
.then(({service}) => {
|
||||
promise = assert_promise_rejects_with_message(
|
||||
service.getCharacteristics(), expected);
|
||||
// Disconnect called to clear attributeInstanceMap and allow the object to
|
||||
// get garbage collected.
|
||||
service.device.gatt.disconnect();
|
||||
})
|
||||
.then(runGarbageCollection)
|
||||
.then(() => promise),
|
||||
test_desc);
|
||||
|
||||
</script>
|
|
@ -0,0 +1,31 @@
|
|||
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
|
||||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Calls to getCharacteristics should return the same object.';
|
||||
|
||||
bluetooth_test(() => getHealthThermometerService()
|
||||
.then(({service}) => Promise.all([
|
||||
service.getCharacteristics('measurement_interval'),
|
||||
service.getCharacteristics('measurement_interval')]))
|
||||
.then(([characteristics_first_call, characteristics_second_call]) => {
|
||||
// Convert to arrays if necessary.
|
||||
characteristics_first_call = [].concat(characteristics_first_call);
|
||||
characteristics_second_call = [].concat(characteristics_second_call);
|
||||
|
||||
let first_call_set = new Set(characteristics_first_call);
|
||||
assert_equals(characteristics_first_call.length, first_call_set.size);
|
||||
let second_call_set = new Set(characteristics_second_call);
|
||||
assert_equals(characteristics_second_call.length, second_call_set.size);
|
||||
|
||||
characteristics_first_call.forEach(characteristic => {
|
||||
assert_true(second_call_set.has(characteristic));
|
||||
});
|
||||
}), test_desc);
|
||||
|
||||
</script>
|
|
@ -0,0 +1,31 @@
|
|||
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
|
||||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Calls to getCharacteristics should return the same object.';
|
||||
|
||||
bluetooth_test(() => getHealthThermometerService()
|
||||
.then(({service}) => Promise.all([
|
||||
service.getCharacteristics(),
|
||||
service.getCharacteristics()]))
|
||||
.then(([characteristics_first_call, characteristics_second_call]) => {
|
||||
// Convert to arrays if necessary.
|
||||
characteristics_first_call = [].concat(characteristics_first_call);
|
||||
characteristics_second_call = [].concat(characteristics_second_call);
|
||||
|
||||
let first_call_set = new Set(characteristics_first_call);
|
||||
assert_equals(characteristics_first_call.length, first_call_set.size);
|
||||
let second_call_set = new Set(characteristics_second_call);
|
||||
assert_equals(characteristics_second_call.length, second_call_set.size);
|
||||
|
||||
characteristics_first_call.forEach(characteristic => {
|
||||
assert_true(second_call_set.has(characteristic));
|
||||
});
|
||||
}), test_desc);
|
||||
|
||||
</script>
|
|
@ -0,0 +1,30 @@
|
|||
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
|
||||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'Wrong Characteristic name. Reject with TypeError.';
|
||||
const expected = new DOMException(
|
||||
"Failed to execute 'getCharacteristics' on " +
|
||||
"'BluetoothRemoteGATTService': Invalid Characteristic name: " +
|
||||
"'wrong_name'. " +
|
||||
"It must be a valid UUID alias (e.g. 0x1234), " +
|
||||
"UUID (lowercase hex characters e.g. " +
|
||||
"'00001234-0000-1000-8000-00805f9b34fb'), " +
|
||||
"or recognized standard name from " +
|
||||
"https://www.bluetooth.com/specifications/gatt/characteristics" +
|
||||
" e.g. 'aerobic_heart_rate_lower_limit'.",
|
||||
'TypeError');
|
||||
|
||||
bluetooth_test(() => getHealthThermometerService()
|
||||
.then(({service}) => assert_promise_rejects_with_message(
|
||||
service.getCharacteristics('wrong_name'),
|
||||
expected,
|
||||
'Wrong Characteristic name passed.')),
|
||||
test_desc);
|
||||
|
||||
</script>
|
|
@ -0,0 +1,42 @@
|
|||
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
|
||||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'disconnect() and connect() called during ' +
|
||||
'getCharacteristics. Reject with NetworkError.';
|
||||
const expected = new DOMException(
|
||||
'GATT Server is disconnected. Cannot retrieve characteristics. ' +
|
||||
'(Re)connect first with `device.gatt.connect`.',
|
||||
'NetworkError');
|
||||
let device;
|
||||
|
||||
bluetooth_test(() => getHealthThermometerDeviceWithServicesDiscovered({
|
||||
filters: [{services: [health_thermometer.name]}],
|
||||
})
|
||||
.then(_ => ({device} = _))
|
||||
.then(() => device.gatt.getPrimaryService(health_thermometer.name))
|
||||
.then(service => Promise.all([
|
||||
// 1. Make a call to service.getCharacteristics, while the service is still
|
||||
// valid.
|
||||
assert_promise_rejects_with_message(service.getCharacteristics(measurement_interval.name), expected),
|
||||
|
||||
// 2. disconnect() and connect before the initial call completes.
|
||||
// This is accomplished by making the calls without waiting for the
|
||||
// earlier promises to resolve.
|
||||
// connect() guarantees on OS-level connection, but disconnect()
|
||||
// only disconnects the current instance.
|
||||
// getHealthThermometerDeviceWithServicesDiscovered holds another
|
||||
// connection in an iframe, so disconnect() and connect() are certain to
|
||||
// reconnect. However, disconnect() will invalidate the service object so
|
||||
// the subsequent calls made to it will fail, even after reconnecting.
|
||||
device.gatt.disconnect(),
|
||||
device.gatt.connect()
|
||||
])),
|
||||
test_desc);
|
||||
|
||||
</script>
|
|
@ -0,0 +1,42 @@
|
|||
<!-- Generated by //third_party/WebKit/LayoutTests/bluetooth/generate.py -->
|
||||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/resources/testdriver.js"></script>
|
||||
<script src="/resources/testdriver-vendor.js"></script>
|
||||
<script src="/bluetooth/resources/bluetooth-helpers.js"></script>
|
||||
<script>
|
||||
'use strict';
|
||||
const test_desc = 'disconnect() and connect() called during ' +
|
||||
'getCharacteristics. Reject with NetworkError.';
|
||||
const expected = new DOMException(
|
||||
'GATT Server is disconnected. Cannot retrieve characteristics. ' +
|
||||
'(Re)connect first with `device.gatt.connect`.',
|
||||
'NetworkError');
|
||||
let device;
|
||||
|
||||
bluetooth_test(() => getHealthThermometerDeviceWithServicesDiscovered({
|
||||
filters: [{services: [health_thermometer.name]}],
|
||||
})
|
||||
.then(_ => ({device} = _))
|
||||
.then(() => device.gatt.getPrimaryService(health_thermometer.name))
|
||||
.then(service => Promise.all([
|
||||
// 1. Make a call to service.getCharacteristics, while the service is still
|
||||
// valid.
|
||||
assert_promise_rejects_with_message(service.getCharacteristics(), expected),
|
||||
|
||||
// 2. disconnect() and connect before the initial call completes.
|
||||
// This is accomplished by making the calls without waiting for the
|
||||
// earlier promises to resolve.
|
||||
// connect() guarantees on OS-level connection, but disconnect()
|
||||
// only disconnects the current instance.
|
||||
// getHealthThermometerDeviceWithServicesDiscovered holds another
|
||||
// connection in an iframe, so disconnect() and connect() are certain to
|
||||
// reconnect. However, disconnect() will invalidate the service object so
|
||||
// the subsequent calls made to it will fail, even after reconnecting.
|
||||
device.gatt.disconnect(),
|
||||
device.gatt.connect()
|
||||
])),
|
||||
test_desc);
|
||||
|
||||
</script>
|
4
tests/wpt/web-platform-tests/common/namespaces.js
Normal file
4
tests/wpt/web-platform-tests/common/namespaces.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
var NAMESPACES = {
|
||||
"svg": "http://www.w3.org/2000/svg",
|
||||
"xlink": "http://www.w3.org/1999/xlink",
|
||||
};
|
|
@ -50,7 +50,9 @@
|
|||
{ "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - report-uri present",
|
||||
"csp": "script-src 'unsafe-inline'; report-uri resources/dummy-report.php",
|
||||
"expected": null },
|
||||
// TODO(andypaicu): when `report-to` is implemented, add tests here.
|
||||
{ "name": "Wrong value of `csp` should not trigger sending Sec-Required-CSP Header - report-to present",
|
||||
"csp": "script-src 'unsafe-inline'; report-to resources/dummy-report.php",
|
||||
"expected": null },
|
||||
];
|
||||
|
||||
tests.forEach(test => {
|
||||
|
|
|
@ -2,6 +2,6 @@ Expires: Mon, 26 Jul 1997 05:00:00 GMT
|
|||
Cache-Control: no-store, no-cache, must-revalidate
|
||||
Cache-Control: post-check=0, pre-check=0, false
|
||||
Pragma: no-cache
|
||||
Set-Cookie: reporting-api-doesnt-send-reports-without-violation={{$id:uuid()}}; Path=/content-security-policy/reporting
|
||||
Set-Cookie: reporting-api-doesnt-send-reports-without-violation={{$id:uuid()}}; Path=/content-security-policy/reporting-api
|
||||
Report-To: { "url": "https://{{host}}:{{ports[https][0]}}/content-security-policy/support/report.py?op=put&reportID={{$id}}", "group": "csp-group", "max-age": 10886400 }
|
||||
Content-Security-Policy: script-src 'self' 'unsafe-inline'; img-src 'self'; report-to csp-group
|
|
@ -2,6 +2,6 @@ Expires: Mon, 26 Jul 1997 05:00:00 GMT
|
|||
Cache-Control: no-store, no-cache, must-revalidate
|
||||
Cache-Control: post-check=0, pre-check=0, false
|
||||
Pragma: no-cache
|
||||
Set-Cookie: reporting-api-report-only-sends-reports-on-violation={{$id:uuid()}}; Path=/content-security-policy/reporting
|
||||
Set-Cookie: reporting-api-report-only-sends-reports-on-violation={{$id:uuid()}}; Path=/content-security-policy/reporting-api
|
||||
Report-To: { "url": "https://{{host}}:{{ports[https][0]}}/content-security-policy/support/report.py?op=put&reportID={{$id}}", "group": "csp-group", "max-age": 10886400 }
|
||||
Content-Security-Policy-Report-Only: script-src 'self' 'unsafe-inline'; img-src 'none'; report-to csp-group
|
|
@ -2,6 +2,6 @@ Expires: Mon, 26 Jul 1997 05:00:00 GMT
|
|||
Cache-Control: no-store, no-cache, must-revalidate
|
||||
Cache-Control: post-check=0, pre-check=0, false
|
||||
Pragma: no-cache
|
||||
Set-Cookie: reporting-api-report-to-overrides-report-uri-1={{$id:uuid()}}; Path=/content-security-policy/reporting
|
||||
Set-Cookie: reporting-api-report-to-overrides-report-uri-1={{$id:uuid()}}; Path=/content-security-policy/reporting-api
|
||||
Content-Security-Policy: script-src 'self' 'unsafe-inline'; img-src 'none'; report-uri "/content-security-policy/support/report.py?op=put&reportID={{$id}}"; report-to csp-group
|
||||
Report-To: { "url": "https://{{host}}:{{ports[https][0]}}/content-security-policy/support/report.py?op=put&reportID={{$id:uuid()}}", "group": "csp-group", "max-age": 10886400 }
|
|
@ -2,6 +2,6 @@ Expires: Mon, 26 Jul 1997 05:00:00 GMT
|
|||
Cache-Control: no-store, no-cache, must-revalidate
|
||||
Cache-Control: post-check=0, pre-check=0, false
|
||||
Pragma: no-cache
|
||||
Set-Cookie: reporting-api-report-to-overrides-report-uri-2={{$id:uuid()}}; Path=/content-security-policy/reporting
|
||||
Set-Cookie: reporting-api-report-to-overrides-report-uri-2={{$id:uuid()}}; Path=/content-security-policy/reporting-api
|
||||
Content-Security-Policy: script-src 'self' 'unsafe-inline'; img-src 'none'; report-to csp-group; report-uri "/content-security-policy/support/report.py?op=put&reportID={{$id}}"
|
||||
Report-To: { "url": "https://{{host}}:{{ports[https][0]}}/content-security-policy/support/report.py?op=put&reportID={{$id:uuid()}}", "group": "csp-group", "max-age": 10886400 }
|
|
@ -2,6 +2,6 @@ Expires: Mon, 26 Jul 1997 05:00:00 GMT
|
|||
Cache-Control: no-store, no-cache, must-revalidate
|
||||
Cache-Control: post-check=0, pre-check=0, false
|
||||
Pragma: no-cache
|
||||
Set-Cookie: reporting-api-sends-reports-on-violation={{$id:uuid()}}; Path=/content-security-policy/reporting
|
||||
Set-Cookie: reporting-api-sends-reports-on-violation={{$id:uuid()}}; Path=/content-security-policy/reporting-api
|
||||
Report-To: { "url": "https://{{host}}:{{ports[https][0]}}/content-security-policy/support/report.py?op=put&reportID={{$id}}", "group": "csp-group", "max-age": 10886400 }
|
||||
Content-Security-Policy: script-src 'self' 'unsafe-inline'; img-src 'none'; report-to csp-group
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test that reports using the report-api service are sent when there's a violation</title>
|
||||
<script src='/resources/testharness.js'></script>
|
||||
<script src='/resources/testharnessreport.js'></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
async_test(function(t2) {
|
||||
window.addEventListener("securitypolicyviolation", t2.step_func(function(e) {
|
||||
assert_equals(e.blockedURI, "{{location[scheme]}}://{{location[host]}}/content-security-policy/support/fail.html");
|
||||
assert_equals(e.violatedDirective, "frame-src");
|
||||
t2.done();
|
||||
}));
|
||||
}, "Event is fired");
|
||||
</script>
|
||||
<iframe src="../support/fail.html"></iframe>
|
||||
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=frame-src%20%27none%27'></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,6 @@
|
|||
Expires: Mon, 26 Jul 1997 05:00:00 GMT
|
||||
Cache-Control: no-store, no-cache, must-revalidate
|
||||
Pragma: no-cache
|
||||
Set-Cookie: reporting-api-works-on-frame-src={{$id:uuid()}}; Path=/content-security-policy/reporting-api
|
||||
Report-To: { "url": "https://{{host}}:{{ports[https][0]}}/content-security-policy/support/report.py?op=put&reportID={{$id}}", "group": "csp-group", "max-age": 10886400 }
|
||||
Content-Security-Policy: script-src 'self' 'unsafe-inline'; frame-src 'none'; report-to csp-group
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<title>When multiple report-uri endpoints for multiple policies are specified, each gets a report</title>
|
||||
<!-- CSP headers
|
||||
Content-Security-Policy-Report-Only: img-src http://* https://*; default-src 'self'; script-src 'self' 'unsafe-inline'; report-uri ../support/report.py?op=put&reportID={{$id}}
|
||||
|
||||
Content-Security-Policy-Report-Only: img-src http://*; default-src 'self'; script-src 'self' 'unsafe-inline'; report-uri ../support/report.py?op=put&reportID={{$id}}
|
||||
-->
|
||||
</head>
|
||||
<body>
|
||||
<img src="ftp://blah.test" />
|
||||
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20http%3A%2F%2F%2A%20https%3A%2F%2F%2A&testName=1-Violation%20report%20status%20OK'></script>
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20http%3A%2F%2F%2A&reportCookieName=multiple-report-policies-2&testName=2-Violation%20report%20status%20OK'></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,8 @@
|
|||
Expires: Mon, 26 Jul 1997 05:00:00 GMT
|
||||
Cache-Control: no-store, no-cache, must-revalidate
|
||||
Cache-Control: post-check=0, pre-check=0, false
|
||||
Pragma: no-cache
|
||||
Set-Cookie: multiple-report-policies={{$id:uuid()}}; Path=/content-security-policy/reporting/
|
||||
Content-Security-Policy-Report-Only: img-src http://* https://*; default-src 'self'; script-src 'self' 'unsafe-inline'; report-uri ../support/report.py?op=put&reportID={{$id}}
|
||||
Set-Cookie: multiple-report-policies-2={{$id:uuid()}}; Path=/content-security-policy/reporting/
|
||||
Content-Security-Policy-Report-Only: img-src http://*; default-src 'self'; script-src 'self' 'unsafe-inline'; report-uri ../support/report.py?op=put&reportID={{$id}}
|
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<title>Reporting and enforcing policies can be different</title>
|
||||
<!-- CSP headers
|
||||
Content-Security-Policy: img-src 'none'; style-src *; script-src 'self' 'unsafe-inline'
|
||||
|
||||
Content-Security-Policy-Report-Only: img-src *; style-src 'none'; script-src 'self' 'unsafe-inline'; report-uri ../support/report.py?op=put&reportID={{$id}}
|
||||
-->
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var img_test = async_test("The image should be blocked");
|
||||
var sheet_test = async_test("The stylesheet should load");
|
||||
<!-- This image should be blocked, but should not generate a report-->
|
||||
var i = document.createElement('img');
|
||||
i.onerror = img_test.step_func_done();
|
||||
i.onload = img_test.unreached_func("Should not have loaded the img");
|
||||
i.src = "../support/fail.png";
|
||||
document.body.appendChild(i);
|
||||
<!-- This font should be loaded but should generate a report-->
|
||||
var s = document.createElement('link');
|
||||
s.onerror = sheet_test.unreached_func("Should have loaded the font");
|
||||
s.onload = sheet_test.step_func_done();
|
||||
s.type = "text/css";
|
||||
s.rel="stylesheet";
|
||||
s.href = "../support/fonts.css";
|
||||
document.body.appendChild(s);
|
||||
</script>
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=style-src%20%27none%27'></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
Expires: Mon, 26 Jul 1997 05:00:00 GMT
|
||||
Cache-Control: no-store, no-cache, must-revalidate
|
||||
Cache-Control: post-check=0, pre-check=0, false
|
||||
Pragma: no-cache
|
||||
Set-Cookie: report-and-enforce={{$id:uuid()}}; Path=/content-security-policy/reporting/
|
||||
Content-Security-Policy: img-src 'none'; style-src *; script-src 'self' 'unsafe-inline'
|
||||
Content-Security-Policy-Report-Only: img-src *; style-src 'none'; script-src 'self' 'unsafe-inline'; report-uri ../support/report.py?op=put&reportID={{$id}}
|
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<title>Data-uri images are reported correctly</title>
|
||||
<!-- CSP headers
|
||||
Content-Security-Policy: img-src 'none'; report-uri ../support/report.py?op=put&reportID={{$id}}
|
||||
-->
|
||||
</head>
|
||||
<body>
|
||||
<img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==">
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20%27none%27'></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,6 @@
|
|||
Expires: Mon, 26 Jul 1997 05:00:00 GMT
|
||||
Cache-Control: no-store, no-cache, must-revalidate
|
||||
Cache-Control: post-check=0, pre-check=0, false
|
||||
Pragma: no-cache
|
||||
Set-Cookie: report-blocked-data-uri={{$id:uuid()}}; Path=/content-security-policy/reporting/
|
||||
Content-Security-Policy: img-src 'none'; report-uri ../support/report.py?op=put&reportID={{$id}}
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<title>Cross-origin images are reported correctly</title>
|
||||
<!-- CSP headers
|
||||
Content-Security-Policy: script-src 'self' 'unsafe-inline'
|
||||
Content-Security-Policy-Report-Only: img-src 'none'; script-src 'self' 'unsafe-inline'; report-uri ../support/report.py?op=put&reportID=$id
|
||||
-->
|
||||
</head>
|
||||
<body>
|
||||
<img src="http://{{domains[www1]}}:{{ports[http][0]}}/content-security-policy/support/pass.png">
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20%27none%27'></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
Expires: Mon, 26 Jul 1997 05:00:00 GMT
|
||||
Cache-Control: no-store, no-cache, must-revalidate
|
||||
Cache-Control: post-check=0, pre-check=0, false
|
||||
Pragma: no-cache
|
||||
Set-Cookie: report-blocked-uri-cross-origin={{$id:uuid()}}; Path=/content-security-policy/reporting/
|
||||
Content-Security-Policy: script-src 'self' 'unsafe-inline'
|
||||
Content-Security-Policy-Report-Only: img-src 'none'; script-src 'self' 'unsafe-inline'; report-uri ../support/report.py?op=put&reportID={{$id}}
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<title>Blocked relative images are reported correctly</title>
|
||||
<!-- CSP headers
|
||||
Content-Security-Policy: script-src 'self' 'unsafe-inline'
|
||||
Content-Security-Policy-Report-Only: img-src 'none'; script-src 'self' 'unsafe-inline'; report-uri ../support/report.py?op=put&reportID={{$id}}
|
||||
-->
|
||||
</head>
|
||||
<body>
|
||||
<img src="../support/pass.png">
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20%27none%27'></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,7 @@
|
|||
Expires: Mon, 26 Jul 1997 05:00:00 GMT
|
||||
Cache-Control: no-store, no-cache, must-revalidate
|
||||
Cache-Control: post-check=0, pre-check=0, false
|
||||
Pragma: no-cache
|
||||
Set-Cookie: report-blocked-uri={{$id:uuid()}}; Path=/content-security-policy/reporting/
|
||||
Content-Security-Policy: script-src 'self' 'unsafe-inline'
|
||||
Content-Security-Policy-Report-Only: img-src 'none'; script-src 'self' 'unsafe-inline'; report-uri ../support/report.py?op=put&reportID={{$id}}
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<title>Cookies are not sent on cross origin violation reports</title>
|
||||
<!-- CSP headers
|
||||
Content-Security-Policy: script-src 'unsafe-inline' 'self'; img-src 'none'; report-uri http://{{domains[www1]}}:{{ports[http][0]}}/content-security-policy/support/report.py?op=put&reportID=$id
|
||||
-->
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var test = async_test("Image should not load");
|
||||
fetch(
|
||||
"/cookies/resources/set-cookie.py?name=cspViolationReportCookie1&path=" + encodeURIComponent("{{domains[www1]}}:{{ports[http][0]}}/"),
|
||||
{mode: 'no-cors', credentials: 'include'})
|
||||
.then(() => {
|
||||
// This image will generate a CSP violation report.
|
||||
const img = new Image();
|
||||
img.onerror = test.step_func_done();
|
||||
img.onload = test.unreached_func("Should not have loaded the image");
|
||||
|
||||
img.src = "../support/fail.png";
|
||||
document.body.appendChild(img);
|
||||
});
|
||||
</script>
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20%27none%27&noCookies=true'></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,6 @@
|
|||
Expires: Mon, 26 Jul 1997 05:00:00 GMT
|
||||
Cache-Control: no-store, no-cache, must-revalidate
|
||||
Cache-Control: post-check=0, pre-check=0, false
|
||||
Pragma: no-cache
|
||||
Set-Cookie: report-cross-origin-no-cookies={{$id:uuid()}}; Path=/content-security-policy/reporting/
|
||||
Content-Security-Policy: script-src 'unsafe-inline' 'self'; img-src 'none'; report-uri http://{{domains[www1]}}:{{ports[http][0]}}/content-security-policy/support/report.py?op=put&reportID={{$id}}
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<title>Test multiple violations cause multiple reports</title>
|
||||
<!-- CSP headers
|
||||
Content-Security-Policy-Report-Only: script-src 'unsafe-inline' 'self'; img-src 'none'; report-uri ../support/report.py?op=put&reportID={{$id}}
|
||||
-->
|
||||
</head>
|
||||
<body>
|
||||
<img src="../support/pass.png">
|
||||
<img src="../support/pass2.png">
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20%27none%27&reportCount=2'></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,6 @@
|
|||
Expires: Mon, 26 Jul 1997 05:00:00 GMT
|
||||
Cache-Control: no-store, no-cache, must-revalidate
|
||||
Cache-Control: post-check=0, pre-check=0, false
|
||||
Pragma: no-cache
|
||||
Set-Cookie: report-multiple-violations-01={{$id:uuid()}}; Path=/content-security-policy/reporting/
|
||||
Content-Security-Policy-Report-Only: script-src 'unsafe-inline' 'self'; img-src 'none'; report-uri ../support/report.py?op=put&reportID={{$id}}
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<title>This tests that multiple violations on a page trigger multiple reports
|
||||
if and only if the violations are distinct.</title>
|
||||
<!-- CSP headers
|
||||
Content-Security-Policy-Report-Only: script-src 'unsafe-inline' 'self'; report-uri ../support/report.py?op=put&reportID={{$id}}
|
||||
-->
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
for (var i = 0; i<5; i++)
|
||||
setTimeout("alert('PASS: setTimeout #" + i + " executed.');", 0);
|
||||
</script>
|
||||
<script async defer src='../support/checkReport.sub.js?reportField=violated-directive&reportValue=script-src%20%27unsafe-inline%27%20%27self%27&reportCount=1'></script>
|
||||
</body>
|
||||
</html>
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue