Search code examples
capybaraintegration-testingminitestacceptance-testingcircleci

Frontend testing with CircleCI and Minitest: Tests don't wait long enough for page to load


So my tests seem to pass about 75% of the time. The other 25% fail because the testing suite isn't waiting long enough for the page to completely load. On our local machines the test takes about 35s, but on CircleCI's logs it's only 5s. (On local I run the tests with BROWSER=chrome m path/to/test.file)

I'm new to this tech stack so any help is greatly appreciated, even if it's just appropriate reference docs.

it 'should use this form' do

  assert page.has_content?('#target_form')
  within '#target_form' do
    # fill in the form and apply payment
  end

  # it will throw errors here "can't find css..." 
  # the text/element won't even have loaded yet
  # by the time the test is run
  assert_equal '24', find_qa('price').text
end

Solution

  • The way you're writing your assertions isn't utilizing Capybara's waiting/retrying behavior so running on slower hardware (CircleCI compared to your local box) can cause your tests to fail. assert_equal evaluates the two parameters compares them, and it's done. This isn't good because Capybara assumes every action could perform asynchronous actions so it doesn't necessarily wait for a button click to submit and load a new page (because it has no way of knowing what action the button click may produce). However if you use the Capybara provided assertions it will wait/retry the comparison up to Capybara.default_max_wait_time seconds for the comparison to be true. I'm not sure how your find_qa method is defined, but if you've declared a custom :qa selector you could do something like

    assert_selector :qa, 'price', text: '24'
    

    If find_qa is just doing a CSS selector then you could do

    assert_selector :css, "whatever find_qa('price') produces as a css selector", text: '24'
    

    or you could do

    find_qa('price').assert_text('24')
    

    Since you're using minitest you probably want to read - https://github.com/teamcapybara/capybara#using-capybara-with-minitest - and configure Capybara's minitest matchers so the counts of assertions run are correct, and to provide a bunch more specific assertions that will utilize Capybara's waiting/retrying behavior. See https://github.com/teamcapybara/capybara/blob/master/lib/capybara/minitest.rb for the matchers added, which will let you write things like

    assert_text find_qa('price'), '24'
    assert_xpath 'an XPath selector', ...
    assert_title ...
    assert_current_path ...
    

    etc.