Capybara Ambiguity Resolution

2019-01-31 05:08发布

How do I resolve ambiguity in Capybara? For some reason I need links with the same values in a page but I can't create a test since I get the error

Failure/Error: click_link("#tag1")
     Capybara::Ambiguous:
       Ambiguous match, found 2 elements matching link "#tag1"

The reason why I can't avoid this is because of the design. I'm trying to recreate the twitter page with tweets/tags on the right and the tags on the left of the page. Therefore it will be inevitable that identical links page shows up on the same page.

8条回答
在下西门庆
2楼-- · 2019-01-31 06:05

To add to the existing body of knowledge here:

For JS tests, Capybara has to keep two threads (one for RSpec, one for Rails) and a second process (the browser) in sync. It does this by waiting (up to the configured maximum wait time) in most matchers and node-finding methods.

Capybara also has methods that don't wait, primarily Node#all. Using them is like telling your specs that you'd like them to fail intermittently.

The accepted answer suggests page.first('selector'). This is undesirable, at least for JS specs, because Node#first uses Node#all.

That said, Node#first will wait if you configure Capybara like so:

# rails_helper.rb
Capybara.wait_on_first_by_default = true

This option was added in Capybara 2.5.0 and is false by default.

As Andrei mentioned, you should instead use

find('selector', match: :first)

or change your selector. Either will work well regardless of config or driver.

To further complicate things, in old versions of Capybara (or with a config option enabled), #find will happily ignore ambiguity and just return the first matching selector. This isn't great either, as it makes your specs less explicit, which I imagine is why no longer the default behavior. I'll leave out the specifics because they've been discussed above already.

More resources:

查看更多
Lonely孤独者°
3楼-- · 2019-01-31 06:06

My solution is

first(:link, link).click

instead of

click_link(link)
查看更多
登录 后发表回答