@skrillex1224/playwright-toolkit 3.0.9 → 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/index.cjs +59 -83
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +60 -84
- package/dist/index.js.map +4 -4
- package/dist/internals/proxy-meter.js +5 -51
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1196,18 +1196,6 @@ var ensureLogPath = () => {
|
|
|
1196
1196
|
const label = runId ? `proxy-meter-${runId}-${suffix}.json` : `proxy-meter-${process.pid}-${suffix}.json`;
|
|
1197
1197
|
return import_path.default.join(baseDir, label);
|
|
1198
1198
|
};
|
|
1199
|
-
var ensureStdioLogPath = (logPath) => `${logPath}.stdio.log`;
|
|
1200
|
-
var writeChildOutput = (stream, output, prefix) => {
|
|
1201
|
-
if (!stream || !output) return;
|
|
1202
|
-
output.on("data", (chunk) => {
|
|
1203
|
-
const text = chunk?.toString?.() || String(chunk || "");
|
|
1204
|
-
if (!text) return;
|
|
1205
|
-
for (const line of text.split(/\r?\n/)) {
|
|
1206
|
-
if (!line) continue;
|
|
1207
|
-
stream.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] ${prefix} ${line}\n`);
|
|
1208
|
-
}
|
|
1209
|
-
});
|
|
1210
|
-
};
|
|
1211
1199
|
var readSnapshot = (logPath) => {
|
|
1212
1200
|
if (!logPath || !(0, import_fs.existsSync)(logPath)) return null;
|
|
1213
1201
|
try {
|
|
@@ -1375,7 +1363,6 @@ var startProxyMeter = (options = {}) => {
|
|
|
1375
1363
|
observedDomainResourceTypes = /* @__PURE__ */ new Map();
|
|
1376
1364
|
const port = pickFreePort();
|
|
1377
1365
|
const logPath = ensureLogPath();
|
|
1378
|
-
const stdioLogPath = ensureStdioLogPath(logPath);
|
|
1379
1366
|
const scriptPath = resolveScriptPath();
|
|
1380
1367
|
const debugMode = Boolean(options.debugMode);
|
|
1381
1368
|
const debugMaxEvents = Math.max(10, toSafeInt(options.debugMaxEvents) || DEFAULT_DEBUG_MAX_EVENTS);
|
|
@@ -1388,26 +1375,19 @@ var startProxyMeter = (options = {}) => {
|
|
|
1388
1375
|
PROXY_METER_DEBUG: debugMode ? "1" : "0",
|
|
1389
1376
|
PROXY_METER_DEBUG_MAX_EVENTS: String(debugMaxEvents)
|
|
1390
1377
|
};
|
|
1391
|
-
const stdioLog = (0, import_fs.createWriteStream)(stdioLogPath, { flags: "a" });
|
|
1392
|
-
stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] start script=${scriptPath} port=${port} snapshot=${logPath}\n`);
|
|
1393
1378
|
const child = (0, import_child_process.spawn)(process.execPath, [scriptPath], {
|
|
1394
1379
|
env,
|
|
1395
|
-
stdio: ["ignore", "
|
|
1380
|
+
stdio: ["ignore", "ignore", "ignore"]
|
|
1396
1381
|
});
|
|
1397
|
-
|
|
1398
|
-
writeChildOutput(stdioLog, child.stderr, "stderr");
|
|
1399
|
-
child.once("exit", (code, signal) => {
|
|
1400
|
-
stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] exit code=${code ?? ""} signal=${signal ?? ""}\n`);
|
|
1401
|
-
stdioLog.end();
|
|
1382
|
+
child.once("exit", (code) => {
|
|
1402
1383
|
if (code && code !== 0) {
|
|
1403
|
-
logger2.warn(`[proxy-meter] exited with code ${code}
|
|
1384
|
+
logger2.warn(`[proxy-meter] exited with code ${code}`);
|
|
1404
1385
|
}
|
|
1405
1386
|
});
|
|
1406
1387
|
runtime = {
|
|
1407
1388
|
proc: child,
|
|
1408
1389
|
port,
|
|
1409
1390
|
logPath,
|
|
1410
|
-
stdioLogPath,
|
|
1411
1391
|
startedAt: Date.now()
|
|
1412
1392
|
};
|
|
1413
1393
|
registerCleanup();
|
|
@@ -5631,9 +5611,6 @@ var LiveView = {
|
|
|
5631
5611
|
useLiveView
|
|
5632
5612
|
};
|
|
5633
5613
|
|
|
5634
|
-
// src/chaptcha.js
|
|
5635
|
-
var import_uuid = require("uuid");
|
|
5636
|
-
|
|
5637
5614
|
// src/internals/captcha/bytedance.js
|
|
5638
5615
|
var import_promises = require("fs/promises");
|
|
5639
5616
|
var import_path2 = __toESM(require("path"), 1);
|
|
@@ -6292,6 +6269,9 @@ var sloveCaptcha = solveCaptcha;
|
|
|
6292
6269
|
|
|
6293
6270
|
// src/chaptcha.js
|
|
6294
6271
|
var logger12 = createInternalLogger("Captcha");
|
|
6272
|
+
var DOM_MONITOR_WAIT_TIMEOUT_MS = 1e3;
|
|
6273
|
+
var DOM_MONITOR_POST_DETECT_HIDDEN_WAIT_MS = 300;
|
|
6274
|
+
var DOM_MONITOR_RECOVERY_WAIT_MS = 100;
|
|
6295
6275
|
var DEFAULT_CAPTCHA_RECOGNITION_OPTIONS = Object.freeze({
|
|
6296
6276
|
token: "eKJvBfwfN0YRav0-VD_44E2VBSfm7l0YtddUQ7cFySI",
|
|
6297
6277
|
apiUrl: "https://api.jfbym.com/api/YmServer/customApi"
|
|
@@ -6312,6 +6292,15 @@ var mergeDefinedOptions = (...sources) => {
|
|
|
6312
6292
|
}
|
|
6313
6293
|
return merged;
|
|
6314
6294
|
};
|
|
6295
|
+
var sleep = (ms) => new Promise((resolve) => {
|
|
6296
|
+
setTimeout(resolve, ms);
|
|
6297
|
+
});
|
|
6298
|
+
var getErrorMessage = (error) => String(error?.message || error || "");
|
|
6299
|
+
var isTimeoutError = (error) => error?.name === "TimeoutError" || getErrorMessage(error).includes("Timeout");
|
|
6300
|
+
var isPageLifecycleError = (error) => {
|
|
6301
|
+
const message = getErrorMessage(error);
|
|
6302
|
+
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");
|
|
6303
|
+
};
|
|
6315
6304
|
function useCaptchaMonitor(page, options) {
|
|
6316
6305
|
const { domSelector, urlPattern, onDetected } = options;
|
|
6317
6306
|
if (!domSelector && !urlPattern) {
|
|
@@ -6323,10 +6312,13 @@ function useCaptchaMonitor(page, options) {
|
|
|
6323
6312
|
let isStopped = false;
|
|
6324
6313
|
let isHandling = false;
|
|
6325
6314
|
let frameHandler = null;
|
|
6326
|
-
let
|
|
6315
|
+
let domMonitorTask = null;
|
|
6316
|
+
let lastTriggeredAt = 0;
|
|
6327
6317
|
const triggerDetected = async () => {
|
|
6328
|
-
|
|
6318
|
+
const now = Date.now();
|
|
6319
|
+
if (isStopped || isHandling || now - lastTriggeredAt < 250) return;
|
|
6329
6320
|
isHandling = true;
|
|
6321
|
+
lastTriggeredAt = now;
|
|
6330
6322
|
try {
|
|
6331
6323
|
await onDetected();
|
|
6332
6324
|
} finally {
|
|
@@ -6335,60 +6327,38 @@ function useCaptchaMonitor(page, options) {
|
|
|
6335
6327
|
};
|
|
6336
6328
|
const cleanupFns = [];
|
|
6337
6329
|
if (domSelector) {
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
}
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
|
|
6356
|
-
|
|
6357
|
-
const shouldCheck = mutations.some((mutation) => mutation.addedNodes.length > 0);
|
|
6358
|
-
if (shouldCheck && observer) {
|
|
6359
|
-
checkAndReport();
|
|
6360
|
-
}
|
|
6361
|
-
});
|
|
6362
|
-
const mountObserver = () => {
|
|
6363
|
-
const target = document.documentElement;
|
|
6364
|
-
if (target && observer) {
|
|
6365
|
-
observer.observe(target, { childList: true, subtree: true });
|
|
6330
|
+
domMonitorTask = (async () => {
|
|
6331
|
+
const locator = page.locator(domSelector).first();
|
|
6332
|
+
while (!isStopped) {
|
|
6333
|
+
try {
|
|
6334
|
+
await locator.waitFor({ state: "visible", timeout: DOM_MONITOR_WAIT_TIMEOUT_MS });
|
|
6335
|
+
if (isStopped) break;
|
|
6336
|
+
await triggerDetected();
|
|
6337
|
+
if (isStopped) break;
|
|
6338
|
+
await locator.waitFor({
|
|
6339
|
+
state: "hidden",
|
|
6340
|
+
timeout: DOM_MONITOR_POST_DETECT_HIDDEN_WAIT_MS
|
|
6341
|
+
}).catch(() => {
|
|
6342
|
+
});
|
|
6343
|
+
} catch (error) {
|
|
6344
|
+
if (isStopped) break;
|
|
6345
|
+
if (page?.isClosed?.() && isPageLifecycleError(error)) break;
|
|
6346
|
+
if (isTimeoutError(error) || isPageLifecycleError(error)) {
|
|
6347
|
+
await sleep(DOM_MONITOR_RECOVERY_WAIT_MS);
|
|
6348
|
+
continue;
|
|
6366
6349
|
}
|
|
6367
|
-
|
|
6368
|
-
|
|
6369
|
-
|
|
6370
|
-
|
|
6371
|
-
|
|
6350
|
+
logger12.warning(
|
|
6351
|
+
"useCaptchaMonitor",
|
|
6352
|
+
`DOM \u76D1\u63A7\u51FA\u73B0\u5F02\u5E38\uFF08\u7EE7\u7EED\u91CD\u8BD5\uFF09: selector=${domSelector}, error=${getErrorMessage(error)}`
|
|
6353
|
+
);
|
|
6354
|
+
await sleep(DOM_MONITOR_RECOVERY_WAIT_MS);
|
|
6372
6355
|
}
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
observer.disconnect();
|
|
6376
|
-
observer = null;
|
|
6377
|
-
}
|
|
6378
|
-
};
|
|
6379
|
-
})();
|
|
6380
|
-
}, { selector: domSelector, callbackName: exposedFunctionName, cleanerName });
|
|
6356
|
+
}
|
|
6357
|
+
})();
|
|
6381
6358
|
logger12.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${domSelector}`);
|
|
6382
6359
|
cleanupFns.push(async () => {
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
if (window[name]) {
|
|
6386
|
-
window[name]();
|
|
6387
|
-
delete window[name];
|
|
6388
|
-
}
|
|
6389
|
-
}, cleanerName);
|
|
6390
|
-
} catch {
|
|
6391
|
-
}
|
|
6360
|
+
await domMonitorTask?.catch(() => {
|
|
6361
|
+
});
|
|
6392
6362
|
});
|
|
6393
6363
|
}
|
|
6394
6364
|
if (urlPattern) {
|
|
@@ -6403,6 +6373,12 @@ function useCaptchaMonitor(page, options) {
|
|
|
6403
6373
|
};
|
|
6404
6374
|
page.on("framenavigated", frameHandler);
|
|
6405
6375
|
logger12.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${urlPattern}`);
|
|
6376
|
+
Promise.resolve().then(async () => {
|
|
6377
|
+
if (!isStopped && page.url().includes(urlPattern)) {
|
|
6378
|
+
await triggerDetected();
|
|
6379
|
+
}
|
|
6380
|
+
}).catch(() => {
|
|
6381
|
+
});
|
|
6406
6382
|
cleanupFns.push(async () => {
|
|
6407
6383
|
page.off("framenavigated", frameHandler);
|
|
6408
6384
|
});
|
|
@@ -6410,10 +6386,10 @@ function useCaptchaMonitor(page, options) {
|
|
|
6410
6386
|
return {
|
|
6411
6387
|
stop: async () => {
|
|
6412
6388
|
logger12.info("\u6B63\u5728\u505C\u6B62\u9A8C\u8BC1\u7801\u76D1\u63A7...");
|
|
6389
|
+
isStopped = true;
|
|
6413
6390
|
for (const fn of cleanupFns) {
|
|
6414
6391
|
await fn();
|
|
6415
6392
|
}
|
|
6416
|
-
isStopped = true;
|
|
6417
6393
|
}
|
|
6418
6394
|
};
|
|
6419
6395
|
}
|
|
@@ -6458,7 +6434,7 @@ var Captcha = {
|
|
|
6458
6434
|
|
|
6459
6435
|
// src/mutation.js
|
|
6460
6436
|
var import_node_crypto = require("node:crypto");
|
|
6461
|
-
var
|
|
6437
|
+
var import_uuid = require("uuid");
|
|
6462
6438
|
var logger13 = createInternalLogger("Mutation");
|
|
6463
6439
|
var MUTATION_MONITOR_MODE = Object.freeze({
|
|
6464
6440
|
Added: "added",
|
|
@@ -6466,7 +6442,7 @@ var MUTATION_MONITOR_MODE = Object.freeze({
|
|
|
6466
6442
|
All: "all"
|
|
6467
6443
|
});
|
|
6468
6444
|
function generateKey(prefix) {
|
|
6469
|
-
return `__${prefix}_${(0,
|
|
6445
|
+
return `__${prefix}_${(0, import_uuid.v4)().replace(/-/g, "_")}`;
|
|
6470
6446
|
}
|
|
6471
6447
|
var Mutation = {
|
|
6472
6448
|
Mode: MUTATION_MONITOR_MODE,
|
|
@@ -6656,7 +6632,7 @@ var Mutation = {
|
|
|
6656
6632
|
const overallTimeout = options.timeout ?? 180 * 1e3;
|
|
6657
6633
|
const onMutation = options.onMutation;
|
|
6658
6634
|
const pollInterval = 500;
|
|
6659
|
-
const
|
|
6635
|
+
const sleep2 = (ms) => new Promise((resolve) => {
|
|
6660
6636
|
setTimeout(resolve, ms);
|
|
6661
6637
|
});
|
|
6662
6638
|
const truncate = (value, max = 800) => {
|
|
@@ -6848,7 +6824,7 @@ var Mutation = {
|
|
|
6848
6824
|
const deadline = Date.now() + overallTimeout;
|
|
6849
6825
|
let lastState = state2;
|
|
6850
6826
|
while (Date.now() < deadline) {
|
|
6851
|
-
await
|
|
6827
|
+
await sleep2(pollInterval);
|
|
6852
6828
|
lastState = await buildState();
|
|
6853
6829
|
if (!lastState?.hasMatched) {
|
|
6854
6830
|
continue;
|