以@Billy 的建议为基础,log/test.log
并没有给我任何有用的信息,而且我已经在使用js: true
,所以我尝试了这个:
begin
expect { click('.fake_button'); sleep 1 }.to change { clicks.count }.by(1)
rescue Exception => e
begin
timestamp = Time::now.strftime('%Y%m%d%H%M%S%L')
begin
screenshot_name = "tmp/capybara/capybara-screenshot-#{timestamp}.png"
$stderr.puts "Trying to save screenshot #{screenshot_name} due to test failure"
page.save_screenshot(screenshot_name)
rescue Exception => inner
$stderr.puts "Ignoring exception #{inner} while trying to save screenshot of test page"
end
begin
# Page saved by Capybara under tmp/capybara/ by default
save_page "capybara-html-#{timestamp}.html"
rescue Exception => inner
$stderr.puts "Ignoring exception #{inner} while trying to save HTML of failed test page"
end
ensure
raise e
end
end
后来我通过执行以下操作更改了测试本身以利用 Capybara 的 AJAX 同步功能:
starting_count = clicks.count
click('.fake_button')
page.should have_css('.submitted') # Capybara is smart enough to wait for this to happen
clicks.count.should == starting_count + 1
请注意,我正在寻找的 CSS 是通过 AJAX 回调在 JavaScript 中添加到页面的内容,因此它的显示是 AJAX 调用完成的信号。
这些rescue
块很重要,因为屏幕截图的失败率很高,因为没有足够的内存来呈现整个页面并将其转换为图像。
编辑
虽然我还没有尝试过,但有希望的解决方案是Capybara::Screenshot,它会在任何失败时自动保存屏幕截图和 HTML。只是阅读代码,当屏幕截图失败时它看起来会出现问题,并且我无法判断屏幕截图被触发时页面将处于什么状态,但它看起来确实值得一试。