Capybara:ElementNotFound:无法在多部分表单上找到字段名称

sir*_*iel 5 ruby-on-rails capybara rspec2

我在尝试使用此功能规范时难以隔离问题.

require 'spec_helper'

feature 'Add Employee', type: :feature do 
  scenario 'with valid information' do
    # visit setup_add_employees_path
    visit '/setup/add_employees'
    # save_and_open_page
    fill_in "First Name", with: 'Test'
    fill_in 'Last Name', with: 'Employee'
    fill_in 'Email', with: 'testemployee@example.com'
    # fill_in , with: 'testemployee@example.com'

    # expect(page).to find_field('First Name').value
  end
end
Run Code Online (Sandbox Code Playgroud)

这是多部分表单的第2步,我编写了第一步的规范并且工作正常.但是,在此规范中,使用表单字段的fill_in不会.

以下是此规范的相关文件:

# add_employees.html.haml

= render "partials/nav_left_setup"
- model_class = Invitation.new.class
#alert_message
.page-header
  %h1 Invite Your Employees
%p.lead Now it's time to add your employees to HuddleHR. We'll send an email to your employees when setup is complete. Don't worry, the email will include instructions on how to setup their account and update their personal information.
%p.lead
  If you like, you can import your employee list from an
  = succeed "." do
    %a#show_import_form{ href: "#" } Excel file

= render "partials/setup_import_employees"

= nested_form_for @account, :html => {:class => "invitation"} do |f|
  %br/
  = f.fields_for :invitations, @invitations do |invitation_form|
    = invitation_form.hidden_field :product_id, :value => "1"
    = invitation_form.text_field :first_name, :class => "input-small", :placeholder => "First Name", :required => :true
    = invitation_form.text_field :last_name, :class => "input-small", :placeholder => "Last Name", :required => :true
    %span= invitation_form.email_field :email, :class => "text_field", :placeholder => "Email Address", :required => :true
    = invitation_form.collection_select :team_id, @teams, :id, :name
    - if invitation_form.object.new_record?
      = hidden_field_tag :invitaion_new_record, "new record"
      = link_to "Delete", "javascript:void(0);", :class => "btn btn-danger  delete_invitation_row_button", :style => "margin-bottom: 12px"
    - else
      = link_to "Delete", invitation_form.object, :confirm => "Are you sure?", :method => :delete, :remote => true, :class => "btn btn-danger btn-delete destroy_duplicate_nested_form", :style => "margin-bottom: 12px"
  = f.link_to_add raw("<i class=\"icon-plus-sign icon-white\"></i> Add An Employee"), :invitations, class: "btn btn-success"
  .form-actions
    = link_to "Back", @optional_step.prv_link, class: "btn"
    = f.submit "Save & Continue", :class => "btn btn-primary"
    = link_to "Skip This Step", @optional_step.next_link, class: "btn" if @optional_step.optional == true


# The accounts_controller's create method

  def create # TODO we need to document this...
    @account = Account.new(params[:account])

    if @account.save
      # Send the account setup email to the account creator
      UserMailer.account_setup_email(current_user).deliver

      current_user.add_role!(User::ROLES[0]) # asigning the role roster_admin
      current_user.add_role!(User::ROLES[3]) # asigning the role employee

      # Sign the account up for Roster and create some inital records like:
      # Register Roster as a product the account has subscribed to.
      AccountProduct.create!(:account_id => @account.id, :product_id => Product.where(:name => "Roster").first.id)

      # Create the account holder's profile
      Profile.create!(:user_id => current_user.id, :first_name => @account.account_owner_first_name_input, :last_name => @account.account_owner_last_name_input)

      # Create their first default team so they have a place to keep people
      Team.create!(name: "Example Team", description: "This is just a placeholder team. You can rename or delete it.", account_id: @account.id, manager_id: current_user.id)

      # Create their first job description so they have a place to keep people
      JobDescription.create!(title: "Example Job Description", description: "This is just a placeholder job description. You can rename or delete it.", account_id: @account.id)

      # Create a first post for the company so they have something on their homepage...
      Post.create!(title: "Welcome to HuddleHR", body: "The simple and easy way to manage employee information in the cloud. You can invite employees, setup your org chart, fill out your profile and more.", account_id: @account.id, author_id: current_user.id, scope_id: "1")

      # Create the initial employment record
      Employment.create!(:user_id => current_user.id, :team_id => Team.find_by_account_id(@account.id).id, :effective_date => Date.today, :comment => "Initial creation of HuddleHR account owner employment record.")

      # Set the User.account_id to the created account.id
      current_user.update_attributes!(:account_id => @account.id)

      setup_steps = @account.product_setup_steps

      current_step = ProductSetupStep.where("link =? AND product_id =?", URI(request.referer).path, 1).first # Getting the current step

      if current_step
        setup_steps << ProductSetupStep.where("link =? AND product_id =?", URI(request.referer).path, 1).first
        setup_steps << ProductSetupStep.where("step_number =? AND product_id =?", 1, 1).first
        redirect_to current_step.next_link, :notice => 'Your account was successfully created.' if current_step.next_link.present?
        redirect_to account_path(@account), :notice => 'Your account was successfully created.' unless current_step.next_link.present?
      else
        redirect_to account_path(@account), :notice => 'Your account was successfully created.'
      end

    else
      render :action => "new"
    end
  end
