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

wait_for_network_idle failing due to pending requests on previous page #420

Open
cbliard opened this issue Nov 24, 2023 · 1 comment
Open

Comments

@cbliard
Copy link

cbliard commented Nov 24, 2023

I experienced some random Ferrum::TimeoutError when calling wait_for_idle. For the same navigation, sometime it would fail, sometime it would pass.

After adding debug information output for requestWillBeSent, responseReceived, loadingFinished and loadingFailed events, it looks like some request can be sent while navigating to another page, and never receive a responseReceived, loadingFinished, or loadingFailed event.

For instance:

requestWillBeSent for requestId=349E42C73C6810F5DBFA790494E57AE0 loaderId=349E42C73C6810F5DBFA790494E57AE0 at 73687.356628
requestWillBeSent for requestId=429934.40 loaderId=8FCB3DE497DC83193F1D76075900D0D4 at 73687.362944
requestWillBeSent for requestId=429934.41 loaderId=8FCB3DE497DC83193F1D76075900D0D4 at 73687.452702
responseReceived for requestId=349E42C73C6810F5DBFA790494E57AE0 loaderId=349E42C73C6810F5DBFA790494E57AE0 at 73687.54549

The two requests 429934.40 and 429934.41 are in the @traffic array, but no responseReceived, loadingFinished, or loadingFailed event will be sent for them, so they will still be considered pending. They have a different loaderId because they have been loaded by the previous page doing some asynchronous XHR request for some reason.

When wait_for_idle is called, it will wait for all pending request to finish, even those from no-more displayed pages, making it fail with Ferrum::TimeoutError.

I modified the #pending_connections method a little to consider only pending connections for the current page. I looks somewhat like this:

    def pending_connections
      frame_id = @traffic.first&.request&.frame_id
      current_page_loader_id = @traffic.select { |conn| conn.navigation_request?(frame_id) }.last.request.loader_id
      current_page_traffic = @traffic.filter { |exchange| exchange.request.loader_id == current_page_loader_id }
      current_page_traffic.count(&:pending?)
    end

This fixes my issue.

I am no expert in CDP. Maybe there are some other events that I missed. Is this approach correct?

Chrome version is 119.0.6045.105 on Linux amd64.

@route
Copy link
Member

route commented Jan 6, 2024

@cbliard do you have an example of such a page in the public internet? I just want to check the CDP logs to better understand of what's going on

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

No branches or pull requests

2 participants