@orkestrel/test 0.0.14 → 0.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,7 +9,8 @@ enough packages had already written their own; the guide's [Limits](guides/test.
9
9
  states that rule, what it excluded, and the one door the journey layer came through instead. Nothing
10
10
  here runs in production code. Part of the `@orkestrel` line.
11
11
 
12
- It has **zero runtime dependencies**, and no exported signature names an `@orkestrel/*` type. Both
12
+ This package runtime-depends on `@orkestrel/contract` for the outcome type `retryUntil` reads
13
+ internally. That type is not re-exported. No exported signature names an `@orkestrel/*` type. Both
13
14
  rules exist for one reason: a test helper hands its types straight into the consumer's assertions,
14
15
  and a second copy of a package inside its own repository makes the compiler read one type as two.
15
16
 
@@ -1250,6 +1250,65 @@ export declare function readFocus(): string | undefined;
1250
1250
  */
1251
1251
  export declare function readFrame(path: string): Promise<FrameReading>;
1252
1252
 
1253
+ /**
1254
+ * Reads the topmost element at one element's bounding-box centre.
1255
+ *
1256
+ * @param element - The element whose bounding-box centre is the point to read.
1257
+ * @returns The element the owner document's hit test names at that point, or `undefined` where the
1258
+ * point lies outside that viewport or reaches nothing.
1259
+ *
1260
+ * @remarks
1261
+ * This reads one point and nothing else: the centre of the element's own bounding box, hit-tested
1262
+ * against `element.ownerDocument`. That point is where a thumb aimed at the middle of what it sees
1263
+ * lands, and the arrangements that take it away are the ones {@link isReachable} cannot see: a
1264
+ * sticky masthead covering a control that was scrolled to, and a wrapped inline target, whose
1265
+ * per-line rectangles leave a gap the single bounding box spans and whose centre falls in that gap
1266
+ * on the ancestor. `isReachable` reads `checkVisibility`, geometry, and the focus order, and each
1267
+ * arrangement passes all three while a click at that point misses.
1268
+ *
1269
+ * It does not predict where the installed driver clicks. `playwright-core@1.63.0` clips each
1270
+ * content quad to the viewport, drops every quad left without area, and takes the midpoint of the
1271
+ * first quad that survives — `_clickablePoint` at `playwright-core/lib/coreBundle.js:20084`,
1272
+ * reached from the locator `click` the Vitest provider delegates to. For the wrapped target the
1273
+ * first surviving quad is the first line box, so the driver aims inside the link while this centre
1274
+ * sits in the gap. Read a result as the answer for the point this names, and for no other.
1275
+ *
1276
+ * It returns the node rather than a verdict, because the node is the diagnosis: a caller narrows
1277
+ * the result, rules on `link.contains(hit)`, and names what came back — the list item rather than
1278
+ * the link, the masthead rather than the control.
1279
+ *
1280
+ * Pass {@link isRendered} and {@link isReachable} before reading, because neither answer means
1281
+ * anything on an element that failed them. An element the document does not render measures a zero
1282
+ * rectangle at the origin, and a zero-area element measures a point on its own edge; each is
1283
+ * hit-tested like any other point and names whatever paints there — the surrounding container for
1284
+ * a control clipped inside one, and the document body for a rectangle collapsed at the origin.
1285
+ * `contains` is then false, and a caller that skipped the gates reports a cover that is not there.
1286
+ *
1287
+ * A returned node carries silences of its own. A cover painted with `pointer-events: none` is
1288
+ * absent from the hit test, so the reading names the element underneath it and the caller reads
1289
+ * reachable for a cover a person can see. An element inside a shadow tree retargets, in an open
1290
+ * root and a closed one alike: the document-level hit test names the host, the inner element does
1291
+ * not contain the host, and the caller reads the element's own host as a cover. Ask
1292
+ * `element.getRootNode()` for its own `elementFromPoint` where the subject sits in a shadow tree.
1293
+ *
1294
+ * `undefined` carries one silence: a centre outside the viewport reads the same as a centre that
1295
+ * reaches nothing. {@link isOutsideViewport} does not separate them, because it asks whether the
1296
+ * whole rectangle misses the viewport while this asks where one point lands — a rectangle at
1297
+ * `left: -80` with `width: 100` has its right edge at 20, so that predicate reports false while the
1298
+ * centre at -30 reads `undefined` here. The two also measure different windows: the predicate reads
1299
+ * the global `window`, and this reads `element.ownerDocument`. Compare the centre against that
1300
+ * document's own viewport where the distinction is the subject.
1301
+ *
1302
+ * @example
1303
+ * ```ts
1304
+ * const link = requireValue(container.querySelector('a'))
1305
+ * const hit = readHit(link)
1306
+ * // False for a wrapped link whose centre sits between its line boxes.
1307
+ * hit !== undefined && link.contains(hit)
1308
+ * ```
1309
+ */
1310
+ export declare function readHit(element: Element): Element | undefined;
1311
+
1253
1312
  /**
1254
1313
  * Collects the painted layers standing between one element and the surface it sits on.
1255
1314
  *
@@ -269,6 +269,67 @@ function isRendered(element) {
269
269
  return getComputedStyle(element).visibility !== "hidden";
270
270
  }
271
271
  /**
272
+ * Reads the topmost element at one element's bounding-box centre.
273
+ *
274
+ * @param element - The element whose bounding-box centre is the point to read.
275
+ * @returns The element the owner document's hit test names at that point, or `undefined` where the
276
+ * point lies outside that viewport or reaches nothing.
277
+ *
278
+ * @remarks
279
+ * This reads one point and nothing else: the centre of the element's own bounding box, hit-tested
280
+ * against `element.ownerDocument`. That point is where a thumb aimed at the middle of what it sees
281
+ * lands, and the arrangements that take it away are the ones {@link isReachable} cannot see: a
282
+ * sticky masthead covering a control that was scrolled to, and a wrapped inline target, whose
283
+ * per-line rectangles leave a gap the single bounding box spans and whose centre falls in that gap
284
+ * on the ancestor. `isReachable` reads `checkVisibility`, geometry, and the focus order, and each
285
+ * arrangement passes all three while a click at that point misses.
286
+ *
287
+ * It does not predict where the installed driver clicks. `playwright-core@1.63.0` clips each
288
+ * content quad to the viewport, drops every quad left without area, and takes the midpoint of the
289
+ * first quad that survives — `_clickablePoint` at `playwright-core/lib/coreBundle.js:20084`,
290
+ * reached from the locator `click` the Vitest provider delegates to. For the wrapped target the
291
+ * first surviving quad is the first line box, so the driver aims inside the link while this centre
292
+ * sits in the gap. Read a result as the answer for the point this names, and for no other.
293
+ *
294
+ * It returns the node rather than a verdict, because the node is the diagnosis: a caller narrows
295
+ * the result, rules on `link.contains(hit)`, and names what came back — the list item rather than
296
+ * the link, the masthead rather than the control.
297
+ *
298
+ * Pass {@link isRendered} and {@link isReachable} before reading, because neither answer means
299
+ * anything on an element that failed them. An element the document does not render measures a zero
300
+ * rectangle at the origin, and a zero-area element measures a point on its own edge; each is
301
+ * hit-tested like any other point and names whatever paints there — the surrounding container for
302
+ * a control clipped inside one, and the document body for a rectangle collapsed at the origin.
303
+ * `contains` is then false, and a caller that skipped the gates reports a cover that is not there.
304
+ *
305
+ * A returned node carries silences of its own. A cover painted with `pointer-events: none` is
306
+ * absent from the hit test, so the reading names the element underneath it and the caller reads
307
+ * reachable for a cover a person can see. An element inside a shadow tree retargets, in an open
308
+ * root and a closed one alike: the document-level hit test names the host, the inner element does
309
+ * not contain the host, and the caller reads the element's own host as a cover. Ask
310
+ * `element.getRootNode()` for its own `elementFromPoint` where the subject sits in a shadow tree.
311
+ *
312
+ * `undefined` carries one silence: a centre outside the viewport reads the same as a centre that
313
+ * reaches nothing. {@link isOutsideViewport} does not separate them, because it asks whether the
314
+ * whole rectangle misses the viewport while this asks where one point lands — a rectangle at
315
+ * `left: -80` with `width: 100` has its right edge at 20, so that predicate reports false while the
316
+ * centre at -30 reads `undefined` here. The two also measure different windows: the predicate reads
317
+ * the global `window`, and this reads `element.ownerDocument`. Compare the centre against that
318
+ * document's own viewport where the distinction is the subject.
319
+ *
320
+ * @example
321
+ * ```ts
322
+ * const link = requireValue(container.querySelector('a'))
323
+ * const hit = readHit(link)
324
+ * // False for a wrapped link whose centre sits between its line boxes.
325
+ * hit !== undefined && link.contains(hit)
326
+ * ```
327
+ */
328
+ function readHit(element) {
329
+ const rectangle = element.getBoundingClientRect();
330
+ return element.ownerDocument.elementFromPoint(rectangle.left + rectangle.width / 2, rectangle.top + rectangle.height / 2) ?? void 0;
331
+ }
332
+ /**
272
333
  * Computes the pattern that matches one accessible name a decorative glyph may sit beside.
273
334
  *
274
335
  * @param name - The exact accessible name a person reads, whitespace runs collapsed on the way in.
@@ -2246,6 +2307,6 @@ function createJournal() {
2246
2307
  };
2247
2308
  }
2248
2309
  //#endregion
2249
- export { ACCESSIBLE_ROLES, CANVAS_COLOR, CAPTURE_PANE, CAPTURE_STAGINGS, CONTENT_ROLES, FIELD_ROLES, FOCUSABLE_SELECTOR, HEADER_ROLES, IMPLICIT_ROLES, blendColor, build, captureFrame, clearStorage, clickAccessible, clickAccessibleWithin, clickDisclosure, commitInput, computeNamePattern, createChannel, createDragEvent, createJournal, createPointerEvent, createPortfolio, describeFocus, describeTree, expandCaptures, extractOrphans, extractStyles, fillAccessible, findKeyframes, findRule, isOutsideViewport, isReachable, isRendered, matchesColor, measureContent, measureContrast, measureLuminance, mount, parseCSSColor, parseColor, readBackdrop, readCascade, readClasses, readContrast, readFocus, readFrame, readLayers, readName, readPage, readPerception, readPixels, readRing, readRole, readRootToken, readRows, readRules, readStates, readStyle, readText, readToken, readValue, releasePane, removeDatabase, render, resolveAccessible, resolveRendered, stagePane, traverseAccessible, typeAccessible, typeInput, waitForFrame };
2310
+ export { ACCESSIBLE_ROLES, CANVAS_COLOR, CAPTURE_PANE, CAPTURE_STAGINGS, CONTENT_ROLES, FIELD_ROLES, FOCUSABLE_SELECTOR, HEADER_ROLES, IMPLICIT_ROLES, blendColor, build, captureFrame, clearStorage, clickAccessible, clickAccessibleWithin, clickDisclosure, commitInput, computeNamePattern, createChannel, createDragEvent, createJournal, createPointerEvent, createPortfolio, describeFocus, describeTree, expandCaptures, extractOrphans, extractStyles, fillAccessible, findKeyframes, findRule, isOutsideViewport, isReachable, isRendered, matchesColor, measureContent, measureContrast, measureLuminance, mount, parseCSSColor, parseColor, readBackdrop, readCascade, readClasses, readContrast, readFocus, readFrame, readHit, readLayers, readName, readPage, readPerception, readPixels, readRing, readRole, readRootToken, readRows, readRules, readStates, readStyle, readText, readToken, readValue, releasePane, removeDatabase, render, resolveAccessible, resolveRendered, stagePane, traverseAccessible, typeAccessible, typeInput, waitForFrame };
2250
2311
 
2251
2312
  //# sourceMappingURL=index.js.map