bug-mentions-e2e-toast-getbytext-superstring-flake work-item-mentions.spec.ts:170 strict-mode violation — non-exact getByText('<KEY> saved') matches BOTH the toast title AND Radix Toast's sr-only "Notification <KEY> saved" announcement
Symptom
tests/e2e/work-item-mentions.spec.ts:96 (5.8.8, subtask MOTIR-1407) flakes on the Playwright E2E bulk-5 shard. The failing assertion is line 170:
await expect(page.getByText(`${source.identifier} saved`)).toBeVisible();
Playwright error:
Error: expect(locator).toBeVisible() failed
Error: strict mode violation: getByText('WIM-4 saved') resolved to 2 elements:
1) <div class="...">WIM-4 saved</div> (the toast title)
2) <span role="status" aria-live="assertive">Notification WIM-4 saved</span> (Radix Toast's sr-only announcement)
Root cause (a pre-existing latent flake, NOT a regression)
The toast primitive is Radix Toast (@radix-ui/react-toast, components/ui/Toast.tsx). Radix's Toast.Provider renders a hidden screen-reader announcement region for each toast, role="status" aria-live="assertive", whose text is the Provider's label (default "Notification") + the toast title → Notification WIM-4 saved. So a non-exact getByText('WIM-4 saved') matches BOTH the visible Toast.Title and Radix's announcement span. Radix mounts/clears the announcement on a short timer, so whether both are present when the locator resolves is a RACE → intermittent strict-mode violation (it failed the initial run AND Playwright's retry #1 in this instance, but passes on other runs).
This is the new-superstring-label-breaks-playwright-getbyrole class (a new/other accessible name CONTAINING an existing one breaks a non-exact locator). It has been latent since the mentions E2E shipped; it is unrelated to any current diff.
Fix (in the spec — the app is correct)
Make the toast assertion exact / scoped so it can't match the announcement region:
// exact match — excludes "Notification WIM-4 saved"
await expect(page.getByText(`${source.identifier} saved`, { exact: true })).toBeVisible();
// or scope to the toast title role:
// await expect(page.getByRole('status').getByText(`${source.identifier} saved`)).toBeVisible();
Grep the E2E suite for other non-exact getByText('… saved') / toast-title assertions and harden them the same way (any toast-title read is exposed to Radix's "Notification …" announcement).
Discovery
Surfaced by the CI of PR #1473 (MOTIR-851, an unrelated backend internal-API subtask). Confirmed unrelated: PR branch == origin/main (no new main commits) and the diff touches only app/api/internal/ai/* + workItemsService/workItemRepository read methods — zero path to the toast/mentions UI. Per CLAUDE.md's pre-existing-bug rule, logged rather than absorbed into that PR.