mirror of
https://github.com/servo/servo.git
synced 2025-06-27 02:23:41 +01:00
Update web-platform-tests to revision b'ee6da9d71d0268d7fdb04e8e5b26858f46ee0cc4'
This commit is contained in:
parent
4401622eb1
commit
b77ad115f6
16832 changed files with 270819 additions and 87621 deletions
|
@ -3,34 +3,51 @@
|
|||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/common/utils.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
setup({allow_uncaught_exception: true});
|
||||
async_test(function (test) {
|
||||
const worker = new Worker("./resources/worker.js", {
|
||||
promise_test(function (test) {
|
||||
const uuid = token();
|
||||
const worker = new Worker(`./resources/worker.sub.js?key=${uuid}`, {
|
||||
type: "module"
|
||||
});
|
||||
worker.onmessage = test.unreached_func("A CSS Module within a web worker should not load.");
|
||||
worker.onerror = test.step_func_done();
|
||||
}, "A static import CSS Module within a web worker should not load.");
|
||||
return new Promise((resolve, reject) => {
|
||||
worker.addEventListener("error", resolve);
|
||||
worker.addEventListener("message", reject);
|
||||
}).then(async () => {
|
||||
const fetchResponse = await fetch(`./resources/record-fetch.py?key=${uuid}&action=getCount`);
|
||||
const fetchData = await fetchResponse.json();
|
||||
assert_equals(fetchData.count, 0, "Shouldn't have tried fetching CSS module in worker");
|
||||
});
|
||||
}, "A static import CSS Module within a web worker should not load and should not attempt to fetch the module.");
|
||||
|
||||
async_test(function (test) {
|
||||
const worker = new Worker("./resources/worker-dynamic-import.js", {
|
||||
promise_test(function (test) {
|
||||
const uuid = token();
|
||||
const worker = new Worker(`./resources/worker-dynamic-import.sub.js?key=${uuid}`, {
|
||||
type: "module"
|
||||
});
|
||||
worker.onmessage = test.step_func_done(e => {
|
||||
assert_equals(e.data, "NOT LOADED");
|
||||
});
|
||||
}, "A dynamic import CSS Module within a web worker should not load.");
|
||||
|
||||
async_test(function (test) {
|
||||
return new Promise(resolve => {
|
||||
worker.addEventListener("message", resolve);
|
||||
}).then(async (event) => {
|
||||
assert_equals(event.data, "NOT LOADED");
|
||||
const fetchResponse = await fetch(`./resources/record-fetch.py?key=${uuid}&action=getCount`);
|
||||
const fetchData = await fetchResponse.json();
|
||||
assert_equals(fetchData.count, 0, "Shouldn't have tried fetching CSS module in worker");
|
||||
});
|
||||
}, "A dynamic import CSS Module within a web worker should not load and should not attempt to fetch the module.");
|
||||
|
||||
promise_test(function (test) {
|
||||
const worker = new Worker("./resources/basic.css", {
|
||||
type: "module"
|
||||
});
|
||||
worker.onerror = test.step_func_done();
|
||||
}, "A CSS Module within a web worker should not load.");
|
||||
return new Promise(resolve => {
|
||||
worker.onerror = resolve;
|
||||
});
|
||||
}, "An attempt to load a CSS module as a worker should fail.");
|
||||
|
||||
</script>
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
def main(request, response):
|
||||
try:
|
||||
stash_key = request.GET.first(b"key")
|
||||
action = request.GET.first(b"action")
|
||||
|
||||
run_count = request.server.stash.take(stash_key)
|
||||
if not run_count:
|
||||
run_count = 0
|
||||
|
||||
if action == b"incCount":
|
||||
request.server.stash.put(stash_key, run_count + 1)
|
||||
response.headers.set(b"Content-Type", b"text/css")
|
||||
response.content = b'#test { background-color: #FF0000; }'
|
||||
elif action == b"getCount":
|
||||
response.headers.set(b"Content-Type", b"text/json")
|
||||
response.content = b'{"count": %d }' % run_count
|
||||
else:
|
||||
response.set_error(400, u"Invalid action")
|
||||
except:
|
||||
response.set_error(400, u"Not enough parameters")
|
|
@ -1,3 +0,0 @@
|
|||
import("./basic.css", { assert: { type: "css" } })
|
||||
.then(() => postMessage("LOADED"))
|
||||
.catch(e => postMessage("NOT LOADED"));
|
|
@ -0,0 +1,3 @@
|
|||
import("./record-fetch.py?key={{GET[key]}}&action=incCount", { assert: { type: "css" } })
|
||||
.then(() => postMessage("LOADED"))
|
||||
.catch(e => postMessage("NOT LOADED"));
|
|
@ -1,2 +0,0 @@
|
|||
import "./basic.css" assert { type: "css" };
|
||||
postMessage("Unexpectedly loaded");
|
|
@ -0,0 +1,2 @@
|
|||
import "./record-fetch.py?key={{GET[key]}}&action=incCount" assert { type: "css" };
|
||||
postMessage("Unexpectedly loaded");
|
|
@ -14,7 +14,7 @@ self.setup({allow_uncaught_exception: true});
|
|||
// handlers are evaluated, not after each error event handler.
|
||||
|
||||
// Just after each event handler is invoked,
|
||||
// https://heycam.github.io/webidl/#call-a-user-objects-operation
|
||||
// https://webidl.spec.whatwg.org/#call-a-user-objects-operation
|
||||
// calls #clean-up-after-running-script, but this doesn't execute new
|
||||
// microtasks immediately, because:
|
||||
// - Before https://github.com/whatwg/html/pull/4352:
|
||||
|
@ -57,7 +57,7 @@ async_test(t => {
|
|||
// around event events other than the `self` error event cases above.
|
||||
// In this case, microtasks are executed just after each event handler is
|
||||
// invoked via #clean-up-after-running-script called from
|
||||
// https://heycam.github.io/webidl/#call-a-user-objects-operation,
|
||||
// https://webidl.spec.whatwg.org/#call-a-user-objects-operation,
|
||||
// because the event handlers are executed outside the
|
||||
// #prepare-to-run-script/#clean-up-after-running-script scopes in
|
||||
// #run-a-classic-script/#run-a-module-script.
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
promise_test(() => {
|
||||
return (new Function('w', 'return import(w)'))("./import.js?Function")
|
||||
.then(module => assert_equals(module.A.from, 'alpha/import.js'));
|
||||
}, 'alpha - Function');
|
||||
|
||||
promise_test(() => {
|
||||
return eval('import("./import.js?eval")')
|
||||
.then(module => assert_equals(module.A.from, 'alpha/import.js'));
|
||||
}, 'alpha - eval');
|
|
@ -0,0 +1,9 @@
|
|||
promise_test(() => {
|
||||
return (new Function('w', 'return import(w)'))("./import.js?Function")
|
||||
.then(module => assert_equals(module.A.from, 'beta/import.js'));
|
||||
}, 'beta - Function');
|
||||
|
||||
promise_test(() => {
|
||||
return eval('import("./import.js?eval")')
|
||||
.then(module => assert_equals(module.A.from, 'beta/import.js'));
|
||||
}, 'beta - eval');
|
|
@ -0,0 +1,60 @@
|
|||
function objectUrlFromModule(module) {
|
||||
const blob = new Blob([module], { type: "text/javascript" });
|
||||
return URL.createObjectURL(blob);
|
||||
}
|
||||
|
||||
const moduleText = `export const foo = "bar";`;
|
||||
|
||||
async_test((t) => {
|
||||
const moduleBlobUrl = objectUrlFromModule(moduleText);
|
||||
t.add_cleanup(() => URL.revokeObjectURL(moduleBlobUrl));
|
||||
|
||||
const worker = new Worker("./resources/blob-url-worker.js");
|
||||
worker.postMessage(moduleBlobUrl);
|
||||
|
||||
worker.addEventListener(
|
||||
"message",
|
||||
t.step_func_done((evt) => {
|
||||
assert_true(evt.data.importSucceeded);
|
||||
assert_equals(evt.data.module.foo, "bar");
|
||||
})
|
||||
);
|
||||
}, "A blob URL created in a window agent can be imported from a worker");
|
||||
|
||||
async_test((t) => {
|
||||
const moduleBlobUrl = objectUrlFromModule(moduleText);
|
||||
URL.revokeObjectURL(moduleBlobUrl);
|
||||
|
||||
const worker = new Worker("./resources/blob-url-worker.js");
|
||||
worker.postMessage(moduleBlobUrl);
|
||||
|
||||
worker.addEventListener(
|
||||
"message",
|
||||
t.step_func_done((evt) => {
|
||||
assert_false(evt.data.importSucceeded);
|
||||
assert_equals(evt.data.errorName, "TypeError");
|
||||
})
|
||||
);
|
||||
}, "A blob URL revoked in a window agent will not resolve in a worker");
|
||||
|
||||
promise_test(async (t) => {
|
||||
const moduleBlobUrl = objectUrlFromModule(moduleText);
|
||||
|
||||
await import(moduleBlobUrl);
|
||||
|
||||
URL.revokeObjectURL(moduleBlobUrl);
|
||||
|
||||
const worker = new Worker("./resources/blob-url-worker.js");
|
||||
worker.postMessage(moduleBlobUrl);
|
||||
|
||||
await new Promise((resolve) => {
|
||||
worker.addEventListener(
|
||||
"message",
|
||||
t.step_func((evt) => {
|
||||
assert_false(evt.data.importSucceeded);
|
||||
assert_equals(evt.data.errorName, "TypeError");
|
||||
resolve();
|
||||
})
|
||||
);
|
||||
});
|
||||
}, "A revoked blob URL will not resolve in a worker even if it's in the window's module graph");
|
|
@ -0,0 +1,66 @@
|
|||
// META: global=window,dedicatedworker,sharedworker,dedicatedworker-module,sharedworker-module
|
||||
|
||||
function objectUrlFromModule(module) {
|
||||
const blob = new Blob([module], { type: "text/javascript" });
|
||||
return URL.createObjectURL(blob);
|
||||
}
|
||||
|
||||
const moduleText = `export const foo = "bar";`;
|
||||
|
||||
promise_test(async (t) => {
|
||||
const moduleBlobUrl = objectUrlFromModule(moduleText);
|
||||
t.add_cleanup(() => URL.revokeObjectURL(moduleBlobUrl));
|
||||
|
||||
const module = await import(moduleBlobUrl);
|
||||
assert_equals(module.foo, "bar");
|
||||
}, "Blob URLs are supported in dynamic imports");
|
||||
|
||||
promise_test(async (t) => {
|
||||
const moduleBlobUrl = objectUrlFromModule(moduleText);
|
||||
t.add_cleanup(() => URL.revokeObjectURL(moduleBlobUrl));
|
||||
|
||||
const module1 = await import(moduleBlobUrl);
|
||||
const module2 = await import(moduleBlobUrl);
|
||||
assert_equals(module1, module2);
|
||||
}, "Identical blob URLs resolve to the same module");
|
||||
|
||||
promise_test(async (t) => {
|
||||
const moduleBlob = new Blob([moduleText], { type: "text/javascript" });
|
||||
const moduleBlobUrl1 = URL.createObjectURL(moduleBlob);
|
||||
const moduleBlobUrl2 = URL.createObjectURL(moduleBlob);
|
||||
t.add_cleanup(() => {
|
||||
URL.revokeObjectURL(moduleBlobUrl1);
|
||||
URL.revokeObjectURL(moduleBlobUrl2);
|
||||
});
|
||||
|
||||
const module1 = await import(moduleBlobUrl1);
|
||||
const module2 = await import(moduleBlobUrl2);
|
||||
assert_not_equals(module1, module2);
|
||||
}, "Different blob URLs pointing to the same blob resolve to different modules");
|
||||
|
||||
promise_test(async (t) => {
|
||||
const moduleBlobUrl = objectUrlFromModule(moduleText);
|
||||
URL.revokeObjectURL(moduleBlobUrl);
|
||||
|
||||
await promise_rejects_js(t, TypeError, import(moduleBlobUrl));
|
||||
}, "A revoked blob URL will not resolve");
|
||||
|
||||
promise_test(async () => {
|
||||
const moduleBlobUrl = objectUrlFromModule(moduleText);
|
||||
const module1 = await import(moduleBlobUrl);
|
||||
|
||||
URL.revokeObjectURL(moduleBlobUrl);
|
||||
|
||||
const module2 = await import(moduleBlobUrl);
|
||||
assert_equals(module1, module2);
|
||||
}, "A revoked blob URL will resolve if it's already in the module graph");
|
||||
|
||||
promise_test(async () => {
|
||||
const moduleBlobUrl = objectUrlFromModule(moduleText);
|
||||
|
||||
const importPromise = import(moduleBlobUrl);
|
||||
URL.revokeObjectURL(moduleBlobUrl);
|
||||
|
||||
const module = await importPromise;
|
||||
assert_equals(module.foo, "bar");
|
||||
}, "Revoking a blob URL immediately after calling import will not fail");
|
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<!--
|
||||
Regression test for https://crbug.com/990810:
|
||||
Functions with the same source code shouldn't be cached if their referencing
|
||||
scripts and host defined options are different.
|
||||
|
||||
Each Function in the following three scripts should have different base URLs
|
||||
respectively, but in https://crbug.com/990810 the Function in
|
||||
`gamma/code-cache.js` reuses the Function in `beta/code-cache.js`, resulting in
|
||||
wrong base URL.
|
||||
-->
|
||||
|
||||
<script src="alpha/code-cache.js"></script>
|
||||
<script src="beta/code-cache.js"></script>
|
||||
<script src="gamma/code-cache.js"></script>
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
// Regression test for https://crbug.com/979351:
|
||||
// This test loads a same script file (`resources/code-cache-nonce.js`)
|
||||
// with three different nonces (i.e. different host defined options).
|
||||
// Dynamic imports from the script therefore should have different nonces,
|
||||
// but when code caching ignores the difference in nonces, the first nonce
|
||||
// ('abc') is reused incorrectly for subsequent dynamic imports, causing
|
||||
// CSP violation (and thus dynamic import rejection).
|
||||
|
||||
function runTest(nonce, description) {
|
||||
// Perform a dynamic import with nonce=`nonce`
|
||||
// from a page (`iframe`) with a matching CSP script-src 'nonce-`nonce`'.
|
||||
// This should be successful.
|
||||
promise_test(t => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.src = 'resources/code-cache-nonce-iframe.sub.html?nonce=' + nonce;
|
||||
iframe.onload = () => {
|
||||
// `globalThis.promise` is set by `resources/code-cache-nonce.js`.
|
||||
// `t.step_timeout()` is workaround for https://crbug.com/1247801.
|
||||
globalThis.promise.then(
|
||||
v => t.step_timeout(() => resolve(v), 0),
|
||||
v => t.step_timeout(() => reject(v), 0)
|
||||
);
|
||||
};
|
||||
document.body.appendChild(iframe);
|
||||
t.add_cleanup(() => iframe.remove());
|
||||
});
|
||||
}, description);
|
||||
}
|
||||
|
||||
// As `promise_test` are serialized, each iframe is created after previous
|
||||
// iframes and scripts are completely loaded.
|
||||
runTest('abc', 'First dynamic import should use nonce=abc');
|
||||
runTest('def', 'Second dynamic import should use nonce=def');
|
||||
runTest('ghi', 'Third dynamic import should use nonce=ghi');
|
||||
</script>
|
|
@ -3,7 +3,7 @@
|
|||
<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script src="/common/utils.js"></script>
|
||||
<script type="module">
|
||||
const cases = [
|
||||
["wrong MIME type", "../errorhandling-wrongMimetype.js?pipe=header(Content-Type,text/plain)"],
|
||||
|
@ -37,4 +37,25 @@ for (const [label, specifier] of cases) {
|
|||
assert_not_equals(error1, error2, "The error objects must be different");
|
||||
}, "import() must reject with a different error object for each import when there is a " + label);
|
||||
}
|
||||
|
||||
promise_test(async t => {
|
||||
const id = token();
|
||||
const url = `./resources/status-changing-script.py?id=${id}`;
|
||||
|
||||
// Serve HTTP 404 for the first import().
|
||||
await fetch(url + '&newStatus=404');
|
||||
const promise1 = import(url);
|
||||
await promise_rejects_js(t, TypeError, promise1,
|
||||
"First import() must be rejected due to 404");
|
||||
|
||||
// Serve HTTP 200 after the first import() completes.
|
||||
await fetch(url + '&newStatus=200');
|
||||
const r = await fetch(url, { cache: 'no-cache' });
|
||||
assert_equals(r.status, 200);
|
||||
|
||||
const promise2 = import(url);
|
||||
await promise_rejects_js(t, TypeError, promise2,
|
||||
"Second import() must be rejected, because the result of " +
|
||||
"the first import() is cached in the module map");
|
||||
}, "import() fetch errors must be cached");
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
promise_test(() => {
|
||||
return (new Function('w', 'return import(w)'))("./import.js?Function")
|
||||
.then(module => assert_equals(module.A.from, 'gamma/import.js'));
|
||||
}, 'gamma - Function');
|
||||
|
||||
promise_test(() => {
|
||||
return eval('import("./import.js?eval")')
|
||||
.then(module => assert_equals(module.A.from, 'gamma/import.js'));
|
||||
}, 'gamma - eval');
|
|
@ -0,0 +1,11 @@
|
|||
self.addEventListener("message", (evt) => {
|
||||
const importModule = import(evt.data);
|
||||
importModule.then(
|
||||
(module) => {
|
||||
self.postMessage({ importSucceeded: true, module: { ...module } });
|
||||
},
|
||||
(error) => {
|
||||
self.postMessage({ importSucceeded: false, errorName: error.name });
|
||||
}
|
||||
);
|
||||
});
|
|
@ -0,0 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<meta http-equiv="content-security-policy"
|
||||
content="script-src 'unsafe-eval' 'nonce-{{GET[nonce]}}'">
|
||||
<script src="code-cache-nonce.js" nonce="{{GET[nonce]}}"></script>
|
|
@ -0,0 +1,4 @@
|
|||
// Note that the function source text is intentionally different from e.g.
|
||||
// ../alpha/code-cache.js to avoid caching Functions between different sets
|
||||
// of tests.
|
||||
parent.promise = (new Function('x', 'return import(x)'))('../../imports-a.js');
|
|
@ -0,0 +1,18 @@
|
|||
def main(request, response):
|
||||
headers = [(b"Content-Type", b"text/javascript"),
|
||||
(b"Cache-Control", b"private, no-store")]
|
||||
|
||||
id = request.GET.first(b"id")
|
||||
|
||||
with request.server.stash.lock:
|
||||
status = request.server.stash.take(id)
|
||||
if status is None:
|
||||
status = 200
|
||||
|
||||
new_status = request.GET.first(b"newStatus", None)
|
||||
if new_status is not None:
|
||||
status = int(new_status)
|
||||
|
||||
request.server.stash.put(id, status)
|
||||
|
||||
return status, headers, b""
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<meta http-equiv="content-security-policy"
|
||||
content="script-src 'nonce-{{GET[nonce]}}'">
|
||||
<!--
|
||||
base element to make the base URLs of the Document and the script different
|
||||
-->
|
||||
<base href="../">
|
||||
<script src="resources/v8-code-cache.js?pipe=header(Cache-Control,max-age=1000)"
|
||||
nonce="{{GET[nonce]}}" type="{{GET[type]}}"></script>
|
|
@ -0,0 +1,74 @@
|
|||
parent.promise = import('../../imports-a.js');
|
||||
|
||||
// Padding for triggering V8 Code Cache on Chromium.
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
||||
// ============================================================================
|
|
@ -8,17 +8,35 @@
|
|||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<body>
|
||||
<base href="scripts/foo/">
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
// This test is based on the current specification, but all browser
|
||||
// implementations aren't conformant. See
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=1245063
|
||||
// https://github.com/heycam/webidl/pull/902
|
||||
|
||||
// Tweak the base URL of the document here to distinguish:
|
||||
// - document URL
|
||||
// - document base URL = ../
|
||||
// - This inline script's base URL = ./scripts/foo/
|
||||
document.querySelector("base").remove();
|
||||
const base = document.createElement("base");
|
||||
base.setAttribute("href", "../");
|
||||
document.body.appendChild(base);
|
||||
|
||||
self.ran = false;
|
||||
|
||||
// The active script for the dynamic import is this inline script
|
||||
// (see https://html.spec.whatwg.org/C/#hostmakejobcallback).
|
||||
promise_test(t => {
|
||||
t.add_cleanup(() => {
|
||||
self.ran = false;
|
||||
})
|
||||
|
||||
return Promise.resolve(`import("../imports-a.js?1").then(() => { self.ran = true; })`)
|
||||
return Promise.resolve(`import("../../../imports-a.js?1").then(() => { self.ran = true; })`)
|
||||
.then(eval)
|
||||
.then(() => {
|
||||
assert_true(self.ran);
|
||||
|
@ -42,7 +60,7 @@ promise_test(t => {
|
|||
self.ran = false;
|
||||
})
|
||||
|
||||
return Promise.resolve(`return import("../imports-a.js?2").then(() => { self.ran = true; })`)
|
||||
return Promise.resolve(`return import("../../../imports-a.js?2").then(() => { self.ran = true; })`)
|
||||
.then(Function)
|
||||
.then(Function.prototype.call.bind(Function.prototype.call))
|
||||
.then(() => {
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<body>
|
||||
<script>
|
||||
// Regression test for https://crbug.com/1244145:
|
||||
// This test loads a same script file (`resources/v8-code-cache.js`)
|
||||
// multiple times to trigger V8 Code Cache.
|
||||
// Host defined options (including base URLs and nonces) are lost when the
|
||||
// script is compiled using the cached metadata, and thus causing
|
||||
// dynamic import failures due to wrong base URLs and wrong nonces.
|
||||
|
||||
function runTest(type, nonce, description) {
|
||||
promise_test(t => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.src = 'resources/v8-code-cache-iframe.sub.html?nonce=' + nonce + '&type=' + type;
|
||||
iframe.onload = () => {
|
||||
// `window.promise` is set by `resources/v8-code-cache.js`.
|
||||
window.promise.then(resolve, reject);
|
||||
};
|
||||
document.body.appendChild(iframe);
|
||||
t.add_cleanup(() => iframe.remove());
|
||||
});
|
||||
}, type + ': ' + description);
|
||||
}
|
||||
|
||||
// As `promise_test` are serialized, each iframe is created after previous
|
||||
// iframes and scripts are completely loaded.
|
||||
for (const type of ['text/javascript', 'module']) {
|
||||
// Cache the script in V8 Code Cache by running multiple times.
|
||||
runTest(type, 'abc', 'Run #1');
|
||||
runTest(type, 'abc', 'Run #2');
|
||||
runTest(type, 'abc', 'Run #3');
|
||||
runTest(type, 'abc', 'Run #4');
|
||||
// Changing the nonce seems to disable compilation cache, trigger compilation
|
||||
// using V8 Code Cache and thus expose the bug.
|
||||
runTest(type, 'def', 'Run #5');
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,58 @@
|
|||
// META: global=dedicatedworker-module,sharedworker-module,serviceworker-module
|
||||
|
||||
import { importMetaOnRootModule, importMetaOnDependentModule }
|
||||
from "./import-meta-root.js";
|
||||
|
||||
const base = location.href.slice(0, location.href.lastIndexOf('/'));
|
||||
|
||||
test(() => {
|
||||
assert_equals(importMetaOnRootModule.url,
|
||||
base + "/import-meta-root.js");
|
||||
}, "import.meta.url in a root external script");
|
||||
|
||||
test(() => {
|
||||
assert_equals(importMetaOnDependentModule.url,
|
||||
base + "/import-meta-dependent.js");
|
||||
}, "import.meta.url in a dependent external script");
|
||||
|
||||
test(() => {
|
||||
assert_equals(typeof importMetaOnRootModule, "object");
|
||||
assert_not_equals(importMetaOnRootModule, null);
|
||||
}, "import.meta is an object");
|
||||
|
||||
test(() => {
|
||||
importMetaOnRootModule.newProperty = 1;
|
||||
assert_true(Object.isExtensible(importMetaOnRootModule));
|
||||
}, "import.meta is extensible");
|
||||
|
||||
test(() => {
|
||||
const names = new Set(Reflect.ownKeys(importMetaOnRootModule));
|
||||
for (const name of names) {
|
||||
var desc = Object.getOwnPropertyDescriptor(importMetaOnRootModule, name);
|
||||
assert_equals(desc.writable, true);
|
||||
assert_equals(desc.enumerable, true);
|
||||
assert_equals(desc.configurable, true);
|
||||
}
|
||||
}, "import.meta's properties are writable, configurable, and enumerable");
|
||||
|
||||
|
||||
import { importMetaOnRootModule as hashedImportMetaOnRootModule1,
|
||||
importMetaOnDependentModule as hashedImportMetaOnDependentModule1 }
|
||||
from "./import-meta-root.js#1";
|
||||
|
||||
import { importMetaOnRootModule as hashedImportMetaOnRootModule2,
|
||||
importMetaOnDependentModule as hashedImportMetaOnDependentModule2 }
|
||||
from "./import-meta-root.js#2";
|
||||
|
||||
test(() => {
|
||||
assert_equals(hashedImportMetaOnRootModule1.url,
|
||||
base + "/import-meta-root.js#1");
|
||||
assert_equals(hashedImportMetaOnRootModule2.url,
|
||||
base + "/import-meta-root.js#2");
|
||||
|
||||
// Must not be affected
|
||||
assert_equals(hashedImportMetaOnDependentModule1.url,
|
||||
base + "/import-meta-dependent.js");
|
||||
assert_equals(hashedImportMetaOnDependentModule2.url,
|
||||
base + "/import-meta-dependent.js");
|
||||
}, "import.meta.url when importing the module with different fragments");
|
|
@ -1,66 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script type="module">
|
||||
import { importMetaOnRootModule, importMetaOnDependentModule }
|
||||
from "./import-meta-root.js";
|
||||
<script type="module" src="import-meta-url.any.js"></script>
|
||||
|
||||
var base = location.href.slice(0, location.href.lastIndexOf('/'));
|
||||
<script type="module">
|
||||
const base = location.href.slice(0, location.href.lastIndexOf('/'));
|
||||
|
||||
test(() => {
|
||||
assert_equals(import.meta.url, location.href);
|
||||
}, "import.meta.url in a root inline script");
|
||||
|
||||
test(() => {
|
||||
assert_equals(importMetaOnRootModule.url,
|
||||
base + "/import-meta-root.js");
|
||||
}, "import.meta.url in a root external script");
|
||||
|
||||
test(() => {
|
||||
assert_equals(importMetaOnDependentModule.url,
|
||||
base + "/import-meta-dependent.js");
|
||||
}, "import.meta.url in a dependent external script");
|
||||
|
||||
test(() => {
|
||||
assert_equals(typeof importMetaOnRootModule, "object");
|
||||
assert_not_equals(importMetaOnRootModule, null);
|
||||
}, "import.meta is an object");
|
||||
|
||||
test(() => {
|
||||
importMetaOnRootModule.newProperty = 1;
|
||||
assert_true(Object.isExtensible(importMetaOnRootModule));
|
||||
}, "import.meta is extensible");
|
||||
|
||||
test(() => {
|
||||
let names = new Set(Reflect.ownKeys(importMetaOnRootModule));
|
||||
for (name of names) {
|
||||
var desc = Object.getOwnPropertyDescriptor(importMetaOnRootModule, name);
|
||||
assert_equals(desc.writable, true);
|
||||
assert_equals(desc.enumerable, true);
|
||||
assert_equals(desc.configurable, true);
|
||||
}
|
||||
}, "import.meta's properties are writable, configurable, and enumerable");
|
||||
|
||||
|
||||
import { importMetaOnRootModule as hashedImportMetaOnRootModule1,
|
||||
importMetaOnDependentModule as hashedImportMetaOnDependentModule1 }
|
||||
from "./import-meta-root.js#1";
|
||||
|
||||
import { importMetaOnRootModule as hashedImportMetaOnRootModule2,
|
||||
importMetaOnDependentModule as hashedImportMetaOnDependentModule2 }
|
||||
from "./import-meta-root.js#2";
|
||||
|
||||
test(() => {
|
||||
assert_equals(hashedImportMetaOnRootModule1.url,
|
||||
base + "/import-meta-root.js#1");
|
||||
assert_equals(hashedImportMetaOnRootModule2.url,
|
||||
base + "/import-meta-root.js#2");
|
||||
|
||||
// Must not be affected
|
||||
assert_equals(hashedImportMetaOnDependentModule1.url,
|
||||
base + "/import-meta-dependent.js");
|
||||
assert_equals(hashedImportMetaOnDependentModule2.url,
|
||||
base + "/import-meta-dependent.js");
|
||||
}, "import.meta.url when importing the module with different fragments");
|
||||
|
||||
for (const workerType of ['DedicatedWorker', 'SharedWorker']) {
|
||||
promise_test(async t => {
|
||||
const worker_request_url =
|
||||
new URL(`postmessage-worker.js?${workerType}`, location);
|
||||
let w;
|
||||
let port;
|
||||
if (workerType === 'DedicatedWorker') {
|
||||
w = new Worker(worker_request_url.href, {type: 'module'});
|
||||
port = w;
|
||||
} else {
|
||||
w = new SharedWorker(worker_request_url.href, {type: 'module'});
|
||||
port = w.port;
|
||||
w.port.start();
|
||||
}
|
||||
w.onerror = t.unreached_func('Worker error');
|
||||
const url = await new Promise(resolve => {
|
||||
port.onmessage = evt => resolve(evt.data);
|
||||
});
|
||||
assert_equals(url, worker_request_url.href);
|
||||
}, `import.meta.url at top-level module ${workerType}`);
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
if ('DedicatedWorkerGlobalScope' in self &&
|
||||
self instanceof DedicatedWorkerGlobalScope) {
|
||||
postMessage(import.meta.url);
|
||||
} else if (
|
||||
'SharedWorkerGlobalScope' in self &&
|
||||
self instanceof SharedWorkerGlobalScope) {
|
||||
self.onconnect = function(e) {
|
||||
const port = e.ports[0];
|
||||
port.start();
|
||||
port.postMessage(import.meta.url);
|
||||
};
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script>
|
||||
async_test(t => {
|
||||
window.onload = t.step_func_done();
|
||||
}, 'Removing iframe in promise reject handler should not crash');
|
||||
</script>
|
||||
<iframe src="resources/promise-reject-and-remove-iframe.html"></iframe>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<script>
|
||||
const promise = Promise.reject();
|
||||
|
||||
window.onload = () => {
|
||||
promise.catch(() => parent.document.querySelector('iframe').remove());
|
||||
};
|
||||
</script>
|
||||
|
||||
<!-- Load a slow script to delay window.onload for a while.
|
||||
Without this, crashes are flaky. -->
|
||||
<script src="/common/slow.py"></script>
|
Loading…
Add table
Add a link
Reference in a new issue