fix(e2e): two case assertions that could not pass however well the product worked - #2060
Merged
Merged
Conversation
…oduct worked
Both are test defects, and both were measured rather than reasoned about.
The Tags sidebar test clicked a Save button after confirming the field. The
widget has no such second step: CnObjectDataWidget's commitEdit stages the
value and awaits its own save(), and the header Save is v-if="isDirty"
:disabled="saving", so it exists only while the write is in flight and is
disabled for every millisecond of that. The CI trace of the failing run carries
one PUT of the case with {"tags":["spoed"]}, 200, response body carrying the
tag, sent fifteen seconds before the click that timed out. The write worked.
The click was for a step the widget does not have, and it is replaced by an
assertion that the widget is left with nothing staged, so a revert to a
two-step save reddens here instead of passing silently.
The timeline test asserted that the newest audit row says update. Opening the
page is itself an audited event: OpenRegister logs a read on every load, so by
the time the test can look, the newest row is the read its own navigation just
made, which is what CI reported. The reads stay in the tab. An inzage-log is
what a zaaksysteem owes the person the case is about, and the tab already
offers the Action filter for narrowing. What changes is the assertion: it now
reads the order of the writes within the list, so the create must sit below the
update. That is the same defect the original guarded, openregister#3540's
bottom-up ordering, and it still catches it: measured red with "the create sits
above the update" on a dev instance still running the pre-#3540 build, and
green once the rows arrive newest-first.
Contributor
Quality Report — ConductionNL/dossiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue3-compile | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ❌ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 106/106 | |||
| npm | ✅ | ✅ 549/549 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ❌ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ❌ |
Quality workflow — 2026-09-09 08:55 UTC
Download the full PDF report from the workflow artifacts.
Contributor
Quality Report — ConductionNL/dossiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue3-compile | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 106/106 | |||
| npm | ✅ | ✅ 549/549 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-09 09:25 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.
Two e2e assertions in the case suite could not pass however well the product worked. Both are test defects. Both were measured before they were changed, and both were watched failing and then passing.
The Tags sidebar Save button was never clickable
case-identity.spec.tspicked a tag, confirmed the field, and then clicked the widget's header Save. There is no second step to click.CnObjectDataWidget.commitEditstages the value and then awaits its ownsave(), so a click-to-edit confirm writes in one step. The header Save isv-if="isDirty" :disabled="saving", which means it exists only while the write is in flight and is disabled for every millisecond of that. Playwright resolved it, spent the whole budget on "element is not enabled", and then reported it detached, which reads exactly like a broken feature.The CI trace of the failing run settles it: one
PUT /apps/openregister/api/objects/dossiq/case/<id>with{"tags":["spoed"]}, status 200, response body carrying the tag, sent fifteen seconds before the click that timed out. The tag was saved. The test failed on a step the widget does not have.The click is replaced by an assertion rather than deleted: the widget must be left with nothing staged. A revert to a two-step save leaves a Save button standing there and reddens this, which is the signal a bare deletion would have thrown away.
Opening the timeline is itself an audited event
case-timeline.spec.tsasserted that the newest audit row saysupdate. OpenRegister logs areadon every page load, so by the time the test can look at the list the newest row is the read its own navigation just made. CI reported precisely that:Sep 9, 2026, 07:34 AM/admin/read.The reads stay in the tab. An inzage-log is what a zaaksysteem owes the person the case is about, and filtering them out at the source would delete the record that answers "who has seen my dossier". The tab already offers the Action filter for narrowing, and the third test in this file covers it.
So the assertion changes instead. It now reads the order of the writes within the list: the update this spec makes after the create has to sit above it. That is the same defect the original guarded, openregister#3540's bottom-up ordering, and the new form still catches it.
Watched failing, watched passing
panel.getByRole('button', { name: /^(Save|Opslaan)$/ }).click()element is not enabledthen detached, reproduced locallytoHaveCount(0)greenexpect(updateAt).toBeLessThan(createAt)The timeline assertion was mutation checked against the real defect rather than a simulated one. The dev instance this was measured on still runs an openregister that predates #3540 and ignores
_sort[created]=DESC, so it serves the trail oldest-first, and the new assertion reddens on it naming the inversion. Feeding the same page a newest-first payload turns it green. Restored from a byte copy afterwards and diffed.Not in this pull request
The third failure in this batch, the case-type folder button, is a library bound and not a dossiq one.
CnFolderSidebarinsource: "field"mode built its folders from the loaded page, so a category whose rows sit past row 20 has no folder at all. Measured on a 32-row instance: page one held zero categorised rows, so the pane rendered no folders while two categories existed in the set. ConductionNL/nextcloud-vue#1036 fixes it by reading the facet instead, and the platform already emits a completecategorybucket list under_facets=extend. It merged this morning and is not published yet, so dossiq clears that failure with a dependency bump once it is.