@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 CHANGED
@@ -1 +1 @@
1
- {"version":"0.15.2-nightly-20261016073603"}
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
  };
@@ -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
- return page.mouse.wheel(deltaX, deltaY);
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
- // Hover first: it auto-waits for visibility on both target kinds, so the
358
- // immediate box read below observes a settled element.
359
- await asActionable(target).hover({ timeout });
360
- const box = await targetBoundingBox(target, timeout);
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-nightly-20261016073603",
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.21.2-nightly-20261016073603"
53
+ "e2e": ">=0.18.0 <1"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/node": "26.6.2",
57
- "e2e": "0.21.2-nightly-20261016073603",
57
+ "e2e": "0.21.2",
58
58
  "@types/pngjs": "6.0.5",
59
59
  "pngjs": "7.0.0",
60
60
  "typescript": "7.0.2",