@e2e-dev/web 0.15.2-nightly-20261016073603 → 0.15.2
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/.build.json +1 -1
- package/dist/browser.js +1 -0
- package/dist/observation.js +1 -0
- package/dist/support.js +45 -5
- package/package.json +3 -3
package/dist/.build.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"0.15.2
|
|
1
|
+
{"version":"0.15.2"}
|
package/dist/browser.js
CHANGED
|
@@ -237,6 +237,7 @@ export function createBrowserFixture(surface, context) {
|
|
|
237
237
|
url: response.url(),
|
|
238
238
|
status: response.status(),
|
|
239
239
|
headers: response.headers(),
|
|
240
|
+
// oxlint-disable-next-line e2e/no-unchecked-json -- public API: the caller names T, unknown by default
|
|
240
241
|
json: async () => JSON.parse(await text()),
|
|
241
242
|
text,
|
|
242
243
|
};
|
package/dist/observation.js
CHANGED
|
@@ -83,6 +83,7 @@ async function captureInto(deps, scope, stage, host, framePath, budget, signal)
|
|
|
83
83
|
return data;
|
|
84
84
|
}));
|
|
85
85
|
const decoded = typeof metadata === 'string'
|
|
86
|
+
// oxlint-disable-next-line e2e/no-unchecked-json -- page-reported metadata, as unchecked as the structured branch; only the ids and nodes alignment below is checked
|
|
86
87
|
? JSON.parse(metadata)
|
|
87
88
|
: metadata;
|
|
88
89
|
const { nodes, ids, truncated: walkTruncated } = decoded;
|
package/dist/support.js
CHANGED
|
@@ -316,7 +316,7 @@ export async function performViewportSwipe(page, direction, momentum) {
|
|
|
316
316
|
const viewport = await currentViewport(page);
|
|
317
317
|
const distance = swipeDistance(direction === 'up' || direction === 'down' ? viewport.height : viewport.width, momentum);
|
|
318
318
|
const [deltaX, deltaY] = wheelDelta(direction, distance);
|
|
319
|
-
|
|
319
|
+
await wheelRendered(page, deltaX, deltaY);
|
|
320
320
|
}
|
|
321
321
|
/**
|
|
322
322
|
* The browser truncates a fractional pointer coordinate, so a point composed
|
|
@@ -354,10 +354,16 @@ export async function performPointDrag(mouse, start, end, durationMs, signal) {
|
|
|
354
354
|
}
|
|
355
355
|
}
|
|
356
356
|
export async function performElementSwipe(target, direction, momentum, timeout) {
|
|
357
|
-
//
|
|
358
|
-
//
|
|
359
|
-
|
|
360
|
-
|
|
357
|
+
// A node the pointer already hovers takes the wheel where it is; one hit at
|
|
358
|
+
// its centre takes it there, at the box that hit test read; otherwise hover
|
|
359
|
+
// waits for it to be actionable, scrolls it into view, and reports whatever
|
|
360
|
+
// intercepts the pointer.
|
|
361
|
+
const aimed = await (target.kind === 'locator'
|
|
362
|
+
? target.locator.evaluate(wheelAim, undefined, { timeout })
|
|
363
|
+
: target.element.evaluate(wheelAim));
|
|
364
|
+
if (aimed.aim === 'blocked')
|
|
365
|
+
await asActionable(target).hover({ timeout });
|
|
366
|
+
const box = aimed.aim === 'blocked' ? await targetBoundingBox(target, timeout) : aimed.box;
|
|
361
367
|
if (box === null) {
|
|
362
368
|
throw new EngineError('NOT_ACTIONABLE', 'element has no visible bounding box', {
|
|
363
369
|
retryable: false,
|
|
@@ -366,7 +372,41 @@ export async function performElementSwipe(target, direction, momentum, timeout)
|
|
|
366
372
|
const distance = swipeDistance(direction === 'up' || direction === 'down' ? box.height : box.width, momentum);
|
|
367
373
|
const [deltaX, deltaY] = wheelDelta(direction, distance);
|
|
368
374
|
const page = await targetPage(target);
|
|
375
|
+
if (aimed.aim === 'centre')
|
|
376
|
+
await page.mouse.move(box.x + box.width / 2, box.y + box.height / 2);
|
|
377
|
+
await wheelRendered(page, deltaX, deltaY);
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Wheels the page and resolves once a frame rendered the scroll it caused.
|
|
381
|
+
* The scroll lands on the compositor and reaches script on the next frame, so
|
|
382
|
+
* a read right after a bare `mouse.wheel` can see the document it left. A
|
|
383
|
+
* hidden document renders no frames, so it resolves at once.
|
|
384
|
+
*/
|
|
385
|
+
async function wheelRendered(page, deltaX, deltaY) {
|
|
369
386
|
await page.mouse.wheel(deltaX, deltaY);
|
|
387
|
+
await page.evaluate(nextRenderedFrame);
|
|
388
|
+
}
|
|
389
|
+
/** Page-side: resolves after the next rendered frame, or at once in a hidden document. */
|
|
390
|
+
function nextRenderedFrame() {
|
|
391
|
+
if (document.visibilityState === 'hidden')
|
|
392
|
+
return Promise.resolve();
|
|
393
|
+
return new Promise((resolve) => requestAnimationFrame(() => window.setTimeout(resolve, 0)));
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Page-side: where a wheel reaches `element` in a top-level document, whose
|
|
397
|
+
* box is the page's: at the pointer when it already hovers the element, at
|
|
398
|
+
* its centre when the hit target there is the element or inside it, or
|
|
399
|
+
* `blocked` when neither holds.
|
|
400
|
+
*/
|
|
401
|
+
function wheelAim(element) {
|
|
402
|
+
if (window !== window.top || element.getClientRects().length === 0)
|
|
403
|
+
return { aim: 'blocked' };
|
|
404
|
+
const rect = element.getBoundingClientRect();
|
|
405
|
+
const box = { x: rect.x, y: rect.y, width: rect.width, height: rect.height };
|
|
406
|
+
if (element.matches(':hover'))
|
|
407
|
+
return { aim: 'pointer', box };
|
|
408
|
+
const hit = document.elementFromPoint(rect.x + rect.width / 2, rect.y + rect.height / 2);
|
|
409
|
+
return hit !== null && element.contains(hit) ? { aim: 'centre', box } : { aim: 'blocked' };
|
|
370
410
|
}
|
|
371
411
|
function swipeDistance(extent, momentum) {
|
|
372
412
|
const ratio = momentum === 'fast' ? 1.5 : momentum === 'slow' ? 0.75 : 0.5;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@e2e-dev/web",
|
|
3
|
-
"version": "0.15.2
|
|
3
|
+
"version": "0.15.2",
|
|
4
4
|
"description": "Web engine for e2e agentic end-to-end testing, built on Playwright",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"e2e",
|
|
@@ -50,11 +50,11 @@
|
|
|
50
50
|
"playwright-core": "1.64.0"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
|
-
"e2e": "0.
|
|
53
|
+
"e2e": ">=0.18.0 <1"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@types/node": "26.6.2",
|
|
57
|
-
"e2e": "0.21.2
|
|
57
|
+
"e2e": "0.21.2",
|
|
58
58
|
"@types/pngjs": "6.0.5",
|
|
59
59
|
"pngjs": "7.0.0",
|
|
60
60
|
"typescript": "7.0.2",
|