Rspec特征测试 - 渲染空白页面的问题

时间:2017-06-17 09:03:07

标签: ruby-on-rails ruby rspec capybara selenium-chromedriver

我不知道为什么但是在第一个it阻止完成后,Chrome会呈现空白页。

create_account_spec.rb:

require 'feature_helper'
require 'rails_helper'

describe 'Create users' , :chrome do
    let(:company)  { build(:company, :auto_company) }
    let(:financer) { build(:account, :auto_financer) }
    let(:code_1)   { build(:account, :auto_code_1) }
    let(:user)     { build(:account, :auto_user) }

    before :all do
      visit '/'
      company = build(:company, :auto_company)

      GUI.login_as :auto_admin

    # Create Company
    find('#employer_model_screen a').send_keys :enter
    fill_in 'name',           with: company.name
    fill_in 'code_1',         with: company.code1
    fill_in 'code_2',         with: company.code2
    fill_in 'code_3',         with: company.code3
    fill_in 'code_4',         with: company.code4
    select  'Ukraine',        from: 'country_code'
    fill_in 'master_counter', with: company.master_counter
    fill_in 'storage',        with: company.storage
    find('input[value="CREATE"]').send_keys :enter

    GUI.sign_out
  end

  describe 'Check company created', :chrome do
    before :all do
      GUI.login_as :auto_admin
      find('#employer_model_screen a').send_keys :enter
    end

    after :all do
      GUI.sign_out
      visit '/'
    end
    it { expect(first('td.name').text).to eq company.name }
    it { expect(first('td.workflow-type').text).to  eq company.workflow_type }
    it { expect(first('td.code-1').text).to         eq company.code1 }
    it { expect(first('td.code-2').text).to         eq company.code2 }
    it { expect(first('td.code-3').text).to         eq company.code3 }
    it { expect(first('td.code-4').text).to         eq company.code4 }
    it { expect(first('td.country-code').text).to   eq company.country_code }
    it { expect(first('td.business-model').text).to eq 'R1' }
    it { expect(first('td.master-counter').text).to eq company.master_counter.to_s }
    it { expect(first('td.storage').text).to        eq company.storage.to_s }
  end

  context 'financer account' do
    describe 'create financer account', :chrome do
      include_examples 'login as', :auto_admin

      it 'fill financer fields' do
        find('#employer_model_screen a').send_keys :enter
        find('a', text: company.name).send_keys :enter
        fill_in 'emp_id',      with: financer.employee_id
        fill_in 'first_name',  with: financer.first_name
        fill_in 'last_name',   with: financer.last_name
        fill_in 'designation', with: financer.designation
        fill_in 'department',  with: financer.department
        fill_in 'email',       with: financer.email
        find('#create_code2').send_keys :enter
      end

      it { expect(first('td.emp_id').text).to      eq financer.employee_id }
      it { expect(first('td.name').text).to        eq financer.first_name + ' ' + financer.last_name }
      it { expect(first('td.designation').text).to eq financer.designation }
      it { expect(first('td.department').text).to  eq financer.department }
      it { expect(first('td.code_type').text).to   eq 'financer' }
      it { expect(first('td.email').text).to       eq financer.email }
      it { expect(first('td.status').text).to      eq financer.status }
      it { expect(first('.btn-primary').text).to eq 'ACTIVATE' }

      include_examples 'sign out'
    end

    describe 'sign up as financer account', :chrome do
      include_examples 'sign up as', :auto_financer, code: :code2
      include_examples 'check sign up successfully'
      include_examples 'check welcome message'
      include_examples 'sign out'
    end

    describe 'login as financer', :chrome do
      it 'fill email' do
        fill_in 'email', with: financer.email
        sleep(0.5)
      end

      include_examples 'check plan', disabled: :individual, checked: :company

      it 'fill password & Go' do
        fill_in 'password', with: financer.password
        find('[value=Go]').send_keys :enter
      end
      include_examples 'check sign in successfully'
      include_examples 'check navigation items', 'Home', 'Submit', 'Storage (0)',
                       'My Claims', 'Employees\' Claim (0)', 'Sign Out',
                       'Employee Accounts', 'Expense Setup', 'Reports'
      include_examples 'sign out'
    end
  end

  context 'code_1 account' do
    describe 'create code_1 account', :chrome do
      include_examples 'login as', :auto_financer
      it 'fill code_1 fields' do
        find('#employee_accounts_screen a').send_keys :enter
        fill_in 'emp_id',      with: code_1.employee_id
        fill_in 'first_name',  with: code_1.first_name
        fill_in 'last_name',   with: code_1.last_name
        fill_in 'designation', with: code_1.designation
        fill_in 'department',  with: code_1.department
        fill_in 'email',       with: code_1.email
        find('select option[value=User]').select_option
        find('input[value="CREATE"]').send_keys :enter
      end

      # [Question] User are created in the middle of table list (at second position - little weird)
      # I have automated it for 1-st position (like when creating financer account)
      # If it is correct behavior I will change logic
      it { expect(all('td.role')[1].text).to           eq 'User' }
      it { expect(all('td.emp_id')[1].text).to         eq code_1.employee_id }
      it { expect(all('td.name')[1].text).to           eq code_1.first_name + ' ' + code_1.last_name }
      it { expect(all('td.designation')[1].text).to    eq code_1.designation }
      it { expect(all('td.department')[1].text).to     eq code_1.department }
      it { expect(all('td.email')[1].text).to          eq code_1.email }

      include_examples 'sign out'
    end

    describe 'sign up as code_1 account', :chrome do
      include_examples 'sign up as', :auto_code_1, code: :code1
      include_examples 'check sign up successfully'
      include_examples 'check welcome message'
      include_examples 'sign out'
    end

    describe 'login as code_1', :chrome do
      it 'fill email' do
        fill_in 'email', with: code_1.email
        sleep(0.5)
      end

      include_examples 'check plan', disabled: :individual, checked: :company

      it 'fill password & Go' do
        fill_in 'password', with: code_1.password
        find('[value=Go]').send_keys :enter
      end
      include_examples 'check sign in successfully'
      include_examples 'check navigation items', 'Home', 'Submit', 'Storage (0)',
                       'My Claims', 'Employees\' Claim (0)', 'Sign Out'
      include_examples 'sign out'
    end
  end

  context 'user account' do
    describe 'sign up as user account ', :chrome do
      include_examples 'sign up as', :auto_user
      include_examples 'check sign up successfully'
      include_examples 'check welcome message'
      include_examples 'sign out'
    end

    describe 'login as user', :chrome do
      it 'fill email' do
        fill_in 'email', with: user.email
        sleep(0.5)
      end

      include_examples 'check plan', disabled: :company, checked: :individual

      it 'fill password & Go' do
        fill_in 'password', with: user.password
        find('[value=Go]').send_keys :enter
      end
      include_examples 'check sign in successfully'
      include_examples 'check navigation items', 'Home', 'Submit',
                       'Storage (0)', 'My Claims', 'Sign Out'
      include_examples 'sign out'
    end
  end

  context 'duplicate user' do
    describe 'sign up as duplicate user', :chrome do
      include_examples 'sign up as', :auto_user
      include_examples 'check review errors message'
      it 'check warning message ' do
        expect(find('.user-form')).to be_visible
      end
    end
  end
