Capybara 功能规格因 Turbo Drive 而失败

问题描述 投票:0回答:2

我正在尝试在 Rails 6.1 应用程序的几个页面上引入 Turbo Drive。

将一些旧版 JQuery 插件初始化从

$(document).ready()

 调用移至 
document.addEventListener('turbo:load', ..)
 调用后,
Ḯ已按预期获得了结果。

但是,当我运行 Capybara 功能规范时,我可以从失败规范的屏幕截图中看到,例如 JQuery 插件尚未按应有的方式初始化。失败测试的一个典型示例:

scenario 'element is visible', :js do
  visit(my_page_path)
  expect(page.find(#some-jquery-plugin-created-element).text).to \
         eq 'some expected text from the plugin element'
end

任何人都可以帮助我理解为什么这在功能规范中不起作用?在我看来,

turbo:load
事件根本没有被触发。


我尝试过的事情

检查浏览器日志

我在驱动程序中启用登录:

Selenium::WebDriver::Remote::Capabilities.chrome( "goog:loggingPrefs": { browser: 'ALL' } ).

.. 但在失败的

page.driver.browser.manage.logs.get(:browser)
调用之前调用
expect
只会返回一个空数组。

也许我做错了?

确保 Capybara 在页面加载完成之前不会超时

Capybara.default_max_wait_time = 10

ruby-on-rails rspec capybara turbolinks turbo
2个回答
4
投票

写下您的期望,例如

expect(page.find(#some-jquery-plugin-created-element).text).to \
         eq 'some expected text from the plugin element'

您正在击败 Capybaras 重试功能,这将导致动态页面中的大量测试失败。您不应该“永远”将基本的 RSpec 匹配器(eq 等)与 Capybara 相关对象一起使用。

在您的情况下,

find
调用正在等待匹配元素存在,然后获取其文本并检查它。这将会失败,因为当元素首次添加到页面时,它可能还没有完整的文本内容。相反,您应该使用 Capybara 提供的匹配器,它将使用 Capybara 等待行为来匹配事物

expect(page.find(#some-jquery-plugin-created-element)).to have_text('some expected text from the plugin element')

1
投票

根据我的经验:水豚在页面加载后从

visit()
返回,但不一定是在所有脚本运行后。在触发/处理“turbo:load”事件之前,您的测试将立即继续。您可以通过将
sleep()
放入测试中来验证是否是这种情况 - 这将以粗略的方式解决您的问题:

scenario 'element is visible', :js do
  visit(my_page_path)
  sleep 10
  expect(page.find(#some-jquery-plugin-created-element).text).to \
     eq 'some expected text from the plugin element'
end

我的理解是,这就是浏览器的实际工作方式:在显示内容之后、在加载时执行所有脚本之前有一个间隙。对于用户体验而言,这不是问题,因为间隙很短,用户不太可能在短时间内与页面进行交互。测试时情况有所不同,因为它们比人类快得多。

为了使测试工作没有不必要的延迟,您需要确保仅在执行所需的脚本后才继续测试。一种方法是:

  1. 在页面上包含一些隐藏元素,
  2. 使其可见,例如仅在完成其他所有操作后才在您的 Turbo:load 处理程序中,
  3. 在您的测试中,使用具有重试功能的 Capybara 方法等待元素显示。

举个例子,我确实隐藏了整个 HTML 元素:

<html style="visibility: hidden;">

然后只有在 Turbo 加载后才显示:

function showPage(event) {
  document.documentElement.style.visibility="visible";
}
document.addEventListener('turbo:load', showPage);

并且在每次页面加载后,使用具有等待能力的方法,以确保只有在页面完全加载后测试才会继续。

© www.soinside.com 2019 - 2024. All rights reserved.