@skrillex1224/playwright-toolkit 2.1.28 → 2.1.30
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 +36 -37
- package/dist/index.cjs.map +2 -2
- package/dist/index.js +36 -37
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -686,46 +686,19 @@ var Humanize = {
|
|
|
686
686
|
async humanScroll(page, target, options = {}) {
|
|
687
687
|
const { maxSteps = 25, minStep = 80, maxStep = 220 } = options;
|
|
688
688
|
const targetDesc = typeof target === "string" ? target : "ElementHandle";
|
|
689
|
-
logger4.debug(
|
|
689
|
+
logger4.debug(`humanScroll| target=${targetDesc}`);
|
|
690
690
|
let element;
|
|
691
691
|
if (typeof target === "string") {
|
|
692
692
|
element = await page.$(target);
|
|
693
693
|
if (!element) {
|
|
694
|
-
logger4.warn(
|
|
694
|
+
logger4.warn(`humanScroll| Element not found: ${target}`);
|
|
695
695
|
return { element: null, didScroll: false, restore: async () => {
|
|
696
696
|
} };
|
|
697
697
|
}
|
|
698
698
|
} else {
|
|
699
699
|
element = target;
|
|
700
700
|
}
|
|
701
|
-
|
|
702
|
-
const isScrollable = (node) => {
|
|
703
|
-
if (!node || node === document.body) return false;
|
|
704
|
-
const style = window.getComputedStyle(node);
|
|
705
|
-
const overflowY = style.overflowY || style.overflow;
|
|
706
|
-
return (overflowY === "auto" || overflowY === "scroll" || overflowY === "overlay") && node.scrollHeight > node.clientHeight + 1;
|
|
707
|
-
};
|
|
708
|
-
const rect = el.getBoundingClientRect();
|
|
709
|
-
if (!rect || rect.width === 0 || rect.height === 0) return true;
|
|
710
|
-
const inViewport = rect.top >= 0 && rect.bottom <= window.innerHeight;
|
|
711
|
-
if (!inViewport) return true;
|
|
712
|
-
let current = el.parentElement;
|
|
713
|
-
while (current) {
|
|
714
|
-
if (isScrollable(current)) {
|
|
715
|
-
const crect = current.getBoundingClientRect();
|
|
716
|
-
if (rect.top < crect.top || rect.bottom > crect.bottom) {
|
|
717
|
-
return true;
|
|
718
|
-
}
|
|
719
|
-
}
|
|
720
|
-
current = current.parentElement;
|
|
721
|
-
}
|
|
722
|
-
return false;
|
|
723
|
-
});
|
|
724
|
-
if (!needsScroll) {
|
|
725
|
-
logger4.debug("humanScroll", "Element already in view");
|
|
726
|
-
return { element, didScroll: false, restore: async () => {
|
|
727
|
-
} };
|
|
728
|
-
}
|
|
701
|
+
let didScroll = false;
|
|
729
702
|
const scrollStateHandle = await element.evaluateHandle((el) => {
|
|
730
703
|
const isScrollable = (node) => {
|
|
731
704
|
if (!node || node === document.body) return false;
|
|
@@ -771,9 +744,21 @@ var Humanize = {
|
|
|
771
744
|
}
|
|
772
745
|
const scrollingElement = document.scrollingElement || document.documentElement;
|
|
773
746
|
if (scrollingElement) scrollables.push(scrollingElement);
|
|
747
|
+
const cx = rect.left + rect.width / 2;
|
|
748
|
+
const cy = rect.top + rect.height / 2;
|
|
749
|
+
const viewH = window.innerHeight;
|
|
750
|
+
let isObstructed = false;
|
|
751
|
+
if (cy < 0 || cy > viewH) {
|
|
752
|
+
isObstructed = true;
|
|
753
|
+
} else {
|
|
754
|
+
const pointElement = document.elementFromPoint(cx, cy);
|
|
755
|
+
if (pointElement && !el.contains(pointElement) && !pointElement.contains(el)) {
|
|
756
|
+
isObstructed = true;
|
|
757
|
+
}
|
|
758
|
+
}
|
|
774
759
|
let target2 = null;
|
|
775
760
|
for (const container of scrollables) {
|
|
776
|
-
const crect = container === scrollingElement ? { top: 0, bottom:
|
|
761
|
+
const crect = container === scrollingElement ? { top: 0, bottom: viewH } : container.getBoundingClientRect();
|
|
777
762
|
if (rect.top < crect.top + 2) {
|
|
778
763
|
target2 = { container, direction: -1 };
|
|
779
764
|
break;
|
|
@@ -782,26 +767,40 @@ var Humanize = {
|
|
|
782
767
|
target2 = { container, direction: 1 };
|
|
783
768
|
break;
|
|
784
769
|
}
|
|
770
|
+
if (isObstructed) {
|
|
771
|
+
const containerCenter = (crect.top + crect.bottom) / 2;
|
|
772
|
+
const elementCenter = (rect.top + rect.bottom) / 2;
|
|
773
|
+
const forceDirection = elementCenter > containerCenter ? 1 : -1;
|
|
774
|
+
const canScroll = forceDirection === 1 ? container.scrollTop < container.scrollHeight - container.clientHeight : container.scrollTop > 0;
|
|
775
|
+
if (canScroll) {
|
|
776
|
+
target2 = { container, direction: forceDirection };
|
|
777
|
+
break;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
785
780
|
}
|
|
786
781
|
if (!target2) {
|
|
787
|
-
return { moved: false, inView:
|
|
782
|
+
return { moved: false, inView: !isObstructed };
|
|
788
783
|
}
|
|
789
784
|
const maxScroll = target2.container.scrollHeight - target2.container.clientHeight;
|
|
790
785
|
if (maxScroll <= 0) {
|
|
791
|
-
return { moved: false, inView:
|
|
786
|
+
return { moved: false, inView: !isObstructed };
|
|
792
787
|
}
|
|
793
788
|
const before = target2.container.scrollTop;
|
|
794
789
|
let next = before + target2.direction * stepPx;
|
|
795
790
|
if (next < 0) next = 0;
|
|
796
791
|
if (next > maxScroll) next = maxScroll;
|
|
797
|
-
if (next
|
|
798
|
-
return { moved: false, inView:
|
|
792
|
+
if (Math.abs(next - before) < 1) {
|
|
793
|
+
return { moved: false, inView: !isObstructed };
|
|
799
794
|
}
|
|
800
795
|
target2.container.scrollTop = next;
|
|
801
796
|
return { moved: true, inView: false };
|
|
802
797
|
}, step);
|
|
798
|
+
if (result.moved) didScroll = true;
|
|
803
799
|
if (result.inView) break;
|
|
804
|
-
if (!result.moved)
|
|
800
|
+
if (!result.moved && !result.inView) {
|
|
801
|
+
logger4.warn("humanScroll| Stuck: cannot scroll further but element still obstructed/hidden");
|
|
802
|
+
break;
|
|
803
|
+
}
|
|
805
804
|
await (0, import_delay2.default)(this.jitterMs(120, 0.4));
|
|
806
805
|
}
|
|
807
806
|
const restore = async () => {
|
|
@@ -833,7 +832,7 @@ var Humanize = {
|
|
|
833
832
|
}
|
|
834
833
|
};
|
|
835
834
|
logger4.success("humanScroll", "Scroll completed");
|
|
836
|
-
return { element, didScroll
|
|
835
|
+
return { element, didScroll, restore };
|
|
837
836
|
},
|
|
838
837
|
/**
|
|
839
838
|
* 人类化点击 - 使用 ghost-cursor 模拟人类鼠标移动轨迹并点击
|