Testing Utilities
@vielzeug/refine/testing provides helpers for writing component tests on top of @vielzeug/ore/testing. All helpers are tree-shakeable with no runtime side-effects.
The module groups into four concerns: ARIA assertions (check what the DOM exposes to assistive technology), shadow DOM queries (reach inside component internals), form helpers (read form-associated values), and event / timing utilities (simulate keyboard input and wait for reactive updates).
import { isAriaInvalid, queryInShadow, mountOreInput } from '@vielzeug/refine/testing';ARIA Helpers
Boolean predicates and getters for the most common ARIA states:
| Helper | Returns |
|---|---|
isAriaInvalid(el) | true when aria-invalid="true" |
isAriaDisabled(el) | true when aria-disabled="true" |
isAriaChecked(el) | true when aria-checked="true" |
isAriaIndeterminate(el) | true when aria-checked="mixed" |
isAriaExpanded(el) | true when aria-expanded="true" |
isAriaPressed(el) | true when aria-pressed="true" |
isAriaRequired(el) | true when aria-required="true" |
isAriaHidden(el) | true when aria-hidden="true" |
getAriaLabel(el) | aria-label value or null |
getAriaLabelledBy(el) | aria-labelledby value or null |
getAriaDescribedBy(el) | aria-describedby value or null |
getAriaControls(el) | aria-controls value or null |
getRole(el) | role value or null |
Snapshot Assertions
getAriaState(el) returns a plain object snapshot of the eight most commonly asserted ARIA attributes — useful for inline snapshot assertions:
expect(getAriaState(input)).toMatchObject({ invalid: 'true', required: 'true' });Shadow DOM Queries
// Query a single element inside the host's shadow root
const inner = queryInShadow(host, 'input');
// Query all matching elements
const items = queryAllInShadow(host, '[role="option"]');Form-Associated Helpers
// Read the current form value (ElementInternals-based or reflected .value)
const value = getFormValue(el);
// True when the element has no constraint violations
const valid = isFormValid(el);Event Helpers
// Synthetic KeyboardEvent for keyboard navigation tests
const ev = keyEvent('ArrowDown', { shiftKey: true });
element.dispatchEvent(ev);Timing Helpers
// Wait for reactive signal effects to settle (microtask flush)
await nextTick();
// Wait a fixed number of milliseconds — use sparingly
await wait(50);ID Counter Reset
Refine components generate stable IDs for ARIA associations. Reset the counter in beforeEach when you need deterministic IDs across test runs:
import { resetIdCounter } from '@vielzeug/refine/testing';
beforeEach(() => resetIdCounter());Typed Mount Wrappers
Typed wrappers catch prop-name typos at compile time and avoid manual HTML serialization. Each wrapper is named mountSg{ComponentName}:
import {
mountOreButton,
mountOreButtonGroup,
mountOreCheckbox,
mountOreCheckboxGroup,
mountOreCombobox,
mountOreFileInput,
mountOreForm,
mountOreInput,
mountOreNumberInput,
mountOreOtpInput,
mountOreRadio,
mountOreRadioGroup,
mountOreRating,
mountOreSelect,
mountOreSlider,
mountOreSwitch,
mountOreTextarea,
} from '@vielzeug/refine/testing';All wrappers share the same signature:
mountSg{Component}(props?, opts?)
// props — Partial<ComponentProps>, type-checked at compile time
// opts — { innerHTML?: string } for slotted contentExample — asserting ARIA state:
const fixture = await mountOreInput({ label: 'Name', required: true });
const input = queryInShadow(fixture.el, 'input')!;
expect(isAriaRequired(input)).toBe(true);Example — passing slot content:
const fixture = await mountOreSelect(
{ label: 'Country' },
{ innerHTML: '<ore-option value="us">United States</ore-option>' },
);