@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/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
 
@@ -1188,7 +1176,8 @@ var writeChildOutput = (stream, output, prefix) => {
1188
1176
  if (!text) return;
1189
1177
  for (const line of text.split(/\r?\n/)) {
1190
1178
  if (!line) continue;
1191
- stream.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] ${prefix} ${line}\n`);
1179
+ stream.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] ${prefix} ${line}
1180
+ `);
1192
1181
  }
1193
1182
  });
1194
1183
  };
@@ -1373,7 +1362,8 @@ var startProxyMeter = (options = {}) => {
1373
1362
  PROXY_METER_DEBUG_MAX_EVENTS: String(debugMaxEvents)
1374
1363
  };
1375
1364
  const stdioLog = createWriteStream(stdioLogPath, { flags: "a" });
1376
- stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] start script=${scriptPath} port=${port} snapshot=${logPath}\n`);
1365
+ stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] start script=${scriptPath} port=${port} snapshot=${logPath}
1366
+ `);
1377
1367
  const child = spawn(process.execPath, [scriptPath], {
1378
1368
  env,
1379
1369
  stdio: ["ignore", "pipe", "pipe"]
@@ -1381,7 +1371,8 @@ var startProxyMeter = (options = {}) => {
1381
1371
  writeChildOutput(stdioLog, child.stdout, "stdout");
1382
1372
  writeChildOutput(stdioLog, child.stderr, "stderr");
1383
1373
  child.once("exit", (code, signal) => {
1384
- stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] exit code=${code ?? ""} signal=${signal ?? ""}\n`);
1374
+ stdioLog.write(`[${(/* @__PURE__ */ new Date()).toISOString()}] [proxy-meter-runtime] exit code=${code ?? ""} signal=${signal ?? ""}
1375
+ `);
1385
1376
  stdioLog.end();
1386
1377
  if (code && code !== 0) {
1387
1378
  logger2.warn(`[proxy-meter] exited with code ${code}; stdio=${stdioLogPath}`);
@@ -5615,9 +5606,6 @@ var LiveView = {
5615
5606
  useLiveView
5616
5607
  };
5617
5608
 
5618
- // src/chaptcha.js
5619
- import { v4 as uuidv4 } from "uuid";
5620
-
5621
5609
  // src/internals/captcha/bytedance.js
5622
5610
  import { mkdir, writeFile } from "fs/promises";
5623
5611
  import path2 from "path";
@@ -6276,6 +6264,9 @@ var sloveCaptcha = solveCaptcha;
6276
6264
 
6277
6265
  // src/chaptcha.js
6278
6266
  var logger12 = createInternalLogger("Captcha");
6267
+ var DOM_MONITOR_WAIT_TIMEOUT_MS = 1e3;
6268
+ var DOM_MONITOR_POST_DETECT_HIDDEN_WAIT_MS = 300;
6269
+ var DOM_MONITOR_RECOVERY_WAIT_MS = 100;
6279
6270
  var DEFAULT_CAPTCHA_RECOGNITION_OPTIONS = Object.freeze({
6280
6271
  token: "eKJvBfwfN0YRav0-VD_44E2VBSfm7l0YtddUQ7cFySI",
6281
6272
  apiUrl: "https://api.jfbym.com/api/YmServer/customApi"
@@ -6296,6 +6287,15 @@ var mergeDefinedOptions = (...sources) => {
6296
6287
  }
6297
6288
  return merged;
6298
6289
  };
6290
+ var sleep = (ms) => new Promise((resolve) => {
6291
+ setTimeout(resolve, ms);
6292
+ });
6293
+ var getErrorMessage = (error) => String(error?.message || error || "");
6294
+ var isTimeoutError = (error) => error?.name === "TimeoutError" || getErrorMessage(error).includes("Timeout");
6295
+ var isPageLifecycleError = (error) => {
6296
+ const message = getErrorMessage(error);
6297
+ 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");
6298
+ };
6299
6299
  function useCaptchaMonitor(page, options) {
6300
6300
  const { domSelector, urlPattern, onDetected } = options;
6301
6301
  if (!domSelector && !urlPattern) {
@@ -6307,10 +6307,13 @@ function useCaptchaMonitor(page, options) {
6307
6307
  let isStopped = false;
6308
6308
  let isHandling = false;
6309
6309
  let frameHandler = null;
6310
- let exposedFunctionName = null;
6310
+ let domMonitorTask = null;
6311
+ let lastTriggeredAt = 0;
6311
6312
  const triggerDetected = async () => {
6312
- if (isStopped || isHandling) return;
6313
+ const now = Date.now();
6314
+ if (isStopped || isHandling || now - lastTriggeredAt < 250) return;
6313
6315
  isHandling = true;
6316
+ lastTriggeredAt = now;
6314
6317
  try {
6315
6318
  await onDetected();
6316
6319
  } finally {
@@ -6319,60 +6322,38 @@ function useCaptchaMonitor(page, options) {
6319
6322
  };
6320
6323
  const cleanupFns = [];
6321
6324
  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 });
6325
+ domMonitorTask = (async () => {
6326
+ const locator = page.locator(domSelector).first();
6327
+ while (!isStopped) {
6328
+ try {
6329
+ await locator.waitFor({ state: "visible", timeout: DOM_MONITOR_WAIT_TIMEOUT_MS });
6330
+ if (isStopped) break;
6331
+ await triggerDetected();
6332
+ if (isStopped) break;
6333
+ await locator.waitFor({
6334
+ state: "hidden",
6335
+ timeout: DOM_MONITOR_POST_DETECT_HIDDEN_WAIT_MS
6336
+ }).catch(() => {
6337
+ });
6338
+ } catch (error) {
6339
+ if (isStopped) break;
6340
+ if (page?.isClosed?.() && isPageLifecycleError(error)) break;
6341
+ if (isTimeoutError(error) || isPageLifecycleError(error)) {
6342
+ await sleep(DOM_MONITOR_RECOVERY_WAIT_MS);
6343
+ continue;
6350
6344
  }
6351
- };
6352
- if (document.readyState === "loading") {
6353
- window.addEventListener("DOMContentLoaded", mountObserver);
6354
- } else {
6355
- mountObserver();
6345
+ logger12.warning(
6346
+ "useCaptchaMonitor",
6347
+ `DOM \u76D1\u63A7\u51FA\u73B0\u5F02\u5E38\uFF08\u7EE7\u7EED\u91CD\u8BD5\uFF09: selector=${domSelector}, error=${getErrorMessage(error)}`
6348
+ );
6349
+ await sleep(DOM_MONITOR_RECOVERY_WAIT_MS);
6356
6350
  }
6357
- window[cleanupName] = () => {
6358
- if (observer) {
6359
- observer.disconnect();
6360
- observer = null;
6361
- }
6362
- };
6363
- })();
6364
- }, { selector: domSelector, callbackName: exposedFunctionName, cleanerName });
6351
+ }
6352
+ })();
6365
6353
  logger12.success("useCaptchaMonitor", `DOM \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${domSelector}`);
6366
6354
  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
- }
6355
+ await domMonitorTask?.catch(() => {
6356
+ });
6376
6357
  });
6377
6358
  }
6378
6359
  if (urlPattern) {
@@ -6387,6 +6368,12 @@ function useCaptchaMonitor(page, options) {
6387
6368
  };
6388
6369
  page.on("framenavigated", frameHandler);
6389
6370
  logger12.success("useCaptchaMonitor", `URL \u76D1\u63A7\u5DF2\u542F\u7528\uFF1A${urlPattern}`);
6371
+ Promise.resolve().then(async () => {
6372
+ if (!isStopped && page.url().includes(urlPattern)) {
6373
+ await triggerDetected();
6374
+ }
6375
+ }).catch(() => {
6376
+ });
6390
6377
  cleanupFns.push(async () => {
6391
6378
  page.off("framenavigated", frameHandler);
6392
6379
  });
@@ -6394,10 +6381,10 @@ function useCaptchaMonitor(page, options) {
6394
6381
  return {
6395
6382
  stop: async () => {
6396
6383
  logger12.info("\u6B63\u5728\u505C\u6B62\u9A8C\u8BC1\u7801\u76D1\u63A7...");
6384
+ isStopped = true;
6397
6385
  for (const fn of cleanupFns) {
6398
6386
  await fn();
6399
6387
  }
6400
- isStopped = true;
6401
6388
  }
6402
6389
  };
6403
6390
  }
@@ -6442,7 +6429,7 @@ var Captcha = {
6442
6429
 
6443
6430
  // src/mutation.js
6444
6431
  import { createHash } from "node:crypto";
6445
- import { v4 as uuidv42 } from "uuid";
6432
+ import { v4 as uuidv4 } from "uuid";
6446
6433
  var logger13 = createInternalLogger("Mutation");
6447
6434
  var MUTATION_MONITOR_MODE = Object.freeze({
6448
6435
  Added: "added",
@@ -6450,7 +6437,7 @@ var MUTATION_MONITOR_MODE = Object.freeze({
6450
6437
  All: "all"
6451
6438
  });
6452
6439
  function generateKey(prefix) {
6453
- return `__${prefix}_${uuidv42().replace(/-/g, "_")}`;
6440
+ return `__${prefix}_${uuidv4().replace(/-/g, "_")}`;
6454
6441
  }
6455
6442
  var Mutation = {
6456
6443
  Mode: MUTATION_MONITOR_MODE,
@@ -6640,7 +6627,7 @@ var Mutation = {
6640
6627
  const overallTimeout = options.timeout ?? 180 * 1e3;
6641
6628
  const onMutation = options.onMutation;
6642
6629
  const pollInterval = 500;
6643
- const sleep = (ms) => new Promise((resolve) => {
6630
+ const sleep2 = (ms) => new Promise((resolve) => {
6644
6631
  setTimeout(resolve, ms);
6645
6632
  });
6646
6633
  const truncate = (value, max = 800) => {
@@ -6832,7 +6819,7 @@ var Mutation = {
6832
6819
  const deadline = Date.now() + overallTimeout;
6833
6820
  let lastState = state2;
6834
6821
  while (Date.now() < deadline) {
6835
- await sleep(pollInterval);
6822
+ await sleep2(pollInterval);
6836
6823
  lastState = await buildState();
6837
6824
  if (!lastState?.hasMatched) {
6838
6825
  continue;