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
相关产品推荐
相关产品推荐

