简体   繁体   中英

Capybara, Javascript and RSpec Integration Tests with :remote => true

I have a form that is set to :remote => true with 2 submit buttons (One for "Test Connection", one to Create/Update). My controller handles this correctly and renders the correct view based on the button that is clicked.

I have the following integration test to make sure that if the data source can connect, it will show the correct message to the user:

describe "Data Source Validation", :js => true do  

  before (:each) do
    @user = create_logged_in_user
  end

  it "returns true when data source is valid" do    
    DataSource.any_instance.stub(:can_connect).and_return(true)    
    visit new_data_source_path
    fill_in "Name", :with => "Example 123"
    fill_in "Host", :with => "myip.example.com"
    select "SQL Server", :from => "Database type"
    fill_in "Database name", :with => "Example"
    fill_in "Username", :with => "user"
    fill_in "Password", :with => "password"
    click_button "Test Connection"
    expect(page).to have_content "Successfully connected to database"
  end

end

I am using gem "capybara-webkit" and I have defined Capybara.javascript_driver = :webkit in spec_helper.rb.

When the test runs, I get the following result:

Failure/Error: expect(page).to have_content "Successfully connected to database"
    expected to find text "Successfully connected to database" in ...

When I view it in Chrome, it works exactly as I expect it to with the correct error message.

How can I get this test condition to pass?

data_source_controller.rb code that is executed for the "Test Connection" method

begin      
  if @data_source.valid? && @data_source.can_connect?          
    format.js {render "valid_connection" }          
  else
    format.js {render "invalid_connection" }          
  end
rescue Exception => e
  format.js {render "invalid_connection", locals: {error_msg: e.message} }          
end

EDIT #1
I switched the javascript driver to :selenium and ran into the same issue. I also attempted to add the "wait_for_ajax" method helper and received an error:

 Failure/Error: wait_for_ajax
 Capybara::Webkit::InvalidResponseError:
   Javascript failed to execute

The full error message with just the normal webkit driver and no wait/sleep:

Failure/Error: expect(page).to have_content "Successfully connected to database"
   expected to find text "Successfully connected to database" in "Dashboard Reports Data Sources Account Create a New Data Source * Name * Host Port * Database type * Database name * Username * Password We encrypt all information in the database. Nothing can be retrieved without the proper credentials and encryption key. Copyright 2013"

What I am expecting is the text, "Successfully connected to the database", to show dynamically after "Password" and before "We encrypt all information in the database"

I hope that gives some more insight, I can try to put together a github project to test this out but this is frustrating trying to get this working

I had a similar problem of rspec/capybara not detecting ajax changes when things seemed to work fine through a browser. This is what worked for me:

Add to GemFile

gem 'capybara-webkit'

Add to host file

127.0.0.1  testhost.com

Add to spec_helper.rb

DEFAULT_HOST = "testhost.com"
DEFAULT_PORT = 7171  

RSpec.configure do |config|
  config.include Capybara::DSL  
  Capybara.javascript_driver = :webkit

  Capybara.default_host = "http://#{DEFAULT_HOST}"
  Capybara.server_port = DEFAULT_PORT
  Capybara.app_host = "http://#{DEFAULT_HOST}:#{Capybara.server_port}"

  #fixes issues with capybara not detecting db changes made during tests
  config.use_transactional_fixtures = false

  config.before :each do
    if Capybara.current_driver == :rack_test
      DatabaseCleaner.strategy = :transaction
    else
      DatabaseCleaner.strategy = :truncation
    end
    DatabaseCleaner.start
  end

  config.after do
    DatabaseCleaner.clean
  end  
end

On the test giving issues add a :js => true flag in the describe header like so:

 describe 'my test', :js => true do

I also could not have the describe block with :js => true nested in other describe blocks, but had to be on its own for it to work, I think this has to do with switching from rack_test to webkit for the test.

Try to create helper method:

def wait_for_ajax
  counter = 0
  while page.execute_script("return $.active").to_i > 0
    counter += 1
    sleep(0.1)
    raise "AJAX request took longer than 5 seconds." if counter >= 50
  end
end

And then:

click_button "Test Connection"
wait_for_ajax
expect(page).to have_content "Successfully connected to database"

我认为这可能是Chrome版本的一个问题,尝试更新驱动程序, 或者你甚至可以参考这个

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM