Skip to content

Commit 8d4a940

Browse files
committed
Add javadoc; add ScreenshotFactory; add thumbnails scaling
1 parent 6535c21 commit 8d4a940

File tree

5 files changed

+189
-147
lines changed

5 files changed

+189
-147
lines changed

src/main/java/com/assertthat/selenium_screenshotter/core/Screenshot.java

Lines changed: 39 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import com.assertthat.selenium_screenshotter.utils.file.FileUtil;
44
import com.assertthat.selenium_screenshotter.utils.image.ImageProcessor;
55
import com.assertthat.selenium_screenshotter.utils.web.Browser;
6-
import com.assertthat.selenium_screenshotter.utils.web.Screenshotter;
76
import com.assertthat.selenium_screenshotter.utils.web.ScrollStrategy;
87
import org.openqa.selenium.WebDriver;
98
import org.openqa.selenium.WebElement;
@@ -23,68 +22,13 @@ public abstract class Screenshot<T extends Screenshot<T>> {
2322

2423
private static final String extension = "PNG";
2524
protected BufferedImage image;
25+
protected BufferedImage thumbnailImage;
2626
protected WebDriver driver;
2727
private String fileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy_MM_dd_HH_mm_ss_SSS"))
2828
+ "." + extension.toLowerCase();
2929
private Path location = Paths.get("./screenshots/");
3030
private String title;
3131

32-
/**
33-
* Make screenshot of the viewport only.
34-
* To be used when screenshotting the page
35-
* and don't need to scroll while making screenshots (FF, IE).
36-
*
37-
* @param driver WebDriver instance
38-
* @return PageScreenshot instance
39-
*/
40-
public static PageScreenshot page(WebDriver driver) {
41-
Browser browser = new Browser(driver);
42-
PageScreenshot pageScreenshot = new PageScreenshot(driver);
43-
pageScreenshot.setImage(Screenshotter.takeScreenshot(browser));
44-
return pageScreenshot;
45-
}
46-
47-
/**
48-
* To be used when screenshotting the page
49-
* and need to scroll while making screenshots, either vertically or
50-
* horizontally or both directions (Chrome).
51-
*
52-
* @param driver WebDriver instance
53-
* @param scroll ScrollStrategy How you need to scroll
54-
* @return PageScreenshot instance
55-
*/
56-
public static PageScreenshot page(WebDriver driver, ScrollStrategy scroll) {
57-
Browser browser = new Browser(driver);
58-
PageScreenshot pageScreenshot = new PageScreenshot(driver);
59-
switch (scroll) {
60-
case HORIZONTALLY:
61-
pageScreenshot.setImage(Screenshotter.takeScreenshotScrollHorizontally(browser));
62-
break;
63-
case VERTICALLY:
64-
pageScreenshot.setImage(Screenshotter.takeScreenshotScrollVertically(browser));
65-
break;
66-
case BOTH_DIRECTIONS:
67-
pageScreenshot.setImage(Screenshotter.takeScreenshotEntirePage(browser));
68-
}
69-
return pageScreenshot;
70-
}
71-
72-
/**
73-
* To be used when need to screenshot particular element.
74-
*
75-
* @param driver WebDriver instance
76-
* @param element WebElement instance to be screenshotted
77-
* @return ElementScreenshot instance
78-
*/
79-
public static ElementScreenshot element(WebDriver driver, WebElement element) {
80-
Browser browser = new Browser(driver);
81-
ElementScreenshot elementScreenshot = new ElementScreenshot(driver, element);
82-
browser.scrollToElement(element);
83-
elementScreenshot.setImage(Screenshotter.takeScreenshot(browser));
84-
elementScreenshot.setImage(ImageProcessor.getElement(elementScreenshot.getImage(), browser.getBoundingClientRect(element)));
85-
return elementScreenshot;
86-
}
87-
8832
protected abstract T self();
8933

9034
/**
@@ -109,6 +53,36 @@ public T withTitle(String title) {
10953
return self();
11054
}
11155

56+
57+
/**
58+
* Generate a thumbnail of the original screenshot.
59+
* Will save different thumbnails depends on when it was called in the chain.
60+
*
61+
* @param path to save thumbnail image to
62+
* @param name of the resulting image
63+
* @param scale to apply
64+
* @return instance of type Screenshot
65+
*/
66+
public T withThumbnail(String path, String name, double scale) {
67+
File thumbnailFile = new File(path.toString(), name);
68+
thumbnailFile.mkdirs();
69+
thumbnailImage=ImageProcessor.scale(image,0.5);
70+
FileUtil.writeImage(thumbnailImage, extension, thumbnailFile);
71+
return self();
72+
}
73+
74+
/**
75+
* Generate a thumbnail of the original screenshot.
76+
* Will save different thumbnails depends on when it was called in the chain.
77+
*
78+
* @param scale to apply
79+
* @return instance of type Screenshot
80+
*/
81+
public T withThumbnail(double scale) {
82+
withThumbnail(Paths.get(location.toString(),"./thumbnails").toString(),"thumb_"+fileName,scale);
83+
return self();
84+
}
85+
11286
/**
11387
* Apply gray-and-white filter to the image.
11488
*
@@ -136,6 +110,7 @@ protected void setImage(BufferedImage image) {
136110
*/
137111
public void save() {
138112
File screenshotFile = new File(location.toString(), fileName);
113+
screenshotFile.mkdirs();
139114
if (title != null && !title.isEmpty()) {
140115
image = ImageProcessor.addTitle(image, title, Color.red, new Font("Serif", Font.BOLD, 20));
141116
}
@@ -146,30 +121,16 @@ public void save() {
146121
* Final method to be called in the chain.
147122
* Actually saves processed image to the specified path.
148123
*/
149-
public void save(String location) {
150-
File screenshotFile = new File(location, fileName);
151-
if (title != null && !title.isEmpty()) {
152-
image = ImageProcessor.addTitle(image, title, Color.red, new Font("Serif", Font.BOLD, 20));
153-
}
154-
FileUtil.writeImage(image, extension, screenshotFile);
124+
public void save(String path) {
125+
this.location = Paths.get(path);
126+
save();
155127
}
156128

157129
/**
158-
* Final method to be called in the chain.
159-
* Actually saves processed image to the specified path.
160-
*/
161-
public void save(Path location) {
162-
File screenshotFile = new File(location.toString(), fileName);
163-
if (title != null && !title.isEmpty()) {
164-
image = ImageProcessor.addTitle(image, title, Color.red, new Font("Serif", Font.BOLD, 20));
165-
}
166-
FileUtil.writeImage(image, extension, screenshotFile);
167-
}
168-
169-
/**
170-
* @param o
171-
* @param deviation
172-
* @return
130+
* @param o Object to compare with
131+
* @param deviation allowed deviation while comparing.
132+
* @return true if the the percentage of differences
133+
* between current image and provided one is less than or equal to <b>deviation</b>
173134
*/
174135
public boolean equals(Object o, double deviation) {
175136
if (this == o) return true;
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.assertthat.selenium_screenshotter.core;
2+
3+
import com.assertthat.selenium_screenshotter.utils.image.ImageProcessor;
4+
import com.assertthat.selenium_screenshotter.utils.web.Browser;
5+
import com.assertthat.selenium_screenshotter.utils.web.ScrollStrategy;
6+
import org.openqa.selenium.WebDriver;
7+
import org.openqa.selenium.WebElement;
8+
9+
/**
10+
* Created by Glib_Briia on 26/06/2016.
11+
*/
12+
public class ScreenshotFactory {
13+
14+
/**
15+
* Make screenshot of the viewport only.
16+
* To be used when screenshotting the page
17+
* and don't need to scroll while making screenshots (FF, IE).
18+
*
19+
* @param driver WebDriver instance
20+
* @return PageScreenshot instance
21+
*/
22+
public static PageScreenshot page(WebDriver driver) {
23+
Browser browser = new Browser(driver);
24+
PageScreenshot pageScreenshot = new PageScreenshot(driver);
25+
pageScreenshot.setImage(browser.takeScreenshot());
26+
return pageScreenshot;
27+
}
28+
29+
/**
30+
* To be used when screenshotting the page
31+
* and need to scroll while making screenshots, either vertically or
32+
* horizontally or both directions (Chrome).
33+
*
34+
* @param driver WebDriver instance
35+
* @param scroll ScrollStrategy How you need to scroll
36+
* @return PageScreenshot instance
37+
*/
38+
public static PageScreenshot page(WebDriver driver, ScrollStrategy scroll) {
39+
Browser browser = new Browser(driver);
40+
PageScreenshot pageScreenshot = new PageScreenshot(driver);
41+
switch (scroll) {
42+
case HORIZONTALLY:
43+
pageScreenshot.setImage(browser.takeScreenshotScrollHorizontally());
44+
break;
45+
case VERTICALLY:
46+
pageScreenshot.setImage(browser.takeScreenshotScrollVertically());
47+
break;
48+
case BOTH_DIRECTIONS:
49+
pageScreenshot.setImage(browser.takeScreenshotEntirePage());
50+
}
51+
return pageScreenshot;
52+
}
53+
54+
/**
55+
* To be used when need to screenshot particular element.
56+
*
57+
* @param driver WebDriver instance
58+
* @param element WebElement instance to be screenshotted
59+
* @return ElementScreenshot instance
60+
*/
61+
public static ElementScreenshot element(WebDriver driver, WebElement element) {
62+
Browser browser = new Browser(driver);
63+
ElementScreenshot elementScreenshot = new ElementScreenshot(driver, element);
64+
browser.scrollToElement(element);
65+
elementScreenshot.setImage(browser.takeScreenshot());
66+
elementScreenshot.setImage(ImageProcessor.getElement(elementScreenshot.getImage(), browser.getBoundingClientRect(element)));
67+
return elementScreenshot;
68+
}
69+
}

src/main/java/com/assertthat/selenium_screenshotter/utils/image/ImageProcessor.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import javax.imageio.ImageIO;
66
import java.awt.*;
77
import java.awt.color.ColorSpace;
8+
import java.awt.geom.AffineTransform;
89
import java.awt.image.*;
910
import java.io.IOException;
1011
import java.net.URL;
@@ -126,4 +127,25 @@ public static boolean imagesAreEquals(BufferedImage image1, BufferedImage image2
126127
double p = diff / n / 255.0;
127128
return p == 0 || p <= deviation;
128129
}
130+
131+
public static BufferedImage scale(BufferedImage source,double ratio) {
132+
int w = (int) (source.getWidth() * ratio);
133+
int h = (int) (source.getHeight() * ratio);
134+
BufferedImage scaledImage = getCompatibleImage(w, h);
135+
Graphics2D g2d = scaledImage.createGraphics();
136+
double xScale = (double) w / source.getWidth();
137+
double yScale = (double) h / source.getHeight();
138+
AffineTransform at = AffineTransform.getScaleInstance(xScale,yScale);
139+
g2d.drawRenderedImage(source, at);
140+
g2d.dispose();
141+
return scaledImage;
142+
}
143+
144+
private static BufferedImage getCompatibleImage(int w, int h) {
145+
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
146+
GraphicsDevice gd = ge.getDefaultScreenDevice();
147+
GraphicsConfiguration gc = gd.getDefaultConfiguration();
148+
BufferedImage image = gc.createCompatibleImage(w, h);
149+
return image;
150+
}
129151
}

src/main/java/com/assertthat/selenium_screenshotter/utils/web/Browser.java

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@
22

33
import com.assertthat.selenium_screenshotter.utils.file.FileUtil;
44
import org.openqa.selenium.*;
5-
5+
import org.openqa.selenium.Dimension;
6+
import org.openqa.selenium.Point;
7+
8+
import javax.imageio.ImageIO;
9+
import java.awt.*;
10+
import java.awt.image.BufferedImage;
11+
import java.io.File;
12+
import java.io.IOException;
613
import java.util.ArrayList;
714

815
/**
@@ -40,6 +47,57 @@ public static void wait(int milis) {
4047
}
4148
}
4249

50+
public BufferedImage takeScreenshot() {
51+
File srcFile = ((TakesScreenshot) this.getUnderlyingDriver()).getScreenshotAs(OutputType.FILE);
52+
try {
53+
return ImageIO.read(srcFile);
54+
} catch (IOException e) {
55+
throw new UnableTakeScreenshotException(e);
56+
}
57+
}
58+
59+
public BufferedImage takeScreenshotEntirePage() {
60+
BufferedImage combinedImage = new BufferedImage(this.getDocWidth(), this.getDocHeight(), BufferedImage.TYPE_INT_ARGB);
61+
Graphics2D g = combinedImage.createGraphics();
62+
int horizontalIterations = (int) Math.ceil(((double) this.getDocWidth()) / this.getViewportWidth());
63+
int verticalIterations = (int) Math.ceil(((double) this.getDocHeight()) / this.getViewportHeight());
64+
for (int j = 0; j < verticalIterations; j++) {
65+
this.scrollTo(0, j * this.getViewportHeight());
66+
for (int i = 0; i < horizontalIterations; i++) {
67+
this.scrollTo(i * this.getViewportWidth(), this.getViewportHeight() * j);
68+
wait(50);
69+
g.drawImage(takeScreenshot(), this.getCurrentScrollX(), this.getCurrentScrollY(), null);
70+
}
71+
}
72+
g.dispose();
73+
return combinedImage;
74+
}
75+
76+
public BufferedImage takeScreenshotScrollHorizontally() {
77+
BufferedImage combinedImage = new BufferedImage(this.getDocWidth(), this.getViewportHeight(), BufferedImage.TYPE_INT_ARGB);
78+
Graphics2D g = combinedImage.createGraphics();
79+
int horizontalIterations = (int) Math.ceil(((double) this.getDocWidth()) / this.getViewportWidth());
80+
for (int i = 0; i < horizontalIterations; i++) {
81+
this.scrollTo(i * this.getViewportWidth(), 0);
82+
g.drawImage(takeScreenshot(), this.getCurrentScrollX(), 0, null);
83+
}
84+
g.dispose();
85+
return combinedImage;
86+
}
87+
88+
public BufferedImage takeScreenshotScrollVertically() {
89+
BufferedImage combinedImage = new BufferedImage(this.getViewportWidth(), this.getDocHeight(), BufferedImage.TYPE_INT_ARGB);
90+
Graphics2D g = combinedImage.createGraphics();
91+
int verticalIterations = (int) Math.ceil(((double) this.getDocHeight()) / this.getViewportHeight());
92+
for (int j = 0; j < verticalIterations; j++) {
93+
this.scrollTo(0, j * this.getViewportHeight());
94+
g.drawImage(takeScreenshot(), 0, this.getCurrentScrollY(), null);
95+
96+
}
97+
g.dispose();
98+
return combinedImage;
99+
}
100+
43101
public WebDriver getUnderlyingDriver() {
44102
return driver;
45103
}

0 commit comments

Comments
 (0)