Skip to content
Draft
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
126 changes: 126 additions & 0 deletions tests/data/groups.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
{
"https://respec.org/w3c/groups/css/": {
"body": {
"shortname": "css",
"type": "wg",
"id": 32061,
"name": "Cascading Style Sheets (CSS) Working Group",
"URI": "https://www.w3.org/groups/wg/css/",
"patentURI": "https://www.w3.org/groups/wg/css/ipr",
"patentPolicy": "PP2020",
"wgURI": "https://www.w3.org/groups/wg/css"
}
},
"https://respec.org/w3c/groups/maps4html/": {
"body": {
"shortname": "maps4html",
"type": "cg",
"id": 70543,
"name": "Maps For HTML Community Group",
"URI": "https://www.w3.org/community/maps4html/",
"wgURI": "https://www.w3.org/groups/cg/maps4html"
}
},
"https://respec.org/w3c/groups/payments/": {
"body": {
"shortname": "payments",
"type": "wg",
"id": 83744,
"name": "Web Payments Working Group",
"URI": "https://www.w3.org/groups/wg/payments/",
"patentURI": "https://www.w3.org/groups/wg/payments/ipr",
"patentPolicy": "PP2020",
"wgURI": "https://www.w3.org/groups/wg/payments"
}
},
"https://respec.org/w3c/groups/publishingbg/": {
"body": {
"shortname": "publishingbg",
"type": "bg",
"id": 97159,
"name": "Publishing Business Group",
"URI": "https://www.w3.org/community/publishingbg/",
"wgURI": "https://www.w3.org/groups/bg/publishingbg"
}
},
"https://respec.org/w3c/groups/tag/": {
"body": {
"shortname": "tag",
"type": "other",
"id": 34270,
"name": "Technical Architecture Group",
"URI": "https://www.w3.org/2001/tag/",
"wgURI": "https://www.w3.org/groups/other/tag"
}
},
"https://respec.org/w3c/groups/webapps/": {
"body": {
"shortname": "webapps",
"type": "wg",
"id": 114929,
"name": "Web Applications Working Group",
"URI": "https://www.w3.org/groups/wg/webapps/",
"patentURI": "https://www.w3.org/groups/wg/webapps/ipr",
"patentPolicy": "PP2020",
"wgURI": "https://www.w3.org/groups/wg/webapps"
}
},
"https://respec.org/w3c/groups/webperf/": {
"body": {
"shortname": "webperf",
"type": "wg",
"id": 45211,
"name": "Web Performance Working Group",
"URI": "https://www.w3.org/groups/wg/webperf/",
"patentURI": "https://www.w3.org/groups/wg/webperf/ipr",
"patentPolicy": "PP2020",
"wgURI": "https://www.w3.org/groups/wg/webperf"
}
},
"https://respec.org/w3c/groups/wicg/": {
"body": {
"shortname": "wicg",
"type": "cg",
"id": 80485,
"name": "Web Platform Incubator Community Group",
"URI": "https://www.w3.org/community/wicg/",
"wgURI": "https://www.w3.org/groups/cg/wicg"
}
},
"https://respec.org/w3c/groups/wot/wg": {
"body": {
"shortname": "wot",
"type": "wg",
"id": 95969,
"name": "Web of Things Working Group",
"URI": "https://www.w3.org/WoT/wg/",
"patentURI": "https://www.w3.org/groups/wg/wot/ipr",
"patentPolicy": "PP2020",
"wgURI": "https://www.w3.org/groups/wg/wot"
}
},
"https://respec.org/w3c/groups/json-ld/wg": {
"body": {
"shortname": "json-ld",
"type": "wg",
"id": 107714,
"name": "JSON-LD Working Group",
"URI": "https://www.w3.org/groups/wg/json-ld/",
"patentURI": "https://www.w3.org/groups/wg/json-ld/ipr",
"patentPolicy": "PP2020",
"wgURI": "https://www.w3.org/groups/wg/json-ld"
}
},
"https://respec.org/w3c/groups/wot/": {
"status": 409,
"body": "Multiple groups with shortname: \"wot\".\nPlease use either: \"cg/wot\", \"ig/wot\", \"wg/wot\"."
},
"https://respec.org/w3c/groups/404/": {
"status": 404,
"body": "No group with shortname: \"404\"."
},
"https://respec.org/w3c/groups/not%20a%20real%20group/": {
"status": 404,
"body": "No group with shortname: \"not a real group\"."
}
}
2 changes: 2 additions & 0 deletions tests/spec/core/exporter-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import {
makeRSDoc,
makeStandardOps,
} from "../SpecHelper.js";
import { seedGroupCache } from "../respec-cache-helper.js";

