Update web-platform-tests to revision b'ee6da9d71d0268d7fdb04e8e5b26858f46ee0cc4'

This commit is contained in:
WPT Sync Bot 2022-01-20 04:38:55 +00:00 committed by cybai
parent 4401622eb1
commit b77ad115f6
16832 changed files with 270819 additions and 87621 deletions

View file

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

View file

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

View file

@ -1,3 +0,0 @@
import("./basic.css", { assert: { type: "css" } })
.then(() => postMessage("LOADED"))
.catch(e => postMessage("NOT LOADED"));

View file

@ -0,0 +1,3 @@
import("./record-fetch.py?key={{GET[key]}}&action=incCount", { assert: { type: "css" } })
.then(() => postMessage("LOADED"))
.catch(e => postMessage("NOT LOADED"));

View file

@ -1,2 +0,0 @@
import "./basic.css" assert { type: "css" };
postMessage("Unexpectedly loaded");

View file

@ -0,0 +1,2 @@
import "./record-fetch.py?key={{GET[key]}}&action=incCount" assert { type: "css" };
postMessage("Unexpectedly loaded");

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,74 @@
parent.promise = import('../../imports-a.js');
// Padding for triggering V8 Code Cache on Chromium.
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================
// ============================================================================

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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