@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.js
CHANGED
|
@@ -3408,56 +3408,6 @@ var initializedPages = /* @__PURE__ */ new WeakSet();
|
|
|
3408
3408
|
var DEFAULT_TAP_TIMEOUT_MS = 2500;
|
|
3409
3409
|
var DEFAULT_MOUSE_TAP_FALLBACK_TIMEOUT_MS = 1200;
|
|
3410
3410
|
var DEFAULT_ACTIVATE_FALLBACK_TIMEOUT_MS = 900;
|
|
3411
|
-
var INTERACTIVE_SELECTOR = [
|
|
3412
|
-
"button",
|
|
3413
|
-
'[role="button"]',
|
|
3414
|
-
'[role="link"]',
|
|
3415
|
-
'[role="menuitem"]',
|
|
3416
|
-
'[role="tab"]',
|
|
3417
|
-
'[role="switch"]',
|
|
3418
|
-
'[role="checkbox"]',
|
|
3419
|
-
"a[href]",
|
|
3420
|
-
"label",
|
|
3421
|
-
"input",
|
|
3422
|
-
"textarea",
|
|
3423
|
-
"select",
|
|
3424
|
-
"summary",
|
|
3425
|
-
'[contenteditable="true"]',
|
|
3426
|
-
'[tabindex]:not([tabindex="-1"])'
|
|
3427
|
-
].join(",");
|
|
3428
|
-
var EDITABLE_SELECTOR = [
|
|
3429
|
-
"input",
|
|
3430
|
-
"textarea",
|
|
3431
|
-
'[contenteditable="true"]'
|
|
3432
|
-
].join(",");
|
|
3433
|
-
var INTERACTIVE_HINT_PATTERN = [
|
|
3434
|
-
"btn",
|
|
3435
|
-
"button",
|
|
3436
|
-
"send",
|
|
3437
|
-
"submit",
|
|
3438
|
-
"confirm",
|
|
3439
|
-
"cancel",
|
|
3440
|
-
"retry",
|
|
3441
|
-
"reload",
|
|
3442
|
-
"search",
|
|
3443
|
-
"copy",
|
|
3444
|
-
"share",
|
|
3445
|
-
"close",
|
|
3446
|
-
"more",
|
|
3447
|
-
"\u53D1\u9001",
|
|
3448
|
-
"\u63D0\u4EA4",
|
|
3449
|
-
"\u786E\u5B9A",
|
|
3450
|
-
"\u786E\u8BA4",
|
|
3451
|
-
"\u53D6\u6D88",
|
|
3452
|
-
"\u91CD\u8BD5",
|
|
3453
|
-
"\u641C\u7D22",
|
|
3454
|
-
"\u590D\u5236",
|
|
3455
|
-
"\u5206\u4EAB",
|
|
3456
|
-
"\u5173\u95ED",
|
|
3457
|
-
"\u66F4\u591A",
|
|
3458
|
-
"\u5C55\u5F00",
|
|
3459
|
-
"\u6536\u8D77"
|
|
3460
|
-
].join("|");
|
|
3461
3411
|
var clamp = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
3462
3412
|
var resolveViewport = (page) => page?.viewportSize?.() || { width: 390, height: 844 };
|
|
3463
3413
|
var describeTarget = (target) => {
|
|
@@ -3497,47 +3447,7 @@ var withTimeout = async (operation, timeoutMs, label) => {
|
|
|
3497
3447
|
}
|
|
3498
3448
|
};
|
|
3499
3449
|
var checkElementVisibility = async (element) => {
|
|
3500
|
-
return element.evaluate((el
|
|
3501
|
-
const interactiveHintRe = new RegExp(interactiveHintPattern, "i");
|
|
3502
|
-
const nodeClassName = (node) => {
|
|
3503
|
-
if (!node) return "";
|
|
3504
|
-
if (typeof node.className === "string") return node.className;
|
|
3505
|
-
if (node.className && typeof node.className.baseVal === "string") return node.className.baseVal;
|
|
3506
|
-
return "";
|
|
3507
|
-
};
|
|
3508
|
-
const interactiveScore = (node) => {
|
|
3509
|
-
if (!node || node.nodeType !== Node.ELEMENT_NODE) return 0;
|
|
3510
|
-
let score = 0;
|
|
3511
|
-
if (typeof node.matches === "function" && node.matches(interactiveSelector)) score += 8;
|
|
3512
|
-
const hints = [
|
|
3513
|
-
node.id || "",
|
|
3514
|
-
nodeClassName(node),
|
|
3515
|
-
node.getAttribute?.("aria-label") || "",
|
|
3516
|
-
node.getAttribute?.("title") || "",
|
|
3517
|
-
node.getAttribute?.("data-testid") || "",
|
|
3518
|
-
node.getAttribute?.("data-test") || "",
|
|
3519
|
-
node.getAttribute?.("data-click") || "",
|
|
3520
|
-
node.getAttribute?.("data-action") || "",
|
|
3521
|
-
node.getAttribute?.("onclick") || "",
|
|
3522
|
-
String(node.textContent || "").trim().slice(0, 24)
|
|
3523
|
-
].join(" ");
|
|
3524
|
-
if (interactiveHintRe.test(hints)) score += 4;
|
|
3525
|
-
const style = window.getComputedStyle(node);
|
|
3526
|
-
if (style?.cursor === "pointer") score += 2;
|
|
3527
|
-
return score;
|
|
3528
|
-
};
|
|
3529
|
-
const closestInteractive = (node) => {
|
|
3530
|
-
let best = null;
|
|
3531
|
-
let bestScore = 0;
|
|
3532
|
-
for (let current = node; current && current !== document.body; current = current.parentElement) {
|
|
3533
|
-
const score = interactiveScore(current);
|
|
3534
|
-
if (score > bestScore || score > 0 && score === bestScore) {
|
|
3535
|
-
best = current;
|
|
3536
|
-
bestScore = score;
|
|
3537
|
-
}
|
|
3538
|
-
}
|
|
3539
|
-
return best;
|
|
3540
|
-
};
|
|
3450
|
+
return element.evaluate((el) => {
|
|
3541
3451
|
const targetStyle = window.getComputedStyle(el);
|
|
3542
3452
|
if (!targetStyle || targetStyle.display === "none" || targetStyle.visibility === "hidden" || targetStyle.visibility === "collapse") {
|
|
3543
3453
|
return { code: "NOT_INTERACTABLE", reason: "\u5143\u7D20\u4E0D\u53EF\u89C1", direction: "down" };
|
|
@@ -3599,13 +3509,30 @@ var checkElementVisibility = async (element) => {
|
|
|
3599
3509
|
positioning
|
|
3600
3510
|
};
|
|
3601
3511
|
}
|
|
3602
|
-
const
|
|
3603
|
-
const
|
|
3512
|
+
const isRootNode = (node) => !node || node === document || node === document.body || node === document.documentElement;
|
|
3513
|
+
const commonAncestor = (a, b) => {
|
|
3514
|
+
for (let current = a; current && !isRootNode(current); current = current.parentElement) {
|
|
3515
|
+
if (current.contains(b)) return current;
|
|
3516
|
+
}
|
|
3517
|
+
return null;
|
|
3518
|
+
};
|
|
3519
|
+
const sameTapTarget = (pointElement) => {
|
|
3604
3520
|
if (!pointElement) return false;
|
|
3605
3521
|
if (pointElement === el || el.contains(pointElement) || pointElement.contains(el)) {
|
|
3606
3522
|
return true;
|
|
3607
3523
|
}
|
|
3608
|
-
|
|
3524
|
+
const common = commonAncestor(el, pointElement);
|
|
3525
|
+
if (!common) return false;
|
|
3526
|
+
const commonRect = common.getBoundingClientRect?.();
|
|
3527
|
+
if (!commonRect || commonRect.width <= 0 || commonRect.height <= 0) return false;
|
|
3528
|
+
const commonArea = commonRect.width * commonRect.height;
|
|
3529
|
+
const targetArea = Math.max(1, rect.width * rect.height);
|
|
3530
|
+
const maxSharedRegionArea = Math.max(targetArea * 12, 4096);
|
|
3531
|
+
if (commonArea > maxSharedRegionArea) return false;
|
|
3532
|
+
if (commonRect.width > Math.max(rect.width * 8, 120) || commonRect.height > Math.max(rect.height * 8, 120)) {
|
|
3533
|
+
return false;
|
|
3534
|
+
}
|
|
3535
|
+
return common.contains(el) && common.contains(pointElement);
|
|
3609
3536
|
};
|
|
3610
3537
|
const describeElement = (node) => {
|
|
3611
3538
|
if (!node) return null;
|
|
@@ -3634,7 +3561,7 @@ var checkElementVisibility = async (element) => {
|
|
|
3634
3561
|
let obstruction = null;
|
|
3635
3562
|
for (const point of samplePoints) {
|
|
3636
3563
|
const pointElement = document.elementFromPoint(point.x, point.y);
|
|
3637
|
-
if (
|
|
3564
|
+
if (sameTapTarget(pointElement)) {
|
|
3638
3565
|
return { code: "VISIBLE", isFixed, positioning };
|
|
3639
3566
|
}
|
|
3640
3567
|
obstruction = obstruction || describeElement(pointElement);
|
|
@@ -3652,53 +3579,10 @@ var checkElementVisibility = async (element) => {
|
|
|
3652
3579
|
};
|
|
3653
3580
|
}
|
|
3654
3581
|
return { code: "VISIBLE", isFixed, positioning };
|
|
3655
|
-
}, {
|
|
3656
|
-
interactiveSelector: INTERACTIVE_SELECTOR,
|
|
3657
|
-
interactiveHintPattern: INTERACTIVE_HINT_PATTERN
|
|
3658
3582
|
});
|
|
3659
3583
|
};
|
|
3660
3584
|
var resolveSafeTapPoint = async (element) => {
|
|
3661
|
-
return element.evaluate((el
|
|
3662
|
-
const interactiveHintRe = new RegExp(interactiveHintPattern, "i");
|
|
3663
|
-
const nodeClassName = (node) => {
|
|
3664
|
-
if (!node) return "";
|
|
3665
|
-
if (typeof node.className === "string") return node.className;
|
|
3666
|
-
if (node.className && typeof node.className.baseVal === "string") return node.className.baseVal;
|
|
3667
|
-
return "";
|
|
3668
|
-
};
|
|
3669
|
-
const interactiveScore = (node) => {
|
|
3670
|
-
if (!node || node.nodeType !== Node.ELEMENT_NODE) return 0;
|
|
3671
|
-
let score = 0;
|
|
3672
|
-
if (typeof node.matches === "function" && node.matches(interactiveSelector)) score += 8;
|
|
3673
|
-
const hints = [
|
|
3674
|
-
node.id || "",
|
|
3675
|
-
nodeClassName(node),
|
|
3676
|
-
node.getAttribute?.("aria-label") || "",
|
|
3677
|
-
node.getAttribute?.("title") || "",
|
|
3678
|
-
node.getAttribute?.("data-testid") || "",
|
|
3679
|
-
node.getAttribute?.("data-test") || "",
|
|
3680
|
-
node.getAttribute?.("data-click") || "",
|
|
3681
|
-
node.getAttribute?.("data-action") || "",
|
|
3682
|
-
node.getAttribute?.("onclick") || "",
|
|
3683
|
-
String(node.textContent || "").trim().slice(0, 24)
|
|
3684
|
-
].join(" ");
|
|
3685
|
-
if (interactiveHintRe.test(hints)) score += 4;
|
|
3686
|
-
const style = window.getComputedStyle(node);
|
|
3687
|
-
if (style?.cursor === "pointer") score += 2;
|
|
3688
|
-
return score;
|
|
3689
|
-
};
|
|
3690
|
-
const closestInteractive = (node) => {
|
|
3691
|
-
let best = null;
|
|
3692
|
-
let bestScore = 0;
|
|
3693
|
-
for (let current = node; current && current !== document.body; current = current.parentElement) {
|
|
3694
|
-
const score = interactiveScore(current);
|
|
3695
|
-
if (score > bestScore || score > 0 && score === bestScore) {
|
|
3696
|
-
best = current;
|
|
3697
|
-
bestScore = score;
|
|
3698
|
-
}
|
|
3699
|
-
}
|
|
3700
|
-
return best;
|
|
3701
|
-
};
|
|
3585
|
+
return element.evaluate((el) => {
|
|
3702
3586
|
const rect = el.getBoundingClientRect();
|
|
3703
3587
|
if (!rect || rect.width <= 0 || rect.height <= 0) {
|
|
3704
3588
|
return null;
|
|
@@ -3735,13 +3619,30 @@ var resolveSafeTapPoint = async (element) => {
|
|
|
3735
3619
|
if (visibleWidth <= 1 || visibleHeight <= 1) {
|
|
3736
3620
|
return null;
|
|
3737
3621
|
}
|
|
3738
|
-
const
|
|
3739
|
-
const
|
|
3622
|
+
const isRootNode = (node) => !node || node === document || node === document.body || node === document.documentElement;
|
|
3623
|
+
const commonAncestor = (a, b) => {
|
|
3624
|
+
for (let current = a; current && !isRootNode(current); current = current.parentElement) {
|
|
3625
|
+
if (current.contains(b)) return current;
|
|
3626
|
+
}
|
|
3627
|
+
return null;
|
|
3628
|
+
};
|
|
3629
|
+
const sameTapTarget = (pointElement) => {
|
|
3740
3630
|
if (!pointElement) return false;
|
|
3741
3631
|
if (pointElement === el || el.contains(pointElement) || pointElement.contains(el)) {
|
|
3742
3632
|
return true;
|
|
3743
3633
|
}
|
|
3744
|
-
|
|
3634
|
+
const common = commonAncestor(el, pointElement);
|
|
3635
|
+
if (!common) return false;
|
|
3636
|
+
const commonRect = common.getBoundingClientRect?.();
|
|
3637
|
+
if (!commonRect || commonRect.width <= 0 || commonRect.height <= 0) return false;
|
|
3638
|
+
const commonArea = commonRect.width * commonRect.height;
|
|
3639
|
+
const targetArea = Math.max(1, rect.width * rect.height);
|
|
3640
|
+
const maxSharedRegionArea = Math.max(targetArea * 12, 4096);
|
|
3641
|
+
if (commonArea > maxSharedRegionArea) return false;
|
|
3642
|
+
if (commonRect.width > Math.max(rect.width * 8, 120) || commonRect.height > Math.max(rect.height * 8, 120)) {
|
|
3643
|
+
return false;
|
|
3644
|
+
}
|
|
3645
|
+
return common.contains(el) && common.contains(pointElement);
|
|
3745
3646
|
};
|
|
3746
3647
|
const cx = visibleLeft + visibleWidth / 2;
|
|
3747
3648
|
const cy = visibleTop + visibleHeight / 2;
|
|
@@ -3760,7 +3661,7 @@ var resolveSafeTapPoint = async (element) => {
|
|
|
3760
3661
|
];
|
|
3761
3662
|
const safePoints = points.filter((point) => {
|
|
3762
3663
|
const pointElement = document.elementFromPoint(point.x, point.y);
|
|
3763
|
-
return
|
|
3664
|
+
return sameTapTarget(pointElement);
|
|
3764
3665
|
});
|
|
3765
3666
|
const candidates = safePoints.length ? safePoints : points;
|
|
3766
3667
|
const chosen = candidates[Math.floor(Math.random() * candidates.length)];
|
|
@@ -3769,86 +3670,57 @@ var resolveSafeTapPoint = async (element) => {
|
|
|
3769
3670
|
x: chosen.x,
|
|
3770
3671
|
y: chosen.y
|
|
3771
3672
|
};
|
|
3772
|
-
}, {
|
|
3773
|
-
interactiveSelector: INTERACTIVE_SELECTOR,
|
|
3774
|
-
interactiveHintPattern: INTERACTIVE_HINT_PATTERN
|
|
3775
3673
|
});
|
|
3776
3674
|
};
|
|
3777
3675
|
var activateElementFallback = async (element, point = null, options = {}) => {
|
|
3778
|
-
return element.evaluate((el, {
|
|
3779
|
-
const
|
|
3780
|
-
|
|
3781
|
-
if (
|
|
3782
|
-
if (
|
|
3783
|
-
if (node
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
if (!node || node.nodeType !== Node.ELEMENT_NODE) return 0;
|
|
3788
|
-
let score = 0;
|
|
3789
|
-
if (typeof node.matches === "function" && node.matches(interactiveSelector)) score += 8;
|
|
3790
|
-
const hints = [
|
|
3791
|
-
node.id || "",
|
|
3792
|
-
nodeClassName(node),
|
|
3793
|
-
node.getAttribute?.("aria-label") || "",
|
|
3794
|
-
node.getAttribute?.("title") || "",
|
|
3795
|
-
node.getAttribute?.("data-testid") || "",
|
|
3796
|
-
node.getAttribute?.("data-test") || "",
|
|
3797
|
-
node.getAttribute?.("data-click") || "",
|
|
3798
|
-
node.getAttribute?.("data-action") || "",
|
|
3799
|
-
node.getAttribute?.("onclick") || "",
|
|
3800
|
-
String(node.textContent || "").trim().slice(0, 24)
|
|
3801
|
-
].join(" ");
|
|
3802
|
-
if (interactiveHintRe.test(hints)) score += 4;
|
|
3803
|
-
const style = window.getComputedStyle(node);
|
|
3804
|
-
if (style?.cursor === "pointer") score += 2;
|
|
3805
|
-
return score;
|
|
3676
|
+
return element.evaluate((el, { innerOptions }) => {
|
|
3677
|
+
const isEditable = (node) => {
|
|
3678
|
+
if (!node || node.nodeType !== Node.ELEMENT_NODE) return false;
|
|
3679
|
+
if (node.isContentEditable) return true;
|
|
3680
|
+
if (node instanceof HTMLTextAreaElement) return !node.disabled && !node.readOnly;
|
|
3681
|
+
if (node instanceof HTMLInputElement) {
|
|
3682
|
+
return !node.disabled && !node.readOnly && typeof node.select === "function";
|
|
3683
|
+
}
|
|
3684
|
+
return false;
|
|
3806
3685
|
};
|
|
3807
|
-
const
|
|
3808
|
-
const nearestInteractive = (node) => {
|
|
3809
|
-
let best = null;
|
|
3810
|
-
let bestScore = 0;
|
|
3686
|
+
const findEditable = (node) => {
|
|
3811
3687
|
for (let current = node; current && current !== document.body; current = current.parentElement) {
|
|
3812
|
-
|
|
3813
|
-
if (score > bestScore || score > 0 && score === bestScore) {
|
|
3814
|
-
best = current;
|
|
3815
|
-
bestScore = score;
|
|
3816
|
-
}
|
|
3688
|
+
if (isEditable(current)) return current;
|
|
3817
3689
|
}
|
|
3818
|
-
return
|
|
3690
|
+
return null;
|
|
3819
3691
|
};
|
|
3820
|
-
const
|
|
3821
|
-
const pointInteractive = nearestInteractive(pointElement);
|
|
3822
|
-
let target = null;
|
|
3823
|
-
if (pointInteractive && (pointInteractive === targetInteractive || pointInteractive === el || pointInteractive.contains(el) || el.contains(pointInteractive))) {
|
|
3824
|
-
target = pointInteractive;
|
|
3825
|
-
}
|
|
3826
|
-
target = target || targetInteractive || el;
|
|
3827
|
-
const editable = typeof target.closest === "function" ? target.closest(editableSelector) : null;
|
|
3692
|
+
const editable = findEditable(el);
|
|
3828
3693
|
if (editable && typeof editable.focus === "function") {
|
|
3829
3694
|
editable.focus({ preventScroll: true });
|
|
3830
3695
|
if (innerOptions.editableOnly) {
|
|
3831
3696
|
return { activated: true, method: "focus", tag: editable.tagName || "" };
|
|
3832
3697
|
}
|
|
3833
3698
|
}
|
|
3834
|
-
if (
|
|
3835
|
-
|
|
3699
|
+
if (innerOptions.editableOnly) {
|
|
3700
|
+
return { activated: false, method: "none", tag: el?.tagName || "" };
|
|
3836
3701
|
}
|
|
3837
|
-
if (
|
|
3838
|
-
|
|
3839
|
-
|
|
3702
|
+
if (typeof el.focus === "function") {
|
|
3703
|
+
el.focus({ preventScroll: true });
|
|
3704
|
+
}
|
|
3705
|
+
if (typeof el.click === "function") {
|
|
3706
|
+
el.click();
|
|
3707
|
+
return { activated: true, method: "dom-click", tag: el.tagName || "" };
|
|
3708
|
+
}
|
|
3709
|
+
if (typeof el.dispatchEvent === "function") {
|
|
3710
|
+
el.dispatchEvent(new MouseEvent("click", {
|
|
3711
|
+
bubbles: true,
|
|
3712
|
+
cancelable: true,
|
|
3713
|
+
view: window
|
|
3714
|
+
}));
|
|
3715
|
+
return { activated: true, method: "dispatch-click", tag: el.tagName || "" };
|
|
3840
3716
|
}
|
|
3841
3717
|
return {
|
|
3842
3718
|
activated: Boolean(editable),
|
|
3843
3719
|
method: editable ? "focus" : "none",
|
|
3844
|
-
tag:
|
|
3720
|
+
tag: el?.tagName || ""
|
|
3845
3721
|
};
|
|
3846
3722
|
}, {
|
|
3847
|
-
|
|
3848
|
-
innerOptions: options || {},
|
|
3849
|
-
interactiveSelector: INTERACTIVE_SELECTOR,
|
|
3850
|
-
editableSelector: EDITABLE_SELECTOR,
|
|
3851
|
-
interactiveHintPattern: INTERACTIVE_HINT_PATTERN
|
|
3723
|
+
innerOptions: options || {}
|
|
3852
3724
|
});
|
|
3853
3725
|
};
|
|
3854
3726
|
var getScrollableRect = async (element) => {
|