whopper 0.3.2 → 0.5.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/analyzer/apply.d.ts.map +1 -1
- package/dist/analyzer/apply.js +11 -3
- package/dist/analyzer/apply.js.map +1 -1
- package/dist/analyzer/apply.test.js +69 -0
- package/dist/analyzer/apply.test.js.map +1 -1
- package/dist/analyzer/match.d.ts +1 -0
- package/dist/analyzer/match.d.ts.map +1 -1
- package/dist/analyzer/match.js +1 -0
- package/dist/analyzer/match.js.map +1 -1
- package/dist/browser/active_scan.d.ts +5 -0
- package/dist/browser/active_scan.d.ts.map +1 -0
- package/dist/browser/active_scan.js +73 -0
- package/dist/browser/active_scan.js.map +1 -0
- package/dist/browser/active_scan.test.d.ts +2 -0
- package/dist/browser/active_scan.test.d.ts.map +1 -0
- package/dist/browser/active_scan.test.js +207 -0
- package/dist/browser/active_scan.test.js.map +1 -0
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +148 -36
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/index.test.js +141 -3
- package/dist/browser/index.test.js.map +1 -1
- package/dist/browser/types.d.ts +1 -0
- package/dist/browser/types.d.ts.map +1 -1
- package/dist/commands/active_scan_runner.d.ts +5 -0
- package/dist/commands/active_scan_runner.d.ts.map +1 -0
- package/dist/commands/active_scan_runner.js +28 -0
- package/dist/commands/active_scan_runner.js.map +1 -0
- package/dist/commands/active_scan_runner.test.d.ts +2 -0
- package/dist/commands/active_scan_runner.test.d.ts.map +1 -0
- package/dist/commands/active_scan_runner.test.js +80 -0
- package/dist/commands/active_scan_runner.test.js.map +1 -0
- package/dist/commands/detect.d.ts.map +1 -1
- package/dist/commands/detect.js +7 -0
- package/dist/commands/detect.js.map +1 -1
- package/dist/commands/detect.test.js +12 -0
- package/dist/commands/detect.test.js.map +1 -1
- package/dist/signatures/_types.d.ts +7 -0
- package/dist/signatures/_types.d.ts.map +1 -1
- package/dist/signatures/signatures.test.js +24 -2
- package/dist/signatures/signatures.test.js.map +1 -1
- package/dist/signatures/technologies/lodash.d.ts.map +1 -1
- package/dist/signatures/technologies/lodash.js +1 -0
- package/dist/signatures/technologies/lodash.js.map +1 -1
- package/dist/signatures/technologies/lodash.test.d.ts +2 -0
- package/dist/signatures/technologies/lodash.test.d.ts.map +1 -0
- package/dist/signatures/technologies/lodash.test.js +104 -0
- package/dist/signatures/technologies/lodash.test.js.map +1 -0
- package/dist/signatures/technologies/magento.d.ts.map +1 -1
- package/dist/signatures/technologies/magento.js +6 -0
- package/dist/signatures/technologies/magento.js.map +1 -1
- package/dist/signatures/technologies/magento.test.d.ts +2 -0
- package/dist/signatures/technologies/magento.test.d.ts.map +1 -0
- package/dist/signatures/technologies/magento.test.js +28 -0
- package/dist/signatures/technologies/magento.test.js.map +1 -0
- package/dist/signatures/technologies/underscore_js.d.ts.map +1 -1
- package/dist/signatures/technologies/underscore_js.js +2 -0
- package/dist/signatures/technologies/underscore_js.js.map +1 -1
- package/dist/signatures/technologies/underscore_js.test.d.ts +2 -0
- package/dist/signatures/technologies/underscore_js.test.d.ts.map +1 -0
- package/dist/signatures/technologies/underscore_js.test.js +94 -0
- package/dist/signatures/technologies/underscore_js.test.js.map +1 -0
- package/package.json +1 -1
package/dist/browser/index.js
CHANGED
|
@@ -3,6 +3,15 @@ import { chromium } from "playwright";
|
|
|
3
3
|
import { logger } from "../logger/index.js";
|
|
4
4
|
import { extractJsVariables, getHostFromUrl, isFirstPartyHost, isSameHost, sleep, } from "./utils.js";
|
|
5
5
|
const MAX_REDIRECT_HOPS = 20;
|
|
6
|
+
// Quiet period (ms) used for the custom network-idle decision.
|
|
7
|
+
// Playwright's built-in `networkidle` has a fixed 500ms threshold, which
|
|
8
|
+
// is too short: it fires before script-driven secondary requests (e.g. a
|
|
9
|
+
// CSS file loaded from within an async script) have a chance to start,
|
|
10
|
+
// causing technology-detection evidence to be dropped. We use a longer
|
|
11
|
+
// threshold evaluated by our own tracking.
|
|
12
|
+
const NETWORK_IDLE_THRESHOLD_MS = 2000;
|
|
13
|
+
// Polling interval (ms) for the idle-decision loop.
|
|
14
|
+
const NETWORK_IDLE_POLL_INTERVAL_MS = 200;
|
|
6
15
|
function colorizeStatusCode(statusCode) {
|
|
7
16
|
const code = String(statusCode);
|
|
8
17
|
if (statusCode >= 100 && statusCode < 200) {
|
|
@@ -23,7 +32,7 @@ function colorizeStatusCode(statusCode) {
|
|
|
23
32
|
return chalk.gray(code);
|
|
24
33
|
}
|
|
25
34
|
export async function openPage(url, timeoutMs, javascriptVariableNames, options = {}) {
|
|
26
|
-
const { userAgent, locale, extraHTTPHeaders, blockCrossDomainRedirect = false, } = options;
|
|
35
|
+
const { userAgent, locale, extraHTTPHeaders, blockCrossDomainRedirect = false, networkIdleThresholdMs = NETWORK_IDLE_THRESHOLD_MS, } = options;
|
|
27
36
|
const pageHost = getHostFromUrl(url);
|
|
28
37
|
if (!pageHost) {
|
|
29
38
|
throw new Error(`Invalid URL: ${url}`);
|
|
@@ -68,8 +77,7 @@ export async function openPage(url, timeoutMs, javascriptVariableNames, options
|
|
|
68
77
|
await route.continue();
|
|
69
78
|
return;
|
|
70
79
|
}
|
|
71
|
-
if (blockCrossDomainRedirect &&
|
|
72
|
-
!isSameHost(pageHost, targetHost)) {
|
|
80
|
+
if (blockCrossDomainRedirect && !isSameHost(pageHost, targetHost)) {
|
|
73
81
|
logger.warn(`Blocked cross-domain redirect: ${targetUrl}`);
|
|
74
82
|
blockedByRedirectPolicy = true;
|
|
75
83
|
urls.push({ url: targetUrl, error: "Blocked cross-domain redirect" });
|
|
@@ -104,7 +112,9 @@ export async function openPage(url, timeoutMs, javascriptVariableNames, options
|
|
|
104
112
|
// URLs captured here are added to preInspectedUrls so that the
|
|
105
113
|
// page.on("response") listener can skip them and avoid duplicates.
|
|
106
114
|
const firstResponse = response;
|
|
107
|
-
for (let hop = 0; hop < MAX_REDIRECT_HOPS &&
|
|
115
|
+
for (let hop = 0; hop < MAX_REDIRECT_HOPS &&
|
|
116
|
+
response.status() >= 300 &&
|
|
117
|
+
response.status() < 400; hop++) {
|
|
108
118
|
// Capture intermediate 3xx responses so their headers (e.g. server,
|
|
109
119
|
// x-powered-by) are available for analysis even though the browser
|
|
110
120
|
// never sees these responses directly.
|
|
@@ -161,44 +171,146 @@ export async function openPage(url, timeoutMs, javascriptVariableNames, options
|
|
|
161
171
|
});
|
|
162
172
|
const urls = [];
|
|
163
173
|
const responses = [];
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
174
|
+
// Timestamp of the most recent network activity (request sent or
|
|
175
|
+
// response received). Used by the custom idle-decision loop below.
|
|
176
|
+
let lastNetworkActivityAt = Date.now();
|
|
177
|
+
// Number of requests currently in flight. We include this in the idle
|
|
178
|
+
// condition so that a request whose response takes longer than the
|
|
179
|
+
// quiet-period threshold cannot cause the loop to exit before the
|
|
180
|
+
// response is captured.
|
|
181
|
+
let inFlightRequestCount = 0;
|
|
182
|
+
// Pending response-handler promises. The response handler awaits
|
|
183
|
+
// `response.text()`, which can still be in progress when the idle loop
|
|
184
|
+
// decides to break; awaiting this set after the loop prevents those
|
|
185
|
+
// in-progress body reads from being dropped.
|
|
186
|
+
const pendingResponseWork = new Set();
|
|
187
|
+
const onRequest = () => {
|
|
188
|
+
inFlightRequestCount++;
|
|
189
|
+
lastNetworkActivityAt = Date.now();
|
|
190
|
+
};
|
|
191
|
+
const onRequestFinished = () => {
|
|
192
|
+
inFlightRequestCount = Math.max(0, inFlightRequestCount - 1);
|
|
193
|
+
lastNetworkActivityAt = Date.now();
|
|
194
|
+
};
|
|
195
|
+
const onRequestFailed = () => {
|
|
196
|
+
inFlightRequestCount = Math.max(0, inFlightRequestCount - 1);
|
|
197
|
+
lastNetworkActivityAt = Date.now();
|
|
198
|
+
};
|
|
199
|
+
const onResponse = (response) => {
|
|
200
|
+
lastNetworkActivityAt = Date.now();
|
|
201
|
+
const work = (async () => {
|
|
202
|
+
const responseUrl = response.url();
|
|
203
|
+
const statusCode = response.status();
|
|
204
|
+
// Skip responses already captured by the pre-inspection loop to
|
|
205
|
+
// avoid duplicates.
|
|
206
|
+
if (preInspectedUrls.has(responseUrl) &&
|
|
207
|
+
statusCode >= 300 &&
|
|
208
|
+
statusCode < 400) {
|
|
209
|
+
logger.debug(`Skipping already captured response [${colorizeStatusCode(statusCode)}] ${responseUrl}`);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const responseHost = getHostFromUrl(responseUrl) ?? "";
|
|
213
|
+
logger.debug(`Received response [${colorizeStatusCode(statusCode)}] ${responseUrl}`);
|
|
214
|
+
const request = response.request();
|
|
215
|
+
if (request.isNavigationRequest() &&
|
|
216
|
+
request.frame() === page.mainFrame()) {
|
|
217
|
+
urls.push({ url: responseUrl, status: statusCode });
|
|
218
|
+
}
|
|
219
|
+
const res = {
|
|
220
|
+
url: responseUrl,
|
|
221
|
+
host: responseHost,
|
|
222
|
+
isFirstParty: responseHost
|
|
223
|
+
? isFirstPartyHost(pageHost, responseHost)
|
|
224
|
+
: false,
|
|
225
|
+
status: statusCode,
|
|
226
|
+
headers: response.headers(),
|
|
227
|
+
};
|
|
228
|
+
const body = await response.text().catch(() => null);
|
|
229
|
+
if (body) {
|
|
230
|
+
res.body = body;
|
|
231
|
+
}
|
|
232
|
+
responses.push(res);
|
|
233
|
+
})();
|
|
234
|
+
pendingResponseWork.add(work);
|
|
235
|
+
work.finally(() => {
|
|
236
|
+
pendingResponseWork.delete(work);
|
|
237
|
+
});
|
|
238
|
+
};
|
|
239
|
+
page.on("request", onRequest);
|
|
240
|
+
page.on("requestfinished", onRequestFinished);
|
|
241
|
+
page.on("requestfailed", onRequestFailed);
|
|
242
|
+
page.on("response", onResponse);
|
|
194
243
|
let timeoutOccurred = false;
|
|
195
|
-
const
|
|
244
|
+
const navigationStartedAt = Date.now();
|
|
245
|
+
// Playwright's built-in `networkidle` is flaky (500ms fixed threshold),
|
|
246
|
+
// so resolve goto at the `load` event (onload fired) and wait for
|
|
247
|
+
// secondary requests triggered by deferred scripts using our own
|
|
248
|
+
// idle-decision loop below.
|
|
249
|
+
const goto = page.goto(url, { waitUntil: "load" });
|
|
196
250
|
const result = await Promise.race([
|
|
197
251
|
goto.then(() => "loaded").catch((e) => e.message),
|
|
198
252
|
sleep(timeoutMs).then(() => "timeout"),
|
|
199
253
|
]);
|
|
254
|
+
// After onload, wait until all in-flight requests have finished and a
|
|
255
|
+
// quiet period of `networkIdleThresholdMs` has elapsed (or the overall
|
|
256
|
+
// timeout is reached) so that secondary requests triggered by deferred
|
|
257
|
+
// scripts are captured. Including in-flight count in the condition
|
|
258
|
+
// prevents the loop from exiting while a slow response
|
|
259
|
+
// (> networkIdleThresholdMs) is still pending.
|
|
260
|
+
//
|
|
261
|
+
// Tracks whether the loop exited because the network actually went
|
|
262
|
+
// idle, or because the overall timeout budget was exhausted. In the
|
|
263
|
+
// latter case we must return `timeoutOccurred: true` so callers can
|
|
264
|
+
// distinguish a full capture from a partial one.
|
|
265
|
+
let idleWaitTimedOut = false;
|
|
200
266
|
if (result === "loaded") {
|
|
201
|
-
|
|
267
|
+
while (true) {
|
|
268
|
+
const now = Date.now();
|
|
269
|
+
const elapsed = now - navigationStartedAt;
|
|
270
|
+
if (elapsed >= timeoutMs) {
|
|
271
|
+
idleWaitTimedOut = true;
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
const idleFor = now - lastNetworkActivityAt;
|
|
275
|
+
if (inFlightRequestCount === 0 && idleFor >= networkIdleThresholdMs) {
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
const remainingBudget = timeoutMs - elapsed;
|
|
279
|
+
await sleep(Math.min(NETWORK_IDLE_POLL_INTERVAL_MS, remainingBudget));
|
|
280
|
+
}
|
|
281
|
+
// If any response handlers are still running at loop exit (e.g.
|
|
282
|
+
// waiting on `response.text()`), wait for them to finish so their
|
|
283
|
+
// captures are not dropped. However, do not wait beyond the overall
|
|
284
|
+
// timeout: race against the remaining budget so that when the budget
|
|
285
|
+
// is exhausted we drop any still-pending in-flight captures rather
|
|
286
|
+
// than letting the process block indefinitely on slow body reads.
|
|
287
|
+
if (pendingResponseWork.size > 0) {
|
|
288
|
+
const remainingBudget = Math.max(0, timeoutMs - (Date.now() - navigationStartedAt));
|
|
289
|
+
if (remainingBudget > 0) {
|
|
290
|
+
await Promise.race([
|
|
291
|
+
Promise.allSettled(Array.from(pendingResponseWork)),
|
|
292
|
+
sleep(remainingBudget),
|
|
293
|
+
]);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// Detach network listeners so that the `responses` snapshot is frozen
|
|
298
|
+
// at this point. Subsequent activity from cookie/JS extraction (or any
|
|
299
|
+
// delayed in-flight responses) must not mutate the captured set, since
|
|
300
|
+
// those entries would not be awaited and could race with the return.
|
|
301
|
+
page.off("request", onRequest);
|
|
302
|
+
page.off("requestfinished", onRequestFinished);
|
|
303
|
+
page.off("requestfailed", onRequestFailed);
|
|
304
|
+
page.off("response", onResponse);
|
|
305
|
+
logger.info(`${responses.length} responses captured`);
|
|
306
|
+
if (result === "loaded") {
|
|
307
|
+
if (idleWaitTimedOut) {
|
|
308
|
+
timeoutOccurred = true;
|
|
309
|
+
logger.warn(`Timeout of ${timeoutMs}ms exceeded while waiting for network idle after load on ${url}`);
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
logger.info("Page loaded successfully");
|
|
313
|
+
}
|
|
202
314
|
}
|
|
203
315
|
else if (result === "timeout") {
|
|
204
316
|
timeoutOccurred = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,7 @@ import { openPage } from "./index.js";
|
|
|
4
4
|
vi.mock("playwright", () => {
|
|
5
5
|
const mockPage = {
|
|
6
6
|
on: vi.fn(),
|
|
7
|
+
off: vi.fn(),
|
|
7
8
|
route: vi.fn(),
|
|
8
9
|
mainFrame: vi.fn(),
|
|
9
10
|
goto: vi.fn(),
|
|
@@ -55,6 +56,7 @@ describe("openPage", () => {
|
|
|
55
56
|
// Get references to mocked objects
|
|
56
57
|
mockPage = {
|
|
57
58
|
on: vi.fn(),
|
|
59
|
+
off: vi.fn(),
|
|
58
60
|
route: vi.fn(),
|
|
59
61
|
mainFrame: vi.fn(),
|
|
60
62
|
goto: vi.fn(() => Promise.resolve()),
|
|
@@ -90,7 +92,9 @@ describe("openPage", () => {
|
|
|
90
92
|
});
|
|
91
93
|
});
|
|
92
94
|
it("should pass custom userAgent to browser context", async () => {
|
|
93
|
-
await openPage("https://example.com", 10000, [], {
|
|
95
|
+
await openPage("https://example.com", 10000, [], {
|
|
96
|
+
userAgent: "MyCustomAgent/1.0",
|
|
97
|
+
});
|
|
94
98
|
expect(mockBrowser.newContext).toHaveBeenCalledWith({
|
|
95
99
|
ignoreHTTPSErrors: true,
|
|
96
100
|
userAgent: "MyCustomAgent/1.0",
|
|
@@ -115,7 +119,7 @@ describe("openPage", () => {
|
|
|
115
119
|
it("should navigate to the specified URL", async () => {
|
|
116
120
|
await openPage("https://example.com", 10000, []);
|
|
117
121
|
expect(mockPage.goto).toHaveBeenCalledWith("https://example.com", {
|
|
118
|
-
waitUntil: "
|
|
122
|
+
waitUntil: "load",
|
|
119
123
|
});
|
|
120
124
|
});
|
|
121
125
|
it("should log success message on successful load", async () => {
|
|
@@ -176,7 +180,9 @@ describe("openPage", () => {
|
|
|
176
180
|
mockPage.route.mockImplementation(async (_pattern, handler) => {
|
|
177
181
|
routeHandler = handler;
|
|
178
182
|
});
|
|
179
|
-
await openPage("https://example.com", 10000, [], {
|
|
183
|
+
await openPage("https://example.com", 10000, [], {
|
|
184
|
+
blockCrossDomainRedirect: false,
|
|
185
|
+
});
|
|
180
186
|
const mockResponse = { status: () => 200, headers: () => ({}) };
|
|
181
187
|
const continueMock = vi.fn(() => Promise.resolve());
|
|
182
188
|
const abortMock = vi.fn(() => Promise.resolve());
|
|
@@ -1004,6 +1010,138 @@ describe("openPage", () => {
|
|
|
1004
1010
|
expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining("Timeout"));
|
|
1005
1011
|
});
|
|
1006
1012
|
});
|
|
1013
|
+
describe("network idle tracking", () => {
|
|
1014
|
+
it("should register request, requestfinished, and requestfailed listeners", async () => {
|
|
1015
|
+
await openPage("https://example.com", 10000, []);
|
|
1016
|
+
const registeredEvents = mockPage.on.mock.calls.map((call) => call[0]);
|
|
1017
|
+
expect(registeredEvents).toContain("request");
|
|
1018
|
+
expect(registeredEvents).toContain("requestfinished");
|
|
1019
|
+
expect(registeredEvents).toContain("requestfailed");
|
|
1020
|
+
expect(registeredEvents).toContain("response");
|
|
1021
|
+
});
|
|
1022
|
+
it("should set timeoutOccurred when idle wait exhausts timeout budget", async () => {
|
|
1023
|
+
mockPage.goto.mockResolvedValue(undefined);
|
|
1024
|
+
// Use setTimeout(0) so sleep resolves via a macrotask (ensuring
|
|
1025
|
+
// goto's microtask chain wins the race with "loaded"), while still
|
|
1026
|
+
// being fast enough for the idle loop to spin through quickly.
|
|
1027
|
+
vi.mocked(sleep).mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 0)));
|
|
1028
|
+
// Very short timeout: the idle loop will exhaust the budget before
|
|
1029
|
+
// the NETWORK_IDLE_THRESHOLD_MS (2000ms) quiet period is reached.
|
|
1030
|
+
const result = await openPage("https://example.com", 10, []);
|
|
1031
|
+
expect(result.timeoutOccurred).toBe(true);
|
|
1032
|
+
expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining("waiting for network idle after load"));
|
|
1033
|
+
});
|
|
1034
|
+
it("should wait for in-flight requests before declaring idle", async () => {
|
|
1035
|
+
const listeners = {};
|
|
1036
|
+
mockPage.on.mockImplementation((event, callback) => {
|
|
1037
|
+
listeners[event] = callback;
|
|
1038
|
+
});
|
|
1039
|
+
// During goto, fire a request event but NOT requestfinished,
|
|
1040
|
+
// so the request stays in-flight.
|
|
1041
|
+
mockPage.goto.mockImplementation(async () => {
|
|
1042
|
+
listeners["request"]?.();
|
|
1043
|
+
});
|
|
1044
|
+
vi.mocked(sleep).mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 0)));
|
|
1045
|
+
// With an in-flight request (count=1), the idle condition
|
|
1046
|
+
// (inFlightRequestCount === 0) is never met, so the loop can
|
|
1047
|
+
// only exit via timeout budget exhaustion.
|
|
1048
|
+
const result = await openPage("https://example.com", 10, []);
|
|
1049
|
+
expect(result.timeoutOccurred).toBe(true);
|
|
1050
|
+
});
|
|
1051
|
+
it("should exit idle loop after requestfinished fires", async () => {
|
|
1052
|
+
const listeners = {};
|
|
1053
|
+
mockPage.on.mockImplementation((event, callback) => {
|
|
1054
|
+
listeners[event] = callback;
|
|
1055
|
+
});
|
|
1056
|
+
mockPage.goto.mockImplementation(async () => {
|
|
1057
|
+
listeners["request"]?.();
|
|
1058
|
+
listeners["requestfinished"]?.();
|
|
1059
|
+
});
|
|
1060
|
+
vi.mocked(sleep).mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 100)));
|
|
1061
|
+
const result = await openPage("https://example.com", 10000, []);
|
|
1062
|
+
expect(result.timeoutOccurred).toBe(false);
|
|
1063
|
+
expect(logger.info).toHaveBeenCalledWith("Page loaded successfully");
|
|
1064
|
+
});
|
|
1065
|
+
it("should exit idle loop after requestfailed fires", async () => {
|
|
1066
|
+
const listeners = {};
|
|
1067
|
+
mockPage.on.mockImplementation((event, callback) => {
|
|
1068
|
+
listeners[event] = callback;
|
|
1069
|
+
});
|
|
1070
|
+
mockPage.goto.mockImplementation(async () => {
|
|
1071
|
+
listeners["request"]?.();
|
|
1072
|
+
listeners["requestfailed"]?.();
|
|
1073
|
+
});
|
|
1074
|
+
vi.mocked(sleep).mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 100)));
|
|
1075
|
+
const result = await openPage("https://example.com", 10000, []);
|
|
1076
|
+
expect(result.timeoutOccurred).toBe(false);
|
|
1077
|
+
expect(logger.info).toHaveBeenCalledWith("Page loaded successfully");
|
|
1078
|
+
});
|
|
1079
|
+
it("should await pending response handlers within remaining timeout budget", async () => {
|
|
1080
|
+
const listeners = {};
|
|
1081
|
+
mockPage.on.mockImplementation((event, callback) => {
|
|
1082
|
+
listeners[event] = callback;
|
|
1083
|
+
});
|
|
1084
|
+
let resolveText;
|
|
1085
|
+
const textPromise = new Promise((resolve) => {
|
|
1086
|
+
resolveText = resolve;
|
|
1087
|
+
});
|
|
1088
|
+
// During goto, fire a response whose text() resolves quickly.
|
|
1089
|
+
mockPage.goto.mockImplementation(async () => {
|
|
1090
|
+
listeners["response"]?.({
|
|
1091
|
+
url: () => "https://example.com/quick.js",
|
|
1092
|
+
status: () => 200,
|
|
1093
|
+
headers: () => ({}),
|
|
1094
|
+
text: () => textPromise,
|
|
1095
|
+
request: () => ({
|
|
1096
|
+
isNavigationRequest: () => false,
|
|
1097
|
+
frame: () => null,
|
|
1098
|
+
}),
|
|
1099
|
+
});
|
|
1100
|
+
});
|
|
1101
|
+
vi.mocked(sleep).mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 0)));
|
|
1102
|
+
// Generous timeout; resolve text() after the idle loop has exited.
|
|
1103
|
+
const openPagePromise = openPage("https://example.com", 5000, []);
|
|
1104
|
+
setTimeout(() => resolveText("quick content"), 20);
|
|
1105
|
+
const result = await openPagePromise;
|
|
1106
|
+
// text() completes within the remaining budget, so the response
|
|
1107
|
+
// should be captured.
|
|
1108
|
+
const quickResponse = result.responses.find((r) => r.url === "https://example.com/quick.js");
|
|
1109
|
+
expect(quickResponse).toBeDefined();
|
|
1110
|
+
expect(quickResponse.body).toBe("quick content");
|
|
1111
|
+
});
|
|
1112
|
+
it("should not wait for pending response handlers beyond overall timeout", async () => {
|
|
1113
|
+
const listeners = {};
|
|
1114
|
+
mockPage.on.mockImplementation((event, callback) => {
|
|
1115
|
+
listeners[event] = callback;
|
|
1116
|
+
});
|
|
1117
|
+
// Fire a response whose text() never resolves.
|
|
1118
|
+
const neverResolves = new Promise(() => { });
|
|
1119
|
+
mockPage.goto.mockImplementation(async () => {
|
|
1120
|
+
listeners["response"]?.({
|
|
1121
|
+
url: () => "https://example.com/hang.js",
|
|
1122
|
+
status: () => 200,
|
|
1123
|
+
headers: () => ({}),
|
|
1124
|
+
text: () => neverResolves,
|
|
1125
|
+
request: () => ({
|
|
1126
|
+
isNavigationRequest: () => false,
|
|
1127
|
+
frame: () => null,
|
|
1128
|
+
}),
|
|
1129
|
+
});
|
|
1130
|
+
});
|
|
1131
|
+
vi.mocked(sleep).mockImplementation(() => new Promise((resolve) => setTimeout(resolve, 0)));
|
|
1132
|
+
// Even with a short timeout, openPage must return once the budget
|
|
1133
|
+
// is exhausted rather than waiting on the hanging text() call.
|
|
1134
|
+
const start = Date.now();
|
|
1135
|
+
const result = await openPage("https://example.com", 50, []);
|
|
1136
|
+
const elapsed = Date.now() - start;
|
|
1137
|
+
// Must not wait significantly beyond the overall timeout
|
|
1138
|
+
// (with generous slack for CI jitter).
|
|
1139
|
+
expect(elapsed).toBeLessThan(2000);
|
|
1140
|
+
// The hanging response is dropped (body never captured).
|
|
1141
|
+
const hangResponse = result.responses.find((r) => r.url === "https://example.com/hang.js");
|
|
1142
|
+
expect(hangResponse).toBeUndefined();
|
|
1143
|
+
});
|
|
1144
|
+
});
|
|
1007
1145
|
describe("error handling", () => {
|
|
1008
1146
|
it("should log error when page load fails", async () => {
|
|
1009
1147
|
mockPage.goto.mockRejectedValue(new Error("Connection refused"));
|