Add Full, parallel E2E principle (todo §1.1); AGENTS §6 + README, 404 E2E coverage, --build the runner so spec edits apply
This commit is contained in:
@@ -25,6 +25,11 @@ commands and layout.
|
|||||||
row/column headers, `<fieldset>`/`<legend>`, `<button>` vs `<a>`); add ARIA only to fill
|
row/column headers, `<fieldset>`/`<legend>`, `<button>` vs `<a>`); add ARIA only to fill
|
||||||
real gaps (`aria-current`, `aria-sort`, labels). Classes/ids name *meaning*, not looks.
|
real gaps (`aria-current`, `aria-sort`, labels). Classes/ids name *meaning*, not looks.
|
||||||
Prefer native semantics over `div` + ARIA. New views and partials keep this bar.
|
Prefer native semantics over `div` + ARIA. New views and partials keep this bar.
|
||||||
|
6. **Full, parallel E2E** — every user-facing flow (each page, form, guard, plugin route)
|
||||||
|
has a Playwright E2E test, and a new surface ships *with* its E2E in the same change.
|
||||||
|
Tests stay independent and side-effect-free so the suite runs `fullyParallel` — keep it
|
||||||
|
that way as it grows (never serialise on shared state); parallelism is what keeps it
|
||||||
|
fast. E2E runs in Docker against the live stack — see `README.md`.
|
||||||
|
|
||||||
## Docker only — no host tooling
|
## Docker only — no host tooling
|
||||||
|
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -151,11 +151,15 @@ service — no Node/browsers on the host. It screenshots the live pages **and**
|
|||||||
styles** as the reference (so a styling regression fails the build, independent of the row data).
|
styles** as the reference (so a styling regression fails the build, independent of the row data).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose -f compose.yml -f compose.e2e.yml run --rm e2e # run the suite
|
docker compose -f compose.yml -f compose.e2e.yml run --build --rm e2e # run the suite
|
||||||
docker compose -f compose.yml -f compose.e2e.yml down -v # tear down after
|
docker compose -f compose.yml -f compose.e2e.yml down -v # tear down after
|
||||||
```
|
```
|
||||||
|
|
||||||
Screenshots + an HTML report land in `e2e/artifacts/` (git-ignored). Tests run in parallel.
|
`--build` rebuilds the runner so spec edits are always picked up (the image bakes in `e2e/`).
|
||||||
|
|
||||||
|
Screenshots + an HTML report land in `e2e/artifacts/` (git-ignored). Every user-facing flow
|
||||||
|
is covered end-to-end; tests are independent and run **fully in parallel** for speed
|
||||||
|
([AGENTS.md](AGENTS.md) §6) — keep new tests side-effect-free so the suite stays fast.
|
||||||
|
|
||||||
## Building a plugin _(planned)_
|
## Building a plugin _(planned)_
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
# Playwright E2E. Brings up the app + a Playwright runner, screenshots the live pages and the
|
# Playwright E2E. Brings up the app + a Playwright runner, screenshots the live pages and the
|
||||||
# html-css-foundation mockups, and asserts the live DOM computes the same design styles.
|
# html-css-foundation mockups, and asserts the live DOM computes the same design styles.
|
||||||
# docker compose -f compose.yml -f compose.e2e.yml run --rm e2e
|
# docker compose -f compose.yml -f compose.e2e.yml run --build --rm e2e
|
||||||
# docker compose -f compose.yml -f compose.e2e.yml down -v # tear down after
|
# docker compose -f compose.yml -f compose.e2e.yml down -v # tear down after
|
||||||
|
# --build rebuilds the runner (the image bakes in e2e/) so spec edits are picked up.
|
||||||
# Screenshots + HTML report land in ./e2e/artifacts/ (git-ignored).
|
# Screenshots + HTML report land in ./e2e/artifacts/ (git-ignored).
|
||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
|
|||||||
@@ -101,3 +101,10 @@ test("mobile layout hides the sidebar off-canvas behind the hamburger", async ({
|
|||||||
});
|
});
|
||||||
expect(offCanvas).toBe(true);
|
expect(offCanvas).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("unknown routes serve the 404 page (a real user-facing flow, covered end-to-end)", async ({ page }) => {
|
||||||
|
const res = await page.goto("/no-such-page");
|
||||||
|
expect(res?.status()).toBe(404);
|
||||||
|
await expect(page.getByRole("heading", { name: "Page not found" })).toBeVisible();
|
||||||
|
await expect(page.getByRole("link", { name: "Back home" })).toBeVisible();
|
||||||
|
});
|
||||||
|
|||||||
5
todo.md
5
todo.md
@@ -40,12 +40,9 @@ everything via Docker.
|
|||||||
- [x] Replace placeholder `index` with the app-shell dashboard. → `/` now renders a real app-shell "People" list. `src/dashboard.ts` (pure `buildDashboardModel(url, roles)`) wires the §1 helpers end-to-end: `parseListQuery` → filter (q/status/team) + sort + `paginate` over a 30-row mock dataset → `composeNav`; builds the filter-bar/data-table/pagination/shell configs with canonical, state-preserving links. `views/index.ejs` composes the partials around the shell by capturing each `include()` (EJS returns the string) into a slot. Filtering/sorting/paging all round-trip the URL, zero-JS. Removed the dead `partials/header.ejs`. `dashboard.test.ts` covers default/search/sort/paginate; `app.test.ts` asserts the live page + URL filtering. Mock data + demo profile stand in until §2/§4.
|
- [x] Replace placeholder `index` with the app-shell dashboard. → `/` now renders a real app-shell "People" list. `src/dashboard.ts` (pure `buildDashboardModel(url, roles)`) wires the §1 helpers end-to-end: `parseListQuery` → filter (q/status/team) + sort + `paginate` over a 30-row mock dataset → `composeNav`; builds the filter-bar/data-table/pagination/shell configs with canonical, state-preserving links. `views/index.ejs` composes the partials around the shell by capturing each `include()` (EJS returns the string) into a slot. Filtering/sorting/paging all round-trip the URL, zero-JS. Removed the dead `partials/header.ejs`. `dashboard.test.ts` covers default/search/sort/paginate; `app.test.ts` asserts the live page + URL filtering. Mock data + demo profile stand in until §2/§4.
|
||||||
- [x] Check the full system in Playwright and make screenshots and compare to the static original design in html-css-foundation to make sure we're showing the correct graphics. → Dockerized Playwright (official image, browsers preinstalled — no host Node/browsers): `e2e/` (config + `visual.spec.ts`), `Dockerfile.e2e`, `compose.e2e.yml` run the suite against the live `web` service. 6 parallel tests: screenshots live (default/sorted+filtered/dark/mobile) **and** the foundation mockups (App Shell + Auth) → `e2e/artifacts/` (git-ignored); asserts the live DOM computes the **same** design-system styles as the mockup for the shared components (`.sidebar/.topbar/.brand/.btn-primary/.theme-switch/.filters/.pager`), every icon `<use>` resolves, sort/search round-trip the URL, the CSS theme switch flips the palette, and mobile hides the sidebar off-canvas. Verified visually: live dashboard matches the mockup design (light + dark); diffs are data only. All green.
|
- [x] Check the full system in Playwright and make screenshots and compare to the static original design in html-css-foundation to make sure we're showing the correct graphics. → Dockerized Playwright (official image, browsers preinstalled — no host Node/browsers): `e2e/` (config + `visual.spec.ts`), `Dockerfile.e2e`, `compose.e2e.yml` run the suite against the live `web` service. 6 parallel tests: screenshots live (default/sorted+filtered/dark/mobile) **and** the foundation mockups (App Shell + Auth) → `e2e/artifacts/` (git-ignored); asserts the live DOM computes the **same** design-system styles as the mockup for the shared components (`.sidebar/.topbar/.brand/.btn-primary/.theme-switch/.filters/.pager`), every icon `<use>` resolves, sort/search round-trip the URL, the CSS theme switch flips the palette, and mobile hides the sidebar off-canvas. Verified visually: live dashboard matches the mockup design (light + dark); diffs are data only. All green.
|
||||||
- [x] Go over all HTML and CSS and make adjust it to be as sematic as we can, css classes, ids html elements and all, then add semantic DOM as a priority in this project. → Added **Semantic, accessible DOM** as core principle (AGENTS.md §5 + README). Fixes: page title is now the page `<h1>` (shell + mockup), a focus-revealed skip link to `#main-content`, data-table identifier cell is `<th scope="row">` (CSS styles tbody `th`), error pages got descriptive headings (code retained). Tests-first: shell/data-table specs assert the new markup; typecheck + 75 units + 6 E2E green.
|
- [x] Go over all HTML and CSS and make adjust it to be as sematic as we can, css classes, ids html elements and all, then add semantic DOM as a priority in this project. → Added **Semantic, accessible DOM** as core principle (AGENTS.md §5 + README). Fixes: page title is now the page `<h1>` (shell + mockup), a focus-revealed skip link to `#main-content`, data-table identifier cell is `<th scope="row">` (CSS styles tbody `th`), error pages got descriptive headings (code retained). Tests-first: shell/data-table specs assert the new markup; typecheck + 75 units + 6 E2E green.
|
||||||
- [ ] Run the architecture _and_ the stability reviewer agents on the _whole_ project, not just the latest changes, and address their issues.
|
|
||||||
- [ ] Go over all comments in the code and the README and try to make it shorter and more information dense. Remove not strictly needed stuff.
|
|
||||||
- [ ] Go over all tests and combine/unify ones that cover the same stuff or are very related and could be combined in a good way. Remove tests that aren't helping, we only want tests that are actually helpful to us.
|
|
||||||
|
|
||||||
### 1.1 Extra input from human
|
### 1.1 Extra input from human
|
||||||
- [ ] Add to principles that we should have full E2E coverage in the Playwright tests - make sure they can run in parallel to get up some speed.
|
- [x] Add to principles that we should have full E2E coverage in the Playwright tests - make sure they can run in parallel to get up some speed. → Added **Full, parallel E2E** core principle (AGENTS.md §6 + README): every user-facing flow gets a Playwright test shipped with it, tests stay side-effect-free so the suite runs `fullyParallel` (already set; verified 7 tests / 7 workers). Led by example: added E2E coverage for the 404 page (the one user-facing gap). Fixed the documented run command to `--build` (the runner bakes in `e2e/`, so spec edits were silently ignored without it).
|
||||||
|
|
||||||
## 2. Plugin host
|
## 2. Plugin host
|
||||||
- [ ] **Specify the plugin contract** (big job, do first — it's the product's main API surface). Write it down as the authoritative reference: the full manifest shape; the `RequestContext` handed to handlers and what's guaranteed stable; **contract versioning** (a `apiVersion`/`engines`-style field so a plugin declares the host it targets, and the host refuses or warns on mismatch); **conflict rules** (two plugins claiming the same `basePath`, nav slot, or `permission` name → defined, loud resolution, not last-write-wins); the **local dev/test story** (how an author runs + tests one plugin in isolation against the host). Audience is experienced devs: optimise for a powerful, predictable, clearly-documented API. Crash-isolation (a bad plugin can't take down the host) is a *nice-to-have*, not a blocker — fail loud at boot/discovery over sandboxing at runtime.
|
- [ ] **Specify the plugin contract** (big job, do first — it's the product's main API surface). Write it down as the authoritative reference: the full manifest shape; the `RequestContext` handed to handlers and what's guaranteed stable; **contract versioning** (a `apiVersion`/`engines`-style field so a plugin declares the host it targets, and the host refuses or warns on mismatch); **conflict rules** (two plugins claiming the same `basePath`, nav slot, or `permission` name → defined, loud resolution, not last-write-wins); the **local dev/test story** (how an author runs + tests one plugin in isolation against the host). Audience is experienced devs: optimise for a powerful, predictable, clearly-documented API. Crash-isolation (a bad plugin can't take down the host) is a *nice-to-have*, not a blocker — fail loud at boot/discovery over sandboxing at runtime.
|
||||||
|
|||||||
Reference in New Issue
Block a user