foldkit 0.45.0 → 0.46.1

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.
@@ -1,4 +1,4 @@
1
- import { Array, Equal, Match, Option, Predicate, Record, String as String_, flow, pipe, } from 'effect';
1
+ import { Array, Equal, Match, Number as Number_, Option, Predicate, Record, String as String_, flow, pipe, } from 'effect';
2
2
  import { dual } from 'effect/Function';
3
3
  import { evo } from '../struct';
4
4
  const ID_PATTERN = /^#([a-zA-Z0-9_-]+)/;
@@ -55,7 +55,7 @@ export const parseSelector = (input) => {
55
55
  };
56
56
  // NODE UTILITIES
57
57
  const lookupAttribute = (name) => (vnode) => pipe(vnode.data?.attrs?.[name], Option.fromNullable, Option.orElse(() => Option.fromNullable(vnode.data?.props?.[name])));
58
- const lookupStringAttribute = (name) => (vnode) => Option.map(lookupAttribute(name)(vnode), String);
58
+ const lookupStringAttribute = (name) => (vnode) => pipe(vnode, lookupAttribute(name), Option.map(String));
59
59
  const isElement = (node) => !Predicate.isUndefined(node.sel);
60
60
  const isVNode = (child) => !Predicate.isString(child);
61
61
  const vnodeChildren = (vnode) => Array.filterMap(vnode.children ?? [], Option.liftPredicate(isVNode));
@@ -63,9 +63,32 @@ const collectDescendants = (vnode) => Array.flatMap(vnodeChildren(vnode), child
63
63
  child,
64
64
  ...collectDescendants(child),
65
65
  ]);
66
+ const allNodesIn = (vnode) => [
67
+ vnode,
68
+ ...collectDescendants(vnode),
69
+ ];
70
+ /** Returns the ancestor chain of `target` within `root`, ordered from root to
71
+ * the immediate parent of `target` (exclusive). Returns an empty array when
72
+ * `target` is `root` itself or is not present in the subtree. */
73
+ export const ancestorsOf = (root, target) => {
74
+ const walk = (node, chain) => {
75
+ if (node === target) {
76
+ return chain;
77
+ }
78
+ for (const child of vnodeChildren(node)) {
79
+ const result = walk(child, [...chain, node]);
80
+ if (result !== undefined) {
81
+ return result;
82
+ }
83
+ }
84
+ return undefined;
85
+ };
86
+ return walk(root, []) ?? [];
87
+ };
88
+ const attributeEquals = (name, expected) => (vnode) => pipe(vnode, lookupStringAttribute(name), Option.exists(Equal.equals(expected)));
66
89
  const FORM_CONTROL_TAGS = ['input', 'select', 'textarea', 'button', 'output'];
67
90
  const isFormControl = (node) => pipe(node.sel, Option.fromNullable, Option.exists(sel => Array.contains(FORM_CONTROL_TAGS, sel)));
68
- const findById = (root) => (id) => Array.findFirst([root, ...collectDescendants(root)], flow(lookupStringAttribute('id'), Option.exists(Equal.equals(id))));
91
+ const findById = (root) => (id) => Array.findFirst(allNodesIn(root), attributeEquals('id', id));
69
92
  // MATCHING
70
93
  const compareByMode = (mode, expected) => (actual) => Match.value(mode).pipe(Match.when('StartsWith', () => actual.startsWith(expected)), Match.when('Exact', () => actual === expected), Match.exhaustive);
