capybara不等待ajax请求

时间:2017-02-26 20:27:58

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

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

@Repository

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

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

当我插入睡眠1:

   expected: "-1"
        got: "0"

测试通行证。

我理解该页面没有等待异步请求。 如何在不睡觉的情况下重写测试以使其正常工作?

P.S。对不起英文。

1 个答案:

答案 0 :(得分:4)

使用eq匹配器可以消除任何等待行为。这是因为一旦在找到的元素上调用.text,就会有一个String,当与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)来唯一地标识你的元素,而不是返回多个并选择其中一个。如果它只是在页面上异步替换元素的值,那么你不必担心它。