@skrillex1224/playwright-toolkit 3.0.10 → 3.0.12

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 CHANGED
@@ -2853,7 +2853,6 @@ var createActorInfo = (info) => {
2853
2853
  const buildLandingUrl = ({ protocol: protocol2, domain: domain2, path: path2 }) => {
2854
2854
  const safeProtocol = String(protocol2).trim();
2855
2855
  const safeDomain = normalizeDomain(domain2);
2856
- if (!safeDomain) return "";
2857
2856
  const safePath = normalizePath(path2);
2858
2857
  return `${safeProtocol}://${safeDomain}${safePath}`;
2859
2858
  };
@@ -3061,17 +3060,6 @@ var ActorInfo = {
3061
3060
  prefix: "",
3062
3061
  xurl: []
3063
3062
  }
3064
- }),
3065
- webpage: createActorInfo({
3066
- key: "webpage",
3067
- name: "\u901A\u7528\u7F51\u9875",
3068
- domain: "",
3069
- path: "/",
3070
- share: {
3071
- mode: "dom",
3072
- prefix: "",
3073
- xurl: []
3074
- }
3075
3063
  })
3076
3064
  };
3077
3065
 
package/dist/index.cjs CHANGED
@@ -149,7 +149,6 @@ var createActorInfo = (info) => {
149
149
  const buildLandingUrl = ({ protocol: protocol2, domain: domain2, path: path4 }) => {
150
150
  const safeProtocol = String(protocol2).trim();
151
151
  const safeDomain = normalizeDomain(domain2);
152
- if (!safeDomain) return "";
153
152
  const safePath = normalizePath(path4);
154
153
  return `${safeProtocol}://${safeDomain}${safePath}`;
155
154
  };
@@ -357,17 +356,6 @@ var ActorInfo = {
357
356
  prefix: "",
358
357
  xurl: []
359
358
  }
360
- }),
361
- webpage: createActorInfo({
362
- key: "webpage",
363
- name: "\u901A\u7528\u7F51\u9875",
364
- domain: "",
365
- path: "/",
366
- share: {
367
- mode: "dom",
368
- prefix: "",
369
- xurl: []
370
- }
371
359
  })
372
360
  };
373
361
 
@@ -1216,7 +1204,8 @@ var writeChildOutput = (stream, output, prefix) => {
1216
1204
  if (!text) return;
1217
1205
  for (const line of text.split(/\r?\n/)) {
1218
1206
  if (!line) continue;
1219
- stream.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] ${prefix} ${line}\n`);
1207
+ stream.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] ${prefix} ${line}
1208
+ `);
1220
1209
  }
1221
1210
  });
1222
1211
  };
@@ -1401,7 +1390,8 @@ var startProxyMeter = (options = {}) => {
1401
1390
  PROXY_METER_DEBUG_MAX_EVENTS: String(debugMaxEvents)
1402
1391
  };
1403
1392
  const stdioLog = (0, import_fs.createWriteStream)(stdioLogPath, { flags: "a" });
