@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 +37 -17
- package/package.json +7 -5
- package/src/dom-query-helpers.ts +45 -0
- package/src/fire-event.ts +26 -22
- package/src/pure.ts +137 -37
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*`, `
|
|
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
|
|
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
|
-
- `
|
|
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
|
|
64
|
-
|
|
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
|
-
- **
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
`
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
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.
|
|
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.
|
|
44
|
+
"octane": "^0.2.5"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@testing-library/user-event": "^14.6.1",
|
|
48
|
-
"
|
|
49
|
-
"react
|
|
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.
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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`, `
|
|
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
|
|
91
|
-
//
|
|
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
|
-
/**
|
|
124
|
-
export type OctaneUI<P = any> = ComponentBody<P> |
|
|
122
|
+
/** A component body with optional props, or any Octane renderable. */
|
|
123
|
+
export type OctaneUI<P = any> = ComponentBody<P> | OctaneNode;
|
|
125
124
|
|
|
126
|
-
//
|
|
127
|
-
|
|
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
|
-
|
|
145
|
-
'render/rerender
|
|
146
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
178
|
-
|
|
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
|
|
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
|
-
//
|
|
255
|
-
//
|
|
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 =
|
|
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 (
|
|
298
|
-
|
|
299
|
-
|
|
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
|
-
//
|
|
411
|
-
//
|
|
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
|
|
415
|
-
|
|
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';
|