GoogleChrome / chrome-launcher

Launch Google Chrome with ease from node.
https://www.npmjs.com/package/chrome-launcher
Apache License 2.0
1.21k stars 187 forks source link

How to make sure a tab in background will keep running? #169

Open VikramTiwari opened 4 years ago

VikramTiwari commented 4 years ago

Scenario: I am launching chrome with following flags:

      '--disable-background-timer-throttling',
      '--enable-automation',
      '--disable-renderer-backgrounding',
      '--disable-backgrounding-occluded-windows',
      '--disable-ipc-flooding-protection',

And then utilizing puppeteer to do some operations in a tab in the background while I keep focus on a separate tab.

Expectation: The tasks should happen at normal pace in the background tab Reality: The tasks in the background tab are throttled

Please let me know if there are other details that I can provide. Thanks!

patrickhulce commented 4 years ago

Thanks for filing!

Q: You're using headful Chrome, correct? If so, why not headless?

Q: If you're using puppeteer, what led you to use chrome-launcher over puppeteer.launch?

I'm not aware of a way to completely coerce a headful tab to behave like it's the foreground tab, but maybe there are other workarounds for your use case.

VikramTiwari commented 4 years ago

Why headful Chrome? I am trying to run a script where I might have to do some manual interactions that cannot be automated. So if chrome is running in headless then I won't be able to do those interactions. Though I would love to have a way where jobs are running in background and when a specific function is executed, the window becomes headful. The closest I can get to it is by running the task in background tab and bringing the tab to front if I encounter my manual interaction cases.

Why chrome-launcher with puppeteer? Chrome launcher helps me launch chrome with my current user's data directory as well as it gives me the ability to use devtools protocol for certain functions which are not doable via puppeteer. Also, this way I get to simulate the script environment closest to my actual environment.

Other ways to make tab behave like foreground tab: I have seen examples where we could run a non-audible audio file in background in a loop. But that practice doesn't seem great. Are there any other ways you are familiar with @patrickhulce?

patrickhulce commented 4 years ago

I'm not aware of any better ways than the flags you've documented and the autoplay audio and video hacks unfortunately :/

VikramTiwari commented 4 years ago

hmm.. that's not great. In my understanding it's done for performance reasons. So, I was really hoping that this would be just a flag. Is there some reason why it's not? Should I open a feature request on crbug?

cc: @paulirish Are there any other methods that we might be missing here?

paulirish commented 4 years ago

patrick and i know pretty much the same amount on this topic :)

but yeah i think a crbug makes sense if we can prove this is happening. a test page that prints out timer overage would help a lot.

paulirish commented 4 years ago

relevant blog post: https://meowni.ca/posts/metronomes/ & https://metronomes.glitch.me/

VikramTiwari commented 4 years ago

Thanks for the links @paulirish. As mentioned in https://github.com/GoogleChrome/chrome-launcher/pull/170#issuecomment-530160803, I am unable to reproduce the issue right now. Will update if I find something.

VikramTiwari commented 4 years ago

I have updated a working issue which shows that this is an issue. Though it seems like it could be puppeteer's implementation of mousemove.

VikramTiwari commented 4 years ago

Related: https://github.com/ChromeDevTools/devtools-protocol/issues/89

I can also see from the POC that the mousemoves are being sent to the page but at a throttled rate.

VikramTiwari commented 4 years ago

I have added an issue on crbug now: https://bugs.chromium.org/p/chromium/issues/detail?id=1004821

VikramTiwari commented 4 years ago

Related issue: https://github.com/GoogleChrome/puppeteer/issues/3318

@patrickhulce I dig a bit deeper in this. I can do all keyboard events and even do window.xyz events. But for any mouse based events (mousemove/click) it just gets stuck. Mousemoves are throttled, and clicks just wait for the promise to return I am using elementHandle.click(). Does this mean that mouse emulation isn't working in headful background tabs or maybe the mouse events are not being synthesized properly, probably because background tab was not a possible use case scenario.

I also looked into what is page.bringToFront is doing and it seems like it's just activating the window and focusing on that. Is there any reason for the focus event? I would love to just activate and window and not lose the focus from currently focused tab.

VikramTiwari commented 4 years ago

POC for the issue: https://gist.github.com/VikramTiwari/77d0b81e605b0af161e0021e130d34d3

As stated above: mousemoves get throttled and clicks gets stuck altogether.

VikramTiwari commented 4 years ago

I think it might be totally related to puppeteer/CDP since I can click using document.getElementById('xyz').click()

cc: @mathiasbynens

VikramTiwari commented 4 years ago

So, https://github.com/puppeteer/puppeteer/issues/5201 on puppeteer details why click is not working. mousemove is still an issue and possibly on the execution on CDP messages.

ecolss commented 4 years ago

Hey @VikramTiwari, I'm really grateful to your efforts on this thread!

I'm using headless: false mode and having the same issue, i.e. multiple pages are opened and click same button on each page in parallel, only the focused tab will make click event happen, the other pages stuck.

So according to the above comments, looks like this issue is still not fully resolved, although you suggested, using the following code might be a solution,

await page.evaluate(() => document.getElementById('xyz').click());

but as I tested, some button or elements cannot be clicked by this page.evaluate approach, see this post on StackOverflow.

So I still wondered 1) why page.click cannot be ran in parallel in headless: false mode? 2) why page.evaluate doesn't work in some cases?

VikramTiwari commented 4 years ago

Sorry for such a delayed response @ecolss.

Hope these answers are helpful.