@glubean/browser 0.8.4 → 0.9.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.
package/dist/frame.js ADDED
@@ -0,0 +1,183 @@
1
+ /**
2
+ * GlubeanFrame — locator ergonomics scoped to an `<iframe>`'s content frame.
3
+ *
4
+ * Per the proposal's "iframe is a hybrid" note (browser-testing-cloud-rollout.md
5
+ * M5): CDP already does the execution-context switch — that's Puppeteer's own
6
+ * `Frame` object, wired up via `Page.frameAttached` / `Runtime.executionContextCreated`
7
+ * before this module ever runs. The only thing missing was the encapsulation
8
+ * layer's locator ergonomics (byTestId/byText/byRole/byLabel, auto-tracing
9
+ * click/fill/type/hover, auto-retrying expect*) scoped to a frame instead of
10
+ * the top-level page — that's what this module adds. Created via
11
+ * `GlubeanPage.frame(selector)`.
12
+ *
13
+ * @module frame
14
+ */
15
+ import { createWrappedLocator } from "./locator.js";
16
+ /**
17
+ * A Puppeteer `Frame` wrapped with the same locator/assertion ergonomics as
18
+ * `GlubeanPage`, scoped to that frame's content. Returned by `page.frame()`.
19
+ */
20
+ export class GlubeanFrame {
21
+ /** The underlying Puppeteer Frame for advanced use cases. */
22
+ raw;
23
+ _ctx;
24
+ _actionTimeout;
25
+ /** @internal — created by `GlubeanPage.frame()`. */
26
+ constructor(frame, ctx, actionTimeout) {
27
+ this.raw = frame;
28
+ this._ctx = ctx;
29
+ this._actionTimeout = actionTimeout;
30
+ }
31
+ /** Current frame URL. */
32
+ url() {
33
+ return this.raw.url();
34
+ }
35
+ /**
36
+ * Create a WrappedLocator scoped to this frame — same auto-tracing/
37
+ * screenshot behavior as `GlubeanPage.locator()`.
38
+ */
39
+ locator(selector) {
40
+ const inner = this.raw.locator(selector);
41
+ return createWrappedLocator(inner, this._ctx, selector, this.raw);
42
+ }
43
+ /** Locate an element by its `data-testid` attribute, scoped to this frame. */
44
+ byTestId(id) {
45
+ return this.locator(`[data-testid="${id}"]`);
46
+ }
47
+ /** Locate an element by its visible text content, scoped to this frame. */
48
+ byText(text) {
49
+ return this.locator(`::-p-text(${text})`);
50
+ }
51
+ /** Locate an element by its ARIA role (and optionally accessible name), scoped to this frame. */
52
+ byRole(role, options) {
53
+ if (options?.name) {
54
+ return this.locator(`::-p-aria(${options.name}[role="${role}"])`);
55
+ }
56
+ return this.locator(`[role="${role}"]`);
57
+ }
58
+ /** Locate an element by its accessible name (ARIA label), scoped to this frame. */
59
+ byLabel(label) {
60
+ return this.locator(`::-p-aria(${label})`);
61
+ }
62
+ /** Click an element matching the selector, scoped to this frame. */
63
+ async click(selector, options) {
64
+ await this.locator(selector)
65
+ .setTimeout(options?.timeout ?? this._actionTimeout)
66
+ .click();
67
+ }
68
+ /** Clear an input and type a new value, scoped to this frame. */
69
+ async fill(selector, value, options) {
70
+ await this.locator(selector)
71
+ .setTimeout(options?.timeout ?? this._actionTimeout)
72
+ .fill(value);
73
+ }
74
+ /** Type text into an element (appends — does not clear), scoped to this frame. */
75
+ async type(selector, text, options) {
76
+ await this.locator(selector)
77
+ .setTimeout(options?.timeout ?? this._actionTimeout)
78
+ .type(text);
79
+ }
80
+ /** Hover over an element matching the selector, scoped to this frame. */
81
+ async hover(selector, options) {
82
+ await this.locator(selector)
83
+ .setTimeout(options?.timeout ?? this._actionTimeout)
84
+ .hover();
85
+ }
86
+ /** Check whether an element is currently visible. Returns immediately — does not wait. */
87
+ async isVisible(selector) {
88
+ const handle = await this.raw.$(selector);
89
+ if (!handle)
90
+ return false;
91
+ try {
92
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
93
+ return await handle.evaluate((el) => {
94
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
95
+ const style = globalThis.getComputedStyle(el);
96
+ if (style.display === "none" || style.visibility === "hidden")
97
+ return false;
98
+ const box = el.getBoundingClientRect();
99
+ return box.width > 0 && box.height > 0;
100
+ });
101
+ }
102
+ finally {
103
+ await handle.dispose();
104
+ }
105
+ }
106
+ /** Assert that an element is visible, scoped to this frame. Retries until visible or timeout. */
107
+ async expectVisible(selector, options) {
108
+ await this._retryUntil(() => this.isVisible(selector), (visible) => visible === true, "browser:assert", `expectVisible("${selector}")`, () => `expectVisible("${selector}"): element was not visible after ${options?.timeout ?? 5_000}ms`, options);
109
+ }
110
+ /** Assert that an element is hidden or absent, scoped to this frame. Retries until hidden or timeout. */
111
+ async expectHidden(selector, options) {
112
+ await this._retryUntil(() => this.isVisible(selector), (visible) => visible === false, "browser:assert", `expectHidden("${selector}")`, () => `expectHidden("${selector}"): element was still visible after ${options?.timeout ?? 5_000}ms`, options);
113
+ }
114
+ /**
115
+ * Assert that an element's text content matches `expected`, scoped to this
116
+ * frame. Retries until match or timeout. Same normalize/match rules as
117
+ * `GlubeanPage.expectText()`.
118
+ */
119
+ async expectText(selector, expected, options) {
120
+ const normalize = (s) => s.replace(/\s+/g, " ").trim();
121
+ const matches = (text) => {
122
+ if (text === null)
123
+ return false;
124
+ if (expected instanceof RegExp)
125
+ return expected.test(text);
126
+ const norm = normalize(text);
127
+ const exp = normalize(expected);
128
+ if (options?.exact) {
129
+ return options?.ignoreCase ? norm.toLowerCase() === exp.toLowerCase() : norm === exp;
130
+ }
131
+ return options?.ignoreCase ? norm.toLowerCase().includes(exp.toLowerCase()) : norm.includes(exp);
132
+ };
133
+ await this._retryUntil(
134
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
135
+ () => this.raw.$eval(selector, (el) => el.textContent).catch(() => null), matches, "browser:assert", `expectText("${selector}")`, (lastVal) => `expectText("${selector}"): expected ${JSON.stringify(expected)} but received ` +
136
+ `${JSON.stringify(lastVal)} after ${options?.timeout ?? 5_000}ms`, options);
137
+ }
138
+ // ── Retry utility (mirrors GlubeanPage._retryUntil) ─────────────────
139
+ static _POLL_MS = 100;
140
+ async _retryUntil(fn, check, category, target, errorMsg, options) {
141
+ const timeout = options?.timeout ?? 5_000;
142
+ const start = Date.now();
143
+ let lastVal;
144
+ while (Date.now() - start < timeout) {
145
+ try {
146
+ lastVal = await fn();
147
+ if (check(lastVal)) {
148
+ this._ctx.action({ category, target, duration: Date.now() - start, status: "ok" });
149
+ return lastVal;
150
+ }
151
+ }
152
+ catch {
153
+ // element may not exist yet — retry
154
+ }
155
+ await new Promise((r) => setTimeout(r, GlubeanFrame._POLL_MS));
156
+ }
157
+ try {
158
+ lastVal = await fn();
159
+ if (check(lastVal)) {
160
+ this._ctx.action({ category, target, duration: Date.now() - start, status: "ok" });
161
+ return lastVal;
162
+ }
163
+ }
164
+ catch {
165
+ // fall through to error
166
+ }
167
+ const msg = errorMsg(lastVal);
168
+ this._ctx.action({
169
+ category,
170
+ target,
171
+ duration: Date.now() - start,
172
+ status: "timeout",
173
+ detail: { error: msg },
174
+ });
175
+ await this._ctx.captureFailure(target);
176
+ throw new Error(msg);
177
+ }
178
+ }
179
+ /** @internal Build a {@link GlubeanFrame} — called by `GlubeanPage.frame()`. */
180
+ export function createFrame(frame, ctx, actionTimeout) {
181
+ return new GlubeanFrame(frame, ctx, actionTimeout);
182
+ }
183
+ //# sourceMappingURL=frame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame.js","sourceRoot":"","sources":["../src/frame.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -38,7 +38,9 @@
38
38
  */
