-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[WPT] Migrate most of import-maps resolution tests out of blink inter…
…nals This CL migrates most of import maps resolution tests by observing the resolution results by intercepting module script requests by a service worker. This CL also introduces `useInternalMethods` flag to clarify the tests still requiring internal methods. Bug: 1026809 Change-Id: I16c2a87bb67b530dc97b1631f6968b2d3bafdac6 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2457526 Commit-Queue: Hiroshige Hayashizaki <hiroshige@chromium.org> Reviewed-by: Domenic Denicola <domenic@chromium.org> Cr-Commit-Position: refs/heads/master@{#818366}
- Loading branch information
1 parent
ebdb2fc
commit e85837b
Showing
9 changed files
with
279 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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'}} | ||
)); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
import-maps/common/resolving-internal.tentative.https.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
import-maps/common/resources/common-test-helper-iframe.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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}, '*'); | ||
} | ||
}); |
Oops, something went wrong.