@skrillex1224/playwright-toolkit 2.1.244 → 2.1.245
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 +182 -18
- package/dist/index.cjs.map +2 -2
- package/dist/index.js +182 -18
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3439,6 +3439,11 @@ var DEFAULT_ACTIVATE_FALLBACK_TIMEOUT_MS = 900;
|
|
|
3439
3439
|
var INTERACTIVE_SELECTOR = [
|
|
3440
3440
|
"button",
|
|
3441
3441
|
'[role="button"]',
|
|
3442
|
+
'[role="link"]',
|
|
3443
|
+
'[role="menuitem"]',
|
|
3444
|
+
'[role="tab"]',
|
|
3445
|
+
'[role="switch"]',
|
|
3446
|
+
'[role="checkbox"]',
|
|
3442
3447
|
"a[href]",
|
|
3443
3448
|
"label",
|
|
3444
3449
|
"input",
|
|
@@ -3453,6 +3458,34 @@ var EDITABLE_SELECTOR = [
|
|
|
3453
3458
|
"textarea",
|
|
3454
3459
|
'[contenteditable="true"]'
|
|
3455
3460
|
].join(",");
|
|
3461
|
+
var INTERACTIVE_HINT_PATTERN = [
|
|
3462
|
+
"btn",
|
|
3463
|
+
"button",
|
|
3464
|
+
"send",
|
|
3465
|
+
"submit",
|
|
3466
|
+
"confirm",
|
|
3467
|
+
"cancel",
|
|
3468
|
+
"retry",
|
|
3469
|
+
"reload",
|
|
3470
|
+
"search",
|
|
3471
|
+
"copy",
|
|
3472
|
+
"share",
|
|
3473
|
+
"close",
|
|
3474
|
+
"more",
|
|
3475
|
+
"\u53D1\u9001",
|
|
3476
|
+
"\u63D0\u4EA4",
|
|
3477
|
+
"\u786E\u5B9A",
|
|
3478
|
+
"\u786E\u8BA4",
|
|
3479
|
+
"\u53D6\u6D88",
|
|
3480
|
+
"\u91CD\u8BD5",
|
|
3481
|
+
"\u641C\u7D22",
|
|
3482
|
+
"\u590D\u5236",
|
|
3483
|
+
"\u5206\u4EAB",
|
|
3484
|
+
"\u5173\u95ED",
|
|
3485
|
+
"\u66F4\u591A",
|
|
3486
|
+
"\u5C55\u5F00",
|
|
3487
|
+
"\u6536\u8D77"
|
|
3488
|
+
].join("|");
|
|
3456
3489
|
var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
3457
3490
|
var resolveViewport = (page) => page?.viewportSize?.() || { width: 390, height: 844 };
|
|
3458
3491
|
var describeTarget = (target) => {
|
|
@@ -3492,7 +3525,47 @@ var withTimeout = async (operation, timeoutMs, label) => {
|
|
|
3492
3525
|
}
|
|
3493
3526
|
};
|
|
3494
3527
|
var checkElementVisibility = async (element) => {
|
|
3495
|
-
return element.evaluate((el, interactiveSelector) => {
|
|
3528
|
+
return element.evaluate((el, { interactiveSelector, interactiveHintPattern }) => {
|
|
3529
|
+
const interactiveHintRe = new RegExp(interactiveHintPattern, "i");
|
|
3530
|
+
const nodeClassName = (node) => {
|
|
3531
|
+
if (!node) return "";
|
|
3532
|
+
if (typeof node.className === "string") return node.className;
|
|
3533
|
+
if (node.className && typeof node.className.baseVal === "string") return node.className.baseVal;
|
|
3534
|
+
return "";
|
|
3535
|
+
};
|
|
3536
|
+
const interactiveScore = (node) => {
|
|
3537
|
+
if (!node || node.nodeType !== Node.ELEMENT_NODE) return 0;
|
|
3538
|
+
let score = 0;
|
|
3539
|
+
if (typeof node.matches === "function" && node.matches(interactiveSelector)) score += 8;
|
|
3540
|
+
const hints = [
|
|
3541
|
+
node.id || "",
|
|
3542
|
+
nodeClassName(node),
|
|
3543
|
+
node.getAttribute?.("aria-label") || "",
|
|
3544
|
+
node.getAttribute?.("title") || "",
|
|
3545
|
+
node.getAttribute?.("data-testid") || "",
|
|
3546
|
+
node.getAttribute?.("data-test") || "",
|
|
3547
|
+
node.getAttribute?.("data-click") || "",
|
|
3548
|
+
node.getAttribute?.("data-action") || "",
|
|
3549
|
+
node.getAttribute?.("onclick") || "",
|
|
3550
|
+
String(node.textContent || "").trim().slice(0, 24)
|
|
3551
|
+
].join(" ");
|
|
3552
|
+
if (interactiveHintRe.test(hints)) score += 4;
|
|
3553
|
+
const style = window.getComputedStyle(node);
|
|
3554
|
+
if (style?.cursor === "pointer") score += 2;
|
|
3555
|
+
return score;
|
|
3556
|
+
};
|
|
3557
|
+
const closestInteractive = (node) => {
|
|
3558
|
+
let best = null;
|
|
3559
|
+
let bestScore = 0;
|
|
3560
|
+
for (let current = node; current && current !== document.body; current = current.parentElement) {
|
|
3561
|
+
const score = interactiveScore(current);
|
|
3562
|
+
if (score > bestScore || score > 0 && score === bestScore) {
|
|
3563
|
+
best = current;
|
|
3564
|
+
bestScore = score;
|
|
3565
|
+
}
|
|
3566
|
+
}
|
|
3567
|
+
return best;
|
|
3568
|
+
};
|
|
3496
3569
|
const targetStyle = window.getComputedStyle(el);
|
|
3497
3570
|
if (!targetStyle || targetStyle.display === "none" || targetStyle.visibility === "hidden" || targetStyle.visibility === "collapse") {
|
|
3498
3571
|
return { code: "NOT_INTERACTABLE", reason: "\u5143\u7D20\u4E0D\u53EF\u89C1", direction: "down" };
|
|
@@ -3554,16 +3627,13 @@ var checkElementVisibility = async (element) => {
|
|
|
3554
3627
|
positioning
|
|
3555
3628
|
};
|
|
3556
3629
|
}
|
|
3557
|
-
const targetInteractive =
|
|
3630
|
+
const targetInteractive = closestInteractive(el);
|
|
3558
3631
|
const sameInteractiveTarget = (pointElement) => {
|
|
3559
3632
|
if (!pointElement) return false;
|
|
3560
3633
|
if (pointElement === el || el.contains(pointElement) || pointElement.contains(el)) {
|
|
3561
3634
|
return true;
|
|
3562
3635
|
}
|
|
3563
|
-
|
|
3564
|
-
return false;
|
|
3565
|
-
}
|
|
3566
|
-
return pointElement.closest(interactiveSelector) === targetInteractive;
|
|
3636
|
+
return Boolean(targetInteractive && closestInteractive(pointElement) === targetInteractive);
|
|
3567
3637
|
};
|
|
3568
3638
|
const describeElement = (node) => {
|
|
3569
3639
|
if (!node) return null;
|
|
@@ -3610,10 +3680,53 @@ var checkElementVisibility = async (element) => {
|
|
|
3610
3680
|
};
|
|
3611
3681
|
}
|
|
3612
3682
|
return { code: "VISIBLE", isFixed, positioning };
|
|
3613
|
-
},
|
|
3683
|
+
}, {
|
|
3684
|
+
interactiveSelector: INTERACTIVE_SELECTOR,
|
|
3685
|
+
interactiveHintPattern: INTERACTIVE_HINT_PATTERN
|
|
3686
|
+
});
|
|
3614
3687
|
};
|
|
3615
3688
|
var resolveSafeTapPoint = async (element) => {
|
|
3616
|
-
return element.evaluate((el, interactiveSelector) => {
|
|
3689
|
+
return element.evaluate((el, { interactiveSelector, interactiveHintPattern }) => {
|
|
3690
|
+
const interactiveHintRe = new RegExp(interactiveHintPattern, "i");
|
|
3691
|
+
const nodeClassName = (node) => {
|
|
3692
|
+
if (!node) return "";
|
|
3693
|
+
if (typeof node.className === "string") return node.className;
|
|
3694
|
+
if (node.className && typeof node.className.baseVal === "string") return node.className.baseVal;
|
|
3695
|
+
return "";
|
|
3696
|
+
};
|
|
3697
|
+
const interactiveScore = (node) => {
|
|
3698
|
+
if (!node || node.nodeType !== Node.ELEMENT_NODE) return 0;
|
|
3699
|
+
let score = 0;
|
|
3700
|
+
if (typeof node.matches === "function" && node.matches(interactiveSelector)) score += 8;
|
|
3701
|
+
const hints = [
|
|
3702
|
+
node.id || "",
|
|
3703
|
+
nodeClassName(node),
|
|
3704
|
+
node.getAttribute?.("aria-label") || "",
|
|
3705
|
+
node.getAttribute?.("title") || "",
|
|
3706
|
+
node.getAttribute?.("data-testid") || "",
|
|
3707
|
+
node.getAttribute?.("data-test") || "",
|
|
3708
|
+
node.getAttribute?.("data-click") || "",
|
|
3709
|
+
node.getAttribute?.("data-action") || "",
|
|
3710
|
+
node.getAttribute?.("onclick") || "",
|
|
3711
|
+
String(node.textContent || "").trim().slice(0, 24)
|
|
3712
|
+
].join(" ");
|
|
3713
|
+
if (interactiveHintRe.test(hints)) score += 4;
|
|
3714
|
+
const style = window.getComputedStyle(node);
|
|
3715
|
+
if (style?.cursor === "pointer") score += 2;
|
|
3716
|
+
return score;
|
|
3717
|
+
};
|
|
3718
|
+
const closestInteractive = (node) => {
|
|
3719
|
+
let best = null;
|
|
3720
|
+
let bestScore = 0;
|
|
3721
|
+
for (let current = node; current && current !== document.body; current = current.parentElement) {
|
|
3722
|
+
const score = interactiveScore(current);
|
|
3723
|
+
if (score > bestScore || score > 0 && score === bestScore) {
|
|
3724
|
+
best = current;
|
|
3725
|
+
bestScore = score;
|
|
3726
|
+
}
|
|
3727
|
+
}
|
|
3728
|
+
return best;
|
|
3729
|
+
};
|
|
3617
3730
|
const rect = el.getBoundingClientRect();
|
|
3618
3731
|
if (!rect || rect.width <= 0 || rect.height <= 0) {
|
|
3619
3732
|
return null;
|
|
@@ -3650,16 +3763,13 @@ var resolveSafeTapPoint = async (element) => {
|
|
|
3650
3763
|
if (visibleWidth <= 1 || visibleHeight <= 1) {
|
|
3651
3764
|
return null;
|
|
3652
3765
|
}
|
|
3653
|
-
const targetInteractive =
|
|
3766
|
+
const targetInteractive = closestInteractive(el);
|
|
3654
3767
|
const sameInteractiveTarget = (pointElement) => {
|
|
3655
3768
|
if (!pointElement) return false;
|
|
3656
3769
|
if (pointElement === el || el.contains(pointElement) || pointElement.contains(el)) {
|
|
3657
3770
|
return true;
|
|
3658
3771
|
}
|
|
3659
|
-
|
|
3660
|
-
return false;
|
|
3661
|
-
}
|
|
3662
|
-
return pointElement.closest(interactiveSelector) === targetInteractive;
|
|
3772
|
+
return Boolean(targetInteractive && closestInteractive(pointElement) === targetInteractive);
|
|
3663
3773
|
};
|
|
3664
3774
|
const cx = visibleLeft + visibleWidth / 2;
|
|
3665
3775
|
const cy = visibleTop + visibleHeight / 2;
|
|
@@ -3687,14 +3797,53 @@ var resolveSafeTapPoint = async (element) => {
|
|
|
3687
3797
|
x: chosen.x,
|
|
3688
3798
|
y: chosen.y
|
|
3689
3799
|
};
|
|
3690
|
-
},
|
|
3800
|
+
}, {
|
|
3801
|
+
interactiveSelector: INTERACTIVE_SELECTOR,
|
|
3802
|
+
interactiveHintPattern: INTERACTIVE_HINT_PATTERN
|
|
3803
|
+
});
|
|
3691
3804
|
};
|
|
3692
3805
|
var activateElementFallback = async (element, point = null, options = {}) => {
|
|
3693
|
-
return element.evaluate((el, { innerPoint, innerOptions, interactiveSelector, editableSelector }) => {
|
|
3806
|
+
return element.evaluate((el, { innerPoint, innerOptions, interactiveSelector, editableSelector, interactiveHintPattern }) => {
|
|
3807
|
+
const interactiveHintRe = new RegExp(interactiveHintPattern, "i");
|
|
3808
|
+
const nodeClassName = (node) => {
|
|
3809
|
+
if (!node) return "";
|
|
3810
|
+
if (typeof node.className === "string") return node.className;
|
|
3811
|
+
if (node.className && typeof node.className.baseVal === "string") return node.className.baseVal;
|
|
3812
|
+
return "";
|
|
3813
|
+
};
|
|
3814
|
+
const interactiveScore = (node) => {
|
|
3815
|
+
if (!node || node.nodeType !== Node.ELEMENT_NODE) return 0;
|
|
3816
|
+
let score = 0;
|
|
3817
|
+
if (typeof node.matches === "function" && node.matches(interactiveSelector)) score += 8;
|
|
3818
|
+
const hints = [
|
|
3819
|
+
node.id || "",
|
|
3820
|
+
nodeClassName(node),
|
|
3821
|
+
node.getAttribute?.("aria-label") || "",
|
|
3822
|
+
node.getAttribute?.("title") || "",
|
|
3823
|
+
node.getAttribute?.("data-testid") || "",
|
|
3824
|
+
node.getAttribute?.("data-test") || "",
|
|
3825
|
+
node.getAttribute?.("data-click") || "",
|
|
3826
|
+
node.getAttribute?.("data-action") || "",
|
|
3827
|
+
node.getAttribute?.("onclick") || "",
|
|
3828
|
+
String(node.textContent || "").trim().slice(0, 24)
|
|
3829
|
+
].join(" ");
|
|
3830
|
+
if (interactiveHintRe.test(hints)) score += 4;
|
|
3831
|
+
const style = window.getComputedStyle(node);
|
|
3832
|
+
if (style?.cursor === "pointer") score += 2;
|
|
3833
|
+
return score;
|
|
3834
|
+
};
|
|
3694
3835
|
const pointElement = innerPoint ? document.elementFromPoint(innerPoint.x, innerPoint.y) : null;
|
|
3695
3836
|
const nearestInteractive = (node) => {
|
|
3696
|
-
|
|
3697
|
-
|
|
3837
|
+
let best = null;
|
|
3838
|
+
let bestScore = 0;
|
|
3839
|
+
for (let current = node; current && current !== document.body; current = current.parentElement) {
|
|
3840
|
+
const score = interactiveScore(current);
|
|
3841
|
+
if (score > bestScore || score > 0 && score === bestScore) {
|
|
3842
|
+
best = current;
|
|
3843
|
+
bestScore = score;
|
|
3844
|
+
}
|
|
3845
|
+
}
|
|
3846
|
+
return best;
|
|
3698
3847
|
};
|
|
3699
3848
|
const targetInteractive = nearestInteractive(el);
|
|
3700
3849
|
const pointInteractive = nearestInteractive(pointElement);
|
|
@@ -3726,7 +3875,8 @@ var activateElementFallback = async (element, point = null, options = {}) => {
|
|
|
3726
3875
|
innerPoint: point,
|
|
3727
3876
|
innerOptions: options || {},
|
|
3728
3877
|
interactiveSelector: INTERACTIVE_SELECTOR,
|
|
3729
|
-
editableSelector: EDITABLE_SELECTOR
|
|
3878
|
+
editableSelector: EDITABLE_SELECTOR,
|
|
3879
|
+
interactiveHintPattern: INTERACTIVE_HINT_PATTERN
|
|
3730
3880
|
});
|
|
3731
3881
|
};
|
|
3732
3882
|
var getScrollableRect = async (element) => {
|
|
@@ -4363,6 +4513,20 @@ var MobileHumanize = {
|
|
|
4363
4513
|
const locator = page.locator(selector);
|
|
4364
4514
|
await MobileHumanize.humanClick(page, locator, { scrollIfNeeded: true });
|
|
4365
4515
|
await waitJitter(160, 0.4);
|
|
4516
|
+
const readValue = async () => {
|
|
4517
|
+
try {
|
|
4518
|
+
return await locator.inputValue({ timeout: 600 });
|
|
4519
|
+
} catch {
|
|
4520
|
+
return await locator.evaluate((el) => "value" in el ? String(el.value || "") : String(el.textContent || "")).catch(() => "");
|
|
4521
|
+
}
|
|
4522
|
+
};
|
|
4523
|
+
const currentValue = await readValue();
|
|
4524
|
+
if (!currentValue) return;
|
|
4525
|
+
await page.keyboard.press("ControlOrMeta+A");
|
|
4526
|
+
await waitJitter(90, 0.35);
|
|
4527
|
+
await page.keyboard.press("Backspace");
|
|
4528
|
+
await waitJitter(120, 0.35);
|
|
4529
|
+
if (!await readValue()) return;
|
|
4366
4530
|
await locator.evaluate((el) => {
|
|
4367
4531
|
if ("value" in el) {
|
|
4368
4532
|
el.value = "";
|