Using Capybara finder methods with arbitrary matching conditions

Posted . Visible to the public. Repeats.

Capybara has a variety of finder methods Show archive.org snapshot like find_button to help you look up DOM elements. There are also matchers Show archive.org snapshot like have_field to make expectations during tests.

These methods also have a number of options to influence the lookup. E.g. the :disabled option lets you control whether Capybara will match disabled fields.

If you have a matching condition that cannot be expressed by the existing Capybara option you may pass a block to define additional conditions in Ruby.

Example

The following will expect a field labeled Username, but also requires that this field has a blank [class] attribute:

expect(page).to have_field('Username') { |field| field[:class].blank? }

Limitations

Using execute_script, evaluate_script or evaluate_async_script within a filter block will crash with a timeout:

*** Selenium::WebDriver::Error::ScriptTimeoutError Exception: script timeout

This is due to Capybara using a zero timeout Show archive.org snapshot while calling the filter block.

A workaround is to temporarily set a different timeout while running your script:

expect(page).to have_field('Username') do |field|
  field.session.using_wait_time(0.5 * Capybara.default_max_wait_time) do
    execute_script(...)
  end
end

Note

Don't reset the wait time to the full Capybara.default_max_wait_time or you will lose Capybara's retry mechanism Show archive.org snapshot .

Profile picture of Henning Koch
Henning Koch
Last edit
Henning Koch
License
Source code in this card is licensed under the MIT License.
Posted by Henning Koch to makandra dev (2023-05-11 12:46)