user2084865
user2084865

Reputation: 697

RSpec: wait alternative to match

There are some articles (e.g. [1]) regarding solving flaky acceptance tests when using Capybara which advocates using e.g.

.to have_text("foo")

instead of

.to eql("foo")

In one of my tests I have .to match(/foo/) and every once in a while this fails. I assume that the match matcher is not in the same category as e.g. the have_text matcher and doesn't wait. The documentation doesn't mention anything regarding this.

Is there any regex matcher so that I can check e.g.

expect(next_url).to match(/foo/)

?


Versions used (not changeable):

capybara: 2.7.x

spec-rails: 3.6.x

[1] https://www.urbanbound.com/make/fix-flaky-feature-tests-by-using-capybaras-apis-properly

Upvotes: 1

Views: 2824

Answers (2)

napster235
napster235

Reputation: 9

If you have a page where elements have a delay appearing on the page, you can define a 'wait' method in 'capybara_helpers.rb'

def wait_for timeout = 10, &block
Timeout.timeout(timeout) do
  loop do
    condition = yield
    if (condition)
      break true
    end
  end
end

rescue Timeout::Error
  raise "Condition not true in #{timeout} seconds"

end

After that, you can use 'wait_for' method like this:

wait_for { page.has_css?('.class', text: 'Something') }

Upvotes: 0

Thomas Walpole
Thomas Walpole

Reputation: 49890

The docs for have_text link to the assert_text docs - https://www.rubydoc.info/gems/capybara/Capybara/Node/Matchers#assert_text-instance_method which show that it takes either a string

expect(page).to have_text('Something')

or a Regexp

expect(page).to have_text(/foo/)

As the article you linked to implies, if you find yourself using any non capybara provided matcher with information returned from Capybara you're probably doing something wrong, and setting yourself up for flaky tests.

Upvotes: 2

Related Questions