Skip to content

Commit

Permalink
Support taking test screenshots of individual elements
Browse files Browse the repository at this point in the history
Change-Id: Iac06c3df156c68f3ec995e00d3cf7703c2673a81
  • Loading branch information
Artur- authored and Vaadin Code Review committed Jun 26, 2015
1 parent 965faaf commit bd41cf7
Show file tree
Hide file tree
Showing 2 changed files with 193 additions and 1 deletion.
165 changes: 165 additions & 0 deletions uitest/src/com/vaadin/tests/tb3/CustomTestBenchCommandExecutor.java
@@ -0,0 +1,165 @@
/*
* Copyright 2000-2014 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.tests.tb3;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.logging.Logger;

import javax.imageio.IIOException;
import javax.imageio.ImageIO;

import org.openqa.selenium.Dimension;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Point;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import com.vaadin.testbench.Parameters;
import com.vaadin.testbench.screenshot.ImageComparison;
import com.vaadin.testbench.screenshot.ImageFileUtil;

/**
* Internal hack to support capturing screenshots for elements.
*
* Most parts are from TestBenchCommandExecutor and the feature should be
* integrated into TB4.
*
* @author Vaadin Ltd
*/
public class CustomTestBenchCommandExecutor {

private ImageComparison imageComparison = new ImageComparison();
private final WebDriver actualDriver;

public CustomTestBenchCommandExecutor(WebDriver driver) {
actualDriver = driver;
}

/**
* Compares the screenshot of the given element with the reference.
*
* Copied from TestBenchCommandExecutor
*/
public boolean compareScreen(WebElement element, File reference,
boolean isIE8) throws IOException {
BufferedImage image = null;
try {
image = ImageIO.read(reference);
} catch (IIOException e) {
// Don't worry, an error screen shot will be generated that later
// can be used as the reference
}
return compareScreen(element, image, reference.getName(), isIE8);
}

/**
* Compares the screenshot of the given element with the reference.
*
* Copied from TestBenchCommandExecutor and added cropToElement
*/
public boolean compareScreen(WebElement element, BufferedImage reference,
String referenceName, boolean isIE8) throws IOException {
for (int times = 0; times < Parameters.getMaxScreenshotRetries(); times++) {
BufferedImage screenshotImage = cropToElement(element,
ImageIO.read(new ByteArrayInputStream(
((TakesScreenshot) actualDriver)
.getScreenshotAs(OutputType.BYTES))), isIE8);
if (reference == null) {
// Store the screenshot in the errors directory and fail the
// test
ImageFileUtil.createScreenshotDirectoriesIfNeeded();
ImageIO.write(screenshotImage, "png",
ImageFileUtil.getErrorScreenshotFile(referenceName));
getLogger().severe(
"No reference found for "
+ referenceName
+ " in "
+ ImageFileUtil
.getScreenshotReferenceDirectory());
return false;
}
if (imageComparison.imageEqualToReference(screenshotImage,
reference, referenceName,
Parameters.getScreenshotComparisonTolerance())) {
return true;
}
pause(Parameters.getScreenshotRetryDelay());
}
return false;
}

/**
* Crops the image to show only the element. If the element is partly off
* screen, crops to show the part of the element which is in the screenshot
*
* @param element
* the element to retain in the screenshot
* @param fullScreen
* the full screen image
* @param isIE8
* true if the browser is IE8
* @return
* @throws IOException
*/
private BufferedImage cropToElement(WebElement element,
BufferedImage fullScreen, boolean isIE8) throws IOException {
Point loc = element.getLocation();
Dimension size = element.getSize();
int x = loc.x, y = loc.y;
int w = size.width;
int h = size.height;

if (isIE8) {
// IE8 border...
x += 2;
y += 2;
}
if (x >= 0 && x < fullScreen.getWidth()) {
// X loc on screen
// Get the part of the element which is on screen
w = Math.min(fullScreen.getWidth() - x, w);
} else {
throw new IOException("Element x is outside the screenshot (x: "
+ x + ", y: " + y + ")");
}

if (y >= 0 && y < fullScreen.getHeight()) {
// Y loc on screen
// Get the part of the element which is on screen
h = Math.min(fullScreen.getHeight() - y, h);
} else {
throw new IOException("Element y is outside the screenshot (x: "
+ x + ", y: " + y + ")");
}

return fullScreen.getSubimage(x, y, w, h);
}

private void pause(int delay) {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
}
}

private static Logger getLogger() {
return Logger.getLogger(CustomTestBenchCommandExecutor.class.getName());
}
}
29 changes: 28 additions & 1 deletion uitest/src/com/vaadin/tests/tb3/ScreenshotTB3Test.java
Expand Up @@ -30,6 +30,8 @@
import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;

import com.vaadin.testbench.Parameters;
Expand Down Expand Up @@ -119,6 +121,11 @@ public void setupScreenComparisonParameters() {
* @throws IOException
*/
protected void compareScreen(String identifier) throws IOException {
compareScreen(null, identifier);
}

protected void compareScreen(WebElement element, String identifier)
throws IOException {
if (identifier == null || identifier.isEmpty()) {
throw new IllegalArgumentException("Empty identifier not supported");
}
Expand All @@ -129,7 +136,17 @@ protected void compareScreen(String identifier) throws IOException {
List<File> failedReferenceFiles = new ArrayList<File>();

for (File referenceFile : referenceFiles) {
if (testBench(driver).compareScreen(referenceFile)) {
boolean match = false;
if (element == null) {
// Full screen
match = testBench(driver).compareScreen(referenceFile);
} else {
// Only the element
match = customTestBench(driver).compareScreen(element,
referenceFile,
BrowserUtil.isIE8(getDesiredCapabilities()));
}
if (match) {
// There might be failure files because of retries in TestBench.
deleteFailureFiles(getErrorFileFromReference(referenceFile));
break;
Expand Down Expand Up @@ -180,6 +197,16 @@ protected void compareScreen(String identifier) throws IOException {
}
}

private CustomTestBenchCommandExecutor customTestBench = null;

private CustomTestBenchCommandExecutor customTestBench(WebDriver driver) {
if (customTestBench == null) {
customTestBench = new CustomTestBenchCommandExecutor(driver);
}

return customTestBench;
}

private void enableAutoswitch(File htmlFile) throws FileNotFoundException,
IOException {
if (htmlFile == null || !htmlFile.exists()) {
Expand Down

0 comments on commit bd41cf7

Please sign in to comment.