// tests/e2e-landing/emitted-output.spec.ts
import fs from "node:fs";
import path from "node:path";
import { expect, test } from "@playwright/test";
/**
* Release contract for the built landing site: every same-origin reference in the
* emitted HTML has to resolve to a file the build actually wrote.
*
* A rendered-page walk cannot cover this. Playwright would have to visit all 798
* pages to see the `` heads where the breakage lives, and a
* page that is never visited is a page whose dead links nobody notices. Reading
* `dist` directly checks all of them in about a second.
*
* The landing harness builds before it previews, so `dist` is the exact tree the
* preview server is serving.
*/
const DIST = path.resolve(__dirname, "../../apps/landing/dist");
const SITE_ORIGIN = "https://snapotter.com";
function walk(dir: string, acc: string[] = []): string[] {
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
const full = path.join(dir, entry.name);
if (entry.isDirectory()) walk(full, acc);
else acc.push(full);
}
return acc;
}
const REFERENCE_RE =
/<(a|link|script|img|source|iframe|form|video|audio|track)\b[^>]*?\s(href|src|action|srcset)\s*=\s*("([^"]*)"|'([^']*)')/gi;
interface Emitted {
files: Set;
htmlFiles: string[];
redirects: Map;
}
function readEmitted(): Emitted {
const all = walk(DIST).map((f) => path.relative(DIST, f).split(path.sep).join("/"));
const redirects = new Map();
const redirectsFile = path.join(DIST, "_redirects");
if (fs.existsSync(redirectsFile)) {
for (const line of fs.readFileSync(redirectsFile, "utf8").split("\n")) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith("#")) continue;
const [from, to] = trimmed.split(/\s+/);
// Splat and placeholder rules are skipped on purpose. Letting a wildcard
// satisfy a target would green the crawl over pages that do not exist.
if (!from || !to || from.includes("*") || from.includes(":")) continue;
redirects.set(from.replace(/\/$/, "") || "/", to);
}
}
return {
files: new Set(all),
htmlFiles: all.filter((f) => f.endsWith(".html")),
redirects,
};
}
/** On-disk paths a pathname could be served from under static hosting. */
function candidates(pathname: string): string[] {
const clean = decodeURIComponent(pathname).replace(/^\//, "");
if (clean === "") return ["index.html"];
if (clean.endsWith("/")) return [clean, `${clean}index.html`];
return [clean, `${clean}.html`, `${clean}/index.html`];
}
function resolvesOnDisk(emitted: Emitted, pathname: string): boolean {
if (candidates(pathname).some((c) => emitted.files.has(c))) return true;
const redirect = emitted.redirects.get(pathname.replace(/\/$/, "") || "/");
if (!redirect) return false;
return candidates(new URL(redirect, "http://local").pathname).some((c) => emitted.files.has(c));
}
test.describe("landing emitted output", () => {
test("every same-origin reference resolves to an emitted file", () => {
const emitted = readEmitted();
expect(emitted.htmlFiles.length).toBeGreaterThan(500);
const missing = new Map }>();
let sameOrigin = 0;
for (const rel of emitted.htmlFiles) {
const html = fs.readFileSync(path.join(DIST, rel), "utf8");
const dirname = path.dirname(rel);
const base = `http://local/${dirname === "." ? "" : `${dirname}/`}`;
for (const match of html.matchAll(REFERENCE_RE)) {
const attr = match[2].toLowerCase();
const raw = (match[4] ?? match[5] ?? "").trim();
if (!raw) continue;
const values =
attr === "srcset" ? raw.split(",").map((v) => v.trim().split(/\s+/)[0]) : [raw];
for (const value of values) {
if (!value || /^(mailto:|tel:|javascript:|data:|blob:|#)/i.test(value)) continue;
let url: URL;
try {
url = new URL(value, base);
} catch {
continue;
}
const sameSite = url.hostname === "local" || url.origin === SITE_ORIGIN;
if (!sameSite) continue;
sameOrigin += 1;
if (resolvesOnDisk(emitted, url.pathname)) continue;
const entry = missing.get(url.pathname) ?? { count: 0, sources: new Set() };
entry.count += 1;
entry.sources.add(rel);
missing.set(url.pathname, entry);
}
}
}
expect(sameOrigin).toBeGreaterThan(10_000);
const sample = [...missing.entries()]
.slice(0, 8)
.map(([target, v]) => `${target} (from ${[...v.sources][0]})`);
expect(
[...missing.keys()].length,
`${missing.size} same-origin targets are referenced but never emitted. First few:\n ${sample.join("\n ")}`,
).toBe(0);
});
test("no page loads a subresource from a third-party host", () => {
// PostHog and Sentry are the only destinations this project is allowed to
// talk to, and both are reached from inline script at runtime, never as a
// tag in the markup. So every fetching tag in the emitted HTML has to point
// at our own origin. A hot-linked badge or a font CDN leaks the visitor's IP,
// Referer, and UA to a third party on every single page view.
const emitted = readEmitted();
// Tags the browser fetches without being asked. `` and the
// non-fetching values (canonical, alternate) are navigation
// metadata, not egress, so they stay out.
const FETCHING_REL = new Set([
"stylesheet",
"preload",
"prefetch",
"modulepreload",
"preconnect",
"dns-prefetch",
"icon",
"shortcut icon",
"apple-touch-icon",
"manifest",
]);
const TAG_RE = /<(script|img|iframe|source|video|audio|track|embed|link)\b([^>]*)>/gi;
const ATTR_RE = /\s(src|srcset|href|rel)\s*=\s*("([^"]*)"|'([^']*)')/gi;
const offenders = new Map }>();
for (const rel of emitted.htmlFiles) {
const html = fs.readFileSync(path.join(DIST, rel), "utf8");
for (const tag of html.matchAll(TAG_RE)) {
const name = tag[1].toLowerCase();
const attrs: Record = {};
for (const a of tag[2].matchAll(ATTR_RE)) {
attrs[a[1].toLowerCase()] = a[3] ?? a[4] ?? "";
}
if (name === "link" && !FETCHING_REL.has((attrs.rel ?? "").toLowerCase())) continue;
const raw = [attrs.src, attrs.srcset, name === "link" ? attrs.href : undefined];
for (const value of raw) {
if (!value) continue;
for (const candidate of value.split(",").map((v) => v.trim().split(/\s+/)[0])) {
if (!candidate || /^(data:|blob:|#)/i.test(candidate)) continue;
let url: URL;
try {
url = new URL(candidate, "http://local/");
} catch {
continue;
}
if (url.hostname === "local" || url.origin === SITE_ORIGIN) continue;
const key = `${url.origin} (${name})`;
const entry = offenders.get(key) ?? { count: 0, sources: new Set() };
entry.count += 1;
entry.sources.add(rel);
offenders.set(key, entry);
}
}
}
}
const detail = [...offenders.entries()]
.map(([origin, v]) => `${origin} on ${v.count} page(s), e.g. ${[...v.sources][0]}`)
.join("\n ");
expect([...offenders.keys()], `third-party subresources in the build:\n ${detail}`).toEqual(
[],
);
});
test("English-only pages advertise no localized alternate that was never built", () => {
const emitted = readEmitted();
// Tool-detail pages and /self-hosted/ are built in English only. Their
// hreflang set must therefore be the self-reference plus x-default, never a
// per-locale fan-out at a URL the build did not write.
const englishOnly = emitted.htmlFiles.filter(
(f) =>
/^tools\/(image|video|audio|pdf|files)\/[^/]+\/index\.html$/.test(f) ||
/^self-hosted\/([^/]+\/)?index\.html$/.test(f),
);
expect(englishOnly.length).toBeGreaterThan(200);
const offenders: string[] = [];
for (const rel of englishOnly) {
const html = fs.readFileSync(path.join(DIST, rel), "utf8");
for (const match of html.matchAll(
/]*\brel=["']alternate["'][^>]*\bhref=["']([^"']+)["']/gi,
)) {
const target = new URL(match[1], SITE_ORIGIN);
if (target.origin !== SITE_ORIGIN) continue;
if (!resolvesOnDisk(emitted, target.pathname)) {
offenders.push(`${rel} -> ${target.pathname}`);
}
}
}
expect(
offenders,
`dangling hreflang alternates:\n ${offenders.slice(0, 8).join("\n ")}`,
).toEqual([]);
});
});