title: How to take a screenshot of a full browser page and its elements using selenium-webdriver/capybara in Ruby?
body: <p>I am working on screenshot automation. In particular, I am trying to achieve the following:</p>
  
  <ol>
  <li>Prompt the user for the links to different pages on the website X</li>
  <li>Prompt the user for the class name Y</li>
  <li>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</li>
  <li>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)</li>
  <li>Save them in the current directory</li>
  </ol>
  
  <p><a href="https://i.stack.imgur.com/qLE40.png" rel="noreferrer">Please click on the link for visual representation</a></p>
  
  <p><strong>I wanted to implement the following solution in Ruby (but I am also open to any other suggestions):</strong></p>
  
  <p>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</p>
  
  <p><strong>Problem is the following:</strong></p>
  
  <p>I cannot take a screenshot of the entire page, I was only able to take a screenshot of the visible area of my screen.</p>
  
  <p><strong>This is what I tried and corresponding problems:</strong></p>
  
  <p><strong>SOLUTION 1 (Ruby - General):</strong></p>
  
  <pre><code>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 # &lt;- works for firefox only
  driver.save_screenshot('picture1.png')
  
  # Problem: it captures only the viewable area, 
  # not an entire page
  </code></pre>
  
  <p><strong>SOLUTION 2 (Ruby - Window Resizing):</strong></p>
  
  <pre><code>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) # &lt;- resizes the window
  driver.manage.window.full_screen  # &lt;- 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
  </code></pre>
  
  <p><strong>SOLUTION 3 (Ruby- watir gem):</strong></p>
  
  <pre><code>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
  </code></pre>
  
  <p><strong>SOLUTION 4 (Ruby - Single element capturing)</strong></p>
  
  <pre><code>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
  </code></pre>
  
  <p><strong>SOLUTION 5 (Ruby - Zooming)</strong></p>
  
  <pre><code>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%'") &lt;-- 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
  </code></pre>
  
  <p><strong>SOLUTION 6 - (Ruby - Headless Chrome Resizing)</strong></p>
  
  <pre><code>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) # &lt;-- 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             # &lt;--- 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
  </code></pre>
  
  <p>Tools/Technologies:</p>
  
  <ul>
  <li>selenium-webdriver (3.12.0)</li>
  <li>ChromeDriver 2.40</li>
  </ul>