1404
- stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] start script=${scriptPath} port=${port} snapshot=${logPath}\n`);
1393
+ stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] start script=${scriptPath} port=${port} snapshot=${logPath}
1394
+ `);
1405
1395
  const child = (0, import_child_process.spawn)(process.execPath, [scriptPath], {
1406
1396
  env,
1407
1397
  stdio: ["ignore", "pipe", "pipe"]
@@ -1409,7 +1399,8 @@ var startProxyMeter = (options = {}) => {
1409
1399
  writeChildOutput(stdioLog, child.stdout, "stdout");
1410
1400
  writeChildOutput(stdioLog, child.stderr, "stderr");
1411
1401
  child.once("exit", (code, signal) => {
1412
- stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] exit code=${code ?? ""} signal=${signal ?? ""}\n`);
1402
+ stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] exit code=${code ?? ""} signal=${signal ?? ""}
1403
+ `);
1413
1404
  stdioLog.end();
1414
1405
  if (code && code !== 0) {
1415
1406
  logger2.warn(`[proxy-meter] exited with code ${code}; stdio=${stdioLogPath}`);
@@ -5643,9 +5634,6 @@ var LiveView = {
5643
5634
  useLiveView
5644
5635
  };
5645
5636
 
5646
- // src/chaptcha.js
5647
- var import_uuid = require("uuid");
5648
-
5649
5637
  // src/internals/captcha/bytedance.js
5650
5638
  var import_promises = require("fs/promises");
5651
5639
  var import_path2 = __toESM(require("path"), 1);
@@ -6304,6 +6292,9 @@ var sloveCaptcha = solveCaptcha;
6304
6292
 
6305
6293
  // src/chaptcha.js
6306
6294
  var logger12 = createInternalLogger("Captcha");
6295
+ var DOM_MONITOR_WAIT_TIMEOUT_MS = 1e3;
6296
+ var DOM_MONITOR_POST_DETECT_HIDDEN_WAIT_MS = 300;
6297
+ var DOM_MONITOR_RECOVERY_WAIT_MS = 100;
6307
6298
  var DEFAULT_CAPTCHA_RECOGNITION_OPTIONS = Object.freeze({
6308
6299
  token: "eKJvBfwfN0YRav0-VD_44E2VBSfm7l0YtddUQ7cFySI",
6309
6300
  apiUrl: "https://api.jfbym.com/api/YmServer/customApi"
@@ -6324,6 +6315,15 @@ var mergeDefinedOptions = (...sources) => {
6324
6315
  }
6325
6316
  return merged;
6326
6317
  };
6318
+ var sleep = (ms) => new Promise((resolve) => {
6319
+ setTimeout(resolve, ms);
6320
+ });
6321
+ var getErrorMessage = (error) => String(error?.message || error || "");
6322
+ var isTimeoutError = (error) => error?.name === "TimeoutError" || getErrorMessage(error).includes("Timeout");
6323
+ var isPageLifecycleError = (error) => {
6324
+ const message = getErrorMessage(error);
6325
+ 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");
6326
+ };
6327
6327
  function useCaptchaMonitor(page, options) {
6328
6328
  const { domSelector, urlPattern, onDetected } = options;
6329
6329
  if (!domSelector && !urlPattern) {
@@ -6335,10 +6335,13 @@ function useCaptchaMonitor(page, options) {
6335
6335
  let isStopped = false;
6336
6336
  let isHandling = false;
6337
6337
  let frameHandler = null;
6338
- let exposedFunctionName = null;
6338
+ let domMonitorTask = null;
6339
+ let lastTriggeredAt = 0;
6339
6340
  const triggerDetected = async () => {
6340
- if (isStopped || isHandling) return;
6341
+ const now = Date.now();
6342
+ if (isStopped || isHandling || now - lastTriggeredAt < 250) return;
6341
6343
  isHandling = true;
6344
+ lastTriggeredAt = now;
6342
6345
  try {
6343
6346
  await onDetected();
6344
6347
  } finally {
@@ -6347,60 +6350,38 @@ function useCaptchaMonitor(page, options) {
6347
6350
  };
6348
6351
  const cleanupFns = [];
6349
6352
  if (domSelector) {
6350
- exposedFunctionName = `__c_d_${(0, import_uuid.v4)().replace(/-/g, "_")}`;
6351
- const cleanerName = `__c_cleaner_${(0, import_uuid.v4)().replace(/-/g, "_")}`;
6352
- page.exposeFunction(exposedFunctionName, triggerDetected).catch(() => {
6353
- });
6354
- page.addInitScript(({ selector, callbackName, cleanerName: cleanupName }) => {
6355
- (() => {
6356
- let observer = null;
6357
- const checkAndReport = () => {
6358
- const element = document.querySelector(selector);
6359
- if (!element) {
6360
- return false;
6361
- }
6362
- if (window[callbackName]) {
6363
- window[callbackName]();
6364
- }
6365
- return true;
6366
- };
6367
- checkAndReport();
6368
- observer = new MutationObserver((mutations) => {
6369
- const shouldCheck = mutations.some((mutation) => mutation.addedNodes.length > 0);
6370
- if (shouldCheck && observer) {
6371
- checkAndReport();
6372
- }
6373
- });
6374
- const mountObserver = () => {
6375
- const target = document.documentElement;
6376
- if (target && observer) {
6377
- observer.observe(target, { childList: true, subtree: true });
6353
+ domMonitorTask = (async () => {
6354
+ const locator = page.locator(domSelector).first();
6355
+ while (!isStopped) {
6356
+ try {
6357
+ await locator.waitFor({ state: "visible", timeout: DOM_MONITOR_WAIT_TIMEOUT_MS });
6358
+ if (isStopped) break;
6359
+ await triggerDetected();
6360
+ if (isStopped) break;
6361
+ await locator.waitFor({
6362
+ state: "hidden",
6363
+ timeout: DOM_MONITOR_POST_DETECT_HIDDEN_WAIT_MS
6364
+ }).catch(() => {
6365
+ });
6366
+ } catch (error) {
6367
+ if (isStopped) break;
6368
+ if (page?.isClosed?.() && isPageLifecycleError(error)) break;
6369
+ if (isTimeoutError(error) || isPageLifecycleError(error)) {
6370
+ await sleep(DOM_MONITOR_RECOVERY_WAIT_MS);
6371
+ continue;
6378
6372
  }
6379
- };
6380
- if (document.readyState === "loading") {
6381
- window.addEventListener("DOMContentLoaded", mountObserver);
6382
- } else {
6383
- mountObserver();
6373
+ logger12.warning(
6374
+ "useCaptchaMonitor",
6375
+ `DOM \u76D1\u63A7\u51FA\u73B0\u5F02\u5E38\uFF08\u7EE7\u7EED\u91CD\u8BD5\uFF09: selector=${domSelector}, error=${getErrorMessage(error)}`
6376
+ );
6377
+ await sleep(DOM_MONITOR_RECOVERY_WAIT_MS);
6384
6378
  }
6385
- window[cleanupName] = () => {
6386
- if (observer) {
6387
- observer.disconnect();
6388
- observer = null;
6389
- }
6390
- };
6391
- })();
6392
- }, { selector: domSelector, callbackName: exposedFunctionName, cleanerName });
6379
+ }
6380
+ })();
6393
6381
  logger12.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${domSelector}`);
6394
6382
  cleanupFns.push(async () => {
6395
- try {
6396
- await page.evaluate((name) => {
6397
- if (window[name]) {
6398
- window[name]();
6399
- delete window[name];
6400
- }
6401
- }, cleanerName);
6402
- } catch {
6403
- }
6383
+ await domMonitorTask?.catch(() => {
6384
+ });
6404
6385
  });
6405
6386
  }
6406
6387
  if (urlPattern) {
@@ -6415,6 +6396,12 @@ function useCaptchaMonitor(page, options) {
6415
6396
  };
6416
6397
  page.on("framenavigated", frameHandler);
6417
6398
  logger12.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${urlPattern}`);
6399
+ Promise.resolve().then(async () => {
6400
+ if (!isStopped && page.url().includes(urlPattern)) {
6401
+ await triggerDetected();
6402
+ }
6403
+ }).catch(() => {
6404
+ });
6418
6405
  cleanupFns.push(async () => {
6419
6406
  page.off("framenavigated", frameHandler);
6420
6407
  });
@@ -6422,10 +6409,10 @@ function useCaptchaMonitor(page, options) {
6422
6409
  return {
6423
6410
  stop: async () => {
6424
6411
  logger12.info("\u6B63\u5728\u505C\u6B62\u9A8C\u8BC1\u7801\u76D1\u63A7...");
6412
+ isStopped = true;
6425
6413
  for (const fn of cleanupFns) {
6426
6414
  await fn();
6427
6415
  }
6428
- isStopped = true;
6429
6416
  }
6430
6417
  };
6431
6418
  }
@@ -6470,7 +6457,7 @@ var Captcha = {
6470
6457
 
6471
6458
  // src/mutation.js
6472
6459
  var import_node_crypto = require("node:crypto");
6473
- var import_uuid2 = require("uuid");
6460
+ var import_uuid = require("uuid");
6474
6461
  var logger13 = createInternalLogger("Mutation");
6475
6462
  var MUTATION_MONITOR_MODE = Object.freeze({
6476
6463
  Added: "added",
@@ -6478,7 +6465,7 @@ var MUTATION_MONITOR_MODE = Object.freeze({
6478
6465
  All: "all"
6479
6466
  });
6480
6467
  function generateKey(prefix) {
6481
- return `__${prefix}_${(0, import_uuid2.v4)().replace(/-/g, "_")}`;
6468
+ return `__${prefix}_${(0, import_uuid.v4)().replace(/-/g, "_")}`;
6482
6469
  }
6483
6470
  var Mutation = {
6484
6471
  Mode: MUTATION_MONITOR_MODE,
@@ -6668,7 +6655,7 @@ var Mutation = {
6668
6655
  const overallTimeout = options.timeout ?? 180 * 1e3;
6669
6656
  const onMutation = options.onMutation;
6670
6657
  const pollInterval = 500;
6671
- const sleep = (ms) => new Promise((resolve) => {
6658
+ const sleep2 = (ms) => new Promise((resolve) => {
6672
6659
  setTimeout(resolve, ms);
6673
6660
  });
6674
6661
  const truncate = (value, max = 800) => {
@@ -6860,7 +6847,7 @@ var Mutation = {
6860
6847
  const deadline = Date.now() + overallTimeout;
6861
6848
  let lastState = state2;
6862
6849
  while (Date.now() < deadline) {
6863
- await sleep(pollInterval);
6850
+ await sleep2(pollInterval);
6864
6851
  lastState = await buildState();
6865
6852
  if (!lastState?.hasMatched) {
6866
6853
  continue;