## TL;DR

Cypress needs `includeShadowDom: true` to pierce shadow roots. Set it globally or per-command, then use normal `cy.get()` selectors across the boundary.

## Error

```text
CypressError: Timed out retrying after 4000ms: Expected to find element: `my-button`, but never found it.
(The button is inside an open shadow root.)
```

## Steps

1. Confirm the shadow root is open in devtools. Expected: `#shadow-root (open)`.
2. Set `includeShadowDom: true` in `cypress.config.js` or per test config. Expected: piercing enabled.
3. Use normal selectors: `cy.get('my-card').find('button')`. Expected: crosses the boundary.
4. For closed roots, this does not work; request test hooks from the component team. Expected: the hard limit acknowledged.
5. Re-run. Expected: green.

## When to use

- Web components under test in Cypress.
- Open shadow roots.

## When not to use

- Closed shadow roots (not pierceable).
- Playwright (automatic).

## Tool compatibility

- Cypress 10 through 14; `includeShadowDom` option.

## Variant phrasings

### Cypress shadow DOM support

The general topic; the flag is the answer.

### Cypress cannot find element in web component

Usually the flag; check open vs closed.

## Why it happens

Cypress's selector engine respects shadow boundaries by default. The flag opts into piercing.

## Edge cases

- The flag affects all queries; watch for newly ambiguous matches.
- Nested shadow roots pierce recursively with the flag on.
- Third-party closed components remain untestable; escalate.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_dmM9jPj-AEeWiFWmN_Ul6w
