com.galenframework.api.GalenPageDump Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of galen-core Show documentation
Show all versions of galen-core Show documentation
A library for layout testing of websites
/*******************************************************************************
* Copyright 2018 Ivan Shubin http://galenframework.com
*
* 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.galenframework.api;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.regex.Pattern;
import com.galenframework.browser.Browser;
import com.galenframework.browser.SeleniumBrowser;
import com.galenframework.page.PageElement;
import com.galenframework.page.Rect;
import com.galenframework.rainbow4j.Rainbow4J;
import com.galenframework.speclang2.pagespec.PageSpecReader;
import com.galenframework.specs.page.Locator;
import com.galenframework.specs.page.PageSpec;
import com.galenframework.speclang2.pagespec.SectionFilter;
import com.galenframework.utils.GalenUtils;
import com.galenframework.validation.PageValidation;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.openqa.selenium.WebDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
public class GalenPageDump {
private final static Logger LOG = LoggerFactory.getLogger(GalenPageDump.class);
private static final List EMPTY_TAGS = Collections.emptyList();
private boolean onlyImages = false;
private String pageName;
private Integer maxWidth = null;
private Integer maxHeight = null;
private Properties properties;
private Map jsVariables;
private Map objects;
private List excludedObjects;
public GalenPageDump(String pageName) {
setPageName(pageName);
}
public void dumpPage(WebDriver driver, String pageSpecPath, String reportFolderPath) throws IOException {
Browser browser = new SeleniumBrowser(driver);
dumpPage(browser, loadPageSpec(browser, pageSpecPath), reportFolderPath);
}
private PageSpec loadPageSpec(Browser browser, String pageSpecPath) throws IOException {
PageSpecReader reader = new PageSpecReader();
return reader.read(pageSpecPath, browser.getPage(), new SectionFilter(EMPTY_TAGS, EMPTY_TAGS), properties, jsVariables, objects);
}
public void dumpPage(Browser browser, String pageSpecPath, String reportFolderPath) throws IOException {
dumpPage(browser, loadPageSpec(browser, pageSpecPath), reportFolderPath);
}
public void dumpPage(Browser browser, PageSpec pageSpec, String reportFolderPath) throws IOException {
File reportFolder = new File(reportFolderPath);
if (!reportFolder.exists()) {
if (!reportFolder.mkdirs()) {
throw new RuntimeException("Cannot create dir: " + reportFolder.getAbsolutePath());
}
}
Set objectNames = pageSpec.getObjects().keySet();
PageValidation pageValidation = new PageValidation(browser, browser.getPage(), pageSpec, null, null);
PageDump pageDump = new PageDump();
pageDump.setTitle(browser.getPage().getTitle());
List patterns = convertPatterns(excludedObjects);
Set finalObjectNames = new HashSet<>();
finalObjectNames.addAll(objectNames);
finalObjectNames.add("screen");
finalObjectNames.add("viewport");
for (String objectName : finalObjectNames) {
if (!matchesExcludedPatterns(objectName, patterns)) {
PageElement pageElement = pageValidation.findPageElement(objectName);
if (pageElement.isVisible() && pageElement.getArea() != null) {
PageDump.Element element = new PageDump.Element(objectName, pageElement.getArea().toIntArray());
if (pageElement.isPresent() && pageElement.isVisible() && isWithinArea(pageElement, maxWidth, maxHeight)) {
element.setHasImage(true);
}
pageDump.addElement(element);
}
}
}
if (!onlyImages) {
pageDump.setPageName(pageName);
exportAsJson(pageDump, new File(reportFolder.getAbsoluteFile() + File.separator + "page.json"));
exportAsHtml(pageDump, pageName, new File(reportFolder.getAbsoluteFile() + File.separator + "page.html"));
copyResource("/html-report/vue.js", new File(reportFolder.getAbsolutePath() + File.separator + "vue.js"));
copyResource("/html-report/galen-report.js", new File(reportFolder.getAbsolutePath() + File.separator + "galen-report.js"));
copyResource("/html-report/galen-report.css", new File(reportFolder.getAbsolutePath() + File.separator + "galen-report.css"));
}
exportAllScreenshots(pageDump, browser, reportFolder);
}
private boolean matchesExcludedPatterns(String objectName, List patterns) {
for (Pattern pattern : patterns) {
if (pattern.matcher(objectName).matches()) {
return true;
}
}
return false;
}
private List convertPatterns(List excludedObjects) {
List patterns = new LinkedList<>();
if (excludedObjects != null) {
for (String excludedObject : excludedObjects) {
patterns.add(GalenUtils.convertObjectNameRegex(excludedObject));
}
}
return patterns;
}
public void exportAsJson(PageDump pageDump, File file) throws IOException {
makeSureFileExists(file);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.writeValue(file, pageDump);
}
public void exportAsHtml(PageDump pageDump, String title, File file) throws IOException {
makeSureFileExists(file);
ObjectMapper objectMapper = new ObjectMapper();
String jsonText = objectMapper.writeValueAsString(pageDump);
String template = IOUtils.toString(getClass().getResourceAsStream("/html-report/page-dump.tpl.html"));
String htmlText = template.replace("${title}", title);
htmlText = htmlText.replace("${json}", jsonText);
FileUtils.writeStringToFile(file, htmlText);
}
public void makeSureFileExists(File file) throws IOException {
if (!file.exists()) {
if (!file.createNewFile()) {
throw new RuntimeException("Couldn't create file: " + file.getAbsolutePath());
}
}
}
public void exportAllScreenshots(PageDump pageDump, Browser browser, File reportFolder) throws IOException {
File screenshotOriginalFile = browser.getPage().getScreenshotFile();
FileUtils.copyFile(screenshotOriginalFile, new File(reportFolder.getAbsolutePath() + File.separator + "page.png"));
BufferedImage image = Rainbow4J.loadImage(screenshotOriginalFile.getAbsolutePath());
File objectsFolder = new File(reportFolder.getAbsolutePath() + File.separator + "objects");
objectsFolder.mkdirs();
for (PageDump.Element element : pageDump.getItems().values()) {
if (element.getHasImage()) {
int[] area = element.getArea();
if (area[0] < image.getWidth() && area[1] < image.getHeight()) {
int x = Math.max(area[0], 0);
int y = Math.max(area[1], 0);
int x2 = Math.min(area[0] + area[2], image.getWidth());
int y2 = Math.min(area[1] + area[3], image.getHeight());
int availableWidth = x2 - x;
int availableHeight = y2 - y;
try {
if (availableWidth > 0 && availableHeight > 0) {
BufferedImage subImage = image.getSubimage(x, y, availableWidth, availableHeight);
Rainbow4J.saveImage(subImage, new File(objectsFolder.getAbsolutePath() + File.separator + element.getObjectName() + ".png"));
} else {
element.setHasImage(false);
}
}
catch (Exception ex) {
LOG.error("Got error during saving image", ex);
}
}
}
}
screenshotOriginalFile.deleteOnExit();
}
private static void copyResource(String resourceName, File destFile) throws IOException {
String value = IOUtils.toString(Galen.class.getResourceAsStream(resourceName));
FileUtils.writeStringToFile(destFile, value);
}
private static boolean isWithinArea(PageElement element, Integer maxWidth, Integer maxHeight) {
Rect area = element.getArea();
if (maxWidth != null && maxHeight != null) {
return maxWidth * maxHeight > area.getWidth() * area.getHeight();
}
else if (maxWidth != null) {
return maxWidth > area.getWidth();
}
else if (maxHeight != null) {
return maxHeight > area.getHeight();
}
else return true;
}
public String getPageName() {
return pageName;
}
public GalenPageDump setPageName(String pageName) {
this.pageName = pageName;
return this;
}
public GalenPageDump setProperties(Properties properties) {
this.properties = properties;
return this;
}
public GalenPageDump setJsVariables(Map jsVariables) {
this.jsVariables = jsVariables;
return this;
}
public void setObjects(Map objects) {
this.objects = objects;
}
public Integer getMaxHeight() {
return maxHeight;
}
public Integer getMaxWidth() {
return maxWidth;
}
public GalenPageDump setMaxHeight(Integer maxHeight) {
this.maxHeight = maxHeight;
return this;
}
public GalenPageDump setMaxWidth(Integer maxWidth) {
this.maxWidth = maxWidth;
return this;
}
public GalenPageDump setOnlyImages(boolean onlyImages) {
this.onlyImages = onlyImages;
return this;
}
public boolean isOnlyImages() {
return onlyImages;
}
public GalenPageDump setExcludedObjects(List excludedObjects) {
this.excludedObjects = excludedObjects;
return this;
}
public List getExcludedObjects() {
return excludedObjects;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy