@octanejs/testing-library 0.1.49 → 0.1.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,13 +10,17 @@ npm install @octanejs/testing-library
10
10
  pnpm add @octanejs/testing-library
11
11
  ```
12
12
 
13
+ This package peers on **Octane `^0.2.5`**. Published 0.2.4 and earlier do not export
14
+ `isInActScope`, which both public entries import.
15
+
13
16
  The split mirrors RTL's own architecture (and
14
17
  `docs/react-library-compat-plan.md` §2): **`@testing-library/dom` is
15
18
  framework-agnostic and reused verbatim** — every query, `screen`, `within`,
16
- `waitFor`/`waitForElementToBeRemoved`, `findBy*`, `fireEvent`, `prettyDOM`,
19
+ `waitFor`/`waitForElementToBeRemoved`, `findBy*`, `prettyDOM`,
17
20
  `configure` — while only react-testing-library's thin React layer is ported to
18
21
  octane: `render`, `cleanup`, `renderHook`, the `act` re-export, and the
19
- dom-testing-library config wiring (`eventWrapper`/`asyncWrapper`) that makes
22
+ focus/blur event helpers and dom-testing-library config wiring
23
+ (`eventWrapper`/`asyncWrapper`) that makes
20
24
  every dispatch/wait commit octane's scheduled work before your assertions run.
21
25
 
22
26
  ```ts
