test(ui): require accessible company save errors
This commit is contained in:
@@ -8,6 +8,7 @@ Every completed logical unit is pushed to `codex/ui-redesign-phase4`, without fo
|
||||
| Historical system/workflow audit at execution entry | `9d6d29dba4733778e478909d4ff74a25409b3115` | Fresh fetch: development HEAD=origin; seven modified files preserved |
|
||||
| Current P6-00 baseline and design audit | `7da083c374abcb6b34600f3c6667830d47b14760` | Whitespace/source/document review; pushed normally; HEAD=origin immediately after push, main unchanged |
|
||||
| P6-01 shared semantic/contrast/panel corrections | `a94ea0a4a4695d1c196366ac39793a901485e919` | Final521 units/85 suites, type/lint/build and4 native Settings cases green; normal push, HEAD=origin |
|
||||
| P6-02 cross-application save/retry and localisation corrections | `c135d03602fd273658cfa1c087491c7442060c6a` | Company/language native4/4 with persistence after retry/reload; final521 units; normal push, HEAD=origin |
|
||||
|
||||
## Current execution evidence
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# P6-02 — Cross-application UX and workflow review
|
||||
|
||||
## Companion regression correction
|
||||
|
||||
The first fresh full browser attempt recorded153 passes and four failures in `named-controls-modal-state.spec.ts`: its historical P4-02-D02 assertion deliberately required the company error to be hidden from the dialog. P6's verified error repair makes that expectation obsolete. The test now scopes the alert to the active company dialog and requires no aria-hidden ancestor, while preserving draft, no-write, keyboard/focus and subsequent CV/document assertions. The focused four theme/locale/width cases pass with no skips/retries; [exact evidence](../p6-05/evidence/modal-results.json). Final full regression is recorded separately in P6-05. This strengthens the intended current contract rather than weakening the assertion or masking a failure.
|
||||
|
||||
Fresh bounded repair result: **4/4 native EN/Bokmål company and language error/retry/persistence/reload workflows pass**, retries0, skips0; [portable feedback proof](../p6-05/evidence/feedback-results.json). The final complete521-unit run also passes. The first native company cases exposed generic English Axios500 text; the shared API helper now uses translated caller fallbacks for transport failures, while server validation and explicit cancellation/session explanations remain. Five actual-helper cases pass after2 localized RED cases. Company list/card dates and pending company-filter labels also reuse the established locale/translation owners. Full integrated native evidence follows in P6-05.
|
||||
|
||||
## Scope and baseline
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"command": {
|
||||
"name": "modal",
|
||||
"command": [
|
||||
"rtk",
|
||||
"proxy",
|
||||
"node",
|
||||
"node_modules/@playwright/test/cli.js",
|
||||
"test",
|
||||
"e2e/named-controls-modal-state.spec.ts",
|
||||
"--retries=0",
|
||||
"--reporter=list,json",
|
||||
"--output=E:\\Storage\\Projects\\Active\\Job tracker\\.artifacts\\phase6\\current\\ui\\modal-results"
|
||||
],
|
||||
"startedUtc": "2026-10-11T08:29:22.055451+00:00",
|
||||
"finishedUtc": "2026-10-11T08:30:11.562991+00:00",
|
||||
"exitCode": 0,
|
||||
"stats": {
|
||||
"startTime": "2026-10-11T08:29:22.590Z",
|
||||
"duration": 48931.805,
|
||||
"expected": 4,
|
||||
"skipped": 0,
|
||||
"unexpected": 0,
|
||||
"flaky": 0
|
||||
}
|
||||
},
|
||||
"reportSha256": "9fd4d78d4cf5e0b53385115b82e354f8361c1a0917c1a9d694dea281250ad9c5",
|
||||
"logSha256": "d99d15e42c69da4e13796418b2ac7cc7c332ac334b13d273c640a960167ec6ff",
|
||||
"stats": {
|
||||
"startTime": "2026-10-11T08:29:22.590Z",
|
||||
"duration": 48931.805,
|
||||
"expected": 4,
|
||||
"skipped": 0,
|
||||
"unexpected": 0,
|
||||
"flaky": 0
|
||||
},
|
||||
"cases": [
|
||||
{
|
||||
"title": "[PRES-E07 PRES-E08 PRES-J08 PRES-C08 PRES-C09 PRES-W06 PRES-W08] light/en/1440 named controls, modal keyboard and retained draft",
|
||||
"expectedStatus": "passed",
|
||||
"status": "expected",
|
||||
"results": [
|
||||
{
|
||||
"status": "passed",
|
||||
"retry": 0,
|
||||
"durationMs": 11675
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "[PRES-E07 PRES-E08 PRES-J08 PRES-C08 PRES-C09 PRES-W06 PRES-W08] dark/nb/1440 named controls, modal keyboard and retained draft",
|
||||
"expectedStatus": "passed",
|
||||
"status": "expected",
|
||||
"results": [
|
||||
{
|
||||
"status": "passed",
|
||||
"retry": 0,
|
||||
"durationMs": 10471
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "[PRES-E07 PRES-E08 PRES-J08 PRES-C08 PRES-C09 PRES-W06 PRES-W08] light/nb/390 named controls, modal keyboard and retained draft",
|
||||
"expectedStatus": "passed",
|
||||
"status": "expected",
|
||||
"results": [
|
||||
{
|
||||
"status": "passed",
|
||||
"retry": 0,
|
||||
"durationMs": 9975
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "[PRES-E07 PRES-E08 PRES-J08 PRES-C08 PRES-C09 PRES-W06 PRES-W08] dark/en/390 named controls, modal keyboard and retained draft",
|
||||
"expectedStatus": "passed",
|
||||
"status": "expected",
|
||||
"results": [
|
||||
{
|
||||
"status": "passed",
|
||||
"retry": 0,
|
||||
"durationMs": 9608
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -93,13 +93,11 @@ for (const [mode, language, width] of [["light", "en", 1440], ["dark", "nb", 144
|
||||
await companyDialog.getByRole("textbox", { name: t.companiesRecruiterName, exact: true }).fill("Retained æøå draft");
|
||||
await page.route(`${apiUrl}/companies/${owner.companyId}`, route => route.request().method() === "PUT" ? route.fulfill({ status: 503, contentType: "application/json", body: JSON.stringify({ message: "Synthetic save failure" }) }) : route.continue());
|
||||
await companyDialog.getByRole("button", { name: t.save, exact: true }).click();
|
||||
// Existing P4-02-D02: this caller reports save errors in the shared toast,
|
||||
// outside the modal's accessible subtree. Preserve the draft proof while
|
||||
// recording the hidden-alert defect instead of claiming an AT error pass.
|
||||
const saveError = page.getByRole("alert", { includeHidden: true }).filter({ hasText: "Synthetic save failure" });
|
||||
// P6 closes P4-02-D02: the retained draft's error belongs to the dialog.
|
||||
const saveError = companyDialog.getByRole("alert");
|
||||
await expect(saveError).toContainText("Synthetic save failure");
|
||||
await expect(saveError).toBeVisible();
|
||||
expect(await saveError.evaluate(node => !!node.closest('[aria-hidden="true"]'))).toBe(true);
|
||||
expect(await saveError.evaluate(node => !!node.closest('[aria-hidden="true"]'))).toBe(false);
|
||||
await expect(companyDialog.getByRole("textbox", { name: t.companiesRecruiterName, exact: true })).toHaveValue("Retained æøå draft");
|
||||
expect(await statusNode!.getAttribute("data-test-announcements")).toBeNull();
|
||||
await capture(page, info, `retained-draft-${suffix}`);
|
||||
|
||||
Reference in New Issue
Block a user