< prev index next >

tools/SharedTestUtilsOpen/src/test/javaclient/shared/screenshots/ScreenshotUtils.java

Print this page
rev 320 : 8151500: [TEST] Implement multiple golden image support
Summary: Makes possible using any number of golden images.

*** 1,7 **** /* ! * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 21,77 **** * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any */ package test.javaclient.shared.screenshots; ! import java.io.File; ! import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.layout.Pane; import javafx.stage.Stage; import org.jemmy.Rectangle; import org.jemmy.TimeoutExpiredException; - import org.jemmy.action.GetAction; import org.jemmy.control.Wrap; - import org.jemmy.env.Environment; import org.jemmy.fx.ByWindowType; import org.jemmy.fx.NodeDock; import org.jemmy.fx.Root; import org.jemmy.image.Image; import org.jemmy.interfaces.Parent; - import org.jemmy.timing.State; import org.junit.Assert; import test.javaclient.shared.AbstractTestableApplication; import test.javaclient.shared.JemmyUtils; - import test.javaclient.shared.TestUtil; - import test.javaclient.shared.description.FXSceneTreeBuilder; - import test.javaclient.shared.description.FXSimpleNodeDescription; - import test.javaclient.shared.description.TreeNode; /** ! * @author Andrey Glushchenko */ public class ScreenshotUtils { ! //private static Wrap<? extends Scene> scene = null; private static AbstractTestableApplication application; ! /** ! * Verify or generate golden screenshot for a test depending on ! * <code>IS_GOLDEN_MODE</code> status. * * @param testClass * @param testName test name for a test * @param scene scene to take a screenshot of */ public static void checkScreenshot(Class testClass, String testName, Wrap node) { checkScreenshot(testClass.getName() + "." + testName, node); } /** ! * Verify or generate golden screenshot for a test depending on ! * <code>IS_GOLDEN_MODE</code> status. * * @param testName test name for a test * @param scene scene to take a screenshot of */ public static void checkScreenshot(String testName, Wrap node) { --- 21,71 ---- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any */ package test.javaclient.shared.screenshots; ! import java.nio.file.Paths; import java.util.LinkedList; import java.util.List; import javafx.scene.Node; import javafx.scene.Scene; import javafx.scene.layout.Pane; import javafx.stage.Stage; import org.jemmy.Rectangle; import org.jemmy.TimeoutExpiredException; import org.jemmy.control.Wrap; import org.jemmy.fx.ByWindowType; import org.jemmy.fx.NodeDock; import org.jemmy.fx.Root; import org.jemmy.image.Image; + import org.jemmy.image.ImageLoader; import org.jemmy.interfaces.Parent; import org.junit.Assert; import test.javaclient.shared.AbstractTestableApplication; import test.javaclient.shared.JemmyUtils; /** ! * @author Andrey Glushchenko, andrey.rusakov@oracle.com */ public class ScreenshotUtils { ! ! private static final List<Throwable> SCREENSHOT_ERRORS = new LinkedList<>(); private static AbstractTestableApplication application; ! ! /** ! * Verify or generate golden screenshot for a test. * * @param testClass * @param testName test name for a test * @param scene scene to take a screenshot of */ public static void checkScreenshot(Class testClass, String testName, Wrap node) { checkScreenshot(testClass.getName() + "." + testName, node); } + /** ! * Verify or generate golden screenshot for a test. * * @param testName test name for a test * @param scene scene to take a screenshot of */ public static void checkScreenshot(String testName, Wrap node) {
*** 81,234 **** public static void checkScreenshot(String testName, Wrap node, int width, int height) { checkScreenshot(testName, node, new Rectangle(width, height)); } public static void checkScreenshot(String testName, final Wrap node, Rectangle rect) { ! Image sceneImage; ! if (rect != null) { ! sceneImage = node.getScreenImage(rect); ! } else { ! sceneImage = node.getScreenImage(); ! } ! String name = ImagesManager.getInstance().lookupGoldenScreenshot(testName); ! String descrName = ImagesManager.getInstance().getDescriptionPath(testName); ! Assert.assertNotNull("Invalid images path", name); ! if (TestUtil.IS_GOLDEN_MODE) { ! //TODO: specified directory ! sceneImage.save(ImagesManager.getInstance().getScreenshotPath(testName)); ! } else { ! String diffName = ImagesManager.getInstance().getScreenshotPath(testName + "-diff"); ! String resName = ImagesManager.getInstance().getScreenshotPath(testName); ! if (TestUtil.IS_DESCRIPTION_MODE) { ! String descr_name = ImagesManager.getInstance().lookupGoldenDescription(testName); ! if (new File(descr_name).exists()) { ! try { ! List<TreeNode<FXSimpleNodeDescription>> list = (List<TreeNode<FXSimpleNodeDescription>>) TestUtil.read(descr_name); ! node.waitState(new State<List<TreeNode<FXSimpleNodeDescription>>>() { ! public List<TreeNode<FXSimpleNodeDescription>> reached() { ! return FXSceneTreeBuilder.build(node); ! } ! ! @Override ! public String toString() { ! return "Control having expected image description"; ! } ! }, list); ! } catch (TimeoutExpiredException e) { ! if (diffName != null) { ! node.getEnvironment().getOutput(Wrap.OUTPUT).println("Saving difference to " + diffName); ! final Image diffImage = node.getScreenImage().compareTo(node.getEnvironment().getImageLoader().load(name)); ! if (diffImage != null) { ! diffImage.save(diffName); ! } ! } ! throw e; ! } finally { ! if (resName != null) { ! node.getEnvironment().getOutput(Wrap.OUTPUT).println("Saving result to " + resName); ! node.getScreenImage().save(resName); ! } ! } ! } else { ! Assert.fail("Golden image description (" + descr_name + ") not found. Actual image is saved as " + descrName); ! ArrayList<TreeNode<FXSimpleNodeDescription>> description = FXSceneTreeBuilder.build(node); ! TestUtil.write(description, descrName); ! } ! } else { ! if (new File(name).exists()) { try { if (rect != null) { ! node.waitImage(node.getEnvironment().getImageLoader().load(name), rect, resName, diffName); } else { ! node.waitImage(node.getEnvironment().getImageLoader().load(name), resName, diffName); } } catch (TimeoutExpiredException imagesAreDifferentException) { - //If images are really different, then not only diff and - //original images are to put in the results folder, but also golden image. try { ! String expectedName = ImagesManager.getInstance().getScreenshotPath(testName + "-expected"); ! node.getEnvironment().getImageLoader().load(name).save(expectedName); } catch (Throwable ex) { ! ex.printStackTrace(); } - throw imagesAreDifferentException; } - if (TestUtil.IS_DESCRIBING_MODE) { - ArrayList<TreeNode<FXSimpleNodeDescription>> description = FXSceneTreeBuilder.build(node); - TestUtil.write(description, descrName); - } - } else { - sceneImage.save(resName); - Assert.fail("Golden image (" + name + ") not found. Actual image is saved as " + resName); } } } - } - private static List<Throwable> screenshotErrors = new LinkedList<Throwable>(); public static void setApplication(AbstractTestableApplication application) { ScreenshotUtils.application = application; } public static void setScene(Wrap<? extends Scene> scene) { // ScreenshotUtils.scene = scene; } ! private static void error(Throwable ex){ ! screenshotErrors.add(ex); ex.printStackTrace(); } ! /** ! * Set image comparator distance. Should be called from constructor or {} ! * class initialization block. ! * ! * @param comparatorDistance distance ! */ public static void setComparatorDistance(float comparatorDistance) { JemmyUtils.comparatorDistance = comparatorDistance; } ! public static void throwScreenshotErrors(){ StringBuilder sb = new StringBuilder(); ! for(Throwable ex: screenshotErrors){ sb.append(ex.toString()).append("\n"); } ! screenshotErrors.clear(); String msg = sb.toString(); ! if(!"".equals(msg) && msg!=null){ Assert.fail(msg); } } public static void checkPageContentScreenshot(String name) { checkPageContentScreenshot(name, false); } public static void checkPageContentScreenshot(String name, boolean valuable_rect) { try { ! if(application.getNodeForScreenshot()==null){ final Wrap<? extends Scene> scene = Root.ROOT.lookup(new ByWindowType(Stage.class)).lookup(Scene.class).wrap(0); checkScreenshot(name, scene); ! }else{ ! if (valuable_rect) { checkScreenshot(name, getPageContent(), getPageContentSize()); } else { checkScreenshot(name, getPageContent()); } - } } catch (Throwable th) { error(th); } } public static Wrap<? extends Node> getPageContent() { Node n = application.getNodeForScreenshot(); final Wrap<? extends Scene> scene = Root.ROOT.lookup(new ByWindowType(Stage.class)).lookup(Scene.class).wrap(0); return new NodeDock(scene.as(Parent.class, Node.class), n.getId()).wrap(); } /** * ! * @return rectangle contains all children of page content. This rectangle ! * may have different size then size of Content. */ public static Rectangle getPageContentSize() { Node node = getPageContent().getControl(); Rectangle rect = new Rectangle(); if (node instanceof Pane) { --- 75,181 ---- public static void checkScreenshot(String testName, Wrap node, int width, int height) { checkScreenshot(testName, node, new Rectangle(width, height)); } public static void checkScreenshot(String testName, final Wrap node, Rectangle rect) { ! ImageLoader imgLoader = node.getEnvironment().getImageLoader(); ! List<String> goldenImages = GoldenImageManager.getTestImages(testName, ".png"); ! String resultPath = GoldenImageManager.getScreenshotPath(testName); ! if (goldenImages.isEmpty()) { ! Image sceneImage = (rect == null) ? node.getScreenImage() : node.getScreenImage(rect); ! sceneImage.save(resultPath); ! throw new RuntimeException("No golden images found for " + testName ! + ", actual image saved to " + resultPath); ! } ! boolean nothingMatched = true; ! for (int i = 0; i < goldenImages.size(); i++) { ! String goldenPath = goldenImages.get(i); ! String goldenName = Paths.get(goldenPath).getFileName().toString() ! .replaceFirst("\\.[^\\.]*$", String.format("-%02d", i)); ! String diffPath = GoldenImageManager.getScreenshotPath(goldenName + "-diff"); ! Image image = imgLoader.load(goldenPath); try { if (rect != null) { ! node.waitImage(image, rect, resultPath, diffPath); } else { ! node.waitImage(image, resultPath, diffPath); } + nothingMatched = false; + break; } catch (TimeoutExpiredException imagesAreDifferentException) { try { ! String expectedName = GoldenImageManager.getScreenshotPath(goldenName + "-expected"); ! imgLoader.load(goldenPath).save(expectedName); } catch (Throwable ex) { ! System.err.println(ex); } } } + if (nothingMatched) { + throw new TimeoutExpiredException("Control having expected image has not been reached"); } } public static void setApplication(AbstractTestableApplication application) { ScreenshotUtils.application = application; } + public static void setScene(Wrap<? extends Scene> scene) { // ScreenshotUtils.scene = scene; } ! private static void error(Throwable ex) { ! SCREENSHOT_ERRORS.add(ex); ex.printStackTrace(); } ! public static void setComparatorDistance(float comparatorDistance) { JemmyUtils.comparatorDistance = comparatorDistance; } ! ! public static void throwScreenshotErrors() { StringBuilder sb = new StringBuilder(); ! for (Throwable ex : SCREENSHOT_ERRORS) { sb.append(ex.toString()).append("\n"); } ! SCREENSHOT_ERRORS.clear(); String msg = sb.toString(); ! if (!"".equals(msg) && msg != null) { Assert.fail(msg); } } public static void checkPageContentScreenshot(String name) { checkPageContentScreenshot(name, false); } public static void checkPageContentScreenshot(String name, boolean valuable_rect) { try { ! if (application.getNodeForScreenshot() == null) { final Wrap<? extends Scene> scene = Root.ROOT.lookup(new ByWindowType(Stage.class)).lookup(Scene.class).wrap(0); checkScreenshot(name, scene); ! } else if (valuable_rect) { checkScreenshot(name, getPageContent(), getPageContentSize()); } else { checkScreenshot(name, getPageContent()); } } catch (Throwable th) { error(th); } } + public static Wrap<? extends Node> getPageContent() { Node n = application.getNodeForScreenshot(); final Wrap<? extends Scene> scene = Root.ROOT.lookup(new ByWindowType(Stage.class)).lookup(Scene.class).wrap(0); return new NodeDock(scene.as(Parent.class, Node.class), n.getId()).wrap(); } + /** * ! * @return rectangle contains all children of page content. This rectangle may have different ! * size then size of Content. */ public static Rectangle getPageContentSize() { Node node = getPageContent().getControl(); Rectangle rect = new Rectangle(); if (node instanceof Pane) {
< prev index next >