Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to take partial screenshot (frame) with Selenium WebDriver?

Is it possible to take a screenshot with WebDriver of only one frame (not the complete window) within a frameset?

Alternatively, is it possible to define coordinates of a window for the screenshot or crop the image afterwards?

like image 355
timomeinen Avatar asked Jun 01 '12 10:06

timomeinen


3 Answers

This should work:

import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;

import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Point;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;

public class Shooter{

    private WebDriver driver;

    public void shootWebElement(WebElement element) throws IOException  {

        File screen = ((TakesScreenshot) this.driver).getScreenshotAs(OutputType.FILE);

        Point p = element.getLocation();

        int width = element.getSize().getWidth();
        int height = element.getSize().getHeight();

        BufferedImage img = ImageIO.read(screen);

        BufferedImage dest = img.getSubimage(p.getX(), p.getY(), width,   
                                 height);

        ImageIO.write(dest, "png", screen);

        File f = new File("S:\\ome\\where\\over\\the\\rainbow");

        FileUtils.copyFile(screen, f);

    }
}
like image 134
Franz Ebner Avatar answered Nov 12 '22 18:11

Franz Ebner


Python solution (dependency: PIL or Pillow):

from PIL import Image
from selenium import webdriver

def element_screenshot(driver, element, filename):
    bounding_box = (
        element.location['x'], # left
        element.location['y'], # upper
        (element.location['x'] + element.size['width']), # right
        (element.location['y'] + element.size['height']) # bottom
    )
    return bounding_box_screenshot(driver, bounding_box, filename)

def bounding_box_screenshot(driver, bounding_box, filename):
    driver.save_screenshot(filename)
    base_image = Image.open(filename)
    cropped_image = base_image.crop(bounding_box)
    base_image = base_image.resize(cropped_image.size)
    base_image.paste(cropped_image, (0, 0))
    base_image.save(filename)
    return base_image

if __name__ == '__main__':
    driver = webdriver.Firefox()
    driver.get('https://www.google.com/?gws_rd=ssl')
    element = driver.find_element_by_id('body')

    screenshot = element_screenshot(driver, element, 'element.png') # Screenshot the '#body' element

    bounding_box = (100, 100, 600, 600)
    screenshot = bounding_box_screenshot(driver, bounding_box, 'box.png') # Screenshot the bounding box (100, 100, 600, 600)
like image 41
rrb5068 Avatar answered Nov 12 '22 18:11

rrb5068


Ruby solution

Setup

Install xvfb

apt-get install xvfb -y

Install headless browser and image manipulation gem

gem install chunky_png
gem install headless
gem install selenium-webdriver

Install chrome driver

wget http://chromedriver.googlecode.com/files/chromedriver_linux64_<latest>.zip
apt-get install unzip
unzip chromedriver_linux64_<latest>.zip
cp chromedriver /usr/local/bin

More info can be found here

Code

#!/usr/bin/env ruby

require "headless"
require "selenium-webdriver"
require 'chunky_png'

headless = Headless.new
headless.start

site = "?_some_site_?"

driver = Selenium::WebDriver.for :chrome
driver.navigate.to site
sleep 1
driver.save_screenshot('screenshot.png')

el= driver.find_element(:xpath, '?_some_xpath_?')

image = ChunkyPNG::Image.from_file('screenshot.png')

image.crop!(el.location.x + 1, el.location.y + 1, el.size.width, el.size.height)
image.save('croped.png')

driver.quit
headless.destroy
like image 6
michal Avatar answered Nov 12 '22 19:11

michal