describe("Core - exporter", () => {
afterAll(flushIframes);
beforeAll(seedGroupCache);

it("removes .removeOnSave elements", async () => {
const ops = makeStandardOps();
Expand Down
2 changes: 2 additions & 0 deletions tests/spec/core/include-config-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import {
makeRSDoc,
makeStandardOps,
} from "../SpecHelper.js";
import { seedGroupCache } from "../respec-cache-helper.js";

describe("Core — Include config as JSON", () => {
afterAll(flushIframes);
beforeAll(seedGroupCache);
let ops;
beforeAll(() => {
ops = {
Expand Down
2 changes: 2 additions & 0 deletions tests/spec/core/seo-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import {
makeRSDoc,
makeStandardOps,
} from "../SpecHelper.js";
import { seedGroupCache } from "../respec-cache-helper.js";

describe("Core — Seo", () => {
afterAll(flushIframes);
beforeAll(seedGroupCache);
it("doesn't insert a meta description element if there is no abstract", async () => {
const ops = {
config: makeBasicConfig(),
Expand Down
2 changes: 2 additions & 0 deletions tests/spec/core/ui-spec.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
"use strict";

import { flushIframes, makeRSDoc, makeStandardOps } from "../SpecHelper.js";
import { seedGroupCache } from "../respec-cache-helper.js";

describe("Core - UI", () => {
afterAll(flushIframes);
beforeAll(seedGroupCache);

it("shows and hides the UI", async () => {
const doc = await makeRSDoc(makeStandardOps());
Expand Down
5 changes: 5 additions & 0 deletions tests/spec/karma.conf.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ const additionalFiles = [
type: "module",
included: false,
},
{
pattern: "tests/spec/respec-cache-helper.js",
type: "module",
included: false,
},
{
pattern: "tests/spec/**/*-spec.js",
type: "module",
Expand Down
58 changes: 58 additions & 0 deletions tests/spec/respec-cache-helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"use strict";

const WEEK = 7 * 24 * 60 * 60 * 1000;

/**
* Pre-seeds the browser Cache API so fetchAndCache() returns cached
* data without hitting the network. Works for any respec.org endpoint.
*
* @param {Record<string, {status?: number, body: any}>} entries
* Keys are full URLs, values have optional status (default 200)
* and a body (object for JSON, string for text).
*/
export async function seedCache(entries) {
const byOrigin = new Map();
for (const [url, entry] of Object.entries(entries)) {
const origin = new URL(url).origin;
if (!byOrigin.has(origin)) byOrigin.set(origin, []);
byOrigin.get(origin).push([url, entry]);
}
const expires = new Date(Date.now() + WEEK).toISOString();
for (const [origin, urls] of byOrigin) {
const cache = await caches.open(origin);
for (const [url, { status = 200, body }] of urls) {
const isJSON = body !== null && typeof body === "object";
const headers = {
"Content-Type": isJSON ? "application/json" : "text/plain",
Expires: expires,
};
const responseBody = isJSON ? JSON.stringify(body) : body;
await cache.put(
new Request(url),
new Response(responseBody, { status, headers })
);
}
}
}

let groupsPromise;

/**
* Seeds the cache with W3C group API responses from tests/data/groups.json.
* Call from beforeAll() in any test file that uses group: in its config.
*/
export async function seedGroupCache() {
if (!groupsPromise) {
groupsPromise = fetch("/tests/data/groups.json")
.then(r => {
if (!r.ok)
throw new Error(`Failed to load groups fixture: ${r.status}`);
return r.json();
})
.catch(err => {
groupsPromise = undefined;
throw err;
});
}
await seedCache(await groupsPromise);
}
Comment on lines +40 to +58
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description suggests all tests using group: no longer depend on the live https://respec.org/w3c/groups/ API, but seedGroupCache() is only being wired into a subset of suites (the W3C ones in this PR). There are other spec files (e.g., under tests/spec/core/ and tests/spec/w3c/linter-rules/) that still set group: and will continue to hit the network when run in isolation (e.g., via --grep). Consider either adding beforeAll(seedGroupCache) to those suites too, or centralizing the seeding in shared test setup (e.g., SpecHelper/test-main) so individual suites can’t forget it.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 551e75e — added seedGroupCache to all 5 remaining test files that use group: in their config: core/exporter-spec.js, core/include-config-spec.js, core/seo-spec.js, core/ui-spec.js, and w3c/linter-rules/required-sections-spec.js.

2 changes: 2 additions & 0 deletions tests/spec/w3c/defaults-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import {
makeRSDoc,
makeStandardOps,
} from "../SpecHelper.js";
import { seedGroupCache } from "../respec-cache-helper.js";
const errorsFilter = errorFilters.filter("w3c/defaults");

describe("W3C — Defaults", () => {
afterAll(flushIframes);
beforeAll(seedGroupCache);
it("sets sensible defaults for w3c specs", async () => {
const ops = {
config: { editors: [{ name: "foo" }], specStatus: "base" },
Expand Down
2 changes: 2 additions & 0 deletions tests/spec/w3c/group-spec.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
"use strict";

import { flushIframes, makeRSDoc, makeStandardOps } from "../SpecHelper.js";
import { seedGroupCache } from "../respec-cache-helper.js";

describe("W3C — Group", () => {
afterAll(flushIframes);
beforeAll(seedGroupCache);

async function getGroupConf(config) {
const ops = makeStandardOps(config);
Expand Down
3 changes: 3 additions & 0 deletions tests/spec/w3c/headers-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
makeStandardOps,
} from "../SpecHelper.js";

import { seedGroupCache } from "../respec-cache-helper.js";

const headerErrors = errorFilters.filter("w3c/headers");
const defaultErrors = errorFilters.filter("w3c/defaults");

Expand All @@ -26,6 +28,7 @@ const findContent = string => {
};
describe("W3C — Headers", () => {
afterEach(flushIframes);
beforeAll(seedGroupCache);
const simpleSpecURL = "spec/core/simple.html";
/**
* @param {Node} node
Expand Down
2 changes: 2 additions & 0 deletions tests/spec/w3c/linter-rules/required-sections-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import {
warningFilters,
} from "../../SpecHelper.js";
import { requiresSomeSectionStatus } from "../../../../src/w3c/linter-rules/required-sections.js";
import { seedGroupCache } from "../../respec-cache-helper.js";

describe("w3c — required-sections", () => {
afterAll(() => {
flushIframes();
});
beforeAll(seedGroupCache);

const errorsFilter = errorFilters.filter(
"w3c/linter-rules/required-sections"
Expand Down
2 changes: 2 additions & 0 deletions tests/spec/w3c/seo-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import { flushIframes, makeRSDoc, makeStandardOps } from "../SpecHelper.js";
import { requiresCanonicalLink } from "../../../src/w3c/seo.js";
import { seedGroupCache } from "../respec-cache-helper.js";

describe("W3C - SEO", () => {
afterAll(flushIframes);
beforeAll(seedGroupCache);

it("defaults to TR as canonical URI", async () => {
const doc = await makeRSDoc(
Expand Down
3 changes: 3 additions & 0 deletions tests/spec/w3c/style-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
makeStandardOps,
} from "../SpecHelper.js";

import { seedGroupCache } from "../respec-cache-helper.js";

const statuses = [
{
specStatus: undefined,
Expand Down Expand Up @@ -163,6 +165,7 @@ const statuses = [

describe("W3C - Style", () => {
afterAll(flushIframes);
beforeAll(seedGroupCache);

it("should include 'fixup.js'", async () => {
const ops = makeStandardOps();
Expand Down
Loading