You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Capybara测试中如何仅在存在窗口时执行page.save_screenshot截图

Capybara 失败截图条件判断方案

直接在spec_helper.rb的config.after(:each)钩子中加入多层校验逻辑,仅在真实存在已打开的浏览器窗口(兼容无头/非无头模式)时才执行截图,避免无浏览器场景下自动唤起浏览器的问题。

核心实现代码

RSpec.configure do |config|
  config.after(:each) do |example|
    # 用例通过时直接跳过
    next unless example.exception

    # 逐层校验是否满足截图前提
    current_driver = Capybara.current_driver
    browser = page.driver.browser

    # 1. 排除rack_test这类无真实浏览器的驱动
    next if current_driver == :rack_test
    # 2. 校验底层是否存在浏览器实例(过滤rest-client等纯接口测试场景)
    next unless browser.respond_to?(:window_handles)
    # 3. 校验是否存在已打开的窗口/标签页
    next if browser.window_handles.empty?

    # 所有条件满足时再保存截图
    screenshot_path = "tmp/failure_screenshots/#{example.full_description.parameterize}.png"
    page.save_screenshot(screenshot_path)
  end
end

判断逻辑说明

  • 第一层过滤默认的rack_test驱动:该驱动是纯内存模拟的HTTP请求工具,没有真实浏览器进程,本身不支持截图
  • 第二层校验window_handles方法存在性:纯接口测试场景下虽然能访问到page对象,但底层没有绑定浏览器实例,不会响应该方法,直接跳过即可
  • 第三层校验窗口句柄非空:不管是无头还是有头模式,只要浏览器已经启动且打开了至少一个页面,window_handles就会返回非空的句柄数组;如果没有打开的窗口,该数组为空,此时调用截图方法就会触发Capybara自动启动新浏览器,直接跳过就能规避这个问题。

自定义驱动适配

如果项目中使用了Cuprite、Apparition等其他浏览器驱动,或者自定义了专门的接口测试驱动,可以加一层驱动白名单强化判断:

# 定义允许截图的浏览器驱动列表
BROWSER_DRIVERS = [:selenium_chrome, :selenium_chrome_headless, :cuprite, :apparition].freeze

# 在钩子最前面加入校验
next unless BROWSER_DRIVERS.include?(Capybara.current_driver)

内容的提问来源于stack exchange,提问作者Phil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 23:15:11