OUIA test hooks (data-ouia-* contract)
testing specs/testing/ouia-test-hooks.kmd
Every KDS-spec'd component MUST emit Open UI Automation (OUIA) attributes (`data-ouia-component-type`, `data-ouia-component-id`, `data-ouia-safe`) on its root element so test frameworks (Playwright, Cypress, Selenium, Flutter integration tests) have a stable selector contract that survives DOM refactors and styling churn.
Quando esta spec se aplica
Triggers primários
- Implement a KDS-spec'd component in koder_kit / koder_web_kit
Todos os triggers
- Add a new component to KDS
- Refactor a component's DOM tree
- Author UI tests against a Koder product
Corpo da especificação
Spec — OUIA test hooks
Status: v0.1.0 — Draft. Modeled after PatternFly's adoption of Open UI Automation (OUIA). Contract applies to every component in
specs/components/*.kmdonce ratified; existing components must add the attributes in a follow-up wave (one ticket per component inkoder_kit+koder_web_kit).
R1 — Required attributes
Every component MUST emit on its root rendered element:
| Attribute | Value | Notes |
|---|---|---|
data-ouia-component-type | PascalCase component name | e.g. Button, Combobox, DataTable, EmptyState |
data-ouia-component-id | Stable identifier unique on the page | Defaults to <type>-<slug-of-content-or-aria-label> if not user-provided |
data-ouia-safe | "true" only when component is idle/ready | "false" during load / mount / transition |
R2 — Naming
data-ouia-component-type value MUST match the spec slug in
specs/components/<slug>.kmd converted to PascalCase (kebab → Pascal:
empty-state → EmptyState, index-filters → IndexFilters,
data-table → DataTable).
R3 — Implementation contract
- koder_kit (Flutter) — emits the attributes via the Semantics tree on the component's outermost rendered widget; values exposed through the platform channels for integration tests.
- koder_web_kit (JS) — emits as HTML attributes on the outermost element returned by the component.
- Other (Kotlin / Swift native) — emits via the platform's
accessibility-identifier surface (
testTag/accessibilityIdentifier) using the same value scheme.
R4 — data-ouia-safe lifecycle
Component MUST set data-ouia-safe="false" during:
- Initial mount until first paint of stable content
- Any internal state transition (open/close, async fetch, animation)
Component MUST set data-ouia-safe="true" when:
- Content is stable
- No pending async ops
- Animations completed
Tests SHOULD wait on data-ouia-safe="true" before asserting.
R5 — CI enforcement
CI gate in koder_kit and koder_web_kit lints that every public component emits the 3 attributes. Failure blocks merge.
R6 — Opt-out
Pure decorative wrappers (e.g. KoderSpacer, KoderDivider) MAY omit
OUIA attributes if they are documented as decorative-only in their spec
page. Decorative components SHOULD NOT be selectable in tests anyway.
Não-escopo
- Test framework adoption — consumer concern; spec only sets the contract.
- Per-product test ID conventions on top of OUIA — products may add their own attributes alongside OUIA, never instead of.
Referências
specs/components/buttons.kmdspecs/testingrfcs/design-RFC-001-koder-design-system.kmd