test(e2e): per-tier × per-page + per-async-state live-UI matrix sweep - #199
Merged
Conversation
Closes the inventory's biggest remaining gap (docs/ci/00-INTERACTION-PATHS.md Part C: "no per-route × per-tier × per-async-state CI sweep"). Two new real-backend (minted cohort) live-UI specs, owned entirely under e2e/: live-ui-tier-matrix.spec.ts — per-tier × per-page sweep. Registry-iterates the tier ladder (TIER_RANK ∩ factory-mintable, rule 18) and, per tier, mints one cohort account and asserts the tier-correct gated/ungated UI across /app, /app/resources, /app/deployments, /app/vault, /app/settings, /app/billing: private-deploy configurator vs upsell, vault multi-env wall, deploy-TTL edit gate, Overview upgrade CTA, and the HARD "Team is never self-serve" rule (Team CTA = Contact sales). Per-tier expectation is COMPUTED in e2e/tier-matrix.ts from the app's soft-gate allowlists (back-referenced), so a new tier or a gate change auto-expands the matrix. live-ui-error-states.spec.ts — per-async-state sweep. 401 revoked-session → /login?session_expired=1 (REAL, disposable account logout/revoke); 402 at-limit upgrade wall (REAL, sub-Pro pause); 429 retry-hint + 5xx error banner (MOCKED route-stub — labeled, since a real prod 429/5xx isn't safely reachable); empty states (REAL fresh account → no infinite spinner). @pr-smoke subset (one sub-Pro gated-CTA assertion + the 401-redirect) rides the existing e2e-pr-smoke.yml (--grep @pr-smoke); full matrix on the schedule. Both specs registered in e2e/live-ui.coverage.ts so the prod-coverage done-bar guard tracks them. Finding F1 (filed for the src/-owning bug-hunt team): on a 429/5xx the DeploymentsPage renders the "No deployments yet" empty row ALONGSIDE the error banner (empty-state gates on items.length===0, not !err). The error banner is the dominant signal so the anti-silent-collapse guarantee holds; the simultaneous empty copy is mildly contradictory UX. Verified: npm run gate green (81 files, 1144 passed); both specs run green against real prod (10/10 — free/hobby/hobby_plus/pro × 6 pages + 5 error legs), ledger empty (no leaks), reap 200. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mastermanas805
enabled auto-merge (squash)
June 6, 2026 07:27
size-limit report 📦
|
mastermanas805
added a commit
that referenced
this pull request
Jun 6, 2026
On a 429/5xx the DeploymentsPage catch handler sets items=[] (honest — nothing loaded), so the "No deployments yet" create-CTA (deployments-empty) rendered at the same time as the deployments-error banner: contradictory UX that tells the user both "nothing here, create one" and "something went wrong". Gate the empty-state on `!err` so the error banner is the sole dominant signal during a load error. The genuine zero-deployments empty state (no error) is unchanged and still shows the create CTA. Found by the per-tier error-state matrix sweep (PR #199). Tests (DeploymentsPage.test.tsx): - error → error banner shown AND empty-state NOT shown (fails before fix) - 429 → retry-hint banner, no empty row (fails before fix) - genuine empty (no error, zero items) → create CTA still shown - happy-path empty has no error banner Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Closes the inventory's biggest remaining CI gap —
docs/ci/00-INTERACTION-PATHS.mdPart C: "no per-route × per-tier × per-async-state CI sweep". Two new real-backend (minted cohort) live-UI Playwright specs, entirely undere2e/.e2e/live-ui-tier-matrix.spec.ts— per-tier × per-page sweepRegistry-iterates the tier ladder (
TIER_RANK∩ factory-mintable tiers — rule 18; a new tier auto-expands the matrix) and, per tier, mints one cohort account and asserts the tier-correct gated/ungated UI across 6 pages:/app,/app/resources,/app/deployments,/app/vault,/app/settings,/app/billing./app/deployments)PRIVATE_DEPLOY_TIERS/app/vault)VAULT_MULTI_ENV_TIERS/app/settings)isPaidTier/app)showProUpgrade/app/billing)Per-tier expectation is computed in
e2e/tier-matrix.tsfrom the app's soft-gate allowlists (each back-referenced to its source page), so a soft-gate change is a one-line edit in lockstep.e2e/live-ui-error-states.spec.ts— per-async-state sweep/login?session_expired=1(REAL — disposable minted account, logout/revoke; never touches the shared JWT) —@pr-smokeWiring
@pr-smokesubset (one sub-Pro gated-CTA assertion + the 401-redirect) rides the existinge2e-pr-smoke.yml(--grep @pr-smoke); full matrix stays on the schedule. No workflow edit needed.e2e/live-ui.coverage.tsso the prod-coverage done-bar guard tracks them.Finding F1 (for the
src/-owning bug-hunt team)On a 429/5xx the
DeploymentsPagerenders the "No deployments yet" empty row alongside the error banner (empty-state gates onitems.length===0, not!err). The error banner (role=alert, top) is the dominant signal so the anti-silent-collapse guarantee holds; the simultaneous empty copy is mildly contradictory UX. Filed, not fixed (fix is insrc/, out of this round's e2e-only scope).Verification
npm run gateGREEN (tsc + build + prerender + vitest — 81 files, 1144 passed, 3 skipped). New specs arelive-*.spec.ts→ excluded from the mocked PR suite and vitest, picked up only byplaywright.live.config.ts.@pr-smokesubset: exactly the 2 intended tests, green against prod.Cross-ref:
docs/ci/00-INTERACTION-PATHS.mdPart C.🤖 Generated with Claude Code