71
94
  const matchesValue = (maybeExpected, mode) => (maybeActual) => Option.match(maybeActual, {
@@ -124,21 +147,32 @@ const INPUT_TYPE_ROLE_MAP = {
124
147
  };
125
148
  const inputRole = (vnode) => pipe(vnode, lookupStringAttribute('type'), Option.getOrElse(() => 'text'), Option.liftPredicate(typeString => typeString !== 'hidden'), Option.map(typeString => pipe(INPUT_TYPE_ROLE_MAP, Record.get(typeString), Option.getOrElse(() => 'textbox'))));
126
149
  const implicitRole = (vnode) => pipe(vnode.sel, Option.fromNullable, Option.flatMap(tag => tag === 'input' ? inputRole(vnode) : Record.get(IMPLICIT_ROLE_MAP, tag)));
127
- const resolveRole = (vnode) => pipe(vnode, lookupStringAttribute('role'), Option.orElse(() => implicitRole(vnode)));
150
+ const resolveRoles = (vnode) => pipe(vnode, lookupStringAttribute('role'), Option.map(flow(String_.split(WHITESPACE_PATTERN), Array.filter(String_.isNonEmpty))), Option.orElse(() => Option.map(implicitRole(vnode), Array.of)), Option.getOrElse(() => []));
128
151
  // ACCESSIBLE NAME
129
152
  const nonEmptyString = (value) => Option.filter(Option.some(String(value)), String_.isNonEmpty);
130
153
  const nameFromLabelledBy = (root) => (vnode) => pipe(vnode, lookupAttribute('aria-labelledby'), Option.flatMap(nonEmptyString), Option.map(labelledBy => pipe(labelledBy, String_.split(WHITESPACE_PATTERN), Array.filterMap(flow(findById(root), Option.map(textContent))), Array.join(' '))), Option.filter(String_.isNonEmpty));
131
154
  const nameFromAriaLabel = (vnode) => pipe(vnode, lookupAttribute('aria-label'), Option.flatMap(nonEmptyString));
132
- const nameFromLabelFor = (vnode, root) => pipe(vnode, lookupStringAttribute('id'), Option.flatMap(idString => pipe([root, ...collectDescendants(root)], Array.findFirst(node => node.sel === 'label' &&
155
+ const nameFromLabelFor = (root) => (vnode) => pipe(vnode, lookupStringAttribute('id'), Option.flatMap(idString => pipe(allNodesIn(root), Array.findFirst(node => node.sel === 'label' &&
133
156
  pipe(node, lookupStringAttribute('for'), Option.exists(Equal.equals(idString)))), Option.map(textContent))));
134
157
  const nameFromTextContent = (vnode) => Option.filter(Option.some(textContent(vnode)), String_.isNonEmpty);
135
158
  const nameFromTitle = (vnode) => pipe(vnode, lookupAttribute('title'), Option.flatMap(nonEmptyString));
136
- const accessibleName = (vnode, root) => pipe(vnode, nameFromLabelledBy(root), Option.orElse(() => nameFromAriaLabel(vnode)), Option.orElse(() => nameFromLabelFor(vnode, root)), Option.orElse(() => nameFromTextContent(vnode)), Option.orElse(() => nameFromTitle(vnode)), Option.getOrElse(() => ''));
159
+ /** Computes the accessible name of an element. Resolves via
160
+ * `aria-labelledby`, `aria-label`, `<label for>`, text content, then `title`. */
161
+ export const accessibleName = (root) => (vnode) => pipe(vnode, nameFromLabelledBy(root), Option.orElse(() => nameFromAriaLabel(vnode)), Option.orElse(() => nameFromLabelFor(root)(vnode)), Option.orElse(() => nameFromTextContent(vnode)), Option.orElse(() => nameFromTitle(vnode)), Option.getOrElse(() => ''));
162
+ /** Computes the accessible description of an element. Resolves via
163
+ * `aria-describedby` (joining referenced elements' text content). */
164
+ export const accessibleDescription = (root) => (vnode) => pipe(vnode, lookupAttribute('aria-describedby'), Option.flatMap(nonEmptyString), Option.match({
165
+ onNone: () => '',
166
+ onSome: flow(String_.split(WHITESPACE_PATTERN), Array.filterMap(flow(findById(root), Option.map(textContent))), Array.join(' ')),
167
+ }));
137
168
  // PUBLIC API
138
169
  const findAllImpl = (selectorString) => (html) => {
139
170
  const selector = parseSelector(selectorString);
140
- const allNodes = [html, ...collectDescendants(html)];
141
- return pipe(Array.head(selector), Option.map(firstSegment => Array.reduce(Array.drop(selector, 1), Array.filter(allNodes, matchesSimpleSelector(firstSegment)), (candidates, segment) => Array.filter(Array.flatMap(candidates, collectDescendants), matchesSimpleSelector(segment)))), Option.getOrElse(() => []));
171
+ const allNodes = allNodesIn(html);
172
+ return pipe(selector, Array.head, Option.match({
173
+ onNone: () => [],
174
+ onSome: firstSegment => Array.reduce(Array.drop(selector, 1), Array.filter(allNodes, matchesSimpleSelector(firstSegment)), (candidates, segment) => Array.filter(Array.flatMap(candidates, collectDescendants), matchesSimpleSelector(segment))),
175
+ }));
142
176
  };
143
177
  /** Finds the first VNode matching the CSS selector. */
144
178
  export const find = dual(2, (html, selectorString) => pipe(html, findAllImpl(selectorString), Array.head));
@@ -159,23 +193,77 @@ const attrImpl = (vnode, name) => {
159
193
  /** Reads an attribute or prop value from a VNode. */
160
194
  export const attr = dual(2, attrImpl);
161
195
  // ACCESSIBLE LOCATORS
162
- /** Finds the first element with the given ARIA role and optional accessible name. */
196
+ const HEADING_LEVEL_PATTERN = /^h([1-6])$/;
197
+ const headingLevelFromTag = (vnode) => pipe(vnode.sel, Option.fromNullable, Option.flatMap(String_.match(HEADING_LEVEL_PATTERN)), Option.map(match => Number(match[1])));
198
+ const ariaLevel = (vnode) => pipe(vnode, lookupStringAttribute('aria-level'), Option.flatMap(Number_.parse), Option.filter(value => !Number.isNaN(value)));
199
+ const resolveLevel = (vnode) => Option.orElse(ariaLevel(vnode), () => headingLevelFromTag(vnode));
200
+ const ariaTriStateMatches = (attribute, expected) => (vnode) => pipe(vnode, lookupStringAttribute(attribute), Option.exists(value => value === String(expected)));
201
+ const checkedMatches = (expected) => (vnode) => {
202
+ const fromAria = ariaTriStateMatches('aria-checked', expected)(vnode);
203
+ if (fromAria)
204
+ return true;
205
+ if (expected === 'mixed')
206
+ return false;
207
+ return pipe(vnode, lookupAttribute('checked'), Option.exists(value => Boolean(value) === expected));
208
+ };
209
+ const selectedMatches = (expected) => (vnode) => {
210
+ const fromAria = ariaTriStateMatches('aria-selected', expected)(vnode);
211
+ if (fromAria)
212
+ return true;
213
+ return pipe(vnode, lookupAttribute('selected'), Option.exists(value => Boolean(value) === expected));
214
+ };
215
+ const disabledMatches = (expected) => (vnode) => {
216
+ const ariaValue = lookupStringAttribute('aria-disabled')(vnode);
217
+ if (Option.isSome(ariaValue)) {
218
+ return ariaValue.value === String(expected);
219
+ }
220
+ const disabled = pipe(vnode, lookupAttribute('disabled'), Option.exists(Boolean));
221
+ return disabled === expected;
222
+ };
223
+ const roleOptionsMatch = (options, html) => (node) => {
224
+ if (!options)
225
+ return true;
226
+ if (options.name !== undefined &&
227
+ accessibleName(html)(node) !== options.name) {
228
+ return false;
229
+ }
230
+ if (options.level !== undefined &&
231
+ !Option.exists(resolveLevel(node), Equal.equals(options.level))) {
232
+ return false;
233
+ }
234
+ if (options.checked !== undefined &&
235
+ !checkedMatches(options.checked)(node)) {
236
+ return false;
237
+ }
238
+ if (options.selected !== undefined &&
239
+ !selectedMatches(options.selected)(node)) {
240
+ return false;
241
+ }
242
+ if (options.pressed !== undefined &&
243
+ !ariaTriStateMatches('aria-pressed', options.pressed)(node)) {
244
+ return false;
245
+ }
246
+ if (options.expanded !== undefined &&
247
+ !ariaTriStateMatches('aria-expanded', options.expanded)(node)) {
248
+ return false;
249
+ }
250
+ if (options.disabled !== undefined &&
251
+ !disabledMatches(options.disabled)(node)) {
252
+ return false;
253
+ }
254
+ return true;
255
+ };
256
+ /** Finds the first element with the given ARIA role and optional matching options.
257
+ * Supports `name` (accessible name), `level` (heading level), `checked`,
258
+ * `selected`, `pressed`, `expanded`, and `disabled` state filters. */
163
259
  export const getByRole = (role, options) => (html) => {
164
- const maybeName = Option.fromNullable(options?.name);
165
- return Array.findFirst([html, ...collectDescendants(html)], node => pipe(node, resolveRole, Option.exists(Equal.equals(role))) &&
166
- Option.match(maybeName, {
167
- onNone: () => true,
168
- onSome: name => accessibleName(node, html) === name,
169
- }));
170
- };
171
- /** Finds all elements with the given ARIA role and optional accessible name. */
172
- export const getAllByRole = (html, role, options) => {
173
- const maybeName = Option.fromNullable(options?.name);
174
- return Array.filter([html, ...collectDescendants(html)], node => pipe(node, resolveRole, Option.exists(Equal.equals(role))) &&
175
- Option.match(maybeName, {
176
- onNone: () => true,
177
- onSome: Equal.equals(accessibleName(node, html)),
178
- }));
260
+ const matchesOptions = roleOptionsMatch(options, html);
261
+ return Array.findFirst(allNodesIn(html), node => Array.contains(resolveRoles(node), role) && matchesOptions(node));
262
+ };
263
+ /** Finds all elements with the given ARIA role and optional matching options. */
264
+ export const getAllByRole = (role, options) => (html) => {
265
+ const matchesOptions = roleOptionsMatch(options, html);
266
+ return Array.filter(allNodesIn(html), node => Array.contains(resolveRoles(node), role) && matchesOptions(node));
179
267
  };
180
268
  /** Finds the most specific element matching the given text content.
181
269
  * Skips text VNodes (sel undefined) — only returns actual DOM elements. */
@@ -185,27 +273,102 @@ export const getByText = (target, options) => (html) => {
185
273
  const nodeText = textContent(node);
186
274
  return exact ? nodeText === target : String_.includes(target)(nodeText);
187
275
  };
188
- return pipe([html, ...collectDescendants(html)], Array.filter(node => isElement(node) && textMatches(node)), Array.findFirst(match => !Array.some(Array.filter(collectDescendants(match), isElement), textMatches)));
276
+ return pipe(allNodesIn(html), Array.filter(node => isElement(node) && textMatches(node)), Array.findFirst(match => !Array.some(Array.filter(collectDescendants(match), isElement), textMatches)));
189
277
  };
190
278
  /** Finds the first element with the given placeholder attribute. */
191
- export const getByPlaceholder = (placeholderValue) => (html) => Array.findFirst([html, ...collectDescendants(html)], flow(lookupStringAttribute('placeholder'), Option.exists(Equal.equals(placeholderValue))));
279
+ export const getByPlaceholder = (placeholderValue) => (html) => Array.findFirst(allNodesIn(html), attributeEquals('placeholder', placeholderValue));
192
280
  /** Finds the first element with the given label text. Checks `aria-label`
193
281
  * first, then `<label for="id">` association, then `<label>` nesting,
194
282
  * then `aria-labelledby` reverse lookup. */
195
283
  export const getByLabel = (labelValue) => (html) => {
196
- const allNodes = [html, ...collectDescendants(html)];
197
- return pipe(Array.findFirst(allNodes, flow(lookupStringAttribute('aria-label'), Option.exists(Equal.equals(labelValue)))), Option.orElse(() => pipe(Array.filter(allNodes, node => node.sel === 'label' && textContent(node) === labelValue), Array.filterMap(labelNode => pipe(lookupStringAttribute('for')(labelNode), Option.flatMap(findById(html)), Option.orElse(() => Array.findFirst(collectDescendants(labelNode), isFormControl)))), Array.head)), Option.orElse(() => Array.findFirst(allNodes, flow(nameFromLabelledBy(html), Option.exists(Equal.equals(labelValue))))));
284
+ const allNodes = allNodesIn(html);
285
+ return pipe(Array.findFirst(allNodes, attributeEquals('aria-label', labelValue)), Option.orElse(() => pipe(Array.filter(allNodes, node => node.sel === 'label' && textContent(node) === labelValue), Array.filterMap(labelNode => pipe(lookupStringAttribute('for')(labelNode), Option.flatMap(findById(html)), Option.orElse(() => Array.findFirst(collectDescendants(labelNode), isFormControl)))), Array.head)), Option.orElse(() => Array.findFirst(allNodes, flow(nameFromLabelledBy(html), Option.exists(Equal.equals(labelValue))))));
286
+ };
287
+ /** Finds every element with the given label text. Applies the same four
288
+ * resolution strategies as `getByLabel` (`aria-label`, `<label for="id">`,
289
+ * `<label>` nesting, `aria-labelledby`) and returns deduplicated matches. */
290
+ export const getAllByLabel = (labelValue) => (html) => {
291
+ const allNodes = allNodesIn(html);
292
+ const viaAriaLabel = Array.filter(allNodes, attributeEquals('aria-label', labelValue));
293
+ const viaLabelElement = pipe(Array.filter(allNodes, node => node.sel === 'label' && textContent(node) === labelValue), Array.flatMap(labelNode => pipe(lookupStringAttribute('for')(labelNode), Option.flatMap(findById(html)), Option.match({
294
+ onNone: () => Array.filter(collectDescendants(labelNode), isFormControl),
295
+ onSome: control => [control],
296
+ }))));
297
+ const viaLabelledBy = Array.filter(allNodes, flow(nameFromLabelledBy(html), Option.exists(Equal.equals(labelValue))));
298
+ return Array.dedupe([...viaAriaLabel, ...viaLabelElement, ...viaLabelledBy]);
299
+ };
300
+ /** Finds the first element with the given `alt` attribute. */
301
+ export const getByAltText = (altValue) => (html) => Array.findFirst(allNodesIn(html), attributeEquals('alt', altValue));
302
+ /** Finds the first element with the given `title` attribute. */
303
+ export const getByTitle = (titleValue) => (html) => Array.findFirst(allNodesIn(html), attributeEquals('title', titleValue));
304
+ /** Finds the first element with the given `data-testid` attribute. */
305
+ export const getByTestId = (testIdValue) => (html) => Array.findFirst(allNodesIn(html), attributeEquals('data-testid', testIdValue));
306
+ /** Finds all elements matching the given text content.
307
+ * Includes nested ancestors — a `<div><p>hi</p></div>` with text "hi" yields both. */
308
+ export const getAllByText = (target, options) => (html) => {
309
+ const exact = options?.exact !== false;
310
+ return Array.filter(allNodesIn(html), node => {
311
+ if (!isElement(node))
312
+ return false;
313
+ const nodeText = textContent(node);
314
+ return exact ? nodeText === target : String_.includes(target)(nodeText);
315
+ });
198
316
  };
317
+ /** Finds all elements with the given placeholder attribute. */
318
+ export const getAllByPlaceholder = (placeholderValue) => (html) => Array.filter(allNodesIn(html), attributeEquals('placeholder', placeholderValue));
319
+ /** Finds all elements with the given `alt` attribute. */
320
+ export const getAllByAltText = (altValue) => (html) => Array.filter(allNodesIn(html), attributeEquals('alt', altValue));
321
+ /** Finds all elements with the given `title` attribute. */
322
+ export const getAllByTitle = (titleValue) => (html) => Array.filter(allNodesIn(html), attributeEquals('title', titleValue));
323
+ /** Finds all elements with the given `data-testid` attribute. */
324
+ export const getAllByTestId = (testIdValue) => (html) => Array.filter(allNodesIn(html), attributeEquals('data-testid', testIdValue));
325
+ /** Finds all form controls whose current value matches. */
326
+ export const getAllByDisplayValue = (displayValueString) => (html) => Array.filter(allNodesIn(html), node => isFormControl(node) &&
327
+ attributeEquals('value', displayValueString)(node));
328
+ /** Finds the first form control whose current value matches. Checks the `value`
329
+ * attribute on inputs, textareas, and selects. */
330
+ export const getByDisplayValue = (displayValue) => (html) => Array.findFirst(allNodesIn(html), node => isFormControl(node) && attributeEquals('value', displayValue)(node));
199
331
  const makeLocator = (resolve, description) => Object.assign(resolve, { description });
200
- /** Creates a Locator that finds an element by ARIA role and optional accessible name. */
201
- export const role = (roleValue, options) => makeLocator(getByRole(roleValue, options), Option.match(Option.fromNullable(options?.name), {
202
- onNone: () => roleValue,
203
- onSome: name => `${roleValue} "${name}"`,
204
- }));
332
+ const makeLocatorAll = (resolve, description) => Object.assign(resolve, { description });
333
+ const describeRoleOptions = (options) => {
334
+ const parts = [];
335
+ if (options.name !== undefined)
336
+ parts.push(`"${options.name}"`);
337
+ if (options.level !== undefined)
338
+ parts.push(`level=${options.level}`);
339
+ if (options.checked !== undefined)
340
+ parts.push(`checked=${options.checked}`);
341
+ if (options.selected !== undefined)
342
+ parts.push(`selected=${options.selected}`);
343
+ if (options.pressed !== undefined)
344
+ parts.push(`pressed=${options.pressed}`);
345
+ if (options.expanded !== undefined)
346
+ parts.push(`expanded=${options.expanded}`);
347
+ if (options.disabled !== undefined)
348
+ parts.push(`disabled=${options.disabled}`);
349
+ return Array.join(parts, ' ');
350
+ };
351
+ /** Creates a Locator that finds an element by ARIA role. Supports matching on
352
+ * `name`, `level`, `checked`, `selected`, `pressed`, `expanded`, and `disabled`. */
353
+ export const role = (roleValue, options) => {
354
+ const optionsDescription = options ? describeRoleOptions(options) : '';
355
+ const description = String_.isEmpty(optionsDescription)
356
+ ? roleValue
357
+ : `${roleValue} ${optionsDescription}`;
358
+ return makeLocator(getByRole(roleValue, options), description);
359
+ };
205
360
  /** Creates a Locator that finds an element by placeholder attribute. */
206
361
  export const placeholder = (placeholderValue) => makeLocator(getByPlaceholder(placeholderValue), `placeholder "${placeholderValue}"`);
207
362
  /** Creates a Locator that finds an element by aria-label. */
208
363
  export const label = (labelValue) => makeLocator(getByLabel(labelValue), `label "${labelValue}"`);
364
+ /** Creates a Locator that finds an element by its `alt` attribute. */
365
+ export const altText = (altValue) => makeLocator(getByAltText(altValue), `alt text "${altValue}"`);
366
+ /** Creates a Locator that finds an element by its `title` attribute. */
367
+ export const title = (titleValue) => makeLocator(getByTitle(titleValue), `title "${titleValue}"`);
368
+ /** Creates a Locator that finds an element by its `data-testid` attribute. */
369
+ export const testId = (testIdValue) => makeLocator(getByTestId(testIdValue), `testId "${testIdValue}"`);
370
+ /** Creates a Locator that finds a form control by its current `value`. */
371
+ export const displayValue = (valueString) => makeLocator(getByDisplayValue(valueString), `display value "${valueString}"`);
209
372
  /** Creates a Locator that finds the most specific element matching the given text content. */
210
373
  export const text = (target, options) => makeLocator(getByText(target, options), `text "${target}"`);
211
374
  /** Creates a Locator that wraps a CSS selector. Escape hatch for cases
@@ -215,6 +378,72 @@ export const selector = (css) => makeLocator(flow(findAllImpl(css), Array.head),
215
378
  * Composes via `Option.flatMap` — the parent is resolved first, then
216
379
  * the child is searched within the parent's subtree. */
217
380
  export const within = dual(2, (parent, child) => makeLocator(flow(parent, Option.flatMap(child)), `${child.description} within ${parent.description}`));
381
+ // LOCATOR-ALL FACTORIES
382
+ /** Creates a LocatorAll that finds every element matching the role. */
383
+ export const allRole = (roleValue, options) => {
384
+ const optionsDescription = options ? describeRoleOptions(options) : '';
385
+ const description = String_.isEmpty(optionsDescription)
386
+ ? roleValue
387
+ : `${roleValue} ${optionsDescription}`;
388
+ return makeLocatorAll(getAllByRole(roleValue, options), `all ${description}`);
389
+ };
390
+ /** Creates a LocatorAll that finds every element matching the text. */
391
+ export const allText = (target, options) => makeLocatorAll(getAllByText(target, options), `all text "${target}"`);
392
+ /** Creates a LocatorAll that finds every element with the given label. */
393
+ export const allLabel = (labelValue) => makeLocatorAll(getAllByLabel(labelValue), `all label "${labelValue}"`);
394
+ /** Creates a LocatorAll that finds every element with the given placeholder. */
395
+ export const allPlaceholder = (placeholderValue) => makeLocatorAll(getAllByPlaceholder(placeholderValue), `all placeholder "${placeholderValue}"`);
396
+ /** Creates a LocatorAll that finds every element with the given alt text. */
397
+ export const allAltText = (altValue) => makeLocatorAll(getAllByAltText(altValue), `all alt text "${altValue}"`);
398
+ /** Creates a LocatorAll that finds every element with the given title. */
399
+ export const allTitle = (titleValue) => makeLocatorAll(getAllByTitle(titleValue), `all title "${titleValue}"`);
400
+ /** Creates a LocatorAll that finds every element with the given data-testid. */
401
+ export const allTestId = (testIdValue) => makeLocatorAll(getAllByTestId(testIdValue), `all testId "${testIdValue}"`);
402
+ /** Creates a LocatorAll that finds every form control with the given value. */
403
+ export const allDisplayValue = (valueString) => makeLocatorAll(getAllByDisplayValue(valueString), `all display value "${valueString}"`);
404
+ /** Creates a LocatorAll from a CSS selector — returns every match. */
405
+ export const allSelector = (css) => makeLocatorAll(findAllImpl(css), `all "${css}"`);
406
+ // LOCATOR-ALL COMBINATORS
407
+ /** Picks the first match from a LocatorAll, producing a single-match Locator. */
408
+ export const first = (locatorAll) => makeLocator(flow(locatorAll, Array.head), `first of ${locatorAll.description}`);
409
+ /** Picks the last match from a LocatorAll, producing a single-match Locator. */
410
+ export const last = (locatorAll) => makeLocator(flow(locatorAll, Array.last), `last of ${locatorAll.description}`);
411
+ /** Picks the nth match (0-indexed) from a LocatorAll, producing a Locator. */
412
+ export const nth = dual(2, (locatorAll, index) => makeLocator(flow(locatorAll, Array.get(index)), `nth(${index}) of ${locatorAll.description}`));
413
+ const describeFilterOptions = (options) => {
414
+ const parts = [];
415
+ if (options.has)
416
+ parts.push(`has ${options.has.description}`);
417
+ if (options.hasNot)
418
+ parts.push(`hasNot ${options.hasNot.description}`);
419
+ if (options.hasText !== undefined)
420
+ parts.push(`hasText "${options.hasText}"`);
421
+ if (options.hasNotText !== undefined) {
422
+ parts.push(`hasNotText "${options.hasNotText}"`);
423
+ }
424
+ return Array.join(parts, ', ');
425
+ };
426
+ /** Filters a LocatorAll's matches. Supports `has`/`hasNot` to keep entries
427
+ * that do/don't contain a matching descendant, and `hasText`/`hasNotText`
428
+ * to keep entries whose text content does/doesn't include a substring. */
429
+ export const filter = dual(2, (locatorAll, options) => makeLocatorAll(html => Array.filter(locatorAll(html), match => {
430
+ if (options.has && Option.isNone(options.has(match)))
431
+ return false;
432
+ if (options.hasNot && Option.isSome(options.hasNot(match))) {
433
+ return false;
434
+ }
435
+ if (options.hasText !== undefined) {
436
+ if (!String_.includes(options.hasText)(textContent(match))) {
437
+ return false;
438
+ }
439
+ }
440
+ if (options.hasNotText !== undefined) {
441
+ if (String_.includes(options.hasNotText)(textContent(match))) {
442
+ return false;
443
+ }
444
+ }
445
+ return true;
446
+ }), `${locatorAll.description} filtered by (${describeFilterOptions(options)})`));
218
447
  /** Resolves a target (CSS selector string or Locator) against a VNode tree. */
219
448
  export const resolveTarget = (html, target) => {
220
449
  if (typeof target === 'string') {
@@ -2,10 +2,34 @@ import type { CommandDefinition } from '../command';
2
2
  import type { Html, KeyboardModifiers } from '../html';
3
3
  import type { VNode } from '../vdom';
4
4
  import type { AnyCommand, ResolverPair } from './internal';
5
- import type { Locator } from './query';
5
+ import type { Locator, LocatorAll } from './query';
6
6
  export type { AnyCommand, ResolverPair };
7
- export type { Locator } from './query';
8
- export { find, findAll, textContent, attr, getByRole, getAllByRole, getByText, getByPlaceholder, getByLabel, role, placeholder, label, selector, text, within, } from './query';
7
+ export { find, findAll, textContent, attr, getByRole, getAllByRole, getByText, getByPlaceholder, getByLabel, getByAltText, getByTitle, getByTestId, getByDisplayValue, role, placeholder, label, altText, title, testId, displayValue, selector, text, within, getAllByText, getAllByLabel, getAllByPlaceholder, getAllByAltText, getAllByTitle, getAllByTestId, getAllByDisplayValue, first, last, nth, filter, } from './query';
8
+ export type { Locator, LocatorAll } from './query';
9
+ /** Multi-match Locator factories. Each returns a `LocatorAll` that resolves
10
+ * to every matching VNode. Convert to a single `Locator` via `first`,
11
+ * `last`, or `nth(n)`, or narrow via `filter`. */
12
+ export declare const all: {
13
+ readonly role: (roleValue: string, options?: Readonly<{
14
+ name?: string;
15
+ level?: number;
16
+ checked?: boolean | "mixed";
17
+ selected?: boolean;
18
+ pressed?: boolean | "mixed";
19
+ expanded?: boolean;
20
+ disabled?: boolean;
21
+ }>) => LocatorAll;
22
+ readonly text: (target: string, options?: Readonly<{
23
+ exact?: boolean;
24
+ }>) => LocatorAll;
25
+ readonly label: (labelValue: string) => LocatorAll;
26
+ readonly placeholder: (placeholderValue: string) => LocatorAll;
27
+ readonly altText: (altValue: string) => LocatorAll;
28
+ readonly title: (titleValue: string) => LocatorAll;
29
+ readonly testId: (testIdValue: string) => LocatorAll;
30
+ readonly displayValue: (valueString: string) => LocatorAll;
31
+ readonly selector: (css: string) => LocatorAll;
32
+ };
9
33
  export { sceneMatchers } from './matchers';
10
34
  /** An immutable test simulation that includes the rendered VNode tree.
11
35
  * The Model and Message are intentionally opaque — Scene tests assert
@@ -35,8 +59,33 @@ export declare const resolve: {
35
59
  export declare const resolveAll: (pairs: ReadonlyArray<ResolverPair>) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
36
60
  /** Runs a function for side effects (e.g. assertions) without breaking the step chain. */
37
61
  export declare const tap: <Model, Message, OutMessage = undefined>(f: (simulation: SceneSimulation<Model, Message, OutMessage>) => void) => (simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
38
- /** Simulates a click on the element matching the target. */
62
+ /** Scopes a sequence of steps to a parent element. Every Locator referenced by
63
+ * child steps — assertions, interactions — resolves within the parent's subtree.
64
+ * Use this when several steps share the same scope. For a single scoped query,
65
+ * prefer `within(parent, child)` directly. Nested `inside` calls compose scopes
66
+ * via `within(outer, inner)`. */
67
+ export declare const inside: <Model, Message, OutMessage = undefined>(parent: Locator, ...steps: ReadonlyArray<NoInfer<SceneStep<Model, Message, OutMessage>>>) => (simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
68
+ /** Simulates a click on the element matching the target.
69
+ * When the element is a submit button (`<button>` with no type or
70
+ * `type="submit"`, `<input type="submit">`, `<input type="image">`) with no
71
+ * click handler of its own, the click falls through to the `submit` handler
72
+ * of the nearest ancestor `<form>` — mirroring browser behavior. */
39
73
  export declare const click: (target: string | Locator) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
74
+ /** Simulates a double-click on the element matching the target. */
75
+ export declare const doubleClick: (target: string | Locator) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
76
+ /** Simulates a hover (mouseenter) on the element matching the target.
77
+ * Dispatches the `mouseenter` handler, falling back to `mouseover`. */
78
+ export declare const hover: (target: string | Locator) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
79
+ /** Simulates a focus event on the element matching the target. */
80
+ export declare const focus: (target: string | Locator) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
81
+ /** Simulates a blur event on the element matching the target. */
82
+ export declare const blur: (target: string | Locator) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
83
+ /** Simulates a change event on the element matching the target.
84
+ * Dual: `change(target, value)` or `change(value)` for data-last piping. */
85
+ export declare const change: {
86
+ (target: string | Locator, value: string): <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
87
+ (value: string): (target: string | Locator) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
88
+ };
40
89
  /** Simulates form submission on the element matching the target. */
41
90
  export declare const submit: (target: string | Locator) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
42
91
  /** Simulates typing a value into the input matching the target.
@@ -61,8 +110,8 @@ declare const expect_: (locator: Locator) => {
61
110
  not: {
62
111
  toExist: () => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
63
112
  toBeAbsent: () => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
64
- toHaveText: (expected: string) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
65
- toContainText: (expected: string) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
113
+ toHaveText: (expected: string | RegExp) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
114
+ toContainText: (expected: string | RegExp) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
66
115
  toHaveAttr: (name: string, value?: string) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
67
116
  toHaveClass: (expected: string) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
68
117
  toHaveStyle: (name: string, value?: string) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
@@ -71,12 +120,17 @@ declare const expect_: (locator: Locator) => {
71
120
  toHaveValue: (expected: string) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
72
121
  toBeDisabled: () => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
73
122
  toBeEnabled: () => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
123
+ toBeEmpty: () => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
124
+ toBeVisible: () => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
125
+ toHaveId: (expected: string) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
126
+ toHaveAccessibleName: (expected: string | RegExp) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
127
+ toHaveAccessibleDescription: (expected: string | RegExp) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
74
128
  toBeChecked: () => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
75
129
  };
76
130
  toExist: () => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
77
131
  toBeAbsent: () => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
78
- toHaveText: (expected: string) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
79
- toContainText: (expected: string) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
132
+ toHaveText: (expected: string | RegExp) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
133
+ toContainText: (expected: string | RegExp) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
80
134
  toHaveAttr: (name: string, value?: string) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
81
135
  toHaveClass: (expected: string) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
82
136
  toHaveStyle: (name: string, value?: string) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
@@ -85,8 +139,23 @@ declare const expect_: (locator: Locator) => {
85
139
  toHaveValue: (expected: string) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
86
140
  toBeDisabled: () => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
87
141
  toBeEnabled: () => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
142
+ toBeEmpty: () => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
143
+ toBeVisible: () => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
144
+ toHaveId: (expected: string) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
145
+ toHaveAccessibleName: (expected: string | RegExp) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
146
+ toHaveAccessibleDescription: (expected: string | RegExp) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
88
147
  toBeChecked: () => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
89
148
  };
149
+ /** Creates an inline multi-match assertion step. Use for count-based
150
+ * assertions like `toHaveCount(n)` or `toBeEmpty()`. */
151
+ export declare const expectAll: (locatorAll: LocatorAll) => {
152
+ not: {
153
+ toHaveCount: (expected: number) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
154
+ toBeEmpty: () => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
155
+ };
156
+ toHaveCount: (expected: number) => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
157
+ toBeEmpty: () => <Model, Message, OutMessage = undefined>(simulation: SceneSimulation<Model, Message, OutMessage>) => SceneSimulation<Model, Message, OutMessage>;
158
+ };
90
159
  /** Adapts a submodel view for Scene testing. In the Submodel pattern, the view
91
160
  * takes a `toParentMessage` function that maps child Messages to parent Messages.
92
161
  * Scene tests the child in isolation, so `childView` passes the identity function
@@ -1 +1 @@
1
- {"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../../src/test/scene.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../../src/test/scene.ts"],"names":[],"mappings":"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"}