@skrillex1224/playwright-toolkit 3.0.10 → 3.0.11
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/browser.js +0 -12
- package/dist/index.cjs +59 -95
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +60 -96
- package/dist/index.js.map +4 -4
- package/dist/internals/proxy-meter.js +5 -51
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -122,7 +122,6 @@ var createActorInfo = (info) => {
|
|
|
122
122
|
const buildLandingUrl = ({ protocol: protocol2, domain: domain2, path: path4 }) => {
|
|
123
123
|
const safeProtocol = String(protocol2).trim();
|
|
124
124
|
const safeDomain = normalizeDomain(domain2);
|
|
125
|
-
if (!safeDomain) return "";
|
|
126
125
|
const safePath = normalizePath(path4);
|
|
127
126
|
return `${safeProtocol}://${safeDomain}${safePath}`;
|
|
128
127
|
};
|
|
@@ -330,17 +329,6 @@ var ActorInfo = {
|
|
|
330
329
|
prefix: "",
|
|
331
330
|
xurl: []
|
|
332
331
|
}
|
|
333
|
-
}),
|
|
334
|
-
webpage: createActorInfo({
|
|
335
|
-
key: "webpage",
|
|
336
|
-
name: "\u901A\u7528\u7F51\u9875",
|
|
337
|
-
domain: "",
|
|
338
|
-
path: "/",
|
|
339
|
-
share: {
|
|
340
|
-
mode: "dom",
|
|
341
|
-
prefix: "",
|
|
342
|
-
xurl: []
|
|
343
|
-
}
|
|
344
332
|
})
|
|
345
333
|
};
|
|
346
334
|
|
|
@@ -1071,7 +1059,7 @@ import { serializeError as serializeError2 } from "serialize-error";
|
|
|
1071
1059
|
|
|
1072
1060
|
// src/internals/proxy-meter-runtime.js
|
|
1073
1061
|
import { spawn, spawnSync } from "child_process";
|
|
1074
|
-
import {
|
|
1062
|
+
import { existsSync, mkdirSync, readFileSync, rmSync } from "fs";
|
|
1075
1063
|
import { tmpdir } from "os";
|
|
1076
1064
|
import path from "path";
|
|
1077
1065
|
import { fileURLToPath } from "url";
|
|
@@ -1180,18 +1168,6 @@ var ensureLogPath = () => {
|
|
|
1180
1168
|
const label = runId ? `proxy-meter-${runId}-${suffix}.json` : `proxy-meter-${process.pid}-${suffix}.json`;
|
|
1181
1169
|
return path.join(baseDir, label);
|
|
1182
1170
|
};
|
|
1183
|
-
var ensureStdioLogPath = (logPath) => `${logPath}.stdio.log`;
|
|
1184
|
-
var writeChildOutput = (stream, output, prefix) => {
|
|
1185
|
-
if (!stream || !output) return;
|
|
1186
|
-
output.on("data", (chunk) => {
|
|
1187
|
-
const text = chunk?.toString?.() || String(chunk || "");
|
|
1188
|
-
if (!text) return;
|
|
1189
|
-
for (const line of text.split(/\r?\n/)) {
|
|
1190
|
-
if (!line) continue;
|
|
1191
|
-
stream.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] ${prefix} ${line}\n`);
|
|
1192
|
-
}
|
|
1193
|
-
});
|
|
1194
|
-
};
|
|
1195
1171
|
var readSnapshot = (logPath) => {
|
|
1196
1172
|
if (!logPath || !existsSync(logPath)) return null;
|
|
1197
1173
|
try {
|
|
@@ -1359,7 +1335,6 @@ var startProxyMeter = (options = {}) => {
|
|
|
1359
1335
|
observedDomainResourceTypes = /* @__PURE__ */ new Map();
|
|
1360
1336
|
const port = pickFreePort();
|
|
1361
1337
|
const logPath = ensureLogPath();
|
|
1362
|
-
const stdioLogPath = ensureStdioLogPath(logPath);
|
|
1363
1338
|
const scriptPath = resolveScriptPath();
|
|
1364
1339
|
const debugMode = Boolean(options.debugMode);
|
|
1365
1340
|
const debugMaxEvents = Math.max(10, toSafeInt(options.debugMaxEvents) || DEFAULT_DEBUG_MAX_EVENTS);
|
|
@@ -1372,26 +1347,19 @@ var startProxyMeter = (options = {}) => {
|
|
|
1372
1347
|
PROXY_METER_DEBUG: debugMode ? "1" : "0",
|
|
1373
1348
|
PROXY_METER_DEBUG_MAX_EVENTS: String(debugMaxEvents)
|
|
1374
1349
|
};
|
|
1375
|
-
const stdioLog = createWriteStream(stdioLogPath, { flags: "a" });
|
|
1376
|
-
stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] start script=${scriptPath} port=${port} snapshot=${logPath}\n`);
|
|
1377
1350
|
const child = spawn(process.execPath, [scriptPath], {
|
|
1378
1351
|
env,
|
|
1379
|
-
stdio: ["ignore", "
|
|
1352
|
+
stdio: ["ignore", "ignore", "ignore"]
|
|
1380
1353
|
});
|
|
1381
|
-
|
|
1382
|
-
writeChildOutput(stdioLog, child.stderr, "stderr");
|
|
1383
|
-
child.once("exit", (code, signal) => {
|
|
1384
|
-
stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] exit code=${code ?? ""} signal=${signal ?? ""}\n`);
|
|
1385
|
-
stdioLog.end();
|
|
1354
|
+
child.once("exit", (code) => {
|
|
1386
1355
|
if (code && code !== 0) {
|
|
1387
|
-
logger2.warn(`[proxy-meter] exited with code ${code}
|
|
1356
|
+
logger2.warn(`[proxy-meter] exited with code ${code}`);
|
|
1388
1357
|
}
|
|
1389
1358
|
});
|
|
1390
1359
|
runtime = {
|
|
1391
1360
|
proc: child,
|
|
1392
1361
|
port,
|
|
1393
1362
|
logPath,
|
|
1394
|
-
stdioLogPath,
|
|
1395
1363
|
startedAt: Date.now()
|
|
1396
1364
|
};
|
|
1397
1365
|
registerCleanup();
|
|
@@ -5615,9 +5583,6 @@ var LiveView = {
|
|
|
5615
5583
|
useLiveView
|
|
5616
5584
|
};
|
|
5617
5585
|
|
|
5618
|
-
// src/chaptcha.js
|
|
5619
|
-
import { v4 as uuidv4 } from "uuid";
|
|
5620
|
-
|
|
5621
5586
|
// src/internals/captcha/bytedance.js
|
|
5622
5587
|
import { mkdir, writeFile } from "fs/promises";
|
|
5623
5588
|
import path2 from "path";
|
|
@@ -6276,6 +6241,9 @@ var sloveCaptcha = solveCaptcha;
|
|
|
6276
6241
|
|
|
6277
6242
|
// src/chaptcha.js
|
|
6278
6243
|
var logger12 = createInternalLogger("Captcha");
|
|
6244
|
+
var DOM_MONITOR_WAIT_TIMEOUT_MS = 1e3;
|
|
6245
|
+
var DOM_MONITOR_POST_DETECT_HIDDEN_WAIT_MS = 300;
|
|
6246
|
+
var DOM_MONITOR_RECOVERY_WAIT_MS = 100;
|
|
6279
6247
|
var DEFAULT_CAPTCHA_RECOGNITION_OPTIONS = Object.freeze({
|
|
6280
6248
|
token: "eKJvBfwfN0YRav0-VD_44E2VBSfm7l0YtddUQ7cFySI",
|
|
6281
6249
|
apiUrl: "https://api.jfbym.com/api/YmServer/customApi"
|
|
@@ -6296,6 +6264,15 @@ var mergeDefinedOptions = (...sources) => {
|
|
|
6296
6264
|
}
|
|
6297
6265
|
return merged;
|
|
6298
6266
|
};
|
|
6267
|
+
var sleep = (ms) => new Promise((resolve) => {
|
|
6268
|
+
setTimeout(resolve, ms);
|
|
6269
|
+
});
|
|
6270
|
+
var getErrorMessage = (error) => String(error?.message || error || "");
|
|
6271
|
+
var isTimeoutError = (error) => error?.name === "TimeoutError" || getErrorMessage(error).includes("Timeout");
|
|
6272
|
+
var isPageLifecycleError = (error) => {
|
|
6273
|
+
const message = getErrorMessage(error);
|
|
6274
|
+
return message.includes("Execution context was destroyed") || message.includes("Frame was detached") || message.includes("Target page, context or browser has been closed") || message.includes("Target closed") || message.includes("Most likely the page has been closed");
|
|
6275
|
+
};
|
|
6299
6276
|
function useCaptchaMonitor(page, options) {
|
|
6300
6277
|
const { domSelector, urlPattern, onDetected } = options;
|
|
6301
6278
|
if (!domSelector && !urlPattern) {
|
|
@@ -6307,10 +6284,13 @@ function useCaptchaMonitor(page, options) {
|
|
|
6307
6284
|
let isStopped = false;
|
|
6308
6285
|
let isHandling = false;
|
|
6309
6286
|
let frameHandler = null;
|
|
6310
|
-
let
|
|
6287
|
+
let domMonitorTask = null;
|
|
6288
|
+
let lastTriggeredAt = 0;
|
|
6311
6289
|
const triggerDetected = async () => {
|
|
6312
|
-
|
|
6290
|
+
const now = Date.now();
|
|
6291
|
+
if (isStopped || isHandling || now - lastTriggeredAt < 250) return;
|
|
6313
6292
|
isHandling = true;
|
|
6293
|
+
lastTriggeredAt = now;
|
|
6314
6294
|
try {
|
|
6315
6295
|
await onDetected();
|
|
6316
6296
|
} finally {
|
|
@@ -6319,60 +6299,38 @@ function useCaptchaMonitor(page, options) {
|
|
|
6319
6299
|
};
|
|
6320
6300
|
const cleanupFns = [];
|
|
6321
6301
|
if (domSelector) {
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
|
|
6330
|
-
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
}
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
const shouldCheck = mutations.some((mutation) => mutation.addedNodes.length > 0);
|
|
6342
|
-
if (shouldCheck && observer) {
|
|
6343
|
-
checkAndReport();
|
|
6344
|
-
}
|
|
6345
|
-
});
|
|
6346
|
-
const mountObserver = () => {
|
|
6347
|
-
const target = document.documentElement;
|
|
6348
|
-
if (target && observer) {
|
|
6349
|
-
observer.observe(target, { childList: true, subtree: true });
|
|
6302
|
+
domMonitorTask = (async () => {
|
|
6303
|
+
const locator = page.locator(domSelector).first();
|
|
6304
|
+
while (!isStopped) {
|
|
6305
|
+
try {
|
|
6306
|
+
await locator.waitFor({ state: "visible", timeout: DOM_MONITOR_WAIT_TIMEOUT_MS });
|
|
6307
|
+
if (isStopped) break;
|
|
6308
|
+
await triggerDetected();
|
|
6309
|
+
if (isStopped) break;
|
|
6310
|
+
await locator.waitFor({
|
|
6311
|
+
state: "hidden",
|
|
6312
|
+
timeout: DOM_MONITOR_POST_DETECT_HIDDEN_WAIT_MS
|
|
6313
|
+
}).catch(() => {
|
|
6314
|
+
});
|
|
6315
|
+
} catch (error) {
|
|
6316
|
+
if (isStopped) break;
|
|
6317
|
+
if (page?.isClosed?.() && isPageLifecycleError(error)) break;
|
|
6318
|
+
if (isTimeoutError(error) || isPageLifecycleError(error)) {
|
|
6319
|
+
await sleep(DOM_MONITOR_RECOVERY_WAIT_MS);
|
|
6320
|
+
continue;
|
|
6350
6321
|
}
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
|
|
6322
|
+
logger12.warning(
|
|
6323
|
+
"useCaptchaMonitor",
|
|
6324
|
+
`DOM \u76D1\u63A7\u51FA\u73B0\u5F02\u5E38\uFF08\u7EE7\u7EED\u91CD\u8BD5\uFF09: selector=${domSelector}, error=${getErrorMessage(error)}`
|
|
6325
|
+
);
|
|
6326
|
+
await sleep(DOM_MONITOR_RECOVERY_WAIT_MS);
|
|
6356
6327
|
}
|
|
6357
|
-
|
|
6358
|
-
|
|
6359
|
-
observer.disconnect();
|
|
6360
|
-
observer = null;
|
|
6361
|
-
}
|
|
6362
|
-
};
|
|
6363
|
-
})();
|
|
6364
|
-
}, { selector: domSelector, callbackName: exposedFunctionName, cleanerName });
|
|
6328
|
+
}
|
|
6329
|
+
})();
|
|
6365
6330
|
logger12.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${domSelector}`);
|
|
6366
6331
|
cleanupFns.push(async () => {
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
if (window[name]) {
|
|
6370
|
-
window[name]();
|
|
6371
|
-
delete window[name];
|
|
6372
|
-
}
|
|
6373
|
-
}, cleanerName);
|
|
6374
|
-
} catch {
|
|
6375
|
-
}
|
|
6332
|
+
await domMonitorTask?.catch(() => {
|
|
6333
|
+
});
|
|
6376
6334
|
});
|
|
6377
6335
|
}
|
|
6378
6336
|
if (urlPattern) {
|
|
@@ -6387,6 +6345,12 @@ function useCaptchaMonitor(page, options) {
|
|
|
6387
6345
|
};
|
|
6388
6346
|
page.on("framenavigated", frameHandler);
|
|
6389
6347
|
logger12.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${urlPattern}`);
|
|
6348
|
+
Promise.resolve().then(async () => {
|
|
6349
|
+
if (!isStopped && page.url().includes(urlPattern)) {
|
|
6350
|
+
await triggerDetected();
|
|
6351
|
+
}
|
|
6352
|
+
}).catch(() => {
|
|
6353
|
+
});
|
|
6390
6354
|
cleanupFns.push(async () => {
|
|
6391
6355
|
page.off("framenavigated", frameHandler);
|
|
6392
6356
|
});
|
|
@@ -6394,10 +6358,10 @@ function useCaptchaMonitor(page, options) {
|
|
|
6394
6358
|
return {
|
|
6395
6359
|
stop: async () => {
|
|
6396
6360
|
logger12.info("\u6B63\u5728\u505C\u6B62\u9A8C\u8BC1\u7801\u76D1\u63A7...");
|
|
6361
|
+
isStopped = true;
|
|
6397
6362
|
for (const fn of cleanupFns) {
|
|
6398
6363
|
await fn();
|
|
6399
6364
|
}
|
|
6400
|
-
isStopped = true;
|
|
6401
6365
|
}
|
|
6402
6366
|
};
|
|
6403
6367
|
}
|
|
@@ -6442,7 +6406,7 @@ var Captcha = {
|
|
|
6442
6406
|
|
|
6443
6407
|
// src/mutation.js
|
|
6444
6408
|
import { createHash } from "node:crypto";
|
|
6445
|
-
import { v4 as
|
|
6409
|
+
import { v4 as uuidv4 } from "uuid";
|
|
6446
6410
|
var logger13 = createInternalLogger("Mutation");
|
|
6447
6411
|
var MUTATION_MONITOR_MODE = Object.freeze({
|
|
6448
6412
|
Added: "added",
|
|
@@ -6450,7 +6414,7 @@ var MUTATION_MONITOR_MODE = Object.freeze({
|
|
|
6450
6414
|
All: "all"
|
|
6451
6415
|
});
|
|
6452
6416
|
function generateKey(prefix) {
|
|
6453
|
-
return `__${prefix}_${
|
|
6417
|
+
return `__${prefix}_${uuidv4().replace(/-/g, "_")}`;
|
|
6454
6418
|
}
|
|
6455
6419
|
var Mutation = {
|
|
6456
6420
|
Mode: MUTATION_MONITOR_MODE,
|
|
@@ -6640,7 +6604,7 @@ var Mutation = {
|
|
|
6640
6604
|
const overallTimeout = options.timeout ?? 180 * 1e3;
|
|
6641
6605
|
const onMutation = options.onMutation;
|
|
6642
6606
|
const pollInterval = 500;
|
|
6643
|
-
const
|
|
6607
|
+
const sleep2 = (ms) => new Promise((resolve) => {
|
|
6644
6608
|
setTimeout(resolve, ms);
|
|
6645
6609
|
});
|
|
6646
6610
|
const truncate = (value, max = 800) => {
|
|
@@ -6832,7 +6796,7 @@ var Mutation = {
|
|
|
6832
6796
|
const deadline = Date.now() + overallTimeout;
|
|
6833
6797
|
let lastState = state2;
|
|
6834
6798
|
while (Date.now() < deadline) {
|
|
6835
|
-
await
|
|
6799
|
+
await sleep2(pollInterval);
|
|
6836
6800
|
lastState = await buildState();
|
|
6837
6801
|
if (!lastState?.hasMatched) {
|
|
6838
6802
|
continue;
|