我在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。对不起英文。
答案 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)来唯一地标识你的元素,而不是返回多个并选择其中一个。如果它只是在页面上异步替换元素的值,那么你不必担心它。