anks
anks

Reputation: 313

Capybara's fill_in on a Site Prism's page object doesn't work

I'm rewriting feature specs to page objects and I have a problem with fill_in method.

The code is as follows:

Page object:

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

Spec:

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: '[email protected]'
    login_page.fill_in login_page.password, with: 'bad password'
    login_page.submit.click
    expect(login_page).to have_content 'Invalid credentials'
  end

The input field is defined like this:

<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">`

When I run the test, I get the following error:

[2] pry(#<RSpec::ExampleGroups::Login>)> login_page.fill_in login_page.email, 
with: '[email protected]'
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">

However, this field is findable:

[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">

I guess it might be connected with how fill_in uses find when CSS are used.

Is there any way to handle it as close as possible to how the end user would interact with the form? I don't want to use login_page.email.set '[email protected]', because set doesn't care if the field is actually clickable/fillable and not hidden by some element.

Upvotes: 0

Views: 1017

Answers (2)

Thomas Walpole
Thomas Walpole

Reputation: 49910

Capbaras #fill_in is basically implemented as find(:fillable_field, "the id/name/label text").set("value to set"). Site-prism moves the find behavior to element, but does allow you to specify the selector used when specifying the element. So rather than doing

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

you can do

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

which should make login_page.email.set("xyz") equivalent to using Capybaras fill_in. The same can be done with :checkbox, :radio_button, etc.

Upvotes: 1

anks
anks

Reputation: 313

It turns out that this works:

login_page.fill_in login_page.email[:name], with: '[email protected]'

The [:name] symbol is any unique input attribute you may have in the code.

This helped me How to use fill_in with find in Capybara (if possible)

Upvotes: 0

Related Questions