feat(harness): centralize browser coverage contract

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-03-24 18:34:56 +08:00
parent 151d776842
commit fe24dfba68
4 changed files with 227 additions and 122 deletions
+28 -56
View File
@@ -3,6 +3,7 @@ import path from "node:path";
import { createRequire } from "node:module";
import { chromium } from "@playwright/test";
import harnessStoryContract from "../../tests/e2e/support/story-harness-contract.json" with { type: "json" };
import { repoRoot } from "./core.mjs";
@@ -16,65 +17,36 @@ const axeSourcePath = require.resolve("axe-core/axe.min.js");
const reportDir = path.join(repoRoot, ".artifacts", "a11y");
const reportPath = path.join(reportDir, "storybook-a11y.json");
const stories = [
{
id: "components-button--playground",
label: "Button playground"
const a11yPrepareHandlers = {
"open-date-picker": async (page) => {
await page.getByRole("combobox", { name: "Launch date" }).click();
await page.getByRole("dialog", { name: "Launch date calendar" }).waitFor({ state: "visible" });
},
{
id: "components-combobox--controlled",
label: "Combobox controlled"
"open-dialog": async (page) => {
await page.getByRole("button", { name: "Open approval dialog" }).click();
await page.getByRole("dialog", { name: "Launch this release?" }).waitFor({ state: "visible" });
},
{
id: "components-data-table--playground",
label: "Data table playground"
"open-dropdown-menu": async (page) => {
await page.getByRole("button", { name: "Review lane menu" }).click();
await page.getByRole("menu").waitFor({ state: "visible" });
},
{
id: "components-datepicker--playground",
label: "Date picker playground",
prepare: async (page) => {
await page.getByRole("combobox", { name: "Launch date" }).click();
await page.getByRole("dialog", { name: "Launch date calendar" }).waitFor({ state: "visible" });
}
"open-popover": async (page) => {
await page.getByRole("button", { name: "Inspect summary" }).click();
await page.getByText("Release health").waitFor({ state: "visible" });
},
{
id: "components-dialog--playground",
label: "Dialog playground",
prepare: async (page) => {
await page.getByRole("button", { name: "Open approval dialog" }).click();
await page.getByRole("dialog", { name: "Launch this release?" }).waitFor({ state: "visible" });
}
},
{
id: "components-dropdownmenu--states",
label: "Dropdown menu states",
prepare: async (page) => {
await page.getByRole("button", { name: "Review lane menu" }).click();
await page.getByRole("menu").waitFor({ state: "visible" });
}
},
{
id: "components-form--launch-settings",
label: "Form launch settings",
query: "globals=motion:reduced"
},
{
id: "components-popover--playground",
label: "Popover playground",
prepare: async (page) => {
await page.getByRole("button", { name: "Inspect summary" }).click();
await page.getByText("Release health").waitFor({ state: "visible" });
}
},
{
id: "components-sheet--playground",
label: "Sheet playground",
prepare: async (page) => {
await page.getByRole("button", { name: "Open right sheet" }).click();
await page.getByRole("dialog", { name: "Launch settings" }).waitFor({ state: "visible" });
}
"open-sheet": async (page) => {
await page.getByRole("button", { name: "Open right sheet" }).click();
await page.getByRole("dialog", { name: "Launch settings" }).waitFor({ state: "visible" });
}
];
};
const stories = harnessStoryContract.stories.filter((story) => story.suites.includes("a11y"));
for (const story of stories) {
if (story.a11yPrepare && !(story.a11yPrepare in a11yPrepareHandlers)) {
throw new Error(`Unknown a11y prepare handler "${story.a11yPrepare}" for ${story.id}.`);
}
}
function buildStoryUrl(story) {
const params = new URLSearchParams({
@@ -215,8 +187,8 @@ async function main() {
try {
await gotoStory(page, story);
if (story.prepare) {
await story.prepare(page);
if (story.a11yPrepare) {
await a11yPrepareHandlers[story.a11yPrepare](page);
}
const result = await runAxe(page);
@@ -0,0 +1,35 @@
// @vitest-environment node
import { describe, expect, it } from "vitest";
import harnessStoryContract from "../../tests/e2e/support/story-harness-contract.json";
describe("story harness contract", () => {
it("uses unique story ids", () => {
const storyIds = harnessStoryContract.stories.map((story) => story.id);
expect(new Set(storyIds).size).toBe(storyIds.length);
});
it("requires a reason for every curated story", () => {
expect(harnessStoryContract.stories.every((story) => story.reason.trim().length > 0)).toBe(true);
});
it("requires smoke scenarios for docs-smoke coverage", () => {
expect(
harnessStoryContract.stories
.filter((story) => story.suites.includes("docs-smoke"))
.every((story) => Boolean(story.smokeScenario))
).toBe(true);
});
it("keeps every story on at least one supported suite", () => {
const supportedSuites = new Set(["a11y", "docs-smoke"]);
expect(
harnessStoryContract.stories.every(
(story) => story.suites.length > 0 && story.suites.every((suite) => supportedSuites.has(suite))
)
).toBe(true);
});
});