Trap room
Every control here is broken on purpose. This is the one page in the app where bad markup and hostile behaviour are the point. Nothing on this page should ever be “fixed”.
1. Looks clickable, is not
The first is a bare <div> with no role, no tabindex and no
handler. It is styled identically to a button. getByRole('button') will not match
it; a CSS class selector will, and the click will silently do nothing.
Nothing approved.
2. Toast that disappears
The 1-second toast is gone before a slow assertion arrives. Auto-retrying
expect with a short timeout catches it; textContent() after an
await usually does not.
3. Disabled until valid
Validation runs on input, so fill() enables it but
setting value through evaluate does not.
4. Responds to tap, not to click
Bound to touchstart only. A mouse click() does nothing.
Needs page.tap() with hasTouch: true in the context.
Not confirmed.
5. Covered by an invisible overlay
A transparent pseudo-element sits on top. Playwright's actionability check
reports that another element intercepts the pointer event, and the click times out.
force: true does not help: it skips the checks but still clicks
at those coordinates, where the overlay is still the hit target. Only
dispatchEvent('click') reaches the handler. That is the lesson —
force is not a universal unblocker.
Not released.
6. pointer-events: none
Enabled, visible, in the accessibility tree, and unclickable. Even
force: true will not fire its handler; only dispatchEvent will.
No label printed.
7. Moving target
Not accepted.
8. List that re-renders under you
The whole <ul> is replaced every 1200ms, so any handle you hold
goes stale. Locators re-resolve and survive; elementHandle does not.
9. Duplicated test id
Three different controls share data-testid="save". A bare
getByTestId('save') resolves to three elements and throws in strict mode.
Nothing saved.
10. Text split across elements
Total due: ₹12,890
The amount is split across four sibling <span> elements, so no
leaf element contains ₹12,890. A span-scoped locator such as
locator('[data-testid="split-text"] span', { hasText: '₹12,890' }) resolves to
nothing. Playwright's getByText walks up and matches the containing paragraph
(and its ancestors), so it resolves to more than one element and is not strict-mode safe on
its own.
Status: Awaiting pickup
The line above has collapsed whitespace in the DOM but not in the source.
Playwright's text matching normalises whitespace; a raw textContent comparison
does not.
11. Revealed only on hover
The button is hidden until the container is hovered.
Not cancelled.
12. Input that refuses fill()
fill() throws on a readonly input. focus() then
pressSequentially() works, because focus removes the attribute.
No code entered.
13. Far below the fold
1200px of filler, then the control. Playwright auto-scrolls; a raw
document.querySelector().click() in a manual script would not.
Month open.
14. Attaches late
waitForTimeout(500).