我想编写一个请求规范,验证给定页面上 javascript 的加载和执行,没有任何错误。
我知道我可以在我的 JavaScript 文件的末尾添加一些东西到 DOM 并断言这个内容的存在,但这感觉就像一个 hack 并且迫使我出于测试原因污染我的代码。我宁愿做一些类似的事情。
visit some_path
page.should succesfully_run_javascript
我想编写一个请求规范,验证给定页面上 javascript 的加载和执行,没有任何错误。
我知道我可以在我的 JavaScript 文件的末尾添加一些东西到 DOM 并断言这个内容的存在,但这感觉就像一个 hack 并且迫使我出于测试原因污染我的代码。我宁愿做一些类似的事情。
visit some_path
page.should succesfully_run_javascript
您可以在测试中使用以下代码来实现这一点。
page.driver.console_messages.each { |error| puts error }
expect(page.driver.console_messages.length).to eq(0)
第一行打印出一个错误,方便查看发生了什么。第二行导致测试失败。
一种可能不会造成很大污染的方法是通过在 head 中添加类似这样的内容来收集任何错误(请记住,这将覆盖您可能已经拥有的任何 onerror 处理程序):
<script>
window.errors = [];
window.onerror = function(error, url, line) {
window.errors.push(error);
};
</script>
然后,您可以执行以下操作:
page_errors = page.evaluate_script('window.errors')
并断言数组为空。否则您可以输出错误...
注意:将 scriptlet 添加到 head(可能作为第一个 scriptlet/script 标记)很重要,因为它必须是第一个执行的脚本之一。
使用的一个问题page.driver.console_messages
是它在测试之间并不清楚。因此,如果您只想断言特定测试中没有错误,则规范可能会由于先前的测试而失败。
console.log
您可以通过保存最后一个时间戳将这些错误限定为特定规范。
辅助方法:
def assert_no_js_errors
last_timestamp = page.driver.browser.manage.logs.get(:browser)
.map(&:timestamp)
.last || 0
yield
errors = page.driver.browser.manage.logs.get(:browser)
.reject { |e| e.timestamp > last_timestamp }
.reject { |e| e.level == 'WARNING' }
assert errors.length.zero?, "Expected no js errors, but these errors where found: #{errors.join(', ')}"
end
然后像这样使用它:
def test_somthing_without_js_errors
assert_no_js_errors do
# TODO: Write test
end
end