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

Network cache is cleared during test suite #128

Open
harmdewit opened this issue Jul 27, 2020 · 8 comments
Open

Network cache is cleared during test suite #128

harmdewit opened this issue Jul 27, 2020 · 8 comments

Comments

@harmdewit
Copy link

harmdewit commented Jul 27, 2020

For one of our rails projects I was interested to see if cuprite is faster than our current selenium chrome specs. Selenium still seemed a bit faster for the feature specs (3:26) vs cuprite (3:52)

I was looking at the differences between the two and I noticed that cuprite doesn't cache the assets during the full test suite while selenium does. Looking at the capybara method it seems like the reset should only reset the session (e.g. cookies?), however it seems like cuprite uses a new context (e.g. incognito browser sessions for every test).

Capybara reference: https://github.com/teamcapybara/capybara/blob/476c8508a34cb072489c03d44fe251427605fa40/lib/capybara/session.rb#L112-L118

Changing the browser.reset in Capybara::Cuprite::Driver#reset to browser.cookies.reset made cuprite faster (3:06) and all specs still pass.

@route
Copy link
Member

route commented Jul 27, 2020

@harmdewit Thanks for the the info, this is good to know. I was thinking about speeding up reset, even created branch called soft reset but faced some issues even in capybara's test suit. I think there's room for improvement but it requires more time for investigation. Currently new context is much safer than removing cookies though like you noticed slower.

@jdelStrother
Copy link

jdelStrother commented Oct 1, 2020

FWIW this hack:

 Capybara::Cuprite::Driver.class_eval do
   def reset!
      @zoom_factor = nil
      @paper_size = nil
      browser.url_blacklist = @options[:url_blacklist]
      browser.url_whitelist = @options[:url_whitelist]
      browser.cookies.clear # instead of browser.reset
      @started = false
    end
 end

reduced our feature spec time from 3:01 minutes to 2:40.

(Sadly it's still slower than Selenium at 2:03 - I'm not sure why cuprite & apparition are so much slower for us)

@route
Copy link
Member

route commented Oct 2, 2020

@jdelStrother there are also a few of storage types which you are not cleaning and I think you shouldn't set started to false.

Should be faster, maybe there are some timing issues. Did you investigate debug log? Sometimes I find network issues there which I didn't notice before.

@jdelStrother
Copy link

I did check the logs, but couldn't spot any obvious network issues.

I did some profiling of the methods in Capybara::Session totalled up over the course of our test suite. Here's the top 10 from Cuprite:

:visit
min: 137.959, max: 2184.627, avg: 382.831, stddev: 260.036, total: 63549.982
:click_button
min: 46.845, max: 1173.461, avg: 329.293, stddev: 282.220, total: 22391.940
:within_element
min: 5.556, max: 1110.794, avg: 317.879, stddev: 328.821, total: 14940.316
:assert_text
min: 0.921, max: 1102.321, avg: 118.985, stddev: 256.257, total: 10946.618
:fill_in
min: 11.832, max: 407.418, avg: 53.369, stddev: 59.252, total: 3042.049
:click_link
min: 48.178, max: 199.280, avg: 89.206, stddev: 47.866, total: 2319.355
:find
min: 3.434, max: 491.310, avg: 19.665, stddev: 59.326, total: 2300.825
:assert_no_selector
min: 1.668, max: 579.190, avg: 126.516, stddev: 237.482, total: 2277.283
:click_on
min: 143.976, max: 160.694, avg: 151.971, stddev: 5.265, total: 1519.715
:assert_selector
min: 2.905, max: 207.138, avg: 14.418, stddev: 32.765, total: 994.876

(times are in ms - eg we spent a total of 63 seconds waiting for Capybara::Session#visit)

And for Selenium/Chrome:

:visit
min: 68.124, max: 2446.280, avg: 185.465, stddev: 226.993, total: 30787.216
:assert_text
min: 3.355, max: 1285.161, avg: 188.129, stddev: 259.408, total: 17307.893
:click_button
min: 43.872, max: 1096.096, avg: 209.377, stddev: 286.690, total: 14237.622
:within_element
min: 12.974, max: 1492.645, avg: 269.444, stddev: 363.740, total: 12663.852
:fill_in
min: 46.283, max: 521.980, avg: 104.936, stddev: 66.875, total: 6086.316
:find
min: 5.975, max: 237.464, avg: 26.530, stddev: 42.978, total: 3103.998
:assert_no_selector
min: 4.812, max: 613.410, avg: 139.908, stddev: 240.031, total: 2518.352
:assert_selector
min: 6.162, max: 389.870, avg: 27.872, stddev: 49.655, total: 1923.150
:click_link
min: 43.413, max: 140.698, avg: 60.207, stddev: 20.152, total: 1565.393

So some of cuprite's methods (eg assert_selector/assert_text/source)) are significantly faster. But visit being 2x slower on average in cuprite is troubling.

However! I added another awful hack: commenting out network.subscribe in Ferrum::Page has reduced my overall Capybara::Session#visit time from 63s to 35s, almost on par with Selenium.

This is starting to sound like a separate issue from the original network cache one though. Should I reopen it somewhere else?

@route
Copy link
Member

route commented Oct 3, 2020

I think what happens is Selenium doesn’t wait until the page fully loads and your test starts executing earlier. While it looks like speed increase though it’s dangerous because we start interacting with partially loaded website. It’s only a clue though

@ianks
Copy link
Contributor

ianks commented Oct 5, 2020

@jdelStrother Thank you for that tip. It has significantly decreased our test suite time! I feel like caching assets is a pretty sane default, especially given that many apps use app servers like Puma which will end up serving static assets via the Ruby process (which is slow).

We altered our version slightly to:

  Capybara::Cuprite::Driver.class_eval do
    def reset!
      clear_network_traffic
      resize(*screen_size)
      visit('about:blank')
      @zoom_factor = nil
      @paper_size = nil
      browser.url_blacklist = @options[:url_blacklist]
      browser.url_whitelist = @options[:url_whitelist]
      browser.cookies.clear # instead of browser.reset
      @started = false
    end
  end

@jdelStrother
Copy link

I think what happens is Selenium doesn’t wait until the page fully loads and your test starts executing earlier. While it looks like speed increase though it’s dangerous because we start interacting with partially loaded website. It’s only a clue though

Maaaybe. We have hundreds of tests that we currently run with selenium-webdriver chrome without running into problems though. I guess Capybara's default behaviour of waiting for an element to appear when you do something like click_button "foo" is papering over the problem of partially loaded pages, making this Cuprite feature seem like unnecessary overhead for our use case.

(Sorry if that sounds like I'm being negative on Cuprite! I'm just trying to understand the tradeoffs you're making here, given that other bits of Cuprite are much faster than Selenium.)

@lenon
Copy link

lenon commented Jul 19, 2024

@ianks and @jdelStrother, thanks for the patch! I used it in our specs and the time required to run the tests was reduced from 2min 40s to 1min 42s.

It would be nice to have an option to configure this behavior and only reset the session cookies, I think.

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

5 participants