@orkestrel/test 0.0.16 → 0.0.18
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 +7 -5
- package/dist/src/browser/index.d.ts +637 -10
- package/dist/src/browser/index.js +651 -4
- package/dist/src/browser/index.js.map +1 -1
- package/dist/src/core/index.cjs +99 -16
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +580 -456
- package/dist/src/core/index.d.ts +580 -456
- package/dist/src/core/index.js +98 -17
- package/dist/src/core/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -23,6 +23,11 @@
|
|
|
23
23
|
* @packageDocumentation
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
+
import type { JourneyVariant } from '@orkestrel/test';
|
|
27
|
+
import type { StatechartStatus } from '@orkestrel/test';
|
|
28
|
+
import type { StateScenario } from '@orkestrel/test';
|
|
29
|
+
import type { WaitOptions } from '@orkestrel/test';
|
|
30
|
+
|
|
26
31
|
/**
|
|
27
32
|
* Names the interactive ARIA roles a bare accessible name is searched across.
|
|
28
33
|
*
|
|
@@ -69,6 +74,117 @@ export declare function blendColor(front: Color, back: Color): Color;
|
|
|
69
74
|
*/
|
|
70
75
|
export declare function build<K extends keyof HTMLElementTagNameMap>(tag: K, options?: ElementOptions): HTMLElementTagNameMap[K];
|
|
71
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Builds detached markup carrying one undeclared class token on HTML and another on SVG.
|
|
79
|
+
*
|
|
80
|
+
* @returns The detached root, the token the HTML element carries, and the one the SVG carries.
|
|
81
|
+
*
|
|
82
|
+
* @remarks
|
|
83
|
+
* The SVG element is the trap a census has to survive: `className` on an SVG element is an
|
|
84
|
+
* `SVGAnimatedString` rather than a string, so a reader splitting that value finds nothing and
|
|
85
|
+
* reports one undeclared token where two are carried. {@link readCensus} reads every element
|
|
86
|
+
* through `classList`, and this is the control that proves it.
|
|
87
|
+
*
|
|
88
|
+
* The two tokens are returned rather than written into a caller's expectation, so a cascade that
|
|
89
|
+
* later declares one of these names moves the fixture and the assertion together. Each token also
|
|
90
|
+
* carries a suffix drawn per call from `crypto.getRandomValues`, so a consumer cascade cannot
|
|
91
|
+
* declare either of them in advance and two controls in one document never share a token.
|
|
92
|
+
* `getRandomValues` rather than `randomUUID`, because that one answers outside a secure context
|
|
93
|
+
* too, and a browser project served from a remote host is not one.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```ts
|
|
97
|
+
* const control = buildCensus()
|
|
98
|
+
* readCensus(control.root).undeclared // [control.mark, control.token], sorted
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export declare function buildCensus(): CensusFixture;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Builds a detached translucent stack whose composited and flat contrast readings straddle one bar.
|
|
105
|
+
*
|
|
106
|
+
* @param bar - The contrast ratio `refused` and `accepted` must sit on opposite sides of.
|
|
107
|
+
* @returns The opaque root carrying the tint, and the refused and accepted foregrounds under it.
|
|
108
|
+
* @throws An `Error` when no grey foreground puts the two readings on opposite sides of the bar.
|
|
109
|
+
*
|
|
110
|
+
* @remarks
|
|
111
|
+
* A contrast instrument that never composites still clears every fixture painting its own opaque
|
|
112
|
+
* background, so this is the control that makes {@link readContrast}'s ancestor walk and alpha
|
|
113
|
+
* blend the thing under test. The stack is an opaque floor, a translucent tint over it, and two
|
|
114
|
+
* grey foregrounds inside the tint. `refused` reads under the bar composited and at or over it
|
|
115
|
+
* flat, and `accepted` reads the other way about, so no single non-compositing reading satisfies
|
|
116
|
+
* both.
|
|
117
|
+
*
|
|
118
|
+
* The greys are searched rather than written down, so the control follows the bar it was asked for.
|
|
119
|
+
* A bar at or under `1` is refused because every contrast ratio reaches `1`, and a bar above what
|
|
120
|
+
* the tinted surface can reach is refused because no foreground clears it — each refusal names the
|
|
121
|
+
* bar rather than returning a stack that proves nothing.
|
|
122
|
+
*
|
|
123
|
+
* The nodes are detached, so nothing is mounted for you. Append `root` to the surface you are
|
|
124
|
+
* reading, take both readings, and remove it: a computed color needs the document, and a fixture
|
|
125
|
+
* left behind is the next test's resolver ambiguity.
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```ts
|
|
129
|
+
* const control = buildContrast(4.5)
|
|
130
|
+
* mount(control.root)
|
|
131
|
+
* readContrast(control.refused) < 4.5 // true
|
|
132
|
+
* readContrast(control.accepted) >= 4.5 // true
|
|
133
|
+
* control.root.remove()
|
|
134
|
+
* ```
|
|
135
|
+
*/
|
|
136
|
+
export declare function buildContrast(bar: number): ContrastFixture;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Builds the refusal a host withholding a storage operation raises.
|
|
140
|
+
*
|
|
141
|
+
* @param operation - The withheld operation, named as the `Storage` interface names it.
|
|
142
|
+
* @param key - The storage key the operation addressed. Omit it for an operation that takes none.
|
|
143
|
+
* @returns The refusal, unthrown.
|
|
144
|
+
*
|
|
145
|
+
* @remarks
|
|
146
|
+
* A browser with site data blocked, a sandboxed frame, and a hardened privacy mode all raise a
|
|
147
|
+
* `DOMException` named `SecurityError` from the storage object rather than answering, so this is
|
|
148
|
+
* the voice rather than a message of this package's. {@link createStorage} raises it from every
|
|
149
|
+
* operation the permission withholds; it is exported because a fixture implementing `Storage` some
|
|
150
|
+
* other way needs the same voice rather than a second spelling of it.
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```ts
|
|
154
|
+
* buildDenial('getItem', 'theme').message // 'Access is denied for getItem "theme"'
|
|
155
|
+
* buildDenial('length').name // 'SecurityError'
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
export declare function buildDenial(operation: string, key?: string): DOMException;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Builds detached markup carrying one style escape of each kind, plus the sheet a project allows.
|
|
162
|
+
*
|
|
163
|
+
* @param permitted - The `id` the caller's reading exempts, placed on the third element.
|
|
164
|
+
* @returns The detached root, the inline escape, the embedded escape, and the exempt sheet.
|
|
165
|
+
*
|
|
166
|
+
* @remarks
|
|
167
|
+
* {@link extractStyles} has two branches — an inline `style` attribute and a `<style>` element —
|
|
168
|
+
* and a reading fed only the first never exercises the second. The exempt sheet is the other half
|
|
169
|
+
* of the control: a project that allows one standalone stylesheet writes an exemption for its id,
|
|
170
|
+
* and a reading that passes by refusing every `<style>` element clears the two escapes and fails
|
|
171
|
+
* that exemption.
|
|
172
|
+
*
|
|
173
|
+
* The declaration `inline`, `embedded`, and `permitted` carry is this package's, so assert on which
|
|
174
|
+
* elements are reported rather than on what they declare.
|
|
175
|
+
*
|
|
176
|
+
* The nodes are detached and stay that way: `extractStyles` takes any `ParentNode`, so the reading
|
|
177
|
+
* runs without mounting, and an embedded sheet that reached the document would join the cascade
|
|
178
|
+
* every other reading measures against.
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```ts
|
|
182
|
+
* const control = buildEscapes('project-stylesheet')
|
|
183
|
+
* extractStyles(control.root).length // 3 — the inline escape, the embedded sheet, and the exempt one
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
export declare function buildEscapes(permitted: string): EscapeFixture;
|
|
187
|
+
|
|
72
188
|
/**
|
|
73
189
|
* Names the color a browser paints an unstyled document with: opaque white.
|
|
74
190
|
*
|
|
@@ -169,14 +285,16 @@ export declare const CAPTURE_STAGINGS = 4;
|
|
|
169
285
|
*/
|
|
170
286
|
export declare function captureFrame(options: FrameOptions): Promise<string>;
|
|
171
287
|
|
|
172
|
-
/**
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
288
|
+
/**
|
|
289
|
+
* Adds to a journey variant the document change a capture run applies before resizing.
|
|
290
|
+
*
|
|
291
|
+
* @remarks
|
|
292
|
+
* The name, the width, and the height come from {@link JourneyVariant}, which a project
|
|
293
|
+
* configuration can serialize and hand to the suite that renders it. The change this adds is a
|
|
294
|
+
* function, so it belongs to the suite rather than to that configuration: a variant a configuration
|
|
295
|
+
* declares and a variant a capture run renders are the same row read at two depths.
|
|
296
|
+
*/
|
|
297
|
+
export declare interface CaptureVariant extends JourneyVariant {
|
|
180
298
|
/**
|
|
181
299
|
* Holds the document change this variant needs before the viewport is resized — a theme
|
|
182
300
|
* attribute, a density class, a language direction. Omit it when the variant is a viewport alone.
|
|
@@ -184,6 +302,41 @@ export declare interface CaptureVariant {
|
|
|
184
302
|
readonly apply?: () => void;
|
|
185
303
|
}
|
|
186
304
|
|
|
305
|
+
/**
|
|
306
|
+
* Holds detached markup an authored-class census must report as undeclared.
|
|
307
|
+
*
|
|
308
|
+
* @remarks
|
|
309
|
+
* One token rides on an HTML element and the other on an SVG element, because `className` on an SVG
|
|
310
|
+
* element is an `SVGAnimatedString` rather than a string: a census splitting that value finds
|
|
311
|
+
* nothing and reports one token where two are carried.
|
|
312
|
+
*/
|
|
313
|
+
export declare interface CensusFixture {
|
|
314
|
+
/** Holds the detached root carrying both marked elements. */
|
|
315
|
+
readonly root: HTMLElement;
|
|
316
|
+
/** Holds the class token the HTML element carries. */
|
|
317
|
+
readonly token: string;
|
|
318
|
+
/** Holds the class token the SVG element carries. */
|
|
319
|
+
readonly mark: string;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Reports an authored-class census: the population walked, the tokens found, and the undeclared.
|
|
324
|
+
*
|
|
325
|
+
* @remarks
|
|
326
|
+
* The population is reported beside the finding because an empty walk satisfies every difference
|
|
327
|
+
* check: a census that read no element reports no undeclared token, and so does a census over
|
|
328
|
+
* markup whose every class the cascade declares. Assert on `elements` as well as on `undeclared`
|
|
329
|
+
* and the two cannot be confused.
|
|
330
|
+
*/
|
|
331
|
+
export declare interface CensusReading {
|
|
332
|
+
/** Reports how many elements the walk read, the root included when it is an element. */
|
|
333
|
+
readonly elements: number;
|
|
334
|
+
/** Lists every class token the markup carries, sorted. */
|
|
335
|
+
readonly tokens: readonly string[];
|
|
336
|
+
/** Lists every carried token no loaded stylesheet declares, sorted. */
|
|
337
|
+
readonly undeclared: readonly string[];
|
|
338
|
+
}
|
|
339
|
+
|
|
187
340
|
/**
|
|
188
341
|
* Clears both browser storage surfaces.
|
|
189
342
|
*
|
|
@@ -335,6 +488,24 @@ export declare function computeNamePattern(name: string): RegExp;
|
|
|
335
488
|
*/
|
|
336
489
|
export declare const CONTENT_ROLES: readonly string[];
|
|
337
490
|
|
|
491
|
+
/**
|
|
492
|
+
* Holds a detached translucent stack whose flat and composited readings disagree across one bar.
|
|
493
|
+
*
|
|
494
|
+
* @remarks
|
|
495
|
+
* `refused` and `accepted` are the control a composited-contrast reading owes: the composited
|
|
496
|
+
* reading refuses one and the flat reading clears it, and the other way about for the second. A reader that takes the
|
|
497
|
+
* nearest declared background at full strength answers the opposite pair, so no single
|
|
498
|
+
* non-compositing reading satisfies both.
|
|
499
|
+
*/
|
|
500
|
+
export declare interface ContrastFixture {
|
|
501
|
+
/** Holds the opaque floor carrying the translucent tint; append this to read either foreground. */
|
|
502
|
+
readonly root: HTMLElement;
|
|
503
|
+
/** Holds the foreground whose composited reading falls under the bar. */
|
|
504
|
+
readonly refused: HTMLElement;
|
|
505
|
+
/** Holds the foreground whose composited reading reaches the bar. */
|
|
506
|
+
readonly accepted: HTMLElement;
|
|
507
|
+
}
|
|
508
|
+
|
|
338
509
|
/**
|
|
339
510
|
* Creates one console channel that records every call it receives and hands that call on unchanged.
|
|
340
511
|
*
|
|
@@ -389,6 +560,59 @@ export declare function createChannel(name: string, output: string[], forward: (
|
|
|
389
560
|
*/
|
|
390
561
|
export declare function createDragEvent(name: string, options?: DragEventInit): DragEvent;
|
|
391
562
|
|
|
563
|
+
/**
|
|
564
|
+
* Creates a mounted statechart harness that renders one transition table and drives it row by row.
|
|
565
|
+
*
|
|
566
|
+
* @typeParam TState - The states the entity moves between.
|
|
567
|
+
* @typeParam TEvent - The events the entity accepts.
|
|
568
|
+
* @typeParam TContext - The fixture each row drives.
|
|
569
|
+
* @param options - The table, the fixture builder, the state reader, and the delay between rows.
|
|
570
|
+
* @returns The mounted harness, standing idle with its tally at zero.
|
|
571
|
+
* @throws An `Error` reading `Statechart harness mounted no transition` for an empty table, before
|
|
572
|
+
* anything reaches the document.
|
|
573
|
+
*
|
|
574
|
+
* @remarks
|
|
575
|
+
* A page cannot import this package, because the browser entry imports `vitest/browser` at module
|
|
576
|
+
* scope. So the harness is test-side: the suite mounts it, a gate outside the page polls the
|
|
577
|
+
* markup it renders, and `STATECHART_ATTRIBUTES` is the whole contract between the two. Nothing
|
|
578
|
+
* here spells a `data-statechart-*` string of its own, and neither does a gate. That gate has no
|
|
579
|
+
* rejection channel, so every exit writes a terminal status: a run that completes writes `passed` or
|
|
580
|
+
* `failed`, and a run that a `state` reader or a non-`Error` phase throw ends writes `failed` and
|
|
581
|
+
* then rejects with that value by identity, without counting the row as failed.
|
|
582
|
+
*
|
|
583
|
+
* The markup is framework-free. The root carries `status` and the tally; a `role="status"`
|
|
584
|
+
* announcer narrates each step in a sentence; one element carries `state` and renders what the
|
|
585
|
+
* entity's own reader reports; and an ordered list carries one row per scenario, each labelled with
|
|
586
|
+
* its `from`, its `event`, and its `to` and marked with the transition's name. The `state` element
|
|
587
|
+
* mounts empty and takes its attribute from the first row that produces a context, because a state
|
|
588
|
+
* is read from an entity and no entity exists until a row builds one.
|
|
589
|
+
*
|
|
590
|
+
* Construction writes `pending`, mounts the root, renders every row, then writes the row count and
|
|
591
|
+
* `idle` — so a gate that reads `pending` has found a harness whose rows never mounted, and the
|
|
592
|
+
* order is observable from outside through the mutations the document records.
|
|
593
|
+
*
|
|
594
|
+
* `execute` clears every rendered result and the rendered state, writes `running`, and drives each
|
|
595
|
+
* row in order through {@link executeScenario} against a context of that row's own. It continues
|
|
596
|
+
* past a failing row, so one run reports on the whole table rather than stopping at the first
|
|
597
|
+
* finding, and a builder that throws counts as its row failing under {@link buildRefusal}'s
|
|
598
|
+
* sentence, which is the one `executeScenarios` raises. What decides whether a row's phases run is
|
|
599
|
+
* whether its builder returned, not what it returned, so a table whose context is `undefined` drives
|
|
600
|
+
* every phase. A second `execute` runs the same table from a fresh tally and a cleared state.
|
|
601
|
+
*
|
|
602
|
+
* Every reading comes off the markup, so the object and the page cannot disagree, and `failures` is
|
|
603
|
+
* the `scenario` name of each row whose rendered `result` reads `failed` rather than a second list
|
|
604
|
+
* beside them.
|
|
605
|
+
*
|
|
606
|
+
* @example
|
|
607
|
+
* ```ts
|
|
608
|
+
* const harness = createHarness({ scenarios: SCENARIOS, build: buildDisclosure, state: readState })
|
|
609
|
+
* await harness.execute()
|
|
610
|
+
* harness.status // 'passed'
|
|
611
|
+
* harness.destroy()
|
|
612
|
+
* ```
|
|
613
|
+
*/
|
|
614
|
+
export declare function createHarness<TState extends string, TEvent extends string, TContext>(options: HarnessOptions<TState, TEvent, TContext>): HarnessInterface;
|
|
615
|
+
|
|
392
616
|
/**
|
|
393
617
|
* Creates the journal one scenario records its steps and the page's own output into.
|
|
394
618
|
*
|
|
@@ -470,6 +694,50 @@ export declare function createPointerEvent(name: string, options?: PointerEventI
|
|
|
470
694
|
*/
|
|
471
695
|
export declare function createPortfolio(options: PortfolioOptions): PortfolioInterface;
|
|
472
696
|
|
|
697
|
+
/**
|
|
698
|
+
* Creates an inert `Storage` a host can withhold, grant, and run out of room in.
|
|
699
|
+
*
|
|
700
|
+
* @param options - The seed, the read and write permissions, and the quota.
|
|
701
|
+
* @returns A store carrying the Web Storage surface plus the grant.
|
|
702
|
+
* @throws An `Error` when `quota` is not a non-negative safe integer. A quota above
|
|
703
|
+
* `Number.MAX_SAFE_INTEGER` carries the same sentence, because a counter that cannot decrement past
|
|
704
|
+
* that point bounds nothing.
|
|
705
|
+
*
|
|
706
|
+
* @remarks
|
|
707
|
+
* Conditions a real origin produces are unreachable from a test otherwise: a browser with
|
|
708
|
+
* site data blocked refuses every operation the permission withholds, an origin with no room left
|
|
709
|
+
* refuses `setItem`, and a person allowing site data grants what was withheld. This makes each of
|
|
710
|
+
* them reachable against a real `Storage` surface rather than a shaped object.
|
|
711
|
+
*
|
|
712
|
+
* The store answers through its methods and intercepts no named-property access, so drive a
|
|
713
|
+
* consumer under test through `getItem` and `setItem`. `Storage` declares an index signature, so
|
|
714
|
+
* `store.theme` typechecks and reads `undefined` while `getItem('theme')` answers, and a property
|
|
715
|
+
* write lands on the object rather than in the store, consuming no quota and meeting no refusal.
|
|
716
|
+
*
|
|
717
|
+
* It is backed by a map of its own and patches nothing: `localStorage` and `sessionStorage` are
|
|
718
|
+
* untouched, no `storage` event is dispatched, and the store is reached only by the code the test
|
|
719
|
+
* hands it to. Reach for {@link clearStorage} where the real browser surfaces are the subject.
|
|
720
|
+
*
|
|
721
|
+
* `length`, `key`, and `getItem` are reads; `clear`, `removeItem`, and `setItem` are writes. A
|
|
722
|
+
* withheld operation raises {@link buildDenial}'s `SecurityError`, and `permit` lifts both
|
|
723
|
+
* permissions at once, the way a person allowing site data lifts them. Reads answer from what the
|
|
724
|
+
* store actually accepted, so a journey reads what the application kept while the host was refusing.
|
|
725
|
+
*
|
|
726
|
+
* `quota` counts accepted `setItem` calls rather than bytes, because the number of writes is what a
|
|
727
|
+
* journey scripts and a byte budget is the browser's own arithmetic. `removeItem` consumes none of
|
|
728
|
+
* it, and `permit` replenishes none of it: room and permission are different refusals, and a test
|
|
729
|
+
* that granted the permission still meets the full origin.
|
|
730
|
+
*
|
|
731
|
+
* @example
|
|
732
|
+
* ```ts
|
|
733
|
+
* const storage = createStorage({ values: { theme: 'dark' }, writes: false })
|
|
734
|
+
* storage.getItem('theme') // 'dark'
|
|
735
|
+
* storage.permit()
|
|
736
|
+
* storage.setItem('theme', 'light')
|
|
737
|
+
* ```
|
|
738
|
+
*/
|
|
739
|
+
export declare function createStorage(options?: StorageOptions): WebStorageInterface;
|
|
740
|
+
|
|
473
741
|
/**
|
|
474
742
|
* Describes the order sequential keyboard navigation visits one element's controls in.
|
|
475
743
|
*
|
|
@@ -538,6 +806,25 @@ export declare interface ElementOptions {
|
|
|
538
806
|
readonly attributes?: Readonly<Record<string, string>>;
|
|
539
807
|
}
|
|
540
808
|
|
|
809
|
+
/**
|
|
810
|
+
* Holds detached markup a style-escape reading must find, and the one it must leave alone.
|
|
811
|
+
*
|
|
812
|
+
* @remarks
|
|
813
|
+
* `inline`, `embedded`, and `permitted` are the branches a style-escape reading has: an inline
|
|
814
|
+
* attribute, an embedded element, and the sheet a project deliberately allows. A reading that passes
|
|
815
|
+
* by refusing every `<style>` element clears the escapes and fails the exemption.
|
|
816
|
+
*/
|
|
817
|
+
export declare interface EscapeFixture {
|
|
818
|
+
/** Holds the detached root carrying the inline escape, the embedded escape, and the exempt sheet. */
|
|
819
|
+
readonly root: HTMLElement;
|
|
820
|
+
/** Holds the element carrying an inline `style` attribute. */
|
|
821
|
+
readonly inline: HTMLElement;
|
|
822
|
+
/** Holds the embedded `<style>` element. */
|
|
823
|
+
readonly embedded: HTMLElement;
|
|
824
|
+
/** Holds the `<style>` element carrying the exempt id the caller named. */
|
|
825
|
+
readonly permitted: HTMLElement;
|
|
826
|
+
}
|
|
827
|
+
|
|
541
828
|
/**
|
|
542
829
|
* Expands a capture registry across every variant into the filenames a complete portfolio holds.
|
|
543
830
|
*
|
|
@@ -726,6 +1013,75 @@ export declare interface FrameReading {
|
|
|
726
1013
|
readonly floor: string | undefined;
|
|
727
1014
|
}
|
|
728
1015
|
|
|
1016
|
+
/**
|
|
1017
|
+
* Holds a mounted statechart harness, the tally it publishes, and the run it drives.
|
|
1018
|
+
*
|
|
1019
|
+
* @remarks
|
|
1020
|
+
* Every reading comes off the mounted markup rather than out of a field beside it, so the object a
|
|
1021
|
+
* test asserts on and the attributes a gate polls cannot disagree. `status`, `total`, `passed`, and
|
|
1022
|
+
* `failed` read the root's own attributes, and `failures` reads the `scenario` name of every row
|
|
1023
|
+
* whose `result` reads `failed`, so no second list can drift from the rows.
|
|
1024
|
+
*
|
|
1025
|
+
* `root` is the mounted element, handed out so a test can read the markup a gate would read.
|
|
1026
|
+
* `failures` hands out a snapshot, so a list read mid-run stays what it was.
|
|
1027
|
+
*/
|
|
1028
|
+
export declare interface HarnessInterface {
|
|
1029
|
+
/** Holds the mounted root carrying the status, the tally, and every row. */
|
|
1030
|
+
readonly root: HTMLElement;
|
|
1031
|
+
/** Reports the run state the root announces. */
|
|
1032
|
+
readonly status: StatechartStatus;
|
|
1033
|
+
/** Reports how many rows the table declares. */
|
|
1034
|
+
readonly total: number;
|
|
1035
|
+
/** Reports how many rows the last run finished with a passing result. */
|
|
1036
|
+
readonly passed: number;
|
|
1037
|
+
/** Reports how many rows the last run finished with a failing result. */
|
|
1038
|
+
readonly failed: number;
|
|
1039
|
+
/** Lists the name of every row whose rendered result reads failed, in table order. */
|
|
1040
|
+
readonly failures: readonly string[];
|
|
1041
|
+
/**
|
|
1042
|
+
* Drives every row in table order, from a fresh tally and a cleared state.
|
|
1043
|
+
*
|
|
1044
|
+
* @returns A promise resolving after the last row settles and the terminal status is written.
|
|
1045
|
+
* @throws The value a `state` reader or a non-`Error` phase threw, by identity, after the harness
|
|
1046
|
+
* writes `failed`. Every exit is terminal, because the gate polling the markup has no rejection
|
|
1047
|
+
* channel to read.
|
|
1048
|
+
*/
|
|
1049
|
+
execute(): Promise<void>;
|
|
1050
|
+
/** Removes the mounted root, and does nothing when it is already removed. */
|
|
1051
|
+
destroy(): void;
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
/**
|
|
1055
|
+
* Configures the harness that renders one transition table and drives it row by row.
|
|
1056
|
+
*
|
|
1057
|
+
* @typeParam TState - The states the entity moves between, as a string-literal union.
|
|
1058
|
+
* @typeParam TEvent - The events the entity accepts, as a string-literal union.
|
|
1059
|
+
* @typeParam TContext - The fixture the three phases of each row drive.
|
|
1060
|
+
* @remarks
|
|
1061
|
+
* `scenarios` is the table in the order it renders and the order it runs, so the rows a reader sees
|
|
1062
|
+
* are the rows the run walks. `build` is called once per row, the way `executeScenarios` calls it,
|
|
1063
|
+
* so one table can mix fixtures and a row never inherits the entity the row before it left behind.
|
|
1064
|
+
*
|
|
1065
|
+
* `state` is the reader that puts the entity's current state on the page. It is called with the
|
|
1066
|
+
* row's own context after that row settles, pass or fail, so the rendered state is where the event
|
|
1067
|
+
* actually left the entity rather than where the row expected it. It is a reader rather than a
|
|
1068
|
+
* phase: a `state` that throws rejects the run after the harness writes `failed`, and the row it was
|
|
1069
|
+
* reading is not counted as failed.
|
|
1070
|
+
*
|
|
1071
|
+
* `pause` holds a delay between rows, for a table whose entity is worth watching. Omit it and the
|
|
1072
|
+
* rows run back to back.
|
|
1073
|
+
*/
|
|
1074
|
+
export declare interface HarnessOptions<TState extends string, TEvent extends string, TContext> {
|
|
1075
|
+
/** Holds the table to render and drive, in the order it is written. */
|
|
1076
|
+
readonly scenarios: ReadonlyArray<StateScenario<TState, TEvent, TContext>>;
|
|
1077
|
+
/** Builds the fixture one row drives, called once per row and awaited when it returns a promise. */
|
|
1078
|
+
readonly build: (scenario: StateScenario<TState, TEvent, TContext>) => TContext | Promise<TContext>;
|
|
1079
|
+
/** Reads the state the entity is in, for the element the harness renders it on. */
|
|
1080
|
+
readonly state: (context: TContext) => TState;
|
|
1081
|
+
/** Holds the delay in milliseconds the harness waits between rows. */
|
|
1082
|
+
readonly pause?: number;
|
|
1083
|
+
}
|
|
1084
|
+
|
|
729
1085
|
/**
|
|
730
1086
|
* Names the role a `th` carries for the header axis its `scope` names.
|
|
731
1087
|
*
|
|
@@ -777,8 +1133,9 @@ export declare function isOutsideViewport(rectangle: DOMRectReadOnly): boolean;
|
|
|
777
1133
|
*
|
|
778
1134
|
* @param element - The element to judge.
|
|
779
1135
|
* @returns True if the element is connected, visible, laid out with a non-zero box, in the
|
|
780
|
-
* sequential focus order, neither disabled nor marked `aria-disabled="true"`,
|
|
781
|
-
* `[inert]` subtree
|
|
1136
|
+
* sequential focus order, neither disabled nor marked `aria-disabled="true"`, outside every
|
|
1137
|
+
* `[inert]` subtree, and inside every shown `[aria-modal="true"]` element its document carries;
|
|
1138
|
+
* false otherwise.
|
|
782
1139
|
*
|
|
783
1140
|
* @remarks
|
|
784
1141
|
* This is the one reachability filter the layer applies. `resolveRendered`, `clickAccessibleWithin`,
|
|
@@ -790,6 +1147,29 @@ export declare function isOutsideViewport(rectangle: DOMRectReadOnly): boolean;
|
|
|
790
1147
|
* refuses it. Nothing here asks about the viewport: `resolveAccessible` scrolls a wholly
|
|
791
1148
|
* off-viewport target into view and measures that separately with {@link isOutsideViewport}.
|
|
792
1149
|
*
|
|
1150
|
+
* An open modal dialog takes the page behind it away, and the element's own facts cannot report
|
|
1151
|
+
* that: the covered control stays connected, laid out, focusable, and outside every `[inert]`
|
|
1152
|
+
* subtree while a pointer, a Tab, and a reader honouring `aria-modal` all stop at the dialog. So
|
|
1153
|
+
* this asks the document for its `[aria-modal="true"]` elements, puts each through
|
|
1154
|
+
* {@link isRendered}, and refuses the subject wherever a shown one does not contain it. A closed
|
|
1155
|
+
* dialog is hidden and excludes nothing, which is why the visibility reading is the announced one
|
|
1156
|
+
* rather than a bare `checkVisibility` call: a drawer parked at `visibility: hidden` is still laid
|
|
1157
|
+
* out. Nesting needs no separate rule, because an element inside the innermost dialog sits inside
|
|
1158
|
+
* every dialog around it.
|
|
1159
|
+
*
|
|
1160
|
+
* Containment follows the flat tree, so a subject inside a shadow tree is judged by its host chain
|
|
1161
|
+
* as well as itself and a dialog holding the host holds its shadow content too. Two arrangements
|
|
1162
|
+
* stay outside the read: a native `<dialog>` opened with `showModal` carries no `aria-modal`
|
|
1163
|
+
* attribute, and a dialog declared inside a shadow tree is not in what a document query returns.
|
|
1164
|
+
* Each leaves the page behind it reachable here.
|
|
1165
|
+
*
|
|
1166
|
+
* Inside a shadow tree it answers for the element's own facts, in an open root and a closed one
|
|
1167
|
+
* alike: the box, the focus order, `:disabled`, and `aria-disabled` are all the element's. The
|
|
1168
|
+
* `[inert]` ancestor is the one read that stops at the boundary, because `closest` never leaves the
|
|
1169
|
+
* element's own tree, so a host marked `[inert]` is invisible here. What the flat tree decides still
|
|
1170
|
+
* reaches the subject — a host the document does not lay out takes the element off the page and this
|
|
1171
|
+
* refuses it. Ask the host separately where an ancestor attribute is the subject.
|
|
1172
|
+
*
|
|
793
1173
|
* @example
|
|
794
1174
|
* ```ts
|
|
795
1175
|
* isReachable(requireValue(container.querySelector('button')))
|
|
@@ -816,6 +1196,13 @@ export declare function isReachable(element: Element): boolean;
|
|
|
816
1196
|
* for the box tree, and `visibility` inherits, so between them an ancestor cannot hide a control
|
|
817
1197
|
* from a reader and leave it standing in a description.
|
|
818
1198
|
*
|
|
1199
|
+
* Inside a shadow tree it answers for the element's own facts, in an open root and a closed one
|
|
1200
|
+
* alike. The `aria-hidden` ancestor is the one read that stops at the boundary, because `closest`
|
|
1201
|
+
* never leaves the element's own tree, so a host marked `aria-hidden="true"` is invisible here and
|
|
1202
|
+
* this reports `true` for a subject a reader is never told about. `checkVisibility` and the computed
|
|
1203
|
+
* `visibility` read the flat tree, so a host the document does not lay out still takes the element
|
|
1204
|
+
* off the page. Ask the host separately where an ancestor attribute is the subject.
|
|
1205
|
+
*
|
|
819
1206
|
* @example
|
|
820
1207
|
* ```ts
|
|
821
1208
|
* isRendered(requireValue(container.querySelector('[aria-hidden="true"] button'))) // false
|
|
@@ -1094,6 +1481,32 @@ export declare interface PortfolioOptions {
|
|
|
1094
1481
|
readonly enabled?: boolean;
|
|
1095
1482
|
}
|
|
1096
1483
|
|
|
1484
|
+
/**
|
|
1485
|
+
* Sends a key sequence to whatever holds focus, and refuses to send it to nothing.
|
|
1486
|
+
*
|
|
1487
|
+
* @param keys - The sequence in the provider's own key syntax, such as `{Enter}` or `{Escape}`.
|
|
1488
|
+
* @returns A promise resolving after every keystroke completes.
|
|
1489
|
+
* @throws When the document body holds focus, or nothing does.
|
|
1490
|
+
*
|
|
1491
|
+
* @remarks
|
|
1492
|
+
* The refusal is the whole of what this adds over `userEvent.keyboard`. A key sent while focus sits
|
|
1493
|
+
* on the body reaches no control, and every assertion after it reads the surface the key never
|
|
1494
|
+
* touched — which is the false green a guarded keyboard step exists to catch. Bring focus about
|
|
1495
|
+
* first through {@link traverseAccessible}, {@link clickAccessible}, or {@link typeAccessible}, and
|
|
1496
|
+
* send the sequence here.
|
|
1497
|
+
*
|
|
1498
|
+
* Escaping is the caller's, because the sequence is the subject: `{` opens a key name and `[` opens
|
|
1499
|
+
* a code name. Reach for {@link typeAccessible} where the text is the subject and the syntax is in
|
|
1500
|
+
* the way.
|
|
1501
|
+
*
|
|
1502
|
+
* @example
|
|
1503
|
+
* ```ts
|
|
1504
|
+
* await traverseAccessible('Evaluate')
|
|
1505
|
+
* await pressKeys('{Enter}')
|
|
1506
|
+
* ```
|
|
1507
|
+
*/
|
|
1508
|
+
export declare function pressKeys(keys: string): Promise<void>;
|
|
1509
|
+
|
|
1097
1510
|
/**
|
|
1098
1511
|
* Resolves the opaque color standing behind one element.
|
|
1099
1512
|
*
|
|
@@ -1148,6 +1561,33 @@ export declare function readBackdrop(element: Element, floor: Color): Color;
|
|
|
1148
1561
|
*/
|
|
1149
1562
|
export declare function readCascade(): ReadonlySet<string>;
|
|
1150
1563
|
|
|
1564
|
+
/**
|
|
1565
|
+
* Takes the authored-class census of one subtree against the cascade this document loaded.
|
|
1566
|
+
*
|
|
1567
|
+
* @param root - The subtree to walk. A detached element and a `DocumentFragment` both work.
|
|
1568
|
+
* @returns The population walked, every class token the markup carries, and every one of them no
|
|
1569
|
+
* loaded stylesheet declares; both lists sorted.
|
|
1570
|
+
* @throws An `Error` when the walk reads no element at all.
|
|
1571
|
+
*
|
|
1572
|
+
* @remarks
|
|
1573
|
+
* This is {@link readClasses} differenced against {@link readCascade}, with the population reported
|
|
1574
|
+
* beside the difference. The population is what makes the reading falsifiable: an empty walk
|
|
1575
|
+
* reports no undeclared token, and so does a subtree whose every class the cascade declares, so a
|
|
1576
|
+
* check reading `undeclared` alone passes for a census that read nothing. The empty walk is refused
|
|
1577
|
+
* outright for the same reason.
|
|
1578
|
+
*
|
|
1579
|
+
* The root counts when it is an `Element`, so a `DocumentFragment` contributes its descendants
|
|
1580
|
+
* alone. Both lists are sorted rather than left in sighting order, because a census is compared
|
|
1581
|
+
* against a previous one or against an expected list, and document order is not a fact about the
|
|
1582
|
+
* classes.
|
|
1583
|
+
*
|
|
1584
|
+
* @example
|
|
1585
|
+
* ```ts
|
|
1586
|
+
* readCensus(container).undeclared // ['lead'] — no loaded stylesheet declares it
|
|
1587
|
+
* ```
|
|
1588
|
+
*/
|
|
1589
|
+
export declare function readCensus(root: ParentNode): CensusReading;
|
|
1590
|
+
|
|
1151
1591
|
/**
|
|
1152
1592
|
* Collects every class token the markup under one root carries.
|
|
1153
1593
|
*
|
|
@@ -1424,6 +1864,49 @@ export declare function readPerception(name: string): string;
|
|
|
1424
1864
|
*/
|
|
1425
1865
|
export declare function readPixels(element: Element, property: string): number;
|
|
1426
1866
|
|
|
1867
|
+
/**
|
|
1868
|
+
* Reads the refusal one named target answers with, or nothing when it resolves.
|
|
1869
|
+
*
|
|
1870
|
+
* @param name - The target's exact accessible name.
|
|
1871
|
+
* @returns The refusal sentence {@link resolveRendered} raised, or `undefined` when it resolved.
|
|
1872
|
+
* @throws Whatever the resolver threw that is not an `Error`.
|
|
1873
|
+
*
|
|
1874
|
+
* @example
|
|
1875
|
+
* ```ts
|
|
1876
|
+
* readRefusal('Save changes') // undefined — the control resolves
|
|
1877
|
+
* readRefusal('Menu') // 'Interactive target "Menu" is not visible and focus-reachable'
|
|
1878
|
+
* ```
|
|
1879
|
+
*/
|
|
1880
|
+
export declare function readRefusal(name: string): string | undefined;
|
|
1881
|
+
|
|
1882
|
+
/**
|
|
1883
|
+
* Reads the refusal one named target answers with under an exact role, or nothing when it resolves.
|
|
1884
|
+
*
|
|
1885
|
+
* @param role - The target's exact ARIA role.
|
|
1886
|
+
* @param name - The target's exact accessible name.
|
|
1887
|
+
* @returns The refusal sentence {@link resolveRendered} raised, or `undefined` when it resolved.
|
|
1888
|
+
* @throws Whatever the resolver threw that is not an `Error`.
|
|
1889
|
+
*
|
|
1890
|
+
* @remarks
|
|
1891
|
+
* Absent, present-but-gated, and ambiguous are different findings about an interface, and the
|
|
1892
|
+
* layer keeps their sentences distinct, so a journey asserting on the one it means needs the
|
|
1893
|
+
* sentence rather than a boolean. This fixes the resolver, translates the `unknown` a `catch` binds
|
|
1894
|
+
* into `string | undefined`, and rethrows anything that is not an `Error` — a value no resolver
|
|
1895
|
+
* raises, and one a caller reading a message would otherwise lose. `undefined` is rethrown with the
|
|
1896
|
+
* rest: a resolver that returned and a hostile getter that threw `undefined` are different findings,
|
|
1897
|
+
* which is why the `catch` is this function's own rather than a captured thrown value.
|
|
1898
|
+
*
|
|
1899
|
+
* It resolves rather than acts, so a target it reports `undefined` for is one an acting verb
|
|
1900
|
+
* reaches. Assert on the exact sentence: a comparison against a substring passes for a refusal
|
|
1901
|
+
* about a different condition.
|
|
1902
|
+
*
|
|
1903
|
+
* @example
|
|
1904
|
+
* ```ts
|
|
1905
|
+
* readRefusal('tab', 'Drafts') // undefined — the tab resolves under its role
|
|
1906
|
+
* ```
|
|
1907
|
+
*/
|
|
1908
|
+
export declare function readRefusal(role: string, name: string): string | undefined;
|
|
1909
|
+
|
|
1427
1910
|
/**
|
|
1428
1911
|
* Measures the contrast the focus chrome painted on one control reaches against its own backdrop.
|
|
1429
1912
|
*
|
|
@@ -1868,6 +2351,42 @@ export declare function resolveRendered(first: string, second?: string): HTMLEle
|
|
|
1868
2351
|
*/
|
|
1869
2352
|
export declare function stagePane(width: number, height: number): Promise<void>;
|
|
1870
2353
|
|
|
2354
|
+
/**
|
|
2355
|
+
* Configures a bounded wait over the states a control announces.
|
|
2356
|
+
*
|
|
2357
|
+
* @remarks
|
|
2358
|
+
* The direction is a boolean because a state is either announced or it is not, and both directions
|
|
2359
|
+
* are the same wait over the same reading. The time bounds and the abort signal come from
|
|
2360
|
+
* {@link WaitOptions} and mean there what they mean everywhere else.
|
|
2361
|
+
*/
|
|
2362
|
+
export declare interface StateOptions extends WaitOptions {
|
|
2363
|
+
/** Determines the direction: `true` waits until the state is gone, `false` until it appears. */
|
|
2364
|
+
readonly absent?: boolean;
|
|
2365
|
+
}
|
|
2366
|
+
|
|
2367
|
+
/**
|
|
2368
|
+
* Configures an inert `Storage`: its seed, which operations the host permits, and its quota.
|
|
2369
|
+
*
|
|
2370
|
+
* @remarks
|
|
2371
|
+
* Every member describes a condition a real origin produces. A withheld read or write is what a
|
|
2372
|
+
* browser with site data blocked raises from the storage object, and a quota is what an origin with
|
|
2373
|
+
* no room left raises from `setItem`. Omit a member and the store behaves as an ordinary origin
|
|
2374
|
+
* does: seeded with nothing, permitting everything, and bounded by nothing.
|
|
2375
|
+
*/
|
|
2376
|
+
export declare interface StorageOptions {
|
|
2377
|
+
/** Holds the entries the store starts with, keyed by storage key. */
|
|
2378
|
+
readonly values?: Readonly<Record<string, string>>;
|
|
2379
|
+
/** Determines whether the host permits reads. Default: `true`. */
|
|
2380
|
+
readonly reads?: boolean;
|
|
2381
|
+
/** Determines whether the host permits writes. Default: `true`. */
|
|
2382
|
+
readonly writes?: boolean;
|
|
2383
|
+
/**
|
|
2384
|
+
* Caps the accepted `setItem` calls, as a non-negative safe integer. When omitted, nothing bounds
|
|
2385
|
+
* the store.
|
|
2386
|
+
*/
|
|
2387
|
+
readonly quota?: number;
|
|
2388
|
+
}
|
|
2389
|
+
|
|
1871
2390
|
/**
|
|
1872
2391
|
* Reaches a named control only through natural forward Tab traversal from the current focus.
|
|
1873
2392
|
*
|
|
@@ -1925,6 +2444,43 @@ export declare function typeAccessible(name: string, text: string): Promise<void
|
|
|
1925
2444
|
*/
|
|
1926
2445
|
export declare function typeInput(element: HTMLInputElement | HTMLTextAreaElement, text: string): void;
|
|
1927
2446
|
|
|
2447
|
+
/**
|
|
2448
|
+
* Waits until every finite animation on one element and its subtree has stopped moving.
|
|
2449
|
+
*
|
|
2450
|
+
* @param element - The element whose own animations and descendants' animations to wait on.
|
|
2451
|
+
* @param options - The time bounds and the abort signal.
|
|
2452
|
+
* @returns A promise resolving once no finite animation is still running.
|
|
2453
|
+
* @throws An `Error` when the element is not in a document, when a bound is invalid, or when an
|
|
2454
|
+
* animation is still running at the budget; or the abort reason.
|
|
2455
|
+
*
|
|
2456
|
+
* @remarks
|
|
2457
|
+
* A reading taken while paint is moving reports an interpolated frame — a `background-color` at a
|
|
2458
|
+
* fraction of its alpha, a `color` part way between two values — that no state of the interface
|
|
2459
|
+
* ever paints. This waits for the paint a person sees, whichever state it settles in.
|
|
2460
|
+
*
|
|
2461
|
+
* It parks on each animation's own `finished` promise rather than re-reading on a timer, and reads
|
|
2462
|
+
* the list again after each completion or cancellation, so an animation a finishing one starts is
|
|
2463
|
+
* waited on too.
|
|
2464
|
+
*
|
|
2465
|
+
* Some animations are left out, and each exclusion is a decision rather than an oversight. An animation
|
|
2466
|
+
* whose effect declares infinite iterations never finishes, so a spinner that runs forever is a
|
|
2467
|
+
* finding about the reading rather than a wait to lengthen. A finished animation filling its target
|
|
2468
|
+
* stays in the list a browser reports and is already at rest. A paused animation is at rest too,
|
|
2469
|
+
* and nothing here resumes it.
|
|
2470
|
+
*
|
|
2471
|
+
* The bounds are the wait family's, validated the same way. Default budget: `1000` milliseconds.
|
|
2472
|
+
* The interval is validated for consistency with the family and is not used, because this parks on
|
|
2473
|
+
* the animations. A detached element is refused rather than reported settled, because an element in
|
|
2474
|
+
* no document runs no animation and would answer `true` to every wait.
|
|
2475
|
+
*
|
|
2476
|
+
* @example
|
|
2477
|
+
* ```ts
|
|
2478
|
+
* await clickAccessible('Dark')
|
|
2479
|
+
* await waitForAnimations(document.body)
|
|
2480
|
+
* ```
|
|
2481
|
+
*/
|
|
2482
|
+
export declare function waitForAnimations(element: Element, options?: WaitOptions): Promise<void>;
|
|
2483
|
+
|
|
1928
2484
|
/**
|
|
1929
2485
|
* Waits for one animation frame to settle pending browser paint work.
|
|
1930
2486
|
*
|
|
@@ -1937,4 +2493,75 @@ export declare function typeInput(element: HTMLInputElement | HTMLTextAreaElemen
|
|
|
1937
2493
|
*/
|
|
1938
2494
|
export declare function waitForFrame(): Promise<void>;
|
|
1939
2495
|
|
|
2496
|
+
/**
|
|
2497
|
+
* Waits until one named control announces a state, or stops announcing it.
|
|
2498
|
+
*
|
|
2499
|
+
* @param name - The control's exact accessible name.
|
|
2500
|
+
* @param state - The state, spelled as {@link readStates} reports it.
|
|
2501
|
+
* @param options - The time bounds, the abort signal, and the direction.
|
|
2502
|
+
* @returns The states the control announced when the wait resolved.
|
|
2503
|
+
* @throws The resolver's own refusal, the abort reason, or an `Error` when a bound is invalid or
|
|
2504
|
+
* the state is not reached within the budget.
|
|
2505
|
+
*
|
|
2506
|
+
* @example
|
|
2507
|
+
* ```ts
|
|
2508
|
+
* await clickAccessible('Pin note')
|
|
2509
|
+
* await waitForState('Pin note', 'pressed=true')
|
|
2510
|
+
* ```
|
|
2511
|
+
*/
|
|
2512
|
+
export declare function waitForState(name: string, state: string, options?: StateOptions): Promise<readonly string[]>;
|
|
2513
|
+
|
|
2514
|
+
/**
|
|
2515
|
+
* Waits until one control of an exact role announces a state, or stops announcing it.
|
|
2516
|
+
*
|
|
2517
|
+
* @param role - The control's exact ARIA role.
|
|
2518
|
+
* @param name - The control's exact accessible name.
|
|
2519
|
+
* @param state - The state, spelled as {@link readStates} reports it.
|
|
2520
|
+
* @param options - The time bounds, the abort signal, and the direction.
|
|
2521
|
+
* @returns The states the control announced when the wait resolved.
|
|
2522
|
+
* @throws The resolver's own refusal, the abort reason, or an `Error` when a bound is invalid or
|
|
2523
|
+
* the state is not reached within the budget.
|
|
2524
|
+
*
|
|
2525
|
+
* @remarks
|
|
2526
|
+
* The control is resolved afresh on every reading, because a framework replaces the node between
|
|
2527
|
+
* one render and the next: the subject is the role and the name, never one element. That also means
|
|
2528
|
+
* the resolver's own voices reach the caller unchanged — a control that leaves the document
|
|
2529
|
+
* mid-wait refuses as absent rather than timing out as unannounced, which is the more useful
|
|
2530
|
+
* finding.
|
|
2531
|
+
*
|
|
2532
|
+
* {@link waitForCondition} owns the poll, so the bounds and the abort reason are that helper's.
|
|
2533
|
+
* Default budget: `1000` milliseconds. Default interval: `10` milliseconds. The exhaustion message
|
|
2534
|
+
* names the control and the state, and carries the last states read, so a wait that ran out says
|
|
2535
|
+
* what the control was announcing instead.
|
|
2536
|
+
*
|
|
2537
|
+
* This is the published replacement for a settle keyed to a framework's own class names. Where a
|
|
2538
|
+
* surface announces nothing, the finding is the surface's: give the control its `aria-expanded`,
|
|
2539
|
+
* `aria-pressed`, or `aria-busy` rather than reading the classes a stylesheet happens to use.
|
|
2540
|
+
*
|
|
2541
|
+
* @example
|
|
2542
|
+
* ```ts
|
|
2543
|
+
* await clickDisclosure('Advanced')
|
|
2544
|
+
* await waitForState('button', 'Advanced', 'collapsed', { absent: true })
|
|
2545
|
+
* ```
|
|
2546
|
+
*/
|
|
2547
|
+
export declare function waitForState(role: string, name: string, state: string, options?: StateOptions): Promise<readonly string[]>;
|
|
2548
|
+
|
|
2549
|
+
/**
|
|
2550
|
+
* Holds a store the host can withhold and later grant.
|
|
2551
|
+
*
|
|
2552
|
+
* @remarks
|
|
2553
|
+
* The name carries `Web` because `@orkestrel/database` owns `StorageInterface` for the operations a
|
|
2554
|
+
* driver's transaction scope offers, and the fleet gives one bare exported name one owning package.
|
|
2555
|
+
* This one is the Web Storage surface a browser publishes on `localStorage`, plus the grant a
|
|
2556
|
+
* person allowing site data performs.
|
|
2557
|
+
*
|
|
2558
|
+
* `Storage` declares an index signature, so `store.theme` typechecks against this type. A store
|
|
2559
|
+
* `createStorage` returns answers through its methods alone and intercepts no named-property
|
|
2560
|
+
* access, so drive a consumer under test through `getItem` and `setItem`.
|
|
2561
|
+
*/
|
|
2562
|
+
export declare interface WebStorageInterface extends Storage {
|
|
2563
|
+
/** Grants the reads and the writes the host withheld, and replenishes no quota. */
|
|
2564
|
+
permit(): void;
|
|
2565
|
+
}
|
|
2566
|
+
|
|
1940
2567
|
export { }
|