Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Mouse wheel or page.scroll #1115

Closed
jperl opened this issue Feb 26, 2020 · 18 comments
Closed

[Feature] Mouse wheel or page.scroll #1115

jperl opened this issue Feb 26, 2020 · 18 comments

Comments

@jperl
Copy link
Contributor

jperl commented Feb 26, 2020

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.

@dgozman
Copy link
Contributor

dgozman commented Feb 27, 2020

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

@jperl
Copy link
Contributor Author

jperl commented Feb 28, 2020

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.

@dgozman
Copy link
Contributor

dgozman commented Feb 28, 2020

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?

@jperl
Copy link
Contributor Author

jperl commented Feb 28, 2020

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.

@OlgaKuksa
Copy link

+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

@Tyriar
Copy link
Member

Tyriar commented Sep 10, 2020

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

@colemars
Copy link

colemars commented Sep 21, 2020

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);
};

@DJ-Glock
Copy link

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 :)

@yairEO
Copy link

yairEO commented Dec 27, 2020

I also need to test mouse wheel. I have <input type="range"> where the mouse wheel (over the input element) controls the value, and this is extremely important in the implementation of my component, where normal dragging the thumb is not sensitive enough, so wheel movement is sometimes prefered.

I would love to see support for simulating wheel event


This is my component, which I want to test the wheel event on:
https://github.com/yairEO/color-picker

@yifeikong
Copy link

Another workaround of page.scroll is to simply use page.keyboard.press("PageDown").

@devniel
Copy link

devniel commented Jul 9, 2021

+1 for this feature, especially for tables, when scrolling horizontally.

@etale-cohomology
Copy link

Without this feature how are we supposed to load dynamic content from websites that load content by scrolling down

@sergioariveros
Copy link

+1 We also need this to navigate inside a carousel

@racingcow
Copy link

+1 We need it to test zoom in/out of a map component.

@mxschmitt
Copy link
Member

Closing since landed in #8690

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

15 participants