Capybara:测试JavaScript运行没有错误

时间:2013-07-24 13:28:13

标签: ruby-on-rails capybara

我想写一个请求规范来验证在给定页面上加载和执行javascript而没有任何错误。

我知道我可以在我的JavaScript文件末尾添加一些内容并声明这些内容的存在,但这感觉就像是一个黑客并迫使我因为测试原因而污染我的代码。我更愿意做一些事情。

visit some_path
page.should succesfully_run_javascript

3 个答案:

答案 0 :(得分:4)

您可以在测试中使用以下代码实现此目的。

page.driver.console_messages.each { |error| puts error }
expect(page.driver.console_messages.length).to eq(0)

第一行打印出错误,方便查看正在进行的操作。第二行导致测试失败。

答案 1 :(得分:3)

可能不是很污染的一种方法是通过添加类似这样的内容来收集任何错误(请记住,这将覆盖您可能已经拥有的任何错误处理程序):

<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标记)非常重要,因为它需要是第一个执行的脚本。

答案 2 :(得分:2)

使用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