end

feature_helper:

require 'capybara/rspec'
require 'capybara/poltergeist'

require './spec/support/helpers/feature_helper'
require './spec/support/shared_examples/sign_in_examples'
require './spec/support/shared_examples/sign_up_examples'
require './spec/support/shared_examples/main_page_examples'

# Configure Capybara
Capybara.register_driver :chrome do |app|
  Capybara::Selenium::Driver.new(app, :browser => :chrome)
end
Capybara.default_driver = :poltergeist
Capybara.javascript_driver = :poltergeist
Capybara.current_driver = :chrome
Capybara.app_host = 'http://0.0.0.0:3000/'
Capybara.exact = true

RSpec.configure do |config|
  config.expect_with :rspec do |expectations|
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
    config.include Capybara::DSL, :type => :request
  end

  config.mock_with :rspec do |mocks|
    mocks.verify_partial_doubles = true
  end
end

支持/ feature_helper.rb

require 'capybara/dsl'

module GUI
  extend Capybara::DSL

  class << self
    def login_as(user)
      binding.pry
      user = FactoryGirl.build(:account, user)
      find('a', text: 'Sign In').send_keys :enter
      fill_in 'email',    with: user.email
      fill_in 'password', with: user.password
      find('[value=Go]').send_keys :enter
    end

    def sign_out
      binding.pry
      find('a', text: 'Sign Out').send_keys :enter
    end
  end
end

的Gemfile:         group:开发,:test do       宝石'dotenv-rails'       宝石'撬轨'       宝石'byebug'       宝石'factory_girl_rails'       宝石'rspec-rails'       宝石'chromedriver-helper'     端

group :test do
  gem 'capybara'
  gem 'selenium-webdriver'
  gem 'poltergeist'
  gem 'codeclimate-test-reporter', require: false
  gem 'database_cleaner'
  gem 'simplecov', require: false # Test Coverage analytics
  gem 'shoulda-matchers', '~> 3.1'
  gem 'webmock' # Mocking http request
  gem 'terminal-notifier-guard' # for OSX
  gem 'rspec-steps'
end

如果我在expect块上写下所有it,它就可以正常工作。

提前致谢。

1 个答案:

答案 0 :(得分:2)

针对此特定问题的问题是,您的visit来电位置错误,但更大的问题是您正在编写单元测试等功能测试。

每个it块都是一个单独的测试,假设您正在使用标准的Capybara rspec集成,最后完成的任务之一就是访问about:blank。这将在您after :all阻止之后发生。因此,您要测试的页面的visit应该在您的before :all区块或单独的测试中发生。此外,由于数据库/应该在每个测试(it / scenario块之间重置),因此通常不需要注销。

before :all do
  visit '/' # Alternatively you could move this to your login_as method
  GUI.login_as :auto_admin
  find('#employer_model_screen a').send_keys :enter
end

# Not generally necessary for tests of the type you show
# after :all do
#   GUI.sign_out
#   visit '/'
# end

现在,更大的问题是您正在测试整个&#34;功能&#34;然后在每个测试中测试单个视觉元素。这意味着要查看是否显示公司名称,必须创建公司,创建用户,让浏览器访问页面,然后登录,然后检查名称。接下来,它要检查国家/地区类型,以便它必须再次创建公司,创建用户,让浏览器访问同一页面,然后登录,然后检查国家/地区类型。如果你继续编写这样的功能测试,他们很快就会花费数小时甚至数天才能运行。如果您检查的目的是显示所有公司信息,那么它应该是一个it / scenario

it "shows the company info" do
  expect(page).to have_css('td.name'.text: company.name)
  expect(page).to have_css('td.workflow-type', text: company.workflow_type)
  ...
end

还要注意使用capybara提供的匹配器,而不是.texteq,这样一旦你开始拥有ajax /异步操作和页面更新,它将使你的测试更加稳定,因为它提供了等待/重试检查行为。 (您应尽可能远离all / first,因为它们对动态网页有严重限制)