Repository navigation
test: website e2e as Markdown specs in the ui-verify grammar; smoke every CLI command and MCP tool - #700
Conversation
…site One manifest entry per page (src/routes.ts) generates the page tests; a vitest guard fails when a page.tsx under packages/web has no entry. Public pages run signed out against a local build; dashboard pages also get a signed-out redirect check, and render checks when a test user is configured. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
…dds one without a check - packages/cli/test/smoke: a case manifest that runs the real lorekit binary for all 32 commands, in an offline lane (throwaway HOME, no network) and a remote lane (live endpoint, per-run scope, self-cleaning, refuses prod). - cli-smoke.test.mjs runs the offline lane inside cli:test and guards coverage: every command, alias, local stdio MCP tool and hosted MCP tool needs a check. - smoke-mcp-tools.mjs: add the missing memory.protect, policy.update and groom.run coverage, and report which tools each run exercised. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
The Dash0 GitHub App cannot push .github/workflows/* (no workflows permission). Apply with: git am .github/pending-workflow-changes.patch Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
…mmar Adding a website test is now a Markdown block in packages/web-e2e/specs/, in aw-tester's WHEN/THEN grammar — the body of a <!-- ui-verify:v1 --> PR block — instead of TypeScript. A zero-dep parser (src/spec/grammar.cjs) runs it deterministically, refusing what needs judgment (semantic:, intent specs, continues-from) by name. spec:import / spec:export move specs to and from ui-verify PR blocks and aw-tester's compiled routes. specs.test.ts parses every file and fails a PR when a page.tsx has no spec. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
- CLI smoke and the new hosted MCP check mint keys as smoke-<epoch-ms>-<name>, the shape smoke-cleanup.mjs recognises, so a killed run leaves nothing the sweeper cannot find on the shared preview project. - The remote scopes case asserts the run's scope is listed (it asserted only that a JSON object came back). - The wrong-password journey never targets production auth. - The grammar reads 'signed-in' (hyphenated) as signed in and refuses 'has text', which would silently read as an attribute. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
…oped to steps Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
|
| Gate | Status | Details |
|---|---|---|
| Description vs. code | Body still cites the deleted pending-workflow-changes.patch; wiring is in ci/deploy/preview.yml. Omits /onboarding. | |
| Prior review feedback | ✅ | Earlier review comments are resolved. |
| Documentation | ✅ | docs/smoke-tests.md, specs/README.md, CLAUDE.md package map and adding-an-operation.md cover the suites. |
| Self-review signals | ✅ | No debug logs, leftover TODOs, or unreviewed stubs. |
| Code review | ✅ | The multi-lens review found no blocking issues. |
Found
Quality — produced 0 → posted inline 0 · cleared 0 · carried forward 0 · deferred 0 · below-bar 0
Optimality — ran — approach fits the repo's table-driven guard pattern; no proposal
Standards — ran — 2 governing docs, 62 bullets; 0 findings
Measurability — ran — quiet: test and CI wiring only, no new observable product behaviour
Run
full · 19 lines in delta · tier deep · depth checkout
Integrations — dependency finder: @playwright/test 1.56.0 added to the new web-e2e package, same version as the root pin; no usage-site change
CI — still pending: Typecheck, Test & Lint (affected), Web — Playwright e2e (local build + local Supabase), Web — Storybook interaction + visual tests (changed) · 11 passed
Memories — no relevance rules or lessons consulted
Nothing to report — severity, 0 files skipped.
pr-reviewer · commit 6297f24 · full review · how these findings are produced · updated
Addresses review comment by dash0-dev (pr-reviewer): #700 (comment) Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
Addresses review comment by dash0-dev (pr-reviewer): #700 (comment) Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
R17: type the ui-verify marker table instead of casting its version to any. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
Addresses review comment by dash0-dev (pr-reviewer): #700 (comment) Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
Addresses the pr-reviewer report advisory by dash0-dev (pr-reviewer): #700 (comment) Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
…on is in play Addresses review comment by dash0-dev (pr-reviewer): #700 (comment) Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
Addresses the pr-reviewer report advisory by dash0-dev (pr-reviewer): #700 (comment) Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
Addresses review comment by dash0-dev (pr-reviewer): #700 (comment) Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
Addresses review comment by dash0-dev (pr-reviewer): #700 (comment) Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
Addresses review comment by dash0-dev (pr-reviewer): #700 (comment) Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
Addresses the pr-reviewer report advisory by dash0-dev (pr-reviewer): #700 (comment) Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
Spec numbers move when a spec is added or removed; the title does not. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
- ci.yml: new web-e2e job (local build + local Supabase, every page signed out and signed in) in the CI Summary gate; the web filter covers web-e2e. - deploy.yml: CLI remote lane in smoke-preview; e2e-web-staged runs Playwright on the staged production build and gates promote-web-production; smoke-production runs Playwright against lorekit.io (a failed page rolls back). In both, the test-account sign-in is its own step that can only warn, so a credential problem never blocks promotion or rolls back, and secrets are scoped to the steps that use them. - preview.yml: CLI remote lane, so /preview validates it before merge. Co-authored-by: dash0-dev[bot] <257284812+dash0-dev[bot]@users.noreply.github.com>
# Why local-verify F-1: the `test` target inherited `dependsOn: ["^build"]` from nx.json, and `implicitDependencies: ["web"]` turned that into `web:build:production` — a full Next.js build (or a cache restore over packages/web/.next) before a 7 ms vitest guard that only reads specs/*.md and the page.tsx tree. In CI's `check` job that is a website build per web PR. # What `test.dependsOn: []`. Verified with `nx run web-e2e:test --graph`: the task graph is now `web-e2e:test` alone; the guard still passes (20/20).
# Why
local-verify F-2: `test.use({ allowedConsoleErrors: [/a/, /b/] })` crashed with
"allowedConsoleErrors is not iterable", so the wrong-password login journey
never asserted anything (red in CI on every retry). Playwright 1.56 treats any
array whose second element is an object as a `[value, options]` tuple
(`isFixtureTuple`), so the value became the first RegExp. Every spec that
asserts two error statuses had the same latent bug via `allowedFor(spec)`.
# What
An `allowing(patterns)` helper returns the explicit `[patterns, { scope }]`
tuple; both call sites use it. Re-verified: the journey passes against the
local stack.
# Why local-verify F-3 (pre-existing, caught by the new e2e suite): a signed-in visit to /onboarding threw "Rendered more hooks than during the previous render" (React #310) inside Next's app-router before landing on /docs/setup. The page only calls redirect(), but its loading.tsx wrapped it in a Suspense boundary, so the redirect streamed to the client and ran as a client-side hop — the same crash next.config.ts already documents for /settings. The /tutorials redirect stubs have no loading.tsx and never threw. # What Delete the skeleton (a loading state for a page that never renders) and say why beside the redirect. Re-verified on `next dev` (no page error) and in the production build: the "Onboarding forwards to Getting started" spec passes.
# Why local-verify F-4: the app-shell journey timed out on every run looking for Settings inside `Main navigation`. Settings sits in the sidebar footer, outside that landmark (Sidebar.tsx); the mobile tab bar's copy is display:none at desktop width, so an unscoped role query matches exactly one link.
…es the session # Why local-verify F-5: 1 run in 2 failed on four console 401s from /functions/v1/memories/* — /lore's data queries were still in flight when sign-out revoked the token under them. The redirect to /login is the behavior under test; waiting for network idle instead would hide the realistic case of a user signing out straight away. # What Allow `status of 401` on /functions/v1/ for this test only. 3/3 full runs green afterwards (58 passed each).
Local verify — ✅ verifiedThe suite now passes end to end on a local production build + local Supabase: 58/58 on three consecutive runs, signed-in tests included. Getting there took five fixes, one per commit: three test bugs that made CI's
Acceptance criteria
Edge cases
Not applicable (2)
Findings
Fixes
Screenshots — 0 (0 to upload)No screenshots: the final runs are green, and evidence for the fixed failures is in the CI logs and the commit bodies. Under the hoodTelemetry not reviewed: the local build runs with Open and escalated
Lessons
Generated by |
|
The dashboard preview for this PR — redeployed on each push that changes the web app.
Preview always points at this PR's latest commit; Deployment is the immutable build of |
✅ Preview deploy succeededBranch: 🔗 Open preview → https://lorekit-8ojpm24p0-mads-thines-projects.vercel.app
Endpoints: |
…ing apex # Why Review r4306443351 (@mthines / pr-reviewer): lorekit.io 308-redirects to www.lorekit.io, and the e2e page-health check only counts same-origin responses (fixtures.ts ORIGIN from E2E_BASE_URL), so on production it never saw a 5xx and a broken page could pass without a rollback. # What Default WEB_PROD_URL fallbacks (curl gate + three e2e steps) and the smoke docs to https://www.lorekit.io, and note that an override must be the non-redirecting origin. Addresses @mthines's comment: #700 (comment) Refs: #700
Restore the dashboard journey's docblock close, which f16dc99 folded onto the preceding line.
…-keyed CLI smokes on service-role (#701) * test(cli): skip owner-keyed smokes on a service-role token Preview's LOREKIT_SMOKE_TOKEN is service-role, and protect/pin/unpin/policy/groom refuse a credential with no owner — the same skip the hosted MCP smoke and purge already make. This failed smoke-preview on the #700 deploy run. * ci: run the staged-build e2e without a Vercel bypass secret Deployment Protection is off for the web project, so the staged URL is public. Drop the bypass-secret gate from e2e-web-staged (it ran unconditionally-skipped) and the bypass header plumbing from packages/web-e2e. Traces stay off for any production-target run.
Why
A merge should prove the core still works — every page of the website, every
lorekitcommand and every MCP tool — and adding a test should be trivial, in the same spec format/ui-verifyuses.What changed
packages/web-e2e— website tests are Markdown blocks inspecs/*.md, written in aw-tester'sWHEN/THENgrammar (the body of a ui-verify v1 PR block). A zero-dependency parser runs them in Playwright and refuses, by line number, what it cannot check deterministically (semantic:, intent specs).spec:import/spec:exportmove specs to and from ui-verify PR blocks and aw-tester's compiled routes.specs.test.tsfails a PR when a spec does not parse or apage.tsxhas no spec; every signed-in spec also gets a generated "signed-out visitor goes to/login" check.packages/cli/test/smoke— all 32 commands through the real binary: offline insidecli:test, and against preview at deploy time.cli-smoke.test.mjsfails a PR when a command, alias or MCP tool has no smoke.scripts/smoke/smoke-mcp-tools.mjs— covers the three tools nothing called (memory.protect,policy.update,groom.run).ci.yml,deploy.yml,preview.yml) — aweb-e2ePR job (local build + local Supabase, no secrets); Playwright on the staged production build before promotion and onwww.lorekit.ioafter (the apex redirects, which would hide same-origin 5xx); the CLI lane insmoke-previewand/preview. A failed test-account sign-in only warns, so it never blocks promotion or rolls back, and deploy-time runs record no Playwright traces (a trace keeps headers and cookies, and this repo's artifacts are public)./onboardingcrash fix — the new suite caught a signed-in visit throwing React chore: release main #310 before redirecting: itsloading.tsxstreamed the serverredirect()to the client (the crashnext.config.tsalready documents for/settings). The skeleton is deleted.docs/smoke-tests.mdandpackages/web-e2e/specs/README.md.How to verify
pnpm nx test web-e2e && node --test packages/cli/test/cli-smoke.test.mjs— the guards plus the offline CLI/MCP lane. The browser suite runs in theWeb — Playwright e2eCI job (58 tests; also green locally 3× against a local production build).Notes for reviewers
Optional repo secrets (each gate skips with a warning while unset):
VERCEL_AUTOMATION_BYPASS_SECRET,LOREKIT_TESTING_USER_NAME/LOREKIT_TESTING_USER_PW. The title istest:, so release notes will not list the/onboardingfix unless the squash title changes.