mattsse / chromiumoxide

Chrome Devtools Protocol rust API
Apache License 2.0
712 stars 69 forks source link

Fix for iframes and future timeout #174

Closed chirok11 closed 10 months ago

chirok11 commented 10 months ago

This library have some problems with handling iframes and dont work properly and handle service workers. I created this pull request that contain's fixes for few cases.

1) Some websites, that contain's an iframe will load forever and never resolve's. Problem is: I checked puppeteer or playwright libraries, and found, that they're sending runIfWaitingForDebugger for attached targets to target, what chromiumoxide doesn't do or handle. Also, I noticed, that we have to send two events for service workers, runIfWaitingForDebugger and detachFromTarget. I implemented both, and page's, that won't load before now loading successfully. Example URLs: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe https://www.financialexpress.com/ (has an service worker)

Solution: I added runIfWaitingForDebugger when CdpEvent::TargetAttachedToTarget is emitted, and also, if it new target is service_worker, then we also send event detachFromTarget

After, I noticed, that page's now loading correctly, but future .goto(url) still failing on timeout. Then I started discovery source of this problem. And solution is in next case.

2) If page has an iframe, it will load forever and .goto(url) always fail on timeout. Sample URL: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe Expected behaviour: Page loaded and .goto(url) future returns Ok.

Solution: I modified check_lifecycle and checking it for if lifecycle events contain's "load" event, or (if page url is None and lifecycle events has event DOMContentLoaded).

3) No way to customize request timeout. Solution: I added function connect_with_config to Browser instance. It accepts url as first parameter, and HandlerConfig as second.

4) Problem with .goto(url) action. How to reproduce: Open new page and call .goto(url) on it, then go to browser and close tab (you should choose long-loading website to reproduce). Future never will be await'ed, even there will be no timeout or other error. So it will runs forever.

Solution: Added DelayFuture in CommandFuture, it uses crate::REQUEST_TIMEOUT and will return CdpError::Timeout if timer is ready.

Closes #163 and closes #171

chirok11 commented 10 months ago

I am not quite familiar with github workflow with pull's or issues, I pushed new commit to my branch, should I reopen pull request or how?

escritorio-gustavo commented 10 months ago

Don't worry, as you push new commits to your branch this PR will be automatically updated, you don't need to create a new one