Playwright: [Feature] Mouse wheel or page.scroll

Created on 26 Feb 2020  路  10Comments  路  Source: microsoft/playwright

It would be nice to have a cross browser way to test scrolling.

Ex. via CDP

await client.send("Input.dispatchMouseEvent", { type: "mouseWheel", deltaX: 0, deltaY: 500, x: 0, y: 0 });

For an auto-wait API, you could keep trying to scroll to a point and timeout if it cannot reach it.

P3-collecting-feedback

Most helpful comment

Definitely mouseWheel is very important feature. we have to have some well-known Official API way to handle with infinite scrolls when content will be downloaded dynamically when user reaches the end of the page

plus some quick-nav methods like

  • scrollPageToBottom
  • scrollPageToTop

https://codecept.io/helpers/Playwright/#scrollpagetobottom

+1 for API-native mouseWheel

All 10 comments

Could you share more about scenario? Are there scroll handlers? Why not use element.scrollIntoViewIfNeeded?

One use case is to test an infinite scroll component. Keep scrolling down in the x or y axis until the scrollLeft / scrollTop reaches a value.

Right now I am doing this with evaluate which works, I was just hoping to have a playwright API I could use.

I think this evaluate script is reasonable for now, because it matches the exact semantics you care about. If we were to introduce scrolling, it would be more like user interaction as you proposed (either a mouse wheel scroll or touchscreen/touchpad scroll gesture), and it's unclear how to "wait for completion" in this case.

For infinite lists, perhaps (await page.$('list-footer')).scrollIntoViewIfNeeded() could just work?

Sounds good, I have workarounds but will leave this issue open for a potential future API.

Right now I am using Input.dispatchMouseEvent when I need to test the user behavior. It would be nice to have a cross-browser playwright API like that. The problem with using Input.dispatchMouseEvent now is that I do not know when the scroll happens so I have an arbitrary wait. This is why an auto-waiting playwright api would be nice.

The way the auto-waiting could work is that it would resolve after the corresponding "scroll" was completed. If the scroll could not be completed (the page could not scroll that amount), it would throw an error.

Definitely mouseWheel is very important feature. we have to have some well-known Official API way to handle with infinite scrolls when content will be downloaded dynamically when user reaches the end of the page

plus some quick-nav methods like

  • scrollPageToBottom
  • scrollPageToTop

https://codecept.io/helpers/Playwright/#scrollpagetobottom

+1 for API-native mouseWheel

+1 for API-native mouseWheel or scroll to bottom
sample case - page.click() doesn't scroll to the element in the bottom of react-virtualized list of elements

it should be really awesome and i've been waiting for this feature very hard
but by the way could anyone of developers explain us what does "Native input events for mouse and keyboard" mean exactly?

are they really OS-native (putting mouse & keyboard like events into Browser's Window Procedure/Native Browser Event loop) or just emulated with some JS ?

ps. just cant found more appropriate place for this Q such as i'm asking playwright's devs personally to know exactly what "Native input" means here.

thx

I'd like this for xterm.js, I'm currently figuring out how to update our playwright private API usage that ensures wheel events get correctly serialized depending on the terminal mouse mode:

https://github.com/xtermjs/xterm.js/blob/4e18a78c02d0bcb5b97eeeb741d5e3c0b996cdc3/test/api/MouseTracking.api.ts#L77-L98

I think this evaluate script is reasonable for now, because it matches the exact semantics you care about. If we were to introduce scrolling, it would be more like user interaction as you proposed (either a mouse wheel scroll or touchscreen/touchpad scroll gesture), and it's unclear how to "wait for completion" in this case.

Perhaps a "Scroll element until some selector hits or timeout" behavior? That would likely be a solid solution for infinite lists.

Although my current solution seems to work rather fine with a bit of tweaking perhaps to get to a certain item within an infinite list. Below is just getting to the bottom.

  await page.waitForSelector('.row-item');
  const scrollToBottomOfInfiniteList = async prev => {
    const items = await page.$$('.row-item');
    const lastItemRendered = items[items.length - 1];
    const control = prev ?? await lastItemRendered.getAttribute('data-index');
    await lastItemRendered.scrollIntoViewIfNeeded();
    await page.waitForTimeout(100); // going straight to the next eval wasn't catching the newly rendered row items
    const experiment = await page.$$eval(
      '.row-item',
      els => els[els.length - 1].dataset.index // row-items have data-index attributes revealing their true index
    );
    if (control === experiment) return;
    await scrollToBottomOfInfiniteList(experiment);
  };
  await scrollToBottomOfInfiniteList();
  await page.waitForTimeout(15000);
};

I have another case when mouse wheel is required - zooming. I have a webpage where zooming in/out works only with Ctrl+Mouse Wheel. So there is not way to do it with scrollIntoViewIfNeeded :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

osmenia picture osmenia  路  4Comments

arjunattam picture arjunattam  路  4Comments

shirshak55 picture shirshak55  路  3Comments

kblok picture kblok  路  3Comments

wolf002 picture wolf002  路  3Comments