diff --git a/CHANGELOG/fix_e2e-realm-delete-flake.md b/CHANGELOG/fix_e2e-realm-delete-flake.md new file mode 100644 index 0000000..7b2d82b --- /dev/null +++ b/CHANGELOG/fix_e2e-realm-delete-flake.md @@ -0,0 +1,7 @@ +## Tests + +- The admin UI E2E test that deletes a realm now checks the realm cards instead of any text on the page, because the confirm modal and the success toast also show the realm name, so on a slow runner the page-wide match found several elements and failed at once with a strict-mode violation. + +## Docs + +- The admin UI E2E conventions now require scoped locators (card, row or cell) for assertions after a create, update or delete, and `admin-ui/CLAUDE.md` points agents to those conventions when they add E2E tests. diff --git a/admin-ui/CLAUDE.md b/admin-ui/CLAUDE.md index 1810947..7559fc2 100644 --- a/admin-ui/CLAUDE.md +++ b/admin-ui/CLAUDE.md @@ -47,7 +47,7 @@ tests/ 1. Write failing test (red) — include error/edge cases, not just happy path 2. Implement minimal code (green) 3. Refactor, re-run tests -4. Add E2E test after unit tests pass +4. Add E2E test after unit tests pass, following the conventions in `tests/e2e/README.md` ## Coding Rules diff --git a/admin-ui/tests/e2e/README.md b/admin-ui/tests/e2e/README.md index ecbd82d..97891d9 100644 --- a/admin-ui/tests/e2e/README.md +++ b/admin-ui/tests/e2e/README.md @@ -27,5 +27,9 @@ pnpm exec playwright test - Prefer role-based locators (`getByRole("cell" | "tab" | "button", ...)`). Use `exact: true` or an anchored regex when a substring would match multiple elements (e.g. a role name that is also a substring of its `role_id` cell). +- After a create, update or delete, assert on the element that holds the data (`.ant-card`, + `getByRole("cell" | "row")`), not a page-wide `getByText(name)`: the confirm modal and the + success toast repeat the name, and several matches fail at once with a strict-mode + violation. Assert absence with `toHaveCount(0)` on that scoped locator. - Token self-service endpoints authenticate via the `X-Vault-Token` header, not the admin cookie — assert the header is present in their mocks. diff --git a/admin-ui/tests/e2e/realms.spec.ts b/admin-ui/tests/e2e/realms.spec.ts index 6129d5d..e7fc175 100644 --- a/admin-ui/tests/e2e/realms.spec.ts +++ b/admin-ui/tests/e2e/realms.spec.ts @@ -203,7 +203,8 @@ test.describe("Realms page", () => { await page.getByRole("button", { name: "Delete" }).last().click(); // The realm must no longer appear in the cards. - await expect(page.getByText("my-service")).not.toBeVisible(); + // Scope to `.ant-card`: the confirm modal and the success toast also show the realm name. + await expect(page.locator(".ant-card").filter({ hasText: "my-service" })).toHaveCount(0); }); test("should create a SAML realm from pasted IdP metadata", async ({ page }) => {