Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions scripts/availability-probes.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,18 @@ test("fixture: a missing availability job or loop yields null", () => {
assert.equal(probedUrls(GOOD_YAML.replace("for url in", "for u in")), null);
});

test("fixture: siteUrlToFile resolves /, directories and bare files, and rejects the bare origin, foreign hosts and traversal", () => {
assert.equal(siteUrlToFile(SITE_ORIGIN + "/"), join(ROOT, "index.html"));
assert.equal(siteUrlToFile(SITE_ORIGIN + "/stories/"), join(ROOT, "stories", "index.html"));
assert.equal(siteUrlToFile(SITE_ORIGIN + "/og.png?v=2#x"), join(ROOT, "og.png"));
// Unlike page-meta's resolver, the bare origin is not the home page here: a
// probe URL must carry its trailing slash or curl sees a 301, not the page.
assert.equal(siteUrlToFile(SITE_ORIGIN), null);
assert.equal(siteUrlToFile("https://docs.hivecommons.dev/"), null);
assert.equal(siteUrlToFile(SITE_ORIGIN + "/../scripts/availability-probes.test.mjs"), null);
assert.equal(siteUrlToFile(SITE_ORIGIN + "/definitely-not-a-page/"), null);
});

test("fixture: sitemap <loc> values are extracted", () => {
assert.deepEqual(sitemapLocs(`<urlset><url><loc> ${SITE_ORIGIN}/ </loc></url><url><loc>${SITE_ORIGIN}/a/</loc></url></urlset>`), [
`${SITE_ORIGIN}/`, `${SITE_ORIGIN}/a/`,
Expand Down
2 changes: 0 additions & 2 deletions scripts/coverage-floor.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ const CHILD_ENV = "COVERAGE_FLOOR_CHILD";
export const TEST_HELPER_BASELINE = {
"scripts/acmm-levels.test.mjs": 3,
"scripts/automation-docs.test.mjs": 4,
"scripts/availability-probes.test.mjs": 2,
"scripts/carousels.test.mjs": 6,
"scripts/ci-wiring.test.mjs": 6,
"scripts/dependabot-config.test.mjs": 9,
Expand All @@ -44,7 +43,6 @@ export const TEST_HELPER_BASELINE = {
"scripts/no-js-controls.test.mjs": 5,
"scripts/page-404.test.mjs": 5,
"scripts/page-images.test.mjs": 19,
"scripts/page-markup.test.mjs": 2,
"scripts/page-meta.test.mjs": 20,
"scripts/page-structure.test.mjs": 7,
"scripts/pages-build.test.mjs": 4,
Expand Down
10 changes: 9 additions & 1 deletion scripts/page-markup.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ function markupOnly(html) {
function attrValue(tag, name) {
const m = new RegExp(`\\s${name}\\s*=\\s*(?:"([^"]*)"|'([^']*)'|([^\\s"'>]+))`, "i").exec(tag);
if (!m) return null;
return m[1] ?? m[2] ?? m[3] ?? "";
// Exactly one alternative matched; the quoted ones capture "" for an empty value.
return m[1] ?? m[2] ?? m[3];
}

function hasAttr(tag, name) {
Expand Down Expand Up @@ -172,6 +173,13 @@ test("fixture: ids declared only inside <script> text do not satisfy idrefs", ()
assert.equal(danglingIdrefs(html).length, 1);
});

test("fixture: unquoted and single-quoted attribute values are read like double-quoted ones", () => {
const html = `<html lang=en><body>\n<input id=name>\n<label for=name></label>\n<label for='name'></label>\n<label for=gone></label>\n<p id=name></p></body></html>`;
assert.deepEqual(danglingIdrefs(html), ['line 5: for="gone" does not match any id on the page']);
assert.deepEqual(duplicateIds(html), ['line 6: duplicate id "name" (first at line 2)']);
assert.deepEqual(missingHtmlLang(html), []);
});

test("fixture: <img> without alt is reported; alt=\"\" and unquoted alt are fine", () => {
const html = `<html lang="en"><body>\n<img src="a.png">\n<img src="b.png" alt="">\n<img alt=x src="c.png">\n<img src="d.png"\n width="1"></body></html>`;
assert.deepEqual(imagesWithoutAlt(html), [
Expand Down
Loading