Reputation: 3328
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?
Upvotes: 21
Views: 21076
Reputation: 11775
Just posting a solution based on C# on taking a specific Html element's screenshot in selenium:
First we need to take the screen shot of entire web page using the GetScreenShot method of selenium web driver as below.
Screenshot screenshot = ((ITakesScreenshot)this.driver).GetScreenshot();
screenshot.SaveAsFile(filename, System.Drawing.Imaging.ImageFormat.Jpeg);
Then create a rectangle from the location , height and width of the specified html element. (This has to be obtained using FindElement()
method of selenium by providing id or class name).
Image img = Bitmap.FromFile(uniqueName);
Rectangle rect = new Rectangle();
if (element != null)
{
// Get the Width and Height of the WebElement using
int width = element.Size.Width;
int height = element.Size.Height;
// Get the Location of WebElement in a Point.
// This will provide X & Y co-ordinates of the WebElement
Point p = element.Location;
// Create a rectangle using Width, Height and element location
rect = new Rectangle(p.X, p.Y, width, height);
}
Using this we are going to crop the the screenshot as below and the result will be the screenshot specific web element.
Bitmap bmpImage = new Bitmap(img);
var cropedImag = bmpImage.Clone(rect, bmpImage.PixelFormat);
Full code as a method below:
/// <summary>
/// Captures the element screen shot.
/// </summary>
/// <param name="element">The element.</param>
/// <param name="uniqueName">Name of the unique.</param>
/// <returns>returns the screenshot image </returns>
public Image CaptureElementScreenShot(HTMLElement element, string uniqueName)
{
Screenshot screenshot = ((ITakesScreenshot)this.driver).GetScreenshot();
screenshot.SaveAsFile(filename, System.Drawing.Imaging.ImageFormat.Jpeg);
Image img = Bitmap.FromFile(uniqueName);
Rectangle rect = new Rectangle();
if (element != null)
{
// Get the Width and Height of the WebElement using
int width = element.Size.Width;
int height = element.Size.Height;
// Get the Location of WebElement in a Point.
// This will provide X & Y co-ordinates of the WebElement
Point p = element.Location;
// Create a rectangle using Width, Height and element location
rect = new Rectangle(p.X, p.Y, width, height);
}
// croping the image based on rect.
Bitmap bmpImage = new Bitmap(img);
var cropedImag = bmpImage.Clone(rect, bmpImage.PixelFormat);
return cropedImag;
}
Upvotes: 2
Reputation: 81
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)
Upvotes: 8
Reputation: 5106
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);
}
}
Upvotes: 26
Reputation: 328
Scala solution:
import javax.imageio.ImageIO
import java.awt.image.BufferedImage
// phone is a case class with witdth and height Int fields
def producer {
[..]
processScreenshot(driver.getScreenshotAs(OutputType.FILE), ph)
}
def processScreenshot(file: File, phone: Phone) = {
val img: BufferedImage = ImageIO.read(file)
val w = math.min(img.getWidth, phone.width)
val h = math.min(img.getHeight, phone.height)
val dest = img.getSubimage(0, 0, w, h)
ImageIO.write(dest, "png", new File(s"/tmp/${un}_${phone.file}.png"))
}
Upvotes: 1
Reputation: 381
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
Upvotes: 6