Skip to content

moooon

Motir

Vibe your whole project. Bring an idea — Motir's three AI layers plan it, track it, and ship it, end to end. You're looking at Motir, built in Motir.

  • Vibe Project
  • Open Source
  • AI Agent
  • AI Loop
1
requests
0
upvotes
145
planned
1,361
shipped

Motir · Work items

MOTIR-1512Done

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.