msmith1114
msmith1114

Reputation: 3229

Capybara RSpec matchers waiting for elements?

When writing a test framework/tests using Capybara + RSpec I came across this suggestion for testing for an element NOT to exist:

expect(page).to have_no_button('Save')   # OK
expect(page).not_to have_button('Save')  # Bad

I was confused why, until I saw this was stated:

Use should have_no_* versions with RSpec matchers because should_not have_* doesn’t wait for a timeout from the driver.

Is this true? If not...doesn't it make more sense from a page object model perspective to have a method to check and return if an <element> exists (I usually use .visible?) that way you can use the rspec matcher to do expect(page_object).to be_method_visible or expect(page_object).not_to be_method_visible ?

As opposed to having to write 2 separate methods in your page objects (Unless it is true that not_to will not wait)

For an example of my assertion methods in my page object model, here is what I do for checking for "logout link"

def logged_in?
    logout_text.visible?
end

private
def logout_text
    find 'a', text: 'Log Out'
end

And then in the spec I would say: expect(page_object).to be_logged_in

So I would use something similar for other elements.

Upvotes: 1

Views: 1324

Answers (1)

Thomas Walpole
Thomas Walpole

Reputation: 49880

I don't know where you came across that suggestion (maybe it's really really old) but for any "recent" version of Capybara (at least the last 4 years) when using the Capybara provided matchers it is not correct.

Assuming have_button and have_no_button are the Capybara provided matchers (not RSpecs built-in have_xxx => has_xxx? matcher calling a has_button? method you've defined on your page object) the two examples you give

expect(page).to have_no_button('Save')
expect(page).not_to have_button('Save')

will behave identically. They will both check for the existence of the button and return when it doesn't exist or raise an exception if Capybara.default_max_wait_time seconds has passed and the button is still visible on the page.

Upvotes: 1

Related Questions