# the imacros file, which I'm told is similar to selenium 

' Add Employee
TAG POS=1 TYPE=A ATTR=TXT:Add<SP>An<SP>Employee
TAG POS=1 TYPE=INPUT:TEXT FORM=ID:edit_account_*  ATTR=ID:account_invitations_attributes_*_first_name CONTENT=Test
TAG POS=1 TYPE=INPUT:TEXT FORM=ID:edit_account_* ATTR=ID:account_invitations_attributes_*_last_name CONTENT=Employee{{!VAR1}}
TAG POS=1 TYPE=INPUT:EMAIL FORM=ID:edit_account_* ATTR=ID:account_invitations_attributes_*_email CONTENT=testemployee{{!VAR1}}@huddlehr.com
TAG POS=1 TYPE=INPUT:SUBMIT FORM=ID:edit_account_* ATTR=NAME:commit
TAG POS=1 TYPE=INPUT:SUBMIT FORM=ID:edit_account_* ATTR=NAME:commit
TAG POS=1 TYPE=A ATTR=TXT:Send<SP>Invitations<SP>To<SP>These<SP>Employees
TAG POS=1 TYPE=A ATTR=TXT:Finish<SP>Setup
TAG POS=1 TYPE=A ATTR=TXT:Finish
Run Code Online (Sandbox Code Playgroud)

如果我不得不猜测,我会说问题在于我没有背景块来模仿这种形式的第2步所加载的东西.在步骤1中,背景块包含sign_up_with(电子邮件,传递).因此,如果我正确的背景是fill_in无法找到我的form_field id名称的原因,那么我需要在step2功能规范的背景块中设置什么?

顺便说一下,第1步是一个名为create account的规范,看起来像这样:

# create_account_spec.rb

require 'spec_helper'
# require 'ruby-debug'

feature 'Create Account', type: :feature do
  background do
    sign_up_with Faker::Internet.email, '1Password'
  end

  scenario 'Fill form data' do
    # visit '/setup'
    visit new_account_path
    fill_in 'First Name', with: 'Test'
    fill_in 'Last Name', with: 'Owner'
    fill_in 'Company Name', with: 'Company'
    fill_in :account_addresses_attributes_0_line_one, with: '133 Main St'
    fill_in :account_addresses_attributes_0_city, with: 'Columbia'
    select 'SC', from: 'State'
    fill_in :account_addresses_attributes_0_zip, with: '11111'
    fill_in :account_phone_numbers_attributes_0_number, with: '(111) 111-11111'
    select '(GMT-05:00) Eastern Time (US & Canada)', from: 'Time zone'
    click_button('Save & Continue')
  end
end
Run Code Online (Sandbox Code Playgroud)

我已经阅读了以下相关资源,以便更好地了解Capybara和集成测试:

使用capybara和rspec的未定义方法``

Capybara在github上的README

Capybara :: ElementNotFound,但它就在那里

rspec测试结果Capybara :: ElementNotFound

Capybara :: ElementNotFound:错误

如何解决Capybara :: ElementNotFound错误

sir*_*iel 1

好吧,据我所知,问题是我没有正确设置我的背景来模仿多表单集成规范的第 2 部分所在的站点。我通过使用 FactoryGirl 创建一个用户,然后使用 Capybara 的 fill_in 和 user.email && user.password 来解决这个问题,而不是使用上面看到的 faker。

这是我目前的规格:

# spec/features/add_employee_spec.rb
require 'spec_helper'

feature 'Add Employee', type: :feature do 
  background do
    user = create :user
    visit user_session_path
    fill_in 'Email', with: user.email
    fill_in 'Password', with: user.password
    click_button 'Sign In'

    expect(page).to have_content('Setup An Account')
  end

  scenario 'clicks Add A New Employee and fills out the form' do
    account = create :account
    save_and_open_page
    visit setup_add_employees_path
    fill_in 'first_name', with: 'Test'
    fill_in 'Last Name', with: 'Employee'
    fill_in 'Email', with: 'testemployee@example.com'
  end
end
Run Code Online (Sandbox Code Playgroud)

当使用 Faker 为注册生成不同的用户名时,我不正确地设置了“背景”块,就好像我是一个想要第一次注册的用户一样。

如果我还忽略了其他任何内容,或者可能是有关改进集成规范的一些其他提示,我期待您的评论。