mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-26 01:35:08 +02:00
Imported WPT tests often load resources using canonical absolute paths, for example: /html/browsers/windows/resources/message-parent.html Our usual strategy is to rewrite such URLs to relative paths during import so they resolve from the importing test HTML file (which also allows for loading this HTML as a file://). That works for same-origin relative loading with the echo server, but it breaks down when a test constructs a cross-origin URL from an absolute path, for example: get_host_info().REMOTE_ORIGIN + "/some/wpt/path.html" In that case the resource still needs to be fetched at its canonical absolute path, so rewriting it relative to the importing document is no longer sufficient. Update the HTTP test server so /static/ continues to serve from the general test root, other non-echo requests are served from the imported WPT tree, and dynamically registered echo responses live under /echo/ to avoid path conflicts.
141 lines
3.6 KiB
JavaScript
141 lines
3.6 KiB
JavaScript
var __outputElement = null;
|
|
let __alreadyCalledTest = false;
|
|
let __originalURL = null;
|
|
function __preventMultipleTestFunctions() {
|
|
if (__alreadyCalledTest) {
|
|
throw new Error("You must only call test() or asyncTest() once per page");
|
|
}
|
|
__alreadyCalledTest = true;
|
|
}
|
|
|
|
if (globalThis.internals === undefined) {
|
|
internals = {
|
|
signalTestIsDone: function () {},
|
|
spoofCurrentURL: function (url) {},
|
|
};
|
|
}
|
|
|
|
function __finishTest() {
|
|
if (__originalURL) {
|
|
internals.spoofCurrentURL(__originalURL);
|
|
}
|
|
internals.signalTestIsDone(__outputElement.innerText);
|
|
}
|
|
|
|
function spoofCurrentURL(url) {
|
|
if (__originalURL === null) {
|
|
__originalURL = document.location.href;
|
|
}
|
|
internals.spoofCurrentURL(url);
|
|
}
|
|
|
|
function println(s) {
|
|
__outputElement.appendChild(document.createTextNode(s + "\n"));
|
|
}
|
|
|
|
function printElement(e) {
|
|
let element_string = `<${e.nodeName}`;
|
|
if (e.id) element_string += ` id="${e.id}"`;
|
|
element_string += ">";
|
|
println(element_string);
|
|
}
|
|
|
|
function animationFrame() {
|
|
const { promise, resolve } = Promise.withResolvers();
|
|
requestAnimationFrame(resolve);
|
|
return promise;
|
|
}
|
|
|
|
function timeout(ms) {
|
|
const { promise, resolve } = Promise.withResolvers();
|
|
setTimeout(resolve, ms);
|
|
return promise;
|
|
}
|
|
|
|
const __testErrorHandlerController = new AbortController();
|
|
window.addEventListener(
|
|
"error",
|
|
event => {
|
|
println(`Uncaught Error In Test: ${event.message}`);
|
|
__finishTest();
|
|
},
|
|
{ signal: __testErrorHandlerController.signal }
|
|
);
|
|
|
|
function removeTestErrorHandler() {
|
|
__testErrorHandlerController.abort();
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", function () {
|
|
__outputElement = document.createElement("pre");
|
|
__outputElement.setAttribute("id", "out");
|
|
document.body.appendChild(__outputElement);
|
|
});
|
|
|
|
function test(f) {
|
|
__preventMultipleTestFunctions();
|
|
document.addEventListener("DOMContentLoaded", f);
|
|
window.addEventListener("load", () => {
|
|
__finishTest();
|
|
});
|
|
}
|
|
|
|
function asyncTest(f) {
|
|
const done = () => {
|
|
__preventMultipleTestFunctions();
|
|
__finishTest();
|
|
};
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
Promise.resolve(f(done)).catch(error => {
|
|
println(`Caught error while running async test: ${error}`);
|
|
done();
|
|
});
|
|
});
|
|
}
|
|
|
|
function promiseTest(f) {
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
f().then(() => {
|
|
__preventMultipleTestFunctions();
|
|
__finishTest();
|
|
});
|
|
});
|
|
}
|
|
|
|
class HTTPTestServer {
|
|
constructor(baseURL) {
|
|
this.baseURL = baseURL;
|
|
}
|
|
async createEcho(method, path, options) {
|
|
const echoPath = `/echo${path}`;
|
|
const result = await fetch(`${this.baseURL}/echo`, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({ ...options, method, path: echoPath }),
|
|
});
|
|
if (!result.ok) {
|
|
throw new Error("Error creating echo: " + result.statusText);
|
|
}
|
|
return `${this.baseURL}${echoPath}`;
|
|
}
|
|
getStaticURL(path) {
|
|
return `${this.baseURL}/static/${path}`;
|
|
}
|
|
}
|
|
|
|
const __httpTestServer = (function () {
|
|
if (globalThis.internals && globalThis.internals.getEchoServerPort)
|
|
return new HTTPTestServer(`http://localhost:${internals.getEchoServerPort()}`);
|
|
|
|
return null;
|
|
})();
|
|
|
|
function httpTestServer() {
|
|
if (!__httpTestServer) {
|
|
throw new Error("window.internals must be exposed to use HTTPTestServer");
|
|
}
|
|
return __httpTestServer;
|
|
}
|