水豚不等待 ajax 请求
capybara not wait ajax request
我在 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
Failure/Error: 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
测试通过。
我了解到页面未等待异步请求。
如何重写测试以使其在不睡觉的情况下正常工作?
P.S。对不起英语。
您正在使用 eq
匹配器终止任何等待行为。这是因为一旦你在找到的元素上调用 .text
你就有了一个 String 并且在与 eq
匹配器一起使用时无法 reload/re-query 该字符串。如果你想要 waiting/retrying 行为,你需要使用 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)的查询一起使用来唯一标识您的元素,而不是返回倍数和选择其中之一。如果只是页面上被异步替换的元素的值那么你不用担心。
我在 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
Failure/Error: 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
测试通过。
我了解到页面未等待异步请求。 如何重写测试以使其在不睡觉的情况下正常工作?
P.S。对不起英语。
您正在使用 eq
匹配器终止任何等待行为。这是因为一旦你在找到的元素上调用 .text
你就有了一个 String 并且在与 eq
匹配器一起使用时无法 reload/re-query 该字符串。如果你想要 waiting/retrying 行为,你需要使用 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)的查询一起使用来唯一标识您的元素,而不是返回倍数和选择其中之一。如果只是页面上被异步替换的元素的值那么你不用担心。