ruby-on-rails - capybara 不等待ajax请求

标签 ruby-on-rails rspec capybara poltergeist capybara-webkit

我在 rspec + capybara + poltergeist 中收到以下错误:

given!(:user_owner) { create(:user) }
given!(:second_user) { create(:user) }
given!(:question) { create(:question, user: user_owner) }

describe 'as not question owner' do
  before do
    login_as(second_user, scope: :user, run_callbacks: false)
    visit question_path(question)
  end

  scenario 'can upvote just one time', js: true do
    first('a#question-upvote').click
    expect(first('div#question-score').text).to eq '1'
    first('a#question-upvote').click
    expect(first('div#question-score').text).to eq '1'
  end

失败/错误:expect(page.first('div#question-score').text).to eq '-1'

   expected: "-1"
        got: "0"

当我插休眠眠1时:

scenario 'can upvote just one time', js: true do
   first('a#question-upvote').click
   sleep 1
   expect(first('div#question-score').text).to eq '1'
   first('a#question-upvote').click
   sleep 1
   expect(first('div#question-score').text).to eq '1'
end

测试通过。

我知道页面没有等待异步请求。 我怎样才能重写测试以使其在不 sleep 的情况下正常工作?

附注抱歉英语不好。

最佳答案

您可以使用 eq 匹配器来终止任何等待行为。这是因为一旦您在找到的元素上调用 .text ,您就有了一个字符串,并且在与 eq 匹配器一起使用时无法重新加载/重新查询该字符串。如果您想要等待/重试行为,您需要将 Capybara 提供的匹配器与 Capybara 元素结合使用。

所以你应该做的不是 expect(first('div#question-score').text).to eq '1'

expect(first('div#question-score')).to have_text('1', exact: true) # you could also use a Regexp instead of specifying exact: true

另一件事要注意的是 all/first 禁用元素的重新加载,因此如果整个页面正在更改(或者您正在等待文本的元素正在被更改)完全替换)并且初始页面有一个与选择器匹配的元素,但您实际上希望检查第二页中的元素(或替换元素),您不应该使用 first/all - 在这种情况下,您需要使用 find 进行查询,使用 css :first-child/:first-of-type 等类型的内容(或等效的 XPath)来唯一地标识您的元素,而不是返回多个元素并选择其中之一。如果只是页面上异步替换元素的值,那么您不必担心。

关于ruby-on-rails - capybara 不等待ajax请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42473848/

相关文章:

ruby-on-rails - 与 Ruby 中的 Time.now.advance() 相反

ruby-on-rails - Twitter 仍然在 Rails 上运行吗?

ruby-on-rails - RSpec 测试失败 - 显示套接字已占用但锁定文件丢失

ruby-on-rails - 使用 RSpec 测试 Rails Controller ——如何测试 : current_account. 项目

javascript - 有没有办法使用 Rspec/Capybara/Selenium 将 javascript console.errors 打印到终端?

ruby-on-rails - 在 ActionMailer 中使用助手

ruby-on-rails - FactoryGirl 和 RSpec : create a record with required nested_attributes for specs

rspec - 如何在 rspec 中抑制警告 "removing ` 初始化'可能会导致严重问题”?

ruby-on-rails - #<Class :XYZ> (NoMethodError) [rspec] 的未定义方法 'visit'

ruby-on-rails - 在 Rails/Capybara/Poltergeist 规范中使用 url_for 将驱动程序发送到 example.com 而不是应用程序