@skrillex1224/playwright-toolkit 2.1.240 → 2.1.242
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.cjs
CHANGED
|
@@ -167,8 +167,9 @@ var ActorInfo = {
|
|
|
167
167
|
qbot: createActorInfo({
|
|
168
168
|
key: "qbot",
|
|
169
169
|
name: "QQ\u6D4F\u89C8\u5668AI\u641C",
|
|
170
|
-
domain: "sogou.com",
|
|
170
|
+
domain: "m.sogou.com",
|
|
171
171
|
path: "/web",
|
|
172
|
+
device: Device.Mobile,
|
|
172
173
|
share: {
|
|
173
174
|
mode: "dom",
|
|
174
175
|
prefix: "",
|
|
@@ -749,14 +750,16 @@ var expandScrollableContent = async (page, options = {}) => {
|
|
|
749
750
|
expandDocumentElements: options.expandDocumentElements === true
|
|
750
751
|
});
|
|
751
752
|
};
|
|
752
|
-
var
|
|
753
|
+
var adjustAffixedElementsForExpandedScreenshot = async (page, options = {}) => {
|
|
753
754
|
return await page.evaluate(({ className, targetHeight }) => {
|
|
755
|
+
const viewportWidth = window.innerWidth || document.documentElement?.clientWidth || document.body?.clientWidth || 0;
|
|
754
756
|
const viewportHeight = window.innerHeight || document.documentElement?.clientHeight || document.body?.clientHeight || 0;
|
|
757
|
+
const scrollY = window.scrollY || window.pageYOffset || 0;
|
|
755
758
|
const safeTargetHeight = Math.ceil(Number(targetHeight) || 0);
|
|
756
|
-
|
|
757
|
-
if (deltaY <= 1) {
|
|
759
|
+
if (safeTargetHeight <= viewportHeight + 1) {
|
|
758
760
|
return 0;
|
|
759
761
|
}
|
|
762
|
+
const hasOwn = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
|
|
760
763
|
const isVisible = (el, style, rect) => {
|
|
761
764
|
if (!el || !style || !rect) return false;
|
|
762
765
|
if (style.display === "none" || style.visibility === "hidden" || style.visibility === "collapse") {
|
|
@@ -765,7 +768,7 @@ var pinBottomAffixedElements = async (page, options = {}) => {
|
|
|
765
768
|
if (Number(style.opacity) === 0) return false;
|
|
766
769
|
return rect.width > 0 && rect.height > 0;
|
|
767
770
|
};
|
|
768
|
-
const
|
|
771
|
+
const edgeThreshold = Math.max(24, Math.min(96, viewportHeight * 0.12));
|
|
769
772
|
const maxAffixedHeight = Math.max(56, viewportHeight * 0.65);
|
|
770
773
|
const candidates = [];
|
|
771
774
|
document.querySelectorAll("*").forEach((el) => {
|
|
@@ -775,28 +778,49 @@ var pinBottomAffixedElements = async (page, options = {}) => {
|
|
|
775
778
|
const rect = el.getBoundingClientRect();
|
|
776
779
|
if (!isVisible(el, style, rect)) return;
|
|
777
780
|
if (rect.height > maxAffixedHeight) return;
|
|
778
|
-
if (rect.
|
|
781
|
+
if (rect.width < viewportWidth * 0.25 && rect.height < 80) return;
|
|
782
|
+
const top = Number.parseFloat(style.top);
|
|
779
783
|
const bottom = Number.parseFloat(style.bottom);
|
|
784
|
+
const hasTopRule = Number.isFinite(top) && top <= Math.max(160, viewportHeight * 0.25);
|
|
780
785
|
const hasBottomRule = Number.isFinite(bottom) && bottom <= Math.max(160, viewportHeight * 0.25);
|
|
781
|
-
const
|
|
782
|
-
|
|
783
|
-
|
|
786
|
+
const isNearViewportTop = rect.top <= edgeThreshold;
|
|
787
|
+
const isNearViewportBottom = rect.bottom >= viewportHeight - edgeThreshold;
|
|
788
|
+
const edge = (hasBottomRule || isNearViewportBottom) && !(hasTopRule || isNearViewportTop) ? "bottom" : "top";
|
|
789
|
+
if (position === "fixed" && edge === "top" && !hasTopRule && !isNearViewportTop) return;
|
|
790
|
+
if (position === "fixed" && edge === "bottom" && !hasBottomRule && !isNearViewportBottom) return;
|
|
791
|
+
if (position === "sticky" && !hasTopRule && !hasBottomRule && !isNearViewportTop && !isNearViewportBottom) return;
|
|
792
|
+
candidates.push({ el, position, edge });
|
|
784
793
|
});
|
|
785
|
-
const candidateSet = new Set(candidates);
|
|
786
|
-
const topLevelCandidates = candidates.filter((el) => {
|
|
794
|
+
const candidateSet = new Set(candidates.map(({ el }) => el));
|
|
795
|
+
const topLevelCandidates = candidates.filter(({ el }) => {
|
|
787
796
|
for (let parent = el.parentElement; parent; parent = parent.parentElement) {
|
|
788
797
|
if (candidateSet.has(parent)) return false;
|
|
789
798
|
}
|
|
790
799
|
return true;
|
|
791
800
|
});
|
|
792
|
-
topLevelCandidates.forEach((el) => {
|
|
793
|
-
if (!
|
|
794
|
-
el.dataset.
|
|
801
|
+
topLevelCandidates.forEach(({ el, position, edge }) => {
|
|
802
|
+
if (!hasOwn(el.dataset, "pkAffixedAdjusted")) {
|
|
803
|
+
el.dataset.pkAffixedAdjusted = "1";
|
|
804
|
+
el.dataset.pkOrigPosition = el.style.getPropertyValue("position") || "";
|
|
805
|
+
el.dataset.pkOrigPositionPriority = el.style.getPropertyPriority("position") || "";
|
|
806
|
+
el.dataset.pkOrigTop = el.style.getPropertyValue("top") || "";
|
|
807
|
+
el.dataset.pkOrigTopPriority = el.style.getPropertyPriority("top") || "";
|
|
808
|
+
el.dataset.pkOrigBottom = el.style.getPropertyValue("bottom") || "";
|
|
809
|
+
el.dataset.pkOrigBottomPriority = el.style.getPropertyPriority("bottom") || "";
|
|
795
810
|
el.dataset.pkOrigTranslate = el.style.getPropertyValue("translate") || "";
|
|
796
811
|
el.dataset.pkOrigTranslatePriority = el.style.getPropertyPriority("translate") || "";
|
|
797
812
|
}
|
|
798
813
|
el.classList.add(className);
|
|
799
|
-
|
|
814
|
+
if (position === "fixed") {
|
|
815
|
+
const deltaY = edge === "bottom" ? safeTargetHeight - viewportHeight - scrollY : -scrollY;
|
|
816
|
+
if (Math.abs(deltaY) > 1) {
|
|
817
|
+
el.style.setProperty("translate", `0 ${Math.round(deltaY)}px`, "important");
|
|
818
|
+
}
|
|
819
|
+
return;
|
|
820
|
+
}
|
|
821
|
+
el.style.setProperty("position", "relative", "important");
|
|
822
|
+
el.style.setProperty("top", "auto", "important");
|
|
823
|
+
el.style.setProperty("bottom", "auto", "important");
|
|
800
824
|
});
|
|
801
825
|
return topLevelCandidates.length;
|
|
802
826
|
}, {
|
|
@@ -804,7 +828,7 @@ var pinBottomAffixedElements = async (page, options = {}) => {
|
|
|
804
828
|
targetHeight: options.targetHeight
|
|
805
829
|
});
|
|
806
830
|
};
|
|
807
|
-
var
|
|
831
|
+
var restoreAffixedElementsForExpandedScreenshot = async (page) => {
|
|
808
832
|
await page.evaluate((className) => {
|
|
809
833
|
const hasOwn = (source, key) => Object.prototype.hasOwnProperty.call(source, key);
|
|
810
834
|
const expansionKeys = [
|
|
@@ -813,13 +837,28 @@ var restoreBottomAffixedElements = async (page) => {
|
|
|
813
837
|
"pkOrigMinHeight",
|
|
814
838
|
"pkOrigMaxHeight"
|
|
815
839
|
];
|
|
816
|
-
document.querySelectorAll('[data-pk-
|
|
840
|
+
document.querySelectorAll('[data-pk-affixed-adjusted="1"]').forEach((el) => {
|
|
841
|
+
if (hasOwn(el.dataset, "pkOrigPosition")) {
|
|
842
|
+
el.style.setProperty("position", el.dataset.pkOrigPosition || "", el.dataset.pkOrigPositionPriority || "");
|
|
843
|
+
delete el.dataset.pkOrigPosition;
|
|
844
|
+
delete el.dataset.pkOrigPositionPriority;
|
|
845
|
+
}
|
|
846
|
+
if (hasOwn(el.dataset, "pkOrigTop")) {
|
|
847
|
+
el.style.setProperty("top", el.dataset.pkOrigTop || "", el.dataset.pkOrigTopPriority || "");
|
|
848
|
+
delete el.dataset.pkOrigTop;
|
|
849
|
+
delete el.dataset.pkOrigTopPriority;
|
|
850
|
+
}
|
|
851
|
+
if (hasOwn(el.dataset, "pkOrigBottom")) {
|
|
852
|
+
el.style.setProperty("bottom", el.dataset.pkOrigBottom || "", el.dataset.pkOrigBottomPriority || "");
|
|
853
|
+
delete el.dataset.pkOrigBottom;
|
|
854
|
+
delete el.dataset.pkOrigBottomPriority;
|
|
855
|
+
}
|
|
817
856
|
if (hasOwn(el.dataset, "pkOrigTranslate")) {
|
|
818
857
|
el.style.setProperty("translate", el.dataset.pkOrigTranslate || "", el.dataset.pkOrigTranslatePriority || "");
|
|
819
858
|
delete el.dataset.pkOrigTranslate;
|
|
820
859
|
delete el.dataset.pkOrigTranslatePriority;
|
|
821
860
|
}
|
|
822
|
-
delete el.dataset.
|
|
861
|
+
delete el.dataset.pkAffixedAdjusted;
|
|
823
862
|
const stillExpanded = expansionKeys.some((key) => hasOwn(el.dataset, key));
|
|
824
863
|
if (!stillExpanded) {
|
|
825
864
|
el.classList.remove(className);
|
|
@@ -848,8 +887,8 @@ var prepareExpandedFullPageScreenshot = async (page, options = {}) => {
|
|
|
848
887
|
});
|
|
849
888
|
viewportResized = true;
|
|
850
889
|
} else {
|
|
851
|
-
await
|
|
852
|
-
logger.warning(`\u79FB\u52A8\u7AEF\u5438\
|
|
890
|
+
await adjustAffixedElementsForExpandedScreenshot(page, { targetHeight }).catch((error) => {
|
|
891
|
+
logger.warning(`\u79FB\u52A8\u7AEF\u5438\u9644\u5143\u7D20\u91CD\u5B9A\u4F4D\u5931\u8D25: ${error?.message || error}`);
|
|
853
892
|
});
|
|
854
893
|
}
|
|
855
894
|
if (settleMs > 0) {
|
|
@@ -955,8 +994,8 @@ var captureExpandedFullPageScreenshot = async (page, options = {}) => {
|
|
|
955
994
|
maxClipHeight: state.targetHeight
|
|
956
995
|
});
|
|
957
996
|
} finally {
|
|
958
|
-
await
|
|
959
|
-
logger.warning(`\u79FB\u52A8\u7AEF\u5438\
|
|
997
|
+
await restoreAffixedElementsForExpandedScreenshot(page).catch((error) => {
|
|
998
|
+
logger.warning(`\u79FB\u52A8\u7AEF\u5438\u9644\u5143\u7D20\u6062\u590D\u5931\u8D25: ${error?.message || error}`);
|
|
960
999
|
});
|
|
961
1000
|
if (options.restore) {
|
|
962
1001
|
await restoreExpandedFullPageScreenshot(page, state);
|
|
@@ -3397,6 +3436,26 @@ var waitJitter = (base, jitterPercent = 0.3) => (0, import_delay3.default)(jitte
|
|
|
3397
3436
|
// src/internals/humanize/mobile.js
|
|
3398
3437
|
var logger7 = createInternalLogger("Humanize.Mobile");
|
|
3399
3438
|
var initializedPages = /* @__PURE__ */ new WeakSet();
|
|
3439
|
+
var DEFAULT_TAP_TIMEOUT_MS = 2500;
|
|
3440
|
+
var DEFAULT_MOUSE_TAP_FALLBACK_TIMEOUT_MS = 1200;
|
|
3441
|
+
var DEFAULT_ACTIVATE_FALLBACK_TIMEOUT_MS = 900;
|
|
3442
|
+
var INTERACTIVE_SELECTOR = [
|
|
3443
|
+
"button",
|
|
3444
|
+
'[role="button"]',
|
|
3445
|
+
"a[href]",
|
|
3446
|
+
"label",
|
|
3447
|
+
"input",
|
|
3448
|
+
"textarea",
|
|
3449
|
+
"select",
|
|
3450
|
+
"summary",
|
|
3451
|
+
'[contenteditable="true"]',
|
|
3452
|
+
'[tabindex]:not([tabindex="-1"])'
|
|
3453
|
+
].join(",");
|
|
3454
|
+
var EDITABLE_SELECTOR = [
|
|
3455
|
+
"input",
|
|
3456
|
+
"textarea",
|
|
3457
|
+
'[contenteditable="true"]'
|
|
3458
|
+
].join(",");
|
|
3400
3459
|
var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
3401
3460
|
var resolveViewport = (page) => page?.viewportSize?.() || { width: 390, height: 844 };
|
|
3402
3461
|
var describeTarget = (target) => {
|
|
@@ -3419,8 +3478,24 @@ var clipBoxToViewport = (box, viewport) => {
|
|
|
3419
3478
|
}
|
|
3420
3479
|
return box;
|
|
3421
3480
|
};
|
|
3481
|
+
var withTimeout = async (operation, timeoutMs, label) => {
|
|
3482
|
+
const safeTimeoutMs = Math.max(50, Number(timeoutMs || 0));
|
|
3483
|
+
let timeoutId = null;
|
|
3484
|
+
try {
|
|
3485
|
+
return await Promise.race([
|
|
3486
|
+
Promise.resolve().then(operation),
|
|
3487
|
+
new Promise((_, reject) => {
|
|
3488
|
+
timeoutId = setTimeout(() => {
|
|
3489
|
+
reject(new Error(`${label} timeout after ${safeTimeoutMs}ms`));
|
|
3490
|
+
}, safeTimeoutMs);
|
|
3491
|
+
})
|
|
3492
|
+
]);
|
|
3493
|
+
} finally {
|
|
3494
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
3495
|
+
}
|
|
3496
|
+
};
|
|
3422
3497
|
var checkElementVisibility = async (element) => {
|
|
3423
|
-
return element.evaluate((el) => {
|
|
3498
|
+
return element.evaluate((el, interactiveSelector) => {
|
|
3424
3499
|
const targetStyle = window.getComputedStyle(el);
|
|
3425
3500
|
if (!targetStyle || targetStyle.display === "none" || targetStyle.visibility === "hidden" || targetStyle.visibility === "collapse") {
|
|
3426
3501
|
return { code: "NOT_INTERACTABLE", reason: "\u5143\u7D20\u4E0D\u53EF\u89C1", direction: "down" };
|
|
@@ -3437,10 +3512,12 @@ var checkElementVisibility = async (element) => {
|
|
|
3437
3512
|
let clipTop = 0;
|
|
3438
3513
|
let clipBottom = viewH;
|
|
3439
3514
|
let isFixed = false;
|
|
3515
|
+
let positioning = null;
|
|
3440
3516
|
for (let node = el; node && node !== document.body; node = node.parentElement) {
|
|
3441
3517
|
const style = window.getComputedStyle(node);
|
|
3442
3518
|
if (style && (style.position === "fixed" || style.position === "sticky")) {
|
|
3443
3519
|
isFixed = true;
|
|
3520
|
+
positioning = style.position;
|
|
3444
3521
|
break;
|
|
3445
3522
|
}
|
|
3446
3523
|
}
|
|
@@ -3476,21 +3553,10 @@ var checkElementVisibility = async (element) => {
|
|
|
3476
3553
|
direction: centerY < clipTop ? "up" : "down",
|
|
3477
3554
|
cy: centerY,
|
|
3478
3555
|
viewH,
|
|
3479
|
-
isFixed
|
|
3556
|
+
isFixed,
|
|
3557
|
+
positioning
|
|
3480
3558
|
};
|
|
3481
3559
|
}
|
|
3482
|
-
const interactiveSelector = [
|
|
3483
|
-
"button",
|
|
3484
|
-
'[role="button"]',
|
|
3485
|
-
"a[href]",
|
|
3486
|
-
"label",
|
|
3487
|
-
"input",
|
|
3488
|
-
"textarea",
|
|
3489
|
-
"select",
|
|
3490
|
-
"summary",
|
|
3491
|
-
'[contenteditable="true"]',
|
|
3492
|
-
'[tabindex]:not([tabindex="-1"])'
|
|
3493
|
-
].join(",");
|
|
3494
3560
|
const targetInteractive = typeof el.closest === "function" ? el.closest(interactiveSelector) : null;
|
|
3495
3561
|
const sameInteractiveTarget = (pointElement) => {
|
|
3496
3562
|
if (!pointElement) return false;
|
|
@@ -3512,6 +3578,7 @@ var checkElementVisibility = async (element) => {
|
|
|
3512
3578
|
id: node.id || "",
|
|
3513
3579
|
className,
|
|
3514
3580
|
isFixed: Boolean(style && (style.position === "fixed" || style.position === "sticky")),
|
|
3581
|
+
positioning: style?.position || "",
|
|
3515
3582
|
top: rect2 ? rect2.top : null,
|
|
3516
3583
|
bottom: rect2 ? rect2.bottom : null,
|
|
3517
3584
|
left: rect2 ? rect2.left : null,
|
|
@@ -3529,7 +3596,7 @@ var checkElementVisibility = async (element) => {
|
|
|
3529
3596
|
for (const point of samplePoints) {
|
|
3530
3597
|
const pointElement = document.elementFromPoint(point.x, point.y);
|
|
3531
3598
|
if (sameInteractiveTarget(pointElement)) {
|
|
3532
|
-
return { code: "VISIBLE", isFixed };
|
|
3599
|
+
return { code: "VISIBLE", isFixed, positioning };
|
|
3533
3600
|
}
|
|
3534
3601
|
obstruction = obstruction || describeElement(pointElement);
|
|
3535
3602
|
}
|
|
@@ -3541,14 +3608,15 @@ var checkElementVisibility = async (element) => {
|
|
|
3541
3608
|
obstruction,
|
|
3542
3609
|
cy,
|
|
3543
3610
|
viewH,
|
|
3544
|
-
isFixed
|
|
3611
|
+
isFixed,
|
|
3612
|
+
positioning
|
|
3545
3613
|
};
|
|
3546
3614
|
}
|
|
3547
|
-
return { code: "VISIBLE", isFixed };
|
|
3548
|
-
});
|
|
3615
|
+
return { code: "VISIBLE", isFixed, positioning };
|
|
3616
|
+
}, INTERACTIVE_SELECTOR);
|
|
3549
3617
|
};
|
|
3550
3618
|
var resolveSafeTapPoint = async (element) => {
|
|
3551
|
-
return element.evaluate((el) => {
|
|
3619
|
+
return element.evaluate((el, interactiveSelector) => {
|
|
3552
3620
|
const rect = el.getBoundingClientRect();
|
|
3553
3621
|
if (!rect || rect.width <= 0 || rect.height <= 0) {
|
|
3554
3622
|
return null;
|
|
@@ -3585,18 +3653,6 @@ var resolveSafeTapPoint = async (element) => {
|
|
|
3585
3653
|
if (visibleWidth <= 1 || visibleHeight <= 1) {
|
|
3586
3654
|
return null;
|
|
3587
3655
|
}
|
|
3588
|
-
const interactiveSelector = [
|
|
3589
|
-
"button",
|
|
3590
|
-
'[role="button"]',
|
|
3591
|
-
"a[href]",
|
|
3592
|
-
"label",
|
|
3593
|
-
"input",
|
|
3594
|
-
"textarea",
|
|
3595
|
-
"select",
|
|
3596
|
-
"summary",
|
|
3597
|
-
'[contenteditable="true"]',
|
|
3598
|
-
'[tabindex]:not([tabindex="-1"])'
|
|
3599
|
-
].join(",");
|
|
3600
3656
|
const targetInteractive = typeof el.closest === "function" ? el.closest(interactiveSelector) : null;
|
|
3601
3657
|
const sameInteractiveTarget = (pointElement) => {
|
|
3602
3658
|
if (!pointElement) return false;
|
|
@@ -3634,6 +3690,46 @@ var resolveSafeTapPoint = async (element) => {
|
|
|
3634
3690
|
x: chosen.x,
|
|
3635
3691
|
y: chosen.y
|
|
3636
3692
|
};
|
|
3693
|
+
}, INTERACTIVE_SELECTOR);
|
|
3694
|
+
};
|
|
3695
|
+
var activateElementFallback = async (element, point = null, options = {}) => {
|
|
3696
|
+
return element.evaluate((el, { innerPoint, innerOptions, interactiveSelector, editableSelector }) => {
|
|
3697
|
+
const pointElement = innerPoint ? document.elementFromPoint(innerPoint.x, innerPoint.y) : null;
|
|
3698
|
+
const nearestInteractive = (node) => {
|
|
3699
|
+
if (!node || typeof node.closest !== "function") return null;
|
|
3700
|
+
return node.closest(interactiveSelector);
|
|
3701
|
+
};
|
|
3702
|
+
const targetInteractive = nearestInteractive(el);
|
|
3703
|
+
const pointInteractive = nearestInteractive(pointElement);
|
|
3704
|
+
let target = null;
|
|
3705
|
+
if (pointInteractive && (pointInteractive === targetInteractive || pointInteractive === el || pointInteractive.contains(el) || el.contains(pointInteractive))) {
|
|
3706
|
+
target = pointInteractive;
|
|
3707
|
+
}
|
|
3708
|
+
target = target || targetInteractive || el;
|
|
3709
|
+
const editable = typeof target.closest === "function" ? target.closest(editableSelector) : null;
|
|
3710
|
+
if (editable && typeof editable.focus === "function") {
|
|
3711
|
+
editable.focus({ preventScroll: true });
|
|
3712
|
+
if (innerOptions.editableOnly) {
|
|
3713
|
+
return { activated: true, method: "focus", tag: editable.tagName || "" };
|
|
3714
|
+
}
|
|
3715
|
+
}
|
|
3716
|
+
if (typeof target.focus === "function") {
|
|
3717
|
+
target.focus({ preventScroll: true });
|
|
3718
|
+
}
|
|
3719
|
+
if (!innerOptions.editableOnly && typeof target.click === "function") {
|
|
3720
|
+
target.click();
|
|
3721
|
+
return { activated: true, method: "dom-click", tag: target.tagName || "" };
|
|
3722
|
+
}
|
|
3723
|
+
return {
|
|
3724
|
+
activated: Boolean(editable),
|
|
3725
|
+
method: editable ? "focus" : "none",
|
|
3726
|
+
tag: target?.tagName || ""
|
|
3727
|
+
};
|
|
3728
|
+
}, {
|
|
3729
|
+
innerPoint: point,
|
|
3730
|
+
innerOptions: options || {},
|
|
3731
|
+
interactiveSelector: INTERACTIVE_SELECTOR,
|
|
3732
|
+
editableSelector: EDITABLE_SELECTOR
|
|
3637
3733
|
});
|
|
3638
3734
|
};
|
|
3639
3735
|
var getScrollableRect = async (element) => {
|
|
@@ -3838,12 +3934,31 @@ var dispatchTouchSwipe = async (page, deltaY, options = {}) => {
|
|
|
3838
3934
|
}
|
|
3839
3935
|
}
|
|
3840
3936
|
};
|
|
3841
|
-
var tapPoint = async (page, point) => {
|
|
3937
|
+
var tapPoint = async (page, point, options = {}) => {
|
|
3938
|
+
const {
|
|
3939
|
+
timeoutMs = DEFAULT_TAP_TIMEOUT_MS,
|
|
3940
|
+
mouseFallbackTimeoutMs = DEFAULT_MOUSE_TAP_FALLBACK_TIMEOUT_MS,
|
|
3941
|
+
allowMouseFallback = true
|
|
3942
|
+
} = options;
|
|
3842
3943
|
if (page.touchscreen && typeof page.touchscreen.tap === "function") {
|
|
3843
|
-
|
|
3844
|
-
|
|
3944
|
+
try {
|
|
3945
|
+
await withTimeout(
|
|
3946
|
+
() => page.touchscreen.tap(point.x, point.y),
|
|
3947
|
+
timeoutMs,
|
|
3948
|
+
"touchscreen.tap"
|
|
3949
|
+
);
|
|
3950
|
+
return { method: "touchscreen" };
|
|
3951
|
+
} catch (error) {
|
|
3952
|
+
logger7.warn(`tapPoint | touchscreen.tap \u5931\u8D25\u6216\u8D85\u65F6\uFF0C\u5C1D\u8BD5\u9F20\u6807\u515C\u5E95: ${error?.message || error}`);
|
|
3953
|
+
if (!allowMouseFallback) throw error;
|
|
3954
|
+
}
|
|
3845
3955
|
}
|
|
3846
|
-
await
|
|
3956
|
+
await withTimeout(
|
|
3957
|
+
() => page.mouse.click(point.x, point.y),
|
|
3958
|
+
mouseFallbackTimeoutMs,
|
|
3959
|
+
"mouse.click fallback"
|
|
3960
|
+
);
|
|
3961
|
+
return { method: "mouse" };
|
|
3847
3962
|
};
|
|
3848
3963
|
var MobileHumanize = {
|
|
3849
3964
|
jitterMs,
|
|
@@ -3896,6 +4011,10 @@ var MobileHumanize = {
|
|
|
3896
4011
|
return { element, didScroll, restore: null };
|
|
3897
4012
|
}
|
|
3898
4013
|
const scrollRect = await getScrollableRect(element);
|
|
4014
|
+
if (!scrollRect && status.isFixed && status.code === "OUT_OF_VIEWPORT") {
|
|
4015
|
+
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"})`);
|
|
4016
|
+
return { element, didScroll, restore: null };
|
|
4017
|
+
}
|
|
3899
4018
|
if (!scrollRect && status.isFixed && status.code === "OBSTRUCTED") {
|
|
3900
4019
|
logger7.warn(`humanScroll | fixed/sticky \u76EE\u6807\u88AB\u906E\u6321\uFF0C\u6EDA\u52A8\u65E0\u6CD5\u89E3\u9664 (${status.obstruction?.tag || "unknown"})`);
|
|
3901
4020
|
return { element, didScroll, restore: null };
|
|
@@ -4016,7 +4135,12 @@ var MobileHumanize = {
|
|
|
4016
4135
|
const {
|
|
4017
4136
|
reactionDelay = 220,
|
|
4018
4137
|
throwOnMissing = true,
|
|
4019
|
-
scrollIfNeeded = true
|
|
4138
|
+
scrollIfNeeded = true,
|
|
4139
|
+
tapTimeoutMs = DEFAULT_TAP_TIMEOUT_MS,
|
|
4140
|
+
mouseFallbackTimeoutMs = DEFAULT_MOUSE_TAP_FALLBACK_TIMEOUT_MS,
|
|
4141
|
+
activateFallbackTimeoutMs = DEFAULT_ACTIVATE_FALLBACK_TIMEOUT_MS,
|
|
4142
|
+
fallbackDomClick = true,
|
|
4143
|
+
fallbackDomClickOnTapError = true
|
|
4020
4144
|
} = options;
|
|
4021
4145
|
const targetDesc = describeTarget(target);
|
|
4022
4146
|
logger7.start("humanClick", `target=${targetDesc}`);
|
|
@@ -4027,6 +4151,9 @@ var MobileHumanize = {
|
|
|
4027
4151
|
await tapPoint(page, {
|
|
4028
4152
|
x: viewport.width * (0.45 + Math.random() * 0.1),
|
|
4029
4153
|
y: viewport.height * (0.48 + Math.random() * 0.12)
|
|
4154
|
+
}, {
|
|
4155
|
+
timeoutMs: tapTimeoutMs,
|
|
4156
|
+
mouseFallbackTimeoutMs
|
|
4030
4157
|
});
|
|
4031
4158
|
logger7.success("humanClick", "Tapped current position");
|
|
4032
4159
|
return true;
|
|
@@ -4041,6 +4168,19 @@ var MobileHumanize = {
|
|
|
4041
4168
|
}
|
|
4042
4169
|
const status = await checkElementVisibility(element).catch(() => null);
|
|
4043
4170
|
if (status && status.code !== "VISIBLE") {
|
|
4171
|
+
if (fallbackDomClick && status.isFixed && status.code === "OUT_OF_VIEWPORT") {
|
|
4172
|
+
const fallback = await withTimeout(
|
|
4173
|
+
() => activateElementFallback(element, null, {
|
|
4174
|
+
editableOnly: true
|
|
4175
|
+
}),
|
|
4176
|
+
activateFallbackTimeoutMs,
|
|
4177
|
+
"focus fallback"
|
|
4178
|
+
).catch(() => null);
|
|
4179
|
+
if (fallback?.activated) {
|
|
4180
|
+
logger7.warn(`humanClick: fixed/sticky \u76EE\u6807\u4E0D\u5728\u89C6\u53E3\u5185\uFF0C\u5DF2\u7528 ${fallback.method} \u6FC0\u6D3B`);
|
|
4181
|
+
return true;
|
|
4182
|
+
}
|
|
4183
|
+
}
|
|
4044
4184
|
const message = `\u5143\u7D20\u4E0D\u53EF\u70B9\u51FB: ${status.reason || status.code}`;
|
|
4045
4185
|
if (throwOnMissing) throw new Error(message);
|
|
4046
4186
|
logger7.warn(`humanClick: ${message}\uFF0C\u8DF3\u8FC7\u70B9\u51FB`);
|
|
@@ -4055,7 +4195,23 @@ var MobileHumanize = {
|
|
|
4055
4195
|
await waitJitter(reactionDelay, 0.45);
|
|
4056
4196
|
const safePoint = await resolveSafeTapPoint(element).catch(() => null);
|
|
4057
4197
|
const tapTarget = safePoint || randomPointInBox(clipBoxToViewport(box, resolveViewport(page)), 0.2);
|
|
4058
|
-
|
|
4198
|
+
try {
|
|
4199
|
+
await tapPoint(page, tapTarget, {
|
|
4200
|
+
timeoutMs: tapTimeoutMs,
|
|
4201
|
+
mouseFallbackTimeoutMs
|
|
4202
|
+
});
|
|
4203
|
+
} catch (tapError) {
|
|
4204
|
+
if (!fallbackDomClickOnTapError) throw tapError;
|
|
4205
|
+
const fallback = await withTimeout(
|
|
4206
|
+
() => activateElementFallback(element, tapTarget, {
|
|
4207
|
+
editableOnly: false
|
|
4208
|
+
}),
|
|
4209
|
+
activateFallbackTimeoutMs,
|
|
4210
|
+
"activation fallback"
|
|
4211
|
+
).catch(() => null);
|
|
4212
|
+
if (!fallback?.activated) throw tapError;
|
|
4213
|
+
logger7.warn(`humanClick: tap \u5931\u8D25\u540E\u5DF2\u7528 ${fallback.method} \u515C\u5E95: ${tapError?.message || tapError}`);
|
|
4214
|
+
}
|
|
4059
4215
|
await waitJitter(120, 0.35);
|
|
4060
4216
|
logger7.success("humanClick");
|
|
4061
4217
|
return true;
|
|
@@ -6873,7 +7029,7 @@ var getHostname = (url) => {
|
|
|
6873
7029
|
return "\u672C\u5730\u9875\u9762";
|
|
6874
7030
|
}
|
|
6875
7031
|
};
|
|
6876
|
-
var
|
|
7032
|
+
var withTimeout2 = async (promise, timeoutMs) => {
|
|
6877
7033
|
const safeTimeoutMs = Math.max(0, Number(timeoutMs) || 0);
|
|
6878
7034
|
if (!safeTimeoutMs) {
|
|
6879
7035
|
return promise;
|
|
@@ -6958,7 +7114,7 @@ var resolveWithCustomResolver = async (page, baseMeta, options = {}) => {
|
|
|
6958
7114
|
const serverAddr = response && typeof response.serverAddr === "function" ? await response.serverAddr().catch(() => null) : null;
|
|
6959
7115
|
const controller = typeof AbortController === "function" ? new AbortController() : null;
|
|
6960
7116
|
try {
|
|
6961
|
-
const resolved = await
|
|
7117
|
+
const resolved = await withTimeout2(
|
|
6962
7118
|
Promise.resolve(resolver({
|
|
6963
7119
|
page,
|
|
6964
7120
|
response,
|
|
@@ -7258,13 +7414,13 @@ var resolveWithIpLookup = async (page, options = {}) => {
|
|
|
7258
7414
|
const contentType = normalizeText(await pickHeaderValue(response, ["content-type"]));
|
|
7259
7415
|
let rawText = "";
|
|
7260
7416
|
if (response && typeof response.text === "function") {
|
|
7261
|
-
rawText = String(await
|
|
7417
|
+
rawText = String(await withTimeout2(
|
|
7262
7418
|
response.text().catch(() => ""),
|
|
7263
7419
|
timeoutMs
|
|
7264
7420
|
) || "");
|
|
7265
7421
|
}
|
|
7266
7422
|
if (!rawText) {
|
|
7267
|
-
rawText = String(await
|
|
7423
|
+
rawText = String(await withTimeout2(
|
|
7268
7424
|
probePage.evaluate(() => {
|
|
7269
7425
|
return document.body?.innerText || document.documentElement?.innerText || "";
|
|
7270
7426
|
}).catch(() => ""),
|