@unotest/web 0.9.0 → 0.10.0

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.
@@ -45,11 +45,17 @@ type LocatorStep = {
45
45
  } | {
46
46
  kind: 'nth';
47
47
  index: number;
48
+ } | {
49
+ kind: 'randomNth';
48
50
  } | {
49
51
  kind: 'contentFrame';
50
52
  } | {
51
53
  kind: 'ref';
52
54
  ref: string;
55
+ } | {
56
+ kind: 'intent';
57
+ intent: string;
58
+ ordinal?: 'first' | 'last' | number;
53
59
  };
54
60
  interface LocatorValue {
55
61
  readonly kind: 'locator';
@@ -163,6 +169,18 @@ type WaitState = "attached" | "detached" | "visible" | "hidden";
163
169
  interface WaitOptions extends ActionTimeout {
164
170
  state?: WaitState;
165
171
  }
172
+ interface WaitForTextOptions extends WaitOptions {
173
+ /** @deprecated No-op: "first visible occurrence" is the default now.
174
+ * Chat feeds and repeated labels made the old whole-list strict-mode
175
+ * wait a footgun — ≥1 visible match is what "the text is on screen"
176
+ * means. Kept so recorded scenarios with {first: true} stay valid. */
177
+ first?: boolean;
178
+ /** Match the full text exactly (Playwright getByText semantics).
179
+ * Default: substring, which also matches INSIDE a word ("hi" hits
180
+ * "anything") — pass a regex with \b anchors via the DSL for
181
+ * word-boundary matching. */
182
+ exact?: boolean;
183
+ }
166
184
  interface NavigationOptions extends ActionTimeout {
167
185
  /**
168
186
  * When to consider navigation done. Default: 'load'.
@@ -328,19 +346,30 @@ interface DriverPage {
328
346
  scrollIntoView(loc: LocatorValue): Promise<void>;
329
347
  /** Drag the source element onto the target. */
330
348
  dragAndDrop(from: LocatorValue, to: LocatorValue, opts?: ClickOptions): Promise<void>;
331
- /** Set the input element's selected files. Accepts one or many paths. */
332
- uploadFile(loc: LocatorValue, files: string | ReadonlyArray<string>): Promise<void>;
349
+ /** Set the input element's selected files. Accepts a path, path[], or an in-memory file buffer. */
350
+ uploadFile(loc: LocatorValue, files: string | ReadonlyArray<string> | {
351
+ name: string;
352
+ mimeType: string;
353
+ buffer: Buffer;
354
+ }): Promise<void>;
333
355
  /** Focus the locator then dispatch a paste-like input with `text`. */
334
356
  clipboardPaste(loc: LocatorValue, text: string): Promise<void>;
335
357
  count(loc: LocatorValue): Promise<number>;
336
358
  textContent(loc: LocatorValue): Promise<string | null>;
337
359
  inputValue(loc: LocatorValue): Promise<string>;
360
+ /** Checked state of a checkbox / radio / switch, `null` when the element
361
+ * is none of those. Separate from `inputValue` on purpose: a checkbox's
362
+ * `value` is the submitted payload ("on" by default), never its state. */
363
+ checkedState(loc: LocatorValue): Promise<boolean | null>;
338
364
  isVisible(loc: LocatorValue): Promise<boolean>;
339
365
  /** Read a DOM attribute on the matched element. Returns null if absent. */
340
366
  getAttribute(loc: LocatorValue, name: string): Promise<string | null>;
341
367
  waitFor(loc: LocatorValue, opts?: WaitOptions): Promise<void>;
342
368
  waitForUrl(pattern: string | RegExp, opts?: NavigationOptions): Promise<void>;
343
- waitForText(text: string, opts?: WaitOptions): Promise<void>;
369
+ /** Wait until ≥1 VISIBLE occurrence of `text` matches (or none, with
370
+ * `state: 'hidden' | 'detached'`). Accepts a regex matcher in the
371
+ * JSON-safe `Matcher` shape. */
372
+ waitForText(text: Matcher, opts?: WaitForTextOptions): Promise<void>;
344
373
  waitForNavigation(opts?: NavigationOptions): Promise<void>;
345
374
  goto(url: string, opts?: GotoOptions): Promise<void>;
346
375
  reload(opts?: ReloadOptions): Promise<void>;
@@ -392,6 +421,16 @@ interface ElementHint {
392
421
  /** textContent (trimmed, clipped). Last-resort semantic fallback
393
422
  * before the CSS escape hatch. */
394
423
  text?: string;
424
+ /** Descendant text of a STRUCTURAL container (record row / card /
425
+ * tree-item / `<li>` / `<tr>`) that carries no accessible name of its
426
+ * own — its identifying text lives in children, so it has no `name`/
427
+ * `text` signal. Captured ONLY when short enough to name a single
428
+ * record (not a whole table/section). The resolver turns it into
429
+ * `getByRole(role).filter({hasText})` — the sole semantic handle on
430
+ * containers materialised from unit-grounded asserts (assert_visible on
431
+ * a record). Kept separate from `text` so ARIA name semantics (a
432
+ * container takes its name only from aria-label/labelledby) hold. */
433
+ containerText?: string;
395
434
  /** href attribute for `<a>` elements lacking any of the above.
396
435
  * Resolver emits `locator('a[href="..."]')`. */
397
436
  href?: string;