How to take a screenshot of a full browser page and its elements using selenium-webdriver/capybara in Ruby?

强颜欢笑 提交于 2020-07-18 10:43:06

问题


I am working on screenshot automation. In particular, I am trying to achieve the following:

  1. Prompt the user for the links to different pages on the website X
  2. Prompt the user for the class name Y
  3. I should be able to visit a website X login page, provide login details (assume they are known), click on "submit" button, that should redirect me to the "home" page
  4. Then I look at the list of links, provided by the user, visit each page and take screenshots of all elements, that have class Y (or the entire page)
  5. Save them in the current directory

Please click on the link for visual representation

I wanted to implement the following solution in Ruby (but I am also open to any other suggestions):

1) Take a screenshot of the entire scrollable page on the website X 2) Find the element(s) of class Y, in particular its location on the page, width and height. 3) Crop the full screenshot so that only desired element is visible

Problem is the following:

I cannot take a screenshot of the entire page, I was only able to take a screenshot of the visible area of my screen.

This is what I tried and corresponding problems:

SOLUTION 1 (Ruby - General):

require 'selenium-webdriver'

driver = Selenium::WebDriver.for :firefox #:chrome

driver.navigate.to "https://some_very-very_long_page_on_website_X"
driver.manage.window.maximize # <- works for firefox only
driver.save_screenshot('picture1.png')

# Problem: it captures only the viewable area, 
# not an entire page

SOLUTION 2 (Ruby - Window Resizing):

require 'selenium-webdriver'

driver = Selenium::WebDriver.for :firefox #:chrome
driver.navigate.to 'https://some_very-very_long_page_on_website_X'

width  = driver.execute_script("return Math.max(document.body.scrollWidth,document.body.offsetWidth,document.documentElement.clientWidth,document.documentElement.scrollWidth,document.documentElement.offsetWidth);")
height = driver.execute_script("return Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight);")

driver.manage.window.resize_to(width, height) # <- resizes the window
driver.manage.window.full_screen  # <- works, but in chrome throws:
                                  # full_screen': undefined method `full_screen_window'

picture = driver.screenshot_as(:png)

File.open('picture2.png', 'w+') do |fh|
  fh.write picture
end

driver.quit

# Resizes the window only to the viewable area, as a result,
# it captures the viewable area only

SOLUTION 3 (Ruby- watir gem):

require 'watir'

b = Watir::Browser.new
b.goto 'https://some_very-very_long_page_on_website_X'
b.screenshot.save("picture.png")

# Issues: does not capture the entire page

SOLUTION 4 (Ruby - Single element capturing)

require "selenium-webdriver"

driver = Selenium::WebDriver.for :chrome

driver.get'https://some_very-very_long_page_on_website_X'

driver.manage.window.maximize
driver.execute_script("document.getElementById('some_id').scrollIntoView();")
driver.save_screenshot "picture3.png"

# Problem: captures the element, which I need, but only if its size is less than
# the viewable area

SOLUTION 5 (Ruby - Zooming)

require "selenium-webdriver"

driver = Selenium::WebDriver.for :firefox

driver.get 'https://some_very-very_long_page_on_website_X'

driver.manage.window.maximize
driver.execute_script("document.body.style.transform = 'scale(0.5)'")
#driver.execute_script("document.body.style.zoom = '50%'") <-- transform works better than zoom

driver.save_screenshot "picture3.png"

#Issues: works, but not for very long pages, in addition it may change the layout
# (some elements may start to overlap each other)
# Also I am not sure how to calculate the value of the parameter for scale
# for very long pages

SOLUTION 6 - (Ruby - Headless Chrome Resizing)

require "selenium-webdriver"

options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--headless')
driver = Selenium::WebDriver.for :chrome, options: options

driver.get "https://some_very-very_long_page_on_website_X"

width  = driver.execute_script("return Math.max(document.body.scrollWidth,document.body.offsetWidth,document.documentElement.clientWidth,document.documentElement.scrollWidth,document.documentElement.offsetWidth);")
height = driver.execute_script("return Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight);")

driver.manage.window.resize_to(width+2000, height+2000) # <-- if I do not have +2000, page looks squished
                                                        # the greater the number, the greater the quality
                                                        # but also the more white space is around the page
                                                        # and the picture is heavier
driver.manage.window.maximize

sleep 5             # <--- required waiting for page loading 
driver.save_screenshot "full.png"

# One of the best approaches, but it is not clear to me how to calculate 
# the parameters for resize_to

Tools/Technologies:

  • selenium-webdriver (3.12.0)
  • ChromeDriver 2.40

来源:https://stackoverflow.com/questions/50865148/how-to-take-a-screenshot-of-a-full-browser-page-and-its-elements-using-selenium

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!