70 lines
3.0 KiB
HTML
70 lines
3.0 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Fast browser development fixture</title>
|
|
<style>
|
|
body { font: 16px system-ui, sans-serif; margin: 2rem; max-width: 42rem; }
|
|
label, input, button { display: block; margin: .6rem 0; }
|
|
input { min-width: 18rem; padding: .4rem; }
|
|
button { padding: .5rem .8rem; }
|
|
#status { min-height: 1.5rem; }
|
|
</style>
|
|
</head>
|
|
<body data-mode="__MODE__" data-retained="__RETAINED__" data-cookie-check="__COOKIE_CHECK__" data-cookie-forbid="__COOKIE_FORBID__">
|
|
<h1>Fast browser local development fixture</h1>
|
|
<p id="status">__INITIAL_STATUS__</p>
|
|
<label for="display-name">Display name</label>
|
|
<input id="display-name" name="display-name" type="text" autocomplete="off">
|
|
<button id="action" type="button">__BUTTON_LABEL__</button>
|
|
<script>
|
|
const readyCase = __READY_CASE__;
|
|
const body = document.body;
|
|
const status = document.getElementById("status");
|
|
const input = document.getElementById("display-name");
|
|
const button = document.getElementById("action");
|
|
let retained = body.dataset.retained === "true";
|
|
const cookieCheck = body.dataset.cookieCheck;
|
|
const cookieForbid = body.dataset.cookieForbid;
|
|
if (cookieCheck) {
|
|
const names = document.cookie.split(";").map((item) => item.trim().split("=", 1)[0]);
|
|
retained = names.includes(cookieCheck) && (!cookieForbid || !names.includes(cookieForbid));
|
|
body.dataset.retained = String(retained);
|
|
}
|
|
|
|
button.addEventListener("click", () => {
|
|
if (body.dataset.mode === "retained" && retained && input.value === "Milestone") {
|
|
status.textContent = "Retained session verified";
|
|
} else if (body.dataset.mode === "headless" && input.value === "Ada") {
|
|
status.textContent = "Headless bounded action verified";
|
|
} else if (body.dataset.mode === "isolation-a" && retained) {
|
|
status.textContent = "Profile A isolated";
|
|
} else if (body.dataset.mode === "isolation-b" && retained) {
|
|
status.textContent = "Profile B isolated";
|
|
} else {
|
|
status.textContent = "Fixture action did not meet its bounded condition";
|
|
}
|
|
if (body.dataset.mode === "retained") {
|
|
void fetch(`/automation-outcome?status=${encodeURIComponent(status.textContent ?? "")}`, { cache: "no-store" }).catch(() => {});
|
|
}
|
|
});
|
|
|
|
async function notifyReady() {
|
|
if (!readyCase) return;
|
|
for (let attempt = 0; attempt < 50; attempt += 1) {
|
|
try {
|
|
const response = await fetch(`/ready?case=${encodeURIComponent(readyCase)}`, { cache: "no-store" });
|
|
if (response.ok) return;
|
|
} catch (_) {
|
|
// The local server is expected to be available; the finite retry is
|
|
// only for the first renderer turn while the fixture is starting.
|
|
}
|
|
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
}
|
|
}
|
|
void notifyReady();
|
|
</script>
|
|
</body>
|
|
</html>
|