Skip to content

test(e2e): three behavioural tests for the Features & Roadmap surface (gate-19 850 → 847) - #2422

Merged
rubenvdlinde merged 1 commit into
developmentfrom
test/e2e-features-roadmap-behaviour
Aug 11, 2026
Merged

test(e2e): three behavioural tests for the Features & Roadmap surface (gate-19 850 → 847)#2422
rubenvdlinde merged 1 commit into
developmentfrom
test/e2e-features-roadmap-behaviour

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

What

Three behavioural e2e tests for the Features & Roadmap surface, plus the one-line allow-list entry that makes CI run them.

gate-19, full tree, canonical checker ConductionNL/.github@3c8da4c:

covered uncovered
development (fdb0d6ca8) 10 850
this branch 13 847

Zero new @e2e excludes.

Why these three, and why a new file

spec-coverage/feature-pages.spec.ts asserts that each page renders. These assert that it decides:

  • an empty features manifest renders No features documented yet;
  • the suggest-feature form stays unsubmittable until every required field is set;
  • features_roadmap_enabled defaults to true, and the guard that enforces it can still refuse.

Every test carries its own control

Each of those requirements is otherwise satisfied for free by a page that failed to mount — a disabled button is disabled when it does not exist, and an empty state is empty when nothing rendered. So each test pairs its requirement with a state the same locator must distinguish:

test requirement control (same locator)
empty manifest .cn-features-tab shows No features documented yet toggle to roadmap → same <main> swaps to .cn-roadmap-tab + No roadmap items yet, then back
submit gate Continue on <forge> disabled while invalid four-state gradient ending in enabled; Cancel enabled throughout
default flag key absent → guard answers not-403 key set false403 feature_disabled, then removed

Proven able to fail

Each requirement assertion was inverted, run, observed red naming the real observed value, and restored byte-identical (md5 963de99d… before and after):

Expected: "MUTANT-1 no features documented yet"   Received: "No features documented yet"
Expected: enabled                                 Received: disabled
Expected: 200                                     Received: 403

Negative controls (the real evidence — see scope note)

shipped                                    covered=13  uncovered=847
remove this PR's spec file                 covered=10  uncovered=850   (-3, exactly its 3 anchors)
restore                                    covered=13  uncovered=847

remove openspec/specs/features-roadmap-menu/spec.md (45 counted scenarios, 0 excluded)
                                           covered=9   uncovered=806   (-4 and -41 = -45, exact)
restore                                    covered=13  uncovered=847

⚠️ Scope. This PR changes no spec file, so gate-19's diff scope on this PR is empty and its cell will go green having inspected nothing. That green is not evidence for the numbers above. Both figures are --full on the canonical checker; the negative controls are the evidence.

Admission criteria

Checked against all four criteria in tests/e2e/ci/playwright.config.ts: hermetic (the outbound GitHub call is stubbed with page.route(), so no external network dependency is added), self-cleaning (the only mutation is the app-config key, removed in a finally), no conditional-assert guards, no test.skip().

Full CI subset on a dedicated NC 34 rig: 44 passed, 0 failed (41 before + 3).

Deliberately not anchored

#pat-not-configured-roadmap is exercised in substance but not anchored: the shipped CnRoadmapTab renders Roadmap not yet configured, while the spec's THEN clause names Roadmap currently unavailable. Crediting it would report a stated outcome as verified when it was not. Filed separately, along with the finding that the features_roadmap_enabled UI gate is unimplemented.

🤖 Generated with Claude Code

Adds tests/e2e/spec-coverage/features-roadmap-surface.spec.ts and admits it
to the CI allow-list. gate-19 (full tree, canonical checker 3c8da4c):
uncovered 850 -> 847, covered 10 -> 13. Zero new excludes.

Unlike the existing feature-pages.spec.ts, which asserts that a page
RENDERS, these assert that it DECIDES:

  * an empty features manifest renders "No features documented yet", with
    the panel toggle (features <-> roadmap, both empty states asserted) as
    proof the panel is live rather than a page that failed to mount;
  * the suggest-feature form stays unsubmittable across a four-state
    gradient and flips to enabled only when every required field including
    the priority select is set, and issues no POST while invalid;
  * features_roadmap_enabled defaults to true, with the app-config key
    flipped to false and back as the control that GitHubGuards can still
    refuse (403 feature_disabled).

Each test carries its own control, because each requirement is otherwise
satisfied for free by a broken page: a disabled button is disabled when it
does not exist, and an empty state is empty when nothing rendered.

Every assertion was proven able to fail: each requirement assertion was
inverted, observed red naming the real value ("No features documented yet",
"disabled", 403), and restored byte-identical.

The outbound GitHub call is stubbed with page.route(), so admitting this
file adds no external network dependency to CI. The only mutation is the
app-config key, removed in a finally.
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/openregister @ 5285fb7

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-specs
test-l10n
composer ✅ 173/173
npm ✅ 546/546
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-11 17:31 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde
rubenvdlinde merged commit 9628dc5 into development Aug 11, 2026
23 of 29 checks passed
@rubenvdlinde
rubenvdlinde deleted the test/e2e-features-roadmap-behaviour branch August 11, 2026 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants