rubycdp / cuprite

Headless Chrome/Chromium driver for Capybara
https://cuprite.rubycdp.com
MIT License
1.22k stars 91 forks source link

Cuprite does not play nicely with Async #168

Open BillyRuffian opened 2 years ago

BillyRuffian commented 2 years ago

(I've done very little digging and maybe this should be posted to Ferrum)

Using Ruby 3.x

require 'async'
require 'benchmark'
require 'capybara/dsl'
require 'capybara/cuprite'

include Capybara::DSL

Capybara.javascript_driver = :cuprite
Capybara.register_driver(:cuprite) do |app|
  Capybara::Cuprite::Driver.new(app, window_size: [1200, 800], headless: false)
end

Capybara.default_driver = :cuprite

visit('https://duckduckgo.com')

Benchmark.bm(10) do |timings|
  timings.report('No async') { page.text }

  Async do |task|
    timings.report('Async block') { page.text }

    task.async do
      timings.report('Async task') { page.text }      
    end
  end
end

Gives the rather painful...

                 user     system      total        real
No async     0.002730   0.001640   0.004370 (  0.008259)
Async block  0.006395   0.003081   0.009476 ( 10.018538)
Async task   0.004829   0.002527   0.007356 ( 10.015278)
route commented 2 years ago

I'm currently working on this, though I work on Ferrum rather than Cuprite/Capybara

route commented 2 years ago

Same code you provided for Ferrum:

require 'ferrum'
require 'async'
require 'benchmark'

browser = Ferrum::Browser.new(window_size: [1200, 800], headless: true)
browser.go_to('https://duckduckgo.com')

Benchmark.bm(10) do |timings|
  timings.report('No async') { browser.body }

  Async do |task|
    timings.report('Async block') { browser.body }

    task.async do
      timings.report('Async task') { browser.body }
    end
  end
end

and shows:

                 user     system      total        real
No async     0.001006   0.000192   0.001198 (  0.003663)
Async block  0.001031   0.000197   0.001228 (  0.002775)
Async task   0.000861   0.000164   0.001025 (  0.002329)
BillyRuffian commented 2 years ago

Nice, so a Curpite issue rather than a Ferrum one then?

route commented 2 years ago

I’d say capybara

BillyRuffian commented 2 years ago

Hmmm the apparition driver with capybara, also CDP driven, has no issues with Async.

route commented 2 years ago

I’ll take a look but off the top of my head can’t remember anything done wrong in cuprite.

jjimenez commented 6 months ago

Just chiming in here to share my example on an m1 machine with the cuprite 0.15 and ruby 3.2. I don't think this is a problem in cuprite or a problem anymore.


require 'async'
require 'benchmark'
require 'capybara/dsl'
require 'capybara/cuprite'
require 'ferrum'

include Capybara::DSL

Capybara.javascript_driver = :cuprite
Capybara.register_driver(:cuprite) do |app|
  Capybara::Cuprite::Driver.new(app, headless: 'new', process_timeout: 30, browser_options: { 'no-sandbox': nil }, timeout: 30)
end

Capybara.default_driver = :cuprite

visit('https://duckduckgo.com')

browser = Ferrum::Browser.new(window_size: [1200, 800], headless: true, process_timeout: 30, browser_options: { 'no-sandbox': nil })
browser.go_to('https://duckduckgo.com')

Benchmark.bmbm(20) do |timings|
  timings.report('.text None') { page.text }

  Async do |task|
    timings.report('.text block') { page.text }

    task.async do
      timings.report('.text task') { page.text }
    end
  end

  timings.report('body None') { page.driver.browser.body }

  Async do |task|
    timings.report('body block ') { page.driver.browser.body }

    task.async do
      timings.report('body task') { page.driver.browser.body }
    end
  end
  timings.report('Ferrum None') { browser.body }

  Async do |task|
    timings.report('Ferrum block') { browser.body }

    task.async do
      timings.report('Ferrum task') { browser.body }
    end
  end

end

gives the following output

Rehearsal --------------------------------------------------------
.text None             0.001866   0.000963   0.002829 (  0.007786)
.text block            0.001093   0.000485   0.001578 (  0.004904)
.text task             0.001418   0.000114   0.001532 (  0.004882)
body None              0.000568   0.001148   0.001716 (  0.006823)
body block             0.001493   0.000000   0.001493 (  0.005610)
body task              0.001561   0.000000   0.001561 (  0.005709)
Ferrum None            0.000934   0.000775   0.001709 (  0.006787)
Ferrum block           0.000000   0.001682   0.001682 (  0.005934)
Ferrum task            0.000480   0.001109   0.001589 (  0.005837)
----------------------------------------------- total: 0.015689sec

                           user     system      total        real
.text None             0.001385   0.000832   0.002217 (  0.005786)
.text block            0.001780   0.000000   0.001780 (  0.005316)
.text task             0.001382   0.000360   0.001742 (  0.005239)
body None              0.001311   0.000081   0.001392 (  0.005684)
body block             0.000504   0.000871   0.001375 (  0.005660)
body task              0.001482   0.000000   0.001482 (  0.011515)
Ferrum None            0.001450   0.000000   0.001450 (  0.006018)
Ferrum block           0.001366   0.000090   0.001456 (  0.006078)
Ferrum task            0.001390   0.000000   0.001390 (  0.005621)

real times are pretty consistent over all three methods