Capybara在网站上的fill_in Prism的页面对象不起作用

时间:2016-03-24 16:36:08

标签: capybara pageobjects site-prism

我正在重写页面对象的功能规范,我遇到了fill_in方法的问题。

代码如下:

页面对象:

class LoginPage < SitePrism::Page
 set_url '/login'

 section :navbar, NavbarSection, '.navbar-collapse'
 section :drop_menu, DropMenuSection, '.popover-content'
 element :email, 'input[name=email]'
 element :password, 'input[type=password]'
 element :submit, 'button[type=submit]'
 element :help, 'a', text: "Help! I can't sign in"
end

规格:

require 'spec_helper'

feature 'Login', js: true do
  let(:app) { App.new }
  let(:login_page) { app.login }

  scenario 'with invalid credentials results in error message' do
    login_page.load
    login_page.fill_in login_page.email, with: 'wrong@mail.com'
    login_page.fill_in login_page.password, with: 'bad password'
    login_page.submit.click
    expect(login_page).to have_content 'Invalid credentials'
  end

输入字段的定义如下:

<input class="form-control input-lg ng-pristine ng-untouched 
ng-invalid ng-invalid-required" name="email" 
ng-model="login.credentials.email" placeholder="Email"
required="" tabindex="0" aria-required="true" 
aria-invalid="true">`

当我运行测试时,我收到以下错误:

[2] pry(#<RSpec::ExampleGroups::Login>)> login_page.fill_in login_page.email, 
with: 'wrong@mail.com'
Capybara::ElementNotFound: Unable to find field #<Capybara::Node::Element 
tag="input" path="/html/body/div[1]/div/div/div/div/div[2]/div/form/div[1]/div/input">

但是,这个字段是可以找到的:

[1] pry(#<RSpec::ExampleGroups::Login>)> login_page.email
=> #<Capybara::Node::Element tag="input" 
path="/html/body/div[1]/div/div/div/div/div[2]/div/form/div[1]/div/input">

我猜这可能与使用CSS时fill_in使用find的方式有关。

有没有办法尽可能接近最终用户与表单交互的方式处理它? 我不想使用login_page.email.set 'wrong@mail.com',因为set并不关心字段是否实际上是可点击/可填充的,而不是被某个元素隐藏。

2 个答案:

答案 0 :(得分:1)

Capbaras #fill_in基本上实现为find(:fillable_field, "the id/name/label text").set("value to set")。 Site-prism将查找行为移动到元素,但允许您指定在指定元素时使用的选择器。所以而不是做

element :email, "some css to find the email field"

你可以做到

element :email, :fillable_field, "the id/name/label you would have passed to fill_in"

这应该使login_page.email.set("xyz")等同于使用Capybaras fill_in。同样可以使用:checkbox,:radio_button等

答案 1 :(得分:0)

事实证明这有效:

login_page.fill_in login_page.email[:name], with: 'wrong@mail.com'

[:name]符号是代码中可能包含的任何唯一输入属性。

这帮助了我How to use fill_in with find in Capybara (if possible)