我在 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/