5

I wrote some tests using capybara for request testing using poltergeist and phantomjs as javascript driver.

The following steps for filling in a login form works great without js:

it "signs in" do
    visit new_user_session_path
    fill_in "Email", with: user
    fill_in "Password", with: password||"foobar"
    click_button "Login"
end

If I define my test with js it "signs in", js: true do my test fails with error:

Capybara::ElementNotFound: Unable to find field "Email"

The login form itself is built using simple_form as form generator and bootstrap in frontend. The fields do not have a label. the search text is only contained in the placeholder attribute.

= simple_form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f|
  = f.input :email, :placeholder => User.human_attribute_name(:email), :label => false, :input_html => {:class => 'input-xlarge'}
  = f.input :password, :placeholder => User.human_attribute_name(:password), :label => false, :input_html => {:class => 'input-xlarge'}
  %div
    = f.button :submit, "Login", :class => 'btn btn-large btn-primary'

This code generates the following html code

<form accept-charset="UTF-8" action="/users/login" class="simple_form new_user" id="new_user" method="post" novalidate="novalidate">
  <div style="margin:0;padding:0;display:inline">
    <input name="utf8" type="hidden" value="✓">
  </div>
  <div class="control-group email required user_email">
    <div class="controls">
      <input class="string email required input-xlarge" id="user_email" name="user[email]" placeholder="Email" size="50" type="email" value="">
    </div>
  </div>
  <div class="control-group password required user_password">
    <div class="controls">
      <input class="password required input-xlarge" id="user_password" name="user[password]" placeholder="Password" size="50" type="password">
    </div>
  </div>
  <div>
    <input class="btn btn btn-large btn-primary" name="commit" type="submit" value="Login">
  </div>
</form>

Do you have any Idea how to ensure that the fields are found even if js is activated?

Michael Ef
  • 141
  • 3
  • 9
  • Were you ever able to find a working solution for this? – Scott Sep 29 '14 at 22:00
  • Try this link it will help you http://stackoverflow.com/questions/15784398/test-case-for-hidden-field-is-not-working-with-cucumber – Arvind Sep 30 '14 at 04:11

2 Answers2

3

I don't know how your Webrat test passed. In my experience Capybara can't find "Email" if there is no matching Label or id.

In your case, since you don't use label, I suggest you to find the field with id

fill_in "user_email", with user.email 
# user_email is the id created by simple_form in general case. Verify yours.
# Don't need "#" before id. 
Billy Chan
  • 24,625
  • 4
  • 52
  • 68
  • I tried this, but capybara is also unable to find the field 'user_email'. Could it be a problem, that there is also an element with a class user_email? – Michael Ef Jun 06 '13 at 18:54
  • 1
    @MichaelEf, yes it's possible. I met the same when I have a modal hidden in one project. Though the error should be `Ambitious Match`, it could also be "Can't find". Double check all your html code. – Billy Chan Jun 06 '13 at 19:00
  • The error was still ElementNotFound. The class user_email is generated by simple_form. Didn't find a way to remove this. So I changed the my form fields to :label => 'Email' and 'Password'. Now there is a label generated and printed out but still no success for the js enabled test. – Michael Ef Jun 06 '13 at 19:16
  • @MichaelEf, all sounds correct. A dumb question, is the whole form hidden by JS? If not this reason, I have no clue :( – Billy Chan Jun 06 '13 at 19:33
  • No. I don't need activated JS for this form. The JS test will follow once this works. The login form has no special JS. – Michael Ef Jun 06 '13 at 22:06
1

Take a screenshot after visit new_user_session_path and verify html is being rendered when :js => true.

visit new_user_session_path
save_and_open_page

If nothing is being rendered, just an empty html document, make sure in your spec_helper.rb

config.use_transactional_fixtures = false

Also try using DatabaseCleaner gem.

RSpec.configure do |config|
  config.use_transactional_fixtures = false

  config.before(:suite) do
    DatabaseCleaner.clean_with :truncation
  end

  config.before(:each) do
    if example.metadata[:js]
      DatabaseCleaner.strategy = :truncation
    else
      DatabaseCleaner.strategy = :transaction
    end
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
end
styliii
  • 646
  • 6
  • 13