fix(site): add explicit not-found page
All checks were successful
ci / build (push) Successful in 41s
All checks were successful
ci / build (push) Successful in 41s
This commit is contained in:
parent
82e8c8f8ae
commit
7ef9106723
3 changed files with 274 additions and 3 deletions
|
|
@ -32,8 +32,8 @@ const GEOMETRY_WIDTHS = [320, 390, 768, 1024, 1440, 1920, 2560];
|
|||
const CAPTURE_WIDTHS = new Set([390, 1440]);
|
||||
const HEIGHTS = new Map([[320, 844], [390, 844], [768, 1024], [1024, 900], [1440, 1000], [1920, 1080], [2560, 1440]]);
|
||||
const AXE_TAGS = ["wcag2a", "wcag2aa", "wcag21a", "wcag21aa", "wcag22aa"];
|
||||
const EXPECTED_SCENARIOS = 80;
|
||||
const EXPECTED_ASSERTIONS = 995;
|
||||
const EXPECTED_SCENARIOS = 81;
|
||||
const EXPECTED_ASSERTIONS = 1009;
|
||||
const EXPECTED_CAPTURES = 8;
|
||||
|
||||
function parseArguments(argv) {
|
||||
|
|
@ -1394,6 +1394,62 @@ async function main() {
|
|||
console.log(`Serving ${serveRoot}`);
|
||||
console.log(`Evidence ${evidenceRoot}\n`);
|
||||
|
||||
const notFoundScope = "404 artifact and recovery";
|
||||
await results.scenario(notFoundScope, async () => {
|
||||
const artifact = path.join(serveRoot, "404.html");
|
||||
results.equal(notFoundScope, "top-level 404 artifact exists", true, fs.existsSync(artifact));
|
||||
const opened = await openPage(browser, server.origin, { path: "/404.html" }, { width: 390 });
|
||||
try {
|
||||
const state = await opened.page.evaluate(() => {
|
||||
const robots = [...document.querySelectorAll("meta[name='robots']")].map((element) => element.getAttribute("content") || "");
|
||||
const h1s = [...document.querySelectorAll("h1")].map((element) => element.textContent?.replace(/\s+/g, " ").trim() || "");
|
||||
const englishCopy = [...document.querySelectorAll("[lang='en']")].some((element) => /Page not found\./.test(element.textContent || ""));
|
||||
const links = [...document.querySelectorAll("main a[href]")].map((element) => ({
|
||||
href: element.getAttribute("href"),
|
||||
lang: element.getAttribute("lang"),
|
||||
text: element.textContent?.replace(/\s+/g, " ").trim() || "",
|
||||
}));
|
||||
const executableScripts = [...document.scripts].filter((script) => {
|
||||
const type = (script.getAttribute("type") || "").trim().toLowerCase();
|
||||
return !["application/ld+json", "application/json", "importmap"].includes(type);
|
||||
}).length;
|
||||
return {
|
||||
lang: document.documentElement.lang,
|
||||
mainCount: document.querySelectorAll("main").length,
|
||||
h1s,
|
||||
robots,
|
||||
englishCopy,
|
||||
links,
|
||||
executableScripts,
|
||||
viewportWidth: innerWidth,
|
||||
documentWidth: document.documentElement.scrollWidth,
|
||||
};
|
||||
});
|
||||
const axe = await runAxe(opened.page);
|
||||
results.equal(notFoundScope, "local artifact route responds", 200, opened.status);
|
||||
results.equal(notFoundScope, "document language is Korean", "ko", state.lang);
|
||||
results.equal(notFoundScope, "one main landmark", 1, state.mainCount);
|
||||
results.equal(notFoundScope, "one unique h1", 1, state.h1s.length);
|
||||
results.equal(notFoundScope, "h1 identifies the missing page", "페이지를 찾을 수 없습니다", state.h1s[0]);
|
||||
results.equal(notFoundScope, "English explanation is language tagged", true, state.englishCopy);
|
||||
results.equal(notFoundScope, "one robots directive", 1, state.robots.length);
|
||||
results.check(notFoundScope, "robots directive prevents indexing", state.robots[0]?.split(",").some((value) => value.trim().toLowerCase() === "noindex"), {
|
||||
expected: "noindex",
|
||||
actual: state.robots,
|
||||
});
|
||||
results.check(notFoundScope, "Korean home recovery link exists", state.links.some((link) => link.href === "/" && link.text.endsWith("한국어 홈")), { actual: state.links });
|
||||
results.check(notFoundScope, "English home recovery link exists and is language tagged", state.links.some((link) => link.href === "/en/" && link.lang === "en" && link.text === "EN English home"), { actual: state.links });
|
||||
results.equal(notFoundScope, "no executable scripts", 0, state.executableScripts);
|
||||
results.check(notFoundScope, "no horizontal document overflow", state.documentWidth <= state.viewportWidth + 1, {
|
||||
expected: `<= ${state.viewportWidth + 1}`,
|
||||
actual: state.documentWidth,
|
||||
});
|
||||
results.empty(notFoundScope, "axe WCAG A/AA violations", axe);
|
||||
} finally {
|
||||
await closePage(opened.page);
|
||||
}
|
||||
});
|
||||
|
||||
// Four routes across the complete local preflight width matrix. Only the
|
||||
// 390/1440 states create visual evidence; every width gets the full geometry gate.
|
||||
for (const route of ROUTES) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue