@skrillex1224/playwright-toolkit 2.1.243 → 2.1.244
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 +80 -8
- package/dist/index.cjs.map +2 -2
- package/dist/index.js +80 -8
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3830,6 +3830,47 @@ var scrollAwayFromObstruction = async (element, status) => {
|
|
|
3830
3830
|
};
|
|
3831
3831
|
}, status);
|
|
3832
3832
|
};
|
|
3833
|
+
var getElementViewportSnapshot = async (element) => {
|
|
3834
|
+
return element.evaluate((el) => {
|
|
3835
|
+
const rect = el.getBoundingClientRect();
|
|
3836
|
+
return {
|
|
3837
|
+
top: rect.top,
|
|
3838
|
+
bottom: rect.bottom,
|
|
3839
|
+
left: rect.left,
|
|
3840
|
+
right: rect.right,
|
|
3841
|
+
width: rect.width,
|
|
3842
|
+
height: rect.height,
|
|
3843
|
+
scrollX: window.scrollX,
|
|
3844
|
+
scrollY: window.scrollY
|
|
3845
|
+
};
|
|
3846
|
+
});
|
|
3847
|
+
};
|
|
3848
|
+
var isTargetImmobileAfterScroll = (before, after) => {
|
|
3849
|
+
if (!before || !after) return false;
|
|
3850
|
+
const rectDeltaY = Number(after.top || 0) - Number(before.top || 0);
|
|
3851
|
+
const rectDeltaX = Number(after.left || 0) - Number(before.left || 0);
|
|
3852
|
+
const scrollDeltaY = Number(after.scrollY || 0) - Number(before.scrollY || 0);
|
|
3853
|
+
const scrollDeltaX = Number(after.scrollX || 0) - Number(before.scrollX || 0);
|
|
3854
|
+
const rectMoved = Math.abs(rectDeltaY) > 3 || Math.abs(rectDeltaX) > 3;
|
|
3855
|
+
const pageMoved = Math.abs(scrollDeltaY) > 3 || Math.abs(scrollDeltaX) > 3;
|
|
3856
|
+
if (!rectMoved && !pageMoved) return true;
|
|
3857
|
+
if (pageMoved && !rectMoved) return true;
|
|
3858
|
+
if (Math.abs(scrollDeltaY) > 12 && Math.abs(rectDeltaY) < Math.min(12, Math.abs(scrollDeltaY) * 0.2)) {
|
|
3859
|
+
return true;
|
|
3860
|
+
}
|
|
3861
|
+
return false;
|
|
3862
|
+
};
|
|
3863
|
+
var restoreWindowFromSnapshot = async (page, before, after) => {
|
|
3864
|
+
if (!before || !after) return;
|
|
3865
|
+
if (Math.abs(Number(after.scrollX || 0) - Number(before.scrollX || 0)) <= 2 && Math.abs(Number(after.scrollY || 0) - Number(before.scrollY || 0)) <= 2) {
|
|
3866
|
+
return;
|
|
3867
|
+
}
|
|
3868
|
+
await page.evaluate(
|
|
3869
|
+
(state) => window.scrollTo(state.x, state.y),
|
|
3870
|
+
{ x: Number(before.scrollX || 0), y: Number(before.scrollY || 0) }
|
|
3871
|
+
).catch(() => {
|
|
3872
|
+
});
|
|
3873
|
+
};
|
|
3833
3874
|
var dispatchTouchSwipe = async (page, deltaY, options = {}) => {
|
|
3834
3875
|
const viewport = resolveViewport(page);
|
|
3835
3876
|
const rawRect = options.rect || null;
|
|
@@ -4010,11 +4051,11 @@ var MobileHumanize = {
|
|
|
4010
4051
|
const scrollRect = await getScrollableRect(element);
|
|
4011
4052
|
if (!scrollRect && status.isFixed && status.code === "OUT_OF_VIEWPORT") {
|
|
4012
4053
|
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"})`);
|
|
4013
|
-
return { element, didScroll, restore: null };
|
|
4054
|
+
return { element, didScroll, restore: null, unscrollable: true };
|
|
4014
4055
|
}
|
|
4015
4056
|
if (!scrollRect && status.isFixed && status.code === "OBSTRUCTED") {
|
|
4016
4057
|
logger7.warn(`humanScroll | fixed/sticky \u76EE\u6807\u88AB\u906E\u6321\uFF0C\u6EDA\u52A8\u65E0\u6CD5\u89E3\u9664 (${status.obstruction?.tag || "unknown"})`);
|
|
4017
|
-
return { element, didScroll, restore: null };
|
|
4058
|
+
return { element, didScroll, restore: null, unscrollable: true };
|
|
4018
4059
|
}
|
|
4019
4060
|
if (scrollRect && status.code === "OBSTRUCTED" && status.obstruction?.isFixed) {
|
|
4020
4061
|
const moved = await scrollAwayFromObstruction(element, status);
|
|
@@ -4045,6 +4086,7 @@ var MobileHumanize = {
|
|
|
4045
4086
|
}
|
|
4046
4087
|
}
|
|
4047
4088
|
const beforeWindowState = scrollRect ? await page.evaluate(() => ({ x: window.scrollX, y: window.scrollY })) : null;
|
|
4089
|
+
const beforeElementSnapshot = await getElementViewportSnapshot(element).catch(() => null);
|
|
4048
4090
|
const beforeState = scrollRect ? await element.evaluate((el) => {
|
|
4049
4091
|
const isScrollable = (node) => {
|
|
4050
4092
|
const style = window.getComputedStyle(node);
|
|
@@ -4074,6 +4116,21 @@ var MobileHumanize = {
|
|
|
4074
4116
|
logger7.debug(`humanScroll | \u7A97\u53E3\u6EDA\u52A8\u56DE\u6536 from=${Math.round(afterWindowState.y)} to=${Math.round(beforeWindowState.y)}`);
|
|
4075
4117
|
}
|
|
4076
4118
|
}
|
|
4119
|
+
let afterElementSnapshot = null;
|
|
4120
|
+
const readAfterElementSnapshot = async () => {
|
|
4121
|
+
if (!afterElementSnapshot) {
|
|
4122
|
+
afterElementSnapshot = await getElementViewportSnapshot(element).catch(() => null);
|
|
4123
|
+
}
|
|
4124
|
+
return afterElementSnapshot;
|
|
4125
|
+
};
|
|
4126
|
+
if (!scrollRect && beforeElementSnapshot) {
|
|
4127
|
+
const afterSnapshot = await readAfterElementSnapshot();
|
|
4128
|
+
if (isTargetImmobileAfterScroll(beforeElementSnapshot, afterSnapshot)) {
|
|
4129
|
+
await restoreWindowFromSnapshot(page, beforeElementSnapshot, afterSnapshot);
|
|
4130
|
+
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"})`);
|
|
4131
|
+
return { element, didScroll, restore: null, unscrollable: true };
|
|
4132
|
+
}
|
|
4133
|
+
}
|
|
4077
4134
|
if (scrollRect && beforeState) {
|
|
4078
4135
|
const afterState = await element.evaluate((el) => {
|
|
4079
4136
|
const isScrollable = (node) => {
|
|
@@ -4111,6 +4168,14 @@ var MobileHumanize = {
|
|
|
4111
4168
|
}
|
|
4112
4169
|
}
|
|
4113
4170
|
}
|
|
4171
|
+
if (scrollRect && beforeElementSnapshot) {
|
|
4172
|
+
const afterSnapshot = await getElementViewportSnapshot(element).catch(() => null);
|
|
4173
|
+
if (isTargetImmobileAfterScroll(beforeElementSnapshot, afterSnapshot)) {
|
|
4174
|
+
await restoreWindowFromSnapshot(page, beforeElementSnapshot, afterSnapshot);
|
|
4175
|
+
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"})`);
|
|
4176
|
+
return { element, didScroll, restore: null, unscrollable: true };
|
|
4177
|
+
}
|
|
4178
|
+
}
|
|
4114
4179
|
didScroll = true;
|
|
4115
4180
|
}
|
|
4116
4181
|
try {
|
|
@@ -4160,21 +4225,28 @@ var MobileHumanize = {
|
|
|
4160
4225
|
logger7.warn(`humanClick: \u5143\u7D20\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u70B9\u51FB ${targetDesc}`);
|
|
4161
4226
|
return false;
|
|
4162
4227
|
}
|
|
4163
|
-
|
|
4164
|
-
await MobileHumanize.humanScroll(page, element, { throwOnMissing });
|
|
4165
|
-
}
|
|
4228
|
+
const scrollResult = scrollIfNeeded ? await MobileHumanize.humanScroll(page, element, { throwOnMissing }) : null;
|
|
4166
4229
|
const status = await checkElementVisibility(element).catch(() => null);
|
|
4167
4230
|
if (status && status.code !== "VISIBLE") {
|
|
4168
|
-
if (fallbackDomClick && status.
|
|
4169
|
-
|
|
4231
|
+
if (fallbackDomClick && (status.code === "OUT_OF_VIEWPORT" || status.code === "OBSTRUCTED") && (status.isFixed || scrollResult?.unscrollable)) {
|
|
4232
|
+
let fallback = await withTimeout(
|
|
4170
4233
|
() => activateElementFallback(element, null, {
|
|
4171
4234
|
editableOnly: true
|
|
4172
4235
|
}),
|
|
4173
4236
|
activateFallbackTimeoutMs,
|
|
4174
4237
|
"focus fallback"
|
|
4175
4238
|
).catch(() => null);
|
|
4239
|
+
if (!fallback?.activated) {
|
|
4240
|
+
fallback = await withTimeout(
|
|
4241
|
+
() => activateElementFallback(element, null, {
|
|
4242
|
+
editableOnly: false
|
|
4243
|
+
}),
|
|
4244
|
+
activateFallbackTimeoutMs,
|
|
4245
|
+
"activation fallback"
|
|
4246
|
+
).catch(() => null);
|
|
4247
|
+
}
|
|
4176
4248
|
if (fallback?.activated) {
|
|
4177
|
-
logger7.warn(`humanClick:
|
|
4249
|
+
logger7.warn(`humanClick: \u4E0D\u53EF\u6EDA\u52A8\u76EE\u6807\u4E0D\u53EF\u7269\u7406\u70B9\u51FB\uFF0C\u5DF2\u7528 ${fallback.method} \u6FC0\u6D3B`);
|
|
4178
4250
|
return true;
|
|
4179
4251
|
}
|
|
4180
4252
|
}
|