39
39
  export { browser } from "./plugin.js";
40
40
  export { GlubeanBrowser, GlubeanPage } from "./page.js";
41
- export type { ActionOptions, BrowserAction, BrowserEvent, BrowserOptions, BrowserTestContext, InstrumentedPage, PuppeteerLike, NetworkTraceOptions, ResponseChecks, } from "./page.js";
42
- export type { EmulationOptions, EvidenceScreenshotOptions, GeolocationOverride, MockRule, ScreenshotEntry, ScreenshotMode, ScreenshotTrigger, ViewportOverride, } from "./evidence.js";
43
- export type { WrappedLocator } from "./locator.js";
41
+ export type { ActionOptions, BrowserAction, BrowserEvent, BrowserOptions, BrowserTestContext, DialogHandler, DialogMode, InstrumentedPage, PuppeteerLike, NetworkTraceOptions, ResponseChecks, } from "./page.js";
42
+ export type { DownloadEntry, DownloadOptions, DownloadState, EmulationOptions, EvidenceScreenshotOptions, GeolocationOverride, MockRule, ScreenshotEntry, ScreenshotMode, ScreenshotTrigger, StorageCookie, StorageState, ViewportOverride, } from "./evidence.js";
43
+ export type { IndexedLocator, Queryable, WrappedLocator } from "./locator.js";
44
+ export { GlubeanFrame } from "./frame.js";
45
+ export type { FrameActionOptions } from "./frame.js";
44
46
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxD,YAAY,EACV,aAAa,EACb,aAAa,EACb,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,YAAY,EACV,gBAAgB,EAChB,yBAAyB,EACzB,mBAAmB,EACnB,QAAQ,EACR,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxD,YAAY,EACV,aAAa,EACb,aAAa,EACb,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,YAAY,EACV,aAAa,EACb,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,yBAAyB,EACzB,mBAAmB,EACnB,QAAQ,EACR,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -38,4 +38,5 @@
38
38
  */
