这个项目是对原版的重新启动,我正在努力掌握各种宝石 - 除了我之外,轨道作曲家对所有事情都做得非常出色。
我得到的这个Capybara错误与注册代码有关(我有几个使用该调用的规范,但是这里只包含其中一个,因为它们都调用了相同的帮助程序)。
Capybara::Ambiguous:
Ambiguous match, found 2 elements matching field "Password"
我看过StackOverflow(好几次),并使用了Messr Google的力量 - 他主要建议我看看这里。
起初我认为这与
不匹配有关fill_in 'Email', with: email
和
fill_in 'Email', :with => email
但似乎没有任何区别。
通过阅读rubydoc.info capybara fill-in处的文档(我知道:羞愧地垂头丧气),填充内容包含一个定位器和一个选项数组。
我的理解是fill_in 'Password', with: password
会匹配Password
定位符,这是html的id="user_password"
部分。我在页面上看不到任何其他人,所以我现在正在寻求帮助。
我的所有代码都在项目Github project branch to match this question的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
规格/支持/助手/ 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
设计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" %>
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="✓" />
<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>
答案 0 :(得分: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