Expose a stable open-state anchor (role/data-*) on HoverCard & Tooltip layers for testability
- Dominant language
- TypeScript
- Stars
- 13k
- Forks
- 1.1k
- Avg merge
- 1d 15h
- Merged PRs (30d)
- 690
Description
## Summary
`HoverCard` and `Tooltip` render their floating layer as a body-level element with `popover="manual"`/`"auto"` and **no `role`, no `data-testid`, and no open-state attribute**. The only programmatic link from the trigger to the layer is the injected `aria-describedby` → layer `id`. This makes the open/closed state and the layer itself hard to anchor for UI test tooling that resolves elements via stable selectors (roles, `data-*`, accessible names) rather than build-time-hashed StyleX classes.
## Current DOM (observed, v0.1.1)
```html
Hover me
```
- `Tooltip` is identical except the layer class is `astryx-tooltip` and its content is a bare text `
- The layer carries **no `role`** (not `tooltip`, not `dialog`) and **no attribute reflecting open/closed**.
## Why it matters
- Open/closed cannot be distinguished from attributes — only via the native Popover API's visibility, which environments without a layout/Popover engine (e.g. jsdom) cannot observe. This forces *all* open-state coverage to full-browser E2E.
- Anchoring the layer requires either the unstable StyleX-hashed class or following `aria-describedby` to the `id` — workable for a single instance, fragile for many.
## Requested change (any one would help, in priority order)
1. Add `role="tooltip"` to the `Tooltip` layer (and an appropriate role to the `HoverCard` layer), per the ARIA APG.
2. Reflect open state with a stable attribute on the trigger and/or layer (e.g. `aria-expanded` on the trigger, or `data-state="open|closed"` on the layer) — mirroring the pattern `Popover` already uses (`aria-expanded`/`aria-controls`).
3. Forward a `data-testid` from props onto the layer.
## Workaround we ship today
We ship a **best-effort v1** `HoverCardDriver`/`TooltipDriver` (in [`@atomic-testing/component-driver-astryx`](https://github.com/atomic-testing/atomic-testing)) that anchors on the trigger and resolves the layer via `aria-describedby` → `id`, reading content in both states; the open transition is documented as E2E-only. Any of the above would let us promote these from best-effort to first-class.
Contributor guide
Assessment
This issue has not been assessed yet.