为什么这个水豚测试在 运行 编程时失败,但在手动完成时通过?

Why is this capybara test failing when running programmatically, but passing when done manually?

我在 Rspec/Capybara 中有一个非常简单的测试,它表现出一些奇怪的行为。当我 运行 使用 rspec <filename> 进行测试时,Capybara 无法单击按钮,因此测试失败。如果我 pry 测试和 copy/paste 完全相同的代码行,则单击按钮并且测试通过。我正在尝试找出如何调试差异。

测试:

    context "when menu is open" do
      before do
        visit root_path
        page.find("svg", class: "fa-bars").click
      end

      it "shows bars again once closed" do
        page.find("svg", class: "fa-times").click(wait: 5)
        expect(page).to have_css(".fa-bars")
      end
    end

在 find/click 之前放置一个 binding.pry,然后 运行ning 该行,效果很好。我对为什么行为如此不同感到困惑。

我们的系统在 Selenium 上测试 运行:

  config.before(:each, type: :system) do
    if !!ENV['SYSTEM_TESTS_BROWSER_MODE']
      driven_by :selenium, using: :firefox
    else
      driven_by :selenium_headless
    end
  end

当你说“点击失败”时,我假设你并不是说你从 page.find("svg", class: "fa-times").click(wait: 5) 收到了错误,而是说线路运行正常,你的 expect(page).to have_css(".fa-bars") 是真正失败的地方。

鉴于此,你的描述告诉我水豚实际上点击得很好,但它发生在菜单准备好将点击解释为关闭之前。当您添加 binding.pry 时,您就是在给菜单时间来完成打开。关于传递 wait 参数,您需要了解的一点是它设置了 Capybara 等待元素存在的最长时间。如果该元素在此时间之前存在,Capybara 将继续前进,因此当 wait: 5 在该行上没有错误时设置 wait: 10 将没有任何区别(已经满足条件 - 允许它等待更长的时间是没有意义的) .您可以通过在 find/click 行之前放置一个 sleep(2) 来延迟查找并单击足够长的时间以使菜单在单击恰好将其关闭之前打开来确认这一点。对测试的正确修复是在测试环境中禁用动画(这样菜单会立即打开),或者对菜单的某些状态添加额外的期望,表明它实际上已完全打开并准备好接收关闭它的点击。