Using Capybara finder methods with arbitrary matching conditions

Posted . Visible to the public.

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 .

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)