@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/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 { createWriteStream, existsSync, mkdirSync, readFileSync, rmSync } from "fs";
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", "pipe", "pipe"]
1352
+ stdio: ["ignore", "ignore", "ignore"]
1380
1353
  });
1381
- writeChildOutput(stdioLog, child.stdout, "stdout");
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}; stdio=${stdioLogPath}`);
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 exposedFunctionName = null;
6287
+ let domMonitorTask = null;
6288
+ let lastTriggeredAt = 0;
6311
6289
  const triggerDetected = async () => {
6312
- if (isStopped || isHandling) return;
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
- exposedFunctionName = `__c_d_${uuidv4().replace(/-/g, "_")}`;
6323
- const cleanerName = `__c_cleaner_${uuidv4().replace(/-/g, "_")}`;
6324
- page.exposeFunction(exposedFunctionName, triggerDetected).catch(() => {
6325
- });
6326
- page.addInitScript(({ selector, callbackName, cleanerName: cleanupName }) => {
6327
- (() => {
6328
- let observer = null;
6329
- const checkAndReport = () => {
6330
- const element = document.querySelector(selector);
6331
- if (!element) {
6332
- return false;
6333
- }
6334
- if (window[callbackName]) {
6335
- window[callbackName]();
6336
- }
6337
- return true;
6338
- };
6339
- checkAndReport();
6340
- observer = new MutationObserver((mutations) => {
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
- if (document.readyState === "loading") {
6353
- window.addEventListener("DOMContentLoaded", mountObserver);
6354
- } else {
6355
- mountObserver();
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
- window[cleanupName] = () => {
6358
- if (observer) {
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
- try {
6368
- await page.evaluate((name) => {
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 uuidv42 } from "uuid";
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}_${uuidv42().replace(/-/g, "_")}`;
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 sleep = (ms) => new Promise((resolve) => {
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 sleep(pollInterval);
6799
+ await sleep2(pollInterval);
6836
6800
  lastState = await buildState();
6837
6801
  if (!lastState?.hasMatched) {
6838
6802
  continue;