forked from mirrors/gecko-dev
Bug 1356225 - Update web-platform-tests to revision d519fe9011da7cfce7949f7ed826e9759dc5c532, a=testonly
MozReview-Commit-ID: GmGgeZxHy0j --HG-- rename : testing/web-platform/tests/content-security-policy/media-src/media-src-7_1_2.html.sub.headers => testing/web-platform/tests/content-security-policy/media-src/media-src-7_1_2.sub.html.sub.headers rename : testing/web-platform/tests/content-security-policy/media-src/media-src-7_2_2.html.sub.headers => testing/web-platform/tests/content-security-policy/media-src/media-src-7_2_2.sub.html.sub.headers rename : testing/web-platform/tests/content-security-policy/media-src/media-src-7_3_2.html.sub.headers => testing/web-platform/tests/content-security-policy/media-src/media-src-7_3_2.sub.html.sub.headers rename : testing/web-platform/tests/html/browsers/windows/nested-browsing-contexts/test.html => testing/web-platform/tests/html/browsers/windows/nested-browsing-contexts/resources/frameElement-nested-frame.html rename : testing/web-platform/tests/html/browsers/windows/nested-browsing-contexts/testcase3.html => testing/web-platform/tests/html/browsers/windows/nested-browsing-contexts/resources/frameElement-window-post.html rename : testing/web-platform/tests/presentation-api/controlling-ua/PresentationAvailability_onchange-manual.html => testing/web-platform/tests/presentation-api/controlling-ua/PresentationAvailability_onchange-manual.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/PresentationConnection_onmessage-manual.html => testing/web-platform/tests/presentation-api/controlling-ua/PresentationConnection_onmessage-manual.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/PresentationConnection_send-manual.html => testing/web-platform/tests/presentation-api/controlling-ua/PresentationConnection_send-manual.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/PresentationRequest_error.html => testing/web-platform/tests/presentation-api/controlling-ua/PresentationRequest_error.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/PresentationRequest_onconnectionavailable-manual.html => testing/web-platform/tests/presentation-api/controlling-ua/PresentationRequest_onconnectionavailable-manual.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/PresentationRequest_sandboxing_error.html => testing/web-platform/tests/presentation-api/controlling-ua/PresentationRequest_sandboxing_error.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/PresentationRequest_sandboxing_success.html => testing/web-platform/tests/presentation-api/controlling-ua/PresentationRequest_sandboxing_success.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/PresentationRequest_success.html => testing/web-platform/tests/presentation-api/controlling-ua/PresentationRequest_success.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/defaultRequest_success-manual.html => testing/web-platform/tests/presentation-api/controlling-ua/defaultRequest_success-manual.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/getAvailability.html => testing/web-platform/tests/presentation-api/controlling-ua/getAvailability.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/getAvailability_sandboxing_success.html => testing/web-platform/tests/presentation-api/controlling-ua/getAvailability_sandboxing_success.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/reconnectToPresentation_notfound_error.html => testing/web-platform/tests/presentation-api/controlling-ua/reconnectToPresentation_notfound_error.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/reconnectToPresentation_sandboxing_success.html => testing/web-platform/tests/presentation-api/controlling-ua/reconnectToPresentation_sandboxing_success.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/reconnectToPresentation_success-manual.html => testing/web-platform/tests/presentation-api/controlling-ua/reconnectToPresentation_success-manual.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/startNewPresentation_displaynotallowed-manual.html => testing/web-platform/tests/presentation-api/controlling-ua/startNewPresentation_displaynotallowed-manual.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/startNewPresentation_displaynotfound-manual.html => testing/web-platform/tests/presentation-api/controlling-ua/startNewPresentation_displaynotfound-manual.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/startNewPresentation_error.html => testing/web-platform/tests/presentation-api/controlling-ua/startNewPresentation_error.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/startNewPresentation_sandboxing_success-manual.html => testing/web-platform/tests/presentation-api/controlling-ua/startNewPresentation_sandboxing_success-manual.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/startNewPresentation_success-manual.html => testing/web-platform/tests/presentation-api/controlling-ua/startNewPresentation_success-manual.https.html rename : testing/web-platform/tests/presentation-api/controlling-ua/startNewPresentation_unsettledpromise-manual.html => testing/web-platform/tests/presentation-api/controlling-ua/startNewPresentation_unsettledpromise-manual.https.html rename : testing/web-platform/tests/presentation-api/receiving-ua/idlharness-manual.html => testing/web-platform/tests/presentation-api/receiving-ua/idlharness-manual.https.html rename : testing/web-platform/tests/presentation-api/receiving-ua/support/idlharness_receiving-ua.html => testing/web-platform/tests/presentation-api/receiving-ua/support/idlharness_receiving-ua.https.html rename : testing/web-platform/tests/webdriver/util/http_request.py => testing/web-platform/tests/webdriver/support/http_request.py
This commit is contained in:
parent
beabf923ac
commit
1325009ca4
924 changed files with 33612 additions and 6217 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -1,2 +1,2 @@
|
||||||
local: 5dc5249408ecc0003f0c68d32a8e782dec23fd36
|
local: 0000000000000000000000000000000000000000
|
||||||
upstream: aef9b4f327326fd32420281f9bc1ca9b60d553b3
|
upstream: 8181d7f09ee35cb521452bb727a48a1667901afd
|
||||||
|
|
|
||||||
6
testing/web-platform/tests/.gitmodules
vendored
6
testing/web-platform/tests/.gitmodules
vendored
|
|
@ -6,3 +6,9 @@
|
||||||
path = tools
|
path = tools
|
||||||
url = https://github.com/w3c/wpt-tools.git
|
url = https://github.com/w3c/wpt-tools.git
|
||||||
ignore = dirty
|
ignore = dirty
|
||||||
|
[submodule "css/tools/apiclient"]
|
||||||
|
path = css/tools/apiclient
|
||||||
|
url = https://github.com/w3c/csswg-apiclient.git
|
||||||
|
[submodule "css/tools/w3ctestlib"]
|
||||||
|
path = css/tools/w3ctestlib
|
||||||
|
url = https://github.com/w3c/csswg-w3ctestlib.git
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,18 @@ before_install:
|
||||||
install:
|
install:
|
||||||
- pip install -U setuptools
|
- pip install -U setuptools
|
||||||
- pip install -U requests
|
- pip install -U requests
|
||||||
|
env: # required at the top-level for allow_failures to work below
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: linux
|
- os: linux
|
||||||
python: "2.7"
|
python: "2.7"
|
||||||
env:
|
env: SCRIPT=ci_lint.sh
|
||||||
- SCRIPT=ci_lint.sh
|
|
||||||
- os: linux
|
- os: linux
|
||||||
python: "2.7"
|
python: "2.7"
|
||||||
env:
|
env: SCRIPT=ci_built_diff.sh
|
||||||
- SCRIPT=ci_built_diff.sh
|
- os: linux
|
||||||
|
python: "2.7"
|
||||||
|
env: SCRIPT=css/build-css-testsuites.sh
|
||||||
- os: linux
|
- os: linux
|
||||||
python: "2.7"
|
python: "2.7"
|
||||||
addons:
|
addons:
|
||||||
|
|
@ -34,8 +36,7 @@ matrix:
|
||||||
- libnss3-tools
|
- libnss3-tools
|
||||||
env:
|
env:
|
||||||
- secure: "YTSXPwI0DyCA1GhYrLT9KMEV6b7QQKuEeaQgeFDP38OTzJ1+cIj3CC4SRNqbnJ/6SJwPGcdqSxLuV8m4e5HFFnyCcQnJe6h8EMsTehZ7W3j/fP9UYrJqYqvGpe3Vj3xblO5pwBYmq7sg3jAmmuCgAgOW6VGf7cRMucrsmFeo7VM="
|
- secure: "YTSXPwI0DyCA1GhYrLT9KMEV6b7QQKuEeaQgeFDP38OTzJ1+cIj3CC4SRNqbnJ/6SJwPGcdqSxLuV8m4e5HFFnyCcQnJe6h8EMsTehZ7W3j/fP9UYrJqYqvGpe3Vj3xblO5pwBYmq7sg3jAmmuCgAgOW6VGf7cRMucrsmFeo7VM="
|
||||||
- SCRIPT=ci_stability.sh
|
- SCRIPT=ci_stability.sh PRODUCT=firefox:nightly
|
||||||
- PRODUCT=firefox:nightly
|
|
||||||
- os: linux
|
- os: linux
|
||||||
sudo: required
|
sudo: required
|
||||||
python: "2.7"
|
python: "2.7"
|
||||||
|
|
@ -46,8 +47,11 @@ matrix:
|
||||||
- fonts-liberation
|
- fonts-liberation
|
||||||
env:
|
env:
|
||||||
- secure: "YTSXPwI0DyCA1GhYrLT9KMEV6b7QQKuEeaQgeFDP38OTzJ1+cIj3CC4SRNqbnJ/6SJwPGcdqSxLuV8m4e5HFFnyCcQnJe6h8EMsTehZ7W3j/fP9UYrJqYqvGpe3Vj3xblO5pwBYmq7sg3jAmmuCgAgOW6VGf7cRMucrsmFeo7VM="
|
- secure: "YTSXPwI0DyCA1GhYrLT9KMEV6b7QQKuEeaQgeFDP38OTzJ1+cIj3CC4SRNqbnJ/6SJwPGcdqSxLuV8m4e5HFFnyCcQnJe6h8EMsTehZ7W3j/fP9UYrJqYqvGpe3Vj3xblO5pwBYmq7sg3jAmmuCgAgOW6VGf7cRMucrsmFeo7VM="
|
||||||
- SCRIPT=ci_stability.sh
|
- SCRIPT=ci_stability.sh PRODUCT=chrome:unstable
|
||||||
- PRODUCT=chrome:unstable
|
exclude:
|
||||||
|
- env: # exclude empty env from the top-level above
|
||||||
|
allow_failures:
|
||||||
|
- env: SCRIPT=css/build-css-testsuites.sh
|
||||||
script:
|
script:
|
||||||
- bash $SCRIPT
|
- bash $SCRIPT
|
||||||
cache:
|
cache:
|
||||||
|
|
|
||||||
58
testing/web-platform/tests/2dcontext/imagebitmap/common.js
Normal file
58
testing/web-platform/tests/2dcontext/imagebitmap/common.js
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
function testCanvasDisplayingPattern(canvas)
|
||||||
|
{
|
||||||
|
var tolerance = 5; // for creating ImageBitmap from a video, the tolerance needs to be high
|
||||||
|
_assertPixelApprox(canvas, 5,5, 255,0,0,255, "5,5", "255,0,0,255", tolerance);
|
||||||
|
_assertPixelApprox(canvas, 15,5, 0,255,0,255, "15,5", "0,255,0,255", tolerance);
|
||||||
|
_assertPixelApprox(canvas, 5,15, 0,0,255,255, "5,15", "0,0,255,255", tolerance);
|
||||||
|
_assertPixelApprox(canvas, 15,15, 0,0,0,255, "15,15", "0,0,0,255", tolerance);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testDrawImageBitmap(source)
|
||||||
|
{
|
||||||
|
var canvas = document.createElement("canvas");
|
||||||
|
canvas.width = 20;
|
||||||
|
canvas.height = 20;
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
return createImageBitmap(source).then(imageBitmap => {
|
||||||
|
ctx.drawImage(imageBitmap, 0, 0);
|
||||||
|
testCanvasDisplayingPattern(canvas);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function initializeTestCanvas(testCanvas)
|
||||||
|
{
|
||||||
|
testCanvas.width = 20;
|
||||||
|
testCanvas.height = 20;
|
||||||
|
var testCtx = testCanvas.getContext("2d");
|
||||||
|
testCtx.fillStyle = "rgb(255, 0, 0)";
|
||||||
|
testCtx.fillRect(0, 0, 10, 10);
|
||||||
|
testCtx.fillStyle = "rgb(0, 255, 0)";
|
||||||
|
testCtx.fillRect(10, 0, 10, 10);
|
||||||
|
testCtx.fillStyle = "rgb(0, 0, 255)";
|
||||||
|
testCtx.fillRect(0, 10, 10, 10);
|
||||||
|
testCtx.fillStyle = "rgb(0, 0, 0)";
|
||||||
|
testCtx.fillRect(10, 10, 10, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
function initializeImageData(imgData, width, height)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < width * height * 4; i+=4) {
|
||||||
|
imgData.data[i] = 0;
|
||||||
|
imgData.data[i + 1] = 0;
|
||||||
|
imgData.data[i + 2] = 0;
|
||||||
|
imgData.data[i + 3] = 255; //alpha channel: 255
|
||||||
|
}
|
||||||
|
var halfWidth = width/2;
|
||||||
|
var halfHeight = height/2;
|
||||||
|
// initialize to R, G, B, Black, with each one 10*10 pixels
|
||||||
|
for (var i = 0; i < halfHeight; i++)
|
||||||
|
for (var j = 0; j < halfWidth; j++)
|
||||||
|
imgData.data[i * width * 4 + j * 4] = 255;
|
||||||
|
for (var i = 0; i < halfHeight; i++)
|
||||||
|
for (var j = halfWidth; j < width; j++)
|
||||||
|
imgData.data[i * width * 4 + j * 4 + 1] = 255;
|
||||||
|
for (var i = halfHeight; i < height; i++)
|
||||||
|
for (var j = 0; j < halfWidth; j++)
|
||||||
|
imgData.data[i * width * 4 + j * 4 + 2] = 255;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<title>createImageBitmap + drawImage test</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/common/canvas-tests.js"></script>
|
||||||
|
<script src="common.js"></script>
|
||||||
|
<link rel="stylesheet" href="/common/canvas-tests.css">
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
promise_test(function() {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
var img = new Image();
|
||||||
|
img.onload = function() { resolve(img); };
|
||||||
|
img.src = "/images/pattern.png";
|
||||||
|
}).then(function(img) {
|
||||||
|
return testDrawImageBitmap(img);
|
||||||
|
});
|
||||||
|
}, "createImageBitmap from a HTMLImageElement, and drawImage on the created ImageBitmap");
|
||||||
|
|
||||||
|
promise_test(function() {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", '/images/pattern.png');
|
||||||
|
xhr.responseType = 'blob';
|
||||||
|
xhr.send();
|
||||||
|
xhr.onload = function() {
|
||||||
|
blob = xhr.response;
|
||||||
|
resolve(blob);
|
||||||
|
};
|
||||||
|
}).then(function(blob) {
|
||||||
|
return testDrawImageBitmap(blob);
|
||||||
|
});
|
||||||
|
}, "createImageBitmap from a Blob, and drawImage on the created ImageBitmap");
|
||||||
|
|
||||||
|
promise_test(function() {
|
||||||
|
var testCanvas = document.createElement("canvas");
|
||||||
|
initializeTestCanvas(testCanvas);
|
||||||
|
testDrawImageBitmap(testCanvas);
|
||||||
|
}, "createImageBitmap from a HTMLCanvasElement, and drawImage on the created ImageBitmap");
|
||||||
|
|
||||||
|
promise_test(function() {
|
||||||
|
var testCanvas = document.createElement("canvas");
|
||||||
|
initializeTestCanvas(testCanvas);
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
createImageBitmap(testCanvas).then(function(bitmap) {
|
||||||
|
resolve(bitmap);
|
||||||
|
});
|
||||||
|
}).then(function(bitmap) {
|
||||||
|
return testDrawImageBitmap(bitmap);
|
||||||
|
});
|
||||||
|
}, "createImageBitmap from an ImageBitmap, and drawImage on the created ImageBitmap");
|
||||||
|
|
||||||
|
promise_test(function() {
|
||||||
|
var imgData = new ImageData(20, 20);
|
||||||
|
initializeImageData(imgData, 20, 20);
|
||||||
|
return testDrawImageBitmap(imgData);
|
||||||
|
}, "createImageBitmap from an ImageData, and drawImage on the created ImageBitmap");
|
||||||
|
|
||||||
|
promise_test(function() {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
var video = document.createElement("video");
|
||||||
|
video.oncanplaythrough = function() {
|
||||||
|
resolve(video);
|
||||||
|
};
|
||||||
|
video.src = "/images/pattern.ogv";
|
||||||
|
}).then(function(video) {
|
||||||
|
return testDrawImageBitmap(video);
|
||||||
|
});
|
||||||
|
}, "createImageBitmap from a HTMLVideoElement, and drawImage on the created ImageBitmap");
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
|
<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
|
||||||
<title>Canvas test: 2d.imageData.create2.round</title>
|
<title>Canvas test: 2d.imageData.create2.double</title>
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="/common/canvas-tests.js"></script>
|
<script src="/common/canvas-tests.js"></script>
|
||||||
<link rel="stylesheet" href="/common/canvas-tests.css">
|
<link rel="stylesheet" href="/common/canvas-tests.css">
|
||||||
<body class="show_output">
|
<body class="show_output">
|
||||||
|
|
||||||
<h1>2d.imageData.create2.round</h1>
|
<h1>2d.imageData.create2.double</h1>
|
||||||
<p class="desc">createImageData(w, h) is rounded the same as getImageData(0, 0, w, h)</p>
|
<p class="desc">createImageData(w, h) double is converted to long</p>
|
||||||
|
|
||||||
|
|
||||||
<p class="output">Actual output:</p>
|
<p class="output">Actual output:</p>
|
||||||
|
|
@ -16,13 +16,15 @@
|
||||||
|
|
||||||
<ul id="d"></ul>
|
<ul id="d"></ul>
|
||||||
<script>
|
<script>
|
||||||
var t = async_test("createImageData(w, h) is rounded the same as getImageData(0, 0, w, h)");
|
var t = async_test("createImageData(w, h) double is converted to long");
|
||||||
_addTest(function(canvas, ctx) {
|
_addTest(function(canvas, ctx) {
|
||||||
|
|
||||||
var imgdata1 = ctx.createImageData(10.01, 10.99);
|
var imgdata1 = ctx.createImageData(10.01, 10.99);
|
||||||
var imgdata2 = ctx.getImageData(0, 0, 10.01, 10.99);
|
var imgdata2 = ctx.createImageData(-10.01, -10.99);
|
||||||
_assertSame(imgdata1.width, imgdata2.width, "imgdata1.width", "imgdata2.width");
|
_assertSame(imgdata1.width, 10, "imgdata1.width", "10");
|
||||||
_assertSame(imgdata1.height, imgdata2.height, "imgdata1.height", "imgdata2.height");
|
_assertSame(imgdata1.height, 10, "imgdata1.height", "10");
|
||||||
|
_assertSame(imgdata2.width, 10, "imgdata2.width", "10");
|
||||||
|
_assertSame(imgdata2.height, 10, "imgdata2.height", "10");
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
|
|
||||||
<title>Canvas test: 2d.imageData.create2.tiny</title>
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="/common/canvas-tests.js"></script>
|
|
||||||
<link rel="stylesheet" href="/common/canvas-tests.css">
|
|
||||||
<body class="show_output">
|
|
||||||
|
|
||||||
<h1>2d.imageData.create2.tiny</h1>
|
|
||||||
<p class="desc">createImageData(sw, sh) works for sizes smaller than one pixel</p>
|
|
||||||
|
|
||||||
|
|
||||||
<p class="output">Actual output:</p>
|
|
||||||
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
|
||||||
|
|
||||||
<ul id="d"></ul>
|
|
||||||
<script>
|
|
||||||
var t = async_test("createImageData(sw, sh) works for sizes smaller than one pixel");
|
|
||||||
_addTest(function(canvas, ctx) {
|
|
||||||
|
|
||||||
var imgdata = ctx.createImageData(0.0001, 0.0001);
|
|
||||||
_assertSame(imgdata.data.length, imgdata.width*imgdata.height*4, "imgdata.data.length", "imgdata.width*imgdata.height*4");
|
|
||||||
_assertSame(imgdata.width, 1, "imgdata.width", "1");
|
|
||||||
_assertSame(imgdata.height, 1, "imgdata.height", "1");
|
|
||||||
var isTransparentBlack = true;
|
|
||||||
for (var i = 0; i < imgdata.data.length; ++i)
|
|
||||||
if (imgdata.data[i] !== 0)
|
|
||||||
isTransparentBlack = false;
|
|
||||||
_assert(isTransparentBlack, "isTransparentBlack");
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
@ -22,6 +22,8 @@ _addTest(function(canvas, ctx) {
|
||||||
assert_throws("INDEX_SIZE_ERR", function() { ctx.createImageData(10, 0); });
|
assert_throws("INDEX_SIZE_ERR", function() { ctx.createImageData(10, 0); });
|
||||||
assert_throws("INDEX_SIZE_ERR", function() { ctx.createImageData(0, 10); });
|
assert_throws("INDEX_SIZE_ERR", function() { ctx.createImageData(0, 10); });
|
||||||
assert_throws("INDEX_SIZE_ERR", function() { ctx.createImageData(0, 0); });
|
assert_throws("INDEX_SIZE_ERR", function() { ctx.createImageData(0, 0); });
|
||||||
|
assert_throws("INDEX_SIZE_ERR", function() { ctx.createImageData(0.99, 10); });
|
||||||
|
assert_throws("INDEX_SIZE_ERR", function() { ctx.createImageData(10, 0.1); });
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
|
||||||
|
<title>Canvas test: 2d.imageData.get.double</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/common/canvas-tests.js"></script>
|
||||||
|
<link rel="stylesheet" href="/common/canvas-tests.css">
|
||||||
|
<body class="show_output">
|
||||||
|
|
||||||
|
<h1>2d.imageData.get.double</h1>
|
||||||
|
<p class="desc">createImageData(w, h) double is converted to long</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p class="output">Actual output:</p>
|
||||||
|
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||||
|
|
||||||
|
<ul id="d"></ul>
|
||||||
|
<script>
|
||||||
|
var t = async_test("createImageData(w, h) double is converted to long");
|
||||||
|
_addTest(function(canvas, ctx) {
|
||||||
|
|
||||||
|
var imgdata1 = ctx.getImageData(0, 0, 10.01, 10.99);
|
||||||
|
var imgdata2 = ctx.getImageData(0, 0, -10.01, -10.99);
|
||||||
|
_assertSame(imgdata1.width, 10, "imgdata1.width", "10");
|
||||||
|
_assertSame(imgdata1.height, 10, "imgdata1.height", "10");
|
||||||
|
_assertSame(imgdata2.width, 10, "imgdata2.width", "10");
|
||||||
|
_assertSame(imgdata2.height, 10, "imgdata2.height", "10");
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
@ -22,6 +22,10 @@ _addTest(function(canvas, ctx) {
|
||||||
assert_throws("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 10, 0); });
|
assert_throws("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 10, 0); });
|
||||||
assert_throws("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 0, 10); });
|
assert_throws("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 0, 10); });
|
||||||
assert_throws("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 0, 0); });
|
assert_throws("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 0, 0); });
|
||||||
|
assert_throws("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 0.1, 10); });
|
||||||
|
assert_throws("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 10, 0.99); });
|
||||||
|
assert_throws("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, -0.1, 10); });
|
||||||
|
assert_throws("INDEX_SIZE_ERR", function() { ctx.getImageData(1, 1, 10, -0.99); });
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
|
||||||
|
<title>Canvas test: 2d.imageData.object.ctor.array.bounds</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/common/canvas-tests.js"></script>
|
||||||
|
<link rel="stylesheet" href="/common/canvas-tests.css">
|
||||||
|
<body class="show_output">
|
||||||
|
|
||||||
|
<h1>2d.imageData.object.ctor.array.bounds</h1>
|
||||||
|
<p class="desc">ImageData has a usable constructor</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p class="output">Actual output:</p>
|
||||||
|
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||||
|
|
||||||
|
<ul id="d"></ul>
|
||||||
|
<script>
|
||||||
|
var t = async_test("ImageData has a usable constructor");
|
||||||
|
_addTest(function(canvas, ctx) {
|
||||||
|
|
||||||
|
_assertDifferent(window.ImageData, undefined, "window.ImageData", "undefined");
|
||||||
|
|
||||||
|
assert_throws("INVALID_STATE_ERR", function() { new ImageData(new Uint8ClampedArray(0), 1); });
|
||||||
|
assert_throws("INVALID_STATE_ERR", function() { new ImageData(new Uint8ClampedArray(3), 1); });
|
||||||
|
assert_throws("INDEX_SIZE_ERR", function() { new ImageData(new Uint8ClampedArray(4), 0); });
|
||||||
|
assert_throws("INDEX_SIZE_ERR", function() { new ImageData(new Uint8ClampedArray(4), 1, 2); });
|
||||||
|
assert_throws(new TypeError(), function() { new ImageData(new Uint8Array(8), 1, 2); });
|
||||||
|
assert_throws(new TypeError(), function() { new ImageData(new Int8Array(8), 1, 2); });
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
|
<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
|
||||||
<title>Canvas test: 2d.imageData.get.tiny</title>
|
<title>Canvas test: 2d.imageData.object.ctor.array</title>
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="/common/canvas-tests.js"></script>
|
<script src="/common/canvas-tests.js"></script>
|
||||||
<link rel="stylesheet" href="/common/canvas-tests.css">
|
<link rel="stylesheet" href="/common/canvas-tests.css">
|
||||||
<body class="show_output">
|
<body class="show_output">
|
||||||
|
|
||||||
<h1>2d.imageData.get.tiny</h1>
|
<h1>2d.imageData.object.ctor.array</h1>
|
||||||
<p class="desc">getImageData() works for sizes smaller than one pixel</p>
|
<p class="desc">ImageData has a usable constructor</p>
|
||||||
|
|
||||||
|
|
||||||
<p class="output">Actual output:</p>
|
<p class="output">Actual output:</p>
|
||||||
|
|
@ -16,13 +16,16 @@
|
||||||
|
|
||||||
<ul id="d"></ul>
|
<ul id="d"></ul>
|
||||||
<script>
|
<script>
|
||||||
var t = async_test("getImageData() works for sizes smaller than one pixel");
|
var t = async_test("ImageData has a usable constructor");
|
||||||
_addTest(function(canvas, ctx) {
|
_addTest(function(canvas, ctx) {
|
||||||
|
|
||||||
var imgdata = ctx.getImageData(0, 0, 0.0001, 0.0001);
|
_assertDifferent(window.ImageData, undefined, "window.ImageData", "undefined");
|
||||||
_assertSame(imgdata.data.length, imgdata.width*imgdata.height*4, "imgdata.data.length", "imgdata.width*imgdata.height*4");
|
|
||||||
|
var array = new Uint8ClampedArray(8);
|
||||||
|
var imgdata = new window.ImageData(array, 1, 2);
|
||||||
_assertSame(imgdata.width, 1, "imgdata.width", "1");
|
_assertSame(imgdata.width, 1, "imgdata.width", "1");
|
||||||
_assertSame(imgdata.height, 1, "imgdata.height", "1");
|
_assertSame(imgdata.height, 2, "imgdata.height", "2");
|
||||||
|
_assertSame(imgdata.data, array, "imgdata.data", "array");
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
|
<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
|
||||||
<title>Canvas test: 2d.imageData.object.ctor</title>
|
<title>Canvas test: 2d.imageData.object.ctor.size.bounds</title>
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="/common/canvas-tests.js"></script>
|
<script src="/common/canvas-tests.js"></script>
|
||||||
<link rel="stylesheet" href="/common/canvas-tests.css">
|
<link rel="stylesheet" href="/common/canvas-tests.css">
|
||||||
<body class="show_output">
|
<body class="show_output">
|
||||||
|
|
||||||
<h1>2d.imageData.object.ctor</h1>
|
<h1>2d.imageData.object.ctor.size.bounds</h1>
|
||||||
<p class="desc">ImageData does not have a usable constructor</p>
|
<p class="desc">ImageData has a usable constructor</p>
|
||||||
|
|
||||||
|
|
||||||
<p class="output">Actual output:</p>
|
<p class="output">Actual output:</p>
|
||||||
|
|
@ -16,11 +16,13 @@
|
||||||
|
|
||||||
<ul id="d"></ul>
|
<ul id="d"></ul>
|
||||||
<script>
|
<script>
|
||||||
var t = async_test("ImageData does not have a usable constructor");
|
var t = async_test("ImageData has a usable constructor");
|
||||||
_addTest(function(canvas, ctx) {
|
_addTest(function(canvas, ctx) {
|
||||||
|
|
||||||
_assertDifferent(window.ImageData, undefined, "window.ImageData", "undefined");
|
_assertDifferent(window.ImageData, undefined, "window.ImageData", "undefined");
|
||||||
assert_throws(new TypeError(), function() { new window.ImageData(1,1); });
|
assert_throws("INDEX_SIZE_ERR", function() { new window.ImageData(0, 0); });
|
||||||
|
assert_throws("INDEX_SIZE_ERR", function() { new window.ImageData(0, 1); });
|
||||||
|
assert_throws("INDEX_SIZE_ERR", function() { new window.ImageData(1, 0); });
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
|
||||||
|
<title>Canvas test: 2d.imageData.object.ctor.size</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/common/canvas-tests.js"></script>
|
||||||
|
<link rel="stylesheet" href="/common/canvas-tests.css">
|
||||||
|
<body class="show_output">
|
||||||
|
|
||||||
|
<h1>2d.imageData.object.ctor.size</h1>
|
||||||
|
<p class="desc">ImageData has a usable constructor</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p class="output">Actual output:</p>
|
||||||
|
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||||
|
|
||||||
|
<ul id="d"></ul>
|
||||||
|
<script>
|
||||||
|
var t = async_test("ImageData has a usable constructor");
|
||||||
|
_addTest(function(canvas, ctx) {
|
||||||
|
|
||||||
|
_assertDifferent(window.ImageData, undefined, "window.ImageData", "undefined");
|
||||||
|
|
||||||
|
var imgdata = new window.ImageData(2, 3);
|
||||||
|
_assertSame(imgdata.width, 2, "imgdata.width", "2");
|
||||||
|
_assertSame(imgdata.height, 3, "imgdata.height", "3");
|
||||||
|
_assertSame(imgdata.data.length, 2 * 3 * 4, "imgdata.data.length", "2 * 3 * 4");
|
||||||
|
for (var i = 0; i < imgdata.data.length; ++i) {
|
||||||
|
_assertSame(imgdata.data[i], 0, "imgdata.data[\""+(i)+"\"]", "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
@ -9276,22 +9276,6 @@
|
||||||
isTransparentBlack = false;
|
isTransparentBlack = false;
|
||||||
@assert isTransparentBlack;
|
@assert isTransparentBlack;
|
||||||
|
|
||||||
- name: 2d.imageData.create2.tiny
|
|
||||||
desc: createImageData(sw, sh) works for sizes smaller than one pixel
|
|
||||||
testing:
|
|
||||||
- 2d.imageData.create2.size
|
|
||||||
- 2d.imageData.one
|
|
||||||
code: |
|
|
||||||
var imgdata = ctx.createImageData(0.0001, 0.0001);
|
|
||||||
@assert imgdata.data.length === imgdata.width*imgdata.height*4;
|
|
||||||
@assert imgdata.width === 1;
|
|
||||||
@assert imgdata.height === 1;
|
|
||||||
var isTransparentBlack = true;
|
|
||||||
for (var i = 0; i < imgdata.data.length; ++i)
|
|
||||||
if (imgdata.data[i] !== 0)
|
|
||||||
isTransparentBlack = false;
|
|
||||||
@assert isTransparentBlack;
|
|
||||||
|
|
||||||
- name: 2d.imageData.create2.negative
|
- name: 2d.imageData.create2.negative
|
||||||
desc: createImageData(sw, sh) takes the absolute magnitude of the size arguments
|
desc: createImageData(sw, sh) takes the absolute magnitude of the size arguments
|
||||||
testing:
|
testing:
|
||||||
|
|
@ -9313,6 +9297,8 @@
|
||||||
@assert throws INDEX_SIZE_ERR ctx.createImageData(10, 0);
|
@assert throws INDEX_SIZE_ERR ctx.createImageData(10, 0);
|
||||||
@assert throws INDEX_SIZE_ERR ctx.createImageData(0, 10);
|
@assert throws INDEX_SIZE_ERR ctx.createImageData(0, 10);
|
||||||
@assert throws INDEX_SIZE_ERR ctx.createImageData(0, 0);
|
@assert throws INDEX_SIZE_ERR ctx.createImageData(0, 0);
|
||||||
|
@assert throws INDEX_SIZE_ERR ctx.createImageData(0.99, 10);
|
||||||
|
@assert throws INDEX_SIZE_ERR ctx.createImageData(10, 0.1);
|
||||||
|
|
||||||
- name: 2d.imageData.create2.nonfinite
|
- name: 2d.imageData.create2.nonfinite
|
||||||
desc: createImageData() throws TypeError if arguments are not finite
|
desc: createImageData() throws TypeError if arguments are not finite
|
||||||
|
|
@ -9333,15 +9319,17 @@
|
||||||
code: |
|
code: |
|
||||||
@assert throws TypeError ctx.createImageData(null);
|
@assert throws TypeError ctx.createImageData(null);
|
||||||
|
|
||||||
- name: 2d.imageData.create2.round
|
- name: 2d.imageData.create2.double
|
||||||
desc: createImageData(w, h) is rounded the same as getImageData(0, 0, w, h)
|
desc: createImageData(w, h) double is converted to long
|
||||||
testing:
|
testing:
|
||||||
- 2d.imageData.createround
|
- 2d.imageData.create2.size
|
||||||
code: |
|
code: |
|
||||||
var imgdata1 = ctx.createImageData(10.01, 10.99);
|
var imgdata1 = ctx.createImageData(10.01, 10.99);
|
||||||
var imgdata2 = ctx.getImageData(0, 0, 10.01, 10.99);
|
var imgdata2 = ctx.createImageData(-10.01, -10.99);
|
||||||
@assert imgdata1.width === imgdata2.width;
|
@assert imgdata1.width === 10;
|
||||||
@assert imgdata1.height === imgdata2.height;
|
@assert imgdata1.height === 10;
|
||||||
|
@assert imgdata2.width === 10;
|
||||||
|
@assert imgdata2.height === 10;
|
||||||
|
|
||||||
- name: 2d.imageData.get.basic
|
- name: 2d.imageData.get.basic
|
||||||
desc: getImageData() exists and returns something
|
desc: getImageData() exists and returns something
|
||||||
|
|
@ -9371,6 +9359,10 @@
|
||||||
@assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 10, 0);
|
@assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 10, 0);
|
||||||
@assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 0, 10);
|
@assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 0, 10);
|
||||||
@assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 0, 0);
|
@assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 0, 0);
|
||||||
|
@assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 0.1, 10);
|
||||||
|
@assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 10, 0.99);
|
||||||
|
@assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, -0.1, 10);
|
||||||
|
@assert throws INDEX_SIZE_ERR ctx.getImageData(1, 1, 10, -0.99);
|
||||||
|
|
||||||
- name: 2d.imageData.get.nonfinite
|
- name: 2d.imageData.get.nonfinite
|
||||||
desc: getImageData() throws TypeError if arguments are not finite
|
desc: getImageData() throws TypeError if arguments are not finite
|
||||||
|
|
@ -9488,15 +9480,17 @@
|
||||||
@assert imgdata2.width > imgdata1.width;
|
@assert imgdata2.width > imgdata1.width;
|
||||||
@assert imgdata2.height > imgdata1.height;
|
@assert imgdata2.height > imgdata1.height;
|
||||||
|
|
||||||
- name: 2d.imageData.get.tiny
|
- name: 2d.imageData.get.double
|
||||||
desc: getImageData() works for sizes smaller than one pixel
|
desc: createImageData(w, h) double is converted to long
|
||||||
testing:
|
testing:
|
||||||
- 2d.imageData.one
|
- 2d.imageData.get.basic
|
||||||
code: |
|
code: |
|
||||||
var imgdata = ctx.getImageData(0, 0, 0.0001, 0.0001);
|
var imgdata1 = ctx.getImageData(0, 0, 10.01, 10.99);
|
||||||
@assert imgdata.data.length === imgdata.width*imgdata.height*4;
|
var imgdata2 = ctx.getImageData(0, 0, -10.01, -10.99);
|
||||||
@assert imgdata.width === 1;
|
@assert imgdata1.width === 10;
|
||||||
@assert imgdata.height === 1;
|
@assert imgdata1.height === 10;
|
||||||
|
@assert imgdata2.width === 10;
|
||||||
|
@assert imgdata2.height === 10;
|
||||||
|
|
||||||
- name: 2d.imageData.get.nonpremul
|
- name: 2d.imageData.get.nonpremul
|
||||||
desc: getImageData() returns non-premultiplied colours
|
desc: getImageData() returns non-premultiplied colours
|
||||||
|
|
@ -9664,13 +9658,57 @@
|
||||||
@assert imgdata.data[2] === 0;
|
@assert imgdata.data[2] === 0;
|
||||||
@assert imgdata.data[3] === 0;
|
@assert imgdata.data[3] === 0;
|
||||||
|
|
||||||
- name: 2d.imageData.object.ctor
|
- name: 2d.imageData.object.ctor.size
|
||||||
desc: ImageData does not have a usable constructor
|
desc: ImageData has a usable constructor
|
||||||
testing:
|
testing:
|
||||||
- 2d.imageData.type
|
- 2d.imageData.type
|
||||||
code: |
|
code: |
|
||||||
@assert window.ImageData !== undefined;
|
@assert window.ImageData !== undefined;
|
||||||
@assert throws TypeError new window.ImageData(1,1);
|
|
||||||
|
var imgdata = new window.ImageData(2, 3);
|
||||||
|
@assert imgdata.width === 2;
|
||||||
|
@assert imgdata.height === 3;
|
||||||
|
@assert imgdata.data.length === 2 * 3 * 4;
|
||||||
|
for (var i = 0; i < imgdata.data.length; ++i) {
|
||||||
|
@assert imgdata.data[i] === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: 2d.imageData.object.ctor.size.bounds
|
||||||
|
desc: ImageData has a usable constructor
|
||||||
|
testing:
|
||||||
|
- 2d.imageData.type
|
||||||
|
code: |
|
||||||
|
@assert window.ImageData !== undefined;
|
||||||
|
@assert throws INDEX_SIZE_ERR new window.ImageData(0, 0);
|
||||||
|
@assert throws INDEX_SIZE_ERR new window.ImageData(0, 1);
|
||||||
|
@assert throws INDEX_SIZE_ERR new window.ImageData(1, 0);
|
||||||
|
|
||||||
|
- name: 2d.imageData.object.ctor.array
|
||||||
|
desc: ImageData has a usable constructor
|
||||||
|
testing:
|
||||||
|
- 2d.imageData.type
|
||||||
|
code: |
|
||||||
|
@assert window.ImageData !== undefined;
|
||||||
|
|
||||||
|
var array = new Uint8ClampedArray(8);
|
||||||
|
var imgdata = new window.ImageData(array, 1, 2);
|
||||||
|
@assert imgdata.width === 1;
|
||||||
|
@assert imgdata.height === 2;
|
||||||
|
@assert imgdata.data === array;
|
||||||
|
|
||||||
|
- name: 2d.imageData.object.ctor.array.bounds
|
||||||
|
desc: ImageData has a usable constructor
|
||||||
|
testing:
|
||||||
|
- 2d.imageData.type
|
||||||
|
code: |
|
||||||
|
@assert window.ImageData !== undefined;
|
||||||
|
|
||||||
|
@assert throws INVALID_STATE_ERR new ImageData(new Uint8ClampedArray(0), 1);
|
||||||
|
@assert throws INVALID_STATE_ERR new ImageData(new Uint8ClampedArray(3), 1);
|
||||||
|
@assert throws INDEX_SIZE_ERR new ImageData(new Uint8ClampedArray(4), 0);
|
||||||
|
@assert throws INDEX_SIZE_ERR new ImageData(new Uint8ClampedArray(4), 1, 2);
|
||||||
|
@assert throws TypeError new ImageData(new Uint8Array(8), 1, 2);
|
||||||
|
@assert throws TypeError new ImageData(new Int8Array(8), 1, 2);
|
||||||
|
|
||||||
- name: 2d.imageData.object.set
|
- name: 2d.imageData.object.set
|
||||||
desc: ImageData.data can be modified
|
desc: ImageData.data can be modified
|
||||||
|
|
|
||||||
|
|
@ -27,3 +27,8 @@ non-infringement, or title; nor that the contents of this repository are
|
||||||
suitable for any purpose. We make no representations, express or implied, that
|
suitable for any purpose. We make no representations, express or implied, that
|
||||||
the content of this repository or the use thereof indicates conformance to a
|
the content of this repository or the use thereof indicates conformance to a
|
||||||
specification. All content is provided as-is to help reach interoperability.
|
specification. All content is provided as-is to help reach interoperability.
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
-------------
|
||||||
|
|
||||||
|
See [web-platform-tests.org](http://web-platform-tests.org/).
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
<title>Historical features</title>
|
<title>Historical features</title>
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="log"></div>
|
<div id="log"></div>
|
||||||
|
|
@ -48,6 +49,10 @@
|
||||||
assert_false('isClosed' in b, 'isClosed in b');
|
assert_false('isClosed' in b, 'isClosed in b');
|
||||||
assert_false('isClosed' in Blob.prototype, 'isClosed in Blob.prototype');
|
assert_false('isClosed' in Blob.prototype, 'isClosed in Blob.prototype');
|
||||||
}, 'Blob.close() should not be supported');
|
}, 'Blob.close() should not be supported');
|
||||||
|
|
||||||
|
// Only add service worker test if service workers are actually supported.
|
||||||
|
if (navigator.serviceWorker)
|
||||||
|
service_worker_test('support/historical-serviceworker.js', 'Service worker test setup');
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
importScripts('/resources/testharness.js');
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
assert_false('FileReaderSync' in self);
|
||||||
|
}, '"FileReaderSync" should not be supported in service workers');
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
<meta charset=utf-8>
|
||||||
<title>IDBCursor direction - index with keyrange</title>
|
<title>IDBCursor direction - index with keyrange</title>
|
||||||
<link rel="author" href="mailto:odinho@opera.com" title="Odin Hørthe Omdal">
|
<link rel="author" href="mailto:odinho@opera.com" title="Odin Hørthe Omdal">
|
||||||
<link rel=help href="http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#cursor-iteration-operation">
|
<link rel=help href="http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#cursor-iteration-operation">
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
<meta charset=utf-8>
|
||||||
<title>IDBCursor direction - object store with keyrange</title>
|
<title>IDBCursor direction - object store with keyrange</title>
|
||||||
<link rel="author" href="mailto:odinho@opera.com" title="Odin Hørthe Omdal">
|
<link rel="author" href="mailto:odinho@opera.com" title="Odin Hørthe Omdal">
|
||||||
<link rel=help href="http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#cursor-iteration-operation">
|
<link rel=help href="http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#cursor-iteration-operation">
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>IndexedDB: Test IDBFactory open() error event properties</title>
|
||||||
|
<meta name=help href="https://w3c.github.io/IndexedDB/#dom-idbfactory-open">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="support.js"></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
async_test(t => {
|
||||||
|
const dbname = document.location + '-' + t.name;
|
||||||
|
indexedDB.deleteDatabase(dbname);
|
||||||
|
const open = indexedDB.open(dbname);
|
||||||
|
open.onsuccess = t.unreached_func('open should not succeed');
|
||||||
|
open.onupgradeneeded = t.step_func(() => {
|
||||||
|
const tx = open.transaction;
|
||||||
|
tx.abort();
|
||||||
|
});
|
||||||
|
open.onerror = t.step_func(e => {
|
||||||
|
assert_equals(e.target, open, 'event target should be request');
|
||||||
|
assert_equals(e.type, 'error', 'Event type should be error');
|
||||||
|
assert_true(e.bubbles, 'Event should bubble');
|
||||||
|
assert_true(e.cancelable, 'Event should be cancelable');
|
||||||
|
t.done();
|
||||||
|
});
|
||||||
|
}, 'Properties of error event from failed open()');
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>IDBObjectStore.createIndex() - AutoIncrement in Compound Index</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="support.js"></script>
|
||||||
|
<script>
|
||||||
|
indexeddb_test(
|
||||||
|
function(t, db, txn) {
|
||||||
|
// No auto-increment
|
||||||
|
var store = db.createObjectStore("Store1", {keyPath: "id"});
|
||||||
|
store.createIndex("CompoundKey", ["num", "id"]);
|
||||||
|
|
||||||
|
// Add data
|
||||||
|
store.put({id: 1, num: 100});
|
||||||
|
},
|
||||||
|
function(t, db) {
|
||||||
|
var store = db.transaction("Store1", "readwrite").objectStore("Store1");
|
||||||
|
|
||||||
|
store.openCursor().onsuccess = t.step_func(function(e) {
|
||||||
|
var item = e.target.result.value;
|
||||||
|
store.index("CompoundKey").get([item.num, item.id]).onsuccess = t.step_func(function(e) {
|
||||||
|
assert_equals(e.target.result ? e.target.result.num : null, 100, 'Expected 100.');
|
||||||
|
t.done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"Explicit Primary Key"
|
||||||
|
);
|
||||||
|
|
||||||
|
indexeddb_test(
|
||||||
|
function(t, db, txn) {
|
||||||
|
// Auto-increment
|
||||||
|
var store = db.createObjectStore("Store2", {keyPath: "id", autoIncrement: true});
|
||||||
|
store.createIndex("CompoundKey", ["num", "id"]);
|
||||||
|
|
||||||
|
// Add data
|
||||||
|
store.put({num: 100});
|
||||||
|
},
|
||||||
|
function(t, db) {
|
||||||
|
var store = db.transaction("Store2", "readwrite").objectStore("Store2");
|
||||||
|
store.openCursor().onsuccess = t.step_func(function(e) {
|
||||||
|
var item = e.target.result.value;
|
||||||
|
store.index("CompoundKey").get([item.num, item.id]).onsuccess = t.step_func(function(e) {
|
||||||
|
assert_equals(e.target.result ? e.target.result.num : null, 100, 'Expected 100.');
|
||||||
|
t.done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"Auto-Increment Primary Key"
|
||||||
|
);
|
||||||
|
</script>
|
||||||
196
testing/web-platform/tests/IndexedDB/interleaved-cursors.html
Normal file
196
testing/web-platform/tests/IndexedDB/interleaved-cursors.html
Normal file
|
|
@ -0,0 +1,196 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="timeout" content="long">
|
||||||
|
<title>IndexedDB: Interleaved iteration of multiple cursors</title>
|
||||||
|
<link rel="author" href="pwnall@chromium.org" title="Victor Costan">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="support-promises.js"></script>
|
||||||
|
<script>
|
||||||
|
// Number of objects that each iterator goes over.
|
||||||
|
const itemCount = 10;
|
||||||
|
|
||||||
|
// Ratio of small objects to large objects.
|
||||||
|
const largeObjectRatio = 5;
|
||||||
|
|
||||||
|
// Size of large objects. This should exceed the size of a block in the storage
|
||||||
|
// method underlying the browser's IndexedDB implementation. For example, this
|
||||||
|
// needs to exceed the LevelDB block size on Chrome, and the SQLite block size
|
||||||
|
// on Firefox.
|
||||||
|
const largeObjectSize = 48 * 1024;
|
||||||
|
|
||||||
|
function objectKey(cursorIndex, itemIndex) {
|
||||||
|
return `${cursorIndex}-key-${itemIndex}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function objectValue(cursorIndex, itemIndex) {
|
||||||
|
if ((cursorIndex * itemCount + itemIndex) % largeObjectRatio === 0) {
|
||||||
|
// We use a typed array (as opposed to a string) because IndexedDB
|
||||||
|
// implementations may serialize strings using UTF-8 or UTF-16, yielding
|
||||||
|
// larger IndexedDB entries than we'd expect. It's very unlikely that an
|
||||||
|
// IndexedDB implementation would use anything other than the raw buffer to
|
||||||
|
// serialize a typed array.
|
||||||
|
const buffer = new Uint8Array(largeObjectSize);
|
||||||
|
|
||||||
|
// Some IndexedDB implementations, like LevelDB, compress their data blocks
|
||||||
|
// before storing them to disk. We use a simple 32-bit xorshift PRNG, which
|
||||||
|
// should be sufficient to foil any fast generic-purpose compression scheme.
|
||||||
|
|
||||||
|
// 32-bit xorshift - the seed can't be zero
|
||||||
|
let state = 1000 + (cursorIndex * itemCount + itemIndex);
|
||||||
|
|
||||||
|
for (let i = 0; i < largeObjectSize; ++i) {
|
||||||
|
state ^= state << 13;
|
||||||
|
state ^= state >> 17;
|
||||||
|
state ^= state << 5;
|
||||||
|
buffer[i] = state & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
return [cursorIndex, 'small', itemIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writes the objects to be read by one cursor. Returns a promise that resolves
|
||||||
|
// when the write completes.
|
||||||
|
//
|
||||||
|
// We want to avoid creating a large transaction, because that is outside the
|
||||||
|
// test's scope, and it's a bad practice. So we break up the writes across
|
||||||
|
// multiple transactions. For simplicity, each transaction writes all the
|
||||||
|
// objects that will be read by a cursor.
|
||||||
|
function writeCursorObjects(database, cursorIndex) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const transaction = database.transaction('cache', 'readwrite');
|
||||||
|
transaction.onabort = () => { reject(transaction.error); };
|
||||||
|
|
||||||
|
const store = transaction.objectStore('cache');
|
||||||
|
for (let i = 0; i < itemCount; ++i) {
|
||||||
|
store.put({
|
||||||
|
key: objectKey(cursorIndex, i), value: objectValue(cursorIndex, i)});
|
||||||
|
}
|
||||||
|
transaction.oncomplete = resolve;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns a promise that resolves when the store has been populated.
|
||||||
|
function populateTestStore(testCase, database, cursorCount) {
|
||||||
|
let promiseChain = Promise.resolve();
|
||||||
|
|
||||||
|
for (let i = 0; i < cursorCount; ++i)
|
||||||
|
promiseChain = promiseChain.then(() => writeCursorObjects(database, i));
|
||||||
|
|
||||||
|
return promiseChain;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reads cursors in an interleaved fashion, as shown below.
|
||||||
|
//
|
||||||
|
// Given N cursors, each of which points to the beginning of a K-item sequence,
|
||||||
|
// the following accesses will be made.
|
||||||
|
//
|
||||||
|
// OC(i) = open cursor i
|
||||||
|
// RD(i, j) = read result of cursor i, which should be at item j
|
||||||
|
// CC(i) = continue cursor i
|
||||||
|
// | = wait for onsuccess on the previous OC or CC
|
||||||
|
//
|
||||||
|
// OC(1) | RD(1, 1) OC(2) | RD(2, 1) OC(3) | ... | RD(n-1, 1) CC(n) |
|
||||||
|
// RD(n, 1) CC(1) | RD(1, 2) CC(2) | RD(2, 2) CC(3) | ... | RD(n-1, 2) CC(n) |
|
||||||
|
// RD(n, 2) CC(1) | RD(1, 3) CC(2) | RD(2, 3) CC(3) | ... | RD(n-1, 3) CC(n) |
|
||||||
|
// ...
|
||||||
|
// RD(n, k-1) CC(1) | RD(1, k) CC(2) | RD(2, k) CC(3) | ... | RD(n-1, k) CC(n) |
|
||||||
|
// RD(n, k) done
|
||||||
|
function interleaveCursors(testCase, store, cursorCount) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// The cursors used for iteration are stored here so each cursor's onsuccess
|
||||||
|
// handler can call continue() on the next cursor.
|
||||||
|
const cursors = [];
|
||||||
|
|
||||||
|
// The results of IDBObjectStore.openCursor() calls are stored here so we
|
||||||
|
// we can change the requests' onsuccess handler after every
|
||||||
|
// IDBCursor.continue() call.
|
||||||
|
const requests = [];
|
||||||
|
|
||||||
|
const checkCursorState = (cursorIndex, itemIndex) => {
|
||||||
|
const cursor = cursors[cursorIndex];
|
||||||
|
assert_equals(cursor.key, objectKey(cursorIndex, itemIndex));
|
||||||
|
assert_equals(cursor.value.key, objectKey(cursorIndex, itemIndex));
|
||||||
|
assert_equals(
|
||||||
|
cursor.value.value.join('-'),
|
||||||
|
objectValue(cursorIndex, itemIndex).join('-'));
|
||||||
|
};
|
||||||
|
|
||||||
|
const openCursor = (cursorIndex, callback) => {
|
||||||
|
const request = store.openCursor(
|
||||||
|
IDBKeyRange.lowerBound(objectKey(cursorIndex, 0)));
|
||||||
|
requests[cursorIndex] = request;
|
||||||
|
|
||||||
|
request.onsuccess = testCase.step_func(() => {
|
||||||
|
const cursor = request.result;
|
||||||
|
cursors[cursorIndex] = cursor;
|
||||||
|
checkCursorState(cursorIndex, 0);
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
request.onerror = event => reject(request.error);
|
||||||
|
};
|
||||||
|
|
||||||
|
const readItemFromCursor = (cursorIndex, itemIndex, callback) => {
|
||||||
|
const request = requests[cursorIndex];
|
||||||
|
request.onsuccess = testCase.step_func(() => {
|
||||||
|
const cursor = request.result;
|
||||||
|
cursors[cursorIndex] = cursor;
|
||||||
|
checkCursorState(cursorIndex, itemIndex);
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
|
||||||
|
const cursor = cursors[cursorIndex];
|
||||||
|
cursor.continue();
|
||||||
|
};
|
||||||
|
|
||||||
|
// We open all the cursors one at a time, then cycle through the cursors and
|
||||||
|
// call continue() on each of them. This access pattern causes maximal
|
||||||
|
// trashing to an LRU cursor cache. Eviction scheme aside, any cache will
|
||||||
|
// have to evict some cursors, and this access pattern verifies that the
|
||||||
|
// cache correctly restores the state of evicted cursors.
|
||||||
|
const steps = [];
|
||||||
|
for (let cursorIndex = 0; cursorIndex < cursorCount; ++cursorIndex)
|
||||||
|
steps.push(openCursor.bind(null, cursorIndex));
|
||||||
|
for (let itemIndex = 1; itemIndex < itemCount; ++itemIndex) {
|
||||||
|
for (let cursorIndex = 0; cursorIndex < cursorCount; ++cursorIndex)
|
||||||
|
steps.push(readItemFromCursor.bind(null, cursorIndex, itemIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
const runStep = (stepIndex) => {
|
||||||
|
if (stepIndex === steps.length) {
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
steps[stepIndex](() => { runStep(stepIndex + 1); });
|
||||||
|
};
|
||||||
|
runStep(0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let cursorCount of [1, 10, 100, 500]) {
|
||||||
|
promise_test(testCase => {
|
||||||
|
return createDatabase(testCase, (database, transaction) => {
|
||||||
|
const store = database.createObjectStore('cache',
|
||||||
|
{ keyPath: 'key', autoIncrement: true });
|
||||||
|
}).then(database => {
|
||||||
|
return populateTestStore(testCase, database, cursorCount).then(
|
||||||
|
() => database);
|
||||||
|
}).then(database => {
|
||||||
|
database.close();
|
||||||
|
}).then(() => {
|
||||||
|
return openDatabase(testCase);
|
||||||
|
}).then(database => {
|
||||||
|
const transaction = database.transaction('cache', 'readonly');
|
||||||
|
transaction.onabort = () => { reject(transaction.error); };
|
||||||
|
|
||||||
|
const store = transaction.objectStore('cache');
|
||||||
|
return interleaveCursors(testCase, store, cursorCount).then(
|
||||||
|
() => database);
|
||||||
|
}).then(database => {
|
||||||
|
database.close();
|
||||||
|
});
|
||||||
|
}, `${cursorCount} cursors`);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="timeout" content="long">
|
||||||
|
<title>IndexedDB: Parallel iteration of cursors in upgradeneeded</title>
|
||||||
|
<link rel="author" href="pwnall@chromium.org" title="Victor Costan">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="support-promises.js"></script>
|
||||||
|
<script>
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
for (let cursorCount of [2, 10, 100, 1000, 10000]) {
|
||||||
|
promise_test(testCase => {
|
||||||
|
return createDatabase(testCase, (database, transaction) => {
|
||||||
|
const store = database.createObjectStore('cache', { keyPath: 'key' });
|
||||||
|
store.put({ key: '42' });
|
||||||
|
|
||||||
|
const promises = [];
|
||||||
|
|
||||||
|
for (let j = 0; j < 2; j += 1) {
|
||||||
|
const promise = new Promise((resolve, reject) => {
|
||||||
|
let request = null;
|
||||||
|
for (let i = 0; i < cursorCount / 2; i += 1) {
|
||||||
|
request = store.openCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
let continued = false;
|
||||||
|
request.onsuccess = testCase.step_func(() => {
|
||||||
|
const cursor = request.result;
|
||||||
|
|
||||||
|
if (!continued) {
|
||||||
|
assert_equals(cursor.key, '42');
|
||||||
|
assert_equals(cursor.value.key, '42');
|
||||||
|
continued = true;
|
||||||
|
cursor.continue();
|
||||||
|
} else {
|
||||||
|
assert_equals(cursor, null);
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
request.onerror = () => reject(request.error);
|
||||||
|
});
|
||||||
|
promises.push(promise);
|
||||||
|
}
|
||||||
|
return Promise.all(promises);
|
||||||
|
}).then(database => {
|
||||||
|
database.close();
|
||||||
|
});
|
||||||
|
}, `${cursorCount} cursors`);
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
@ -21,7 +21,7 @@ function requestWatcher(testCase, request) {
|
||||||
// open request.
|
// open request.
|
||||||
//
|
//
|
||||||
// Returns a promise. If the versionchange transaction goes through, the promise
|
// Returns a promise. If the versionchange transaction goes through, the promise
|
||||||
// resolves to an IndexedDB database that must be closed by the caller. If the
|
// resolves to an IndexedDB database that should be closed by the caller. If the
|
||||||
// versionchange transaction is aborted, the promise resolves to an error.
|
// versionchange transaction is aborted, the promise resolves to an error.
|
||||||
function migrateDatabase(testCase, newVersion, migrationCallback) {
|
function migrateDatabase(testCase, newVersion, migrationCallback) {
|
||||||
return migrateNamedDatabase(
|
return migrateNamedDatabase(
|
||||||
|
|
@ -37,7 +37,7 @@ function migrateDatabase(testCase, newVersion, migrationCallback) {
|
||||||
// open request.
|
// open request.
|
||||||
//
|
//
|
||||||
// Returns a promise. If the versionchange transaction goes through, the promise
|
// Returns a promise. If the versionchange transaction goes through, the promise
|
||||||
// resolves to an IndexedDB database that must be closed by the caller. If the
|
// resolves to an IndexedDB database that should be closed by the caller. If the
|
||||||
// versionchange transaction is aborted, the promise resolves to an error.
|
// versionchange transaction is aborted, the promise resolves to an error.
|
||||||
function migrateNamedDatabase(
|
function migrateNamedDatabase(
|
||||||
testCase, databaseName, newVersion, migrationCallback) {
|
testCase, databaseName, newVersion, migrationCallback) {
|
||||||
|
|
@ -88,10 +88,20 @@ function migrateNamedDatabase(
|
||||||
resolve(Promise.resolve(callbackResult).then(() => requestEventPromise));
|
resolve(Promise.resolve(callbackResult).then(() => requestEventPromise));
|
||||||
});
|
});
|
||||||
request.onerror = event => reject(event.target.error);
|
request.onerror = event => reject(event.target.error);
|
||||||
request.onsuccess = () => reject(new Error(
|
request.onsuccess = () => {
|
||||||
|
const database = request.result;
|
||||||
|
testCase.add_cleanup(() => { database.close(); });
|
||||||
|
reject(new Error(
|
||||||
'indexedDB.open should not succeed without creating a ' +
|
'indexedDB.open should not succeed without creating a ' +
|
||||||
'versionchange transaction'));
|
'versionchange transaction'));
|
||||||
}).then(event => event.target.result || event.target.error);
|
};
|
||||||
|
}).then(event => {
|
||||||
|
const database = event.target.result;
|
||||||
|
if (database) {
|
||||||
|
testCase.add_cleanup(() => { database.close(); });
|
||||||
|
}
|
||||||
|
return database || event.target.error;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an IndexedDB database whose name is unique for the test case.
|
// Creates an IndexedDB database whose name is unique for the test case.
|
||||||
|
|
@ -100,7 +110,7 @@ function migrateNamedDatabase(
|
||||||
// given the created database, the versionchange transaction, and the database
|
// given the created database, the versionchange transaction, and the database
|
||||||
// open request.
|
// open request.
|
||||||
//
|
//
|
||||||
// Returns a promise that resolves to an IndexedDB database. The caller must
|
// Returns a promise that resolves to an IndexedDB database. The caller should
|
||||||
// close the database.
|
// close the database.
|
||||||
function createDatabase(testCase, setupCallback) {
|
function createDatabase(testCase, setupCallback) {
|
||||||
return createNamedDatabase(testCase, databaseName(testCase), setupCallback);
|
return createNamedDatabase(testCase, databaseName(testCase), setupCallback);
|
||||||
|
|
@ -112,21 +122,23 @@ function createDatabase(testCase, setupCallback) {
|
||||||
// given the created database, the versionchange transaction, and the database
|
// given the created database, the versionchange transaction, and the database
|
||||||
// open request.
|
// open request.
|
||||||
//
|
//
|
||||||
// Returns a promise that resolves to an IndexedDB database. The caller must
|
// Returns a promise that resolves to an IndexedDB database. The caller should
|
||||||
// close the database.
|
// close the database.
|
||||||
function createNamedDatabase(testCase, databaseName, setupCallback) {
|
function createNamedDatabase(testCase, databaseName, setupCallback) {
|
||||||
const request = indexedDB.deleteDatabase(databaseName);
|
const request = indexedDB.deleteDatabase(databaseName);
|
||||||
const eventWatcher = requestWatcher(testCase, request);
|
const eventWatcher = requestWatcher(testCase, request);
|
||||||
|
|
||||||
return eventWatcher.wait_for('success').then(event =>
|
return eventWatcher.wait_for('success').then(event => {
|
||||||
migrateNamedDatabase(testCase, databaseName, 1, setupCallback));
|
testCase.add_cleanup(() => { indexedDB.deleteDatabase(databaseName); });
|
||||||
|
return migrateNamedDatabase(testCase, databaseName, 1, setupCallback)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opens an IndexedDB database without performing schema changes.
|
// Opens an IndexedDB database without performing schema changes.
|
||||||
//
|
//
|
||||||
// The given version number must match the database's current version.
|
// The given version number must match the database's current version.
|
||||||
//
|
//
|
||||||
// Returns a promise that resolves to an IndexedDB database. The caller must
|
// Returns a promise that resolves to an IndexedDB database. The caller should
|
||||||
// close the database.
|
// close the database.
|
||||||
function openDatabase(testCase, version) {
|
function openDatabase(testCase, version) {
|
||||||
return openNamedDatabase(testCase, databaseName(testCase), version);
|
return openNamedDatabase(testCase, databaseName(testCase), version);
|
||||||
|
|
@ -136,12 +148,16 @@ function openDatabase(testCase, version) {
|
||||||
//
|
//
|
||||||
// The given version number must match the database's current version.
|
// The given version number must match the database's current version.
|
||||||
//
|
//
|
||||||
// Returns a promise that resolves to an IndexedDB database. The caller must
|
// Returns a promise that resolves to an IndexedDB database. The caller should
|
||||||
// close the database.
|
// close the database.
|
||||||
function openNamedDatabase(testCase, databaseName, version) {
|
function openNamedDatabase(testCase, databaseName, version) {
|
||||||
const request = indexedDB.open(databaseName, version);
|
const request = indexedDB.open(databaseName, version);
|
||||||
const eventWatcher = requestWatcher(testCase, request);
|
const eventWatcher = requestWatcher(testCase, request);
|
||||||
return eventWatcher.wait_for('success').then(event => event.target.result);
|
return eventWatcher.wait_for('success').then(() => {
|
||||||
|
const database = request.result;
|
||||||
|
testCase.add_cleanup(() => { database.close(); });
|
||||||
|
return database;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// The data in the 'books' object store records in the first example of the
|
// The data in the 'books' object store records in the first example of the
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<title>IndexedDB: Test error events fired at requests from aborted transaction</title>
|
||||||
|
<meta name=help href="https://w3c.github.io/IndexedDB/#abort-a-transaction">
|
||||||
|
<meta name=help href="https://w3c.github.io/IndexedDB/#request-construct">
|
||||||
|
<meta name=help href="https://w3c.github.io/IndexedDB/#transaction-construct">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="support.js"></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
indexeddb_test(
|
||||||
|
(t, db) => {
|
||||||
|
db.createObjectStore('store');
|
||||||
|
},
|
||||||
|
(t, db) => {
|
||||||
|
const tx = db.transaction('store');
|
||||||
|
const request = tx.objectStore('store').get(0);
|
||||||
|
tx.abort();
|
||||||
|
request.onsuccess = t.unreached_func('request should not succeed');
|
||||||
|
|
||||||
|
let connection_saw_error = false;
|
||||||
|
let transaction_saw_error = false;
|
||||||
|
|
||||||
|
request.onerror = t.step_func(e => {
|
||||||
|
assert_equals(request.readyState, 'done',
|
||||||
|
'Request\'s done flag should be set');
|
||||||
|
assert_equals(request.result, undefined,
|
||||||
|
'Request\'s result should be undefined');
|
||||||
|
assert_equals(request.error.name, 'AbortError',
|
||||||
|
'Request\'s error should be AbortError');
|
||||||
|
|
||||||
|
assert_equals(e.target, request, 'event target should be request');
|
||||||
|
assert_equals(e.type, 'error', 'Event type should be error');
|
||||||
|
assert_true(e.bubbles, 'Event should bubble');
|
||||||
|
assert_true(e.cancelable, 'Event should cancelable');
|
||||||
|
|
||||||
|
assert_true(connection_saw_error,
|
||||||
|
'Event propagated through connection');
|
||||||
|
assert_true(transaction_saw_error,
|
||||||
|
'Event propagated through transaction');
|
||||||
|
t.done();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Event propagates via "get the parent" on request and transaction.
|
||||||
|
|
||||||
|
db.addEventListener('error', t.step_func(e => {
|
||||||
|
connection_saw_error = true;
|
||||||
|
assert_equals(e.target, request, 'event target should be request');
|
||||||
|
assert_equals(e.type, 'error', 'Event type should be error');
|
||||||
|
assert_true(e.bubbles, 'Event should bubble');
|
||||||
|
assert_true(e.cancelable, 'Event should cancelable');
|
||||||
|
}), true);
|
||||||
|
|
||||||
|
tx.addEventListener('error', t.step_func(e => {
|
||||||
|
transaction_saw_error = true;
|
||||||
|
assert_equals(e.target, request, 'event target should be request');
|
||||||
|
assert_equals(e.type, 'error', 'Event type should be error');
|
||||||
|
assert_true(e.bubbles, 'Event should bubble');
|
||||||
|
assert_true(e.cancelable, 'Event should cancelable');
|
||||||
|
|
||||||
|
assert_true(connection_saw_error,
|
||||||
|
'Event propagated through connection');
|
||||||
|
}), true);
|
||||||
|
},
|
||||||
|
'Properties of error events fired at requests when aborting a transaction');
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
@ -2,9 +2,7 @@ The web-platform-tests Project [](http://irc.w
|
||||||
==============================
|
==============================
|
||||||
|
|
||||||
The web-platform-tests Project is a W3C-coordinated attempt to build a
|
The web-platform-tests Project is a W3C-coordinated attempt to build a
|
||||||
cross-browser testsuite for the Web-platform stack. However, for mainly
|
cross-browser testsuite for the Web-platform stack. Writing tests in a way
|
||||||
historic reasons, the CSS WG testsuite is in a separate repository,
|
|
||||||
[csswg-test](https://github.com/w3c/csswg-test). Writing tests in a way
|
|
||||||
that allows them to be run in all browsers gives browser projects
|
that allows them to be run in all browsers gives browser projects
|
||||||
confidence that they are shipping software that is compatible with other
|
confidence that they are shipping software that is compatible with other
|
||||||
implementations, and that later implementations will be compatible with
|
implementations, and that later implementations will be compatible with
|
||||||
|
|
@ -110,41 +108,23 @@ Alternatively, you may also use
|
||||||
in the Windows 10 Anniversary Update build, then access your windows
|
in the Windows 10 Anniversary Update build, then access your windows
|
||||||
partition from there to launch wptserve.
|
partition from there to launch wptserve.
|
||||||
|
|
||||||
Test Runner
|
|
||||||
===========
|
|
||||||
|
|
||||||
There is a test runner that is designed to provide a
|
|
||||||
convenient way to run the web-platform-tests in-browser. It will run
|
|
||||||
testharness.js tests automatically but requires manual work for
|
|
||||||
reftests and manual tests.
|
|
||||||
|
|
||||||
The runner can be found at `/tools/runner/index.html` on the local
|
|
||||||
server i.e.
|
|
||||||
|
|
||||||
```
|
|
||||||
http://web-platform.test:8000/tools/runner/index.html
|
|
||||||
```
|
|
||||||
|
|
||||||
in the default configuration. The first time you use this it has to
|
|
||||||
generate a manifest of all tests. This may take some time, so please
|
|
||||||
be patient.
|
|
||||||
|
|
||||||
Publication
|
Publication
|
||||||
===========
|
===========
|
||||||
|
|
||||||
The master branch is automatically synced to http://w3c-test.org/.
|
The master branch is automatically synced to http://w3c-test.org/.
|
||||||
|
|
||||||
Pull requests are automatically mirrored to
|
Pull requests are
|
||||||
http://w3c-test.org/submissions/ a few minutes after someone with merge
|
[automatically mirrored](http://w3c-test.org/submissions/) except those
|
||||||
access has added a comment with "LGTM" (or "w3c-test:mirror") to indicate
|
that modify sensitive resources (such as `.py`). The latter require
|
||||||
the PR has been checked.
|
someone with merge access to comment with "LGTM" or "w3c-test:mirror" to
|
||||||
|
indicate the pull request has been checked.
|
||||||
|
|
||||||
Finding Things
|
Finding Things
|
||||||
==============
|
==============
|
||||||
|
|
||||||
Each top-level directory represents a W3C specification: the name
|
Each top-level directory matches the shortname used by a standard, with
|
||||||
matches the shortname used after the canonical address of the said
|
some exceptions. (Typically the shortname is from the standard's
|
||||||
specification under http://www.w3.org/TR/ .
|
corresponding GitHub repository.)
|
||||||
|
|
||||||
For some of the specifications, the tree under the top-level directory
|
For some of the specifications, the tree under the top-level directory
|
||||||
represents the sections of the respective documents, using the section
|
represents the sections of the respective documents, using the section
|
||||||
|
|
@ -185,6 +165,14 @@ The way to contribute is just as usual:
|
||||||
* Commit locally and push that to your repo.
|
* Commit locally and push that to your repo.
|
||||||
* Send in a pull request based on the above.
|
* Send in a pull request based on the above.
|
||||||
|
|
||||||
|
Issues with web-platform-tests
|
||||||
|
------------------------------
|
||||||
|
|
||||||
|
If you spot an issue with a test and are not comfortable providing a
|
||||||
|
pull request per above to fix it, please
|
||||||
|
[file a new issue](https://github.com/w3c/web-platform-tests/issues/new).
|
||||||
|
Thank you!
|
||||||
|
|
||||||
Lint tool
|
Lint tool
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
// Step 1.
|
||||||
|
test(function() {
|
||||||
|
assert_throws("TypeMismatchError", function() {
|
||||||
|
self.crypto.getRandomValues(new Float32Array(6))
|
||||||
|
}, "Float32Array")
|
||||||
|
assert_throws("TypeMismatchError", function() {
|
||||||
|
self.crypto.getRandomValues(new Float64Array(6))
|
||||||
|
}, "Float64Array")
|
||||||
|
|
||||||
|
assert_throws("TypeMismatchError", function() {
|
||||||
|
self.crypto.getRandomValues(new Float32Array(65537))
|
||||||
|
}, "Float32Array (too long)")
|
||||||
|
assert_throws("TypeMismatchError", function() {
|
||||||
|
self.crypto.getRandomValues(new Float64Array(65537))
|
||||||
|
}, "Float64Array (too long)")
|
||||||
|
}, "Float arrays")
|
||||||
|
|
||||||
|
var arrays = {
|
||||||
|
'Int8Array': Int8Array,
|
||||||
|
'Int16Array': Int16Array,
|
||||||
|
'Int32Array': Int32Array,
|
||||||
|
'Uint8Array': Uint8Array,
|
||||||
|
'Uint8ClampedArray': Uint8ClampedArray,
|
||||||
|
'Uint16Array': Uint16Array,
|
||||||
|
'Uint32Array': Uint32Array,
|
||||||
|
};
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
for (var array in arrays) {
|
||||||
|
assert_equals(self.crypto.getRandomValues(new arrays[array](8)).constructor,
|
||||||
|
arrays[array], "crypto.getRandomValues(new " + array + "(8))")
|
||||||
|
}
|
||||||
|
}, "Integer array")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
for (var array in arrays) {
|
||||||
|
var maxlength = 65536 / (arrays[array].BYTES_PER_ELEMENT);
|
||||||
|
assert_throws("QuotaExceededError", function() {
|
||||||
|
self.crypto.getRandomValues(new arrays[array](maxlength + 1))
|
||||||
|
}, "crypto.getRandomValues length over 65536")
|
||||||
|
}
|
||||||
|
}, "Large length")
|
||||||
|
|
||||||
|
test(function() {
|
||||||
|
for (var array in arrays) {
|
||||||
|
assert_true(self.crypto.getRandomValues(new arrays[array](0)).length == 0)
|
||||||
|
}
|
||||||
|
}, "Null arrays")
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
function run_test() {
|
|
||||||
// Step 1.
|
|
||||||
test(function() {
|
|
||||||
assert_throws("TypeMismatchError", function() {
|
|
||||||
self.crypto.getRandomValues(new Float32Array(6))
|
|
||||||
}, "Float32Array")
|
|
||||||
assert_throws("TypeMismatchError", function() {
|
|
||||||
self.crypto.getRandomValues(new Float64Array(6))
|
|
||||||
}, "Float64Array")
|
|
||||||
|
|
||||||
assert_throws("TypeMismatchError", function() {
|
|
||||||
self.crypto.getRandomValues(new Float32Array(65537))
|
|
||||||
}, "Float32Array (too long)")
|
|
||||||
assert_throws("TypeMismatchError", function() {
|
|
||||||
self.crypto.getRandomValues(new Float64Array(65537))
|
|
||||||
}, "Float64Array (too long)")
|
|
||||||
}, "Float arrays")
|
|
||||||
|
|
||||||
var arrays = {
|
|
||||||
'Int8Array': Int8Array,
|
|
||||||
'Int16Array': Int16Array,
|
|
||||||
'Int32Array': Int32Array,
|
|
||||||
'Uint8Array': Uint8Array,
|
|
||||||
'Uint8ClampedArray': Uint8ClampedArray,
|
|
||||||
'Uint16Array': Uint16Array,
|
|
||||||
'Uint32Array': Uint32Array,
|
|
||||||
};
|
|
||||||
|
|
||||||
test(function() {
|
|
||||||
for (var array in arrays) {
|
|
||||||
assert_equals(self.crypto.getRandomValues(new arrays[array](8)).constructor,
|
|
||||||
arrays[array], "crypto.getRandomValues(new " + array + "(8))")
|
|
||||||
}
|
|
||||||
}, "Integer array")
|
|
||||||
|
|
||||||
test(function() {
|
|
||||||
for (var array in arrays) {
|
|
||||||
var maxlength = 65536 / (arrays[array].BYTES_PER_ELEMENT);
|
|
||||||
assert_throws("QuotaExceededError", function() {
|
|
||||||
self.crypto.getRandomValues(new arrays[array](maxlength + 1))
|
|
||||||
}, "crypto.getRandomValues length over 65536")
|
|
||||||
}
|
|
||||||
}, "Large length")
|
|
||||||
|
|
||||||
test(function() {
|
|
||||||
for (var array in arrays) {
|
|
||||||
assert_true(self.crypto.getRandomValues(new arrays[array](0)).length == 0)
|
|
||||||
}
|
|
||||||
}, "Null arrays")
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
importScripts("/resources/testharness.js");
|
|
||||||
importScripts("getRandomValues.js");
|
|
||||||
run_test();
|
|
||||||
done();
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<meta charset=utf-8>
|
|
||||||
<title>WebCryptoAPI: getRandomValues()</title>
|
|
||||||
<link rel="author" title="Sunil Yoo" href="mailto:usuanday83@gmail.com">
|
|
||||||
<link rel="help" href="https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#dfn-Crypto-method-getRandomValues">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="getRandomValues.js"></script>
|
|
||||||
<div id="log"></div>
|
|
||||||
<script>
|
|
||||||
run_test();
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
|
<meta charset=utf-8>
|
||||||
<title>DOMException-throwing tests</title>
|
<title>DOMException-throwing tests</title>
|
||||||
<link rel=author title="Aryeh Gregor" href=ayg@aryeh.name>
|
<link rel=author title="Aryeh Gregor" href=ayg@aryeh.name>
|
||||||
<div id=log></div>
|
<div id=log></div>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ test(() => {
|
||||||
const client = new XMLHttpRequest
|
const client = new XMLHttpRequest
|
||||||
client.open("GET", "resources/header-content-length.asis", false)
|
client.open("GET", "resources/header-content-length.asis", false)
|
||||||
client.send()
|
client.send()
|
||||||
assert_equals(client.getAllResponseHeaders(), "CONTENT-LENGTH: 0\r\n")
|
assert_equals(client.getAllResponseHeaders(), "content-length: 0\r\n")
|
||||||
})
|
})
|
||||||
test(() => {
|
test(() => {
|
||||||
const client = new XMLHttpRequest
|
const client = new XMLHttpRequest
|
||||||
|
|
@ -17,11 +17,11 @@ test(() => {
|
||||||
client.setRequestHeader("content-TYPE", "x/x")
|
client.setRequestHeader("content-TYPE", "x/x")
|
||||||
client.send()
|
client.send()
|
||||||
assert_regexp_match(client.responseText, /content-TYPE/)
|
assert_regexp_match(client.responseText, /content-TYPE/)
|
||||||
assert_regexp_match(client.responseText, /THIS-IS-A-TEST: 1,/)
|
assert_regexp_match(client.responseText, /THIS-IS-A-TEST: 1, 2/)
|
||||||
})
|
})
|
||||||
promise_test(() => {
|
promise_test(() => {
|
||||||
return fetch("resources/echo-headers.py", {headers: [["THIS-is-A-test", 1], ["THIS-IS-A-TEST", 2]] }).then(res => res.text()).then(body => {
|
return fetch("resources/echo-headers.py", {headers: [["THIS-is-A-test", 1], ["THIS-IS-A-TEST", 2]] }).then(res => res.text()).then(body => {
|
||||||
assert_regexp_match(body, /THIS-is-A-test: 1/)
|
assert_regexp_match(body, /THIS-is-A-test: 1, 2/)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
<!doctype html>
|
||||||
|
<title>XMLHttpRequest: open() during abort event - abort() called from upload.onloadstart</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<script>
|
||||||
|
async_test(t => {
|
||||||
|
let client = new XMLHttpRequest(),
|
||||||
|
log = [],
|
||||||
|
lastTest = false,
|
||||||
|
expected = [
|
||||||
|
'readyState before abort() 1',
|
||||||
|
"upload.onabort - before open() 4",
|
||||||
|
"readyState after open() 1",
|
||||||
|
"client.onabort 1",
|
||||||
|
"client.onloadend 1",
|
||||||
|
"readyState after abort() 1",
|
||||||
|
"client.onload 4",
|
||||||
|
"client.onloadend 4"
|
||||||
|
]
|
||||||
|
|
||||||
|
client.upload.onloadstart = t.step_func(() => {
|
||||||
|
log.push('readyState before abort() '+client.readyState)
|
||||||
|
client.abort()
|
||||||
|
log.push('readyState after abort() '+client.readyState)
|
||||||
|
})
|
||||||
|
|
||||||
|
client.upload.onabort = t.step_func(() => {
|
||||||
|
log.push('upload.onabort - before open() ' + client.readyState)
|
||||||
|
client.open("GET", "resources/content.py")
|
||||||
|
log.push('readyState after open() ' + client.readyState)
|
||||||
|
client.send(null)
|
||||||
|
})
|
||||||
|
|
||||||
|
client.onabort = t.step_func(() => {
|
||||||
|
// happens immediately after all of upload.onabort, so readyState is 1
|
||||||
|
log.push('client.onabort ' + client.readyState)
|
||||||
|
})
|
||||||
|
|
||||||
|
client.onloadend = t.step_func(() => {
|
||||||
|
log.push('client.onloadend ' + client.readyState)
|
||||||
|
if(lastTest) {
|
||||||
|
assert_array_equals(log, expected)
|
||||||
|
t.done()
|
||||||
|
}
|
||||||
|
lastTest = true
|
||||||
|
})
|
||||||
|
|
||||||
|
client.onload = t.step_func(() => {
|
||||||
|
log.push('client.onload ' + client.readyState)
|
||||||
|
})
|
||||||
|
|
||||||
|
client.open("POST", "resources/content.py")
|
||||||
|
client.send("non-empty")
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
<!doctype html>
|
||||||
|
<title>XMLHttpRequest: open() during abort processing - abort() called from onloadstart</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<div id="log"></div>
|
||||||
|
<script>
|
||||||
|
async_test(t => {
|
||||||
|
let client = new XMLHttpRequest(),
|
||||||
|
test_state = 1,
|
||||||
|
log = [],
|
||||||
|
expected = [
|
||||||
|
"onloadstart readyState before abort() 1",
|
||||||
|
"onreadystatechange readyState before open() 4",
|
||||||
|
"onreadystatechange readyState after open() 1",
|
||||||
|
"onloadstart readyState 1",
|
||||||
|
"upload.onabort 1",
|
||||||
|
"upload.onloadend 1",
|
||||||
|
"client.onabort 1",
|
||||||
|
"readyState after abort() 1",
|
||||||
|
"client.onload 4"
|
||||||
|
]
|
||||||
|
|
||||||
|
client.onreadystatechange = t.step_func(() => {
|
||||||
|
if(test_state === 2){
|
||||||
|
test_state = 3
|
||||||
|
log.push('onreadystatechange readyState before open() ' + client.readyState)
|
||||||
|
client.open("GET", "resources/content.py")
|
||||||
|
log.push('onreadystatechange readyState after open() ' + client.readyState)
|
||||||
|
client.send(null)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
client.onloadstart = t.step_func(() => {
|
||||||
|
if(test_state === 1){
|
||||||
|
test_state = 2
|
||||||
|
log.push('onloadstart readyState before abort() ' + client.readyState)
|
||||||
|
client.abort()
|
||||||
|
log.push('readyState after abort() ' + client.readyState)
|
||||||
|
}else{
|
||||||
|
log.push('onloadstart readyState ' + client.readyState)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
client.upload.onabort = t.step_func(() => {
|
||||||
|
log.push('upload.onabort ' + client.readyState)
|
||||||
|
})
|
||||||
|
|
||||||
|
client.onabort = t.step_func(() => {
|
||||||
|
log.push('client.onabort ' + client.readyState)
|
||||||
|
})
|
||||||
|
|
||||||
|
client.upload.onloadend = t.step_func(() => {
|
||||||
|
log.push('upload.onloadend ' + client.readyState)
|
||||||
|
})
|
||||||
|
|
||||||
|
client.onload = t.step_func_done(() => {
|
||||||
|
log.push('client.onload ' + client.readyState)
|
||||||
|
assert_array_equals(log, expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
client.open("POST", "resources/content.py")
|
||||||
|
client.send('abcd')
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
@ -5,15 +5,14 @@
|
||||||
<title>XMLHttpRequest: redirected worker scripts, origin and referrer</title>
|
<title>XMLHttpRequest: redirected worker scripts, origin and referrer</title>
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::OL[1]/LI[3] following::OL[1]/LI[3]/ol[1]/li[1] following::OL[1]/LI[3]/ol[1]/li[2] following::OL[1]/LI[3]/ol[1]/li[3]" />
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="log"></div>
|
<div id="log"></div>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
var test = async_test() // This "test" does not actually do any assertations. It's just there to have multiple, separate, asyncronous sub-tests.
|
var test = async_test() // This "test" does not actually do any assertations. It's just there to have multiple, separate, asyncronous sub-tests.
|
||||||
var expectations = {
|
var expectations = {
|
||||||
'Referer header': 'referer: '+(location.href.replace(/[^/]*$/, ''))+"resources/workerxhr-origin-referrer.js\n",
|
'Referer header': 'Referer: '+(location.href.replace(/[^/]*$/, ''))+"resources/workerxhr-origin-referrer.js\n",
|
||||||
'Origin header': 'origin: '+location.protocol+'//'+location.hostname+((location.port === "")?"":":"+location.port)+'\n',
|
'Origin header': 'Origin: '+location.protocol+'//'+location.hostname+((location.port === "")?"":":"+location.port)+'\n',
|
||||||
'Request URL test' : (location.href.replace(/[^/]*$/, ''))+'resources/requri.py?full'
|
'Request URL test' : (location.href.replace(/[^/]*$/, ''))+'resources/requri.py?full'
|
||||||
}
|
}
|
||||||
// now start the worker
|
// now start the worker
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,8 @@ def main(request, response):
|
||||||
response.headers.set('Access-Control-Allow-Methods', 'GET');
|
response.headers.set('Access-Control-Allow-Methods', 'GET');
|
||||||
response.headers.set('Access-Control-Allow-Headers', 'authorization, x-user, x-pass');
|
response.headers.set('Access-Control-Allow-Headers', 'authorization, x-user, x-pass');
|
||||||
response.headers.set('Access-Control-Expose-Headers', 'x-challenge, xhr-user, ses-user');
|
response.headers.set('Access-Control-Expose-Headers', 'x-challenge, xhr-user, ses-user');
|
||||||
auth = imp.load_source("", os.path.join(os.path.abspath(os.curdir),
|
auth = imp.load_source("", os.path.abspath("XMLHttpRequest/resources/authentication.py"))
|
||||||
"XMLHttpRequest",
|
|
||||||
"resources",
|
|
||||||
"authentication.py"))
|
|
||||||
if request.method == "OPTIONS":
|
if request.method == "OPTIONS":
|
||||||
return ""
|
return ""
|
||||||
else:
|
else:
|
||||||
return auth.main(request, response)
|
return auth.main(request, response)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,27 @@ def main(request, response):
|
||||||
match = request.headers.get("If-None-Match", None)
|
match = request.headers.get("If-None-Match", None)
|
||||||
date = request.GET.first("date", "")
|
date = request.GET.first("date", "")
|
||||||
modified = request.headers.get("If-Modified-Since", None)
|
modified = request.headers.get("If-Modified-Since", None)
|
||||||
|
cors = request.GET.first("cors", None)
|
||||||
|
|
||||||
|
if request.method == "OPTIONS":
|
||||||
|
response.headers.set("Access-Control-Allow-Origin", "*")
|
||||||
|
response.headers.set("Access-Control-Allow-Headers", "IF-NONE-MATCH")
|
||||||
|
return ""
|
||||||
|
|
||||||
if tag:
|
if tag:
|
||||||
response.headers.set("ETag", '"%s"' % tag)
|
response.headers.set("ETag", '"%s"' % tag)
|
||||||
elif date:
|
elif date:
|
||||||
response.headers.set("Last-Modified", date)
|
response.headers.set("Last-Modified", date)
|
||||||
|
|
||||||
|
if cors:
|
||||||
|
response.headers.set("Access-Control-Allow-Origin", "*")
|
||||||
|
|
||||||
if ((match is not None and match == tag) or
|
if ((match is not None and match == tag) or
|
||||||
(modified is not None and modified == date)):
|
(modified is not None and modified == date)):
|
||||||
response.status = (304, "SUPERCOOL")
|
response.status = (304, "SUPERCOOL")
|
||||||
return ""
|
return ""
|
||||||
else:
|
else:
|
||||||
|
if not cors:
|
||||||
|
response.headers.set("Access-Control-Allow-Origin", "*")
|
||||||
response.headers.set("Content-Type", "text/plain")
|
response.headers.set("Content-Type", "text/plain")
|
||||||
return "MAYBE NOT"
|
return "MAYBE NOT"
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,9 @@ def main(request, response):
|
||||||
delay = int(request.GET.first("delay"))
|
delay = int(request.GET.first("delay"))
|
||||||
time.sleep(delay)
|
time.sleep(delay)
|
||||||
|
|
||||||
|
if "safelist_content_type" in request.GET:
|
||||||
|
headers.append(("Access-Control-Allow-Headers", "content-type"))
|
||||||
|
|
||||||
headers.append(("X-Request-Method", request.method))
|
headers.append(("X-Request-Method", request.method))
|
||||||
headers.append(("X-Request-Query", request.url_parts.query if request.url_parts.query else "NO"))
|
headers.append(("X-Request-Query", request.url_parts.query if request.url_parts.query else "NO"))
|
||||||
headers.append(("X-Request-Content-Length", request.headers.get("Content-Length", "NO")))
|
headers.append(("X-Request-Content-Length", request.headers.get("Content-Length", "NO")))
|
||||||
|
|
|
||||||
|
|
@ -3,4 +3,5 @@ import time
|
||||||
def main(request, response):
|
def main(request, response):
|
||||||
delay = float(request.GET.first("ms", 500))
|
delay = float(request.GET.first("ms", 500))
|
||||||
time.sleep(delay / 1E3);
|
time.sleep(delay / 1E3);
|
||||||
return [("Content-type", "text/plain")], "TEST_DELAY"
|
|
||||||
|
return [("Access-Control-Allow-Origin", "*"), ("Access-Control-Allow-Methods", "YO"), ("Content-type", "text/plain")], "TEST_DELAY"
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,14 @@
|
||||||
|
import time
|
||||||
|
|
||||||
def main(request, response):
|
def main(request, response):
|
||||||
code = int(request.GET.first("code", 302))
|
code = int(request.GET.first("code", 302))
|
||||||
location = request.GET.first("location", request.url_parts.path +"?followed")
|
location = request.GET.first("location", request.url_parts.path +"?followed")
|
||||||
|
|
||||||
if request.url.endswith("?followed"):
|
if "delay" in request.GET:
|
||||||
|
delay = float(request.GET.first("delay"))
|
||||||
|
time.sleep(delay / 1E3);
|
||||||
|
|
||||||
|
if "followed" in request.GET:
|
||||||
return [("Content:Type", "text/plain")], "MAGIC HAPPENED"
|
return [("Content:Type", "text/plain")], "MAGIC HAPPENED"
|
||||||
else:
|
else:
|
||||||
return (code, "WEBSRT MARKETING"), [("Location", location)], "TEST"
|
return (code, "WEBSRT MARKETING"), [("Location", location)], "TEST"
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,11 @@
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<script src="/common/utils.js"></script>
|
<script src="/common/utils.js"></script>
|
||||||
<!-- These spec references do not make much sense simply because the spec doesn't say very much about this.. -->
|
|
||||||
<link rel="help" href="https://xhr.spec.whatwg.org/#the-setrequestheader()-method" data-tested-assertations="following::ol[1]/li[6]" />
|
|
||||||
<link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following::code[contains(@title,'http-authorization')]/.." />
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="log"></div>
|
<div id="log"></div>
|
||||||
<script>
|
<script>
|
||||||
var test = async_test()
|
async_test(test => {
|
||||||
test.step(function() {
|
|
||||||
var client = new XMLHttpRequest(),
|
var client = new XMLHttpRequest(),
|
||||||
urlstart = location.host + location.pathname.replace(/\/[^\/]*$/, '/'),
|
urlstart = location.host + location.pathname.replace(/\/[^\/]*$/, '/'),
|
||||||
user = token()
|
user = token()
|
||||||
|
|
@ -22,15 +18,11 @@
|
||||||
client.setRequestHeader("x-user", user)
|
client.setRequestHeader("x-user", user)
|
||||||
client.setRequestHeader("x-pass", 'pass')
|
client.setRequestHeader("x-pass", 'pass')
|
||||||
client.setRequestHeader('Authorization', 'Basic ' + btoa(user + ":pass"))
|
client.setRequestHeader('Authorization', 'Basic ' + btoa(user + ":pass"))
|
||||||
client.onreadystatechange = function () {
|
client.onload = test.step_func_done(() => {
|
||||||
if (client.readyState < 4) {return}
|
assert_equals(client.responseText, user + '\npass', 'responseText should contain the right user and password')
|
||||||
test.step( function () {
|
|
||||||
assert_true(client.responseText == (user + '\npass'), 'responseText should contain the right user and password')
|
|
||||||
assert_equals(client.status, 200)
|
assert_equals(client.status, 200)
|
||||||
assert_equals(client.getResponseHeader('x-challenge'), 'DID-NOT')
|
assert_equals(client.getResponseHeader('x-challenge'), 'DID-NOT')
|
||||||
test.done()
|
|
||||||
})
|
})
|
||||||
}
|
|
||||||
client.send(null)
|
client.send(null)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
<!doctype html>
|
||||||
|
<title>XMLHttpRequest: send() - conditional cross-origin requests</title>
|
||||||
|
<script src=/resources/testharness.js></script>
|
||||||
|
<script src=/resources/testharnessreport.js></script>
|
||||||
|
<script src=/cors/support.js?pipe=sub></script>
|
||||||
|
<div id=log></div>
|
||||||
|
<script>
|
||||||
|
function request(withCORS, desc) {
|
||||||
|
async_test(t => {
|
||||||
|
const client = new XMLHttpRequest,
|
||||||
|
identifier = Math.random(),
|
||||||
|
cors = withCORS ? "&cors=yes" : "",
|
||||||
|
url = CROSSDOMAIN + "resources/conditional.py?tag=" + identifier + cors
|
||||||
|
client.onload = t.step_func(() => {
|
||||||
|
assert_equals(client.status, 200)
|
||||||
|
assert_equals(client.statusText, "OK")
|
||||||
|
assert_equals(client.responseText, "MAYBE NOT")
|
||||||
|
|
||||||
|
if(withCORS) {
|
||||||
|
client.onload = t.step_func_done(() => {
|
||||||
|
assert_equals(client.status, 304)
|
||||||
|
assert_equals(client.statusText, "SUPERCOOL")
|
||||||
|
assert_equals(client.responseText, "")
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
client.onload = null
|
||||||
|
client.onerror = t.step_func_done(() => {
|
||||||
|
assert_equals(client.status, 0)
|
||||||
|
assert_equals(client.statusText, "")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
client.open("GET", url)
|
||||||
|
client.setRequestHeader("If-None-Match", identifier)
|
||||||
|
client.send()
|
||||||
|
})
|
||||||
|
client.open("GET", url)
|
||||||
|
client.send()
|
||||||
|
}, desc)
|
||||||
|
}
|
||||||
|
request(false, "304 without appropriate CORS header")
|
||||||
|
request(true, "304 with appropriate CORS header")
|
||||||
|
</script>
|
||||||
|
|
@ -1,26 +1,26 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html>
|
<title>XMLHttpRequest: send() - Document with serialization errors</title>
|
||||||
<head>
|
|
||||||
<title>XMLHttpRequest: send() - unserializable Document</title>
|
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<link rel="help" href="https://xhr.spec.whatwg.org/#dom-XMLHttpRequest-send-document" data-tested-assertations="following::p[3]" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="log"></div>
|
<div id="log"></div>
|
||||||
<script>
|
<script>
|
||||||
function request_throws(input) {
|
function serialize(input, output) {
|
||||||
test(function() {
|
async_test(t => {
|
||||||
var client = new XMLHttpRequest()
|
const client = new XMLHttpRequest
|
||||||
client.open("POST", "resources/content.py", false)
|
client.open("POST", "resources/content.py")
|
||||||
assert_throws("InvalidStateError", function() { client.send(input) })
|
client.send(input)
|
||||||
|
client.onload = t.step_func_done(() => {
|
||||||
|
assert_equals(client.responseText, output)
|
||||||
})
|
})
|
||||||
|
}, "Serializing documents through XMLHttpRequest: '" + output + "'")
|
||||||
}
|
}
|
||||||
|
|
||||||
var doc = document.implementation.createDocument(null, null, null)
|
var doc = document.implementation.createDocument(null, null, null)
|
||||||
while(doc.childNodes.length) {
|
serialize(doc, "")
|
||||||
doc.removeChild(doc.childNodes[0])
|
doc.appendChild(doc.createElement("test:test"))
|
||||||
}
|
serialize(doc, "<test:test/>")
|
||||||
request_throws(doc)
|
doc.childNodes[0].setAttribute("test:test", "gee")
|
||||||
|
serialize(doc, "<test:test test:test=\"gee\"/>")
|
||||||
|
doc.childNodes[0].setAttribute("x", "\uD800")
|
||||||
|
serialize(doc, "<test:test test:test=\"gee\" x=\"\uFFFD\"/>")
|
||||||
</script>
|
</script>
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,6 @@
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<base>
|
<base>
|
||||||
<link rel="help" href="https://xhr.spec.whatwg.org/#cross-origin-request-steps" data-tested-assertations="/following::DL[2]/DT[1] /following::DL[2]/DD[1]" />
|
|
||||||
<link rel="help" href="https://xhr.spec.whatwg.org/#cross-origin-request-event-rules" data-tested-assertations="/following::DL[1]/DT[2] /following::DL[1]/DD[2]" />
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="log"></div>
|
<div id="log"></div>
|
||||||
|
|
@ -28,6 +26,8 @@
|
||||||
url(host_info.HTTP_REMOTE_ORIGIN)
|
url(host_info.HTTP_REMOTE_ORIGIN)
|
||||||
url("javascript:alert('FAIL')")
|
url("javascript:alert('FAIL')")
|
||||||
url("folder.txt")
|
url("folder.txt")
|
||||||
|
url("about:blank")
|
||||||
|
url("blob:bogusidentifier")
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
<title>XMLHttpRequest: send() - Redirect to CORS-enabled resource</title>
|
<title>XMLHttpRequest: send() - Redirect to CORS-enabled resource</title>
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<link rel="help" href="https://xhr.spec.whatwg.org/#infrastructure-for-the-send()-method" data-tested-assertations="following::dl[1]/dt[2] following::dl[1]/dd[2]/ol/li[1] following::dl[1]/dd[2]/ol/li[3]" />
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="log"></div>
|
<div id="log"></div>
|
||||||
|
|
@ -13,56 +12,76 @@
|
||||||
if (body === null) {
|
if (body === null) {
|
||||||
return { body: "", type: "NO" };
|
return { body: "", type: "NO" };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof body == "string") {
|
if (typeof body == "string") {
|
||||||
return { body: body, type: "text/plain;charset=UTF-8" };
|
return { body: body, type: "text/plain;charset=UTF-8" };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (body instanceof Uint8Array) {
|
if (body instanceof Uint8Array) {
|
||||||
var arr = Array.prototype.slice.call(body);
|
var arr = Array.prototype.slice.call(body);
|
||||||
return { body: String.fromCharCode.apply(null, arr), type: "NO" }
|
return { body: String.fromCharCode.apply(null, arr), type: "NO" }
|
||||||
}
|
}
|
||||||
|
return { body: "EXTRACT NOT IMPLEMENTED", type: "EXTRACT NOT IMPLEMENTED" }
|
||||||
return { body: "EXTRACT NOT IMPLEMENTED",
|
|
||||||
type: "EXTRACT NOT IMPLEMENTED" }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function redirect(code, name = code, method = "GET", body = null, setExplicitType = true) {
|
function redirect(code, name = code, method = "GET", body = null, explicitType = null, safelistContentType = false) {
|
||||||
var test = async_test(document.title + " (" + name + ")")
|
async_test(t => {
|
||||||
test.step(function() {
|
|
||||||
var client = new XMLHttpRequest()
|
var client = new XMLHttpRequest()
|
||||||
client.onreadystatechange = function() {
|
client.onreadystatechange = t.step_func(() => {
|
||||||
test.step(function() {
|
|
||||||
if (client.readyState == 4) {
|
if (client.readyState == 4) {
|
||||||
assert_equals(client.status, 200);
|
if (explicitType !== "application/x-pony" || safelistContentType) {
|
||||||
assert_equals(client.getResponseHeader("x-request-method"),
|
|
||||||
method);
|
|
||||||
var { body: expectedBody, type: expectedType } = extractBody(body);
|
var { body: expectedBody, type: expectedType } = extractBody(body);
|
||||||
if (setExplicitType) {
|
if (explicitType !== null) {
|
||||||
expectedType = "application/x-pony";
|
expectedType = explicitType
|
||||||
}
|
}
|
||||||
assert_equals(client.getResponseHeader("x-request-content-type"),
|
if (((code === "301" || code === "302") && method === "POST") || code === "303") {
|
||||||
expectedType);
|
method = "GET"
|
||||||
assert_equals(client.getResponseHeader("x-request-data"),
|
expectedBody = ""
|
||||||
expectedBody);
|
}
|
||||||
test.done();
|
assert_equals(client.status, 200);
|
||||||
|
assert_equals(client.getResponseHeader("x-request-method"), method);
|
||||||
|
assert_equals(client.getResponseHeader("x-request-content-type"), expectedType);
|
||||||
|
assert_equals(client.getResponseHeader("x-request-data"), expectedBody);
|
||||||
|
} else {
|
||||||
|
// "application/x-pony" is not safelisted by corsenabled.py -> network error
|
||||||
|
assert_equals(client.status, 0)
|
||||||
|
assert_equals(client.statusText, "")
|
||||||
|
assert_equals(client.responseText, "")
|
||||||
|
assert_equals(client.responseXML, null)
|
||||||
|
}
|
||||||
|
t.done();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
let safelist = ""
|
||||||
|
if (safelistContentType) {
|
||||||
|
safelist = "?safelist_content_type"
|
||||||
}
|
}
|
||||||
client.open(method, "resources/redirect.py?location="+encodeURIComponent("http://www2."+location.host+(location.pathname.replace(/[^\/]+$/, ''))+'resources/corsenabled.py')+"&code=" + code)
|
client.open(method, "resources/redirect.py?location="+encodeURIComponent("http://www2."+location.host+(location.pathname.replace(/[^\/]+$/, ''))+'resources/corsenabled.py')+safelist+"&code=" + code)
|
||||||
if (setExplicitType) {
|
if (explicitType !== null) {
|
||||||
client.setRequestHeader("Content-Type", "application/x-pony")
|
client.setRequestHeader("Content-Type", explicitType)
|
||||||
}
|
}
|
||||||
client.send(body)
|
client.send(body)
|
||||||
})
|
}, document.title + " (" + name + ")")
|
||||||
}
|
}
|
||||||
redirect("301")
|
redirect("301")
|
||||||
|
redirect("301", "301 GET with explicit Content-Type", "GET", null, "application/x-pony")
|
||||||
|
redirect("301", "301 GET with explicit Content-Type safelisted", "GET", null, "application/x-pony", true)
|
||||||
redirect("302")
|
redirect("302")
|
||||||
redirect("303")
|
redirect("303")
|
||||||
|
redirect("303", "303 LALA with string and explicit Content-Type safelisted", "LALA", "test", "application/x-pony", true)
|
||||||
redirect("307")
|
redirect("307")
|
||||||
redirect("307", "307 post with null", "POST", null, false);
|
redirect("307", "307 post with null", "POST", null)
|
||||||
redirect("307", "307 post with string", "POST", "hello", false);
|
redirect("307", "307 post with string", "POST", "hello")
|
||||||
redirect("307", "307 post with typed array", "POST", new Uint8Array([65, 66, 67]), false);
|
redirect("307", "307 post with typed array", "POST", new Uint8Array([65, 66, 67]))
|
||||||
|
redirect("301", "301 POST with string and explicit Content-Type", "POST", "yoyo", "application/x-pony")
|
||||||
|
redirect("301", "301 POST with string and explicit Content-Type safelisted", "POST", "yoyo", "application/x-pony", true)
|
||||||
|
redirect("302", "302 POST with string and explicit Content-Type", "POST", "yoyo", "application/x-pony")
|
||||||
|
redirect("307", "307 POST with string and explicit Content-Type", "POST", "yoyo", "application/x-pony")
|
||||||
|
redirect("307", "307 FOO with string and explicit Content-Type", "FOO", "yoyo", "application/x-pony")
|
||||||
|
redirect("308", "308 POST with string and explicit Content-Type", "POST", "yoyo", "application/x-pony")
|
||||||
|
redirect("308", "308 FOO with string and explicit Content-Type", "FOO", "yoyo", "application/x-pony")
|
||||||
|
redirect("308", "308 FOO with string and explicit Content-Type text/plain", "FOO", "yoyo", "text/plain")
|
||||||
|
redirect("308", "308 FOO with string and explicit Content-Type multipart/form-data", "FOO", "yoyo", "multipart/form-data")
|
||||||
|
redirect("308", "308 FOO with string and explicit Content-Type safelisted", "FOO", "yoyo", "application/thunderstorm", true)
|
||||||
|
redirect("307", "307 POST with string and explicit Content-Type safelisted", "POST", "yoyo", "application/thunderstorm", true)
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<!-- This behaviour is not explicitly spelled out in the spec.
|
|
||||||
It does say "queue tasks" under the "if the synchronous flag is unset" header in point 10 of the "send" algorithm.. -->
|
|
||||||
<link rel="help" href="https://xhr.spec.whatwg.org/#the-send()-method" data-tested-assertations="following-sibling::ol/li[10]/dl/dd/dl/dd[2]/p[3]" />
|
|
||||||
<script src="/resources/testharness.js"></script>
|
<script src="/resources/testharness.js"></script>
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
<title>XMLHttpRequest: sync requests should block events on pending async requests</title>
|
<title>XMLHttpRequest: sync requests should block events on pending async requests</title>
|
||||||
|
|
@ -22,7 +19,7 @@
|
||||||
{
|
{
|
||||||
var xhr_async = new XMLHttpRequest()
|
var xhr_async = new XMLHttpRequest()
|
||||||
xhr_async.open('GET', 'resources/delay.py?ms=1000', true) // first launch an async request, completes in 1 second
|
xhr_async.open('GET', 'resources/delay.py?ms=1000', true) // first launch an async request, completes in 1 second
|
||||||
xhr_async.onreadystatechange = t.step_func(() => {
|
xhr_async.onreadystatechange = test.step_func(() => {
|
||||||
actual.push('async ' + xhr_async.readyState)
|
actual.push('async ' + xhr_async.readyState)
|
||||||
if(xhr_async.readyState === 4 && actual.indexOf('sync 4')>-1){
|
if(xhr_async.readyState === 4 && actual.indexOf('sync 4')>-1){
|
||||||
VerifyResult()
|
VerifyResult()
|
||||||
|
|
@ -33,7 +30,7 @@
|
||||||
test.step_timeout(() => {
|
test.step_timeout(() => {
|
||||||
var xhr_sync = new XMLHttpRequest();
|
var xhr_sync = new XMLHttpRequest();
|
||||||
xhr_sync.open('GET', 'resources/delay.py?ms=2000', false) // here's a sync request that will take 2 seconds to finish
|
xhr_sync.open('GET', 'resources/delay.py?ms=2000', false) // here's a sync request that will take 2 seconds to finish
|
||||||
xhr_sync.onreadystatechange = t.step_func(() => {
|
xhr_sync.onreadystatechange = test.step_func(() => {
|
||||||
actual.push('sync ' + xhr_sync.readyState)
|
actual.push('sync ' + xhr_sync.readyState)
|
||||||
if(xhr_sync.readyState === 4 && actual.indexOf('async 4')>-1){
|
if(xhr_sync.readyState === 4 && actual.indexOf('async 4')>-1){
|
||||||
VerifyResult()
|
VerifyResult()
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ function encode(n) {
|
||||||
return "%" + (s.length === 2 ? s : '0' + s);
|
return "%" + (s.length === 2 ? s : '0' + s);
|
||||||
}
|
}
|
||||||
|
|
||||||
function run_test() {
|
|
||||||
var tests = [];
|
var tests = [];
|
||||||
var overall_test = async_test("Overall fetch with URLSearchParams");
|
var overall_test = async_test("Overall fetch with URLSearchParams");
|
||||||
for (var i = 0; i < NUM_TESTS; i++) {
|
for (var i = 0; i < NUM_TESTS; i++) {
|
||||||
|
|
@ -45,4 +44,3 @@ function run_test() {
|
||||||
usp.append("a" + i, String.fromCharCode(i));
|
usp.append("a" + i, String.fromCharCode(i));
|
||||||
}
|
}
|
||||||
x.send(usp)
|
x.send(usp)
|
||||||
}
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<meta charset=utf-8>
|
|
||||||
<title>XMLHttpRequest.send(URLSearchParams)</title>
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="send-usp.js"></script>
|
|
||||||
<div id="log"></div>
|
|
||||||
<script>
|
|
||||||
run_test();
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
importScripts("/resources/testharness.js");
|
|
||||||
importScripts("send-usp.js");
|
|
||||||
run_test();
|
|
||||||
done();
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<title>XMLHttpRequest: template element parsing</title>
|
<title>XMLHttpRequest: template element parsing</title>
|
||||||
<script src=/resources/testharness.js></script>
|
<script src=/resources/testharness.js></script>
|
||||||
<script src=/resources/testharnessreport.js></script>
|
<script src=/resources/testharnessreport.js></script>
|
||||||
<div id=log>
|
<div id=log></div>
|
||||||
<script>
|
<script>
|
||||||
async_test(t => {
|
async_test(t => {
|
||||||
const client = new XMLHttpRequest
|
const client = new XMLHttpRequest
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
<!doctype html>
|
||||||
|
<title>XMLHttpRequest: timeout, redirects, and CORS preflights</title>
|
||||||
|
<script src=/resources/testharness.js></script>
|
||||||
|
<script src=/resources/testharnessreport.js></script>
|
||||||
|
<script src=/common/get-host-info.sub.js></script>
|
||||||
|
<div id=log></div>
|
||||||
|
<script>
|
||||||
|
async_test(t => {
|
||||||
|
const client = new XMLHttpRequest
|
||||||
|
client.open("GET", "resources/redirect.py?delay=500&location=delay.py") // 500 + 500 = 1000
|
||||||
|
client.timeout = 1000
|
||||||
|
client.send()
|
||||||
|
client.ontimeout = t.step_func_done(() => {
|
||||||
|
assert_equals(client.readyState, 4)
|
||||||
|
})
|
||||||
|
client.onload = t.unreached_func("load event fired")
|
||||||
|
}, "Redirects should not reset the timer")
|
||||||
|
|
||||||
|
async_test(t => {
|
||||||
|
const client = new XMLHttpRequest
|
||||||
|
client.open("YO", get_host_info().HTTP_REMOTE_ORIGIN + "/XMLHttpRequest/resources/delay.py")
|
||||||
|
client.timeout = 1000
|
||||||
|
client.send()
|
||||||
|
client.ontimeout = t.step_func_done(() => {
|
||||||
|
assert_equals(client.readyState, 4)
|
||||||
|
})
|
||||||
|
client.onload = t.unreached_func("load event fired")
|
||||||
|
}, "CORS preflights should not reset the timer")
|
||||||
|
</script>
|
||||||
2
testing/web-platform/tests/background-fetch/OWNERS
Normal file
2
testing/web-platform/tests/background-fetch/OWNERS
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
@beverloo
|
||||||
|
@jakearchibald
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Background Fetch API IDL tests</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
|
||||||
|
|
||||||
|
<h1>idlharness test</h1>
|
||||||
|
<p>This test validates the WebIDL included in the Background Fetch API (Service Workers).</p>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
service_worker_test('interfaces.worker.js', 'Service Worker-scoped tests.');
|
||||||
|
</script>
|
||||||
26
testing/web-platform/tests/background-fetch/interfaces.html
Normal file
26
testing/web-platform/tests/background-fetch/interfaces.html
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Background Fetch API IDL tests</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/resources/WebIDLParser.js"></script>
|
||||||
|
<script src="/resources/idlharness.js"></script>
|
||||||
|
|
||||||
|
<h1>idlharness test</h1>
|
||||||
|
<p>This test validates the WebIDL included in the Background Fetch API (Documents).</p>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
promise_test(function() {
|
||||||
|
return fetch('interfaces.idl')
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(idls => {
|
||||||
|
var idlArray = new IdlArray();
|
||||||
|
idlArray.add_untested_idls('interface ServiceWorkerRegistration {};');
|
||||||
|
idlArray.add_untested_idls('[Exposed=ServiceWorker] interface ServiceWorkerGlobalScope {};');
|
||||||
|
idlArray.add_idls(idls);
|
||||||
|
idlArray.test();
|
||||||
|
});
|
||||||
|
}, 'Exposed interfaces in a Document.');
|
||||||
|
</script>
|
||||||
115
testing/web-platform/tests/background-fetch/interfaces.idl
Normal file
115
testing/web-platform/tests/background-fetch/interfaces.idl
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
// 3.1. Extensions to ServiceWorkerRegistration
|
||||||
|
|
||||||
|
partial interface ServiceWorkerRegistration {
|
||||||
|
readonly attribute BackgroundFetchManager backgroundFetch;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 3.2. BackgroundFetchManager
|
||||||
|
|
||||||
|
[Exposed=(Window,Worker)]
|
||||||
|
interface BackgroundFetchManager {
|
||||||
|
Promise<BackgroundFetchRegistration> fetch(DOMString tag, (RequestInfo or sequence<RequestInfo>) requests, optional BackgroundFetchOptions options);
|
||||||
|
Promise<BackgroundFetchRegistration?> get(DOMString tag);
|
||||||
|
Promise<FrozenArray<DOMString>> getTags();
|
||||||
|
// TODO: in future this should become an async iterator for BackgroundFetchRegistration objects
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary BackgroundFetchOptions {
|
||||||
|
sequence<IconDefinition> icons;
|
||||||
|
DOMString title;
|
||||||
|
long totalDownloadSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is taken from https://w3c.github.io/manifest/#icons-member.
|
||||||
|
// This definition should probably be moved somewhere more general.
|
||||||
|
dictionary IconDefinition {
|
||||||
|
DOMString src;
|
||||||
|
DOMString sizes;
|
||||||
|
DOMString type;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 3.3. BackgroundFetchRegistration
|
||||||
|
|
||||||
|
[Exposed=(Window,Worker)]
|
||||||
|
interface BackgroundFetchRegistration {
|
||||||
|
readonly attribute DOMString tag;
|
||||||
|
readonly attribute FrozenArray<IconDefinition> icons;
|
||||||
|
readonly attribute long totalDownloadSize;
|
||||||
|
readonly attribute DOMString title;
|
||||||
|
readonly attribute FrozenArray<BackgroundFetchActiveFetches> fetches;
|
||||||
|
|
||||||
|
void abort();
|
||||||
|
};
|
||||||
|
|
||||||
|
[Exposed=(Window,Worker)]
|
||||||
|
interface BackgroundFetchFetches {
|
||||||
|
readonly attribute Request request;
|
||||||
|
};
|
||||||
|
|
||||||
|
[Exposed=(Window,Worker)]
|
||||||
|
interface BackgroundFetchActiveFetches : BackgroundFetchFetches {
|
||||||
|
readonly attribute Promise<Response> responseReady;
|
||||||
|
// TODO: this will include fetch controller/observer objects
|
||||||
|
};
|
||||||
|
|
||||||
|
// 3.4. Events
|
||||||
|
|
||||||
|
partial interface ServiceWorkerGlobalScope {
|
||||||
|
attribute EventHandler onbackgroundfetched;
|
||||||
|
attribute EventHandler onbackgroundfetchfail;
|
||||||
|
attribute EventHandler onbackgroundfetchabort;
|
||||||
|
attribute EventHandler onbackgroundfetchclick;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 3.4.1. BackgroundFetchEvent
|
||||||
|
|
||||||
|
[Constructor(DOMString type, BackgroundFetchEventInit init), Exposed=ServiceWorker]
|
||||||
|
interface BackgroundFetchEvent : ExtendableEvent {
|
||||||
|
readonly attribute DOMString tag;
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary BackgroundFetchEventInit : ExtendableEventInit {
|
||||||
|
required DOMString tag;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 3.4.2. BackgroundFetchEndEvent
|
||||||
|
|
||||||
|
[Constructor(DOMString type, BackgroundFetchEndEventInit init), Exposed=ServiceWorker]
|
||||||
|
interface BackgroundFetchEndEvent : BackgroundFetchEvent {
|
||||||
|
readonly attribute FrozenArray<BackgroundFetchSettledFetches> completeFetches;
|
||||||
|
|
||||||
|
Promise<void> updateUI(DOMString title);
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary BackgroundFetchEndEventInit : BackgroundFetchEventInit {
|
||||||
|
required BackgroundFetchSettledFetches completeFetches;
|
||||||
|
};
|
||||||
|
|
||||||
|
[Exposed=ServiceWorker]
|
||||||
|
interface BackgroundFetchSettledFetches : BackgroundFetchFetches {
|
||||||
|
readonly attribute Response? response;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 3.4.3. BackgroundFetchFailEvent
|
||||||
|
|
||||||
|
[Constructor(DOMString type, BackgroundFetchEndEventInit init), Exposed=ServiceWorker]
|
||||||
|
interface BackgroundFetchFailEvent : BackgroundFetchEndEvent {
|
||||||
|
readonly attribute FrozenArray<BackgroundFetchSettledFetches> failedFetches;
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary BackgroundFetchFailEventInit : BackgroundFetchEndEventInit {
|
||||||
|
required BackgroundFetchSettledFetches failedFetches;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 3.4.4. BackgroundFetchClickEvent
|
||||||
|
|
||||||
|
[Constructor(DOMString type, BackgroundFetchEndEventInit init), Exposed=ServiceWorker]
|
||||||
|
interface BackgroundFetchClickEvent : BackgroundFetchEvent {
|
||||||
|
readonly attribute BackgroundFetchState state;
|
||||||
|
};
|
||||||
|
|
||||||
|
dictionary BackgroundFetchClickEventInit : BackgroundFetchEventInit {
|
||||||
|
required BackgroundFetchState state;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BackgroundFetchState { "pending", "succeeded", "failed" };
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
importScripts('/resources/testharness.js');
|
||||||
|
importScripts('/resources/WebIDLParser.js', '/resources/idlharness.js');
|
||||||
|
|
||||||
|
promise_test(function() {
|
||||||
|
return fetch('interfaces.idl')
|
||||||
|
.then(response => response.text())
|
||||||
|
.then(idls => {
|
||||||
|
var idlArray = new IdlArray();
|
||||||
|
idlArray.add_untested_idls('interface ServiceWorkerRegistration {};');
|
||||||
|
idlArray.add_untested_idls('[Exposed=ServiceWorker] interface ServiceWorkerGlobalScope {};');
|
||||||
|
idlArray.add_idls(idls);
|
||||||
|
idlArray.test();
|
||||||
|
});
|
||||||
|
}, 'Exposed interfaces in a Service Worker.');
|
||||||
|
|
@ -1,147 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
// Bluetooth UUID constants:
|
|
||||||
// Services:
|
|
||||||
var blocklist_test_service_uuid = "611c954a-263b-4f4a-aab6-01ddb953f985";
|
|
||||||
var request_disconnection_service_uuid = "01d7d889-7451-419f-aeb8-d65e7b9277af";
|
|
||||||
// Characteristics:
|
|
||||||
var blocklist_exclude_reads_characteristic_uuid = "bad1c9a2-9a5b-4015-8b60-1579bbbf2135";
|
|
||||||
var request_disconnection_characteristic_uuid = "01d7d88a-7451-419f-aeb8-d65e7b9277af";
|
|
||||||
// Descriptors:
|
|
||||||
var blocklist_exclude_reads_descriptor_uuid = "aaaaaaaa-aaaa-1181-0510-810819516110";
|
|
||||||
var blocklist_descriptor_uuid = "07711111-6104-0970-7011-1107105110aaa";
|
|
||||||
var characteristic_user_description_uuid = "00002901-0000-1000-8000-00805f9b34fb";
|
|
||||||
|
|
||||||
// Bluetooth Adapter types:
|
|
||||||
var adapter_type = {
|
|
||||||
not_present: 'NotPresentAdapter',
|
|
||||||
not_powered: 'NotPoweredAdapter',
|
|
||||||
empty: 'EmptyAdapter',
|
|
||||||
heart_rate: 'HeartRateAdapter',
|
|
||||||
two_heart_rate: 'TwoHeartRateServicesAdapter',
|
|
||||||
empty_name_heart_rate: 'EmptyNameHeartRateAdapter',
|
|
||||||
no_name_heart_rate: 'NoNameHeartRateAdapter',
|
|
||||||
glucose_heart_rate: 'GlucoseHeartRateAdapter',
|
|
||||||
unicode_device: 'UnicodeDeviceAdapter',
|
|
||||||
blocklist: 'BlocklistTestAdapter',
|
|
||||||
missing_characteristic_heart_rate: 'MissingCharacteristicHeartRateAdapter',
|
|
||||||
missing_service_heart_rate: 'MissingServiceHeartRateAdapter',
|
|
||||||
missing_descriptor_heart_rate: 'MissingDescriptorHeartRateAdapter'
|
|
||||||
};
|
|
||||||
|
|
||||||
var mock_device_name = {
|
|
||||||
heart_rate: 'Heart Rate Device',
|
|
||||||
glucose: 'Glucose Device'
|
|
||||||
};
|
|
||||||
|
|
||||||
var wrong = {
|
|
||||||
name: 'wrong_name',
|
|
||||||
service: 'wrong_service'
|
|
||||||
};
|
|
||||||
|
|
||||||
// Sometimes we need to test that using either the name, alias, or UUID
|
|
||||||
// produces the same result. The following objects help us do that.
|
|
||||||
var generic_access = {
|
|
||||||
alias: 0x1800,
|
|
||||||
name: 'generic_access',
|
|
||||||
uuid: '00001800-0000-1000-8000-00805f9b34fb'
|
|
||||||
};
|
|
||||||
|
|
||||||
var device_name = {
|
|
||||||
alias: 0x2a00,
|
|
||||||
name: 'gap.device_name',
|
|
||||||
uuid: '00002a00-0000-1000-8000-00805f9b34fb'
|
|
||||||
};
|
|
||||||
|
|
||||||
var reconnection_address = {
|
|
||||||
alias: 0x2a03,
|
|
||||||
name: 'gap.reconnection_address',
|
|
||||||
uuid: '00002a03-0000-1000-8000-00805f9b34fb'
|
|
||||||
};
|
|
||||||
|
|
||||||
var heart_rate = {
|
|
||||||
alias: 0x180d,
|
|
||||||
name: 'heart_rate',
|
|
||||||
uuid: '0000180d-0000-1000-8000-00805f9b34fb'
|
|
||||||
};
|
|
||||||
|
|
||||||
var heart_rate_measurement = {
|
|
||||||
alias: 0x2a37,
|
|
||||||
name: 'heart_rate_measurement',
|
|
||||||
uuid: '00002a37-0000-1000-8000-00805f9b34fb'
|
|
||||||
};
|
|
||||||
|
|
||||||
var body_sensor_location = {
|
|
||||||
alias: 0x2a38,
|
|
||||||
name: 'body_sensor_location',
|
|
||||||
uuid: '00002a38-0000-1000-8000-00805f9b34fb'
|
|
||||||
};
|
|
||||||
|
|
||||||
var glucose = {
|
|
||||||
alias: 0x1808,
|
|
||||||
name: 'glucose',
|
|
||||||
uuid: '00001808-0000-1000-8000-00805f9b34fb'
|
|
||||||
};
|
|
||||||
|
|
||||||
var battery_service = {
|
|
||||||
alias: 0x180f,
|
|
||||||
name: 'battery_service',
|
|
||||||
uuid: '0000180f-0000-1000-8000-00805f9b34fb'
|
|
||||||
};
|
|
||||||
|
|
||||||
var battery_level = {
|
|
||||||
alias: 0x2a19,
|
|
||||||
name: 'battery_level',
|
|
||||||
uuid: '00002a19-0000-1000-8000-00805f9b34fb'
|
|
||||||
};
|
|
||||||
|
|
||||||
var tx_power = {
|
|
||||||
alias: 0x1804,
|
|
||||||
name: 'tx_power',
|
|
||||||
uuid: '00001804-0000-1000-8000-00805f9b34fb'
|
|
||||||
};
|
|
||||||
|
|
||||||
var human_interface_device = {
|
|
||||||
alias: 0x1812,
|
|
||||||
name: 'human_interface_device',
|
|
||||||
uuid: '00001812-0000-1000-8000-00805f9b34fb'
|
|
||||||
};
|
|
||||||
|
|
||||||
var device_information = {
|
|
||||||
alias: 0x180a,
|
|
||||||
name: 'device_information',
|
|
||||||
uuid: '0000180a-0000-1000-8000-00805f9b34fb'
|
|
||||||
};
|
|
||||||
|
|
||||||
var peripherial_privacy_flag = {
|
|
||||||
alias: 0x2a02,
|
|
||||||
name: 'gap.peripheral_privacy_flag',
|
|
||||||
uuid: '00002a02-0000-1000-8000-00805f9b34fb'
|
|
||||||
};
|
|
||||||
|
|
||||||
var serial_number_string = {
|
|
||||||
alias: 0x2a25,
|
|
||||||
name: 'serial_number_string',
|
|
||||||
uuid: '00002a25-0000-1000-8000-00805f9b34fb'
|
|
||||||
};
|
|
||||||
|
|
||||||
var client_characteristic_configuration = {
|
|
||||||
alias: 0x2902,
|
|
||||||
name: 'gatt.client_characteristic_configuration',
|
|
||||||
uuid: '00002902-0000-1000-8000-00805f9b34fb'
|
|
||||||
};
|
|
||||||
|
|
||||||
var number_of_digitals = {
|
|
||||||
alias: 0x2909,
|
|
||||||
name: 'number_of_digitals',
|
|
||||||
uuid: '00002909-0000-1000-8000-00805f9b34fb'
|
|
||||||
};
|
|
||||||
|
|
||||||
// Helper function for converting strings to an array of bytes.
|
|
||||||
function asciiToDecimal(bytestr) {
|
|
||||||
var result = [];
|
|
||||||
for(var i = 0; i < bytestr.length; i++) {
|
|
||||||
result[i] = bytestr.charCodeAt(i) ;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
19
testing/web-platform/tests/bluetooth/idl-Bluetooth.html
Normal file
19
testing/web-platform/tests/bluetooth/idl-Bluetooth.html
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<title>Bluetooth interface</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
assert_throws(null, () => new Bluetooth(),
|
||||||
|
'the constructor should not be callable with "new"');
|
||||||
|
assert_throws(null, () => Bluetooth(),
|
||||||
|
'the constructor should not be callable');
|
||||||
|
|
||||||
|
// Bluetooth implements BluetoothDiscovery;
|
||||||
|
assert_true('requestDevice' in navigator.bluetooth);
|
||||||
|
assert_equals(navigator.bluetooth.requestDevice.length, 0);
|
||||||
|
}, 'Bluetooth IDL test');
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
@ -311,7 +311,8 @@ def get_git_cmd(repo_path):
|
||||||
def git(cmd, *args):
|
def git(cmd, *args):
|
||||||
full_cmd = ["git", cmd] + list(args)
|
full_cmd = ["git", cmd] + list(args)
|
||||||
try:
|
try:
|
||||||
return subprocess.check_output(full_cmd, cwd=repo_path, stderr=subprocess.STDOUT)
|
logger.debug(" ".join(full_cmd))
|
||||||
|
return subprocess.check_output(full_cmd, cwd=repo_path, stderr=subprocess.STDOUT).strip()
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
logger.error("Git command exited with status %i" % e.returncode)
|
logger.error("Git command exited with status %i" % e.returncode)
|
||||||
logger.error(e.output)
|
logger.error(e.output)
|
||||||
|
|
@ -363,10 +364,9 @@ class pwd(object):
|
||||||
self.old_dir = None
|
self.old_dir = None
|
||||||
|
|
||||||
|
|
||||||
def fetch_wpt_master(user):
|
def fetch_wpt(user, *args):
|
||||||
"""Fetch the master branch via git."""
|
|
||||||
git = get_git_cmd(wpt_root)
|
git = get_git_cmd(wpt_root)
|
||||||
git("fetch", "https://github.com/%s/web-platform-tests.git" % user, "master:master")
|
git("fetch", "https://github.com/%s/web-platform-tests.git" % user, *args)
|
||||||
|
|
||||||
|
|
||||||
def get_sha1():
|
def get_sha1():
|
||||||
|
|
@ -390,12 +390,44 @@ def install_wptrunner():
|
||||||
call("pip", "install", wptrunner_root)
|
call("pip", "install", wptrunner_root)
|
||||||
|
|
||||||
|
|
||||||
def get_files_changed():
|
def get_branch_point(user):
|
||||||
|
git = get_git_cmd(wpt_root)
|
||||||
|
if os.environ.get("TRAVIS_PULL_REQUEST", "false") != "false":
|
||||||
|
# This is a PR, so the base branch is in TRAVIS_BRANCH
|
||||||
|
branch_point = os.environ.get("TRAVIS_COMMIT_RANGE").split(".", 1)[0]
|
||||||
|
branch_point = git("rev-parse", branch_point)
|
||||||
|
else:
|
||||||
|
# Otherwise we aren't on a PR, so we try to find commits that are only in the
|
||||||
|
# current branch c.f.
|
||||||
|
# http://stackoverflow.com/questions/13460152/find-first-ancestor-commit-in-another-branch
|
||||||
|
head = git("rev-parse", "HEAD")
|
||||||
|
# To do this we need all the commits in the local copy
|
||||||
|
fetch_wpt(user, "--unshallow", "+refs/heads/*:refs/remotes/origin/*")
|
||||||
|
not_heads = [item for item in git("rev-parse", "--not", "--all").split("\n")
|
||||||
|
if not head in item]
|
||||||
|
commits = git("rev-list", "HEAD", *not_heads).split("\n")
|
||||||
|
first_commit = commits[-1]
|
||||||
|
branch_point = git("rev-parse", first_commit + "^")
|
||||||
|
# The above can produce a too-early commit if we are e.g. on master and there are
|
||||||
|
# preceding changes that were rebased and so aren't on any other branch. To avoid
|
||||||
|
# this issue we check for the later of the above branch point and the merge-base
|
||||||
|
# with master
|
||||||
|
merge_base = git("merge-base", "HEAD", "origin/master")
|
||||||
|
if (branch_point != merge_base and
|
||||||
|
not git("log", "--oneline", "%s..%s" % (merge_base, branch_point)).strip()):
|
||||||
|
logger.debug("Using merge-base as the branch point")
|
||||||
|
branch_point = merge_base
|
||||||
|
else:
|
||||||
|
logger.debug("Using first commit on another branch as the branch point")
|
||||||
|
|
||||||
|
logger.debug("Branch point from master: %s" % branch_point)
|
||||||
|
return branch_point
|
||||||
|
|
||||||
|
|
||||||
|
def get_files_changed(branch_point):
|
||||||
"""Get and return files changed since current branch diverged from master."""
|
"""Get and return files changed since current branch diverged from master."""
|
||||||
root = os.path.abspath(os.curdir)
|
root = os.path.abspath(os.curdir)
|
||||||
git = get_git_cmd(wpt_root)
|
git = get_git_cmd(wpt_root)
|
||||||
branch_point = git("merge-base", "HEAD", "master").strip()
|
|
||||||
logger.debug("Branch point from master: %s" % branch_point)
|
|
||||||
files = git("diff", "--name-only", "-z", "%s.." % branch_point)
|
files = git("diff", "--name-only", "-z", "%s.." % branch_point)
|
||||||
if not files:
|
if not files:
|
||||||
return []
|
return []
|
||||||
|
|
@ -557,7 +589,7 @@ def process_results(log, iterations):
|
||||||
results = handler.results
|
results = handler.results
|
||||||
for test_name, test in results.iteritems():
|
for test_name, test in results.iteritems():
|
||||||
if is_inconsistent(test["status"], iterations):
|
if is_inconsistent(test["status"], iterations):
|
||||||
inconsistent.append((test_name, None, test["status"], None))
|
inconsistent.append((test_name, None, test["status"], []))
|
||||||
for subtest_name, subtest in test["subtests"].iteritems():
|
for subtest_name, subtest in test["subtests"].iteritems():
|
||||||
if is_inconsistent(subtest["status"], iterations):
|
if is_inconsistent(subtest["status"], iterations):
|
||||||
inconsistent.append((test_name, subtest_name, subtest["status"], subtest["messages"]))
|
inconsistent.append((test_name, subtest_name, subtest["status"], subtest["messages"]))
|
||||||
|
|
@ -584,7 +616,7 @@ def markdown_adjust(s):
|
||||||
s = s.replace('\t', u'\\t')
|
s = s.replace('\t', u'\\t')
|
||||||
s = s.replace('\n', u'\\n')
|
s = s.replace('\n', u'\\n')
|
||||||
s = s.replace('\r', u'\\r')
|
s = s.replace('\r', u'\\r')
|
||||||
s = s.replace('`', u'\\`')
|
s = s.replace('`', u'')
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -726,14 +758,16 @@ def main():
|
||||||
logger.critical("Unrecognised browser %s" % browser_name)
|
logger.critical("Unrecognised browser %s" % browser_name)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
fetch_wpt_master(args.user)
|
fetch_wpt(args.user, "master:master")
|
||||||
|
|
||||||
head_sha1 = get_sha1()
|
head_sha1 = get_sha1()
|
||||||
logger.info("Testing web-platform-tests at revision %s" % head_sha1)
|
logger.info("Testing web-platform-tests at revision %s" % head_sha1)
|
||||||
|
|
||||||
|
branch_point = get_branch_point(args.user)
|
||||||
|
|
||||||
# For now just pass the whole list of changed files to wptrunner and
|
# For now just pass the whole list of changed files to wptrunner and
|
||||||
# assume that it will run everything that's actually a test
|
# assume that it will run everything that's actually a test
|
||||||
files_changed = get_files_changed()
|
files_changed = get_files_changed(branch_point)
|
||||||
|
|
||||||
if not files_changed:
|
if not files_changed:
|
||||||
logger.info("No files changed")
|
logger.info("No files changed")
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,3 @@ set -ex
|
||||||
|
|
||||||
./manifest
|
./manifest
|
||||||
./lint
|
./lint
|
||||||
./diff-manifest.py
|
|
||||||
|
|
|
||||||
116
testing/web-platform/tests/common/PrefixedLocalStorage.js
Normal file
116
testing/web-platform/tests/common/PrefixedLocalStorage.js
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
/**
|
||||||
|
* Supports pseudo-"namespacing" localStorage for a given test
|
||||||
|
* by generating and using a unique prefix for keys. Why trounce on other
|
||||||
|
* tests' localStorage items when you can keep it "separated"?
|
||||||
|
*
|
||||||
|
* PrefixedLocalStorageTest: Instantiate in testharness.js tests to generate
|
||||||
|
* a new unique-ish prefix
|
||||||
|
* PrefixedLocalStorageResource: Instantiate in supporting test resource
|
||||||
|
* files to use/share a prefix generated by a test.
|
||||||
|
*/
|
||||||
|
var PrefixedLocalStorage = function () {
|
||||||
|
this.prefix = ''; // Prefix for localStorage keys
|
||||||
|
this.param = 'prefixedLocalStorage'; // Param to use in querystrings
|
||||||
|
};
|
||||||
|
|
||||||
|
PrefixedLocalStorage.prototype.clear = function () {
|
||||||
|
if (this.prefix === '') { return; }
|
||||||
|
Object.keys(localStorage).forEach(sKey => {
|
||||||
|
if (sKey.indexOf(this.prefix) === 0) {
|
||||||
|
localStorage.removeItem(sKey);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append/replace prefix parameter and value in URI querystring
|
||||||
|
* Use to generate URLs to resource files that will share the prefix.
|
||||||
|
*/
|
||||||
|
PrefixedLocalStorage.prototype.url = function (uri) {
|
||||||
|
function updateUrlParameter (uri, key, value) {
|
||||||
|
var i = uri.indexOf('#');
|
||||||
|
var hash = (i === -1) ? '' : uri.substr(i);
|
||||||
|
uri = (i === -1) ? uri : uri.substr(0, i);
|
||||||
|
var re = new RegExp(`([?&])${key}=.*?(&|$)`, 'i');
|
||||||
|
var separator = uri.indexOf('?') !== -1 ? '&' : '?';
|
||||||
|
uri = (uri.match(re)) ? uri.replace(re, `$1${key}=${value}$2`) :
|
||||||
|
`${uri}${separator}${key}=${value}`;
|
||||||
|
return uri + hash;
|
||||||
|
}
|
||||||
|
return updateUrlParameter(uri, this.param, this.prefix);
|
||||||
|
};
|
||||||
|
|
||||||
|
PrefixedLocalStorage.prototype.prefixedKey = function (baseKey) {
|
||||||
|
return `${this.prefix}${baseKey}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
PrefixedLocalStorage.prototype.setItem = function (baseKey, value) {
|
||||||
|
localStorage.setItem(this.prefixedKey(baseKey), value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen for `storage` events pertaining to a particular key,
|
||||||
|
* prefixed with this object's prefix. Ignore when value is being set to null
|
||||||
|
* (i.e. removeItem).
|
||||||
|
*/
|
||||||
|
PrefixedLocalStorage.prototype.onSet = function (baseKey, fn) {
|
||||||
|
window.addEventListener('storage', e => {
|
||||||
|
var match = this.prefixedKey(baseKey);
|
||||||
|
if (e.newValue !== null && e.key.indexOf(match) === 0) {
|
||||||
|
fn.call(this, e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Use in a testharnessjs test to generate a new key prefix.
|
||||||
|
* async_test(t => {
|
||||||
|
* var prefixedStorage = new PrefixedLocalStorageTest();
|
||||||
|
* t.add_cleanup(() => prefixedStorage.cleanup());
|
||||||
|
* /...
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
var PrefixedLocalStorageTest = function () {
|
||||||
|
PrefixedLocalStorage.call(this);
|
||||||
|
this.prefix = `${document.location.pathname}-${Math.random()}-${Date.now()}-`;
|
||||||
|
};
|
||||||
|
PrefixedLocalStorageTest.prototype = Object.create(PrefixedLocalStorage.prototype);
|
||||||
|
PrefixedLocalStorageTest.prototype.constructor = PrefixedLocalStorageTest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use in a cleanup function to clear out prefixed entries in localStorage
|
||||||
|
*/
|
||||||
|
PrefixedLocalStorageTest.prototype.cleanup = function () {
|
||||||
|
this.setItem('closeAll', 'true');
|
||||||
|
this.clear();
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Use in test resource files to share a prefix generated by a
|
||||||
|
* PrefixedLocalStorageTest. Will look in URL querystring for prefix.
|
||||||
|
* Setting `close_on_cleanup` opt truthy will make this script's window listen
|
||||||
|
* for storage `closeAll` event from controlling test and close itself.
|
||||||
|
*
|
||||||
|
* var PrefixedLocalStorageResource({ close_on_cleanup: true });
|
||||||
|
*/
|
||||||
|
var PrefixedLocalStorageResource = function (options) {
|
||||||
|
PrefixedLocalStorage.call(this);
|
||||||
|
this.options = Object.assign({}, {
|
||||||
|
close_on_cleanup: false
|
||||||
|
}, options || {});
|
||||||
|
// Check URL querystring for prefix to use
|
||||||
|
var regex = new RegExp(`[?&]${this.param}(=([^&#]*)|&|#|$)`),
|
||||||
|
results = regex.exec(document.location.href);
|
||||||
|
if (results && results[2]) {
|
||||||
|
this.prefix = results[2];
|
||||||
|
}
|
||||||
|
// Optionally have this window close itself when the PrefixedLocalStorageTest
|
||||||
|
// sets a `closeAll` item.
|
||||||
|
if (this.options.close_on_cleanup) {
|
||||||
|
this.onSet('closeAll', () => {
|
||||||
|
window.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
PrefixedLocalStorageResource.prototype = Object.create(PrefixedLocalStorage.prototype);
|
||||||
|
PrefixedLocalStorageResource.prototype.constructor = PrefixedLocalStorageResource;
|
||||||
8
testing/web-platform/tests/common/domain-setter.sub.html
Normal file
8
testing/web-platform/tests/common/domain-setter.sub.html
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>A page that will likely be same-origin-domain but not same-origin</title>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
"use strict";
|
||||||
|
document.domain = "{{host}}";
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
self.testSettingImmutablePrototypeToNewValueOnly =
|
||||||
|
(prefix, target, newValue, newValueString, { isSameOriginDomain }) => {
|
||||||
|
test(() => {
|
||||||
|
assert_throws(new TypeError, () => {
|
||||||
|
Object.setPrototypeOf(target, newValue);
|
||||||
|
});
|
||||||
|
}, `${prefix}: setting the prototype to ${newValueString} via Object.setPrototypeOf should throw a TypeError`);
|
||||||
|
|
||||||
|
let dunderProtoError = "SecurityError";
|
||||||
|
let dunderProtoErrorName = "\"SecurityError\" DOMException";
|
||||||
|
if (isSameOriginDomain) {
|
||||||
|
dunderProtoError = new TypeError();
|
||||||
|
dunderProtoErrorName = "TypeError";
|
||||||
|
}
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
assert_throws(dunderProtoError, function() {
|
||||||
|
target.__proto__ = newValue;
|
||||||
|
});
|
||||||
|
}, `${prefix}: setting the prototype to ${newValueString} via __proto__ should throw a ${dunderProtoErrorName}`);
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
assert_false(Reflect.setPrototypeOf(target, newValue));
|
||||||
|
}, `${prefix}: setting the prototype to ${newValueString} via Reflect.setPrototypeOf should return false`);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.testSettingImmutablePrototype =
|
||||||
|
(prefix, target, originalValue, { isSameOriginDomain }, newValue = {}, newValueString = "an empty object") => {
|
||||||
|
testSettingImmutablePrototypeToNewValueOnly(prefix, target, newValue, newValueString, { isSameOriginDomain });
|
||||||
|
|
||||||
|
const originalValueString = originalValue === null ? "null" : "its original value";
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
assert_equals(Object.getPrototypeOf(target), originalValue);
|
||||||
|
}, `${prefix}: the prototype must still be ${originalValueString}`);
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
Object.setPrototypeOf(target, originalValue);
|
||||||
|
}, `${prefix}: setting the prototype to ${originalValueString} via Object.setPrototypeOf should not throw`);
|
||||||
|
|
||||||
|
if (isSameOriginDomain) {
|
||||||
|
test(() => {
|
||||||
|
target.__proto__ = originalValue;
|
||||||
|
}, `${prefix}: setting the prototype to ${originalValueString} via __proto__ should not throw`);
|
||||||
|
} else {
|
||||||
|
test(() => {
|
||||||
|
assert_throws("SecurityError", function() {
|
||||||
|
target.__proto__ = newValue;
|
||||||
|
});
|
||||||
|
}, `${prefix}: setting the prototype to ${originalValueString} via __proto__ should throw a "SecurityError" since ` +
|
||||||
|
`it ends up in CrossOriginGetOwnProperty`);
|
||||||
|
}
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
assert_true(Reflect.setPrototypeOf(target, originalValue));
|
||||||
|
}, `${prefix}: setting the prototype to ${originalValueString} via Reflect.setPrototypeOf should return true`);
|
||||||
|
};
|
||||||
|
|
@ -89,7 +89,7 @@
|
||||||
"html/attributes/lang/extlang-bad-novalid.html": "Bad value \u201cbat-smg\u201d for attribute \u201clang\u201d on element \u201cbody\u201d: Bad language tag: Bad extlang subtag \u201csmg\u201d.",
|
"html/attributes/lang/extlang-bad-novalid.html": "Bad value \u201cbat-smg\u201d for attribute \u201clang\u201d on element \u201cbody\u201d: Bad language tag: Bad extlang subtag \u201csmg\u201d.",
|
||||||
"html/attributes/lang/xmllang-different-value-novalid.html": "When the attribute \u201cxml:lang\u201d in no namespace is specified, the element must also have the attribute \u201clang\u201d present with the same value.",
|
"html/attributes/lang/xmllang-different-value-novalid.html": "When the attribute \u201cxml:lang\u201d in no namespace is specified, the element must also have the attribute \u201clang\u201d present with the same value.",
|
||||||
"html/attributes/lang/xmllang-only-novalid.html": "When the attribute \u201cxml:lang\u201d in no namespace is specified, the element must also have the attribute \u201clang\u201d present with the same value.",
|
"html/attributes/lang/xmllang-only-novalid.html": "When the attribute \u201cxml:lang\u201d in no namespace is specified, the element must also have the attribute \u201clang\u201d present with the same value.",
|
||||||
"html/attributes/role/unrecognized-role-name-novalid.html": "Discarding unrecognized tokens \u201cswitch\u201d, \u201cinput\u201d from value of attribute \u201crole\u201d. Browsers ignore any token that is not a defined ARIA non-abstract role.",
|
"html/attributes/role/unrecognized-role-name-novalid.html": "Discarding unrecognized token \u201cinput\u201d from value of attribute \u201crole\u201d. Browsers ignore any token that is not a defined ARIA non-abstract role.",
|
||||||
"html/attributes/spellcheck/value-bad-novalid.html": "Bad value \u201cbadvalue\u201d for attribute \u201cspellcheck\u201d on element \u201cp\u201d.",
|
"html/attributes/spellcheck/value-bad-novalid.html": "Bad value \u201cbadvalue\u201d for attribute \u201cspellcheck\u201d on element \u201cp\u201d.",
|
||||||
"html/elements/a/href/fragment-backslash-novalid.html": "Bad value \u201c#\\\u201d for attribute \u201chref\u201d on element \u201ca\u201d: Bad URL: Illegal character in fragment: \u201c\\\u201d is not allowed.",
|
"html/elements/a/href/fragment-backslash-novalid.html": "Bad value \u201c#\\\u201d for attribute \u201chref\u201d on element \u201ca\u201d: Bad URL: Illegal character in fragment: \u201c\\\u201d is not allowed.",
|
||||||
"html/elements/a/href/fragment-contains-hash-novalid.html": "Bad value \u201chttp://foo/path#f#g\u201d for attribute \u201chref\u201d on element \u201ca\u201d: Bad URL: Illegal character in fragment: \u201c#\u201d is not allowed.",
|
"html/elements/a/href/fragment-contains-hash-novalid.html": "Bad value \u201chttp://foo/path#f#g\u201d for attribute \u201chref\u201d on element \u201ca\u201d: Bad URL: Illegal character in fragment: \u201c#\u201d is not allowed.",
|
||||||
|
|
@ -2435,7 +2435,7 @@
|
||||||
"xhtml/elements/keygen/361-novalid.xhtml": "The \u201ckeygen\u201d element is obsolete. ",
|
"xhtml/elements/keygen/361-novalid.xhtml": "The \u201ckeygen\u201d element is obsolete. ",
|
||||||
"xhtml/elements/keygen/keygen-novalid.xhtml": "The \u201ckeygen\u201d element is obsolete. ",
|
"xhtml/elements/keygen/keygen-novalid.xhtml": "The \u201ckeygen\u201d element is obsolete. ",
|
||||||
"xhtml/elements/link/001-novalid.xhtml": "Element \u201clink\u201d is missing required attribute \u201chref\u201d.",
|
"xhtml/elements/link/001-novalid.xhtml": "Element \u201clink\u201d is missing required attribute \u201chref\u201d.",
|
||||||
"xhtml/elements/menu/001-haswarn.xhtml": "The \u201cmenu\u201d element is not supported in all browsers. Please be sure to test, and consider using a polyfill.",
|
"xhtml/elements/menu/001-haswarn.xhtml": "The \u201ccontextmenu\u201d attribute is not supported in all browsers. Please be sure to test, and consider using a polyfill.",
|
||||||
"xhtml/elements/menu/001-novalid.xhtml": "The \u201ccontextmenu\u201d attribute must refer to a \u201cmenu\u201d element.",
|
"xhtml/elements/menu/001-novalid.xhtml": "The \u201ccontextmenu\u201d attribute must refer to a \u201cmenu\u201d element.",
|
||||||
"xhtml/elements/meter/010-novalid.xhtml": "The value of the \u201cmin\u201d attribute must be less than or equal to the value of the \u201cvalue\u201d attribute.",
|
"xhtml/elements/meter/010-novalid.xhtml": "The value of the \u201cmin\u201d attribute must be less than or equal to the value of the \u201cvalue\u201d attribute.",
|
||||||
"xhtml/elements/meter/011-novalid.xhtml": "Element \u201cmeter\u201d is missing required attribute \u201cvalue\u201d.",
|
"xhtml/elements/meter/011-novalid.xhtml": "Element \u201cmeter\u201d is missing required attribute \u201cvalue\u201d.",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Console Count - Logging Manual Test</title>
|
||||||
|
<meta name="author" title="Dominic Farolino" href="mailto:domfarolino@gmail.com">
|
||||||
|
<meta name="assert" content="Console count method default parameter should work">
|
||||||
|
<link rel="help" href="https://console.spec.whatwg.org/#count">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>Open the console inside the developer tools. It should contain four lines whose contents are:</p>
|
||||||
|
<p><code>default: 1</code></p>
|
||||||
|
<p><code>default: 2</code></p>
|
||||||
|
<p><code>default: 3</code></p>
|
||||||
|
<p><code>default: 4</code></p>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
console.count();
|
||||||
|
console.count(undefined);
|
||||||
|
console.count("default");
|
||||||
|
console.count({toString() {return "default"}});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
assert_equals(console.timeline, undefined, "console.timeline should be undefined");
|
||||||
|
}, "'timeline' function should not exist on the console object");
|
||||||
|
|
||||||
|
test(() => {
|
||||||
|
assert_equals(console.timelineEnd, undefined, "console.timelineEnd should be undefined");
|
||||||
|
}, "'timelineEnd' function should not exist on the console object");
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>base-uri works correctly inside a sandboxed iframe.</title>
|
||||||
|
<script src='/resources/testharness.js'></script>
|
||||||
|
<script src='/resources/testharnessreport.js'></script>
|
||||||
|
|
||||||
|
<!-- CSP served: base-uri 'self' -->
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>base-uri works correctly inside a sandboxed iframe.</h1>
|
||||||
|
<div id='log'></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.addEventListener('securitypolicyviolation', function(e) {
|
||||||
|
assert_unreached('No CSP violation report has fired.');
|
||||||
|
});
|
||||||
|
|
||||||
|
async_test(function(t) {
|
||||||
|
var i = document.createElement('iframe');
|
||||||
|
i.sandbox = 'allow-scripts';
|
||||||
|
i.style.display = 'none';
|
||||||
|
i.srcdoc = `
|
||||||
|
<script>
|
||||||
|
window.addEventListener('securitypolicyviolation', function() {
|
||||||
|
top.postMessage('FAIL', '*');
|
||||||
|
});
|
||||||
|
</sc` + `ript>
|
||||||
|
<base href="{{location[scheme]}}://{{domains[]}}:{{ports[http][0]}}/base/">
|
||||||
|
<script>
|
||||||
|
top.postMessage(document.baseURI, '*');
|
||||||
|
</sc` + `ript>`;
|
||||||
|
|
||||||
|
window.addEventListener('message', t.step_func(function(e) {
|
||||||
|
if (e.source === i.contentWindow) {
|
||||||
|
assert_equals(e.data, location.origin + '/base/');
|
||||||
|
t.done();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
document.body.appendChild(i);
|
||||||
|
}, 'base-uri \'self\' works with same-origin sandboxed iframes.');
|
||||||
|
|
||||||
|
async_test(function(t) {
|
||||||
|
var i = document.createElement('iframe');
|
||||||
|
i.sandbox = 'allow-scripts';
|
||||||
|
i.style.display = 'none';
|
||||||
|
i.srcdoc = `
|
||||||
|
<script>
|
||||||
|
window.addEventListener('securitypolicyviolation',
|
||||||
|
function(violation) {
|
||||||
|
if (violation.blockedURI !== '{{location[scheme]}}://{{domains[www2]}}:{{ports[http][0]}}/base/' || violation.effectiveDirective !== 'base-uri') {
|
||||||
|
top.postMessage('FAIL');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
top.postMessage(document.baseURI, '*');
|
||||||
|
});
|
||||||
|
</sc` + `ript>
|
||||||
|
<base href="{{location[scheme]}}://{{domains[www2]}}:{{ports[http][0]}}/base/">
|
||||||
|
<script>
|
||||||
|
top.postMessage(document.baseURI, '*');
|
||||||
|
</sc` + `ript>`;
|
||||||
|
|
||||||
|
window.addEventListener('message', t.step_func(function(e) {
|
||||||
|
if (e.source === i.contentWindow) {
|
||||||
|
assert_equals(e.data, location.href);
|
||||||
|
t.done();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
document.body.appendChild(i);
|
||||||
|
}, 'base-uri \'self\' blocks foreign-origin sandboxed iframes.');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
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
|
||||||
|
Content-Security-Policy: base-uri 'self'
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="connect-src 'self'">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
async_test(t => {
|
||||||
|
document.addEventListener("securitypolicyviolation", t.step_func_done(e => {
|
||||||
|
if (e.blockedURI != "http://{{domains[www]}}:{{ports[http][0]}}/common/text-plain.txt")
|
||||||
|
return;
|
||||||
|
|
||||||
|
assert_equals(e.violatedDirective, "connect-src");
|
||||||
|
}));
|
||||||
|
|
||||||
|
assert_true(navigator.sendBeacon("http://{{domains[www]}}:{{ports[http][0]}}/common/text-plain.txt"));
|
||||||
|
}, "sendBeacon should not throw.");
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="connect-src 'self'">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
async_test(t => {
|
||||||
|
var errorEvent = false;
|
||||||
|
var cspEvent = false;
|
||||||
|
|
||||||
|
var es = new EventSource("http://{{domains[www]}}:{{ports[http][0]}}/common/text-plain.txt");
|
||||||
|
es.onerror = t.step_func(e => {
|
||||||
|
assert_equals(es.readyState, EventSource.CLOSED);
|
||||||
|
|
||||||
|
assert_false(errorEvent);
|
||||||
|
errorEvent = true;
|
||||||
|
if (cspEvent)
|
||||||
|
t.done();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener("securitypolicyviolation", t.step_func(e => {
|
||||||
|
if (e.blockedURI != "http://{{domains[www]}}:{{ports[http][0]}}/common/text-plain.txt")
|
||||||
|
return;
|
||||||
|
|
||||||
|
assert_equals(es.readyState, EventSource.CLOSED);
|
||||||
|
assert_equals(e.violatedDirective, "connect-src");
|
||||||
|
|
||||||
|
assert_false(cspEvent);
|
||||||
|
cspEvent = true;
|
||||||
|
if (errorEvent)
|
||||||
|
t.done();
|
||||||
|
}));
|
||||||
|
}, "EventSource should fire onerror.");
|
||||||
|
|
||||||
|
async_test(t => {
|
||||||
|
var errorEvent = false;
|
||||||
|
var cspEvent = false;
|
||||||
|
|
||||||
|
var es = new EventSource("http://{{domains[www]}}:{{ports[http][0]}}/common/text-plain.txt");
|
||||||
|
es.onerror = t.step_func(e => {
|
||||||
|
assert_equals(es.readyState, EventSource.CLOSED);
|
||||||
|
|
||||||
|
assert_false(errorEvent);
|
||||||
|
errorEvent = true;
|
||||||
|
if (cspEvent)
|
||||||
|
t.done();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener("securitypolicyviolation", t.step_func(e => {
|
||||||
|
if (e.blockedURI != "http://{{domains[www]}}:{{ports[http][0]}}/common/text-plain.txt")
|
||||||
|
return;
|
||||||
|
|
||||||
|
assert_equals(es.readyState, EventSource.CLOSED);
|
||||||
|
assert_equals(e.violatedDirective, "connect-src");
|
||||||
|
|
||||||
|
assert_false(cspEvent);
|
||||||
|
cspEvent = true;
|
||||||
|
if (errorEvent)
|
||||||
|
t.done();
|
||||||
|
}));
|
||||||
|
}, "EventSource should fire onerror.");
|
||||||
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="connect-src 'self'">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
async_test(t => {
|
||||||
|
var errorEvent = false;
|
||||||
|
var cspEvent = false;
|
||||||
|
|
||||||
|
var ws = new WebSocket("ws://{{domains[www]}}:{{ports[ws][0]}}/echo");
|
||||||
|
ws.onopen = t.unreached_func("open should not fire.");
|
||||||
|
ws.onerror = t.step_func(e => {
|
||||||
|
assert_equals(ws.readyState, WebSocket.CLOSED);
|
||||||
|
|
||||||
|
assert_false(errorEvent);
|
||||||
|
errorEvent = true;
|
||||||
|
if (cspEvent)
|
||||||
|
t.done();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener("securitypolicyviolation", t.step_func(e => {
|
||||||
|
if (e.blockedURI != "ws://{{domains[www]}}:{{ports[ws][0]}}")
|
||||||
|
return;
|
||||||
|
|
||||||
|
assert_equals(ws.readyState, WebSocket.CLOSED);
|
||||||
|
assert_equals(e.violatedDirective, "connect-src");
|
||||||
|
|
||||||
|
assert_false(cspEvent);
|
||||||
|
cspEvent = true;
|
||||||
|
if (errorEvent)
|
||||||
|
t.done();
|
||||||
|
}));
|
||||||
|
}, "WebSocket should fire error event.");
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="connect-src 'self'">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
async_test(t => {
|
||||||
|
var errorEvent = false;
|
||||||
|
var cspEvent = false;
|
||||||
|
|
||||||
|
var xhr = new XMLHttpRequest;
|
||||||
|
xhr.open("GET", "http://{{domains[www]}}:{{ports[http][0]}}/common/text-plain.txt");
|
||||||
|
xhr.onload = t.unreached_func("Load should not fire.");
|
||||||
|
xhr.onerror = t.step_func(e => {
|
||||||
|
assert_equals(xhr.readyState, XMLHttpRequest.DONE);
|
||||||
|
|
||||||
|
assert_false(errorEvent);
|
||||||
|
errorEvent = true;
|
||||||
|
if (cspEvent)
|
||||||
|
t.done();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener("securitypolicyviolation", t.step_func(e => {
|
||||||
|
if (e.blockedURI != "http://{{domains[www]}}:{{ports[http][0]}}/common/text-plain.txt")
|
||||||
|
return;
|
||||||
|
|
||||||
|
assert_equals(xhr.readyState, XMLHttpRequest.DONE);
|
||||||
|
assert_equals(e.violatedDirective, "connect-src");
|
||||||
|
|
||||||
|
assert_false(cspEvent);
|
||||||
|
cspEvent = true;
|
||||||
|
if (errorEvent)
|
||||||
|
t.done();
|
||||||
|
}));
|
||||||
|
|
||||||
|
xhr.send();
|
||||||
|
}, "XHR should fire onerror.");
|
||||||
|
|
||||||
|
async_test(t => {
|
||||||
|
var errorEvent = false;
|
||||||
|
var cspEvent = false;
|
||||||
|
|
||||||
|
var xhr = new XMLHttpRequest;
|
||||||
|
xhr.open("GET", "/common/redirect-opt-in.py?status=307&location=http://{{domains[www]}}:{{ports[http][0]}}/common/text-plain.txt");
|
||||||
|
xhr.onload = t.unreached_func("Load should not fire.");
|
||||||
|
xhr.onerror = t.step_func(e => {
|
||||||
|
assert_equals(xhr.readyState, XMLHttpRequest.DONE);
|
||||||
|
|
||||||
|
assert_false(errorEvent);
|
||||||
|
errorEvent = true;
|
||||||
|
if (cspEvent)
|
||||||
|
t.done();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener("securitypolicyviolation", t.step_func(e => {
|
||||||
|
if (e.blockedURI != "http://{{domains[www]}}:{{ports[http][0]}}")
|
||||||
|
return;
|
||||||
|
|
||||||
|
assert_equals(xhr.readyState, XMLHttpRequest.DONE);
|
||||||
|
assert_equals(e.violatedDirective, "connect-src");
|
||||||
|
|
||||||
|
assert_false(cspEvent);
|
||||||
|
cspEvent = true;
|
||||||
|
if (errorEvent)
|
||||||
|
t.done();
|
||||||
|
}));
|
||||||
|
|
||||||
|
xhr.send();
|
||||||
|
}, "XHR should fire onerror after a redirect.");
|
||||||
|
</script>
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<meta charset=utf-8>
|
|
||||||
<title>csp font-src: blacklisted</title>
|
|
||||||
<link href="fonts.css" rel="stylesheet" type="text/css">
|
|
||||||
|
|
||||||
<p>The test passes if the line above are boxes in the test and glyphs in the reference.</p>
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<meta charset=utf-8>
|
|
||||||
<meta http-equiv="Content-Security-Policy" content="font-src 'none'">
|
|
||||||
<title>csp font-src: blacklisted</title>
|
|
||||||
<link rel="mismatch" href="font-blacklisted-ref.html">
|
|
||||||
<link rel="help" href="https://www.w3.org/TR/CSP2/#directive-font-src">
|
|
||||||
<link href="fonts.css" rel="stylesheet" type="text/css">
|
|
||||||
|
|
||||||
<p>The test passes if the line above are boxes in the test and glyphs in the reference.</p>
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="font-src {{domains[www1]}}:{{ports[http][0]}}">
|
||||||
|
<head>
|
||||||
|
<title>Test font loads if it matches font-src.</title>
|
||||||
|
<script src='/resources/testharness.js'></script>
|
||||||
|
<script src='/resources/testharnessreport.js'></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="log"/>
|
||||||
|
<script>
|
||||||
|
async_test(function(t) {
|
||||||
|
document.addEventListener("securitypolicyviolation", t.unreached_func("Loading allowed fonts should not trigger a violation."));
|
||||||
|
var link = document.createElement('link');
|
||||||
|
link.rel="preload";
|
||||||
|
link.as="font";
|
||||||
|
link.href="http://{{domains[www1]}}:{{ports[http][0]}}/content-security-policy/support/Ahem.ttf";
|
||||||
|
link.onload = t.step_func_done();
|
||||||
|
link.onerror = t.unreached_func("Should have loaded the font.");
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(link);
|
||||||
|
}, "Test font loads if it matches font-src.");
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="font-src {{domains[www1]}}:{{ports[http][0]}}">
|
||||||
|
<head>
|
||||||
|
<title>Test font does not load if it does not match font-src.</title>
|
||||||
|
<script src='/resources/testharness.js'></script>
|
||||||
|
<script src='/resources/testharnessreport.js'></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="log"/>
|
||||||
|
<script>
|
||||||
|
async_test(function(t) {
|
||||||
|
var link = document.createElement('link');
|
||||||
|
link.rel="preload";
|
||||||
|
link.as="font";
|
||||||
|
link.href="http://{{domains[www2]}}:{{ports[http][0]}}/content-security-policy/support/Ahem.ttf";
|
||||||
|
link.onload = t.unreached_func("Should not have loaded the font.");
|
||||||
|
link.onerror = t.step_func_done();
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(link);
|
||||||
|
}, "Test font does not load if it does not match font-src.");
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="font-src 'none'">
|
||||||
|
<head>
|
||||||
|
<title>Test font does not load if it does not match font-src.</title>
|
||||||
|
<script src='/resources/testharness.js'></script>
|
||||||
|
<script src='/resources/testharnessreport.js'></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="log"/>
|
||||||
|
<script>
|
||||||
|
async_test(function(t) {
|
||||||
|
var link = document.createElement('link');
|
||||||
|
link.rel="preload";
|
||||||
|
link.as="font";
|
||||||
|
link.href="http://{{domains[www]}}:{{ports[http][0]}}/content-security-policy/support/Ahem.ttf";
|
||||||
|
link.onload = t.unreached_func("Should not have loaded the font.");
|
||||||
|
link.onerror = t.step_func_done();
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(link);
|
||||||
|
}, "Test font does not load if it does not match font-src.");
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="font-src 'self'">
|
||||||
|
<head>
|
||||||
|
<title>Test font loads if it matches font-src.</title>
|
||||||
|
<script src='/resources/testharness.js'></script>
|
||||||
|
<script src='/resources/testharnessreport.js'></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="log"/>
|
||||||
|
<script>
|
||||||
|
async_test(function(t) {
|
||||||
|
document.addEventListener("securitypolicyviolation", t.unreached_func("Loading allowed fonts should not trigger a violation."));
|
||||||
|
var link = document.createElement('link');
|
||||||
|
link.rel="preload";
|
||||||
|
link.as="font";
|
||||||
|
link.href="/content-security-policy/support/Ahem.ttf";
|
||||||
|
link.onload = t.step_func_done();
|
||||||
|
link.onerror = t.unreached_func("Should have loaded the font.");
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(link);
|
||||||
|
}, "Test font loads if it matches font-src.");
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
<!doctype html>
|
||||||
|
<meta charset=utf-8>
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="font-src 'none'">
|
||||||
|
<head>
|
||||||
|
<title>Test font does not load if it does not match font-src.</title>
|
||||||
|
<script src='/resources/testharness.js'></script>
|
||||||
|
<script src='/resources/testharnessreport.js'></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="log"/>
|
||||||
|
<script>
|
||||||
|
async_test(function(t) {
|
||||||
|
var link = document.createElement('link');
|
||||||
|
link.rel="stylesheet";
|
||||||
|
link.type="text/css";
|
||||||
|
link.href="/content-security-policy/support/fonts.css";
|
||||||
|
// The stylesheet should stil load, even though the font contained does not
|
||||||
|
link.onerror = t.unreached_func("Should have loaded the stylesheet.");
|
||||||
|
document.addEventListener("securitypolicyviolation", t.step_func_done(function(e) {
|
||||||
|
assert_equals(e.violatedDirective, "font-src");
|
||||||
|
}));
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(link);
|
||||||
|
}, "Test font does not load if it does not match font-src.");
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<meta charset=utf-8>
|
|
||||||
<title>csp font-src: whitelisted</title>
|
|
||||||
<link href="fonts.css" rel="stylesheet" type="text/css">
|
|
||||||
|
|
||||||
<p>The test passes if the line above shows the same glyphs in the reference.</p>
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<meta charset=utf-8>
|
|
||||||
<meta http-equiv="Content-Security-Policy" content="font-src 'self'">
|
|
||||||
<title>csp font-src: whitelisted</title>
|
|
||||||
<link rel="match" href="font-whitelisted-ref.html">
|
|
||||||
<link rel="help" href="https://www.w3.org/TR/CSP2/#directive-font-src">
|
|
||||||
<link href="fonts.css" rel="stylesheet" type="text/css">
|
|
||||||
|
|
||||||
<p>The test passes if the line above shows the same glyphs in the reference.</p>
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
@font-face {
|
|
||||||
font-family: 'Halflings';
|
|
||||||
src: url('/tools/runner/fonts/glyphicons-halflings-regular.woff') format('woff');
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
|
||||||
font-family: 'Halflings', Fallback, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>img element src attribute must match src list.</title>
|
|
||||||
<script src='/resources/testharness.js'></script>
|
|
||||||
<script src='/resources/testharnessreport.js'></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>img element src attribute must match src list.</h1>
|
|
||||||
<p>
|
|
||||||
<div id='log'></div>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
var t1 = async_test("img-src for relative path should load.");
|
|
||||||
var t2 = async_test("img-src from unapproved domains should not load");
|
|
||||||
var t3 = async_test("img-src from approved domains should load");
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<img src='/content-security-policy/support/pass.png'
|
|
||||||
onerror='t1.step(function() { assert_unreached("The img should have loaded."); t1.done() });'
|
|
||||||
onload='t1.done();'>
|
|
||||||
|
|
||||||
<img src='http://www1.web-platform.test/content-security-policy/support/fail.png'
|
|
||||||
onerror='t2.done();'
|
|
||||||
onload='t2.step(function() { assert_unreached("Image from unapproved domain was loaded."); t2.done()} );'>
|
|
||||||
|
|
||||||
<div id='t3'></div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
var t3img = document.createElement('img');
|
|
||||||
t3img.onerror = function() {t3.step(function() { assert_unreached(); t3.done();})}
|
|
||||||
t3img.onload = function() {t3.done();}
|
|
||||||
t3img.src = location.protocol + '//www.' + location.hostname + ':' + location.port +
|
|
||||||
'/content-security-policy/support/pass.png';
|
|
||||||
var t3div = document.getElementById('t3');
|
|
||||||
t3div.appendChild(t3img);
|
|
||||||
|
|
||||||
var report = document.createElement('script');
|
|
||||||
report.src = '../support/checkReport.sub.js?reportField=violated-directive&reportValue=img-src%20%27self%27%20www.' + location.hostname + (location.port ? ':' + location.port : '');
|
|
||||||
t3div.appendChild(report);
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
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: img-src-4_1={{$id:uuid()}}; Path=/content-security-policy/img-src/
|
|
||||||
Content-Security-Policy: img-src 'self' www.{{host}}:{{ports[http][0]}}; report-uri ../support/report.py?op=put&reportID={{$id}}
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="img-src 'self' {{domains[www]}}:{{ports[http][0]}}">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>img element src attribute must match src list.</title>
|
||||||
|
<script src='/resources/testharness.js'></script>
|
||||||
|
<script src='/resources/testharnessreport.js'></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id='log'/>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
async_test(function(t) {
|
||||||
|
i = new Image();
|
||||||
|
i.onload = t.step_func_done();
|
||||||
|
i.onerror = t.unreached_func("The img should have loaded");
|
||||||
|
i.src = '/content-security-policy/support/pass.png';
|
||||||
|
}, "img-src for relative path should load");
|
||||||
|
|
||||||
|
async_test(function(t) {
|
||||||
|
i = new Image();
|
||||||
|
i.onload = t.unreached_func("Image from unapproved domain was loaded.");
|
||||||
|
i.onerror = t.step_func_done();
|
||||||
|
i.src = 'http://{{domains[www1]}}/content-security-policy/support/fail.png';
|
||||||
|
}, "img-src from unapproved domains should not load");
|
||||||
|
|
||||||
|
async_test(function(t) {
|
||||||
|
i = new Image();
|
||||||
|
i.onload = t.step_func_done();
|
||||||
|
i.onerror = t.unreached_func("The img should have loaded");
|
||||||
|
i.src = location.protocol + '//{{domains[www]}}:{{ports[http][0]}}/content-security-policy/support/pass.png';
|
||||||
|
}, "img-src from approved domains should load");
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="img-src *.{{host}}:{{ports[http][0]}}">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>img-src with full host and wildcard blocks correctly.</title>
|
||||||
|
<script src='/resources/testharness.js'></script>
|
||||||
|
<script src='/resources/testharnessreport.js'></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id='log'/>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var t1 = async_test("img src does not match full host and wildcard csp directive");
|
||||||
|
</script>
|
||||||
|
<img src='http://{{host}}:{{ports[http][0]}}/content-security-policy/support/fail.png'
|
||||||
|
onload='t1.step(function() { assert_unreached("Image should have loaded"); t1.done(); });'
|
||||||
|
onerror='t1.done();'>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="img-src *.{{host}}:{{ports[http][0]}}">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>img-src works correctly with partial host wildcard.</title>
|
||||||
|
<script src='/resources/testharness.js'></script>
|
||||||
|
<script src='/resources/testharnessreport.js'></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id='log'/>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var t1 = async_test("img src matches correctly partial wildcard host csp directive");
|
||||||
|
</script>
|
||||||
|
<img src='http://{{domains[www]}}:{{ports[http][0]}}/content-security-policy/support/pass.png'
|
||||||
|
onload='t1.done();'
|
||||||
|
onerror='t1.step(function() { assert_unreached("Image should have loaded"); t1.done(); });'>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="img-src 'none';">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>img element src attribute must match src list.</title>
|
||||||
|
<script src='/resources/testharness.js'></script>
|
||||||
|
<script src='/resources/testharnessreport.js'></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id='log'/>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var t1 = async_test("img-src with 'none' source should not match");
|
||||||
|
</script>
|
||||||
|
<img src='/content-security-policy/support/fail.png'
|
||||||
|
onload='t1.step(function() { assert_unreached("Image should not have loaded"); t1.done(); });'
|
||||||
|
onerror='t1.done();'>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="img-src http://www.{{host}}:*">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>img-src works correctly with port wildcard source</title>
|
||||||
|
<script src='/resources/testharness.js'></script>
|
||||||
|
<script src='/resources/testharnessreport.js'></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id='log'/>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var t1 = async_test("img-src with wildcard port should match any port");
|
||||||
|
</script>
|
||||||
|
<img src='http://{{domains[www]}}:{{ports[http][0]}}/content-security-policy/support/pass.png'
|
||||||
|
onload='t1.done();'
|
||||||
|
onerror='t1.step(function() { assert_unreached("Image should have loaded."); t1.done()} );'>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta http-equiv="Content-Security-Policy" content="img-src *;">
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>img element src attribute must match src list.</title>
|
||||||
|
<script src='/resources/testharness.js'></script>
|
||||||
|
<script src='/resources/testharnessreport.js'></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id='log'/>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var t1 = async_test("img-src with wildcard should match all");
|
||||||
|
</script>
|
||||||
|
<img src='/content-security-policy/support/pass.png'
|
||||||
|
onload='t1.done();'
|
||||||
|
onerror='t1.step(function() { assert_unreached("Image should have loaded"); t1.done(); });'>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
async_test(function(t) {
|
||||||
|
|
||||||
|
var pngBase64 = "iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAIAAAD/gAIDAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAnklEQVR42u3QMQEAAAgDoGlyo1vBzwciUJlw1ApkyZIlS5YsBbJkyZIlS5YCWbJkyZIlS4EsWbJkyZKlQJYsWbJkyVIgS5YsWbJkKZAlS5YsWbIUyJIlS5YsWQpkyZIlS5YsBbJkyZIlS5YCWbJkyZIlS4EsWbJkyZKlQJYsWbJkyVIgS5YsWbJkKZAlS5YsWbIUyJIlS5YsWQpkyfq2MosBSIeKONMAAAAASUVORK5CYII=";
|
||||||
|
|
||||||
|
blobContents = [atob(pngBase64)];
|
||||||
|
blob = new Blob(blobContents, {type: "image/png"});
|
||||||
|
img = document.createElement("img");
|
||||||
|
img.onerror = function (e) {
|
||||||
|
t.done();
|
||||||
|
};
|
||||||
|
img.onload = function () {
|
||||||
|
assert_unreached("Should not load blob img");
|
||||||
|
t.done();
|
||||||
|
};
|
||||||
|
blobURL = window.URL.createObjectURL(blob);
|
||||||
|
img.src = blobURL;
|
||||||
|
|
||||||
|
},"img-src with wildcard should not match blob");
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
|
||||||
|
<meta http-equiv="content-security-policy" content="connect-src 'self'">
|
||||||
|
<script>
|
||||||
|
// External URLs inherit policy.
|
||||||
|
fetch_tests_from_worker(new Worker("./support/connect-src-self.sub.js"));
|
||||||
|
fetch_tests_from_worker(new Worker("./support/connect-src-self.sub.js?pipe=sub|header(Content-Security-Policy,connect-src 'none')"));
|
||||||
|
fetch_tests_from_worker(new Worker("./support/connect-src-self.sub.js?pipe=sub|header(Content-Security-Policy,connect-src *)"));
|
||||||
|
fetch_tests_from_worker(new Worker("./support/connect-src-self.sub.js?pipe=sub|header(Content-Security-Policy,default-src 'none')"));
|
||||||
|
fetch_tests_from_worker(new Worker("./support/connect-src-self.sub.js?pipe=sub|header(Content-Security-Policy,default-src *)"));
|
||||||
|
|
||||||
|
async_test(t => {
|
||||||
|
fetch("./support/connect-src-self.sub.js")
|
||||||
|
.then(r => r.blob())
|
||||||
|
.then(b => {
|
||||||
|
// 'blob:' URLs inherit policy.
|
||||||
|
var u = URL.createObjectURL(b);
|
||||||
|
fetch_tests_from_worker(new Worker(u));
|
||||||
|
|
||||||
|
if (!window.webkitRequestFileSystem)
|
||||||
|
return t.done();
|
||||||
|
|
||||||
|
|
||||||
|
// 'filesystem:' urls inherit policy.
|
||||||
|
window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024, fs => {
|
||||||
|
fs.root.getFile('dedicated-inheritance-worker.js', { create: true }, entry => {
|
||||||
|
entry.createWriter(w => {
|
||||||
|
w.onwriteend = _ => {
|
||||||
|
var u = entry.toURL();
|
||||||
|
fetch_tests_from_worker(new Worker(u));
|
||||||
|
|
||||||
|
// explicit_done: yay.
|
||||||
|
t.done();
|
||||||
|
};
|
||||||
|
w.onerror = _ => t.unreached_func();
|
||||||
|
w.write(b);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, "Filesystem and blob.");
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
|
||||||
|
<meta http-equiv="content-security-policy" content="script-src 'self' 'nonce-a' blob: filesystem:">
|
||||||
|
<script nonce="a">
|
||||||
|
// External URLs inherit policy: the header delivered with the script resource is ignored.
|
||||||
|
fetch_tests_from_worker(new Worker("./support/script-src-self.sub.js"));
|
||||||
|
fetch_tests_from_worker(new Worker("./support/script-src-self.sub.js?pipe=sub|header(Content-Security-Policy,script-src 'none')"));
|
||||||
|
fetch_tests_from_worker(new Worker("./support/script-src-self.sub.js?pipe=sub|header(Content-Security-Policy,script-src *)"));
|
||||||
|
fetch_tests_from_worker(new Worker("./support/script-src-self.sub.js?pipe=sub|header(Content-Security-Policy,default-src 'none')"));
|
||||||
|
fetch_tests_from_worker(new Worker("./support/script-src-self.sub.js?pipe=sub|header(Content-Security-Policy,default-src *)"));
|
||||||
|
|
||||||
|
async_test(t => {
|
||||||
|
fetch("./support/script-src-self.sub.js")
|
||||||
|
.then(r => r.blob())
|
||||||
|
.then(b => {
|
||||||
|
// 'blob:' URLs inherit policy.
|
||||||
|
var u = URL.createObjectURL(b);
|
||||||
|
fetch_tests_from_worker(new Worker(u));
|
||||||
|
|
||||||
|
if (!window.webkitRequestFileSystem)
|
||||||
|
return t.done();
|
||||||
|
|
||||||
|
|
||||||
|
// 'filesystem:' urls inherit policy.
|
||||||
|
window.webkitRequestFileSystem(window.TEMPORARY, 1024*1024, fs => {
|
||||||
|
fs.root.getFile('dedicated-script-worker.js', { create: true }, entry => {
|
||||||
|
entry.createWriter(w => {
|
||||||
|
w.onwriteend = _ => {
|
||||||
|
var u = entry.toURL();
|
||||||
|
fetch_tests_from_worker(new Worker(u));
|
||||||
|
|
||||||
|
// explicit_done: yay.
|
||||||
|
t.done();
|
||||||
|
};
|
||||||
|
w.onerror = _ => t.unreached_func();
|
||||||
|
w.write(b);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, "Filesystem and blob.");
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
|
||||||
|
<meta http-equiv="content-security-policy" content="connect-src 'self'">
|
||||||
|
<script>
|
||||||
|
// SharedWorkers do not inherit policy.
|
||||||
|
fetch_tests_from_worker(new SharedWorker("./support/connect-src-allow.sub.js"));
|
||||||
|
fetch_tests_from_worker(new SharedWorker("./support/connect-src-self.sub.js?pipe=sub|header(Content-Security-Policy,connect-src 'self')"));
|
||||||
|
fetch_tests_from_worker(new SharedWorker("./support/connect-src-self.sub.js?pipe=sub|header(Content-Security-Policy,default-src 'self')"));
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
|
||||||
|
<meta http-equiv="content-security-policy" content="script-src 'self' 'nonce-a' blob: filesystem:">
|
||||||
|
<script nonce="a">
|
||||||
|
// SharedWorker URLs do not inherit policy.
|
||||||
|
fetch_tests_from_worker(new SharedWorker("./support/script-src-allow.sub.js"));
|
||||||
|
fetch_tests_from_worker(new SharedWorker("./support/script-src-self.sub.js?pipe=sub|header(Content-Security-Policy,script-src 'self'"));
|
||||||
|
fetch_tests_from_worker(new SharedWorker("./support/script-src-self.sub.js?pipe=sub|header(Content-Security-Policy,default-src 'self'"));
|
||||||
|
</script>
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
importScripts("{{location[server]}}/resources/testharness.js");
|
||||||
|
importScripts("{{location[server]}}/content-security-policy/support/testharness-helper.js");
|
||||||
|
|
||||||
|
// Same-origin
|
||||||
|
async_test(t => {
|
||||||
|
var url = "{{location[server]}}/content-security-policy/support/resource.py?same-origin-fetch";
|
||||||
|
assert_no_csp_event_for_url(t, url);
|
||||||
|
|
||||||
|
fetch(url)
|
||||||
|
.then(t.step_func_done(r => assert_equals(r.status, 200)));
|
||||||
|
}, "Same-origin 'fetch()' in " + self.location.protocol + self.location.search);
|
||||||
|
|
||||||
|
async_test(t => {
|
||||||
|
var url = "{{location[server]}}/content-security-policy/support/resource.py?same-origin-xhr";
|
||||||
|
assert_no_csp_event_for_url(t, url);
|
||||||
|
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", url);
|
||||||
|
xhr.onload = t.step_func_done();
|
||||||
|
xhr.onerror = t.unreached_func();
|
||||||
|
xhr.send();
|
||||||
|
}, "Same-origin XHR in " + self.location.protocol + self.location.search);
|
||||||
|
|
||||||
|
// Cross-origin
|
||||||
|
async_test(t => {
|
||||||
|
var url = "http://{{domains[www]}}:{{ports[http][1]}}/content-security-policy/support/resource.py?cross-origin-fetch";
|
||||||
|
assert_no_csp_event_for_url(t, url);
|
||||||
|
|
||||||
|
fetch(url)
|
||||||
|
.then(t.step_func_done(r => assert_equals(r.status, 200)));
|
||||||
|
}, "Cross-origin 'fetch()' in " + self.location.protocol + self.location.search);
|
||||||
|
|
||||||
|
async_test(t => {
|
||||||
|
var url = "http://{{domains[www]}}:{{ports[http][1]}}/content-security-policy/support/resource.py?cross-origin-xhr";
|
||||||
|
assert_no_csp_event_for_url(t, url);
|
||||||
|
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", url);
|
||||||
|
xhr.onload = t.step_func_done();
|
||||||
|
xhr.onerror = t.unreached_func();
|
||||||
|
xhr.send();
|
||||||
|
}, "Cross-origin XHR in " + self.location.protocol + self.location.search);
|
||||||
|
|
||||||
|
// Same-origin redirecting to cross-origin
|
||||||
|
async_test(t => {
|
||||||
|
var url = "{{location[server]}}/common/redirect-opt-in.py?status=307&location=http://{{domains[www]}}:{{ports[http][1]}}/content-security-policy/support/resource.py?cross-origin-fetch";
|
||||||
|
assert_no_csp_event_for_url(t, url);
|
||||||
|
|
||||||
|
fetch(url)
|
||||||
|
.then(t.step_func_done(r => assert_equals(r.status, 200)));
|
||||||
|
}, "Same-origin => cross-origin 'fetch()' in " + self.location.protocol + self.location.search);
|
||||||
|
|
||||||
|
done();
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
importScripts("{{location[server]}}/resources/testharness.js");
|
||||||
|
importScripts("{{location[server]}}/content-security-policy/support/testharness-helper.js");
|
||||||
|
|
||||||
|
// Same-origin
|
||||||
|
async_test(t => {
|
||||||
|
var url = "{{location[server]}}/common/text-plain.txt?same-origin-fetch";
|
||||||
|
assert_no_csp_event_for_url(t, url);
|
||||||
|
|
||||||
|
fetch(url)
|
||||||
|
.then(t.step_func_done(r => assert_equals(r.status, 200)));
|
||||||
|
}, "Same-origin 'fetch()' in " + self.location.protocol + self.location.search);
|
||||||
|
|
||||||
|
async_test(t => {
|
||||||
|
var url = "{{location[server]}}/common/text-plain.txt?same-origin-xhr";
|
||||||
|
assert_no_csp_event_for_url(t, url);
|
||||||
|
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", url);
|
||||||
|
xhr.onload = t.step_func_done();
|
||||||
|
xhr.onerror = t.unreached_func();
|
||||||
|
xhr.send();
|
||||||
|
}, "Same-origin XHR in " + self.location.protocol + self.location.search);
|
||||||
|
|
||||||
|
// Cross-origin
|
||||||
|
async_test(t => {
|
||||||
|
var url = "http://{{domains[www]}}:{{ports[http][1]}}/common/text-plain.txt?cross-origin-fetch";
|
||||||
|
|
||||||
|
Promise.all([
|
||||||
|
// TODO(mkwst): A 'securitypolicyviolation' event should fire.
|
||||||
|
fetch(url)
|
||||||
|
.catch(t.step_func(e => assert_true(e instanceof TypeError)))
|
||||||
|
]).then(t.step_func_done());
|
||||||
|
}, "Cross-origin 'fetch()' in " + self.location.protocol + self.location.search);
|
||||||
|
|
||||||
|
async_test(t => {
|
||||||
|
var url = "http://{{domains[www]}}:{{ports[http][1]}}/common/text-plain.txt?cross-origin-xhr";
|
||||||
|
|
||||||
|
Promise.all([
|
||||||
|
// TODO(mkwst): A 'securitypolicyviolation' event should fire.
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open("GET", url);
|
||||||
|
xhr.onload = t.step_func(_ => reject("xhr.open should have thrown."));
|
||||||
|
xhr.onerror = t.step_func(resolve);
|
||||||
|
xhr.send();
|
||||||
|
})
|
||||||
|
]).then(t.step_func_done());
|
||||||
|
}, "Cross-origin XHR in " + self.location.protocol + self.location.search);
|
||||||
|
|
||||||
|
// Same-origin redirecting to cross-origin
|
||||||
|
async_test(t => {
|
||||||
|
var url = "{{location[server]}}/common/redirect-opt-in.py?status=307&location=http://{{domains[www]}}:{{ports[http][1]}}/common/text-plain.txt?cross-origin-fetch";
|
||||||
|
|
||||||
|
// TODO(mkwst): A 'securitypolicyviolation' event should fire.
|
||||||
|
fetch(url)
|
||||||
|
.catch(t.step_func_done(e => assert_true(e instanceof TypeError)))
|
||||||
|
}, "Same-origin => cross-origin 'fetch()' in " + self.location.protocol + self.location.search);
|
||||||
|
|
||||||
|
done();
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
importScripts("{{location[server]}}/resources/testharness.js");
|
||||||
|
|
||||||
|
test(t => {
|
||||||
|
importScripts("http://{{domains[www]}}:{{ports[http][1]}}/content-security-policy/support/testharness-helper.js");
|
||||||
|
}, "Cross-origin `importScripts()` not blocked in " + self.location.protocol + self.location.search);
|
||||||
|
|
||||||
|
test(t => {
|
||||||
|
assert_equals(2, eval("1+1"));
|
||||||
|
assert_equals(2, (new Function("return 1+1;"))());
|
||||||
|
}, "`eval()` not blocked in " + self.location.protocol + self.location.search);
|
||||||
|
|
||||||
|
async_test(t => {
|
||||||
|
self.callback = t.step_func_done();
|
||||||
|
|
||||||
|
setTimeout("self.callback();", 1);
|
||||||
|
}, "`setTimeout([string])` not blocked in " + self.location.protocol + self.location.search);
|
||||||
|
|
||||||
|
done();
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
importScripts("{{location[server]}}/resources/testharness.js");
|
||||||
|
importScripts("{{location[server]}}/content-security-policy/support/testharness-helper.js");
|
||||||
|
|
||||||
|
test(t => {
|
||||||
|
self.a = false;
|
||||||
|
assert_throws("NetworkError",
|
||||||
|
_ => importScripts("http://{{domains[www]}}:{{ports[http][1]}}/content-security-policy/support/var-a.js"),
|
||||||
|
"importScripts should throw `NetworkError`");
|
||||||
|
assert_false(self.a);
|
||||||
|
}, "Cross-origin `importScripts()` blocked in " + self.location.protocol + self.location.search);
|
||||||
|
|
||||||
|
test(t => {
|
||||||
|
assert_throws(EvalError(),
|
||||||
|
_ => eval("1 + 1"),
|
||||||
|
"`eval()` should throw 'EvalError'.");
|
||||||
|
|
||||||
|
assert_throws(EvalError(),
|
||||||
|
_ => new Function("1 + 1"),
|
||||||
|
"`new Function()` should throw 'EvalError'.");
|
||||||
|
}, "`eval()` blocked in " + self.location.protocol + self.location.search);
|
||||||
|
|
||||||
|
async_test(t => {
|
||||||
|
waitUntilCSPEventForEval(t, 27)
|
||||||
|
.then(t.step_func_done());
|
||||||
|
|
||||||
|
self.setTimeoutTest = t;
|
||||||
|
var result = setTimeout("(self.setTimeoutTest.unreached_func('setTimeout([string]) should not execute.'))()", 1);
|
||||||
|
assert_equals(result, 0);
|
||||||
|
}, "`setTimeout([string])` blocked in " + self.location.protocol + self.location.search);
|
||||||
|
|
||||||
|
done();
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue