Auto merge of #27711 - servo-wpt-sync:wpt_update_19-10-2020, r=servo-wpt-sync

Sync WPT with upstream (19-10-2020)

Automated downstream sync of changes from upstream as of 19-10-2020.
[no-wpt-sync]
r? @servo-wpt-sync
This commit is contained in:
bors-servo 2020-10-19 07:00:22 -04:00 committed by GitHub
commit 938e96b68c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
62 changed files with 550 additions and 198 deletions

View file

@ -1,4 +0,0 @@
[hit-test-floats-002.html]
[Hit test float]
expected: FAIL

View file

@ -1,4 +0,0 @@
[hit-test-floats-005.html]
[Miss clipped float]
expected: FAIL

View file

@ -5,9 +5,6 @@
[[data-expected-height\] 7]
expected: FAIL
[[data-expected-height\] 1]
expected: FAIL
[[data-expected-height\] 2]
[[data-expected-height\] 4]
expected: FAIL

View file

@ -0,0 +1,4 @@
[elementFromPoint-001.html]
[CSSOM View - 5 - extensions to the Document interface]
expected: FAIL

View file

@ -312,24 +312,21 @@
[Response: combined response Content-Type: text/html;" \\" text/plain ";charset=GBK]
expected: NOTRUN
[<iframe>: separate response Content-Type: text/plain */*;charset=gbk]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;" text/plain]
expected: FAIL
[<iframe>: combined response Content-Type: text/html */*;charset=gbk]
expected: FAIL
[<iframe>: combined response Content-Type: */* text/html]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;charset=gbk text/plain text/html]
expected: FAIL
[<iframe>: separate response Content-Type: text/plain */*]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;x=" text/plain]
[<iframe>: combined response Content-Type: text/html */*]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;" text/plain]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;" \\" text/plain]
expected: FAIL

View file

@ -11,3 +11,6 @@
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!]
expected: FAIL
[X-Content-Type-Options%3A%20'NosniFF']
expected: FAIL

View file

@ -1,4 +1,4 @@
[traverse_the_history_4.html]
[traverse_the_history_3.html]
[Multiple history traversals, last would be aborted]
expected: FAIL

View file

@ -1,2 +0,0 @@
[cross-origin-objects-on-new-window.html]
expected: TIMEOUT

View file

@ -1,4 +1,5 @@
[embedded-opener-remove-frame.html]
expected: CRASH
[opener of discarded nested browsing context]
expected: FAIL

View file

@ -1,2 +0,0 @@
[networkState_during_loadstart.html]
expected: TIMEOUT

View file

@ -1,5 +1,5 @@
[iframe_sandbox_popups_escaping-1.html]
expected: CRASH
expected: TIMEOUT
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: TIMEOUT

View file

@ -1,5 +1,5 @@
[iframe_sandbox_popups_escaping-2.html]
expected: TIMEOUT
expected: CRASH
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: TIMEOUT

View file

@ -1,4 +1,5 @@
[iframe_sandbox_popups_escaping-3.html]
expected: TIMEOUT
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: FAIL
expected: TIMEOUT

View file

@ -1,5 +1,5 @@
[iframe_sandbox_popups_nonescaping-2.html]
expected: TIMEOUT
expected: CRASH
[Check that popups from a sandboxed iframe do not escape the sandbox]
expected: NOTRUN

View file

@ -0,0 +1,4 @@
[form-double-submit-3.html]
[<button> should have the same double-submit protection as <input type=submit>]
expected: FAIL

View file

@ -1,13 +1,14 @@
[htmlanchorelement_noopener.html]
expected: TIMEOUT
[Check that targeting of rel=noopener with a given name reuses an existing window with that name]
expected: FAIL
[Check that rel=noopener with target=_top does a normal load]
expected: FAIL
expected: NOTRUN
[Check that rel=noopener with target=_parent does a normal load]
expected: FAIL
expected: NOTRUN
[Check that rel=noopener with target=_self does a normal load]
expected: FAIL
expected: NOTRUN

View file

@ -4,5 +4,5 @@
expected: TIMEOUT
[The entry settings object while executing the compiled callback via Web IDL's invoke must be that of the node document]
expected: TIMEOUT
expected: FAIL

View file

@ -1,6 +1,7 @@
[promise-rejection-events.html]
expected: TIMEOUT
[delayed handling: delaying handling rejected promise created from createImageBitmap will cause both events to fire]
expected: FAIL
expected: TIMEOUT
[unhandledrejection: from createImageBitmap which is UA triggered]
expected: FAIL

View file

@ -161,3 +161,6 @@
[X SNR (43.824040882296586 dB) is not greater than or equal to 65.737. Got 43.824040882296586.]
expected: FAIL
[X Stitched sine-wave buffers at sample rate 43800 does not equal [0,0.06264832615852356,0.12505052983760834,0.18696144223213196,0.24813786149024963,0.308339387178421,0.36732959747314453,0.4248766601085663,0.480754554271698,0.5347436666488647,0.5866320133209229,0.6362156271934509,0.6832997798919678,0.7276994585990906,0.7692402601242065,0.8077589869499207...\] with an element-wise tolerance of {"absoluteThreshold":0.0038986,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[28696\]\t2.9820817510119912e-20\t9.3139332532882690e-1\t9.3139332532882690e-1\t1.0000000000000000e+0\t3.8985999999999999e-3\n\t[28697\]\t7.0477002859115601e-1\t9.0675884485244751e-1\t2.0198881626129150e-1\t2.2275913536212616e-1\t3.8985999999999999e-3\n\tMax AbsError of 9.3139332532882690e-1 at index of 28696.\n\tMax RelError of 1.0000000000000000e+0 at index of 28696.\n]
expected: FAIL

View file

@ -1,5 +1,4 @@
[audiocontext-not-fully-active.html]
expected: TIMEOUT
[frame in navigated remote-site frame]
expected: FAIL

View file

@ -0,0 +1,5 @@
[018.html]
expected: TIMEOUT
[origin of the script that invoked the method, javascript:]
expected: TIMEOUT

View file

@ -0,0 +1,5 @@
[018.html]
expected: TIMEOUT
[origin of the script that invoked the method, javascript:]
expected: TIMEOUT

View file

@ -1,4 +1,5 @@
[003.html]
expected: ERROR
[shared]
expected: FAIL

View file

@ -329883,7 +329883,7 @@
[]
],
"density-corrected-size-bg-ref.html": [
"758ca8edc60adccf491f7db3aa40dbba9d75798b",
"154c1344444c45180628d858ed053434fbd9cab2",
[]
],
"density-corrected-size-img-ref.html": [
@ -347221,17 +347221,29 @@
"6092c0d767050d0c1b13cfd2360f7a7f17d656a5",
[]
],
"common-test-service-worker.js": [
"6985c901fa683a2585ae28cdb3cd5a9711df8222",
[]
],
"resources": {
"common-test-helper-iframe.js": [
"597955fea1f9dc115b6910df59fbb0c5edc1d008",
[]
],
"common-test-helper.js": [
"f7269dba06743efec3bc9aae21556df66d09f52a",
"2bf99184a0c9c944551b472a3be6960dbf159128",
[]
],
"data-base-url.json": [
"81fcf087425c70eefa7d3c3465be59684fb1a521",
[]
],
"empty-import-map-internal.json": [
"59390c89f6b4da9ca95da0142d48022e8dc25f40",
[]
],
"empty-import-map.json": [
"ce6c185498fa38c5e2fcd4e7ba36503778ad0ba7",
"ff85a6d69d5ded8d4fb917ae767748d8903bc4e7",
[]
],
"overlapping-entries.json": [
@ -348758,7 +348770,7 @@
]
},
"lint.ignore": [
"fe2933bb8a31cb7d5a8c39eee06626f1c7b261ac",
"b44faa491f9ad0b4873b9d56cff479310e9c392c",
[]
],
"loading": {
@ -349738,7 +349750,7 @@
[]
],
"mediasource-worker-util.js": [
"e0c4bdc0e10bb5707f7af75bf6cafa293a6f7b9b",
"4cee4862fa4e6c39c43fee7af1a332e8a7cd7ce2",
[]
]
},
@ -469913,6 +469925,13 @@
{}
]
],
"fieldset-percent-height.html": [
"bbe40785be2f0738896e648ce23bc90b9f50c558",
[
null,
{}
]
],
"fieldset-percentage-block-size.html": [
"1c221555c305bd9039558389b3f22ee00d65f8b9",
[
@ -484958,8 +484977,8 @@
}
},
"common": {
"parsing.tentative.html": [
"d3334d7bbb9b4406397f96b596e71463eb252791",
"parsing.tentative.https.html": [
"0dc9e24c8d84ddf06ef38f874605a20712cda214",
[
null,
{
@ -484967,8 +484986,17 @@
}
]
],
"resolving.tentative.html": [
"8dd3e3a2e710f52b05cc34e36a8535d211a480de",
"resolving-internal.tentative.https.html": [
"a9f7c82fd879ca557afd2db85d35901e066e919b",
[
null,
{
"timeout": "long"
}
]
],
"resolving.tentative.https.html": [
"abb30e0afa4f41c306d2a5b1eee788bdd94390bb",
[
null,
{
@ -489208,15 +489236,22 @@
]
],
"dedicated-worker": {
"mediasource-worker-attach.html": [
"b09f05c248531029b9b787597af1ae84e0b65ccd",
"mediasource-worker-objecturl.html": [
"382a9a4f3632a53cd2a94dab121fe34a07d9238d",
[
null,
{}
]
],
"mediasource-worker-objecturl.html": [
"382a9a4f3632a53cd2a94dab121fe34a07d9238d",
"mediasource-worker-play-terminate-worker.html": [
"d1c1c3d3fe8b0feba9eebb8c4796e904c0bcbf2f",
[
null,
{}
]
],
"mediasource-worker-play.html": [
"200f8a851bfc396861ad93b501bcebd7209dffd6",
[
null,
{}
@ -511526,7 +511561,7 @@
]
],
"element-based-offset-clamp.html": [
"6467af199f10224e16f07badf16b73593270f14c",
"b140507493848688f38021573643ce7d6321e514",
[
null,
{}

View file

@ -1,4 +0,0 @@
[hit-test-floats-002.html]
[Hit test float]
expected: FAIL

View file

@ -1,4 +0,0 @@
[hit-test-floats-005.html]
[Miss clipped float]
expected: FAIL

View file

@ -8,9 +8,6 @@
[[data-expected-height\] 3]
expected: FAIL
[[data-expected-height\] 1]
expected: FAIL
[[data-expected-height\] 2]
[[data-expected-height\] 4]
expected: FAIL

View file

@ -0,0 +1,4 @@
[elementFromPoint-001.html]
[CSSOM View - 5 - extensions to the Document interface]
expected: FAIL

View file

@ -312,24 +312,21 @@
[fetch(): separate response Content-Type: text/plain ]
expected: NOTRUN
[<iframe>: separate response Content-Type: text/plain */*;charset=gbk]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;" text/plain]
expected: FAIL
[<iframe>: combined response Content-Type: text/html */*;charset=gbk]
expected: FAIL
[<iframe>: combined response Content-Type: */* text/html]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;charset=gbk text/plain text/html]
expected: FAIL
[<iframe>: separate response Content-Type: text/plain */*]
expected: FAIL
[<iframe>: combined response Content-Type: text/html;x=" text/plain]
[<iframe>: combined response Content-Type: text/html */*]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;" text/plain]
expected: FAIL
[<iframe>: separate response Content-Type: text/html;" \\" text/plain]
expected: FAIL

View file

@ -11,3 +11,6 @@
[X-Content-Type-Options%3A%20nosniff%2C%2C%40%23%24%23%25%25%26%5E%26%5E*()()11!]
expected: FAIL
[X-Content-Type-Options%3A%20'NosniFF']
expected: FAIL

View file

@ -1,4 +1,4 @@
[traverse_the_history_4.html]
[traverse_the_history_3.html]
[Multiple history traversals, last would be aborted]
expected: FAIL

View file

@ -1,2 +0,0 @@
[cross-origin-objects-on-new-window.html]
expected: TIMEOUT

View file

@ -1,4 +1,5 @@
[embedded-opener-remove-frame.html]
expected: CRASH
[opener and "removed" embedded documents]
expected: FAIL

View file

@ -1,2 +0,0 @@
[networkState_during_loadstart.html]
expected: TIMEOUT

View file

@ -1,6 +1,6 @@
[iframe_sandbox_popups_escaping-1.html]
type: testharness
expected: CRASH
expected: TIMEOUT
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: TIMEOUT

View file

@ -1,5 +1,5 @@
[iframe_sandbox_popups_escaping-2.html]
expected: TIMEOUT
expected: CRASH
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: TIMEOUT

View file

@ -1,5 +1,6 @@
[iframe_sandbox_popups_escaping-3.html]
type: testharness
expected: TIMEOUT
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: FAIL
expected: TIMEOUT

View file

@ -1,6 +1,6 @@
[iframe_sandbox_popups_nonescaping-2.html]
type: testharness
expected: TIMEOUT
expected: CRASH
[Check that popups from a sandboxed iframe do not escape the sandbox]
expected: NOTRUN

View file

@ -0,0 +1,4 @@
[form-double-submit-3.html]
[<button> should have the same double-submit protection as <input type=submit>]
expected: FAIL

View file

@ -1,5 +1,6 @@
[htmlanchorelement_noopener.html]
type: testharness
expected: TIMEOUT
[Check that targeting of rel=noopener with a given name ignores an existing window with that name]
expected: NOTRUN
@ -7,11 +8,11 @@
expected: FAIL
[Check that rel=noopener with target=_top does a normal load]
expected: FAIL
expected: NOTRUN
[Check that rel=noopener with target=_parent does a normal load]
expected: FAIL
expected: NOTRUN
[Check that rel=noopener with target=_self does a normal load]
expected: FAIL
expected: NOTRUN

View file

@ -5,5 +5,5 @@
expected: TIMEOUT
[The entry settings object while executing the compiled callback via Web IDL's invoke must be that of the node document]
expected: TIMEOUT
expected: FAIL

View file

@ -1,6 +1,7 @@
[promise-rejection-events.html]
expected: TIMEOUT
[delayed handling: delaying handling rejected promise created from createImageBitmap will cause both events to fire]
expected: FAIL
expected: TIMEOUT
[unhandledrejection: from createImageBitmap which is UA triggered]
expected: FAIL

View file

@ -389,3 +389,6 @@
[X SNR (43.824040882296586 dB) is not greater than or equal to 65.737. Got 43.824040882296586.]
expected: FAIL
[X Stitched sine-wave buffers at sample rate 43800 does not equal [0,0.06264832615852356,0.12505052983760834,0.18696144223213196,0.24813786149024963,0.308339387178421,0.36732959747314453,0.4248766601085663,0.480754554271698,0.5347436666488647,0.5866320133209229,0.6362156271934509,0.6832997798919678,0.7276994585990906,0.7692402601242065,0.8077589869499207...\] with an element-wise tolerance of {"absoluteThreshold":0.0038986,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[28696\]\t2.9820817510119912e-20\t9.3139332532882690e-1\t9.3139332532882690e-1\t1.0000000000000000e+0\t3.8985999999999999e-3\n\t[28697\]\t7.0477002859115601e-1\t9.0675884485244751e-1\t2.0198881626129150e-1\t2.2275913536212616e-1\t3.8985999999999999e-3\n\tMax AbsError of 9.3139332532882690e-1 at index of 28696.\n\tMax RelError of 1.0000000000000000e+0 at index of 28696.\n]
expected: FAIL

View file

@ -1,5 +1,4 @@
[audiocontext-not-fully-active.html]
expected: TIMEOUT
[frame in navigated remote-site frame]
expected: FAIL

View file

@ -0,0 +1,5 @@
[018.html]
expected: TIMEOUT
[origin of the script that invoked the method, javascript:]
expected: TIMEOUT

View file

@ -0,0 +1,5 @@
[018.html]
expected: TIMEOUT
[origin of the script that invoked the method, javascript:]
expected: TIMEOUT

View file

@ -1,5 +1,6 @@
[003.html]
type: testharness
expected: ERROR
[shared]
expected: FAIL

View file

@ -6,26 +6,24 @@
<body>
<style>
body {
--lores: url(resources/exif-resolution-valid-lores.jpg);
--hires: url(resources/exif-resolution-valid-hires.jpg);
--default: url(resources/exif-resolution-none.jpg);
--non-uniform: url(resources/exif-resolution-valid-non-uniform.jpg);
}
.default-bg {background-image: var(--default); }
.lores-bg {background-image: var(--lores); }
.hires-bg {background-image: var(--hires); }
.lores-bg {background-image: var(--default); background-size: 200px 100px; }
.hires-bg {background-image: var(--default); background-size: 50px 25px; }
.invalid-bg {background-image: var(--invalid); }
.non-uniform-bg {background-image: var(--non-uniform); }
.non-uniform-bg {background-image: var(--default); background-size: 50px 100px; }
.box { width: 200px; height: 200px; display: inline-block; }
.tiled {background-repeat: repeat; }
.stretch {background-repeat: no-repeat; background-size: contain; }
.non-uniform-bg.stretch { background-size: 100px 200px; }
</style>
<div class="default-bg tiled box"></div>
<div class="lores-bg tiled box"></div>
<div class="hires-bg tiled box"></div>
<div class="non-uniform-bg tiled box"></div>
<br/>
<div class="lores-bg stretch box"></div>
<div class="default-bg stretch box"></div>
<div class="default-bg stretch box"></div>
<div class="non-uniform-bg stretch box"></div>
</body>

View file

@ -0,0 +1,22 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<table cellspacing="0" cellpadding="0" style="width:100px; height:60px;">
<tr>
<td>
<fieldset style="border:none; padding:0; height:100%; margin:0; margin-top:13px;">
<div><div id="elm"></div></div>
</fieldset>
</td>
</tr>
</table>
<script>
// crbug.com/1138204. Though the specification doesn't mention this behavior,
// there must be no doubt about the expected behavior.
test(() => {
const fieldset = document.querySelector('fieldset');
const initialHeight = fieldset.offsetHeight;
document.querySelector('#elm').style.display = 'none';
assert_equals(fieldset.offsetHeight, initialHeight);
}, 'Fieldset with a percent height should not increase the height on every reflow.');
</script>

View file

@ -0,0 +1,28 @@
let serveImporterScript = false;
self.addEventListener('message', event => {
serveImporterScript = true;
event.source.postMessage('Done');
});
self.addEventListener('fetch', event => {
if (event.request.url.indexOf('common-test-helper-iframe.js') >= 0) {
return;
}
if (serveImporterScript) {
serveImporterScript = false;
event.respondWith(
new Response(
'window.importHelper = (specifier) => import(specifier);',
{headers: {'Content-Type': 'text/javascript'}}
));
} else {
event.respondWith(
new Response(
'export const response = ' +
JSON.stringify({url: event.request.url}) + ';',
{headers: {'Access-Control-Allow-Origin': '*',
'Content-Type': 'text/javascript'}}
));
}
});

View file

@ -2,9 +2,16 @@
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
<script>
// All parsing tests requires Chromium's internal methods.
globalThis.useInternalMethods = true;
</script>
<body>
<script type="module">
import { runTestsFromJSON } from "./resources/common-test-helper.js";
import { runTestsFromJSON, setupGlobalCleanup } from "./resources/common-test-helper.js";
const promises = [];
for (const json of [
'resources/parsing-addresses-absolute.json',
@ -19,8 +26,13 @@ for (const json of [
'resources/parsing-specifier-keys.json',
'resources/parsing-trailing-slashes.json',
]) {
promise_test(() =>
runTestsFromJSON(json),
promise_test(() => {
const promise = runTestsFromJSON(json);
promises.push(promise);
return promise;
},
"Test helper: fetching and sanity checking test JSON: " + json);
}
Promise.all(promises).then(setupGlobalCleanup);
</script>

View file

@ -0,0 +1,31 @@
<!DOCTYPE html>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
<script>
// This test file is for resolution tests that require Chromium's internal
// methods.
// For tests that don't use Chromium's internal methods, see
// resolving.tentative.https.html.
globalThis.useInternalMethods = true;
</script>
<body>
<script type="module">
import { runTestsFromJSON, setupGlobalCleanup } from "./resources/common-test-helper.js";
const promises = [];
for (const json of [
'resources/empty-import-map-internal.json',
]) {
promise_test(() => {
const promise = runTestsFromJSON(json);
promises.push(promise);
return promise;
},
"Test helper: fetching and sanity checking test JSON: " + json);
}
Promise.all(promises).then(setupGlobalCleanup);
</script>

View file

@ -2,9 +2,12 @@
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
<body>
<script type="module">
import { runTestsFromJSON } from "./resources/common-test-helper.js";
import { runTestsFromJSON, setupGlobalCleanup } from "./resources/common-test-helper.js";
const promises = [];
for (const json of [
'resources/scopes.json',
@ -17,8 +20,13 @@ for (const json of [
'resources/overlapping-entries.json',
'resources/resolving-null.json',
]) {
promise_test(() =>
runTestsFromJSON(json),
promise_test(() => {
const promise = runTestsFromJSON(json);
promises.push(promise);
return promise;
},
"Test helper: fetching and sanity checking test JSON: " + json);
}
Promise.all(promises).then(setupGlobalCleanup);
</script>

View file

@ -0,0 +1,103 @@
// Handle errors around fetching, parsing and registering import maps.
const onScriptError = event => {
window.registrationResult = {type: 'FetchError', error: event.error};
return false;
};
window.windowErrorHandler = event => {
window.registrationResult = {type: 'ParseError', error: event.error};
return false;
};
window.addEventListener('error', window.windowErrorHandler);
// Handle specifier resolution requests from the parent frame.
// For failures, we post error names and messages instead of error
// objects themselves and re-create error objects later, to avoid
// issues around serializing error objects which is a quite new feature.
window.addEventListener('message', event => {
if (event.data.action === 'prepareResolve') {
// To get the result of #resolve-a-module-specifier given a script
// (with base URL = |baseURL|) and |specifier|, the service worker
// first serves an importer script with response URL = |baseURL|:
// window.importHelper = (specifier) => import(specifier);
// This is to use |baseURL| as the referringScript's base URL.
// Step 1. Signal the service worker to serve
// the importer script for the next fetch request.
parent.worker.postMessage('serveImporterScript');
} else if (event.data.action === 'resolve') {
if (event.data.expectedURL === null ||
new URL(event.data.expectedURL).protocol === 'https:') {
// Testing without internal methods:
// If the resolution is expected to fail (null case here),
// we can test the failure just by catching the exception.
// If the expected URL is HTTPS, we can test the result by
// intercepting requests by service workers.
// Step 3. Evaluate the importer script as a classic script,
// in order to prevent |baseURL| from being mapped by import maps.
const script = document.createElement('script');
script.onload = () => {
// Step 4. Trigger dynamic import from |baseURL|.
importHelper(event.data.specifier)
.then(module => {
// Step 5. Service worker responds with a JSON containing
// the request URL for the dynamic import
// (= the result of #resolve-a-module-specifier).
parent.postMessage({type: 'ResolutionSuccess',
result: module.response.url},
'*');
})
.catch(e => {
parent.postMessage(
{type: 'Failure', result: e.name, message: e.message},
'*');
});
};
script.src = event.data.baseURL;
document.body.appendChild(script);
} else {
// Testing with internal methods.
// For example, the resolution results are data: URLs.
if (!event.data.useInternalMethods) {
parent.postMessage(
{type: 'Failure',
result: 'Error',
message: 'internals.resolveModuleSpecifier is not available'},
'*');
return;
}
try {
const result = internals.resolveModuleSpecifier(
event.data.specifier,
event.data.baseURL,
document);
parent.postMessage(
{type: 'ResolutionSuccess', result: result}, '*');
} catch (e) {
parent.postMessage(
{type: 'Failure', result: e.name, message: e.message}, '*');
}
}
} else if (event.data.action === 'getParsedImportMap') {
if (!event.data.useInternalMethods) {
parent.postMessage(
{type: 'Failure',
result: 'Error',
message: 'internals.getParsedImportMap is not available'},
'*');
}
try {
parent.postMessage({
type: 'GetParsedImportMapSuccess',
result: internals.getParsedImportMap(document)}, '*');
} catch (e) {
parent.postMessage(
{type: 'Failure', result: e.name, message: e.message}, '*');
}
} else {
parent.postMessage({
type: 'Failure',
result: 'Error',
message: 'Invalid Action: ' + event.data.action}, '*');
}
});

View file

@ -1,5 +1,27 @@
setup({allow_uncaught_exception : true});
// Set window.useInternalMethods = true when needed && available.
let registration;
const scope = './scope/';
// Global setup: this must be the first promise_test.
promise_test(async (t) => {
const script = 'common-test-service-worker.js';
registration =
await service_worker_unregister_and_register(t, script, scope);
window.worker = registration.installing;
await wait_for_state(t, window.worker, 'activated');
}, 'global setup');
export function setupGlobalCleanup() {
// Global cleanup: the final promise_test.
promise_test(() => {
return registration.unregister();
}, 'global cleanup');
}
// Creates a new Document (via <iframe>) and add an inline import map.
function parse(importMap, importMapBaseURL) {
return new Promise(resolve => {
@ -15,79 +37,51 @@ function parse(importMap, importMapBaseURL) {
{once: true});
const testHTML = `
<script>
// Handle errors around fetching, parsing and registering import maps.
let registrationResult;
const onScriptError = event => {
registrationResult = {type: 'FetchError', error: event.error};
return false;
};
const windowErrorHandler = event => {
registrationResult = {type: 'ParseError', error: event.error};
return false;
};
window.addEventListener('error', windowErrorHandler);
window.addEventListener('load', event => {
if (!registrationResult) {
registrationResult = {type: 'Success'};
}
window.removeEventListener('error', windowErrorHandler);
parent.postMessage(registrationResult, '*');
});
// Handle specifier resolution requests from the parent frame.
window.addEventListener('message', event => {
try {
if (event.data.action === 'resolve') {
// URL resolution is tested using Chromium's internals.
// TODO(hiroshige): Remove the Chromium-specific dependency.
const result = internals.resolveModuleSpecifier(
event.data.specifier,
event.data.baseURL,
document);
parent.postMessage({type: 'ResolutionSuccess', result: result}, '*');
} else if (event.data.action === 'getParsedImportMap') {
parent.postMessage({
type: 'GetParsedImportMapSuccess',
result: internals.getParsedImportMap(document)}, '*');
} else {
parent.postMessage({
type: 'Failure',
result: "Invalid Action: " + event.data.action}, '*');
}
} catch (e) {
// We post error names instead of error objects themselves and
// re-create error objects later, to avoid issues around serializing
// error objects which is a quite new feature.
parent.postMessage({type: 'Failure', result: e.name}, '*');
}
});
</script>
<body>
<script src="${location.origin}/import-maps/common/resources/common-test-helper-iframe.js"></script>
<script type="importmap" onerror="onScriptError(event)">
${importMapString}
</script>
<script type="module">
if (!window.registrationResult) {
window.registrationResult = {type: 'Success'};
}
window.removeEventListener('error', window.windowErrorHandler);
parent.postMessage(window.registrationResult, '*');
</script>
</body>
`;
if (new URL(importMapBaseURL).protocol === 'data:') {
if (!window.useInternalMethods) {
throw new Error(
'Import maps with base URL = data: URL requires internal methods');
}
iframe.src = 'data:text/html;base64,' + btoa(testHTML);
} else {
iframe.srcdoc = `<base href="${importMapBaseURL}">` + testHTML;
// Set the src to `scope` in order to make requests from `iframe`
// intercepted by the service worker.
iframe.src = scope;
iframe.onload = () => {
iframe.contentDocument.write(
`<base href="${importMapBaseURL}">` + testHTML);
iframe.contentDocument.close();
};
}
document.body.appendChild(iframe);
});
}
// Returns a promise that is resolved with the resulting URL.
function resolve(specifier, parsedImportMap, baseURL) {
// `expectedURL` is a string, or null if to be thrown.
function resolve(specifier, parsedImportMap, baseURL, expectedURL) {
return new Promise((resolve, reject) => {
window.addEventListener('message', event => {
if (event.data.type === 'ResolutionSuccess') {
resolve(event.data.result);
} else if (event.data.type === 'Failure') {
if (event.data.result === 'TypeError') {
reject(new TypeError());
reject(new TypeError(event.data.message));
} else {
reject(new Error(event.data.result));
}
@ -97,8 +91,20 @@ function resolve(specifier, parsedImportMap, baseURL) {
},
{once: true});
parsedImportMap.contentWindow.postMessage(
{action: "resolve", specifier: specifier, baseURL: baseURL}, '*');
parsedImportMap.contentWindow.postMessage({action: 'prepareResolve'}, '*');
navigator.serviceWorker.addEventListener('message', event => {
// Step 2. After postMessage() at Step 1 is processed, the service worker
// sends back a message and the parent Window receives the message here
// and sends a 'resolve' message to the iframe.
parsedImportMap.contentWindow.postMessage(
{action: 'resolve',
specifier: specifier,
baseURL: baseURL,
expectedURL: expectedURL,
useInternalMethods: window.useInternalMethods},
'*');
}, {once: true});
});
}
@ -112,14 +118,15 @@ function getParsedImportMap(parsedImportMap) {
{once: true});
parsedImportMap.contentWindow.postMessage(
{action: "getParsedImportMap"}, '*');
{action: 'getParsedImportMap',
useInternalMethods: window.useInternalMethods}, '*');
});
}
function assert_no_extra_properties(object, expectedProperties, description) {
for (const actualProperty in object) {
assert_true(expectedProperties.indexOf(actualProperty) !== -1,
description + ": unexpected property " + actualProperty);
description + ': unexpected property ' + actualProperty);
}
}
@ -184,18 +191,18 @@ async function runTests(j) {
assert_own_property(j, 'baseURL');
assert_equals(
j.parsedImportMap.parseImportMapResult,
"Success",
"Import map registration should be successful for resolution tests");
'Success',
'Import map registration should be successful for resolution tests');
for (const specifier in j.expectedResults) {
const expected = j.expectedResults[specifier];
promise_test(async t => {
if (expected === null) {
return promise_rejects_js(t, TypeError,
resolve(specifier, j.parsedImportMap, j.baseURL));
resolve(specifier, j.parsedImportMap, j.baseURL, null));
} else {
// Should be resolved to `expected`.
const actual = await resolve(
specifier, j.parsedImportMap, j.baseURL);
specifier, j.parsedImportMap, j.baseURL, expected);
assert_equals(actual, expected);
}
},
@ -207,7 +214,7 @@ async function runTests(j) {
if (j.hasOwnProperty('expectedParsedImportMap')) {
promise_test(async t => {
if (j.expectedParsedImportMap === null) {
assert_equals(j.parsedImportMap.parseImportMapResult, "ParseError");
assert_equals(j.parsedImportMap.parseImportMapResult, 'ParseError');
} else {
const actualParsedImportMap =
await getParsedImportMap(j.parsedImportMap);

View file

@ -0,0 +1,20 @@
{
"importMap": {},
"importMapBaseURL": "https://example.com/app/index.html",
"baseURL": "https://example.com/js/app.mjs",
"tests": {
"non-HTTPS fetch scheme absolute URLs": {
"expectedResults": {
"about:fetch-scheme": "about:fetch-scheme"
}
},
"non-fetch scheme absolute URLs": {
"expectedResults": {
"mailto:non-fetch-scheme": "mailto:non-fetch-scheme",
"import:non-fetch-scheme": "import:non-fetch-scheme",
"javascript:non-fetch-scheme": "javascript:non-fetch-scheme",
"wss:non-fetch-scheme": "wss://non-fetch-scheme/"
}
}
}
}

View file

@ -18,23 +18,14 @@
"/../foo/../bar": "https://example.com/bar"
}
},
"fetch scheme absolute URLs": {
"HTTPS scheme absolute URLs": {
"expectedResults": {
"about:fetch-scheme": "about:fetch-scheme",
"https://fetch-scheme.net": "https://fetch-scheme.net/",
"https:fetch-scheme.org": "https://fetch-scheme.org/",
"https://fetch%2Dscheme.com/": "https://fetch-scheme.com/",
"https://///fetch-scheme.com///": "https://fetch-scheme.com///"
}
},
"non-fetch scheme absolute URLs": {
"expectedResults": {
"mailto:non-fetch-scheme": "mailto:non-fetch-scheme",
"import:non-fetch-scheme": "import:non-fetch-scheme",
"javascript:non-fetch-scheme": "javascript:non-fetch-scheme",
"wss:non-fetch-scheme": "wss://non-fetch-scheme/"
}
},
"valid relative URLs that are invalid as specifiers should fail": {
"expectedResults": {
"invalid-specifier": null,

View file

@ -690,7 +690,7 @@ MISSING-LINK: css/geometry/*.worker.js
MISSING-LINK: css/filter-effects/*.any.js
# Tests that use WebKit/Blink testing APIs
LAYOUTTESTS APIS: import-maps/common/resources/common-test-helper.js
LAYOUTTESTS APIS: import-maps/common/resources/common-test-helper-iframe.js
LAYOUTTESTS APIS: resources/chromium/enable-hyperlink-auditing.js
LAYOUTTESTS APIS: resources/chromium/generic_sensor_mocks.js
LAYOUTTESTS APIS: resources/chromium/webxr-test.js

View file

@ -0,0 +1,74 @@
<!DOCTYPE html>
<html>
<title>MediaSource-in-Worker looped playback test case with worker termination at various places</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script>
function terminateWorkerAfterMultipleSetTimeouts(test, worker, timeouts_remaining) {
if (timeouts_remaining <= 0) {
worker.terminate();
test.step_timeout(() => { test.done(); }, 0);
} else {
test.step_timeout(() => {
terminateWorkerAfterMultipleSetTimeouts(test, worker, --timeouts_remaining);
}, 0);
}
}
function startWorkerAndTerminateWorker(test, when_to_start_timeouts, timeouts_to_await) {
const worker = new Worker("mediasource-worker-util.js");
worker.onerror = test.unreached_func("worker error");
const video = document.createElement("video");
document.body.appendChild(video);
video.onerror = test.unreached_func("video element error");
if (when_to_start_timeouts == "after first ended event") {
video.addEventListener("ended", test.step_func(() => {
terminateWorkerAfterMultipleSetTimeouts(test, worker, timeouts_to_await);
video.currentTime = 0;
video.loop = true;
}), { once : true });
} else {
video.loop = true;
}
if (when_to_start_timeouts == "before setting src") {
terminateWorkerAfterMultipleSetTimeouts(test, worker, timeouts_to_await);
}
worker.onmessage = test.step_func((e) => {
if (e.data.substr(0,6) == "Error:") {
assert_unreached("Worker error: " + e.data);
} else {
const url = e.data
assert_true(url.match(/^blob:.+/) != null);
video.src = url;
if (when_to_start_timeouts == "after setting src") {
terminateWorkerAfterMultipleSetTimeouts(test, worker, timeouts_to_await);
}
video.play().catch(error => {
// Only rejections due to MEDIA_ERR_SRC_NOT_SUPPORTED are expected to possibly
// occur, except if we expect to reach at least 1 'ended' event.
assert_not_equals(when_to_start_timeouts, "after first ended event");
assert_true(video.error != null);
assert_equals(video.error.code, MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED);
// Do not rethrow. Instead, wait for the step_timeouts to finish the test.
});
}
});
}
[ "before setting src", "after setting src", "after first ended event" ].forEach((when) => {
for (let timeouts = 0; timeouts < 10; ++timeouts) {
async_test((test) => { startWorkerAndTerminateWorker(test, when, timeouts); },
"Test worker MediaSource termination after at least " + timeouts +
" main thread setTimeouts, starting counting " + when);
}
});
</script>
</body>
</html>

View file

@ -1,6 +1,6 @@
<!DOCTYPE html>
<html>
<title>Test attachment to dedicated worker MediaSource</title>
<title>Simple MediaSource-in-Worker playback test case</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
@ -9,15 +9,8 @@
async_test((t) => {
const video = document.createElement('video');
document.body.appendChild(video);
// TODO(https://crbug.com/878133): Enable attachment success by
// completing the CrossThreadAttachment implementation. Currently,
// a custom Chromium MediaError.message is confirmed.
video.onerror = t.step_func(() => {
assert_not_equals(video.error, null);
assert_equals(video.error.message, "MEDIA_ELEMENT_ERROR: Unable to attach MediaSource");
t.done();
});
video.onerror = t.unreached_func("video element error");
video.onended = t.step_func_done();
let worker = new Worker("mediasource-worker-util.js");
worker.onerror = t.unreached_func("worker error");
@ -28,9 +21,10 @@ async_test((t) => {
const url = e.data;
assert_true(url.match(/^blob:.+/) != null);
video.src = url;
video.play();
}
});
}, "Test worker MediaSource attachment (currently should fail to attach)");
}, "Test worker MediaSource construction, attachment, buffering and basic playback");
// TODO(https://crbug.com/878133): Test multiple attachments to same worker
// MediaSource racing each other: precisely one should win the race.

View file

@ -13,11 +13,11 @@ let mediaLoad;
// Find supported test media, if any.
let MEDIA_LIST = [
{
url: 'mp4/test.mp4',
url: '../mp4/test.mp4',
type: 'video/mp4; codecs="mp4a.40.2,avc1.4d400d"',
},
{
url: 'webm/test.webm',
url: '../webm/test.webm',
type: 'video/webm; codecs="vp8, vorbis"',
},
];
@ -56,9 +56,6 @@ onmessage = function(evt) {
postMessage("Error: No message expected by Worker");
};
// TODO(https://crbug.com/878133): Enable this path by completing the
// CrossThreadMediaSourceAttachment implementation such that attachment can
// actually succeed and 'sourceopen' be dispatched.
mediaSource.addEventListener("sourceopen", () => {
URL.revokeObjectURL(mediaSourceObjectUrl);
sourceBuffer = mediaSource.addSourceBuffer(mediaMetadata.type);
@ -66,10 +63,16 @@ mediaSource.addEventListener("sourceopen", () => {
postMessage("Error: " + err);
};
sourceBuffer.onupdateend = () => {
// Reset the parser. Unnecessary for this buffering, except helps with test
// coverage.
sourceBuffer.abort();
// Shorten the buffered media and test playback duration to avoid timeouts.
sourceBuffer.remove(0.5, Infinity);
sourceBuffer.onupdateend = () => {
sourceBuffer.duration = 0.5;
// Issue changeType to the same type that we've already buffered.
// Unnecessary for this buffering, except helps with test coverage.
sourceBuffer.changeType(mediaMetadata.type);
mediaSource.endOfStream();
};
};

View file

@ -7,19 +7,25 @@
<script src="testcommon.js"></script>
<style>
/*
* Overflow hidden prevents user scroll including mouse wheel; however, the
* element is still a scrollable container and can be scrolled programmatically.
* Removing the visible scrollbars in this manner simplifies the position
* calculations in the text.
*/
.scroller {
overflow: hidden;
overflow: scroll;
height: 500px;
width: 500px;
will-change: transform;
}
/* Disable scrollbars to simplify the calculations in the test. */
.scroller {
scrollbar-width: 0;
}
/*
Chrome does not support scrollbar-width so we use this non-standard property
until it does.
*/
.scroller::-webkit-scrollbar {
display: none;
}
.contents {
height: 1200px;
width: 1200px;