Skip to content

fix(e2e): seed the Goals and ProcessTemplate the specs assert on - #1052

Merged
rubenvdlinde merged 2 commits into
developmentfrom
fix/e2e-seed-the-five-goals
Aug 31, 2026
Merged

fix(e2e): seed the Goals and ProcessTemplate the specs assert on#1052
rubenvdlinde merged 2 commits into
developmentfrom
fix/e2e-seed-the-five-goals

Conversation

@rubenvdlinde

@rubenvdlinde rubenvdlinde commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Two of decidiq's four E2E failures share one root cause: objects the specs assert on live in the profile files, and CI runs with example_profile=none.

1. goals-pages.spec.ts — five Goals

Failed on getByText('Duurzame omzetgroei 2028')element(s) not found.

The spec's docblock points at lib/Settings/register.d/66-organisation-goals.json, but that file declares only the Goal schema. The five objects live in three different profiles:

profile goals
corporate.json Duurzame omzetgroei 2028, Operationele effectiviteit 2026
municipality.json Amsterdam klimaatneutraal, Herzien parkeerbeleid vastgesteld
association.json Digitale dienstverlening leden

So no single example_profile yields all five. The spec was written against the older behaviour where installing planted everything — the behaviour #1024 is replacing.

  • No SEED_TAG prefix: the titles are the assertion ({ exact: true }), so prefixing them the way sibling objects are prefixed would break the test this exists to fix.
  • body repointed at this run's governance body. The profiles reference bodies by slug (gemeenteraad-amsterdam, ledenraad-vng, raad-van-bestuur-acme-bv), none of which exist here; a dangling reference would seed an object the index cannot resolve. owner dropped likewise — femke-halsema is not a user on this instance and the field is not required.

2. process-configuration.spec.ts — one built-in ProcessTemplate

Failed at expect(list).toBeVisible() with Received: hidden — not because the list is missing but because it is empty. ProcessTemplates.vue renders <ul v-if="!store.loading"> regardless of row count, and an empty <ul> is a zero-height box. ProcessTemplateService::list() already carries a comment describing exactly this shape from the last time it returned zero rows.

Built-in templates are likewise not shipped with the schema — association/corporate/municipality declare three each.

One is seeded, deliberately. The spec asserts the list renders, then takes the first item carrying process-template-builtin. Seeding all nine would push a full catalogue into every other list reading this schema, which is what none exists to avoid. Municipal Council matches the rest of the fixture (the seeded body is a Gemeenteraad) and is copied verbatim from municipality.json — verified structurally identical minus @self and slug, which are import metadata and server-assigned respectively.

Verifier

'goal': 5 and 'process-template': 1 added to the readability check, for the reason that block exists: a create that answers 2xx but is not listable would resurface as "element(s) not found" or "hidden" — reading as a missing feature or a CSS problem rather than a seed that did not land.

Scope

The other two failures are not seeding gaps and are handled separately:

Verification

bash -n parses; both embedded Python heredocs compile; all five goal payloads validate against the schema's enums (horizon: multi-year/annual/quarterly, status: active/at-risk/draft) and its six required fields; the template payload parses and carries all three required fields (name, initialState, stateMachine) with 7 states and 6 transitions.

`Goals: index lists all five seeded goals` failed on
getByText('Duurzame omzetgroei 2028') -> element(s) not found. The five goals
it names were never created on CI.

The spec's docblock points at lib/Settings/register.d/66-organisation-goals.json,
but that file declares only the Goal SCHEMA. The five objects live in three
different profile files -- association.json (1), corporate.json (2),
municipality.json (2) -- so no single `example_profile` yields all five, and the
seed deliberately picks `none` to keep a whole demo dataset out of the lists
other specs assert on. The spec was written against the older behaviour where
installing planted everything.

Measured on development 67e0f6c: E2E 4 failed / 139 passed, this among them.

Seeded in the governance fixture, beside the objects the other specs need:

- No SEED_TAG prefix. The titles ARE the assertion and are matched with
  { exact: true }, so prefixing them the way the sibling objects are prefixed
  would break the test this exists to fix.
- Titles, descriptions, horizons, deadlines and statuses copied verbatim from
  the profiles, so the fixture and the shipped example sets cannot drift into
  disagreeing about what a Goal looks like.
- `body` repointed at this run's governance body. The profiles reference their
  own bodies by slug (gemeenteraad-amsterdam, ledenraad-vng,
  raad-van-bestuur-acme-bv), none of which exist here; a dangling reference
  would seed an object the index cannot resolve. `owner` is dropped for the
  same reason -- femke-halsema is not a user on this instance, and the field is
  not required.
- 'goal': 5 added to the readability verifier, for the reason that block
  exists: a create that answered 2xx but is not listable would leave the spec
  failing on "element(s) not found", which reads as a missing feature rather
  than a seed that did not land.

