是否可以使用Selenium/Capybara截取整个页面的屏幕截图?

31

PhantomJS有一个选项可以截取整个页面的截图(不仅仅是当前视口)。是否有任何方法可以使用Selenium实现这样的功能?我正在使用headless gem以无头模式运行Cucumber/Capybara测试。我本来想使用PhantomJS,但我遇到了一些其他问题。


3
Capybara有一个方法可以实现这个功能 - http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#save_screenshot-instance_method。它也被Selenium支持。 - Andrei Botalov
4个回答

55

如果有人搜寻如何使用 Poltergeist 实现此操作,您只需要传递 full 参数:

Translated:

假如有人在这里寻找如何使用Poltergeist 来实现此操作,你只需要传递 full 参数:

page.save_screenshot('screen.png', full: true) # If providing a custom file name.
page.save_screenshot(full: true)               # Capybara sets a name based on timestamp.
page.save_and_open_screenshot('screen.png', full: true) # Same as save_screenshot.
page.save_and_open_screenshot(full: true)               # Same as save_screenshot.

文档.

希望它能帮到你!


太棒了,谢谢!我选择使用 puts save_screenshot(nil, full: true) 这个命令,这样它就会生成一个随机的文件名并将其打印出来。 - Asfand Qazi

9
原来我一直在使用headless gem提供的take_screenshot方法,而我可以直接使用page.save_screenshot()方法,它完全满足我的需求。谢谢Andrey。

3

我尝试了很多方法来让Capybara/Selenium实现页面的完整高度。

只有一个尝试成功了,那就是使用headless_chrome。需要注意的是,我使用一个循环在不同的宽度下进行截屏:

最初的回答:

  def screenshot
    driver = Capybara.current_session.driver
    window = Capybara.current_session.driver.browser.manage.window
    widths = [320, 1380] #leave normal w as last
    widths.each do |w|
      window.resize_to(w, 900)
      total_width = driver.execute_script("return document.body.offsetWidth")
      total_height = driver.execute_script("return document.body.scrollHeight")
      window.resize_to(total_width, total_height)
      save_screenshot
    end
  end

我将其调整两次以获取高度信息。

rails_helper.rb:

Capybara.register_driver :headless_chrome do |app|
  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    chromeOptions: { 
      "args" => %w{ 
        headless 
        disable-gpu
        --disable-notifications
      } 
    }
  )
  Capybara::Selenium::Driver.new app,
    browser: :chrome,
    desired_capabilities: capabilities
end

Capybara.javascript_driver     = :headless_chrome
Capybara.current_driver        = :headless_chrome

你会把 def screenshot 这个方法放在哪个文件里?只是一个规范辅助文件吗? - littleforest
@littleforest 将任何所需的文件导入到你的 spec/rails_helper.rb 中。所以,一个 helper 就可以了。 - pixelearth

1
您也可以这样做:

After do |scenario|
  take_screenshot(@browser, scenario)
end

def take_screenshot(browser, scenario)
  if scenario.failed?
    scenario_name = scenario.name.gsub /[^\w\-]/, ' '
    time = Time.now.strftime("%Y-%m-%d %H%M")
    screenshot_path = './failed_png/' + time + ' - ' + scenario_name + '.png'
  else
    scenario_name = scenario.name.gsub /[^\w\-]/, ' '
    time = Time.now.strftime("%Y-%m-%d %H%M")
    screenshot_path = './success_png/' + time + ' - ' + scenario_name + '.png'
  end
  browser.save_screenshot(screenshot_path)
end

如果您创建了一个failed_png和success_png文件夹,这段代码将为每个成功和失败的屏幕截图,并将其放入相应的文件夹中,并带有时间戳。此代码放入您的env.rb文件中,使您无需使用任何助手或添加任何额外的代码到您的步骤定义中。

谢谢,Whitney。我已经设置了自动截图,但只在出现故障时才会进行。同时,我也会输出失败时的HTML以进行调试。我使用类似于 File.open("errors/#{filename}.html", 'w') {|f| f.write(page.html)} 的代码。 - TrashyMcTrash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接