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

fix(page): fix Mouse.click method #7097

Merged
merged 2 commits into from Apr 19, 2021
Merged

fix(page): fix Mouse.click method #7097

merged 2 commits into from Apr 19, 2021

Conversation

ptommasi
Copy link
Contributor

page.click method relies on Mouse.click method for execution. Mouse.click triggers the move, down and up methods in parallel waiting for all of them to finish, when they should be called sequentially instead.

Issues: #6462 (related), #3347 (left a comment in it).

page.click method relies on Mouse.click method for execution. Mouse.click triggers the move, down and up methods in parallel waiting for all of them to finish, when they should be called sequentially instead (issues #6462, #3347).
@google-cla google-cla bot added the cla: yes label Apr 17, 2021
@mathiasbynens
Copy link
Member

Good catch!

@mathiasbynens mathiasbynens merged commit ba7c367 into puppeteer:main Apr 19, 2021
@ptommasi ptommasi deleted the fix-mouse-click branch April 19, 2021 08:07
@ptommasi
Copy link
Contributor Author

Branch deleted for clean up, big thanks for your work! :)

@ondrejvelisek
Copy link

It seems to me this fix could increas probability to unexpected buggy behaviour. Kind of race condition. Since click is not an atomic operation. There could be another external mouse.move call between mouse.move and mouse.down. In such case puppeteer would click on a unexpected and potentialy dangerous position. For example (but not exclusivley) in headful mode where user moves mouse over the screen manually. Am I wrong?

@ptommasi
Copy link
Contributor Author

For example (but not exclusivley) in headful mode where user moves mouse over the screen manually. Am I wrong?

I think you are indeed correct, but out of the two implementations (Promise.all vs sequential await) the latter is more predictable and much safer, in my opinion. Using the Promise.all implementation would not ensure that mouse down will happen before mouse up, and will not ensure that either of them will happen after the move.

As a consequence, page.click might be ignored (e.g. sequence ends up being up, move, down), it could cause a drag (e.g. down, move, up) or any other combination which is not move -> down -> up would cause a problem. In the issues I saw, people were complaining about the unpredictability of page.click, and Promise.all would definitely explain this type of behaviour.

My two cents is that is better to have an implementation that works most of the time and that is observable rather than an unpredictable one which could or could not work (as the issues demonstrated).

@ondrejvelisek
Copy link

Agree. It is definitely better this way.

Anyway it is fair to say and post it here for the future.

To fix it Chrome would need to implement some kind of atomic click operation or a way to send multiple sequential operations together within one call. Which what I know it is not able. Until then i'm afraid Puppeteer has no way to fix it.

@ptommasi
Copy link
Contributor Author

ptommasi commented May 28, 2021

To my understanding, page.click reason to exist is to simulate user behaviour by marking the click event as trusted (based on this comment). Single soft clicks can be still sent to the browser using page.evaluate, which is indeed what I still do at the moment (since I don't know exactly when the fix will be pushed in the deployed version, and the website I'm scraping doesn't seem to make a difference between trusted and untrusted events). For your use case, I suppose you could easily create a util function based on page.$eval(selector, (element) => element.click()) (or page.evaluate).

Disclaimer: I'm not a front-end developer, I'm not a puppeteer developer, I'm barely a developer, I used puppeteer in a hobbyist fashion for one of my pet project, so just keep in mind that my comments are based on very little experience on the matter! 😣

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

Successfully merging this pull request may close these issues.

None yet

3 participants