@skrillex1224/playwright-toolkit 2.1.245 → 2.1.247
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 +75 -203
- package/dist/index.cjs.map +2 -2
- package/dist/index.js +75 -203
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3436,56 +3436,6 @@ var initializedPages = /* @__PURE__ */ new WeakSet();
|
|
|
3436
3436
|
var DEFAULT_TAP_TIMEOUT_MS = 2500;
|
|
3437
3437
|
var DEFAULT_MOUSE_TAP_FALLBACK_TIMEOUT_MS = 1200;
|
|
3438
3438
|
var DEFAULT_ACTIVATE_FALLBACK_TIMEOUT_MS = 900;
|
|
3439
|
-
var INTERACTIVE_SELECTOR = [
|
|
3440
|
-
"button",
|
|
3441
|
-
'[role="button"]',
|
|
3442
|
-
'[role="link"]',
|
|
3443
|
-
'[role="menuitem"]',
|
|
3444
|
-
'[role="tab"]',
|
|
3445
|
-
'[role="switch"]',
|
|
3446
|
-
'[role="checkbox"]',
|
|
3447
|
-
"a[href]",
|
|
3448
|
-
"label",
|
|
3449
|
-
"input",
|
|
3450
|
-
"textarea",
|
|
3451
|
-
"select",
|
|
3452
|
-
"summary",
|
|
3453
|
-
'[contenteditable="true"]',
|
|
3454
|
-
'[tabindex]:not([tabindex="-1"])'
|
|
3455
|
-
].join(",");
|
|
3456
|
-
var EDITABLE_SELECTOR = [
|
|
3457
|
-
"input",
|
|
3458
|
-
"textarea",
|
|
3459
|
-
'[contenteditable="true"]'
|
|
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("|");
|
|
3489
3439
|
var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
3490
3440
|
var resolveViewport = (page) => page?.viewportSize?.() || { width: 390, height: 844 };
|
|
3491
3441
|
var describeTarget = (target) => {
|
|
@@ -3525,47 +3475,7 @@ var withTimeout = async (operation, timeoutMs, label) => {
|
|
|
3525
3475
|
}
|
|
3526
3476
|
};
|
|
3527
3477
|
var checkElementVisibility = async (element) => {
|
|
3528
|
-
return element.evaluate((el
|
|
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
|
-
};
|
|
3478
|
+
return element.evaluate((el) => {
|
|
3569
3479
|
const targetStyle = window.getComputedStyle(el);
|
|
3570
3480
|
if (!targetStyle || targetStyle.display === "none" || targetStyle.visibility === "hidden" || targetStyle.visibility === "collapse") {
|
|
3571
3481
|
return { code: "NOT_INTERACTABLE", reason: "\u5143\u7D20\u4E0D\u53EF\u89C1", direction: "down" };
|
|
@@ -3627,13 +3537,30 @@ var checkElementVisibility = async (element) => {
|
|
|
3627
3537
|
positioning
|
|
3628
3538
|
};
|
|
3629
3539
|
}
|
|
3630
|
-
const
|
|
3631
|
-
const
|
|
3540
|
+
const isRootNode = (node) => !node || node === document || node === document.body || node === document.documentElement;
|
|
3541
|
+
const commonAncestor = (a, b) => {
|
|
3542
|
+
for (let current = a; current && !isRootNode(current); current = current.parentElement) {
|
|
3543
|
+
if (current.contains(b)) return current;
|
|
3544
|
+
}
|
|
3545
|
+
return null;
|
|
3546
|
+
};
|
|
3547
|
+
const sameTapTarget = (pointElement) => {
|
|
3632
3548
|
if (!pointElement) return false;
|
|
3633
3549
|
if (pointElement === el || el.contains(pointElement) || pointElement.contains(el)) {
|
|
3634
3550
|
return true;
|
|
3635
3551
|
}
|
|
3636
|
-
|
|
3552
|
+
const common = commonAncestor(el, pointElement);
|
|
3553
|
+
if (!common) return false;
|
|
3554
|
+
const commonRect = common.getBoundingClientRect?.();
|
|
3555
|
+
if (!commonRect || commonRect.width <= 0 || commonRect.height <= 0) return false;
|
|
3556
|
+
const commonArea = commonRect.width * commonRect.height;
|
|
3557
|
+
const targetArea = Math.max(1, rect.width * rect.height);
|
|
3558
|
+
const maxSharedRegionArea = Math.max(targetArea * 12, 4096);
|
|
3559
|
+
if (commonArea > maxSharedRegionArea) return false;
|
|
3560
|
+
if (commonRect.width > Math.max(rect.width * 8, 120) || commonRect.height > Math.max(rect.height * 8, 120)) {
|
|
3561
|
+
return false;
|
|
3562
|
+
}
|
|
3563
|
+
return common.contains(el) && common.contains(pointElement);
|
|
3637
3564
|
};
|
|
3638
3565
|
const describeElement = (node) => {
|
|
3639
3566
|
if (!node) return null;
|
|
@@ -3662,7 +3589,7 @@ var checkElementVisibility = async (element) => {
|
|
|
3662
3589
|
let obstruction = null;
|
|
3663
3590
|
for (const point of samplePoints) {
|
|
3664
3591
|
const pointElement = document.elementFromPoint(point.x, point.y);
|
|
3665
|
-
if (
|
|
3592
|
+
if (sameTapTarget(pointElement)) {
|
|
3666
3593
|
return { code: "VISIBLE", isFixed, positioning };
|
|
3667
3594
|
}
|
|
3668
3595
|
obstruction = obstruction || describeElement(pointElement);
|
|
@@ -3680,53 +3607,10 @@ var checkElementVisibility = async (element) => {
|
|
|
3680
3607
|
};
|
|
3681
3608
|
}
|
|
3682
3609
|
return { code: "VISIBLE", isFixed, positioning };
|
|
3683
|
-
}, {
|
|
3684
|
-
interactiveSelector: INTERACTIVE_SELECTOR,
|
|
3685
|
-
interactiveHintPattern: INTERACTIVE_HINT_PATTERN
|
|
3686
3610
|
});
|
|
3687
3611
|
};
|
|
3688
3612
|
var resolveSafeTapPoint = async (element) => {
|
|
3689
|
-
return element.evaluate((el
|
|
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
|
-
};
|
|
3613
|
+
return element.evaluate((el) => {
|
|
3730
3614
|
const rect = el.getBoundingClientRect();
|
|
3731
3615
|
if (!rect || rect.width <= 0 || rect.height <= 0) {
|
|
3732
3616
|
return null;
|
|
@@ -3763,13 +3647,30 @@ var resolveSafeTapPoint = async (element) => {
|
|
|
3763
3647
|
if (visibleWidth <= 1 || visibleHeight <= 1) {
|
|
3764
3648
|
return null;
|
|
3765
3649
|
}
|
|
3766
|
-
const
|
|
3767
|
-
const
|
|
3650
|
+
const isRootNode = (node) => !node || node === document || node === document.body || node === document.documentElement;
|
|
3651
|
+
const commonAncestor = (a, b) => {
|
|
3652
|
+
for (let current = a; current && !isRootNode(current); current = current.parentElement) {
|
|
3653
|
+
if (current.contains(b)) return current;
|
|
3654
|
+
}
|
|
3655
|
+
return null;
|
|
3656
|
+
};
|
|
3657
|
+
const sameTapTarget = (pointElement) => {
|
|
3768
3658
|
if (!pointElement) return false;
|
|
3769
3659
|
if (pointElement === el || el.contains(pointElement) || pointElement.contains(el)) {
|
|
3770
3660
|
return true;
|
|
3771
3661
|
}
|
|
3772
|
-
|
|
3662
|
+
const common = commonAncestor(el, pointElement);
|
|
3663
|
+
if (!common) return false;
|
|
3664
|
+
const commonRect = common.getBoundingClientRect?.();
|
|
3665
|
+
if (!commonRect || commonRect.width <= 0 || commonRect.height <= 0) return false;
|
|
3666
|
+
const commonArea = commonRect.width * commonRect.height;
|
|
3667
|
+
const targetArea = Math.max(1, rect.width * rect.height);
|
|
3668
|
+
const maxSharedRegionArea = Math.max(targetArea * 12, 4096);
|
|
3669
|
+
if (commonArea > maxSharedRegionArea) return false;
|
|
3670
|
+
if (commonRect.width > Math.max(rect.width * 8, 120) || commonRect.height > Math.max(rect.height * 8, 120)) {
|
|
3671
|
+
return false;
|
|
3672
|
+
}
|
|
3673
|
+
return common.contains(el) && common.contains(pointElement);
|
|
3773
3674
|
};
|
|
3774
3675
|
const cx = visibleLeft + visibleWidth / 2;
|
|
3775
3676
|
const cy = visibleTop + visibleHeight / 2;
|
|
@@ -3788,7 +3689,7 @@ var resolveSafeTapPoint = async (element) => {
|
|
|
3788
3689
|
];
|
|
3789
3690
|
const safePoints = points.filter((point) => {
|
|
3790
3691
|
const pointElement = document.elementFromPoint(point.x, point.y);
|
|
3791
|
-
return
|
|
3692
|
+
return sameTapTarget(pointElement);
|
|
3792
3693
|
});
|
|
3793
3694
|
const candidates = safePoints.length ? safePoints : points;
|
|
3794
3695
|
const chosen = candidates[Math.floor(Math.random() * candidates.length)];
|
|
@@ -3797,86 +3698,57 @@ var resolveSafeTapPoint = async (element) => {
|
|
|
3797
3698
|
x: chosen.x,
|
|
3798
3699
|
y: chosen.y
|
|
3799
3700
|
};
|
|
3800
|
-
}, {
|
|
3801
|
-
interactiveSelector: INTERACTIVE_SELECTOR,
|
|
3802
|
-
interactiveHintPattern: INTERACTIVE_HINT_PATTERN
|
|
3803
3701
|
});
|
|
3804
3702
|
};
|
|
3805
3703
|
var activateElementFallback = async (element, point = null, options = {}) => {
|
|
3806
|
-
return element.evaluate((el, {
|
|
3807
|
-
const
|
|
3808
|
-
|
|
3809
|
-
if (
|
|
3810
|
-
if (
|
|
3811
|
-
if (node
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
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;
|
|
3704
|
+
return element.evaluate((el, { innerOptions }) => {
|
|
3705
|
+
const isEditable = (node) => {
|
|
3706
|
+
if (!node || node.nodeType !== Node.ELEMENT_NODE) return false;
|
|
3707
|
+
if (node.isContentEditable) return true;
|
|
3708
|
+
if (node instanceof HTMLTextAreaElement) return !node.disabled && !node.readOnly;
|
|
3709
|
+
if (node instanceof HTMLInputElement) {
|
|
3710
|
+
return !node.disabled && !node.readOnly && typeof node.select === "function";
|
|
3711
|
+
}
|
|
3712
|
+
return false;
|
|
3834
3713
|
};
|
|
3835
|
-
const
|
|
3836
|
-
const nearestInteractive = (node) => {
|
|
3837
|
-
let best = null;
|
|
3838
|
-
let bestScore = 0;
|
|
3714
|
+
const findEditable = (node) => {
|
|
3839
3715
|
for (let current = node; current && current !== document.body; current = current.parentElement) {
|
|
3840
|
-
|
|
3841
|
-
if (score > bestScore || score > 0 && score === bestScore) {
|
|
3842
|
-
best = current;
|
|
3843
|
-
bestScore = score;
|
|
3844
|
-
}
|
|
3716
|
+
if (isEditable(current)) return current;
|
|
3845
3717
|
}
|
|
3846
|
-
return
|
|
3718
|
+
return null;
|
|
3847
3719
|
};
|
|
3848
|
-
const
|
|
3849
|
-
const pointInteractive = nearestInteractive(pointElement);
|
|
3850
|
-
let target = null;
|
|
3851
|
-
if (pointInteractive && (pointInteractive === targetInteractive || pointInteractive === el || pointInteractive.contains(el) || el.contains(pointInteractive))) {
|
|
3852
|
-
target = pointInteractive;
|
|
3853
|
-
}
|
|
3854
|
-
target = target || targetInteractive || el;
|
|
3855
|
-
const editable = typeof target.closest === "function" ? target.closest(editableSelector) : null;
|
|
3720
|
+
const editable = findEditable(el);
|
|
3856
3721
|
if (editable && typeof editable.focus === "function") {
|
|
3857
3722
|
editable.focus({ preventScroll: true });
|
|
3858
3723
|
if (innerOptions.editableOnly) {
|
|
3859
3724
|
return { activated: true, method: "focus", tag: editable.tagName || "" };
|
|
3860
3725
|
}
|
|
3861
3726
|
}
|
|
3862
|
-
if (
|
|
3863
|
-
|
|
3727
|
+
if (innerOptions.editableOnly) {
|
|
3728
|
+
return { activated: false, method: "none", tag: el?.tagName || "" };
|
|
3864
3729
|
}
|
|
3865
|
-
if (
|
|
3866
|
-
|
|
3867
|
-
|
|
3730
|
+
if (typeof el.focus === "function") {
|
|
3731
|
+
el.focus({ preventScroll: true });
|
|
3732
|
+
}
|
|
3733
|
+
if (typeof el.click === "function") {
|
|
3734
|
+
el.click();
|
|
3735
|
+
return { activated: true, method: "dom-click", tag: el.tagName || "" };
|
|
3736
|
+
}
|
|
3737
|
+
if (typeof el.dispatchEvent === "function") {
|
|
3738
|
+
el.dispatchEvent(new MouseEvent("click", {
|
|
3739
|
+
bubbles: true,
|
|
3740
|
+
cancelable: true,
|
|
3741
|
+
view: window
|
|
3742
|
+
}));
|
|
3743
|
+
return { activated: true, method: "dispatch-click", tag: el.tagName || "" };
|
|
3868
3744
|
}
|
|
3869
3745
|
return {
|
|
3870
3746
|
activated: Boolean(editable),
|
|
3871
3747
|
method: editable ? "focus" : "none",
|
|
3872
|
-
tag:
|
|
3748
|
+
tag: el?.tagName || ""
|
|
3873
3749
|
};
|
|
3874
3750
|
}, {
|
|
3875
|
-
|
|
3876
|
-
innerOptions: options || {},
|
|
3877
|
-
interactiveSelector: INTERACTIVE_SELECTOR,
|
|
3878
|
-
editableSelector: EDITABLE_SELECTOR,
|
|
3879
|
-
interactiveHintPattern: INTERACTIVE_HINT_PATTERN
|
|
3751
|
+
innerOptions: options || {}
|
|
3880
3752
|
});
|
|
3881
3753
|
};
|
|
3882
3754
|
var getScrollableRect = async (element) => {
|