Capybara模棱两可的匹配错误

Nei*_*ker 1 capybara ruby-on-rails-5

这个项目是对原版的重新启动,我正试图掌握各种宝石 - 除了我之外,轨道作曲家能够很好地理解所发生的事情.

我得到的这个Capybara错误与注册代码有关(我有几个使用该调用的规范,但是这里只包含其中一个,因为它们都调用了相同的帮助器).

 Capybara::Ambiguous:
       Ambiguous match, found 2 elements matching field "Password"
Run Code Online (Sandbox Code Playgroud)

我已经看过StackOverflow(好几次),并使用了Messr Google的力量 - 他主要建议我看看这里.

起初我认为这与做错了有关

fill_in 'Email', with: email
Run Code Online (Sandbox Code Playgroud)

fill_in 'Email', :with => email
Run Code Online (Sandbox Code Playgroud)

但似乎都没有区别.

通过阅读rubydoc.info capybara fill-in中的文档(我知道:惭愧),填充需要一个定位器和一个选项数组.

我的理解是fill_in 'Password', with: password匹配Password定位器,这是id="user_password"html 的一部分.我在页面上看不到任何其他人,所以我现在正在寻求帮助.

我的所有代码都在我的项目Github项目分支的SO001分支上,以匹配这个问题.

sign_up_spec.rb

feature 'Sign Up', :devise do
  # Scenario: Visitor can sign up with valid email address and password
  #   Given I am not signed in
  #   When I sign up with a valid email address and password
  #   Then I see a successful sign up message
  scenario 'visitor can sign up with valid email address and password' do
    sign_up_with('test@example.com', 'please123', 'please123')
    txts = [I18n.t( 'devise.registrations.signed_up'), I18n.t( 'devise.registrations.signed_up_but_unconfirmed')]
    expect(page).to have_content(/.*#{txts[0]}.*|.*#{txts[1]}.*/)
  end
    # ... others snipped for space
end
Run Code Online (Sandbox Code Playgroud)

规格/支持/助理/ session_helpers.rb

module Features
  module SessionHelpers
    def sign_up_with(email, password, confirmation)
      visit new_user_registration_path
      save_and_open_page
      fill_in 'Email', with: email
      fill_in 'Password', with: password
      fill_in 'Password confirmation', :with => confirmation
      click_button 'Sign up'
    end

    def signin(email, password)
      visit new_user_session_path
      fill_in 'Email', with: email
      fill_in 'Password', with: password
      click_button 'Sign in'
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

设计new.html.erb代码是

注册

<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :email, required: true, autofocus: true %>
    <%= f.input :password, required: true, hint: ("#{@minimum_password_length} characters minimum" if @minimum_password_length) %>
    <%= f.input :password_confirmation, required: true %>
  </div>

  <div class="form-actions">
    <%= f.button :submit, "Sign up" %>
  </div>
<% end %>

<%= render "devise/shared/links" %>
Run Code Online (Sandbox Code Playgroud)

html的表单部分有

<form novalidate="novalidate" class="simple_form new_user" id="new_user" action="/users" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="&#x2713;" />


  <div class="form-inputs">
    <div class="form-group email required user_email">
        <label class="control-label email required" for="user_email">
            <abbr title="required">*</abbr> Email
        </label>
        <input class="form-control string email required" autofocus="autofocus" required="required" aria-required="true" type="email" value="" name="user[email]" id="user_email" />
    </div>
    <div class="form-group password required user_password">
        <label class="control-label password required" for="user_password">
            <abbr title="required">*</abbr>
            Password</label>
        <input class="form-control password required" required="required" aria-required="true" type="password" name="user[password]" id="user_password" />
        <p class="help-block">6 characters minimum</p>
    </div>
    <div class="form-group password required user_password_confirmation">
        <label class="control-label password required" for="user_password_confirmation">
            <abbr title="required">*</abbr>
            Password confirmation
        </label>
        <input class="form-control password required" required="required" aria-required="true" type="password" name="user[password_confirmation]" id="user_password_confirmation" />
    </div>
  </div>

  <div class="form-actions">
    <input type="submit" name="commit" value="Sign up" class="btn btn-default" data-disable-with="Sign up" />
  </div>
</form>
Run Code Online (Sandbox Code Playgroud)

Tho*_*ole 5

如文档所述,Capybara fill_in将匹配其id或name属性或相关标签元素的文本上的元素.属性匹配需要精确,并且关联标签元素的文本可以是精确匹配或子串匹配,具体取决于几个选项的设置.

在当前版本的Capybara中,Capybara.exact默认为:smart,当查找关联的标签文本匹配时,将首先尝试完全匹配,如果没有找到,则尝试进行子串匹配.在您的情况下,您的两个字段的标签文本是*Password,*Password confirmation并且在检查完全匹配Password失败时,并且当使用子字符串匹配检查时两者都匹配 - 因此"不明确匹配"错误,因为多于一个元素匹配.

要解决此问题(仍然使用fill_in),您可以执行以下任何操作

fill_in '*Password', with: password # will match exactly on one elements label text

find('div.user_password').fill_in 'Password' with: password # scope fill_in so substring match is unique

fill_in 'user_password', with: password # match on id attribute

fill_in 'user[password]', with: password # match on name attribute
Run Code Online (Sandbox Code Playgroud)