rubycdp / ferrum

Headless Chrome Ruby API
https://ferrum.rubycdp.com
MIT License
1.76k stars 127 forks source link

wait_for_idle has issue with window.URL.createObjectURL #496

Open stoivo opened 1 month ago

stoivo commented 1 month ago

Hi. great work over here.

In out capybara spec we have used some javascript hook to check if all network is done. I found that ferrum can do it with wait_for_idle so I wanted to see if we can switch over and use that instead.

Some part of application uses JQueryTree.js and that does some funky stuff like below. I don't know why.

var wrk = window.URL.createObjectURL(
  new window.Blob(
    ['self.onmessage = ' + func.toString()],
    {type:"text/javascript"}
  )
);
new window.Worker(wrk);

I have created a script to reproduce the issue

script ```rb require 'bundler/inline' gemfile do source 'https://rubygems.org' gem 'ferrum', '0.15' end require "ferrum" browser = Ferrum::Browser.new({ headfull: false, logger: Kernel, }) page = browser.create_page puts "page request make to blob" page.goto("about:blank") # warapped in a IIFE since page.evaluate takes one expresion page.evaluate(<<~JS) (function () { const func = function (data, undefined) {} var wrk = window.URL.createObjectURL( new window.Blob( ['self.onmessage = ' + func.toString()], {type:"text/javascript"} ) ); w = new window.Worker(wrk); })() JS begin page.network.wait_for_idle(duration: 1) rescue Ferrum::TimeoutError => e puts e puts puts "unfinished request from blob" pp page.network.traffic.reject(&:finished?) end # puts "page request make to fetch" # page.goto("about:blank") # page.evaluate(<<~JS) # (function () { # fetch("https://raw.githubusercontent.com/", {"method": "GET", }); # fetch("https://raw.githubusercontent.com/rubycdp/ferrum/refs/heads/main/logo.svg", {"method": "GET", }); # })() # JS # begin # page.network.wait_for_idle(duration: 1) # rescue Ferrum::TimeoutError => e # puts e # puts # puts "unfinished request from fetch" # pp page.network.traffic.reject(&:finished?) # end # puts "page request make to xhr" # page.goto("https://github.com") # page.evaluate(<<~JS) # (function () { # const xhr = new XMLHttpRequest(); # xhr.open("GET", "https://raw.githubusercontent.com/", true); # xhr.send(null); # })() # JS # begin # page.network.wait_for_idle(duration: 1) # rescue Ferrum::TimeoutError => e # puts e # puts # puts "unfinished request from xhr" # pp page.network.traffic.reject(&:finished?) # end ```

It prints out event which happens and from what I can understand these are the relevant events for each of my cases

Relevant events when fetching with Blob

{"method":"Network.requestWillBeSent","params":{"requestId":"14F76E4E856E44E2D9708320CC766C31" ....
{"method":"Network.loadingFinished","params":{"requestId":"14F76E4E856E44E2D9708320CC766C31" ...

Relevant events when fetching with fetch

{"method":"Network.requestWillBeSent","params":{"requestId":"29478.2" ...
{"method":"Network.requestWillBeSentExtraInfo","params":{"requestId":"29478.2" ...
{"method":"Network.responseReceivedExtraInfo","params":{"requestId":"29478.2" ...
{"method":"Network.responseReceived","params":{"requestId":"29478.2" ...
{"method":"Network.dataReceived","params":{"requestId":"29478.2" ...
{"method":"Network.loadingFinished","params":{"requestId":"29478.2" ...

Have you seen this before? Do you think this is a bug in ferrum?

Desktop (please complete the following information):