# Testing

Test Poetry UIs at the cheapest tier that can catch the bug: wiring asserts on rendered contracts, behavior through the Testing helpers (poetry_dialog, poetry_select, poetry_combobox, poetry_dropdown_menu, assert_poetry_controllers_registered), and the browser only for what needs a layout engine.

Poetry apps test at the cheapest tier that can catch the bug, so a failing test names the fix. Lint first: `bin/rails poetry:check` validates ERB against the component registry and controllers manifest without rendering - components, options, variants, and Stimulus controllers, actions, targets, and typed values, hand-written or through a Poetry helper's `data:` keywords (`POETRY_CHECK_JSON=1` for CI, `POETRY_CHECK_DESIGN=1` adds design warnings). Wiring tests render a view and assert `data-slot` parts, ARIA, form participants, and Stimulus wiring, never Tailwind classes. For real interaction, `include Poetry::Ui::Testing` in a system test: `poetry_select`, `poetry_combobox`, `poetry_dropdown_menu`, and `poetry_dialog` drive components through real keyboard and pointer sequences (`via: :keyboard` or `:mouse`) and assert the public attribute contract; `assert_poetry_controllers_registered` guards the page: every Poetry controller present must be registered on the Stimulus application, since Stimulus never errors on an unknown identifier and one failed import silently takes the whole graph down. Refresh the safelist before any browser pass.