39
39
  export { browser } from "./plugin.js";
40
40
  export { GlubeanBrowser, GlubeanPage } from "./page.js";
41
+ export { GlubeanFrame } from "./frame.js";
41
42
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AA8BxD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
package/dist/locator.d.ts CHANGED
@@ -4,7 +4,16 @@
4
4
  *
5
5
  * @module locator
6
6
  */
7
- import type { Locator } from "puppeteer-core";
7
+ import type { ElementHandle, Locator } from "puppeteer-core";
8
+ /**
9
+ * Structural subset of `Page` / `Frame` needed to re-query a selector for
10
+ * `count()` / `nth()`. Both Puppeteer types satisfy this — widened from a
11
+ * hard `Page` type (BT1-M5) so `createWrappedLocator` also works when called
12
+ * with a `Frame` (`page.frame()`'s locator scoping), not just a top-level Page.
13
+ */
14
+ export interface Queryable {
15
+ $$(selector: string): Promise<ElementHandle[]>;
16
+ }
8
17
  /** Context required by the WrappedLocator for trace/screenshot injection. */
9
18
  export interface LocatorContext {
10
19
  action(event: {
@@ -17,6 +26,25 @@ export interface LocatorContext {
17
26
  captureStep(label: string): Promise<void>;
18
27
  captureFailure(label: string): Promise<void>;
19
28
  }
29
+ /**
30
+ * An index-scoped locator returned by `WrappedLocator.nth()`.
31
+ *
32
+ * Puppeteer's own `Locator` resolves a CSS/text/ARIA selector to its
33
+ * **first** match only — there is no native way to act on the Nth match.
34
+ * `nth()` fills that gap with a minimal, independently-polled action surface
35
+ * (not a full `Locator`), resolving matches via `page.$$()` so Puppeteer's
36
+ * `::-p-text()` / `::-p-aria()` / `::-p-xpath()` pseudo-selectors still work.
37
+ */
38
+ export interface IndexedLocator {
39
+ click(): Promise<void>;
40
+ /** Clears the field's existing value, then types `value`. */
41
+ fill(value: string): Promise<void>;
42
+ hover(): Promise<void>;
43
+ /** Types `text` without clearing the existing value. */
44
+ type(text: string): Promise<void>;
45
+ /** Resolve (waiting up to the configured timeout) and return the raw handle. */
46
+ waitHandle(): Promise<ElementHandle>;
47
+ }
20
48
  /** A Puppeteer Locator enhanced with auto-tracing and screenshot capture. */
21
49
  export type WrappedLocator = Locator<any> & {
22
50
  /**
@@ -26,14 +54,57 @@ export type WrappedLocator = Locator<any> & {
26
54
  * that calls `waitHandle()` + `handle.type()` under the hood.
27
55
  */
28
56
  type(text: string): Promise<void>;
57
+ /**
58
+ * Immediate count of elements currently matching the selector. Does **not**
59
+ * wait/retry — for an auto-retrying count assertion, use `page.expectCount()`.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * const n = await page.locator('[data-testid="product-item"]').count();
64
+ * ```
65
+ */
66
+ count(): Promise<number>;
67
+ /**
68
+ * Locate the Nth (0-based) element matching this locator's selector.
69
+ *
70
+ * Independently polled — see {@link IndexedLocator}. Puppeteer's Locator
71
+ * always resolves to the first DOM match, so `nth()` is the only way to
72
+ * act on e.g. "the 2nd product card" without a bespoke selector.
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * await page.locator('[data-testid="add-to-cart"]').nth(1).click();
77
+ * ```
78
+ */
79
+ nth(index: number, options?: {
80
+ timeout?: number;
81
+ }): IndexedLocator;
29
82
  };
83
+ /**
84
+ * @internal Poll for the 0-based `index`-th element matching `selector`,
85
+ * returning its ElementHandle. Uses Puppeteer's own `page.$$()` (not raw
86
+ * `document.querySelectorAll`) so it understands Puppeteer's custom
87
+ * pseudo-selectors — `::-p-text()`, `::-p-aria()`, `::-p-xpath()` — that
88
+ * `byText()` / `byRole()` / `byLabel()` emit and that the DOM API can't parse.
89
+ * The non-chosen matches are disposed each poll; only the returned handle
90
+ * survives (the caller disposes it). Throws with a clear message on timeout.
91
+ */
92
+ export declare function resolveNthHandle(page: Queryable, selector: string, index: number, timeoutMs: number): Promise<ElementHandle>;
30
93
  /**
31
94
  * Create a WrappedLocator that proxies a Puppeteer Locator with auto-tracing.
32
95
  *
33
96
  * - **Chain methods** (setTimeout, setVisibility, etc.) return a new WrappedLocator.
34
97
  * - **Action methods** (click, fill, hover, scroll) inject trace + screenshot.
35
98
  * - **type()** is a custom extension (Locator has no type method).
99
+ * - **count() / nth()** are custom extensions (see {@link IndexedLocator}) —
100
+ * Puppeteer's Locator only ever resolves the first DOM match. They re-query
101
+ * by the selector string (via `page.$$`, which understands Puppeteer's
102
+ * `::-p-*` pseudo-selectors), so they cannot honor a `.filter()` / `.map()`
103
+ * predicate — calling them after those throws rather than mislead.
36
104
  * - Everything else is transparently forwarded.
105
+ *
106
+ * @param filtered — set on locators produced by a `.filter()` / `.map()` chain;
107
+ * makes `count()` / `nth()` throw (their selector re-query can't replay the predicate).
37
108
  */
38
- export declare function createWrappedLocator(inner: Locator<unknown>, ctx: LocatorContext, selector: string): WrappedLocator;
109
+ export declare function createWrappedLocator(inner: Locator<unknown>, ctx: LocatorContext, selector: string, page: Queryable, filtered?: boolean): WrappedLocator;
39
110
  //# sourceMappingURL=locator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"locator.d.ts","sourceRoot":"","sources":["../src/locator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAiB,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE7D,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,KAAK,EAAE;QACZ,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,IAAI,GAAG,OAAO,GAAG,SAAS,CAAC;QACnC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAClC,GAAG,IAAI,CAAC;IACT,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;AAED,6EAA6E;AAE7E,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG;IAC1C;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC,CAAC;AAsBF;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,EACvB,GAAG,EAAE,cAAc,EACnB,QAAQ,EAAE,MAAM,GACf,cAAc,CAoFhB"}
1
+ {"version":3,"file":"locator.d.ts","sourceRoot":"","sources":["../src/locator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,WAAW,SAAS;IACxB,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;CAChD;AAED,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,KAAK,EAAE;QACZ,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,IAAI,GAAG,OAAO,GAAG,SAAS,CAAC;QACnC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAClC,GAAG,IAAI,CAAC;IACT,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,6DAA6D;IAC7D,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,wDAAwD;IACxD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,gFAAgF;IAChF,UAAU,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;CACtC;AAED,6EAA6E;AAE7E,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG;IAC1C;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC;;;;;;;;OAQG;IACH,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACzB;;;;;;;;;;;OAWG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,cAAc,CAAC;CACpE,CAAC;AAaF;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,aAAa,CAAC,CAiBxB;AA6FD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,EACvB,GAAG,EAAE,cAAc,EACnB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,SAAS,EACf,QAAQ,UAAQ,GACf,cAAc,CAqHhB"}
package/dist/locator.js CHANGED
@@ -4,6 +4,88 @@
4
4
  *
5
5
  * @module locator
6
6
  */
7
+ /** @internal Default poll interval while waiting for an nth() match. */
8
+ const NTH_POLL_MS = 100;
9
+ /** @internal Default nth()/count() action timeout — mirrors `actionTimeout`. */
10
+ const NTH_DEFAULT_TIMEOUT_MS = 30_000;
11
+ /** @internal Error thrown when count()/nth() are used on a filtered/mapped locator. */
12
+ const COUNT_NTH_FILTERED_MSG = (method) => `${method}() is not supported after .filter()/.map(): it re-queries by the ` +
13
+ `original selector and cannot replay the predicate. Encode the condition in ` +
14
+ `the selector, or use page.$$()/page.$$eval() directly.`;
15
+ /**
16
+ * @internal Poll for the 0-based `index`-th element matching `selector`,
17
+ * returning its ElementHandle. Uses Puppeteer's own `page.$$()` (not raw
18
+ * `document.querySelectorAll`) so it understands Puppeteer's custom
19
+ * pseudo-selectors — `::-p-text()`, `::-p-aria()`, `::-p-xpath()` — that
20
+ * `byText()` / `byRole()` / `byLabel()` emit and that the DOM API can't parse.
21
+ * The non-chosen matches are disposed each poll; only the returned handle
22
+ * survives (the caller disposes it). Throws with a clear message on timeout.
23
+ */
24
+ export async function resolveNthHandle(page, selector, index, timeoutMs) {
25
+ const start = Date.now();
26
+ for (;;) {
27
+ const handles = await page.$$(selector);
28
+ const chosen = handles[index];
29
+ // Dispose every handle we're not returning so remote objects don't leak.
30
+ await Promise.all(handles.map((h) => (h === chosen ? Promise.resolve() : h.dispose())));
31
+ if (chosen)
32
+ return chosen;
33
+ if (Date.now() - start >= timeoutMs) {
34
+ throw new Error(`nth(${index}): no element matched "${selector}" at index ${index} after ${timeoutMs}ms`);
35
+ }
36
+ await new Promise((r) => setTimeout(r, NTH_POLL_MS));
37
+ }
38
+ }
39
+ /** @internal Build the {@link IndexedLocator} returned by `WrappedLocator.nth()`. */
40
+ function createIndexedLocator(page, ctx, selector, index, timeoutMs) {
41
+ const label = `${selector} >> nth=${index}`;
42
+ const act = async (category, detail, fn) => {
43
+ const start = Date.now();
44
+ try {
45
+ const handle = await resolveNthHandle(page, selector, index, timeoutMs);
46
+ try {
47
+ await fn(handle);
48
+ }
49
+ finally {
50
+ await handle.dispose();
51
+ }
52
+ ctx.action({
53
+ category: `browser:${category}`,
54
+ target: label,
55
+ duration: Date.now() - start,
56
+ status: "ok",
57
+ detail,
58
+ });
59
+ await ctx.captureStep(`${category}-${label}`);
60
+ }
61
+ catch (err) {
62
+ ctx.action({
63
+ category: `browser:${category}`,
64
+ target: label,
65
+ duration: Date.now() - start,
66
+ status: "timeout",
67
+ detail: { ...detail, error: String(err) },
68
+ });
69
+ await ctx.captureFailure(`${category}-${label}`);
70
+ throw err;
71
+ }
72
+ };
73
+ return {
74
+ click: () => act("click", undefined, (h) => h.click()),
75
+ fill: (value) => act("fill", { textLength: value.length }, async (h) => {
76
+ await h.evaluate((el) => {
77
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
78
+ const input = el;
79
+ input.value = "";
80
+ input.dispatchEvent(new Event("input", { bubbles: true }));
81
+ });
82
+ await h.type(value);
83
+ }),
84
+ hover: () => act("hover", undefined, (h) => h.hover()),
85
+ type: (text) => act("type", { textLength: text.length }, (h) => h.type(text)),
86
+ waitHandle: () => resolveNthHandle(page, selector, index, timeoutMs),
87
+ };
88
+ }
7
89
  /** Methods that return a new Locator — we re-wrap the result. */
8
90
  const CHAIN_METHODS = new Set([
9
91
  "setTimeout",
@@ -15,6 +97,13 @@ const CHAIN_METHODS = new Set([
15
97
  "filter",
16
98
  "map",
17
99
  ]);
100
+ /**
101
+ * Chain methods that change the *match set* a Locator resolves — after these,
102
+ * `count()` / `nth()` (which re-query by the raw selector string, not by
103
+ * replaying the Locator's predicate) would give results inconsistent with the
104
+ * chained Locator. They throw instead of silently returning wrong matches.
105
+ */
106
+ const SET_MUTATING_METHODS = new Set(["filter", "map"]);
18
107
  /** Action methods that get trace/screenshot injection. */
19
108
  const ACTION_METHODS = new Set([
20
109
  "click",
@@ -28,11 +117,43 @@ const ACTION_METHODS = new Set([
28
117
  * - **Chain methods** (setTimeout, setVisibility, etc.) return a new WrappedLocator.
29
118
  * - **Action methods** (click, fill, hover, scroll) inject trace + screenshot.
30
119
  * - **type()** is a custom extension (Locator has no type method).
120
+ * - **count() / nth()** are custom extensions (see {@link IndexedLocator}) —
121
+ * Puppeteer's Locator only ever resolves the first DOM match. They re-query
122
+ * by the selector string (via `page.$$`, which understands Puppeteer's
123
+ * `::-p-*` pseudo-selectors), so they cannot honor a `.filter()` / `.map()`
124
+ * predicate — calling them after those throws rather than mislead.
31
125
  * - Everything else is transparently forwarded.
126
+ *
127
+ * @param filtered — set on locators produced by a `.filter()` / `.map()` chain;
128
+ * makes `count()` / `nth()` throw (their selector re-query can't replay the predicate).
32
129
  */
33
- export function createWrappedLocator(inner, ctx, selector) {
130
+ export function createWrappedLocator(inner, ctx, selector, page, filtered = false) {
34
131
  const proxy = new Proxy(inner, {
35
132
  get(target, prop, receiver) {
133
+ if (prop === "count") {
134
+ // Non-async so the filtered guard throws synchronously (like nth()),
135
+ // not as a rejected promise. Dispose the handles `$$` returns — we only
136
+ // want the count, and undisposed handles leak remote objects in Chrome.
137
+ return () => {
138
+ if (filtered)
139
+ throw new Error(COUNT_NTH_FILTERED_MSG("count"));
140
+ return page.$$(selector).then(async (handles) => {
141
+ try {
142
+ return handles.length;
143
+ }
144
+ finally {
145
+ await Promise.all(handles.map((h) => h.dispose()));
146
+ }
147
+ });
148
+ };
149
+ }
150
+ if (prop === "nth") {
151
+ return (index, options) => {
152
+ if (filtered)
153
+ throw new Error(COUNT_NTH_FILTERED_MSG("nth"));
154
+ return createIndexedLocator(page, ctx, selector, index, options?.timeout ?? NTH_DEFAULT_TIMEOUT_MS);
155
+ };
156
+ }
36
157
  if (prop === "type") {
37
158
  return async (text) => {
38
159
  const start = Date.now();
@@ -70,7 +191,11 @@ export function createWrappedLocator(inner, ctx, selector) {
70
191
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
71
192
  return (...args) => {
72
193
  const newLocator = origFn.apply(target, args);
73
- return createWrappedLocator(newLocator, ctx, selector);
194
+ // Once a match-set-mutating method (filter/map) is applied, the
195
+ // re-wrapped locator carries `filtered` so count()/nth() refuse
196
+ // to run against the raw selector.
197
+ const nextFiltered = filtered || SET_MUTATING_METHODS.has(prop);
198
+ return createWrappedLocator(newLocator, ctx, selector, page, nextFiltered);
74
199
  };
75
200
  }
76
201
  }
@@ -1 +1 @@
1
- {"version":3,"file":"locator.js","sourceRoot":"","sources":["../src/locator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"locator.js","sourceRoot":"","sources":["../src/locator.ts"],"names":[],"mappings":"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"}