-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Chrome full size screenshot without sticky header #38
Changes from 2 commits
d64e658
f041c19
badea12
a5f0508
57edfab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -96,6 +96,8 @@ public static PageSnapshot shootPage(WebDriver driver, ScrollStrategy scroll, in | |
break; | ||
case BOTH_DIRECTIONS: | ||
pageScreenshot.setImage(browser.takeScreenshotEntirePage()); | ||
case WITHOUT_STICKY_HEADER: | ||
pageScreenshot.setImage(browser.takeScreenshotEntirePageUsingChromeCommand()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shall we add broser.getName(); which will check which driver instance is currently used (instanceof presumably) and throw UnsupportedOperationException if current driver instance is other than Chrome There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, please add missing break to BOTH_DIRECTIONS case |
||
} | ||
return pageScreenshot; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,18 +6,21 @@ | |
package com.assertthat.selenium_shutterbug.utils.web; | ||
|
||
import com.assertthat.selenium_shutterbug.utils.file.FileUtil; | ||
import com.google.common.collect.ImmutableMap; | ||
import org.openqa.selenium.Dimension; | ||
import org.openqa.selenium.*; | ||
import org.openqa.selenium.Point; | ||
import org.openqa.selenium.chrome.ChromeDriver; | ||
|
||
import javax.imageio.ImageIO; | ||
import java.awt.*; | ||
import java.awt.image.BufferedImage; | ||
import java.io.ByteArrayInputStream; | ||
import java.io.File; | ||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.util.ArrayList; | ||
|
||
import static java.lang.Math.toIntExact; | ||
import java.util.Map; | ||
|
||
/** | ||
* Created by Glib_Briia on 17/06/2016. | ||
|
@@ -34,6 +37,7 @@ public class Browser { | |
public static final String CURRENT_SCROLL_Y_JS = "js/get-current-scrollY.js"; | ||
public static final String CURRENT_SCROLL_X_JS = "js/get-current-scrollX.js"; | ||
public static final String DEVICE_PIXEL_RATIO = "js/get-device-pixel-ratio.js"; | ||
public static final String ALL_METRICS = "js/all-metrics.js"; | ||
|
||
private WebDriver driver; | ||
private int docHeight = -1; | ||
|
@@ -75,7 +79,7 @@ public BufferedImage takeScreenshot() { | |
srcFile.delete(); | ||
} | ||
} | ||
|
||
} | ||
|
||
public BufferedImage takeScreenshotEntirePage() { | ||
|
@@ -86,12 +90,12 @@ public BufferedImage takeScreenshotEntirePage() { | |
int _viewportWidth = this.getViewportWidth(); | ||
int _viewportHeight = this.getViewportHeight(); | ||
final int scrollBarMaxWidth = 40; // this is probably too high, but better to be safe than sorry | ||
|
||
if (_viewportWidth < _docWidth || (_viewportHeight < _docHeight && _viewportWidth - scrollBarMaxWidth < _docWidth)) | ||
_viewportHeight-=scrollBarMaxWidth; // some space for a scrollbar | ||
if (_viewportHeight < _docHeight) | ||
_viewportWidth-=scrollBarMaxWidth; // some space for a scrollbar | ||
|
||
int horizontalIterations = (int) Math.ceil(((double) _docWidth) / _viewportWidth); | ||
int verticalIterations = (int) Math.ceil(((double) _docHeight) / _viewportHeight); | ||
outer_loop: | ||
|
@@ -111,6 +115,33 @@ public BufferedImage takeScreenshotEntirePage() { | |
return combinedImage; | ||
} | ||
|
||
public BufferedImage takeScreenshotEntirePageUsingChromeCommand() { | ||
DriverCommandExecutor driver = null; | ||
try { | ||
driver = new DriverCommandExecutor((ChromeDriver) this.driver); | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
} | ||
int verticalIterations = (int) Math.ceil(((double) this.getDocHeight()) / this.getViewportHeight()); | ||
for (int j = 0; j < verticalIterations; j++) { | ||
this.scrollTo(0, j * this.getViewportHeight()); | ||
wait(scrollTimeout); | ||
} | ||
Object metrics = driver.evaluate(FileUtil.getJsScript(ALL_METRICS)); | ||
driver.sendCommand("Emulation.setDeviceMetricsOverride", metrics); | ||
Object result = driver.sendCommand("Page.captureScreenshot", ImmutableMap.of("format", "png", "fromSurface", true)); | ||
driver.sendCommand("Emulation.clearDeviceMetricsOverride", ImmutableMap.of()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't look like we need to clearDeviceMetricsOverride, as we don't really changing any initial device metrics just width and height which wont influence further test flow, moreover clearDeviceMetricsOverride for some reason spoins further highlighting/bluring etc. elements (coordinates are shifted). |
||
String base64EncodedPng = (String) ((Map<String, ?>) result).get("data"); | ||
InputStream in = new ByteArrayInputStream(OutputType.BYTES.convertFromBase64Png(base64EncodedPng)); | ||
BufferedImage bImageFromConvert; | ||
try { | ||
bImageFromConvert = ImageIO.read(in); | ||
} catch (IOException e) { | ||
throw new RuntimeException("Error while converting results from bytes to BufferedImage"); | ||
} | ||
return bImageFromConvert; | ||
} | ||
|
||
public BufferedImage takeScreenshotScrollHorizontally() { | ||
BufferedImage combinedImage = new BufferedImage(this.getDocWidth(), this.getViewportHeight(), BufferedImage.TYPE_INT_ARGB); | ||
Graphics2D g = combinedImage.createGraphics(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package com.assertthat.selenium_shutterbug.utils.web; | ||
|
||
import com.google.common.collect.ImmutableMap; | ||
import org.openqa.selenium.chrome.ChromeDriver; | ||
import org.openqa.selenium.remote.CommandInfo; | ||
import org.openqa.selenium.remote.HttpCommandExecutor; | ||
import org.openqa.selenium.remote.RemoteWebDriver; | ||
import org.openqa.selenium.remote.Response; | ||
import org.openqa.selenium.remote.http.HttpMethod; | ||
|
||
import java.lang.reflect.InvocationTargetException; | ||
import java.lang.reflect.Method; | ||
import java.util.Map; | ||
|
||
/** | ||
* Created by Anna Galkina on 23-06-2018. | ||
*/ | ||
public class DriverCommandExecutor { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets move command execution methods to Browser class |
||
|
||
private ChromeDriver driver; | ||
|
||
public DriverCommandExecutor(ChromeDriver driver) throws Exception { | ||
this.driver = driver; | ||
CommandInfo cmd = new CommandInfo("/session/:sessionId/chromium/send_command_and_get_result", HttpMethod.POST); | ||
Method defineCommand = HttpCommandExecutor.class.getDeclaredMethod("defineCommand", String.class, CommandInfo.class); | ||
defineCommand.setAccessible(true); | ||
defineCommand.invoke(driver.getCommandExecutor(), "sendCommand", cmd); | ||
} | ||
|
||
public Object sendCommand(String cmd, Object params) { | ||
try { | ||
Method execute = RemoteWebDriver.class.getDeclaredMethod("execute", String.class, Map.class); | ||
execute.setAccessible(true); | ||
Response res = (Response) execute.invoke(driver, "sendCommand", ImmutableMap.of("cmd", cmd, "params", params)); | ||
return res.getValue(); | ||
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
public Object evaluate(String script) { | ||
Object response = sendCommand("Runtime.evaluate", ImmutableMap.of("returnByValue", true, "expression", script)); | ||
Object result = ((Map<String, ?>) response).get("result"); | ||
return ((Map<String, ?>) result).get("value"); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
({width: Math.max(window.innerWidth,document.body.scrollWidth,document.documentElement.scrollWidth)|0, | ||
height: Math.max(window.innerHeight,document.body.scrollHeight,document.documentElement.scrollHeight)|0, | ||
deviceScaleFactor: window.devicePixelRatio || 1,mobile: typeof window.orientation !== 'undefined'}) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add newline at the end of file There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets call it WHOLE_PAGE_CHROME