@skrillex1224/playwright-toolkit 2.1.238 → 2.1.240

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 CHANGED
@@ -83,7 +83,7 @@ var createActorInfo = (info) => {
83
83
  const normalizeShare2 = (value) => {
84
84
  const raw = value && typeof value === "object" ? value : {};
85
85
  const modeRaw = String(raw.mode || "dom").trim().toLowerCase();
86
- const mode = modeRaw === "response" ? "response" : "dom";
86
+ const mode = ["dom", "response", "custom"].includes(modeRaw) ? modeRaw : "dom";
87
87
  const prefix = String(raw.prefix || "").trim();
88
88
  const rawXurl = Array.isArray(raw.xurl) ? raw.xurl : [];
89
89
  const normalizeMatcherList = (input) => {
@@ -240,7 +240,7 @@ var ActorInfo = {
240
240
  path: "/",
241
241
  device: Device.Mobile,
242
242
  share: {
243
- mode: "dom",
243
+ mode: "custom",
244
244
  prefix: "",
245
245
  xurl: []
246
246
  }
@@ -8367,7 +8367,7 @@ var normalizeXurl = (value) => {
8367
8367
  var normalizeShare = (share) => {
8368
8368
  const source = share && typeof share === "object" ? share : {};
8369
8369
  const modeRaw = String(source.mode || "dom").trim().toLowerCase();
8370
- const mode = modeRaw === "response" ? "response" : "dom";
8370
+ const mode = ["dom", "response", "custom"].includes(modeRaw) ? modeRaw : "dom";
8371
8371
  return {
8372
8372
  mode,
8373
8373
  prefix: normalizePrefix(source.prefix),
@@ -8483,16 +8483,17 @@ var Share = {
8483
8483
  * 捕获分享链接(单模式)
8484
8484
  * - mode='dom': 仅 DOM 监听
8485
8485
  * - mode='response': 仅接口监听
8486
+ * - mode='custom': 使用 performActions 返回值作为链接
8486
8487
  *
8487
8488
  * @param {import('playwright').Page} page
8488
8489
  * @param {Object} [options]
8489
- * @param {{ mode?: 'dom' | 'response', prefix: string, xurl?: Array<string | string[]> }} options.share
8490
+ * @param {{ mode?: 'dom' | 'response' | 'custom', prefix: string, xurl?: Array<string | string[]> }} options.share
8490
8491
  * @param {number} [options.timeoutMs=50000]
8491
8492
  * @param {number} [options.payloadSnapshotMaxLen=500]
8492
8493
  * @param {string | string[]} [options.domSelectors='html']
8493
8494
  * @param {'added' | 'changed' | 'all'} [options.domMode='all']
8494
- * @param {() => Promise<void>} [options.performActions]
8495
- * @returns {Promise<{ link: string | null; payloadText: string; payloadSnapshot: string; source: 'dom' | 'response' | 'none' }>}
8495
+ * @param {() => void | string | { link?: string | null; payloadText?: string } | Promise<void | string | { link?: string | null; payloadText?: string }>} [options.performActions]
8496
+ * @returns {Promise<{ link: string | null; payloadText: string; payloadSnapshot: string; source: 'dom' | 'response' | 'custom' | 'none' }>}
8496
8497
  */
8497
8498
  async captureLink(page, options = {}) {
8498
8499
  const share = normalizeShare(options.share);
@@ -8505,7 +8506,7 @@ var Share = {
8505
8506
  if (share.prefix === void 0) {
8506
8507
  throw new Error("Share.captureLink requires options.share.prefix");
8507
8508
  }
8508
- if (share.mode !== "dom" && share.mode !== "response") {
8509
+ if (share.mode !== "dom" && share.mode !== "response" && share.mode !== "custom") {
8509
8510
  throw new Error(`Share.captureLink unsupported share.mode: ${share.mode}`);
8510
8511
  }
8511
8512
  const apiMatchers = share.mode === "response" ? share.xurl[0] || [] : [];
@@ -8527,7 +8528,8 @@ var Share = {
8527
8528
  };
8528
8529
  const candidates = {
8529
8530
  dom: null,
8530
- response: null
8531
+ response: null,
8532
+ custom: null
8531
8533
  };
8532
8534
  const setCandidate = (source, link, payloadText = "") => {
8533
8535
  const safe = String(link || "").trim();
@@ -8627,37 +8629,47 @@ var Share = {
8627
8629
  logger15.info(`\u5F53\u524D\u4E3A\u63A5\u53E3\u6A21\u5F0F\uFF0C\u6302\u8F7D response \u76D1\u542C: apiMatchers=${toJsonInline(apiMatchers, 160)}`);
8628
8630
  page.on("response", onResponse);
8629
8631
  }
8632
+ if (share.mode === "custom") {
8633
+ logger15.info("\u5F53\u524D\u4E3A custom \u6A21\u5F0F\uFF0C\u5C06\u4F7F\u7528 performActions \u8FD4\u56DE\u503C");
8634
+ }
8630
8635
  const deadline = Date.now() + timeoutMs;
8631
8636
  const getRemainingMs = () => Math.max(0, deadline - Date.now());
8632
8637
  try {
8633
8638
  const actionTimeout = getRemainingMs();
8634
8639
  logger15.start("captureLink.performActions", `\u6267\u884C\u52A8\u4F5C\u9884\u7B97=${actionTimeout}ms`);
8640
+ let actionValue;
8635
8641
  if (actionTimeout > 0) {
8636
8642
  let timer = null;
8637
- let actionError = null;
8638
- const actionPromise = Promise.resolve().then(() => performActions()).then(() => "__ACTION_DONE__").catch((error) => {
8639
- actionError = error;
8640
- return "__ACTION_ERROR__";
8641
- });
8643
+ const actionPromise = Promise.resolve().then(() => performActions()).then((result) => ({ type: "done", result })).catch((error) => ({ type: "error", error }));
8642
8644
  const timeoutPromise = new Promise((resolve) => {
8643
- timer = setTimeout(() => resolve("__ACTION_TIMEOUT__"), actionTimeout);
8645
+ timer = setTimeout(() => resolve({ type: "timeout" }), actionTimeout);
8644
8646
  });
8645
8647
  const actionResult = await Promise.race([actionPromise, timeoutPromise]);
8646
8648
  if (timer) clearTimeout(timer);
8647
- if (actionResult === "__ACTION_ERROR__") {
8648
- logger15.fail("captureLink.performActions", actionError);
8649
- throw actionError;
8649
+ if (actionResult.type === "error") {
8650
+ logger15.fail("captureLink.performActions", actionResult.error);
8651
+ throw actionResult.error;
8650
8652
  }
8651
- if (actionResult === "__ACTION_TIMEOUT__") {
8653
+ if (actionResult.type === "timeout") {
8652
8654
  stats.actionTimedOut = true;
8653
8655
  logger15.warning(`performActions \u5DF2\u8D85\u65F6 (${actionTimeout}ms)\uFF0C\u52A8\u4F5C\u53EF\u80FD\u4ECD\u5728\u5F02\u6B65\u6267\u884C`);
8654
8656
  } else {
8657
+ actionValue = actionResult.result;
8655
8658
  logger15.success("captureLink.performActions", "\u6267\u884C\u52A8\u4F5C\u5B8C\u6210");
8656
8659
  }
8657
8660
  }
8661
+ if (share.mode === "custom") {
8662
+ const customLink = typeof actionValue === "string" ? actionValue : actionValue?.link || actionValue?.payloadText;
8663
+ const customPayloadText = typeof actionValue === "string" ? actionValue : actionValue?.payloadText;
8664
+ if (setCandidate("custom", customLink, customPayloadText)) {
8665
+ logger15.success("captureLink.customResult", `custom \u547D\u4E2D\u5206\u4EAB\u94FE\u63A5: link=${candidates.custom.link}`);
8666
+ } else {
8667
+ logger15.warning("performActions \u6267\u884C\u5B8C\u6210\u4F46\u672A\u8FD4\u56DE\u6709\u6548\u5206\u4EAB\u94FE\u63A5");
8668
+ }
8669
+ }
8658
8670
  let nextProgressLogTs = Date.now() + 3e3;
8659
8671
  while (true) {
8660
- const selected = share.mode === "dom" ? candidates.dom : candidates.response;
8672
+ const selected = candidates[share.mode];
8661
8673
  if (selected?.link) {
8662
8674
  logger15.success("captureLink", `\u6355\u83B7\u6210\u529F: source=${share.mode}, link=${selected.link}`);
8663
8675
  return {
@@ -8667,6 +8679,7 @@ var Share = {
8667
8679
  source: share.mode
8668
8680
  };
8669
8681
  }
8682
+ if (share.mode === "custom") break;
8670
8683
  const remaining = getRemainingMs();
8671
8684
  if (remaining <= 0) break;
8672
8685
  const now = Date.now();