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:
James Graham 2017-04-04 17:01:41 +01:00
parent beabf923ac
commit 1325009ca4
924 changed files with 33612 additions and 6217 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,2 +1,2 @@
local: 5dc5249408ecc0003f0c68d32a8e782dec23fd36
upstream: aef9b4f327326fd32420281f9bc1ca9b60d553b3
local: 0000000000000000000000000000000000000000
upstream: 8181d7f09ee35cb521452bb727a48a1667901afd

View file

@ -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

View file

@ -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:

View 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;
}

View file

@ -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>

View file

@ -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");
});

View file

@ -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>

View file

@ -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); });
});

View file

@ -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>

View file

@ -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); });
});

View file

@ -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>

View file

@ -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");
});

View file

@ -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); });
});

View file

@ -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>

View file

@ -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

View file

@ -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/).

View file

@ -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>

View file

@ -0,0 +1,5 @@
importScripts('/resources/testharness.js');
test(() => {
assert_false('FileReaderSync' in self);
}, '"FileReaderSync" should not be supported in service workers');

View file

@ -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">

View file

@ -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">

View file

@ -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>

View file

@ -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>

View 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>

View file

@ -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>

View file

@ -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

View file

@ -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>

View file

@ -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)

View file

@ -2,9 +2,7 @@ The web-platform-tests Project [![IRC chat](https://goo.gl/6nCIks)](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
---------

View file

@ -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")

View file

@ -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")
}

View file

@ -1,4 +0,0 @@
importScripts("/resources/testharness.js");
importScripts("getRandomValues.js");
run_test();
done();

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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

View file

@ -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)

View file

@ -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"

View file

@ -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")))

View file

@ -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"

View file

@ -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"

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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()

View file

@ -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)
}

View file

@ -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>

View file

@ -1,4 +0,0 @@
importScripts("/resources/testharness.js");
importScripts("send-usp.js");
run_test();
done();

View file

@ -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

View file

@ -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>

View file

@ -0,0 +1,2 @@
@beverloo
@jakearchibald

View file

@ -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>

View 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>

View 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" };

View file

@ -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.');

View file

@ -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;
}

View 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>

View file

@ -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")

View file

@ -2,4 +2,3 @@ set -ex
./manifest
./lint
./diff-manifest.py

View 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;

View 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>

View file

@ -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`);
};

View file

@ -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.",

View file

@ -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>

View file

@ -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");

View file

@ -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>

View file

@ -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'

View file

@ -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>

View file

@ -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.");

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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;
}

View file

@ -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>

View file

@ -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}}

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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();

View file

@ -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();

View file

@ -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