@glubean/browser 0.8.1 → 0.8.4
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/evidence.d.ts +274 -0
- package/dist/evidence.d.ts.map +1 -0
- package/dist/evidence.js +343 -0
- package/dist/evidence.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/network.d.ts +15 -5
- package/dist/network.d.ts.map +1 -1
- package/dist/network.js +16 -12
- package/dist/network.js.map +1 -1
- package/dist/page.d.ts +67 -15
- package/dist/page.d.ts.map +1 -1
- package/dist/page.js +112 -111
- package/dist/page.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared evidence CDP session — the foundation for browser evidence capture.
|
|
3
|
+
*
|
|
4
|
+
* A single self-opened `createCDPSession` hosts **all** CDP-backed capabilities
|
|
5
|
+
* at once, instead of opening one session per capability:
|
|
6
|
+
*
|
|
7
|
+
* - **Network trace** (`Network` domain) — every in-page request as a Glubean
|
|
8
|
+
* trace event (see {@link ./network.ts}).
|
|
9
|
+
* - **Request mock** (`Fetch` domain) — fulfill matching requests with a canned
|
|
10
|
+
* response; non-matching requests are continued untouched.
|
|
11
|
+
* - **Emulation** (`Emulation` domain) — timezone / geolocation / viewport.
|
|
12
|
+
*
|
|
13
|
+
* The keystone spike disproved the "Fetch is near-exclusive" hypothesis: a
|
|
14
|
+
* self-opened session running `Fetch.enable`/`fulfillRequest` is stable **as
|
|
15
|
+
* long as the user has not enabled Puppeteer's own request interception**.
|
|
16
|
+
* Two coexistence hazards remain, each handled by a guardrail below:
|
|
17
|
+
*
|
|
18
|
+
* **Guardrail ① — viewport ownership.** Our `Emulation.setDeviceMetricsOverride`
|
|
19
|
+
* and Puppeteer's `page.setViewport()` both drive device metrics and clobber
|
|
20
|
+
* each other last-wins. When `emulate.viewport` is configured, Glubean is the
|
|
21
|
+
* sole owner: it applies the viewport last and blocks `page.setViewport()` with
|
|
22
|
+
* a clear error so the two never race.
|
|
23
|
+
*
|
|
24
|
+
* **Guardrail ② — Fetch double-open.** If the user turns on Puppeteer request
|
|
25
|
+
* interception (`page.setRequestInterception(true)`) while our `Fetch` mock is
|
|
26
|
+
* active, both stacks try to handle the same paused request and fulfillment
|
|
27
|
+
* conflicts. When mocks are enabled, Glubean owns `Fetch` and blocks
|
|
28
|
+
* `page.setRequestInterception(true)` with a clear error. When no mocks are
|
|
29
|
+
* configured we never enable `Fetch`, so the user's own interception is free.
|
|
30
|
+
*
|
|
31
|
+
* @module evidence
|
|
32
|
+
*/
|
|
33
|
+
import type { CDPSession, Page } from "puppeteer-core";
|
|
34
|
+
import { type NetworkTracerOptions, type TraceFn } from "./network.js";
|
|
35
|
+
/**
|
|
36
|
+
* When screenshots are automatically captured into the evidence stream.
|
|
37
|
+
*
|
|
38
|
+
* - `"off"` — no automatic screenshots
|
|
39
|
+
* - `"on-failure"` — capture when a step or test fails (default)
|
|
40
|
+
* - `"every-step"` — capture after every action AND on failure
|
|
41
|
+
*/
|
|
42
|
+
export type ScreenshotMode = "off" | "on-failure" | "every-step";
|
|
43
|
+
/**
|
|
44
|
+
* What triggered a screenshot capture.
|
|
45
|
+
*
|
|
46
|
+
* - `"step"` — post-action capture in every-step mode
|
|
47
|
+
* - `"failure"` — automatic capture on action or assertion failure
|
|
48
|
+
* - `"manual"` — explicit call to `page.captureScreenshot()`
|
|
49
|
+
*/
|
|
50
|
+
export type ScreenshotTrigger = "step" | "failure" | "manual";
|
|
51
|
+
/** A screenshot captured into the evidence stream. */
|
|
52
|
+
export interface ScreenshotEntry {
|
|
53
|
+
/** Sequential number within this evidence session (1-based). */
|
|
54
|
+
seq: number;
|
|
55
|
+
/** Wall-clock ISO timestamp at capture time. */
|
|
56
|
+
ts: string;
|
|
57
|
+
/** Human-readable label (the action or assertion that triggered the capture). */
|
|
58
|
+
label: string;
|
|
59
|
+
/** What triggered this capture. */
|
|
60
|
+
trigger: ScreenshotTrigger;
|
|
61
|
+
/** Artifact ID when `ctx.saveArtifact` is available (SDK ≥ 0.13). */
|
|
62
|
+
artifactId?: string;
|
|
63
|
+
/** File path when falling back to direct file write. */
|
|
64
|
+
path?: string;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Screenshot capture options for the shared evidence session.
|
|
68
|
+
*
|
|
69
|
+
* The `shoot` delegate performs the actual I/O (screenshot + artifact save +
|
|
70
|
+
* `ctx.event()` emission); {@link EvidenceSession.captureShot} handles the
|
|
71
|
+
* mode / trigger policy, sequencing, and accumulation of entries.
|
|
72
|
+
*/
|
|
73
|
+
export interface EvidenceScreenshotOptions {
|
|
74
|
+
/** Policy: which triggers result in a capture. */
|
|
75
|
+
mode: ScreenshotMode;
|
|
76
|
+
/**
|
|
77
|
+
* I/O delegate — takes the screenshot, saves the artifact, and emits
|
|
78
|
+
* the `browser:screenshot` evidence event. Returns an artifact reference
|
|
79
|
+
* for {@link ScreenshotEntry}. Called only when the mode/trigger policy allows.
|
|
80
|
+
*
|
|
81
|
+
* @param filename — suggested filename: `[FAIL-]NNN-label-ts.png`
|
|
82
|
+
* @param label — human label for the action/assertion
|
|
83
|
+
* @param trigger — what triggered this capture
|
|
84
|
+
*/
|
|
85
|
+
shoot: (filename: string, label: string, trigger: ScreenshotTrigger) => Promise<{
|
|
86
|
+
artifactId?: string;
|
|
87
|
+
path?: string;
|
|
88
|
+
}>;
|
|
89
|
+
}
|
|
90
|
+
/** A single header as CDP's `Fetch.fulfillRequest` expects it. */
|
|
91
|
+
interface HeaderEntry {
|
|
92
|
+
name: string;
|
|
93
|
+
value: string;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* A request-mock rule. Matching requests are fulfilled with a canned response;
|
|
97
|
+
* everything else is continued untouched.
|
|
98
|
+
*/
|
|
99
|
+
export interface MockRule {
|
|
100
|
+
/**
|
|
101
|
+
* Match the request URL. A string matches by substring (`url.includes(...)`);
|
|
102
|
+
* a `RegExp` matches by `test(url)`.
|
|
103
|
+
*/
|
|
104
|
+
url: string | RegExp;
|
|
105
|
+
/** Restrict to a single HTTP method (case-insensitive). Omit to match any. */
|
|
106
|
+
method?: string;
|
|
107
|
+
/** Response status code. @default 200 */
|
|
108
|
+
status?: number;
|
|
109
|
+
/** Extra response headers. */
|
|
110
|
+
headers?: Record<string, string>;
|
|
111
|
+
/**
|
|
112
|
+
* Response body. A string is sent verbatim; any other value is
|
|
113
|
+
* `JSON.stringify`-ed. The `content-type` is inferred (JSON vs plain text)
|
|
114
|
+
* unless `contentType` is set.
|
|
115
|
+
*/
|
|
116
|
+
body?: unknown;
|
|
117
|
+
/** Explicit `content-type` header. Overrides the inferred value. */
|
|
118
|
+
contentType?: string;
|
|
119
|
+
}
|
|
120
|
+
/** Geolocation override. */
|
|
121
|
+
export interface GeolocationOverride {
|
|
122
|
+
latitude: number;
|
|
123
|
+
longitude: number;
|
|
124
|
+
/** Accuracy in meters. @default 0 (mirrors Puppeteer's `setGeolocation`). */
|
|
125
|
+
accuracy?: number;
|
|
126
|
+
}
|
|
127
|
+
/** Viewport / device-metrics override (owned solely by Glubean — see guardrail ①). */
|
|
128
|
+
export interface ViewportOverride {
|
|
129
|
+
width: number;
|
|
130
|
+
height: number;
|
|
131
|
+
/** @default 1 */
|
|
132
|
+
deviceScaleFactor?: number;
|
|
133
|
+
/** @default false */
|
|
134
|
+
mobile?: boolean;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Environment emulation applied on the shared evidence session.
|
|
138
|
+
*
|
|
139
|
+
* Timezone and geolocation are pure overrides with no Puppeteer conflict.
|
|
140
|
+
* Viewport is special: see guardrail ① — do **not** also call
|
|
141
|
+
* `page.setViewport()`, it will race with this override.
|
|
142
|
+
*/
|
|
143
|
+
export interface EmulationOptions {
|
|
144
|
+
/** IANA timezone id, e.g. `"America/New_York"`. */
|
|
145
|
+
timezone?: string;
|
|
146
|
+
/** Geolocation override. */
|
|
147
|
+
geolocation?: GeolocationOverride;
|
|
148
|
+
/** Viewport / device metrics. Glubean becomes the sole viewport owner. */
|
|
149
|
+
viewport?: ViewportOverride;
|
|
150
|
+
}
|
|
151
|
+
/** Options for {@link EvidenceSession.attach}. */
|
|
152
|
+
export interface EvidenceSessionOptions {
|
|
153
|
+
/**
|
|
154
|
+
* Network-trace callback (`ctx.trace`). When omitted, the `Network` domain
|
|
155
|
+
* tracer is not attached.
|
|
156
|
+
*/
|
|
157
|
+
trace?: TraceFn;
|
|
158
|
+
/** Network-trace filter configuration. Ignored when `trace` is omitted. */
|
|
159
|
+
network?: Pick<NetworkTracerOptions, "include" | "excludePaths" | "filter">;
|
|
160
|
+
/** Request-mock rules. When non-empty, the `Fetch` domain is enabled (guardrail ②). */
|
|
161
|
+
mocks?: MockRule[];
|
|
162
|
+
/** Environment emulation (timezone / geolocation / viewport). */
|
|
163
|
+
emulate?: EmulationOptions;
|
|
164
|
+
/**
|
|
165
|
+
* Screenshot capture policy and I/O delegate.
|
|
166
|
+
*
|
|
167
|
+
* When provided, {@link EvidenceSession.captureShot} becomes active and will
|
|
168
|
+
* call `screenshots.shoot` based on the configured mode and trigger.
|
|
169
|
+
* Omit (or set `mode: "off"`) to disable all automatic screenshot capture.
|
|
170
|
+
*/
|
|
171
|
+
screenshots?: EvidenceScreenshotOptions;
|
|
172
|
+
}
|
|
173
|
+
/** A single CDP call: `{ method, params }`. Kept pure for testing. */
|
|
174
|
+
export interface CdpCall {
|
|
175
|
+
method: string;
|
|
176
|
+
params?: Record<string, unknown>;
|
|
177
|
+
}
|
|
178
|
+
/** @internal Does `rule` match the given request? */
|
|
179
|
+
export declare function matchMock(rule: MockRule, req: {
|
|
180
|
+
url: string;
|
|
181
|
+
method: string;
|
|
182
|
+
}): boolean;
|
|
183
|
+
/** @internal Find the first matching mock rule, or `undefined`. */
|
|
184
|
+
export declare function findMock(mocks: readonly MockRule[], req: {
|
|
185
|
+
url: string;
|
|
186
|
+
method: string;
|
|
187
|
+
}): MockRule | undefined;
|
|
188
|
+
/**
|
|
189
|
+
* @internal Build `Fetch.fulfillRequest` params from a rule.
|
|
190
|
+
*
|
|
191
|
+
* The body is always base64-encoded (as CDP requires). Content-type is inferred
|
|
192
|
+
* from the body kind unless `rule.contentType` is set. User headers win over the
|
|
193
|
+
* inferred content-type.
|
|
194
|
+
*/
|
|
195
|
+
export declare function buildFulfillParams(rule: MockRule, requestId: string): {
|
|
196
|
+
requestId: string;
|
|
197
|
+
responseCode: number;
|
|
198
|
+
responseHeaders: HeaderEntry[];
|
|
199
|
+
body: string;
|
|
200
|
+
};
|
|
201
|
+
/**
|
|
202
|
+
* @internal Build the ordered list of `Emulation.*` CDP calls.
|
|
203
|
+
*
|
|
204
|
+
* Timezone and geolocation come first; the viewport override is applied **last**
|
|
205
|
+
* (guardrail ①) so it is the final word on device metrics at setup time.
|
|
206
|
+
*/
|
|
207
|
+
export declare function buildEmulationCalls(emulate: EmulationOptions): CdpCall[];
|
|
208
|
+
/**
|
|
209
|
+
* @internal Replace `page[method]` with a guard, returning a restore function.
|
|
210
|
+
*
|
|
211
|
+
* `shouldBlock` decides, per call arguments, whether to throw the guard error.
|
|
212
|
+
* Blocked calls throw synchronously; allowed calls fall through to the original
|
|
213
|
+
* method (or resolve to `undefined` if there was none). Used to enforce
|
|
214
|
+
* guardrails ① (viewport) and ② (Fetch interception).
|
|
215
|
+
*/
|
|
216
|
+
export declare function guardPageMethod(page: any, method: string, message: string, shouldBlock: (args: unknown[]) => boolean): () => void;
|
|
217
|
+
/**
|
|
218
|
+
* A single self-opened CDP session that hosts every CDP-backed evidence
|
|
219
|
+
* capability for one page. Create with {@link EvidenceSession.attach}; release
|
|
220
|
+
* with {@link EvidenceSession.detach}.
|
|
221
|
+
*/
|
|
222
|
+
export declare class EvidenceSession {
|
|
223
|
+
private readonly _cdp;
|
|
224
|
+
private readonly _cleanups;
|
|
225
|
+
private _detached;
|
|
226
|
+
private _screenshotOpts;
|
|
227
|
+
private _screenshotSeq;
|
|
228
|
+
private _screenshotLog;
|
|
229
|
+
private constructor();
|
|
230
|
+
/** The underlying CDP session, for advanced/raw use. */
|
|
231
|
+
get cdp(): CDPSession;
|
|
232
|
+
/**
|
|
233
|
+
* All screenshots captured into this evidence session, in order.
|
|
234
|
+
*
|
|
235
|
+
* Each entry carries `seq`, `ts`, `label`, `trigger`, and an artifact
|
|
236
|
+
* reference (`artifactId` or `path`). The list is empty when no screenshot
|
|
237
|
+
* has been captured yet or when `screenshots.mode` is `"off"`.
|
|
238
|
+
*/
|
|
239
|
+
get screenshots(): readonly ScreenshotEntry[];
|
|
240
|
+
/**
|
|
241
|
+
* Capture a screenshot into the evidence stream, subject to the configured
|
|
242
|
+
* {@link ScreenshotMode} and the `trigger` argument.
|
|
243
|
+
*
|
|
244
|
+
* | mode | "step" trigger | "failure" trigger | "manual" trigger |
|
|
245
|
+
* |---------------|----------------|-------------------|------------------|
|
|
246
|
+
* | "off" | skip | skip | skip |
|
|
247
|
+
* | "on-failure" | skip | capture | capture |
|
|
248
|
+
* | "every-step" | capture | capture | capture |
|
|
249
|
+
*
|
|
250
|
+
* Always best-effort: errors from the I/O delegate are silently swallowed
|
|
251
|
+
* so a broken page state never masks the real test error.
|
|
252
|
+
*
|
|
253
|
+
* Does nothing when no `screenshots` option was passed to {@link attach}.
|
|
254
|
+
*/
|
|
255
|
+
captureShot(label: string, trigger: ScreenshotTrigger): Promise<void>;
|
|
256
|
+
/**
|
|
257
|
+
* Open one CDP session on `page` and wire up the requested capabilities:
|
|
258
|
+
* Network trace, Fetch mock (guardrail ②), and Emulation (guardrail ① for
|
|
259
|
+
* viewport). Capabilities are only enabled when their config is present, so a
|
|
260
|
+
* page with no mocks never enables `Fetch` and leaves the user's own request
|
|
261
|
+
* interception untouched.
|
|
262
|
+
*/
|
|
263
|
+
static attach(page: Page, options: EvidenceSessionOptions): Promise<EvidenceSession>;
|
|
264
|
+
private _installMocks;
|
|
265
|
+
private _guardViewport;
|
|
266
|
+
/**
|
|
267
|
+
* Remove all listeners/overrides, restore guarded page methods, and detach
|
|
268
|
+
* the CDP session. Idempotent and best-effort — safe to call after the page
|
|
269
|
+
* has closed.
|
|
270
|
+
*/
|
|
271
|
+
detach(): Promise<void>;
|
|
272
|
+
}
|
|
273
|
+
export {};
|
|
274
|
+
//# sourceMappingURL=evidence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../src/evidence.ts"],"names":[],"mappings":"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"}
|
package/dist/evidence.js
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared evidence CDP session — the foundation for browser evidence capture.
|
|
3
|
+
*
|
|
4
|
+
* A single self-opened `createCDPSession` hosts **all** CDP-backed capabilities
|
|
5
|
+
* at once, instead of opening one session per capability:
|
|
6
|
+
*
|
|
7
|
+
* - **Network trace** (`Network` domain) — every in-page request as a Glubean
|
|
8
|
+
* trace event (see {@link ./network.ts}).
|
|
9
|
+
* - **Request mock** (`Fetch` domain) — fulfill matching requests with a canned
|
|
10
|
+
* response; non-matching requests are continued untouched.
|
|
11
|
+
* - **Emulation** (`Emulation` domain) — timezone / geolocation / viewport.
|
|
12
|
+
*
|
|
13
|
+
* The keystone spike disproved the "Fetch is near-exclusive" hypothesis: a
|
|
14
|
+
* self-opened session running `Fetch.enable`/`fulfillRequest` is stable **as
|
|
15
|
+
* long as the user has not enabled Puppeteer's own request interception**.
|
|
16
|
+
* Two coexistence hazards remain, each handled by a guardrail below:
|
|
17
|
+
*
|
|
18
|
+
* **Guardrail ① — viewport ownership.** Our `Emulation.setDeviceMetricsOverride`
|
|
19
|
+
* and Puppeteer's `page.setViewport()` both drive device metrics and clobber
|
|
20
|
+
* each other last-wins. When `emulate.viewport` is configured, Glubean is the
|
|
21
|
+
* sole owner: it applies the viewport last and blocks `page.setViewport()` with
|
|
22
|
+
* a clear error so the two never race.
|
|
23
|
+
*
|
|
24
|
+
* **Guardrail ② — Fetch double-open.** If the user turns on Puppeteer request
|
|
25
|
+
* interception (`page.setRequestInterception(true)`) while our `Fetch` mock is
|
|
26
|
+
* active, both stacks try to handle the same paused request and fulfillment
|
|
27
|
+
* conflicts. When mocks are enabled, Glubean owns `Fetch` and blocks
|
|
28
|
+
* `page.setRequestInterception(true)` with a clear error. When no mocks are
|
|
29
|
+
* configured we never enable `Fetch`, so the user's own interception is free.
|
|
30
|
+
*
|
|
31
|
+
* @module evidence
|
|
32
|
+
*/
|
|
33
|
+
import { attachNetworkTracer, } from "./network.js";
|
|
34
|
+
// ── Pure helpers (exported for testing) ───────────────────────────────
|
|
35
|
+
/** @internal Does `rule` match the given request? */
|
|
36
|
+
export function matchMock(rule, req) {
|
|
37
|
+
if (rule.method && rule.method.toUpperCase() !== req.method.toUpperCase()) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
if (typeof rule.url === "string")
|
|
41
|
+
return req.url.includes(rule.url);
|
|
42
|
+
// Test against a stateless clone: a user-supplied global/sticky regex
|
|
43
|
+
// (`/g`, `/y`) carries `lastIndex` state, so `.test()` on the original would
|
|
44
|
+
// flip-flop matches for the same URL across repeated requests (and would also
|
|
45
|
+
// mutate the caller's regex). Strip `g`/`y` on a copy to keep matching pure.
|
|
46
|
+
const stateless = new RegExp(rule.url.source, rule.url.flags.replace(/[gy]/g, ""));
|
|
47
|
+
return stateless.test(req.url);
|
|
48
|
+
}
|
|
49
|
+
/** @internal Find the first matching mock rule, or `undefined`. */
|
|
50
|
+
export function findMock(mocks, req) {
|
|
51
|
+
return mocks.find((m) => matchMock(m, req));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* @internal Build `Fetch.fulfillRequest` params from a rule.
|
|
55
|
+
*
|
|
56
|
+
* The body is always base64-encoded (as CDP requires). Content-type is inferred
|
|
57
|
+
* from the body kind unless `rule.contentType` is set. User headers win over the
|
|
58
|
+
* inferred content-type.
|
|
59
|
+
*/
|
|
60
|
+
export function buildFulfillParams(rule, requestId) {
|
|
61
|
+
let bodyStr = "";
|
|
62
|
+
let inferredType;
|
|
63
|
+
if (rule.body !== undefined) {
|
|
64
|
+
if (typeof rule.body === "string") {
|
|
65
|
+
bodyStr = rule.body;
|
|
66
|
+
inferredType = "text/plain; charset=utf-8";
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
bodyStr = JSON.stringify(rule.body);
|
|
70
|
+
inferredType = "application/json; charset=utf-8";
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const headerMap = new Map();
|
|
74
|
+
const contentType = rule.contentType ?? inferredType;
|
|
75
|
+
if (contentType !== undefined)
|
|
76
|
+
headerMap.set("content-type", contentType);
|
|
77
|
+
// User headers win over the inferred content-type (case-insensitive keys).
|
|
78
|
+
for (const [name, value] of Object.entries(rule.headers ?? {})) {
|
|
79
|
+
headerMap.set(name.toLowerCase(), value);
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
requestId,
|
|
83
|
+
responseCode: rule.status ?? 200,
|
|
84
|
+
responseHeaders: [...headerMap].map(([name, value]) => ({ name, value })),
|
|
85
|
+
body: Buffer.from(bodyStr, "utf8").toString("base64"),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* @internal Build the ordered list of `Emulation.*` CDP calls.
|
|
90
|
+
*
|
|
91
|
+
* Timezone and geolocation come first; the viewport override is applied **last**
|
|
92
|
+
* (guardrail ①) so it is the final word on device metrics at setup time.
|
|
93
|
+
*/
|
|
94
|
+
export function buildEmulationCalls(emulate) {
|
|
95
|
+
const calls = [];
|
|
96
|
+
if (emulate.timezone !== undefined) {
|
|
97
|
+
calls.push({
|
|
98
|
+
method: "Emulation.setTimezoneOverride",
|
|
99
|
+
params: { timezoneId: emulate.timezone },
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
if (emulate.geolocation) {
|
|
103
|
+
const { latitude, longitude, accuracy } = emulate.geolocation;
|
|
104
|
+
calls.push({
|
|
105
|
+
method: "Emulation.setGeolocationOverride",
|
|
106
|
+
params: { latitude, longitude, accuracy: accuracy ?? 0 },
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
if (emulate.viewport) {
|
|
110
|
+
const { width, height, deviceScaleFactor, mobile } = emulate.viewport;
|
|
111
|
+
calls.push({
|
|
112
|
+
method: "Emulation.setDeviceMetricsOverride",
|
|
113
|
+
params: {
|
|
114
|
+
width,
|
|
115
|
+
height,
|
|
116
|
+
deviceScaleFactor: deviceScaleFactor ?? 1,
|
|
117
|
+
mobile: mobile ?? false,
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
return calls;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* @internal Replace `page[method]` with a guard, returning a restore function.
|
|
125
|
+
*
|
|
126
|
+
* `shouldBlock` decides, per call arguments, whether to throw the guard error.
|
|
127
|
+
* Blocked calls throw synchronously; allowed calls fall through to the original
|
|
128
|
+
* method (or resolve to `undefined` if there was none). Used to enforce
|
|
129
|
+
* guardrails ① (viewport) and ② (Fetch interception).
|
|
130
|
+
*/
|
|
131
|
+
export function guardPageMethod(
|
|
132
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
133
|
+
page, method, message, shouldBlock) {
|
|
134
|
+
const hadOwn = Object.prototype.hasOwnProperty.call(page, method);
|
|
135
|
+
const previous = page[method];
|
|
136
|
+
const original = typeof previous === "function"
|
|
137
|
+
? previous.bind(page)
|
|
138
|
+
: undefined;
|
|
139
|
+
page[method] = (...args) => {
|
|
140
|
+
if (shouldBlock(args))
|
|
141
|
+
throw new Error(message);
|
|
142
|
+
return original ? original(...args) : Promise.resolve(undefined);
|
|
143
|
+
};
|
|
144
|
+
return () => {
|
|
145
|
+
if (hadOwn)
|
|
146
|
+
page[method] = previous;
|
|
147
|
+
else
|
|
148
|
+
delete page[method];
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
// ── EvidenceSession ───────────────────────────────────────────────────
|
|
152
|
+
/**
|
|
153
|
+
* A single self-opened CDP session that hosts every CDP-backed evidence
|
|
154
|
+
* capability for one page. Create with {@link EvidenceSession.attach}; release
|
|
155
|
+
* with {@link EvidenceSession.detach}.
|
|
156
|
+
*/
|
|
157
|
+
export class EvidenceSession {
|
|
158
|
+
_cdp;
|
|
159
|
+
_cleanups = [];
|
|
160
|
+
_detached = false;
|
|
161
|
+
// ── Screenshot state ──────────────────────────────────────────────
|
|
162
|
+
_screenshotOpts;
|
|
163
|
+
_screenshotSeq = 0;
|
|
164
|
+
_screenshotLog = [];
|
|
165
|
+
constructor(cdp) {
|
|
166
|
+
this._cdp = cdp;
|
|
167
|
+
}
|
|
168
|
+
/** The underlying CDP session, for advanced/raw use. */
|
|
169
|
+
get cdp() {
|
|
170
|
+
return this._cdp;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* All screenshots captured into this evidence session, in order.
|
|
174
|
+
*
|
|
175
|
+
* Each entry carries `seq`, `ts`, `label`, `trigger`, and an artifact
|
|
176
|
+
* reference (`artifactId` or `path`). The list is empty when no screenshot
|
|
177
|
+
* has been captured yet or when `screenshots.mode` is `"off"`.
|
|
178
|
+
*/
|
|
179
|
+
get screenshots() {
|
|
180
|
+
return this._screenshotLog;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Capture a screenshot into the evidence stream, subject to the configured
|
|
184
|
+
* {@link ScreenshotMode} and the `trigger` argument.
|
|
185
|
+
*
|
|
186
|
+
* | mode | "step" trigger | "failure" trigger | "manual" trigger |
|
|
187
|
+
* |---------------|----------------|-------------------|------------------|
|
|
188
|
+
* | "off" | skip | skip | skip |
|
|
189
|
+
* | "on-failure" | skip | capture | capture |
|
|
190
|
+
* | "every-step" | capture | capture | capture |
|
|
191
|
+
*
|
|
192
|
+
* Always best-effort: errors from the I/O delegate are silently swallowed
|
|
193
|
+
* so a broken page state never masks the real test error.
|
|
194
|
+
*
|
|
195
|
+
* Does nothing when no `screenshots` option was passed to {@link attach}.
|
|
196
|
+
*/
|
|
197
|
+
async captureShot(label, trigger) {
|
|
198
|
+
const opts = this._screenshotOpts;
|
|
199
|
+
if (!opts)
|
|
200
|
+
return;
|
|
201
|
+
// "off" blocks automatic triggers but manual checkpoints always fire.
|
|
202
|
+
if (opts.mode === "off" && trigger !== "manual")
|
|
203
|
+
return;
|
|
204
|
+
if (opts.mode === "on-failure" && trigger === "step")
|
|
205
|
+
return;
|
|
206
|
+
this._screenshotSeq++;
|
|
207
|
+
const seq = this._screenshotSeq;
|
|
208
|
+
const ts = new Date().toISOString();
|
|
209
|
+
const sanitized = label.replace(/[^a-z0-9_-]/gi, "_").slice(0, 60);
|
|
210
|
+
const tsCompact = ts.replace(/[:.]/g, "").slice(0, 15);
|
|
211
|
+
const prefix = trigger === "failure" ? "FAIL-" : "";
|
|
212
|
+
const filename = `${prefix}${String(seq).padStart(3, "0")}-${sanitized}-${tsCompact}.png`;
|
|
213
|
+
try {
|
|
214
|
+
const ref = await opts.shoot(filename, label, trigger);
|
|
215
|
+
this._screenshotLog.push({ seq, ts, label, trigger, ...ref });
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
// best-effort: page may be in a broken state
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Open one CDP session on `page` and wire up the requested capabilities:
|
|
223
|
+
* Network trace, Fetch mock (guardrail ②), and Emulation (guardrail ① for
|
|
224
|
+
* viewport). Capabilities are only enabled when their config is present, so a
|
|
225
|
+
* page with no mocks never enables `Fetch` and leaves the user's own request
|
|
226
|
+
* interception untouched.
|
|
227
|
+
*/
|
|
228
|
+
static async attach(page, options) {
|
|
229
|
+
const cdp = await page.createCDPSession();
|
|
230
|
+
const session = new EvidenceSession(cdp);
|
|
231
|
+
// Wire screenshot options (no CDP domain — just stores the delegate).
|
|
232
|
+
// Store opts even when mode is "off" so that captureShot can still
|
|
233
|
+
// honour explicit manual checkpoints (captureShot itself gates auto
|
|
234
|
+
// triggers via `if (mode === "off" && trigger !== "manual") return`).
|
|
235
|
+
if (options.screenshots) {
|
|
236
|
+
session._screenshotOpts = options.screenshots;
|
|
237
|
+
}
|
|
238
|
+
try {
|
|
239
|
+
// 1. Network trace.
|
|
240
|
+
if (options.trace) {
|
|
241
|
+
const removeNetwork = await attachNetworkTracer(cdp, {
|
|
242
|
+
trace: options.trace,
|
|
243
|
+
include: options.network?.include,
|
|
244
|
+
excludePaths: options.network?.excludePaths,
|
|
245
|
+
filter: options.network?.filter,
|
|
246
|
+
});
|
|
247
|
+
session._cleanups.push(removeNetwork);
|
|
248
|
+
}
|
|
249
|
+
// 2. Fetch mock — guardrail ②: Glubean owns Fetch, block user interception.
|
|
250
|
+
const mocks = options.mocks;
|
|
251
|
+
if (mocks && mocks.length > 0) {
|
|
252
|
+
await session._installMocks(page, mocks);
|
|
253
|
+
}
|
|
254
|
+
// 3. Emulation (timezone / geolocation) + viewport last (guardrail ①).
|
|
255
|
+
if (options.emulate) {
|
|
256
|
+
for (const call of buildEmulationCalls(options.emulate)) {
|
|
257
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
258
|
+
await cdp.send(call.method, call.params);
|
|
259
|
+
}
|
|
260
|
+
if (options.emulate.viewport) {
|
|
261
|
+
session._guardViewport(page);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
catch (err) {
|
|
266
|
+
// Roll back any partial wiring so we never leak a half-open session.
|
|
267
|
+
await session.detach();
|
|
268
|
+
throw err;
|
|
269
|
+
}
|
|
270
|
+
return session;
|
|
271
|
+
}
|
|
272
|
+
async _installMocks(page, mocks) {
|
|
273
|
+
// Guardrail ②: block the user from enabling Puppeteer request interception
|
|
274
|
+
// while our Fetch mock is active (double-fulfill conflict). Disabling
|
|
275
|
+
// (`false`) is allowed through to the original.
|
|
276
|
+
const restoreInterception = guardPageMethod(page, "setRequestInterception", "Glubean request mocking is active on this page: do not call " +
|
|
277
|
+
"page.setRequestInterception(true) — it conflicts with the mock's " +
|
|
278
|
+
"Fetch handler. Remove the `mock` option to manage interception yourself.", (args) => args[0] === true);
|
|
279
|
+
this._cleanups.push(restoreInterception);
|
|
280
|
+
// Intercept every request at the Request stage; match in JS. Mocked
|
|
281
|
+
// requests are fulfilled, everything else is continued untouched — so the
|
|
282
|
+
// Network tracer still observes real responses.
|
|
283
|
+
await this._cdp.send("Fetch.enable", {
|
|
284
|
+
patterns: [{ urlPattern: "*", requestStage: "Request" }],
|
|
285
|
+
});
|
|
286
|
+
const onPaused = (event) => {
|
|
287
|
+
const rule = findMock(mocks, {
|
|
288
|
+
url: event.request.url,
|
|
289
|
+
method: event.request.method,
|
|
290
|
+
});
|
|
291
|
+
const done = rule
|
|
292
|
+
? this._cdp.send("Fetch.fulfillRequest",
|
|
293
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
294
|
+
buildFulfillParams(rule, event.requestId))
|
|
295
|
+
: this._cdp.send("Fetch.continueRequest", {
|
|
296
|
+
requestId: event.requestId,
|
|
297
|
+
});
|
|
298
|
+
// The request is gone if the page navigated away mid-flight — ignore.
|
|
299
|
+
done.catch(() => { });
|
|
300
|
+
};
|
|
301
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
302
|
+
this._cdp.on("Fetch.requestPaused", onPaused);
|
|
303
|
+
this._cleanups.push(() => {
|
|
304
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
305
|
+
this._cdp.off("Fetch.requestPaused", onPaused);
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
_guardViewport(page) {
|
|
309
|
+
// Guardrail ①: Glubean owns the viewport via Emulation on this session.
|
|
310
|
+
// Block page.setViewport() so it can't clobber the override last-wins.
|
|
311
|
+
const restore = guardPageMethod(page, "setViewport", "Glubean owns the viewport on this page (via the `emulate.viewport` " +
|
|
312
|
+
"option): do not call page.setViewport() — the two overrides race " +
|
|
313
|
+
"last-wins. Configure the viewport through browser({ emulate }) instead.", () => true);
|
|
314
|
+
this._cleanups.push(restore);
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Remove all listeners/overrides, restore guarded page methods, and detach
|
|
318
|
+
* the CDP session. Idempotent and best-effort — safe to call after the page
|
|
319
|
+
* has closed.
|
|
320
|
+
*/
|
|
321
|
+
async detach() {
|
|
322
|
+
if (this._detached)
|
|
323
|
+
return;
|
|
324
|
+
this._detached = true;
|
|
325
|
+
// Run cleanups in reverse (LIFO) so guards/overrides unwind in order.
|
|
326
|
+
for (const cleanup of this._cleanups.reverse()) {
|
|
327
|
+
try {
|
|
328
|
+
await cleanup();
|
|
329
|
+
}
|
|
330
|
+
catch {
|
|
331
|
+
// best-effort — page/session may already be gone
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
this._cleanups.length = 0;
|
|
335
|
+
try {
|
|
336
|
+
await this._cdp.detach();
|
|
337
|
+
}
|
|
338
|
+
catch {
|
|
339
|
+
// session may already be closed
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=evidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence.js","sourceRoot":"","sources":["../src/evidence.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -38,6 +38,7 @@
|
|
|
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,
|
|
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";
|
|
42
43
|
export type { WrappedLocator } from "./locator.js";
|
|
43
44
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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,
|
|
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"}
|