test(e2e): three behavioural tests for the Features & Roadmap surface (gate-19 850 → 847) - #2422
Merged
Merged
Conversation
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.
This was referenced Aug 11, 2026
Contributor
Quality Report — ConductionNL/openregister @
|
| 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.
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
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 checkerConductionNL/.github@3c8da4c:development(fdb0d6ca8)Zero new
@e2e excludes.Why these three, and why a new file
spec-coverage/feature-pages.spec.tsasserts that each page renders. These assert that it decides:No features documented yet;features_roadmap_enableddefaults totrue, 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:
.cn-features-tabshowsNo features documented yet<main>swaps to.cn-roadmap-tab+No roadmap items yet, then backContinue on <forge>disabled while invalidCancelenabled throughoutfalse→ 403feature_disabled, then removedProven 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):Negative controls (the real evidence — see scope note)
--fullon 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 withpage.route(), so no external network dependency is added), self-cleaning (the only mutation is the app-config key, removed in afinally), no conditional-assert guards, notest.skip().Full CI subset on a dedicated NC 34 rig: 44 passed, 0 failed (41 before + 3).
Deliberately not anchored
#pat-not-configured-roadmapis exercised in substance but not anchored: the shippedCnRoadmapTabrendersRoadmap not yet configured, while the spec's THEN clause namesRoadmap currently unavailable. Crediting it would report a stated outcome as verified when it was not. Filed separately, along with the finding that thefeatures_roadmap_enabledUI gate is unimplemented.🤖 Generated with Claude Code