This fixes ONE of decidiq's four E2E failures. The other three are not seeding
gaps and are left alone deliberately -- see the PR body.
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/decidiq @ f744956

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-nav-ceiling
test-l10n
format
check-l10n-js
check-schema-l10n
composer ✅ 104/104
npm ✅ 537/537
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright 🚨 NO VERDICT — enabled but never ran
Hydra gates

Quality workflow — 2026-08-31 08:33 UTC

Download the full PDF report from the workflow artifacts.

`Template list shows built-in templates as read-only` failed at

    expect(page.locator('[data-testid="process-template-list"]')).toBeVisible()
    Received: hidden

not because the list is missing but because it is EMPTY. ProcessTemplates.vue
renders `<ul v-if="!store.loading">` regardless of row count, and an empty <ul>
is a zero-height box, which Playwright reports as hidden.
ProcessTemplateService::list() already carries a comment describing exactly
this shape from the last time it returned zero rows.

Same root cause as the Goals in the previous commit: the built-in templates are
not shipped with the schema, they live in the profile files (association.json,
corporate.json and municipality.json declare three each), so
`example_profile=none` leaves the catalogue empty.

ONE is seeded, deliberately. The spec asserts the list renders, then takes the
FIRST item carrying `process-template-builtin` and checks it is read-only.
Seeding all nine would push a full catalogue into every other list that reads
this schema, which is what the `none` profile exists to avoid.

`Municipal Council` is the template that matches the rest of this fixture — the
governance body seeded above is a Gemeenteraad. It is copied verbatim from
municipality.json (states, transitions, guards, voting rule and quorum rule
included), verified structurally identical minus `@self` and `slug`: `@self` is
import metadata the object API sets itself, and the slug is assigned
server-side.

'process-template': 1 added to the readability verifier for the same reason as
'goal': 5 — an unlistable create would resurface as "hidden", which reads as a
CSS or mount problem rather than a seed that did not land.
@rubenvdlinde
rubenvdlinde merged commit aec6caa into development Aug 31, 2026
34 checks passed
@rubenvdlinde rubenvdlinde changed the title fix(e2e): seed the five Goals goals-pages.spec.ts asserts on fix(e2e): seed the Goals and ProcessTemplate the specs assert on Aug 31, 2026
rubenvdlinde added a commit that referenced this pull request Aug 31, 2026
…#1053)

`v2 grid renders the KPI row, list widgets and governance-health chart` failed
with:

  Error: strict mode violation: getByText('Minutes awaiting approval')
  resolved to 2 elements
    1) <h3 class="cn-widget-wrapper__title" id="cn-widget-wrapper-title-minutes-in-review">
    2) <h4 class="cn-kpi-card__title" title="Minutes awaiting approval">

The phrase is rendered twice on this dashboard: once as the widget's own
heading and once as a KPI card title -- src/manifest.json declares the
stats-block with "id": "minutes-in-review", "title": "Minutes awaiting
approval", and repeats that title inside content.entries.

So the assertion failed on a dashboard that is entirely correct, and it fails
louder the more complete the row gets, which is the wrong direction for a
layout test.

CnWidgetWrapper renders its heading as `<h3 :id="titleId">` with
`titleId = cn-widget-wrapper-title-${widgetId}` and `resolvedWidgetId()`
returning the supplied widgetId, so `#cn-widget-wrapper-title-minutes-in-review`
addresses exactly the stats-block this line is about -- the same id the
manifest declares and the same element the CI log named -- and stays correct
if another surface shows the same phrase.

Every other assertion in this test already locates its widget by a stable
attribute rather than by text; this line was the exception.

One of decidiq's four E2E failures. Not related to the seeding gap in #1052.

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/decidiq @ 63a71df

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-nav-ceiling
test-l10n
format
check-l10n-js
check-schema-l10n
composer ✅ 104/104
npm ✅ 537/537
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright 🚨 NO VERDICT — enabled but never ran
Hydra gates

Quality workflow — 2026-08-31 08:46 UTC

Download the full PDF report from the workflow artifacts.

rubenvdlinde added a commit that referenced this pull request Aug 31, 2026
…its (#1054)

`quick-filter dropdown label "All urgent" renders intact at every tested
viewport` failed as a bare:

    Test timeout of 20000ms exceeded.

The test could not pass reliably no matter how healthy the app was.
playwright.config.ts sets `timeout: 20_000` per test. This one loops THREE
viewports, and each iteration navigates and then allows
`waitForSelector(15_000)` plus `expect(select).toBeVisible({ 10_000 })` -- 25s
of permitted waiting in the FIRST iteration alone, against a 20s total budget.

The symptom is misleading in a specific way: a whole-test timeout names no
element, so it reads like a slow or broken dropdown rather than a budget that
was never large enough for the work the test does.

90s matches the sibling multi-step specs (voting-rules.spec.ts uses 90_000;
goals-pages.spec.ts uses 120_000) and the per-step waits are left untouched, so
a genuinely stuck dropdown still fails on its OWN 10s assertion with a message
naming the element.

The fourth and last of decidiq's E2E failures. The other three: two seeding
gaps in #1052, one strict-mode locator violation in #1053.

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
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.

1 participant