@@ -40,7 +44,13 @@ test('increments', () => {
40
44
  `RTL_SKIP_AUTO_CLEANUP=true` or import `@octanejs/testing-library/pure`)
41
45
  - `renderHook(callback, { initialProps, wrapper, ... }?)` → `{ result, rerender, unmount }`
42
46
  - `act` — octane's `act`, re-exported (always async; always `await` it)
43
- - `fireEvent`, `screen`, `waitFor`, `within`, … — dom-testing-library, re-exported
47
+ - `screen`, `waitFor`, `within`, … — dom-testing-library, re-exported
48
+ - `fireEvent` — DOM event helpers, with focus/blur pairs for delegated handlers
49
+
50
+ Multiple `rerender` calls inside one `act` callback commit together when that
51
+ callback finishes. Await `act` before asserting results that depend on promises
52
+ or effects. Promise work settles even when timeout clocks are frozen; advance
53
+ fake timers explicitly when the behavior itself depends on a timer.
44
54
 
45
55
  ## Octane-specific surface
46
56
 
@@ -60,8 +70,8 @@ remounts — exactly RTL's rerender semantics.
60
70
  ## Differences from react-testing-library
61
71
 
62
72
  Octane dispatches **native, delegated DOM events — there is no synthetic event
63
- layer** — so `fireEvent` is dom-testing-library's, deliberately *without* RTL's
64
- React-specific remappings:
73
+ layer**. `fireEvent` uses DOM Testing Library with focus/blur pairs for
74
+ delegation. Other helpers keep native semantics:
65
75
 
66
76
  - **`fireEvent.change` fires a native `change`; `fireEvent.input` a native
67
77
  `input`.** In React, `onChange` handlers actually run off native `input`
@@ -85,18 +95,21 @@ React-specific remappings:
85
95
  sequence and automatic checked-state transition. `fireEvent.change(checkbox)`
86
96
  is only an explicit change dispatch; it does not model the click, activation,
87
97
  cancellation/rollback, or full event ordering.
88
- - **No enter/leave/focus double-dispatch.** RTL's `fireEvent.mouseEnter` also
89
- fires `mouseover` (and `focus` fires `focusin`, `select` fires `keyup`, …)
90
- purely to feed React's plugin system, which listens to different native
91
- events than the handler names suggest. Octane's `onMouseEnter` receives the
92
- real `mouseenter` (non-bubbling events are capture-delegated), so
93
- `fireEvent.mouseEnter` alone triggers it — no compensation needed or wanted.
94
- - **Commit timing is wired, not synthesized.** Octane already commits discrete
95
- events (`click`, `input`, `keydown`, …) synchronously; this package
96
- additionally wraps *every* `fireEvent` dispatch in `flushSync` + an effect
97
- drain via dom-testing-library's `eventWrapper`, so non-discrete/programmatic
98
- events also commit — with their `useEffect` cascades — before `fireEvent`
99
- returns (the equivalent of RTL's `act()` around each dispatch).
98
+ - **Focus helpers emit both native focus events.** `fireEvent.focus` dispatches
99
+ `focus` then `focusin`; `fireEvent.blur` dispatches `blur` then `focusout`,
100
+ matching browser order.
101
+ Octane's delegated `onFocus`/`onBlur` handlers receive `focusin`/`focusout`.
102
+ Both events preserve the supplied options, including `relatedTarget`, except
103
+ that the paired `focusin`/`focusout` always bubbles. The return value is false
104
+ when the native `focus`/`blur` event was canceled.
105
+ Use `user.tab()` or native `focus()`/`blur()` to move actual focus.
106
+ - **No enter/leave remapping.** `fireEvent.mouseEnter` dispatches a real
107
+ `mouseenter`, which Octane's capture delegation delivers directly. It does
108
+ not also dispatch `mouseover` to drive React's synthetic event plugins.
109
+ - **Every dispatch commits before returning.** The DOM library's
110
+ `eventWrapper` runs every `fireEvent` dispatch in `flushSync` and then drains
111
+ effects, so the event's state updates and `useEffect` cascades are visible
112
+ before the helper returns.
100
113
  - **Host elements at the root are `container.firstChild`, like RTL.**
101
114
  `render(createElement('div', …))` goes through octane's value-position
102
115
  renderer, which mounts a lone host element anchorless (the element
@@ -150,3 +163,10 @@ text commit on `tab()`, checkbox click ordering, `keyboard()`).
150
163
  Current scope, known divergences, and verification status are tracked in the
151
164
  generated [bindings status table](../../docs/bindings-status.md), sourced from
152
165
  this package's [`status.json`](./status.json).
166
+
167
+ ## Runtime requirement
168
+
169
+ This release requires Octane 0.2.5 or later in the 0.2 line. Upgrade Octane together
170
+ with testing-library so the `isInActScope` API used for nested `act` batching is
171
+ available. The packed-consumer checks exercise that API and rendering inside
172
+ an outer `act` scope.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@octanejs/testing-library",
3
- "version": "0.1.49",
3
+ "version": "0.1.51",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "engines": {
@@ -41,14 +41,16 @@
41
41
  "@testing-library/dom": "^10.4.1"
42
42
  },
43
43
  "peerDependencies": {
44
- "octane": "^0.1.51 || ^0.2.0"
44
+ "octane": "^0.2.5"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@testing-library/user-event": "^14.6.1",
48
- "react": "^19.2.7",
49
- "react-dom": "^19.2.7",
48
+ "esbuild": "^0.28.1",
49
+ "react": "19.2.7",
50
+ "react-dom": "19.2.7",
51
+ "semver": "7.8.5",
50
52
  "vitest": "^4.1.10",
51
- "octane": "0.2.0"
53
+ "octane": "0.2.5"
52
54
  },
53
55
  "scripts": {
54
56
  "test": "vitest run"
@@ -0,0 +1,45 @@
1
+ import * as dom from '@testing-library/dom';
2
+ import type { GetErrorFunction, QueryMethod, Variant, waitForOptions } from '@testing-library/dom';
3
+
4
+ // DOM Testing Library 10.4.1 exports these values but omits their declarations.
5
+ // Preserve the original functions and describe their pinned query contracts.
6
+ interface RuntimeQueryHelpers {
7
+ getMultipleElementsFoundError(message: string, container: Element): Error;
8
+ makeSingleQuery<Args extends unknown[], ElementType extends HTMLElement>(
9
+ query: QueryMethod<Args, ElementType[]>,
10
+ getMultipleError: GetErrorFunction<Args>,
11
+ ): QueryMethod<Args, ElementType | null>;
12
+ makeGetAllQuery<Args extends unknown[], ElementType extends HTMLElement>(
13
+ query: QueryMethod<Args, ElementType[]>,
14
+ getMissingError: GetErrorFunction<Args>,
15
+ ): QueryMethod<Args, ElementType[]>;
16
+ makeFindQuery<Text, Options, Result>(
17
+ query: (container: HTMLElement, text: Text, options?: Options) => Result,
18
+ ): (
19
+ container: HTMLElement,
20
+ text: Text,
21
+ options?: Options,
22
+ waitOptions?: waitForOptions,
23
+ ) => Promise<Awaited<Result>>;
24
+ wrapSingleQueryWithSuggestion<Args extends unknown[], Result extends HTMLElement | null>(
25
+ query: QueryMethod<Args, Result>,
26
+ queryName: string,
27
+ variant: Variant,
28
+ ): QueryMethod<Args, Result>;
29
+ wrapAllByQueryWithSuggestion<Args extends unknown[], ElementType extends HTMLElement>(
30
+ query: QueryMethod<Args, ElementType[]>,
31
+ queryName: string,
32
+ variant: Variant,
33
+ ): QueryMethod<Args, ElementType[]>;
34
+ }
35
+
36
+ export const {
37
+ getMultipleElementsFoundError,
38
+ makeSingleQuery,
39
+ makeGetAllQuery,
40
+ makeFindQuery,
41
+ wrapSingleQueryWithSuggestion,
42
+ wrapAllByQueryWithSuggestion,
43
+ } = dom as typeof dom & RuntimeQueryHelpers;
44
+
45
+ export const queryHelpers = dom.queryHelpers as typeof dom.queryHelpers & RuntimeQueryHelpers;
package/src/fire-event.ts CHANGED
@@ -1,22 +1,26 @@
1
- // `fireEvent` — dom-testing-library's, re-exported UNWRAPPED.
2
- //
3
- // react-testing-library layers remappings on top of dom-testing-library's
4
- // fireEvent because React's synthetic event system listens to DIFFERENT native
5
- // events than the handler names suggest (mouseEnter handlers run off native
6
- // mouseover, focus/blur off focusin/focusout, `select` is synthesized from key
7
- // events, `onChange` fires on native input, …), so RTL double-dispatches to
8
- // feed React's plugins.
9
- //
10
- // Octane has NO synthetic event layer — `onX` handlers receive the native `x`
11
- // event, delegated. `fireEvent.mouseEnter` therefore dispatches a real
12
- // `mouseenter` and octane's capture-phase delegation of non-bubbling events
13
- // delivers it; `fireEvent.change` fires a native `change` (NOT React's
14
- // input-as-change); no remapping is wanted. The commit wiring (flushSync +
15
- // effect drain around every dispatch) rides on dom-testing-library's
16
- // `eventWrapper` config hook — see pure.ts.
17
- //
18
- // In particular, `fireEvent.change(textbox)` means “dispatch an explicit native
19
- // commit event”; it does not simulate typing or blur. Likewise, change on a
20
- // checkbox does not reproduce click activation/toggling or click → input →
21
- // change ordering. Use user-event's type/tab/click flows for those sequences.
22
- export { fireEvent } from '@testing-library/dom';
1
+ import { fireEvent as domFireEvent } from '@testing-library/dom';
2
+
3
+ // Keep the DOM helpers independent: callers importing @testing-library/dom
4
+ // directly still get one native event per helper. Octane's onFocus/onBlur
5
+ // delegation listens to focusin/focusout, so those two convenience helpers
6
+ // emit native focus/blur followed by the corresponding bubbling event.
7
+ export const fireEvent: typeof domFireEvent = Object.assign(
8
+ (...args: Parameters<typeof domFireEvent>) => domFireEvent(...args),
9
+ domFireEvent,
10
+ );
11
+
12
+ fireEvent.focus = (element, options) => {
13
+ const result = domFireEvent.focus(element, options);
14
+ domFireEvent.focusIn(element, { ...options, bubbles: true });
15
+ return result;
16
+ };
17
+ fireEvent.blur = (element, options) => {
18
+ const result = domFireEvent.blur(element, options);
19
+ domFireEvent.focusOut(element, { ...options, bubbles: true });
20
+ return result;
21
+ };
22
+
23
+ // Other helpers retain DOM semantics: change dispatches an explicit native
24
+ // commit event; mouseEnter does not also dispatch mouseover. Use user-event
25
+ // for complete typing, click activation, and focus movement sequences.
26
+ // Commit/effect flushing uses the DOM library's eventWrapper (see pure.ts).
package/src/pure.ts CHANGED
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Strategy (docs/react-library-compat-plan.md §2): `@testing-library/dom` is
5
5
  * framework-agnostic, so it is depended on VERBATIM and re-exported wholesale
6
- * (queries, `screen`, `within`, `waitFor`, `fireEvent`, `prettyDOM`, …). Only
6
+ * (queries, `screen`, `within`, `waitFor`, `prettyDOM`, …). Only
7
7
  * react-testing-library's thin React layer is ported here, onto octane:
8
8
  *
9
9
  * - `render` / `cleanup` / `renderHook` mount through octane's `createRoot`
@@ -22,6 +22,7 @@
22
22
  */
23
23
  import {
24
24
  act,
25
+ isInActScope,
25
26
  createElement,
26
27
  createRoot,
27
28
  drainPassiveEffects,
@@ -33,6 +34,7 @@ import {
33
34
  withSlot,
34
35
  type ComponentBody,
35
36
  type ElementDescriptor,
37
+ type OctaneNode,
36
38
  type Root,
37
39
  } from 'octane';
38
40
  import {
@@ -43,6 +45,7 @@ import {
43
45
  } from '@testing-library/dom';
44
46
  import type { BoundFunctions, Queries } from '@testing-library/dom';
45
47
  import { getIsOctaneActEnvironment, setOctaneActEnvironment } from './act-environment';
48
+ import { fireEvent as octaneFireEvent } from './fire-event';
46
49
 
47
50
  // ─────────────────────────────────────────────────────────────────────────────
48
51
  // dom-testing-library config wiring (RTL pure.js does the same three hooks).
@@ -87,13 +90,8 @@ configureDTL({
87
90
  setOctaneActEnvironment(previousActEnvironment);
88
91
  }
89
92
  },
90
- // Every `fireEvent` dispatch runs through here. Octane's DISCRETE delegated
91
- // events (click/input/keydown/…) already commit synchronously on their own
92
- // (maybeFlushDiscrete → flushSync), but fireEvent also dispatches event types
93
- // with no discrete path — non-delegated or programmatic events whose updates
94
- // would otherwise sit queued until the next microtask, i.e. after the test's
95
- // assertion. flushSync commits those too, and the passive drain mirrors RTL's
96
- // act(): effects scheduled by the event have run before fireEvent returns.
93
+ // Every fireEvent dispatch commits its updates and drains passive effects
94
+ // before returning, including programmatic and non-discrete events.
97
95
  eventWrapper: (cb) => {
98
96
  let result: unknown;
99
97
  flushSync(() => {
@@ -112,6 +110,7 @@ configureDTL({
112
110
  interface RootEntry {
113
111
  container: Element;
114
112
  root: Root;
113
+ valueRoot: boolean;
115
114
  }
116
115
  const mountedContainers = new Set<Element>();
117
116
  const mountedRootEntries: RootEntry[] = [];
@@ -120,13 +119,11 @@ const mountedRootEntries: RootEntry[] = [];
120
119
  // UI normalization — octane's two authoring forms into one mountable element.
121
120
  // ─────────────────────────────────────────────────────────────────────────────
122
121
 
123
- /** What `render`/`rerender` accept: a component body, or a `createElement` result. */
124
- export type OctaneUI<P = any> = ComponentBody<P> | ElementDescriptor<P>;
122
+ /** A component body with optional props, or any Octane renderable. */
123
+ export type OctaneUI<P = any> = ComponentBody<P> | OctaneNode;
125
124
 
126
- // A root can only mount a COMPONENT. `render(createElement('div', …))` (RTL's
127
- // `render(<div/>)`) produces a HOST descriptor, so it is returned from a pass-
128
- // through component and rendered by the runtime's value-position renderer.
129
- function ValueRoot(props: { children: unknown }): unknown {
125
+ // Arrays and host values share a stable value-rendering owner across rerenders.
126
+ function ValueRoot(props: { children: OctaneNode }): OctaneNode {
130
127
  return props.children;
131
128
  }
132
129
 
@@ -141,12 +138,12 @@ function toElement<P>(ui: OctaneUI<P>, props: P | undefined): ElementDescriptor
141
138
  return ui;
142
139
  }
143
140
  if (typeof ui !== 'function') {
144
- throw new Error(
145
- 'render/rerender expects an octane component (a function) or an element ' +
146
- `descriptor from createElement(...); received ${typeof ui}.`,
147
- );
141
+ if (props !== undefined) {
142
+ throw new Error('render/rerender only accepts the props option with a bare component.');
143
+ }
144
+ return createElement(ValueRoot, { children: ui });
148
145
  }
149
- return createElement(ui, props);
146
+ return createElement(ui as ComponentBody<P>, props);
150
147
  }
151
148
 
152
149
  function wrapUiIfNeeded(
@@ -156,8 +153,10 @@ function wrapUiIfNeeded(
156
153
  return wrapperComponent ? createElement(wrapperComponent, { children: element }) : element;
157
154
  }
158
155
 
159
- function mountable(element: ElementDescriptor): ElementDescriptor {
160
- return typeof element.type === 'string'
156
+ function mountable(element: ElementDescriptor, valueRoot: boolean): ElementDescriptor {
157
+ // Retain one value-rendering owner when rerender moves between an array,
158
+ // fragment, and single element. Keyed children keep their state across them.
159
+ return valueRoot && element.type !== ValueRoot
161
160
  ? createElement(ValueRoot, { children: element })
162
161
  : element;
163
162
  }
@@ -174,14 +173,21 @@ function mountable(element: ElementDescriptor): ElementDescriptor {
174
173
  // `waitFor`/`findBy*`/`act` are for, same as RTL.
175
174
  function settleSync(): void {
176
175
  for (let i = 0; i < 50 && hasPendingWork(); i++) {
177
- drainPassiveEffects();
178
- flushSync(() => {});
176
+ // Passive effects may schedule state updates too. They belong to this
177
+ // testing-library commit, so keep the drain inside its synchronous scope.
178
+ flushSync(() => {
179
+ drainPassiveEffects();
180
+ });
179
181
  }
180
182
  }
181
183
 
182
184
  // Commit a render synchronously — flushSync for the render itself, then the
183
185
  // cascade settle. Equivalent to RTL's `act(() => root.render(ui))` (sync form).
184
186
  function commitRender(root: Root, element: ElementDescriptor): void {
187
+ if (isInActScope()) {
188
+ root.render(element);
189
+ return;
190
+ }
185
191
  flushSync(() => {
186
192
  root.render(element);
187
193
  });
@@ -246,27 +252,32 @@ export function render<P = any>(ui: OctaneUI<P>, options: RenderOptions<P> = {})
246
252
  container = baseElement.appendChild(document.createElement('div'));
247
253
  }
248
254
 
249
- const element = mountable(wrapUiIfNeeded(toElement(ui, props), WrapperComponent));
255
+ const normalized = wrapUiIfNeeded(toElement(ui, props), WrapperComponent);
256
+ const previousEntry = mountedRootEntries.find((entry) => entry.container === container);
257
+ const valueRoot =
258
+ previousEntry?.valueRoot ??
259
+ (typeof normalized.type !== 'function' || normalized.type === ValueRoot);
260
+ const element = mountable(normalized, valueRoot);
250
261
 
251
262
  let root: Root;
252
263
  if (!mountedContainers.has(container)) {
253
264
  if (hydrate) {
254
- // hydrateRoot adopts the server DOM during creation (it renders once,
255
- // synchronously) — only the effect settle is left to do.
256
- root = hydrateRoot(container, element);
265
+ // Adoption queues insertion/layout effects. Commit those before the
266
+ // passive settle, so descendants can use callbacks installed by them.
267
+ root = flushSync(() => hydrateRoot(container, element));
257
268
  settleSync();
258
269
  } else {
259
270
  root = createRoot(container);
260
271
  commitRender(root, element);
261
272
  }
262
- mountedRootEntries.push({ container, root });
273
+ mountedRootEntries.push({ container, root, valueRoot });
263
274
  // Track the container regardless of whether WE created it, so cleanup()
264
275
  // handles caller-supplied containers too (RTL does the same).
265
276
  mountedContainers.add(container);
266
277
  } else {
267
278
  // Same container rendered again → reuse its root (same component updates
268
279
  // props in place; a different component tears down and remounts).
269
- root = mountedRootEntries.find((entry) => entry.container === container)!.root;
280
+ root = previousEntry!.root;
270
281
  commitRender(root, element);
271
282
  }
272
283
 
@@ -294,16 +305,22 @@ export function render<P = any>(ui: OctaneUI<P>, options: RenderOptions<P> = {})
294
305
  let element: ElementDescriptor;
295
306
  if (rerenderUi === undefined) {
296
307
  element = toElement(ui, props); // re-run with the original props
297
- } else if (isValidElement(rerenderUi) || typeof rerenderUi === 'function') {
298
- element = toElement(rerenderUi as OctaneUI, rerenderOptions?.props);
299
- } else {
308
+ } else if (
309
+ rerenderUi !== null &&
310
+ typeof rerenderUi === 'object' &&
311
+ !isValidElement(rerenderUi) &&
312
+ !Array.isArray(rerenderUi) &&
313
+ Object.prototype.hasOwnProperty.call(rerenderUi, 'props')
314
+ ) {
300
315
  // `{ props }` shorthand: reuse the ORIGINAL component with new props.
301
316
  const comp = isValidElement(ui) ? (ui as ElementDescriptor).type : ui;
302
317
  element = createElement(comp as any, (rerenderUi as { props?: any }).props);
318
+ } else {
319
+ element = toElement(rerenderUi, rerenderOptions?.props);
303
320
  }
304
321
  // The wrapper is re-applied so component identity is stable across
305
322
  // rerenders (same body ⇒ octane updates props in place).
306
- commitRender(root, mountable(wrapUiIfNeeded(element, WrapperComponent)));
323
+ commitRender(root, mountable(wrapUiIfNeeded(element, WrapperComponent), valueRoot));
307
324
  },
308
325
  asFragment: () => document.createRange().createContextualFragment(container.innerHTML),
309
326
  ...(getQueriesForElement(baseElement, queries as any) as BoundFunctions<typeof defaultQueries>),
@@ -407,10 +424,93 @@ export function renderHook<Result, Props = undefined>(
407
424
 
408
425
  // ─────────────────────────────────────────────────────────────────────────────
409
426
  // Exports — everything dom-testing-library ships, plus the octane layer.
410
- // `fireEvent` is dom-testing-library's own (see fire-event.ts for why there is
411
- // deliberately NO react-testing-library-style event remapping on top).
427
+ // fireEvent adds native focus/blur pairs for delegated focus handlers.
428
+ // Other convenience helpers retain DOM Testing Library's event semantics.
412
429
  // ─────────────────────────────────────────────────────────────────────────────
413
430
 
414
- export * from '@testing-library/dom';
415
- export { fireEvent } from './fire-event';
431
+ export const fireEvent = octaneFireEvent;
432
+ // Explicit value exports keep older SSR module runners from replacing our
433
+ // focus-aware fireEvent with the DOM helper during wildcard re-export.
434
+ export {
435
+ buildQueries,
436
+ configure,
437
+ createEvent,
438
+ findAllByAltText,
439
+ findAllByDisplayValue,
440
+ findAllByLabelText,
441
+ findAllByPlaceholderText,
442
+ findAllByRole,
443
+ findAllByTestId,
444
+ findAllByText,
445
+ findAllByTitle,
446
+ findByAltText,
447
+ findByDisplayValue,
448
+ findByLabelText,
449
+ findByPlaceholderText,
450
+ findByRole,
451
+ findByTestId,
452
+ findByText,
453
+ findByTitle,
454
+ getAllByAltText,
455
+ getAllByDisplayValue,
456
+ getAllByLabelText,
457
+ getAllByPlaceholderText,
458
+ getAllByRole,
459
+ getAllByTestId,
460
+ getAllByText,
461
+ getAllByTitle,
462
+ getByAltText,
463
+ getByDisplayValue,
464
+ getByLabelText,
465
+ getByPlaceholderText,
466
+ getByRole,
467
+ getByTestId,
468
+ getByText,
469
+ getByTitle,
470
+ getConfig,
471
+ getDefaultNormalizer,
472
+ getElementError,
473
+ getNodeText,
474
+ getQueriesForElement,
475
+ getRoles,
476
+ getSuggestedQuery,
477
+ isInaccessible,
478
+ logDOM,
479
+ logRoles,
480
+ prettyDOM,
481
+ prettyFormat,
482
+ queries,
483
+ queryAllByAltText,
484
+ queryAllByAttribute,
485
+ queryAllByDisplayValue,
486
+ queryAllByLabelText,
487
+ queryAllByPlaceholderText,
488
+ queryAllByRole,
489
+ queryAllByTestId,
490
+ queryAllByText,
491
+ queryAllByTitle,
492
+ queryByAltText,
493
+ queryByAttribute,
494
+ queryByDisplayValue,
495
+ queryByLabelText,
496
+ queryByPlaceholderText,
497
+ queryByRole,
498
+ queryByTestId,
499
+ queryByText,
500
+ queryByTitle,
501
+ screen,
502
+ waitFor,
503
+ waitForElementToBeRemoved,
504
+ within,
505
+ } from '@testing-library/dom';
506
+ export {
507
+ getMultipleElementsFoundError,
508
+ makeFindQuery,
509
+ makeGetAllQuery,
510
+ makeSingleQuery,
511
+ queryHelpers,
512
+ wrapAllByQueryWithSuggestion,
513
+ wrapSingleQueryWithSuggestion,
514
+ } from './dom-query-helpers';
515
+ export type * from '@testing-library/dom';
416
516
  export { act } from 'octane';