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
|
||||
upstream: aef9b4f327326fd32420281f9bc1ca9b60d553b3
|
||||
local: 0000000000000000000000000000000000000000
|
||||
upstream: 8181d7f09ee35cb521452bb727a48a1667901afd
|
||||
|
|
|
|||
8
testing/web-platform/tests/.gitmodules
vendored
8
testing/web-platform/tests/.gitmodules
vendored
|
|
@ -5,4 +5,10 @@
|
|||
[submodule "tools"]
|
||||
path = tools
|
||||
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:
|
||||
- pip install -U setuptools
|
||||
- pip install -U requests
|
||||
env: # required at the top-level for allow_failures to work below
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
python: "2.7"
|
||||
env:
|
||||
- SCRIPT=ci_lint.sh
|
||||
env: SCRIPT=ci_lint.sh
|
||||
- os: linux
|
||||
python: "2.7"
|
||||
env:
|
||||
- SCRIPT=ci_built_diff.sh
|
||||
env: SCRIPT=ci_built_diff.sh
|
||||
- os: linux
|
||||
python: "2.7"
|
||||
env: SCRIPT=css/build-css-testsuites.sh
|
||||
- os: linux
|
||||
python: "2.7"
|
||||
addons:
|
||||
|
|
@ -34,8 +36,7 @@ matrix:
|
|||
- libnss3-tools
|
||||
env:
|
||||
- secure: "YTSXPwI0DyCA1GhYrLT9KMEV6b7QQKuEeaQgeFDP38OTzJ1+cIj3CC4SRNqbnJ/6SJwPGcdqSxLuV8m4e5HFFnyCcQnJe6h8EMsTehZ7W3j/fP9UYrJqYqvGpe3Vj3xblO5pwBYmq7sg3jAmmuCgAgOW6VGf7cRMucrsmFeo7VM="
|
||||
- SCRIPT=ci_stability.sh
|
||||
- PRODUCT=firefox:nightly
|
||||
- SCRIPT=ci_stability.sh PRODUCT=firefox:nightly
|
||||
- os: linux
|
||||
sudo: required
|
||||
python: "2.7"
|
||||
|
|
@ -46,8 +47,11 @@ matrix:
|
|||
- fonts-liberation
|
||||
env:
|
||||
- secure: "YTSXPwI0DyCA1GhYrLT9KMEV6b7QQKuEeaQgeFDP38OTzJ1+cIj3CC4SRNqbnJ/6SJwPGcdqSxLuV8m4e5HFFnyCcQnJe6h8EMsTehZ7W3j/fP9UYrJqYqvGpe3Vj3xblO5pwBYmq7sg3jAmmuCgAgOW6VGf7cRMucrsmFeo7VM="
|
||||
- SCRIPT=ci_stability.sh
|
||||
- PRODUCT=chrome:unstable
|
||||
- SCRIPT=ci_stability.sh PRODUCT=chrome:unstable
|
||||
exclude:
|
||||
- env: # exclude empty env from the top-level above
|
||||
allow_failures:
|
||||
- env: SCRIPT=css/build-css-testsuites.sh
|
||||
script:
|
||||
- bash $SCRIPT
|
||||
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>
|
||||
<!-- 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/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.round</h1>
|
||||
<p class="desc">createImageData(w, h) is rounded the same as getImageData(0, 0, w, h)</p>
|
||||
<h1>2d.imageData.create2.double</h1>
|
||||
<p class="desc">createImageData(w, h) double is converted to long</p>
|
||||
|
||||
|
||||
<p class="output">Actual output:</p>
|
||||
|
|
@ -16,13 +16,15 @@
|
|||
|
||||
<ul id="d"></ul>
|
||||
<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) {
|
||||
|
||||
var imgdata1 = ctx.createImageData(10.01, 10.99);
|
||||
var imgdata2 = ctx.getImageData(0, 0, 10.01, 10.99);
|
||||
_assertSame(imgdata1.width, imgdata2.width, "imgdata1.width", "imgdata2.width");
|
||||
_assertSame(imgdata1.height, imgdata2.height, "imgdata1.height", "imgdata2.height");
|
||||
var imgdata2 = ctx.createImageData(-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");
|
||||
|
||||
|
||||
});
|
||||
|
|
@ -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(0, 10); });
|
||||
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, 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.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>
|
||||
<!-- 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/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.tiny</h1>
|
||||
<p class="desc">getImageData() works for sizes smaller than one pixel</p>
|
||||
<h1>2d.imageData.object.ctor.array</h1>
|
||||
<p class="desc">ImageData has a usable constructor</p>
|
||||
|
||||
|
||||
<p class="output">Actual output:</p>
|
||||
|
|
@ -16,13 +16,16 @@
|
|||
|
||||
<ul id="d"></ul>
|
||||
<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) {
|
||||
|
||||
var imgdata = ctx.getImageData(0, 0, 0.0001, 0.0001);
|
||||
_assertSame(imgdata.data.length, imgdata.width*imgdata.height*4, "imgdata.data.length", "imgdata.width*imgdata.height*4");
|
||||
_assertDifferent(window.ImageData, undefined, "window.ImageData", "undefined");
|
||||
|
||||
var array = new Uint8ClampedArray(8);
|
||||
var imgdata = new window.ImageData(array, 1, 2);
|
||||
_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>
|
||||
<!-- 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/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</h1>
|
||||
<p class="desc">ImageData does not have a usable constructor</p>
|
||||
<h1>2d.imageData.object.ctor.size.bounds</h1>
|
||||
<p class="desc">ImageData has a usable constructor</p>
|
||||
|
||||
|
||||
<p class="output">Actual output:</p>
|
||||
|
|
@ -16,11 +16,13 @@
|
|||
|
||||
<ul id="d"></ul>
|
||||
<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) {
|
||||
|
||||
_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;
|
||||
@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
|
||||
desc: createImageData(sw, sh) takes the absolute magnitude of the size arguments
|
||||
testing:
|
||||
|
|
@ -9313,6 +9297,8 @@
|
|||
@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, 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
|
||||
desc: createImageData() throws TypeError if arguments are not finite
|
||||
|
|
@ -9333,15 +9319,17 @@
|
|||
code: |
|
||||
@assert throws TypeError ctx.createImageData(null);
|
||||
|
||||
- name: 2d.imageData.create2.round
|
||||
desc: createImageData(w, h) is rounded the same as getImageData(0, 0, w, h)
|
||||
- name: 2d.imageData.create2.double
|
||||
desc: createImageData(w, h) double is converted to long
|
||||
testing:
|
||||
- 2d.imageData.createround
|
||||
- 2d.imageData.create2.size
|
||||
code: |
|
||||
var imgdata1 = ctx.createImageData(10.01, 10.99);
|
||||
var imgdata2 = ctx.getImageData(0, 0, 10.01, 10.99);
|
||||
@assert imgdata1.width === imgdata2.width;
|
||||
@assert imgdata1.height === imgdata2.height;
|
||||
var imgdata2 = ctx.createImageData(-10.01, -10.99);
|
||||
@assert imgdata1.width === 10;
|
||||
@assert imgdata1.height === 10;
|
||||
@assert imgdata2.width === 10;
|
||||
@assert imgdata2.height === 10;
|
||||
|
||||
- name: 2d.imageData.get.basic
|
||||
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, 0, 10);
|
||||
@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
|
||||
desc: getImageData() throws TypeError if arguments are not finite
|
||||
|
|
@ -9488,15 +9480,17 @@
|
|||
@assert imgdata2.width > imgdata1.width;
|
||||
@assert imgdata2.height > imgdata1.height;
|
||||
|
||||
- name: 2d.imageData.get.tiny
|
||||
desc: getImageData() works for sizes smaller than one pixel
|
||||
- name: 2d.imageData.get.double
|
||||
desc: createImageData(w, h) double is converted to long
|
||||
testing:
|
||||
- 2d.imageData.one
|
||||
- 2d.imageData.get.basic
|
||||
code: |
|
||||
var imgdata = ctx.getImageData(0, 0, 0.0001, 0.0001);
|
||||
@assert imgdata.data.length === imgdata.width*imgdata.height*4;
|
||||
@assert imgdata.width === 1;
|
||||
@assert imgdata.height === 1;
|
||||
var imgdata1 = ctx.getImageData(0, 0, 10.01, 10.99);
|
||||
var imgdata2 = ctx.getImageData(0, 0, -10.01, -10.99);
|
||||
@assert imgdata1.width === 10;
|
||||
@assert imgdata1.height === 10;
|
||||
@assert imgdata2.width === 10;
|
||||
@assert imgdata2.height === 10;
|
||||
|
||||
- name: 2d.imageData.get.nonpremul
|
||||
desc: getImageData() returns non-premultiplied colours
|
||||
|
|
@ -9664,13 +9658,57 @@
|
|||
@assert imgdata.data[2] === 0;
|
||||
@assert imgdata.data[3] === 0;
|
||||
|
||||
- name: 2d.imageData.object.ctor
|
||||
desc: ImageData does not have a usable constructor
|
||||
- name: 2d.imageData.object.ctor.size
|
||||
desc: ImageData has a usable constructor
|
||||
testing:
|
||||
- 2d.imageData.type
|
||||
code: |
|
||||
@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
|
||||
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
|
||||
the content of this repository or the use thereof indicates conformance to a
|
||||
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>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
|
|
@ -48,6 +49,10 @@
|
|||
assert_false('isClosed' in b, 'isClosed in b');
|
||||
assert_false('isClosed' in Blob.prototype, 'isClosed in Blob.prototype');
|
||||
}, '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>
|
||||
</body>
|
||||
</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>
|
||||
<meta charset=utf-8>
|
||||
<title>IDBCursor direction - index with keyrange</title>
|
||||
<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">
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset=utf-8>
|
||||
<title>IDBCursor direction - object store with keyrange</title>
|
||||
<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">
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
//
|
||||
// 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.
|
||||
function migrateDatabase(testCase, newVersion, migrationCallback) {
|
||||
return migrateNamedDatabase(
|
||||
|
|
@ -37,7 +37,7 @@ function migrateDatabase(testCase, newVersion, migrationCallback) {
|
|||
// open request.
|
||||
//
|
||||
// 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.
|
||||
function migrateNamedDatabase(
|
||||
testCase, databaseName, newVersion, migrationCallback) {
|
||||
|
|
@ -88,10 +88,20 @@ function migrateNamedDatabase(
|
|||
resolve(Promise.resolve(callbackResult).then(() => requestEventPromise));
|
||||
});
|
||||
request.onerror = event => reject(event.target.error);
|
||||
request.onsuccess = () => reject(new Error(
|
||||
'indexedDB.open should not succeed without creating a ' +
|
||||
'versionchange transaction'));
|
||||
}).then(event => event.target.result || event.target.error);
|
||||
request.onsuccess = () => {
|
||||
const database = request.result;
|
||||
testCase.add_cleanup(() => { database.close(); });
|
||||
reject(new Error(
|
||||
'indexedDB.open should not succeed without creating a ' +
|
||||
'versionchange transaction'));
|
||||
};
|
||||
}).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.
|
||||
|
|
@ -100,7 +110,7 @@ function migrateNamedDatabase(
|
|||
// given the created database, the versionchange transaction, and the database
|
||||
// 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.
|
||||
function createDatabase(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
|
||||
// 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.
|
||||
function createNamedDatabase(testCase, databaseName, setupCallback) {
|
||||
const request = indexedDB.deleteDatabase(databaseName);
|
||||
const eventWatcher = requestWatcher(testCase, request);
|
||||
|
||||
return eventWatcher.wait_for('success').then(event =>
|
||||
migrateNamedDatabase(testCase, databaseName, 1, setupCallback));
|
||||
return eventWatcher.wait_for('success').then(event => {
|
||||
testCase.add_cleanup(() => { indexedDB.deleteDatabase(databaseName); });
|
||||
return migrateNamedDatabase(testCase, databaseName, 1, setupCallback)
|
||||
});
|
||||
}
|
||||
|
||||
// Opens an IndexedDB database without performing schema changes.
|
||||
//
|
||||
// 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.
|
||||
function openDatabase(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.
|
||||
//
|
||||
// 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.
|
||||
function openNamedDatabase(testCase, databaseName, version) {
|
||||
const request = indexedDB.open(databaseName, version);
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#Dual-License for W3C Test Suites
|
||||
# Dual-License for W3C Test Suites
|
||||
|
||||
All documents in this Repository are licensed by contributors to be distributed under both the [W3C Test Suite License](#w3c-test-suite-license) and the [W3C 3-clause BSD License](#w3c-3-clause-bsd-license), reproduced below. The choice of license is up to the licensee. For more information, see [Licenses for W3C Test Suites](https://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright.html)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
cross-browser testsuite for the Web-platform stack. However, for mainly
|
||||
historic reasons, the CSS WG testsuite is in a separate repository,
|
||||
[csswg-test](https://github.com/w3c/csswg-test). Writing tests in a way
|
||||
cross-browser testsuite for the Web-platform stack. Writing tests in a way
|
||||
that allows them to be run in all browsers gives browser projects
|
||||
confidence that they are shipping software that is compatible with other
|
||||
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
|
||||
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
|
||||
===========
|
||||
|
||||
The master branch is automatically synced to http://w3c-test.org/.
|
||||
|
||||
Pull requests are automatically mirrored to
|
||||
http://w3c-test.org/submissions/ a few minutes after someone with merge
|
||||
access has added a comment with "LGTM" (or "w3c-test:mirror") to indicate
|
||||
the PR has been checked.
|
||||
Pull requests are
|
||||
[automatically mirrored](http://w3c-test.org/submissions/) except those
|
||||
that modify sensitive resources (such as `.py`). The latter require
|
||||
someone with merge access to comment with "LGTM" or "w3c-test:mirror" to
|
||||
indicate the pull request has been checked.
|
||||
|
||||
Finding Things
|
||||
==============
|
||||
|
||||
Each top-level directory represents a W3C specification: the name
|
||||
matches the shortname used after the canonical address of the said
|
||||
specification under http://www.w3.org/TR/ .
|
||||
Each top-level directory matches the shortname used by a standard, with
|
||||
some exceptions. (Typically the shortname is from the standard's
|
||||
corresponding GitHub repository.)
|
||||
|
||||
For some of the specifications, the tree under the top-level directory
|
||||
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.
|
||||
* 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
|
||||
---------
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
<meta charset=utf-8>
|
||||
<title>DOMException-throwing tests</title>
|
||||
<link rel=author title="Aryeh Gregor" href=ayg@aryeh.name>
|
||||
<div id=log></div>
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ test(() => {
|
|||
const client = new XMLHttpRequest
|
||||
client.open("GET", "resources/header-content-length.asis", false)
|
||||
client.send()
|
||||
assert_equals(client.getAllResponseHeaders(), "CONTENT-LENGTH: 0\r\n")
|
||||
assert_equals(client.getAllResponseHeaders(), "content-length: 0\r\n")
|
||||
})
|
||||
test(() => {
|
||||
const client = new XMLHttpRequest
|
||||
|
|
@ -17,11 +17,11 @@ test(() => {
|
|||
client.setRequestHeader("content-TYPE", "x/x")
|
||||
client.send()
|
||||
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(() => {
|
||||
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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
<script src="/resources/testharness.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>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<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 expectations = {
|
||||
'Referer header': 'referer: '+(location.href.replace(/[^/]*$/, ''))+"resources/workerxhr-origin-referrer.js\n",
|
||||
'Origin header': 'origin: '+location.protocol+'//'+location.hostname+((location.port === "")?"":":"+location.port)+'\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',
|
||||
'Request URL test' : (location.href.replace(/[^/]*$/, ''))+'resources/requri.py?full'
|
||||
}
|
||||
// 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-Headers', 'authorization, x-user, x-pass');
|
||||
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),
|
||||
"XMLHttpRequest",
|
||||
"resources",
|
||||
"authentication.py"))
|
||||
auth = imp.load_source("", os.path.abspath("XMLHttpRequest/resources/authentication.py"))
|
||||
if request.method == "OPTIONS":
|
||||
return ""
|
||||
else:
|
||||
return auth.main(request, response)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,15 +3,27 @@ def main(request, response):
|
|||
match = request.headers.get("If-None-Match", None)
|
||||
date = request.GET.first("date", "")
|
||||
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:
|
||||
response.headers.set("ETag", '"%s"' % tag)
|
||||
elif 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
|
||||
(modified is not None and modified == date)):
|
||||
response.status = (304, "SUPERCOOL")
|
||||
return ""
|
||||
else:
|
||||
if not cors:
|
||||
response.headers.set("Access-Control-Allow-Origin", "*")
|
||||
response.headers.set("Content-Type", "text/plain")
|
||||
return "MAYBE NOT"
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ def main(request, response):
|
|||
delay = int(request.GET.first("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-Query", request.url_parts.query if request.url_parts.query else "NO"))
|
||||
headers.append(("X-Request-Content-Length", request.headers.get("Content-Length", "NO")))
|
||||
|
|
|
|||
|
|
@ -3,4 +3,5 @@ import time
|
|||
def main(request, response):
|
||||
delay = float(request.GET.first("ms", 500))
|
||||
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):
|
||||
code = int(request.GET.first("code", 302))
|
||||
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"
|
||||
else:
|
||||
return (code, "WEBSRT MARKETING"), [("Location", location)], "TEST"
|
||||
|
|
|
|||
|
|
@ -5,15 +5,11 @@
|
|||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.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>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
var test = async_test()
|
||||
test.step(function() {
|
||||
async_test(test => {
|
||||
var client = new XMLHttpRequest(),
|
||||
urlstart = location.host + location.pathname.replace(/\/[^\/]*$/, '/'),
|
||||
user = token()
|
||||
|
|
@ -22,15 +18,11 @@
|
|||
client.setRequestHeader("x-user", user)
|
||||
client.setRequestHeader("x-pass", 'pass')
|
||||
client.setRequestHeader('Authorization', 'Basic ' + btoa(user + ":pass"))
|
||||
client.onreadystatechange = function () {
|
||||
if (client.readyState < 4) {return}
|
||||
test.step( function () {
|
||||
assert_true(client.responseText == (user + '\npass'), 'responseText should contain the right user and password')
|
||||
client.onload = test.step_func_done(() => {
|
||||
assert_equals(client.responseText, user + '\npass', 'responseText should contain the right user and password')
|
||||
assert_equals(client.status, 200)
|
||||
assert_equals(client.getResponseHeader('x-challenge'), 'DID-NOT')
|
||||
test.done()
|
||||
} )
|
||||
}
|
||||
})
|
||||
client.send(null)
|
||||
})
|
||||
</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>
|
||||
<html>
|
||||
<head>
|
||||
<title>XMLHttpRequest: send() - unserializable Document</title>
|
||||
<script src="/resources/testharness.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>
|
||||
<script>
|
||||
function request_throws(input) {
|
||||
test(function() {
|
||||
var client = new XMLHttpRequest()
|
||||
client.open("POST", "resources/content.py", false)
|
||||
assert_throws("InvalidStateError", function() { client.send(input) })
|
||||
})
|
||||
}
|
||||
var doc = document.implementation.createDocument(null, null, null)
|
||||
while(doc.childNodes.length) {
|
||||
doc.removeChild(doc.childNodes[0])
|
||||
}
|
||||
request_throws(doc)
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<title>XMLHttpRequest: send() - Document with serialization errors</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
function serialize(input, output) {
|
||||
async_test(t => {
|
||||
const client = new XMLHttpRequest
|
||||
client.open("POST", "resources/content.py")
|
||||
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)
|
||||
serialize(doc, "")
|
||||
doc.appendChild(doc.createElement("test:test"))
|
||||
serialize(doc, "<test:test/>")
|
||||
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>
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@
|
|||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<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>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
|
|
@ -28,6 +26,8 @@
|
|||
url(host_info.HTTP_REMOTE_ORIGIN)
|
||||
url("javascript:alert('FAIL')")
|
||||
url("folder.txt")
|
||||
url("about:blank")
|
||||
url("blob:bogusidentifier")
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
<title>XMLHttpRequest: send() - Redirect to CORS-enabled resource</title>
|
||||
<script src="/resources/testharness.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>
|
||||
<body>
|
||||
<div id="log"></div>
|
||||
|
|
@ -13,56 +12,76 @@
|
|||
if (body === null) {
|
||||
return { body: "", type: "NO" };
|
||||
}
|
||||
|
||||
if (typeof body == "string") {
|
||||
return { body: body, type: "text/plain;charset=UTF-8" };
|
||||
}
|
||||
|
||||
if (body instanceof Uint8Array) {
|
||||
var arr = Array.prototype.slice.call(body);
|
||||
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) {
|
||||
var test = async_test(document.title + " (" + name + ")")
|
||||
test.step(function() {
|
||||
function redirect(code, name = code, method = "GET", body = null, explicitType = null, safelistContentType = false) {
|
||||
async_test(t => {
|
||||
var client = new XMLHttpRequest()
|
||||
client.onreadystatechange = function() {
|
||||
test.step(function() {
|
||||
if (client.readyState == 4) {
|
||||
assert_equals(client.status, 200);
|
||||
assert_equals(client.getResponseHeader("x-request-method"),
|
||||
method);
|
||||
client.onreadystatechange = t.step_func(() => {
|
||||
if (client.readyState == 4) {
|
||||
if (explicitType !== "application/x-pony" || safelistContentType) {
|
||||
var { body: expectedBody, type: expectedType } = extractBody(body);
|
||||
if (setExplicitType) {
|
||||
expectedType = "application/x-pony";
|
||||
if (explicitType !== null) {
|
||||
expectedType = explicitType
|
||||
}
|
||||
assert_equals(client.getResponseHeader("x-request-content-type"),
|
||||
expectedType);
|
||||
assert_equals(client.getResponseHeader("x-request-data"),
|
||||
expectedBody);
|
||||
test.done();
|
||||
if (((code === "301" || code === "302") && method === "POST") || code === "303") {
|
||||
method = "GET"
|
||||
expectedBody = ""
|
||||
}
|
||||
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)
|
||||
if (setExplicitType) {
|
||||
client.setRequestHeader("Content-Type", "application/x-pony")
|
||||
client.open(method, "resources/redirect.py?location="+encodeURIComponent("http://www2."+location.host+(location.pathname.replace(/[^\/]+$/, ''))+'resources/corsenabled.py')+safelist+"&code=" + code)
|
||||
if (explicitType !== null) {
|
||||
client.setRequestHeader("Content-Type", explicitType)
|
||||
}
|
||||
client.send(body)
|
||||
})
|
||||
}, document.title + " (" + name + ")")
|
||||
}
|
||||
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("303")
|
||||
redirect("303", "303 LALA with string and explicit Content-Type safelisted", "LALA", "test", "application/x-pony", true)
|
||||
redirect("307")
|
||||
redirect("307", "307 post with null", "POST", null, false);
|
||||
redirect("307", "307 post with string", "POST", "hello", false);
|
||||
redirect("307", "307 post with typed array", "POST", new Uint8Array([65, 66, 67]), false);
|
||||
redirect("307", "307 post with null", "POST", null)
|
||||
redirect("307", "307 post with string", "POST", "hello")
|
||||
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>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<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/testharnessreport.js"></script>
|
||||
<title>XMLHttpRequest: sync requests should block events on pending async requests</title>
|
||||
|
|
@ -22,7 +19,7 @@
|
|||
{
|
||||
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.onreadystatechange = t.step_func(() => {
|
||||
xhr_async.onreadystatechange = test.step_func(() => {
|
||||
actual.push('async ' + xhr_async.readyState)
|
||||
if(xhr_async.readyState === 4 && actual.indexOf('sync 4')>-1){
|
||||
VerifyResult()
|
||||
|
|
@ -33,7 +30,7 @@
|
|||
test.step_timeout(() => {
|
||||
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.onreadystatechange = t.step_func(() => {
|
||||
xhr_sync.onreadystatechange = test.step_func(() => {
|
||||
actual.push('sync ' + xhr_sync.readyState)
|
||||
if(xhr_sync.readyState === 4 && actual.indexOf('async 4')>-1){
|
||||
VerifyResult()
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ function encode(n) {
|
|||
return "%" + (s.length === 2 ? s : '0' + s);
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
var tests = [];
|
||||
var overall_test = async_test("Overall fetch with URLSearchParams");
|
||||
for (var i = 0; i < NUM_TESTS; i++) {
|
||||
|
|
@ -45,4 +44,3 @@ function run_test() {
|
|||
usp.append("a" + i, String.fromCharCode(i));
|
||||
}
|
||||
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>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<div id=log>
|
||||
<div id=log></div>
|
||||
<script>
|
||||
async_test(t => {
|
||||
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):
|
||||
full_cmd = ["git", cmd] + list(args)
|
||||
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:
|
||||
logger.error("Git command exited with status %i" % e.returncode)
|
||||
logger.error(e.output)
|
||||
|
|
@ -363,10 +364,9 @@ class pwd(object):
|
|||
self.old_dir = None
|
||||
|
||||
|
||||
def fetch_wpt_master(user):
|
||||
"""Fetch the master branch via git."""
|
||||
def fetch_wpt(user, *args):
|
||||
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():
|
||||
|
|
@ -390,12 +390,44 @@ def install_wptrunner():
|
|||
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."""
|
||||
root = os.path.abspath(os.curdir)
|
||||
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)
|
||||
if not files:
|
||||
return []
|
||||
|
|
@ -557,7 +589,7 @@ def process_results(log, iterations):
|
|||
results = handler.results
|
||||
for test_name, test in results.iteritems():
|
||||
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():
|
||||
if is_inconsistent(subtest["status"], iterations):
|
||||
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('\n', u'\\n')
|
||||
s = s.replace('\r', u'\\r')
|
||||
s = s.replace('`', u'\\`')
|
||||
s = s.replace('`', u'')
|
||||
return s
|
||||
|
||||
|
||||
|
|
@ -726,14 +758,16 @@ def main():
|
|||
logger.critical("Unrecognised browser %s" % browser_name)
|
||||
return 1
|
||||
|
||||
fetch_wpt_master(args.user)
|
||||
fetch_wpt(args.user, "master:master")
|
||||
|
||||
head_sha1 = get_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
|
||||
# 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:
|
||||
logger.info("No files changed")
|
||||
|
|
|
|||
|
|
@ -2,4 +2,3 @@ set -ex
|
|||
|
||||
./manifest
|
||||
./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/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/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/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.",
|
||||
|
|
@ -2435,7 +2435,7 @@
|
|||
"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/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/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.",
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue