@skrillex1224/playwright-toolkit 2.1.246 → 2.1.248
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 +170 -62
- package/dist/index.cjs.map +2 -2
- package/dist/index.js +170 -62
- package/dist/index.js.map +2 -2
- package/index.d.ts +0 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3432,23 +3432,6 @@ var initializedPages = /* @__PURE__ */ new WeakSet();
|
|
|
3432
3432
|
var DEFAULT_TAP_TIMEOUT_MS = 2500;
|
|
3433
3433
|
var DEFAULT_MOUSE_TAP_FALLBACK_TIMEOUT_MS = 1200;
|
|
3434
3434
|
var DEFAULT_ACTIVATE_FALLBACK_TIMEOUT_MS = 900;
|
|
3435
|
-
var INTERACTIVE_SELECTOR = [
|
|
3436
|
-
"button",
|
|
3437
|
-
'[role="button"]',
|
|
3438
|
-
"a[href]",
|
|
3439
|
-
"label",
|
|
3440
|
-
"input",
|
|
3441
|
-
"textarea",
|
|
3442
|
-
"select",
|
|
3443
|
-
"summary",
|
|
3444
|
-
'[contenteditable="true"]',
|
|
3445
|
-
'[tabindex]:not([tabindex="-1"])'
|
|
3446
|
-
].join(",");
|
|
3447
|
-
var EDITABLE_SELECTOR = [
|
|
3448
|
-
"input",
|
|
3449
|
-
"textarea",
|
|
3450
|
-
'[contenteditable="true"]'
|
|
3451
|
-
].join(",");
|
|
3452
3435
|
var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
3453
3436
|
var resolveViewport = (page) => page?.viewportSize?.() || { width: 390, height: 844 };
|
|
3454
3437
|
var describeTarget = (target) => {
|
|
@@ -3488,7 +3471,7 @@ var withTimeout = async (operation, timeoutMs, label) => {
|
|
|
3488
3471
|
}
|
|
3489
3472
|
};
|
|
3490
3473
|
var checkElementVisibility = async (element) => {
|
|
3491
|
-
return element.evaluate((el
|
|
3474
|
+
return element.evaluate((el) => {
|
|
3492
3475
|
const targetStyle = window.getComputedStyle(el);
|
|
3493
3476
|
if (!targetStyle || targetStyle.display === "none" || targetStyle.visibility === "hidden" || targetStyle.visibility === "collapse") {
|
|
3494
3477
|
return { code: "NOT_INTERACTABLE", reason: "\u5143\u7D20\u4E0D\u53EF\u89C1", direction: "down" };
|
|
@@ -3550,16 +3533,30 @@ var checkElementVisibility = async (element) => {
|
|
|
3550
3533
|
positioning
|
|
3551
3534
|
};
|
|
3552
3535
|
}
|
|
3553
|
-
const
|
|
3554
|
-
const
|
|
3536
|
+
const isRootNode = (node) => !node || node === document || node === document.body || node === document.documentElement;
|
|
3537
|
+
const commonAncestor = (a, b) => {
|
|
3538
|
+
for (let current = a; current && !isRootNode(current); current = current.parentElement) {
|
|
3539
|
+
if (current.contains(b)) return current;
|
|
3540
|
+
}
|
|
3541
|
+
return null;
|
|
3542
|
+
};
|
|
3543
|
+
const sameTapTarget = (pointElement) => {
|
|
3555
3544
|
if (!pointElement) return false;
|
|
3556
3545
|
if (pointElement === el || el.contains(pointElement) || pointElement.contains(el)) {
|
|
3557
3546
|
return true;
|
|
3558
3547
|
}
|
|
3559
|
-
|
|
3548
|
+
const common = commonAncestor(el, pointElement);
|
|
3549
|
+
if (!common) return false;
|
|
3550
|
+
const commonRect = common.getBoundingClientRect?.();
|
|
3551
|
+
if (!commonRect || commonRect.width <= 0 || commonRect.height <= 0) return false;
|
|
3552
|
+
const commonArea = commonRect.width * commonRect.height;
|
|
3553
|
+
const targetArea = Math.max(1, rect.width * rect.height);
|
|
3554
|
+
const maxSharedRegionArea = Math.max(targetArea * 12, 4096);
|
|
3555
|
+
if (commonArea > maxSharedRegionArea) return false;
|
|
3556
|
+
if (commonRect.width > Math.max(rect.width * 8, 120) || commonRect.height > Math.max(rect.height * 8, 120)) {
|
|
3560
3557
|
return false;
|
|
3561
3558
|
}
|
|
3562
|
-
return
|
|
3559
|
+
return common.contains(el) && common.contains(pointElement);
|
|
3563
3560
|
};
|
|
3564
3561
|
const describeElement = (node) => {
|
|
3565
3562
|
if (!node) return null;
|
|
@@ -3588,7 +3585,7 @@ var checkElementVisibility = async (element) => {
|
|
|
3588
3585
|
let obstruction = null;
|
|
3589
3586
|
for (const point of samplePoints) {
|
|
3590
3587
|
const pointElement = document.elementFromPoint(point.x, point.y);
|
|
3591
|
-
if (
|
|
3588
|
+
if (sameTapTarget(pointElement)) {
|
|
3592
3589
|
return { code: "VISIBLE", isFixed, positioning };
|
|
3593
3590
|
}
|
|
3594
3591
|
obstruction = obstruction || describeElement(pointElement);
|
|
@@ -3606,10 +3603,10 @@ var checkElementVisibility = async (element) => {
|
|
|
3606
3603
|
};
|
|
3607
3604
|
}
|
|
3608
3605
|
return { code: "VISIBLE", isFixed, positioning };
|
|
3609
|
-
}
|
|
3606
|
+
});
|
|
3610
3607
|
};
|
|
3611
3608
|
var resolveSafeTapPoint = async (element) => {
|
|
3612
|
-
return element.evaluate((el
|
|
3609
|
+
return element.evaluate((el) => {
|
|
3613
3610
|
const rect = el.getBoundingClientRect();
|
|
3614
3611
|
if (!rect || rect.width <= 0 || rect.height <= 0) {
|
|
3615
3612
|
return null;
|
|
@@ -3646,16 +3643,30 @@ var resolveSafeTapPoint = async (element) => {
|
|
|
3646
3643
|
if (visibleWidth <= 1 || visibleHeight <= 1) {
|
|
3647
3644
|
return null;
|
|
3648
3645
|
}
|
|
3649
|
-
const
|
|
3650
|
-
const
|
|
3646
|
+
const isRootNode = (node) => !node || node === document || node === document.body || node === document.documentElement;
|
|
3647
|
+
const commonAncestor = (a, b) => {
|
|
3648
|
+
for (let current = a; current && !isRootNode(current); current = current.parentElement) {
|
|
3649
|
+
if (current.contains(b)) return current;
|
|
3650
|
+
}
|
|
3651
|
+
return null;
|
|
3652
|
+
};
|
|
3653
|
+
const sameTapTarget = (pointElement) => {
|
|
3651
3654
|
if (!pointElement) return false;
|
|
3652
3655
|
if (pointElement === el || el.contains(pointElement) || pointElement.contains(el)) {
|
|
3653
3656
|
return true;
|
|
3654
3657
|
}
|
|
3655
|
-
|
|
3658
|
+
const common = commonAncestor(el, pointElement);
|
|
3659
|
+
if (!common) return false;
|
|
3660
|
+
const commonRect = common.getBoundingClientRect?.();
|
|
3661
|
+
if (!commonRect || commonRect.width <= 0 || commonRect.height <= 0) return false;
|
|
3662
|
+
const commonArea = commonRect.width * commonRect.height;
|
|
3663
|
+
const targetArea = Math.max(1, rect.width * rect.height);
|
|
3664
|
+
const maxSharedRegionArea = Math.max(targetArea * 12, 4096);
|
|
3665
|
+
if (commonArea > maxSharedRegionArea) return false;
|
|
3666
|
+
if (commonRect.width > Math.max(rect.width * 8, 120) || commonRect.height > Math.max(rect.height * 8, 120)) {
|
|
3656
3667
|
return false;
|
|
3657
3668
|
}
|
|
3658
|
-
return
|
|
3669
|
+
return common.contains(el) && common.contains(pointElement);
|
|
3659
3670
|
};
|
|
3660
3671
|
const cx = visibleLeft + visibleWidth / 2;
|
|
3661
3672
|
const cy = visibleTop + visibleHeight / 2;
|
|
@@ -3674,7 +3685,7 @@ var resolveSafeTapPoint = async (element) => {
|
|
|
3674
3685
|
];
|
|
3675
3686
|
const safePoints = points.filter((point) => {
|
|
3676
3687
|
const pointElement = document.elementFromPoint(point.x, point.y);
|
|
3677
|
-
return
|
|
3688
|
+
return sameTapTarget(pointElement);
|
|
3678
3689
|
});
|
|
3679
3690
|
const candidates = safePoints.length ? safePoints : points;
|
|
3680
3691
|
const chosen = candidates[Math.floor(Math.random() * candidates.length)];
|
|
@@ -3683,46 +3694,57 @@ var resolveSafeTapPoint = async (element) => {
|
|
|
3683
3694
|
x: chosen.x,
|
|
3684
3695
|
y: chosen.y
|
|
3685
3696
|
};
|
|
3686
|
-
}
|
|
3697
|
+
});
|
|
3687
3698
|
};
|
|
3688
3699
|
var activateElementFallback = async (element, point = null, options = {}) => {
|
|
3689
|
-
return element.evaluate((el, {
|
|
3690
|
-
const
|
|
3691
|
-
|
|
3692
|
-
if (
|
|
3693
|
-
return node.
|
|
3700
|
+
return element.evaluate((el, { innerOptions }) => {
|
|
3701
|
+
const isEditable = (node) => {
|
|
3702
|
+
if (!node || node.nodeType !== Node.ELEMENT_NODE) return false;
|
|
3703
|
+
if (node.isContentEditable) return true;
|
|
3704
|
+
if (node instanceof HTMLTextAreaElement) return !node.disabled && !node.readOnly;
|
|
3705
|
+
if (node instanceof HTMLInputElement) {
|
|
3706
|
+
return !node.disabled && !node.readOnly && typeof node.select === "function";
|
|
3707
|
+
}
|
|
3708
|
+
return false;
|
|
3709
|
+
};
|
|
3710
|
+
const findEditable = (node) => {
|
|
3711
|
+
for (let current = node; current && current !== document.body; current = current.parentElement) {
|
|
3712
|
+
if (isEditable(current)) return current;
|
|
3713
|
+
}
|
|
3714
|
+
return null;
|
|
3694
3715
|
};
|
|
3695
|
-
const
|
|
3696
|
-
const pointInteractive = nearestInteractive(pointElement);
|
|
3697
|
-
let target = null;
|
|
3698
|
-
if (pointInteractive && (pointInteractive === targetInteractive || pointInteractive === el || pointInteractive.contains(el) || el.contains(pointInteractive))) {
|
|
3699
|
-
target = pointInteractive;
|
|
3700
|
-
}
|
|
3701
|
-
target = target || targetInteractive || el;
|
|
3702
|
-
const editable = typeof target.closest === "function" ? target.closest(editableSelector) : null;
|
|
3716
|
+
const editable = findEditable(el);
|
|
3703
3717
|
if (editable && typeof editable.focus === "function") {
|
|
3704
3718
|
editable.focus({ preventScroll: true });
|
|
3705
3719
|
if (innerOptions.editableOnly) {
|
|
3706
3720
|
return { activated: true, method: "focus", tag: editable.tagName || "" };
|
|
3707
3721
|
}
|
|
3708
3722
|
}
|
|
3709
|
-
if (
|
|
3710
|
-
|
|
3723
|
+
if (innerOptions.editableOnly) {
|
|
3724
|
+
return { activated: false, method: "none", tag: el?.tagName || "" };
|
|
3711
3725
|
}
|
|
3712
|
-
if (
|
|
3713
|
-
|
|
3714
|
-
|
|
3726
|
+
if (typeof el.focus === "function") {
|
|
3727
|
+
el.focus({ preventScroll: true });
|
|
3728
|
+
}
|
|
3729
|
+
if (typeof el.click === "function") {
|
|
3730
|
+
el.click();
|
|
3731
|
+
return { activated: true, method: "dom-click", tag: el.tagName || "" };
|
|
3732
|
+
}
|
|
3733
|
+
if (typeof el.dispatchEvent === "function") {
|
|
3734
|
+
el.dispatchEvent(new MouseEvent("click", {
|
|
3735
|
+
bubbles: true,
|
|
3736
|
+
cancelable: true,
|
|
3737
|
+
view: window
|
|
3738
|
+
}));
|
|
3739
|
+
return { activated: true, method: "dispatch-click", tag: el.tagName || "" };
|
|
3715
3740
|
}
|
|
3716
3741
|
return {
|
|
3717
3742
|
activated: Boolean(editable),
|
|
3718
3743
|
method: editable ? "focus" : "none",
|
|
3719
|
-
tag:
|
|
3744
|
+
tag: el?.tagName || ""
|
|
3720
3745
|
};
|
|
3721
3746
|
}, {
|
|
3722
|
-
|
|
3723
|
-
innerOptions: options || {},
|
|
3724
|
-
interactiveSelector: INTERACTIVE_SELECTOR,
|
|
3725
|
-
editableSelector: EDITABLE_SELECTOR
|
|
3747
|
+
innerOptions: options || {}
|
|
3726
3748
|
});
|
|
3727
3749
|
};
|
|
3728
3750
|
var getScrollableRect = async (element) => {
|
|
@@ -3826,6 +3848,47 @@ var scrollAwayFromObstruction = async (element, status) => {
|
|
|
3826
3848
|
};
|
|
3827
3849
|
}, status);
|
|
3828
3850
|
};
|
|
3851
|
+
var getElementViewportSnapshot = async (element) => {
|
|
3852
|
+
return element.evaluate((el) => {
|
|
3853
|
+
const rect = el.getBoundingClientRect();
|
|
3854
|
+
return {
|
|
3855
|
+
top: rect.top,
|
|
3856
|
+
bottom: rect.bottom,
|
|
3857
|
+
left: rect.left,
|
|
3858
|
+
right: rect.right,
|
|
3859
|
+
width: rect.width,
|
|
3860
|
+
height: rect.height,
|
|
3861
|
+
scrollX: window.scrollX,
|
|
3862
|
+
scrollY: window.scrollY
|
|
3863
|
+
};
|
|
3864
|
+
});
|
|
3865
|
+
};
|
|
3866
|
+
var isTargetImmobileAfterScroll = (before, after) => {
|
|
3867
|
+
if (!before || !after) return false;
|
|
3868
|
+
const rectDeltaY = Number(after.top || 0) - Number(before.top || 0);
|
|
3869
|
+
const rectDeltaX = Number(after.left || 0) - Number(before.left || 0);
|
|
3870
|
+
const scrollDeltaY = Number(after.scrollY || 0) - Number(before.scrollY || 0);
|
|
3871
|
+
const scrollDeltaX = Number(after.scrollX || 0) - Number(before.scrollX || 0);
|
|
3872
|
+
const rectMoved = Math.abs(rectDeltaY) > 3 || Math.abs(rectDeltaX) > 3;
|
|
3873
|
+
const pageMoved = Math.abs(scrollDeltaY) > 3 || Math.abs(scrollDeltaX) > 3;
|
|
3874
|
+
if (!rectMoved && !pageMoved) return true;
|
|
3875
|
+
if (pageMoved && !rectMoved) return true;
|
|
3876
|
+
if (Math.abs(scrollDeltaY) > 12 && Math.abs(rectDeltaY) < Math.min(12, Math.abs(scrollDeltaY) * 0.2)) {
|
|
3877
|
+
return true;
|
|
3878
|
+
}
|
|
3879
|
+
return false;
|
|
3880
|
+
};
|
|
3881
|
+
var restoreWindowFromSnapshot = async (page, before, after) => {
|
|
3882
|
+
if (!before || !after) return;
|
|
3883
|
+
if (Math.abs(Number(after.scrollX || 0) - Number(before.scrollX || 0)) <= 2 && Math.abs(Number(after.scrollY || 0) - Number(before.scrollY || 0)) <= 2) {
|
|
3884
|
+
return;
|
|
3885
|
+
}
|
|
3886
|
+
await page.evaluate(
|
|
3887
|
+
(state) => window.scrollTo(state.x, state.y),
|
|
3888
|
+
{ x: Number(before.scrollX || 0), y: Number(before.scrollY || 0) }
|
|
3889
|
+
).catch(() => {
|
|
3890
|
+
});
|
|
3891
|
+
};
|
|
3829
3892
|
var dispatchTouchSwipe = async (page, deltaY, options = {}) => {
|
|
3830
3893
|
const viewport = resolveViewport(page);
|
|
3831
3894
|
const rawRect = options.rect || null;
|
|
@@ -4006,11 +4069,11 @@ var MobileHumanize = {
|
|
|
4006
4069
|
const scrollRect = await getScrollableRect(element);
|
|
4007
4070
|
if (!scrollRect && status.isFixed && status.code === "OUT_OF_VIEWPORT") {
|
|
4008
4071
|
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"})`);
|
|
4009
|
-
return { element, didScroll, restore: null };
|
|
4072
|
+
return { element, didScroll, restore: null, unscrollable: true };
|
|
4010
4073
|
}
|
|
4011
4074
|
if (!scrollRect && status.isFixed && status.code === "OBSTRUCTED") {
|
|
4012
4075
|
logger7.warn(`humanScroll | fixed/sticky \u76EE\u6807\u88AB\u906E\u6321\uFF0C\u6EDA\u52A8\u65E0\u6CD5\u89E3\u9664 (${status.obstruction?.tag || "unknown"})`);
|
|
4013
|
-
return { element, didScroll, restore: null };
|
|
4076
|
+
return { element, didScroll, restore: null, unscrollable: true };
|
|
4014
4077
|
}
|
|
4015
4078
|
if (scrollRect && status.code === "OBSTRUCTED" && status.obstruction?.isFixed) {
|
|
4016
4079
|
const moved = await scrollAwayFromObstruction(element, status);
|
|
@@ -4041,6 +4104,7 @@ var MobileHumanize = {
|
|
|
4041
4104
|
}
|
|
4042
4105
|
}
|
|
4043
4106
|
const beforeWindowState = scrollRect ? await page.evaluate(() => ({ x: window.scrollX, y: window.scrollY })) : null;
|
|
4107
|
+
const beforeElementSnapshot = await getElementViewportSnapshot(element).catch(() => null);
|
|
4044
4108
|
const beforeState = scrollRect ? await element.evaluate((el) => {
|
|
4045
4109
|
const isScrollable = (node) => {
|
|
4046
4110
|
const style = window.getComputedStyle(node);
|
|
@@ -4070,6 +4134,21 @@ var MobileHumanize = {
|
|
|
4070
4134
|
logger7.debug(`humanScroll | \u7A97\u53E3\u6EDA\u52A8\u56DE\u6536 from=${Math.round(afterWindowState.y)} to=${Math.round(beforeWindowState.y)}`);
|
|
4071
4135
|
}
|
|
4072
4136
|
}
|
|
4137
|
+
let afterElementSnapshot = null;
|
|
4138
|
+
const readAfterElementSnapshot = async () => {
|
|
4139
|
+
if (!afterElementSnapshot) {
|
|
4140
|
+
afterElementSnapshot = await getElementViewportSnapshot(element).catch(() => null);
|
|
4141
|
+
}
|
|
4142
|
+
return afterElementSnapshot;
|
|
4143
|
+
};
|
|
4144
|
+
if (!scrollRect && beforeElementSnapshot) {
|
|
4145
|
+
const afterSnapshot = await readAfterElementSnapshot();
|
|
4146
|
+
if (isTargetImmobileAfterScroll(beforeElementSnapshot, afterSnapshot)) {
|
|
4147
|
+
await restoreWindowFromSnapshot(page, beforeElementSnapshot, afterSnapshot);
|
|
4148
|
+
logger7.warn(`humanScroll | \u76EE\u6807\u4E0D\u968F\u9875\u9762\u6EDA\u52A8\u79FB\u52A8\uFF0C\u9875\u9762\u6EDA\u52A8\u65E0\u6CD5\u6539\u53D8\u5176\u4F4D\u7F6E (status=${status.code}, direction=${status.direction || "unknown"})`);
|
|
4149
|
+
return { element, didScroll, restore: null, unscrollable: true };
|
|
4150
|
+
}
|
|
4151
|
+
}
|
|
4073
4152
|
if (scrollRect && beforeState) {
|
|
4074
4153
|
const afterState = await element.evaluate((el) => {
|
|
4075
4154
|
const isScrollable = (node) => {
|
|
@@ -4107,6 +4186,14 @@ var MobileHumanize = {
|
|
|
4107
4186
|
}
|
|
4108
4187
|
}
|
|
4109
4188
|
}
|
|
4189
|
+
if (scrollRect && beforeElementSnapshot) {
|
|
4190
|
+
const afterSnapshot = await getElementViewportSnapshot(element).catch(() => null);
|
|
4191
|
+
if (isTargetImmobileAfterScroll(beforeElementSnapshot, afterSnapshot)) {
|
|
4192
|
+
await restoreWindowFromSnapshot(page, beforeElementSnapshot, afterSnapshot);
|
|
4193
|
+
logger7.warn(`humanScroll | \u76EE\u6807\u4E0D\u968F\u6EDA\u52A8\u5BB9\u5668\u79FB\u52A8\uFF0C\u6EDA\u52A8\u65E0\u6CD5\u6539\u53D8\u5176\u4F4D\u7F6E (status=${status.code}, direction=${status.direction || "unknown"})`);
|
|
4194
|
+
return { element, didScroll, restore: null, unscrollable: true };
|
|
4195
|
+
}
|
|
4196
|
+
}
|
|
4110
4197
|
didScroll = true;
|
|
4111
4198
|
}
|
|
4112
4199
|
try {
|
|
@@ -4156,21 +4243,28 @@ var MobileHumanize = {
|
|
|
4156
4243
|
logger7.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${targetDesc}`);
|
|
4157
4244
|
return false;
|
|
4158
4245
|
}
|
|
4159
|
-
|
|
4160
|
-
await MobileHumanize.humanScroll(page, element, { throwOnMissing });
|
|
4161
|
-
}
|
|
4246
|
+
const scrollResult = scrollIfNeeded ? await MobileHumanize.humanScroll(page, element, { throwOnMissing }) : null;
|
|
4162
4247
|
const status = await checkElementVisibility(element).catch(() => null);
|
|
4163
4248
|
if (status && status.code !== "VISIBLE") {
|
|
4164
|
-
if (fallbackDomClick && status.
|
|
4165
|
-
|
|
4249
|
+
if (fallbackDomClick && (status.code === "OUT_OF_VIEWPORT" || status.code === "OBSTRUCTED") && (status.isFixed || scrollResult?.unscrollable)) {
|
|
4250
|
+
let fallback = await withTimeout(
|
|
4166
4251
|
() => activateElementFallback(element, null, {
|
|
4167
4252
|
editableOnly: true
|
|
4168
4253
|
}),
|
|
4169
4254
|
activateFallbackTimeoutMs,
|
|
4170
4255
|
"focus fallback"
|
|
4171
4256
|
).catch(() => null);
|
|
4257
|
+
if (!fallback?.activated) {
|
|
4258
|
+
fallback = await withTimeout(
|
|
4259
|
+
() => activateElementFallback(element, null, {
|
|
4260
|
+
editableOnly: false
|
|
4261
|
+
}),
|
|
4262
|
+
activateFallbackTimeoutMs,
|
|
4263
|
+
"activation fallback"
|
|
4264
|
+
).catch(() => null);
|
|
4265
|
+
}
|
|
4172
4266
|
if (fallback?.activated) {
|
|
4173
|
-
logger7.warn(`humanClick:
|
|
4267
|
+
logger7.warn(`humanClick: \u4E0D\u53EF\u6EDA\u52A8\u76EE\u6807\u4E0D\u53EF\u7269\u7406\u70B9\u51FB\uFF0C\u5DF2\u7528 ${fallback.method} \u6FC0\u6D3B`);
|
|
4174
4268
|
return true;
|
|
4175
4269
|
}
|
|
4176
4270
|
}
|
|
@@ -4287,6 +4381,20 @@ var MobileHumanize = {
|
|
|
4287
4381
|
const locator = page.locator(selector);
|
|
4288
4382
|
await MobileHumanize.humanClick(page, locator, { scrollIfNeeded: true });
|
|
4289
4383
|
await waitJitter(160, 0.4);
|
|
4384
|
+
const readValue = async () => {
|
|
4385
|
+
try {
|
|
4386
|
+
return await locator.inputValue({ timeout: 600 });
|
|
4387
|
+
} catch {
|
|
4388
|
+
return await locator.evaluate((el) => "value" in el ? String(el.value || "") : String(el.textContent || "")).catch(() => "");
|
|
4389
|
+
}
|
|
4390
|
+
};
|
|
4391
|
+
const currentValue = await readValue();
|
|
4392
|
+
if (!currentValue) return;
|
|
4393
|
+
await page.keyboard.press("ControlOrMeta+A");
|
|
4394
|
+
await waitJitter(90, 0.35);
|
|
4395
|
+
await page.keyboard.press("Backspace");
|
|
4396
|
+
await waitJitter(120, 0.35);
|
|
4397
|
+
if (!await readValue()) return;
|
|
4290
4398
|
await locator.evaluate((el) => {
|
|
4291
4399
|
if ("value" in el) {
|
|
4292
4400
|
el.value = "";
|