@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.js
CHANGED
|
@@ -1059,7 +1059,7 @@ import { serializeError as serializeError2 } from "serialize-error";
|
|
|
1059
1059
|
|
|
1060
1060
|
// src/internals/proxy-meter-runtime.js
|
|
1061
1061
|
import { spawn, spawnSync } from "child_process";
|
|
1062
|
-
import {
|
|
1062
|
+
import { existsSync, mkdirSync, readFileSync, rmSync } from "fs";
|
|
1063
1063
|
import { tmpdir } from "os";
|
|
1064
1064
|
import path from "path";
|
|
1065
1065
|
import { fileURLToPath } from "url";
|
|
@@ -1168,18 +1168,6 @@ var ensureLogPath = () => {
|
|
|
1168
1168
|
const label = runId ? `proxy-meter-${runId}-${suffix}.json` : `proxy-meter-${process.pid}-${suffix}.json`;
|
|
1169
1169
|
return path.join(baseDir, label);
|
|
1170
1170
|
};
|
|
1171
|
-
var ensureStdioLogPath = (logPath) => `${logPath}.stdio.log`;
|
|
1172
|
-
var writeChildOutput = (stream, output, prefix) => {
|
|
1173
|
-
if (!stream || !output) return;
|
|
1174
|
-
output.on("data", (chunk) => {
|
|
1175
|
-
const text = chunk?.toString?.() || String(chunk || "");
|
|
1176
|
-
if (!text) return;
|
|
1177
|
-
for (const line of text.split(/\r?\n/)) {
|
|
1178
|
-
if (!line) continue;
|
|
1179
|
-
stream.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] ${prefix} ${line}\n`);
|
|
1180
|
-
}
|
|
1181
|
-
});
|
|
1182
|
-
};
|
|
1183
1171
|
var readSnapshot = (logPath) => {
|
|
1184
1172
|
if (!logPath || !existsSync(logPath)) return null;
|
|
1185
1173
|
try {
|
|
@@ -1347,7 +1335,6 @@ var startProxyMeter = (options = {}) => {
|
|
|
1347
1335
|
observedDomainResourceTypes = /* @__PURE__ */ new Map();
|
|
1348
1336
|
const port = pickFreePort();
|
|
1349
1337
|
const logPath = ensureLogPath();
|
|
1350
|
-
const stdioLogPath = ensureStdioLogPath(logPath);
|
|
1351
1338
|
const scriptPath = resolveScriptPath();
|
|
1352
1339
|
const debugMode = Boolean(options.debugMode);
|
|
1353
1340
|
const debugMaxEvents = Math.max(10, toSafeInt(options.debugMaxEvents) || DEFAULT_DEBUG_MAX_EVENTS);
|
|
@@ -1360,26 +1347,19 @@ var startProxyMeter = (options = {}) => {
|
|
|
1360
1347
|
PROXY_METER_DEBUG: debugMode ? "1" : "0",
|
|
1361
1348
|
PROXY_METER_DEBUG_MAX_EVENTS: String(debugMaxEvents)
|
|
1362
1349
|
};
|
|
1363
|
-
const stdioLog = createWriteStream(stdioLogPath, { flags: "a" });
|
|
1364
|
-
stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] start script=${scriptPath} port=${port} snapshot=${logPath}\n`);
|
|
1365
1350
|
const child = spawn(process.execPath, [scriptPath], {
|
|
1366
1351
|
env,
|
|
1367
|
-
stdio: ["ignore", "
|
|
1352
|
+
stdio: ["ignore", "ignore", "ignore"]
|
|
1368
1353
|
});
|
|
1369
|
-
|
|
1370
|
-
writeChildOutput(stdioLog, child.stderr, "stderr");
|
|
1371
|
-
child.once("exit", (code, signal) => {
|
|
1372
|
-
stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] exit code=${code ?? ""} signal=${signal ?? ""}\n`);
|
|
1373
|
-
stdioLog.end();
|
|
1354
|
+
child.once("exit", (code) => {
|
|
1374
1355
|
if (code && code !== 0) {
|
|
1375
|
-
logger2.warn(`[proxy-meter] exited with code ${code}
|
|
1356
|
+
logger2.warn(`[proxy-meter] exited with code ${code}`);
|
|
1376
1357
|
}
|
|
1377
1358
|
});
|
|
1378
1359
|
runtime = {
|
|
1379
1360
|
proc: child,
|
|
1380
1361
|
port,
|
|
1381
1362
|
logPath,
|
|
1382
|
-
stdioLogPath,
|
|
1383
1363
|
startedAt: Date.now()
|
|
1384
1364
|
};
|
|
1385
1365
|
registerCleanup();
|
|
@@ -5603,9 +5583,6 @@ var LiveView = {
|
|
|
5603
5583
|
useLiveView
|
|
5604
5584
|
};
|
|
5605
5585
|
|
|
5606
|
-
// src/chaptcha.js
|
|
5607
|
-
import { v4 as uuidv4 } from "uuid";
|
|
5608
|
-
|
|
5609
5586
|
// src/internals/captcha/bytedance.js
|
|
5610
5587
|
import { mkdir, writeFile } from "fs/promises";
|
|
5611
5588
|
import path2 from "path";
|
|
@@ -6264,6 +6241,9 @@ var sloveCaptcha = solveCaptcha;
|
|
|
6264
6241
|
|
|
6265
6242
|
// src/chaptcha.js
|
|
6266
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;
|
|
6267
6247
|
var DEFAULT_CAPTCHA_RECOGNITION_OPTIONS = Object.freeze({
|
|
6268
6248
|
token: "eKJvBfwfN0YRav0-VD_44E2VBSfm7l0YtddUQ7cFySI",
|
|
6269
6249
|
apiUrl: "https://api.jfbym.com/api/YmServer/customApi"
|
|
@@ -6284,6 +6264,15 @@ var mergeDefinedOptions = (...sources) => {
|
|
|
6284
6264
|
}
|
|
6285
6265
|
return merged;
|
|
6286
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
|
+
};
|
|
6287
6276
|
function useCaptchaMonitor(page, options) {
|
|
6288
6277
|
const { domSelector, urlPattern, onDetected } = options;
|
|
6289
6278
|
if (!domSelector && !urlPattern) {
|
|
@@ -6295,10 +6284,13 @@ function useCaptchaMonitor(page, options) {
|
|
|
6295
6284
|
let isStopped = false;
|
|
6296
6285
|
let isHandling = false;
|
|
6297
6286
|
let frameHandler = null;
|
|
6298
|
-
let
|
|
6287
|
+
let domMonitorTask = null;
|
|
6288
|
+
let lastTriggeredAt = 0;
|
|
6299
6289
|
const triggerDetected = async () => {
|
|
6300
|
-
|
|
6290
|
+
const now = Date.now();
|
|
6291
|
+
if (isStopped || isHandling || now - lastTriggeredAt < 250) return;
|
|
6301
6292
|
isHandling = true;
|
|
6293
|
+
lastTriggeredAt = now;
|
|
6302
6294
|
try {
|
|
6303
6295
|
await onDetected();
|
|
6304
6296
|
} finally {
|
|
@@ -6307,60 +6299,38 @@ function useCaptchaMonitor(page, options) {
|
|
|
6307
6299
|
};
|
|
6308
6300
|
const cleanupFns = [];
|
|
6309
6301
|
if (domSelector) {
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
}
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
const shouldCheck = mutations.some((mutation) => mutation.addedNodes.length > 0);
|
|
6330
|
-
if (shouldCheck && observer) {
|
|
6331
|
-
checkAndReport();
|
|
6332
|
-
}
|
|
6333
|
-
});
|
|
6334
|
-
const mountObserver = () => {
|
|
6335
|
-
const target = document.documentElement;
|
|
6336
|
-
if (target && observer) {
|
|
6337
|
-
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;
|
|
6338
6321
|
}
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
|
|
6342
|
-
|
|
6343
|
-
|
|
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);
|
|
6344
6327
|
}
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
observer.disconnect();
|
|
6348
|
-
observer = null;
|
|
6349
|
-
}
|
|
6350
|
-
};
|
|
6351
|
-
})();
|
|
6352
|
-
}, { selector: domSelector, callbackName: exposedFunctionName, cleanerName });
|
|
6328
|
+
}
|
|
6329
|
+
})();
|
|
6353
6330
|
logger12.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${domSelector}`);
|
|
6354
6331
|
cleanupFns.push(async () => {
|
|
6355
|
-
|
|
6356
|
-
|
|
6357
|
-
if (window[name]) {
|
|
6358
|
-
window[name]();
|
|
6359
|
-
delete window[name];
|
|
6360
|
-
}
|
|
6361
|
-
}, cleanerName);
|
|
6362
|
-
} catch {
|
|
6363
|
-
}
|
|
6332
|
+
await domMonitorTask?.catch(() => {
|
|
6333
|
+
});
|
|
6364
6334
|
});
|
|
6365
6335
|
}
|
|
6366
6336
|
if (urlPattern) {
|
|
@@ -6375,6 +6345,12 @@ function useCaptchaMonitor(page, options) {
|
|
|
6375
6345
|
};
|
|
6376
6346
|
page.on("framenavigated", frameHandler);
|
|
6377
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
|
+
});
|
|
6378
6354
|
cleanupFns.push(async () => {
|
|
6379
6355
|
page.off("framenavigated", frameHandler);
|
|
6380
6356
|
});
|
|
@@ -6382,10 +6358,10 @@ function useCaptchaMonitor(page, options) {
|
|
|
6382
6358
|
return {
|
|
6383
6359
|
stop: async () => {
|
|
6384
6360
|
logger12.info("\u6B63\u5728\u505C\u6B62\u9A8C\u8BC1\u7801\u76D1\u63A7...");
|
|
6361
|
+
isStopped = true;
|
|
6385
6362
|
for (const fn of cleanupFns) {
|
|
6386
6363
|
await fn();
|
|
6387
6364
|
}
|
|
6388
|
-
isStopped = true;
|
|
6389
6365
|
}
|
|
6390
6366
|
};
|
|
6391
6367
|
}
|
|
@@ -6430,7 +6406,7 @@ var Captcha = {
|
|
|
6430
6406
|
|
|
6431
6407
|
// src/mutation.js
|
|
6432
6408
|
import { createHash } from "node:crypto";
|
|
6433
|
-
import { v4 as
|
|
6409
|
+
import { v4 as uuidv4 } from "uuid";
|
|
6434
6410
|
var logger13 = createInternalLogger("Mutation");
|
|
6435
6411
|
var MUTATION_MONITOR_MODE = Object.freeze({
|
|
6436
6412
|
Added: "added",
|
|
@@ -6438,7 +6414,7 @@ var MUTATION_MONITOR_MODE = Object.freeze({
|
|
|
6438
6414
|
All: "all"
|
|
6439
6415
|
});
|
|
6440
6416
|
function generateKey(prefix) {
|
|
6441
|
-
return `__${prefix}_${
|
|
6417
|
+
return `__${prefix}_${uuidv4().replace(/-/g, "_")}`;
|
|
6442
6418
|
}
|
|
6443
6419
|
var Mutation = {
|
|
6444
6420
|
Mode: MUTATION_MONITOR_MODE,
|
|
@@ -6628,7 +6604,7 @@ var Mutation = {
|
|
|
6628
6604
|
const overallTimeout = options.timeout ?? 180 * 1e3;
|
|
6629
6605
|
const onMutation = options.onMutation;
|
|
6630
6606
|
const pollInterval = 500;
|
|
6631
|
-
const
|
|
6607
|
+
const sleep2 = (ms) => new Promise((resolve) => {
|
|
6632
6608
|
setTimeout(resolve, ms);
|
|
6633
6609
|
});
|
|
6634
6610
|
const truncate = (value, max = 800) => {
|
|
@@ -6820,7 +6796,7 @@ var Mutation = {
|
|
|
6820
6796
|
const deadline = Date.now() + overallTimeout;
|
|
6821
6797
|
let lastState = state2;
|
|
6822
6798
|
while (Date.now() < deadline) {
|
|
6823
|
-
await
|
|
6799
|
+
await sleep2(pollInterval);
|
|
6824
6800
|
lastState = await buildState();
|
|
6825
6801
|
if (!lastState?.hasMatched) {
|
|
6826
6802
|
continue;
|