@skrillex1224/playwright-toolkit 2.1.240 → 2.1.241
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 +2 -1
- package/dist/browser.js.map +2 -2
- package/dist/index.cjs +219 -63
- package/dist/index.cjs.map +3 -3
- package/dist/index.js +219 -63
- package/dist/index.js.map +3 -3
- package/index.d.ts +5 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -140,8 +140,9 @@ var ActorInfo = {
|
|
|
140
140
|
qbot: createActorInfo({
|
|
141
141
|
key: "qbot",
|
|
142
142
|
name: "QQ\u6D4F\u89C8\u5668AI\u641C",
|
|
143
|
-
domain: "sogou.com",
|
|
143
|
+
domain: "m.sogou.com",
|
|
144
144
|
path: "/web",
|
|
145
|
+
device: Device.Mobile,
|
|
145
146
|
share: {
|
|
146
147
|
mode: "dom",
|
|
147
148
|
prefix: "",
|
|
@@ -722,14 +723,16 @@ var expandScrollableContent = async (page, options = {}) => {
|
|
|
722
723
|
expandDocumentElements: options.expandDocumentElements === true
|
|
723
724
|
});
|
|
724
725
|
};
|
|
725
|
-
var
|
|
726
|
+
var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
|
|
726
727
|
return await page.evaluate(({ className, targetHeight }) => {
|
|
728
|
+
const viewportWidth = window.innerWidth || document.documentElement?.clientWidth || document.body?.clientWidth || 0;
|
|
727
729
|
const viewportHeight = window.innerHeight || document.documentElement?.clientHeight || document.body?.clientHeight || 0;
|
|
730
|
+
const scrollY = window.scrollY || window.pageYOffset || 0;
|
|
728
731
|
const safeTargetHeight = Math.ceil(Number(targetHeight) || 0);
|
|
729
|
-
|
|
730
|
-
if (deltaY <= 1) {
|
|
732
|
+
if (safeTargetHeight <= viewportHeight + 1) {
|
|
731
733
|
return 0;
|
|
732
734
|
}
|
|
735
|
+
const hasOwn = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
|
|
733
736
|
const isVisible = (el, style, rect) => {
|
|
734
737
|
if (!el || !style || !rect) return false;
|
|
735
738
|
if (style.display === "none" || style.visibility === "hidden" || style.visibility === "collapse") {
|
|
@@ -738,7 +741,7 @@ var pinBottomAffixedElements = async (page, options = {}) => {
|
|
|
738
741
|
if (Number(style.opacity) === 0) return false;
|
|
739
742
|
return rect.width > 0 && rect.height > 0;
|
|
740
743
|
};
|
|
741
|
-
const
|
|
744
|
+
const edgeThreshold = Math.max(24, Math.min(96, viewportHeight * 0.12));
|
|
742
745
|
const maxAffixedHeight = Math.max(56, viewportHeight * 0.65);
|
|
743
746
|
const candidates = [];
|
|
744
747
|
document.querySelectorAll("*").forEach((el) => {
|
|
@@ -748,28 +751,49 @@ var pinBottomAffixedElements = async (page, options = {}) => {
|
|
|
748
751
|
const rect = el.getBoundingClientRect();
|
|
749
752
|
if (!isVisible(el, style, rect)) return;
|
|
750
753
|
if (rect.height > maxAffixedHeight) return;
|
|
751
|
-
if (rect.
|
|
754
|
+
if (rect.width < viewportWidth * 0.25 && rect.height < 80) return;
|
|
755
|
+
const top = Number.parseFloat(style.top);
|
|
752
756
|
const bottom = Number.parseFloat(style.bottom);
|
|
757
|
+
const hasTopRule = Number.isFinite(top) && top <= Math.max(160, viewportHeight * 0.25);
|
|
753
758
|
const hasBottomRule = Number.isFinite(bottom) && bottom <= Math.max(160, viewportHeight * 0.25);
|
|
754
|
-
const
|
|
755
|
-
|
|
756
|
-
|
|
759
|
+
const isNearViewportTop = rect.top <= edgeThreshold;
|
|
760
|
+
const isNearViewportBottom = rect.bottom >= viewportHeight - edgeThreshold;
|
|
761
|
+
const edge = (hasBottomRule || isNearViewportBottom) && !(hasTopRule || isNearViewportTop) ? "bottom" : "top";
|
|
762
|
+
if (position === "fixed" && edge === "top" && !hasTopRule && !isNearViewportTop) return;
|
|
763
|
+
if (position === "fixed" && edge === "bottom" && !hasBottomRule && !isNearViewportBottom) return;
|
|
764
|
+
if (position === "sticky" && !hasTopRule && !hasBottomRule && !isNearViewportTop && !isNearViewportBottom) return;
|
|
765
|
+
candidates.push({ el, position, edge });
|
|
757
766
|
});
|
|
758
|
-
const candidateSet = new Set(candidates);
|
|
759
|
-
const topLevelCandidates = candidates.filter((el) => {
|
|
767
|
+
const candidateSet = new Set(candidates.map(({ el }) => el));
|
|
768
|
+
const topLevelCandidates = candidates.filter(({ el }) => {
|
|
760
769
|
for (let parent = el.parentElement; parent; parent = parent.parentElement) {
|
|
761
770
|
if (candidateSet.has(parent)) return false;
|
|
762
771
|
}
|
|
763
772
|
return true;
|
|
764
773
|
});
|
|
765
|
-
topLevelCandidates.forEach((el) => {
|
|
766
|
-
if (!
|
|
767
|
-
el.dataset.
|
|
774
|
+
topLevelCandidates.forEach(({ el, position, edge }) => {
|
|
775
|
+
if (!hasOwn(el.dataset, "pkAffixedAdjusted")) {
|
|
776
|
+
el.dataset.pkAffixedAdjusted = "1";
|
|
777
|
+
el.dataset.pkOrigPosition = el.style.getPropertyValue("position") || "";
|
|
778
|
+
el.dataset.pkOrigPositionPriority = el.style.getPropertyPriority("position") || "";
|
|
779
|
+
el.dataset.pkOrigTop = el.style.getPropertyValue("top") || "";
|
|
780
|
+
el.dataset.pkOrigTopPriority = el.style.getPropertyPriority("top") || "";
|
|
781
|
+
el.dataset.pkOrigBottom = el.style.getPropertyValue("bottom") || "";
|
|
782
|
+
el.dataset.pkOrigBottomPriority = el.style.getPropertyPriority("bottom") || "";
|
|
768
783
|
el.dataset.pkOrigTranslate = el.style.getPropertyValue("translate") || "";
|
|
769
784
|
el.dataset.pkOrigTranslatePriority = el.style.getPropertyPriority("translate") || "";
|
|
770
785
|
}
|
|
771
786
|
el.classList.add(className);
|
|
772
|
-
|
|
787
|
+
if (position === "fixed") {
|
|
788
|
+
const deltaY = edge === "bottom" ? safeTargetHeight - viewportHeight - scrollY : -scrollY;
|
|
789
|
+
if (Math.abs(deltaY) > 1) {
|
|
790
|
+
el.style.setProperty("translate", `0 ${Math.round(deltaY)}px`, "important");
|
|
791
|
+
}
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
el.style.setProperty("position", "relative", "important");
|
|
795
|
+
el.style.setProperty("top", "auto", "important");
|
|
796
|
+
el.style.setProperty("bottom", "auto", "important");
|
|
773
797
|
});
|
|
774
798
|
return topLevelCandidates.length;
|
|
775
799
|
}, {
|
|
@@ -777,7 +801,7 @@ var pinBottomAffixedElements = async (page, options = {}) => {
|
|
|
777
801
|
targetHeight: options.targetHeight
|
|
778
802
|
});
|
|
779
803
|
};
|
|
780
|
-
var
|
|
804
|
+
var restoreAffixedElementsForExpandedScreenshot = async (page) => {
|
|
781
805
|
await page.evaluate((className) => {
|
|
782
806
|
const hasOwn = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
|
|
783
807
|
const expansionKeys = [
|
|
@@ -786,13 +810,28 @@ var restoreBottomAffixedElements = async (page) => {
|
|
|
786
810
|
"pkOrigMinHeight",
|
|
787
811
|
"pkOrigMaxHeight"
|
|
788
812
|
];
|
|
789
|
-
document.querySelectorAll('[data-pk-
|
|
813
|
+
document.querySelectorAll('[data-pk-affixed-adjusted="1"]').forEach((el) => {
|
|
814
|
+
if (hasOwn(el.dataset, "pkOrigPosition")) {
|
|
815
|
+
el.style.setProperty("position", el.dataset.pkOrigPosition || "", el.dataset.pkOrigPositionPriority || "");
|
|
816
|
+
delete el.dataset.pkOrigPosition;
|
|
817
|
+
delete el.dataset.pkOrigPositionPriority;
|
|
818
|
+
}
|
|
819
|
+
if (hasOwn(el.dataset, "pkOrigTop")) {
|
|
820
|
+
el.style.setProperty("top", el.dataset.pkOrigTop || "", el.dataset.pkOrigTopPriority || "");
|
|
821
|
+
delete el.dataset.pkOrigTop;
|
|
822
|
+
delete el.dataset.pkOrigTopPriority;
|
|
823
|
+
}
|
|
824
|
+
if (hasOwn(el.dataset, "pkOrigBottom")) {
|
|
825
|
+
el.style.setProperty("bottom", el.dataset.pkOrigBottom || "", el.dataset.pkOrigBottomPriority || "");
|
|
826
|
+
delete el.dataset.pkOrigBottom;
|
|
827
|
+
delete el.dataset.pkOrigBottomPriority;
|
|
828
|
+
}
|
|
790
829
|
if (hasOwn(el.dataset, "pkOrigTranslate")) {
|
|
791
830
|
el.style.setProperty("translate", el.dataset.pkOrigTranslate || "", el.dataset.pkOrigTranslatePriority || "");
|
|
792
831
|
delete el.dataset.pkOrigTranslate;
|
|
793
832
|
delete el.dataset.pkOrigTranslatePriority;
|
|
794
833
|
}
|
|
795
|
-
delete el.dataset.
|
|
834
|
+
delete el.dataset.pkAffixedAdjusted;
|
|
796
835
|
const stillExpanded = expansionKeys.some((key) => hasOwn(el.dataset, key));
|
|
797
836
|
if (!stillExpanded) {
|
|
798
837
|
el.classList.remove(className);
|
|
@@ -821,8 +860,8 @@ var prepareExpandedFullPageScreenshot = async (page, options = {}) => {
|
|
|
821
860
|
});
|
|
822
861
|
viewportResized = true;
|
|
823
862
|
} else {
|
|
824
|
-
await
|
|
825
|
-
logger.warning(`\u79FB\u52A8\u7AEF\u5438\
|
|
863
|
+
await adjustAffixedElementsForExpandedScreenshot(page, { targetHeight }).catch((error) => {
|
|
864
|
+
logger.warning(`\u79FB\u52A8\u7AEF\u5438\u9644\u5143\u7D20\u91CD\u5B9A\u4F4D\u5931\u8D25: ${error?.message || error}`);
|
|
826
865
|
});
|
|
827
866
|
}
|
|
828
867
|
if (settleMs > 0) {
|
|
@@ -928,8 +967,8 @@ var captureExpandedFullPageScreenshot = async (page, options = {}) => {
|
|
|
928
967
|
maxClipHeight: state.targetHeight
|
|
929
968
|
});
|
|
930
969
|
} finally {
|
|
931
|
-
await
|
|
932
|
-
logger.warning(`\u79FB\u52A8\u7AEF\u5438\
|
|
970
|
+
await restoreAffixedElementsForExpandedScreenshot(page).catch((error) => {
|
|
971
|
+
logger.warning(`\u79FB\u52A8\u7AEF\u5438\u9644\u5143\u7D20\u6062\u590D\u5931\u8D25: ${error?.message || error}`);
|
|
933
972
|
});
|
|
934
973
|
if (options.restore) {
|
|
935
974
|
await restoreExpandedFullPageScreenshot(page, state);
|
|
@@ -3369,6 +3408,26 @@ var waitJitter = (base, jitterPercent = 0.3) => delay3(jitterMs(base, jitterPerc
|
|
|
3369
3408
|
// src/internals/humanize/mobile.js
|
|
3370
3409
|
var logger7 = createInternalLogger("Humanize.Mobile");
|
|
3371
3410
|
var initializedPages = /* @__PURE__ */ new WeakSet();
|
|
3411
|
+
var DEFAULT_TAP_TIMEOUT_MS = 2500;
|
|
3412
|
+
var DEFAULT_MOUSE_TAP_FALLBACK_TIMEOUT_MS = 1200;
|
|
3413
|
+
var DEFAULT_ACTIVATE_FALLBACK_TIMEOUT_MS = 900;
|
|
3414
|
+
var INTERACTIVE_SELECTOR = [
|
|
3415
|
+
"button",
|
|
3416
|
+
'[role="button"]',
|
|
3417
|
+
"a[href]",
|
|
3418
|
+
"label",
|
|
3419
|
+
"input",
|
|
3420
|
+
"textarea",
|
|
3421
|
+
"select",
|
|
3422
|
+
"summary",
|
|
3423
|
+
'[contenteditable="true"]',
|
|
3424
|
+
'[tabindex]:not([tabindex="-1"])'
|
|
3425
|
+
].join(",");
|
|
3426
|
+
var EDITABLE_SELECTOR = [
|
|
3427
|
+
"input",
|
|
3428
|
+
"textarea",
|
|
3429
|
+
'[contenteditable="true"]'
|
|
3430
|
+
].join(",");
|
|
3372
3431
|
var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
3373
3432
|
var resolveViewport = (page) => page?.viewportSize?.() || { width: 390, height: 844 };
|
|
3374
3433
|
var describeTarget = (target) => {
|
|
@@ -3391,8 +3450,24 @@ var clipBoxToViewport = (box, viewport) => {
|
|
|
3391
3450
|
}
|
|
3392
3451
|
return box;
|
|
3393
3452
|
};
|
|
3453
|
+
var withTimeout = async (operation, timeoutMs, label) => {
|
|
3454
|
+
const safeTimeoutMs = Math.max(50, Number(timeoutMs || 0));
|
|
3455
|
+
let timeoutId = null;
|
|
3456
|
+
try {
|
|
3457
|
+
return await Promise.race([
|
|
3458
|
+
Promise.resolve().then(operation),
|
|
3459
|
+
new Promise((_, reject) => {
|
|
3460
|
+
timeoutId = setTimeout(() => {
|
|
3461
|
+
reject(new Error(`${label} timeout after ${safeTimeoutMs}ms`));
|
|
3462
|
+
}, safeTimeoutMs);
|
|
3463
|
+
})
|
|
3464
|
+
]);
|
|
3465
|
+
} finally {
|
|
3466
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
3467
|
+
}
|
|
3468
|
+
};
|
|
3394
3469
|
var checkElementVisibility = async (element) => {
|
|
3395
|
-
return element.evaluate((el) => {
|
|
3470
|
+
return element.evaluate((el, interactiveSelector) => {
|
|
3396
3471
|
const targetStyle = window.getComputedStyle(el);
|
|
3397
3472
|
if (!targetStyle || targetStyle.display === "none" || targetStyle.visibility === "hidden" || targetStyle.visibility === "collapse") {
|
|
3398
3473
|
return { code: "NOT_INTERACTABLE", reason: "\u5143\u7D20\u4E0D\u53EF\u89C1", direction: "down" };
|
|
@@ -3409,10 +3484,12 @@ var checkElementVisibility = async (element) => {
|
|
|
3409
3484
|
let clipTop = 0;
|
|
3410
3485
|
let clipBottom = viewH;
|
|
3411
3486
|
let isFixed = false;
|
|
3487
|
+
let positioning = null;
|
|
3412
3488
|
for (let node = el; node && node !== document.body; node = node.parentElement) {
|
|
3413
3489
|
const style = window.getComputedStyle(node);
|
|
3414
3490
|
if (style && (style.position === "fixed" || style.position === "sticky")) {
|
|
3415
3491
|
isFixed = true;
|
|
3492
|
+
positioning = style.position;
|
|
3416
3493
|
break;
|
|
3417
3494
|
}
|
|
3418
3495
|
}
|
|
@@ -3448,21 +3525,10 @@ var checkElementVisibility = async (element) => {
|
|
|
3448
3525
|
direction: centerY < clipTop ? "up" : "down",
|
|
3449
3526
|
cy: centerY,
|
|
3450
3527
|
viewH,
|
|
3451
|
-
isFixed
|
|
3528
|
+
isFixed,
|
|
3529
|
+
positioning
|
|
3452
3530
|
};
|
|
3453
3531
|
}
|
|
3454
|
-
const interactiveSelector = [
|
|
3455
|
-
"button",
|
|
3456
|
-
'[role="button"]',
|
|
3457
|
-
"a[href]",
|
|
3458
|
-
"label",
|
|
3459
|
-
"input",
|
|
3460
|
-
"textarea",
|
|
3461
|
-
"select",
|
|
3462
|
-
"summary",
|
|
3463
|
-
'[contenteditable="true"]',
|
|
3464
|
-
'[tabindex]:not([tabindex="-1"])'
|
|
3465
|
-
].join(",");
|
|
3466
3532
|
const targetInteractive = typeof el.closest === "function" ? el.closest(interactiveSelector) : null;
|
|
3467
3533
|
const sameInteractiveTarget = (pointElement) => {
|
|
3468
3534
|
if (!pointElement) return false;
|
|
@@ -3484,6 +3550,7 @@ var checkElementVisibility = async (element) => {
|
|
|
3484
3550
|
id: node.id || "",
|
|
3485
3551
|
className,
|
|
3486
3552
|
isFixed: Boolean(style && (style.position === "fixed" || style.position === "sticky")),
|
|
3553
|
+
positioning: style?.position || "",
|
|
3487
3554
|
top: rect2 ? rect2.top : null,
|
|
3488
3555
|
bottom: rect2 ? rect2.bottom : null,
|
|
3489
3556
|
left: rect2 ? rect2.left : null,
|
|
@@ -3501,7 +3568,7 @@ var checkElementVisibility = async (element) => {
|
|
|
3501
3568
|
for (const point of samplePoints) {
|
|
3502
3569
|
const pointElement = document.elementFromPoint(point.x, point.y);
|
|
3503
3570
|
if (sameInteractiveTarget(pointElement)) {
|
|
3504
|
-
return { code: "VISIBLE", isFixed };
|
|
3571
|
+
return { code: "VISIBLE", isFixed, positioning };
|
|
3505
3572
|
}
|
|
3506
3573
|
obstruction = obstruction || describeElement(pointElement);
|
|
3507
3574
|
}
|
|
@@ -3513,14 +3580,15 @@ var checkElementVisibility = async (element) => {
|
|
|
3513
3580
|
obstruction,
|
|
3514
3581
|
cy,
|
|
3515
3582
|
viewH,
|
|
3516
|
-
isFixed
|
|
3583
|
+
isFixed,
|
|
3584
|
+
positioning
|
|
3517
3585
|
};
|
|
3518
3586
|
}
|
|
3519
|
-
return { code: "VISIBLE", isFixed };
|
|
3520
|
-
});
|
|
3587
|
+
return { code: "VISIBLE", isFixed, positioning };
|
|
3588
|
+
}, INTERACTIVE_SELECTOR);
|
|
3521
3589
|
};
|
|
3522
3590
|
var resolveSafeTapPoint = async (element) => {
|
|
3523
|
-
return element.evaluate((el) => {
|
|
3591
|
+
return element.evaluate((el, interactiveSelector) => {
|
|
3524
3592
|
const rect = el.getBoundingClientRect();
|
|
3525
3593
|
if (!rect || rect.width <= 0 || rect.height <= 0) {
|
|
3526
3594
|
return null;
|
|
@@ -3557,18 +3625,6 @@ var resolveSafeTapPoint = async (element) => {
|
|
|
3557
3625
|
if (visibleWidth <= 1 || visibleHeight <= 1) {
|
|
3558
3626
|
return null;
|
|
3559
3627
|
}
|
|
3560
|
-
const interactiveSelector = [
|
|
3561
|
-
"button",
|
|
3562
|
-
'[role="button"]',
|
|
3563
|
-
"a[href]",
|
|
3564
|
-
"label",
|
|
3565
|
-
"input",
|
|
3566
|
-
"textarea",
|
|
3567
|
-
"select",
|
|
3568
|
-
"summary",
|
|
3569
|
-
'[contenteditable="true"]',
|
|
3570
|
-
'[tabindex]:not([tabindex="-1"])'
|
|
3571
|
-
].join(",");
|
|
3572
3628
|
const targetInteractive = typeof el.closest === "function" ? el.closest(interactiveSelector) : null;
|
|
3573
3629
|
const sameInteractiveTarget = (pointElement) => {
|
|
3574
3630
|
if (!pointElement) return false;
|
|
@@ -3606,6 +3662,46 @@ var resolveSafeTapPoint = async (element) => {
|
|
|
3606
3662
|
x: chosen.x,
|
|
3607
3663
|
y: chosen.y
|
|
3608
3664
|
};
|
|
3665
|
+
}, INTERACTIVE_SELECTOR);
|
|
3666
|
+
};
|
|
3667
|
+
var activateElementFallback = async (element, point = null, options = {}) => {
|
|
3668
|
+
return element.evaluate((el, { innerPoint, innerOptions, interactiveSelector, editableSelector }) => {
|
|
3669
|
+
const pointElement = innerPoint ? document.elementFromPoint(innerPoint.x, innerPoint.y) : null;
|
|
3670
|
+
const nearestInteractive = (node) => {
|
|
3671
|
+
if (!node || typeof node.closest !== "function") return null;
|
|
3672
|
+
return node.closest(interactiveSelector);
|
|
3673
|
+
};
|
|
3674
|
+
const targetInteractive = nearestInteractive(el);
|
|
3675
|
+
const pointInteractive = nearestInteractive(pointElement);
|
|
3676
|
+
let target = null;
|
|
3677
|
+
if (pointInteractive && (pointInteractive === targetInteractive || pointInteractive === el || pointInteractive.contains(el) || el.contains(pointInteractive))) {
|
|
3678
|
+
target = pointInteractive;
|
|
3679
|
+
}
|
|
3680
|
+
target = target || targetInteractive || el;
|
|
3681
|
+
const editable = typeof target.closest === "function" ? target.closest(editableSelector) : null;
|
|
3682
|
+
if (editable && typeof editable.focus === "function") {
|
|
3683
|
+
editable.focus({ preventScroll: true });
|
|
3684
|
+
if (innerOptions.editableOnly) {
|
|
3685
|
+
return { activated: true, method: "focus", tag: editable.tagName || "" };
|
|
3686
|
+
}
|
|
3687
|
+
}
|
|
3688
|
+
if (typeof target.focus === "function") {
|
|
3689
|
+
target.focus({ preventScroll: true });
|
|
3690
|
+
}
|
|
3691
|
+
if (!innerOptions.editableOnly && typeof target.click === "function") {
|
|
3692
|
+
target.click();
|
|
3693
|
+
return { activated: true, method: "dom-click", tag: target.tagName || "" };
|
|
3694
|
+
}
|
|
3695
|
+
return {
|
|
3696
|
+
activated: Boolean(editable),
|
|
3697
|
+
method: editable ? "focus" : "none",
|
|
3698
|
+
tag: target?.tagName || ""
|
|
3699
|
+
};
|
|
3700
|
+
}, {
|
|
3701
|
+
innerPoint: point,
|
|
3702
|
+
innerOptions: options || {},
|
|
3703
|
+
interactiveSelector: INTERACTIVE_SELECTOR,
|
|
3704
|
+
editableSelector: EDITABLE_SELECTOR
|
|
3609
3705
|
});
|
|
3610
3706
|
};
|
|
3611
3707
|
var getScrollableRect = async (element) => {
|
|
@@ -3810,12 +3906,31 @@ var dispatchTouchSwipe = async (page, deltaY, options = {}) => {
|
|
|
3810
3906
|
}
|
|
3811
3907
|
}
|
|
3812
3908
|
};
|
|
3813
|
-
var tapPoint = async (page, point) => {
|
|
3909
|
+
var tapPoint = async (page, point, options = {}) => {
|
|
3910
|
+
const {
|
|
3911
|
+
timeoutMs = DEFAULT_TAP_TIMEOUT_MS,
|
|
3912
|
+
mouseFallbackTimeoutMs = DEFAULT_MOUSE_TAP_FALLBACK_TIMEOUT_MS,
|
|
3913
|
+
allowMouseFallback = true
|
|
3914
|
+
} = options;
|
|
3814
3915
|
if (page.touchscreen && typeof page.touchscreen.tap === "function") {
|
|
3815
|
-
|
|
3816
|
-
|
|
3916
|
+
try {
|
|
3917
|
+
await withTimeout(
|
|
3918
|
+
() => page.touchscreen.tap(point.x, point.y),
|
|
3919
|
+
timeoutMs,
|
|
3920
|
+
"touchscreen.tap"
|
|
3921
|
+
);
|
|
3922
|
+
return { method: "touchscreen" };
|
|
3923
|
+
} catch (error) {
|
|
3924
|
+
logger7.warn(`tapPoint | touchscreen.tap \u5931\u8D25\u6216\u8D85\u65F6\uFF0C\u5C1D\u8BD5\u9F20\u6807\u515C\u5E95: ${error?.message || error}`);
|
|
3925
|
+
if (!allowMouseFallback) throw error;
|
|
3926
|
+
}
|
|
3817
3927
|
}
|
|
3818
|
-
await
|
|
3928
|
+
await withTimeout(
|
|
3929
|
+
() => page.mouse.click(point.x, point.y),
|
|
3930
|
+
mouseFallbackTimeoutMs,
|
|
3931
|
+
"mouse.click fallback"
|
|
3932
|
+
);
|
|
3933
|
+
return { method: "mouse" };
|
|
3819
3934
|
};
|
|
3820
3935
|
var MobileHumanize = {
|
|
3821
3936
|
jitterMs,
|
|
@@ -3868,6 +3983,10 @@ var MobileHumanize = {
|
|
|
3868
3983
|
return { element, didScroll, restore: null };
|
|
3869
3984
|
}
|
|
3870
3985
|
const scrollRect = await getScrollableRect(element);
|
|
3986
|
+
if (!scrollRect && status.isFixed && status.code === "OUT_OF_VIEWPORT") {
|
|
3987
|
+
logger7.warn(`humanScroll | fixed/sticky \u76EE\u6807\u4E0D\u5728\u89C6\u53E3\u5185\uFF0C\u9875\u9762\u6EDA\u52A8\u65E0\u6CD5\u6539\u53D8\u5176\u4F4D\u7F6E (direction=${status.direction || "unknown"})`);
|
|
3988
|
+
return { element, didScroll, restore: null };
|
|
3989
|
+
}
|
|
3871
3990
|
if (!scrollRect && status.isFixed && status.code === "OBSTRUCTED") {
|
|
3872
3991
|
logger7.warn(`humanScroll | fixed/sticky \u76EE\u6807\u88AB\u906E\u6321\uFF0C\u6EDA\u52A8\u65E0\u6CD5\u89E3\u9664 (${status.obstruction?.tag || "unknown"})`);
|
|
3873
3992
|
return { element, didScroll, restore: null };
|
|
@@ -3988,7 +4107,12 @@ var MobileHumanize = {
|
|
|
3988
4107
|
const {
|
|
3989
4108
|
reactionDelay = 220,
|
|
3990
4109
|
throwOnMissing = true,
|
|
3991
|
-
scrollIfNeeded = true
|
|
4110
|
+
scrollIfNeeded = true,
|
|
4111
|
+
tapTimeoutMs = DEFAULT_TAP_TIMEOUT_MS,
|
|
4112
|
+
mouseFallbackTimeoutMs = DEFAULT_MOUSE_TAP_FALLBACK_TIMEOUT_MS,
|
|
4113
|
+
activateFallbackTimeoutMs = DEFAULT_ACTIVATE_FALLBACK_TIMEOUT_MS,
|
|
4114
|
+
fallbackDomClick = true,
|
|
4115
|
+
fallbackDomClickOnTapError = true
|
|
3992
4116
|
} = options;
|
|
3993
4117
|
const targetDesc = describeTarget(target);
|
|
3994
4118
|
logger7.start("humanClick", `target=${targetDesc}`);
|
|
@@ -3999,6 +4123,9 @@ var MobileHumanize = {
|
|
|
3999
4123
|
await tapPoint(page, {
|
|
4000
4124
|
x: viewport.width * (0.45 + Math.random() * 0.1),
|
|
4001
4125
|
y: viewport.height * (0.48 + Math.random() * 0.12)
|
|
4126
|
+
}, {
|
|
4127
|
+
timeoutMs: tapTimeoutMs,
|
|
4128
|
+
mouseFallbackTimeoutMs
|
|
4002
4129
|
});
|
|
4003
4130
|
logger7.success("humanClick", "Tapped current position");
|
|
4004
4131
|
return true;
|
|
@@ -4013,6 +4140,19 @@ var MobileHumanize = {
|
|
|
4013
4140
|
}
|
|
4014
4141
|
const status = await checkElementVisibility(element).catch(() => null);
|
|
4015
4142
|
if (status && status.code !== "VISIBLE") {
|
|
4143
|
+
if (fallbackDomClick && status.isFixed && status.code === "OUT_OF_VIEWPORT") {
|
|
4144
|
+
const fallback = await withTimeout(
|
|
4145
|
+
() => activateElementFallback(element, null, {
|
|
4146
|
+
editableOnly: true
|
|
4147
|
+
}),
|
|
4148
|
+
activateFallbackTimeoutMs,
|
|
4149
|
+
"focus fallback"
|
|
4150
|
+
).catch(() => null);
|
|
4151
|
+
if (fallback?.activated) {
|
|
4152
|
+
logger7.warn(`humanClick: fixed/sticky \u76EE\u6807\u4E0D\u5728\u89C6\u53E3\u5185\uFF0C\u5DF2\u7528 ${fallback.method} \u6FC0\u6D3B`);
|
|
4153
|
+
return true;
|
|
4154
|
+
}
|
|
4155
|
+
}
|
|
4016
4156
|
const message = `\u5143\u7D20\u4E0D\u53EF\u70B9\u51FB: ${status.reason || status.code}`;
|
|
4017
4157
|
if (throwOnMissing) throw new Error(message);
|
|
4018
4158
|
logger7.warn(`humanClick: ${message}\uFF0C\u8DF3\u8FC7\u70B9\u51FB`);
|
|
@@ -4027,7 +4167,23 @@ var MobileHumanize = {
|
|
|
4027
4167
|
await waitJitter(reactionDelay, 0.45);
|
|
4028
4168
|
const safePoint = await resolveSafeTapPoint(element).catch(() => null);
|
|
4029
4169
|
const tapTarget = safePoint || randomPointInBox(clipBoxToViewport(box, resolveViewport(page)), 0.2);
|
|
4030
|
-
|
|
4170
|
+
try {
|
|
4171
|
+
await tapPoint(page, tapTarget, {
|
|
4172
|
+
timeoutMs: tapTimeoutMs,
|
|
4173
|
+
mouseFallbackTimeoutMs
|
|
4174
|
+
});
|
|
4175
|
+
} catch (tapError) {
|
|
4176
|
+
if (!fallbackDomClickOnTapError) throw tapError;
|
|
4177
|
+
const fallback = await withTimeout(
|
|
4178
|
+
() => activateElementFallback(element, tapTarget, {
|
|
4179
|
+
editableOnly: false
|
|
4180
|
+
}),
|
|
4181
|
+
activateFallbackTimeoutMs,
|
|
4182
|
+
"activation fallback"
|
|
4183
|
+
).catch(() => null);
|
|
4184
|
+
if (!fallback?.activated) throw tapError;
|
|
4185
|
+
logger7.warn(`humanClick: tap \u5931\u8D25\u540E\u5DF2\u7528 ${fallback.method} \u515C\u5E95: ${tapError?.message || tapError}`);
|
|
4186
|
+
}
|
|
4031
4187
|
await waitJitter(120, 0.35);
|
|
4032
4188
|
logger7.success("humanClick");
|
|
4033
4189
|
return true;
|
|
@@ -6845,7 +7001,7 @@ var getHostname = (url) => {
|
|
|
6845
7001
|
return "\u672C\u5730\u9875\u9762";
|
|
6846
7002
|
}
|
|
6847
7003
|
};
|
|
6848
|
-
var
|
|
7004
|
+
var withTimeout2 = async (promise, timeoutMs) => {
|
|
6849
7005
|
const safeTimeoutMs = Math.max(0, Number(timeoutMs) || 0);
|
|
6850
7006
|
if (!safeTimeoutMs) {
|
|
6851
7007
|
return promise;
|
|
@@ -6930,7 +7086,7 @@ var resolveWithCustomResolver = async (page, baseMeta, options = {}) => {
|
|
|
6930
7086
|
const serverAddr = response && typeof response.serverAddr === "function" ? await response.serverAddr().catch(() => null) : null;
|
|
6931
7087
|
const controller = typeof AbortController === "function" ? new AbortController() : null;
|
|
6932
7088
|
try {
|
|
6933
|
-
const resolved = await
|
|
7089
|
+
const resolved = await withTimeout2(
|
|
6934
7090
|
Promise.resolve(resolver({
|
|
6935
7091
|
page,
|
|
6936
7092
|
response,
|
|
@@ -7230,13 +7386,13 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
7230
7386
|
const contentType = normalizeText(await pickHeaderValue(response, ["content-type"]));
|
|
7231
7387
|
let rawText = "";
|
|
7232
7388
|
if (response && typeof response.text === "function") {
|
|
7233
|
-
rawText = String(await
|
|
7389
|
+
rawText = String(await withTimeout2(
|
|
7234
7390
|
response.text().catch(() => ""),
|
|
7235
7391
|
timeoutMs
|
|
7236
7392
|
) || "");
|
|
7237
7393
|
}
|
|
7238
7394
|
if (!rawText) {
|
|
7239
|
-
rawText = String(await
|
|
7395
|
+
rawText = String(await withTimeout2(
|
|
7240
7396
|
probePage.evaluate(() => {
|
|
7241
7397
|
return document.body?.innerText || document.documentElement?.innerText || "";
|
|
7242
7398
|
}).catch(() => ""),
|