javascript Capybara with :js => true 导致测试失败

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8178120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 02:33:33  来源:igfitidea点击:

Capybara with :js => true causes test to fail

javascriptruby-on-rails-3capybara

提问by evanmcd

I'm new to Capybara and testing on Rails in general, so please forgive me if this is a simple answer.

我是 Capybara 的新手,一般在 Rails 上测试过,所以如果这是一个简单的答案,请原谅我。

I've got this test

我有这个测试

it "should be able to edit an assignment" do
    visit dashboard_path
    select(@project.client + " - " + @project.name, :from => "assignment_project_id")
    select(@team_member.first_name + " " + @team_member.last_name, :from => "assignment_person_id")
    click_button "Create assignment"
    page.should have_content(@team_member.first_name)
end

it passes as is, but if I add :js => true it fails with

它按原样通过,但是如果我添加 :js => true 它会失败

cannot select option, no option with text 'Test client - Test project' in select box 'assignment_project_id'

I'm using FactoryGirl to create the data, and as the test passes without JS, I know that part is working.

我正在使用 FactoryGirl 创建数据,并且当测试在没有 JS 的情况下通过时,我知道该部分正在工作。

I've tried with the default JS driver, and with the :webkit driver (with capybara-webkit installed)

我已经尝试过使用默认的 JS 驱动程序和 :webkit 驱动程序(安装了 capybara-webkit)

I guess I don't understand enough what turning on JS for Capybara is doing.

我想我不太了解为 Capybara 打开 JS 正在做什么。

Why would the test fail with JS on?

为什么在 JS 上测试会失败?

回答by brutuscat

I've read the Capybara readme at https://github.com/jnicklas/capybaraand it solved my issue.

我在https://github.com/jnicklas/capybara阅读了 Capybara 自述文件,它解决了我的问题。

Transactional fixtures only work in the default Rack::Test driver, but not for other drivers like Selenium. Cucumber takes care of this automatically, but with Test::Unit or RSpec, you may have to use the database_cleaner gem. See this explanation(and code for solution 2and solution 3) for details.

事务性装置仅适用于默认的 Rack::Test 驱动程序,但不适用于 Selenium 等其他驱动程序。Cucumber 会自动处理这个问题,但是对于 Test::Unit 或 RSpec,您可能必须使用 database_cleaner gem。有关详细信息,请参阅此说明(以及解决方案 2解决方案 3 的代码)。

But basically its a threading issue that involves Capybara having its own thread when running the non-Rack driver, that makes the transactional fixtures feature to use a second connection in another context. So the driver thread is never in the same context of the running rspec.

但基本上它是一个线程问题,涉及 Capybara 在运行非 Rack 驱动程序时拥有自己的线程,这使得事务夹具功能在另一个上下文中使用第二个连接。因此驱动程序线程永远不会与正在运行的 rspec 处于同一上下文中。

Luckily this can be easily solve (at least it solved for me) doing a dynamic switching in th DatabaseCleaner strategy to use:

幸运的是,这可以很容易地解决(至少对我来说已经解决了)在使用的 DatabaseCleaner 策略中进行动态切换:

RSpec.configure do |config|
  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

回答by Aidan Feldman

A variation of brutuscat's answerthat fixed our feature specs (which all use Capybara):

brutuscat 答案的变体,修复了我们的功能规格(均使用 Capybara):

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

config.before(:each) do
  # set the default
  DatabaseCleaner.strategy = :transaction
end

config.before(:each, type: :feature) do
  DatabaseCleaner.strategy = :truncation
end

config.before(:each) do
  DatabaseCleaner.start
end

config.append_after(:each) do
  DatabaseCleaner.clean
end

回答by Lars Schirrmeister

There is another way to deal with this problem now described and discussed here: Why not use shared ActiveRecord connections for Rspec + Selenium?

现在这里描述和讨论的还有另一种处理这个问题的方法:为什么不为 Rspec + Selenium 使用共享的 ActiveRecord 连接?