Java tutorial
/* * Copyright (C) 2015-2016 NS Solutions Corporation * * 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.htmlhifive.pitalium.core.rules; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.NoSuchElementException; import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.junit.rules.TestWatcher; import org.junit.runner.Description; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriverException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fasterxml.jackson.annotation.JsonInclude; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.base.Strings; import com.google.common.base.Supplier; import com.google.common.collect.FluentIterable; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; import com.htmlhifive.pitalium.common.exception.TestRuntimeException; import com.htmlhifive.pitalium.common.util.JSONUtils; import com.htmlhifive.pitalium.core.config.ExecMode; import com.htmlhifive.pitalium.core.config.PtlTestConfig; import com.htmlhifive.pitalium.core.io.PersistMetadata; import com.htmlhifive.pitalium.core.io.Persister; import com.htmlhifive.pitalium.core.model.CompareTarget; import com.htmlhifive.pitalium.core.model.DomSelector; import com.htmlhifive.pitalium.core.model.ExecResult; import com.htmlhifive.pitalium.core.model.IndexDomSelector; import com.htmlhifive.pitalium.core.model.ScreenArea; import com.htmlhifive.pitalium.core.model.ScreenAreaResult; import com.htmlhifive.pitalium.core.model.ScreenshotArgument; import com.htmlhifive.pitalium.core.model.ScreenshotResult; import com.htmlhifive.pitalium.core.model.SelectorType; import com.htmlhifive.pitalium.core.model.TargetResult; import com.htmlhifive.pitalium.core.result.TestResultManager; import com.htmlhifive.pitalium.core.selenium.PtlCapabilities; import com.htmlhifive.pitalium.core.selenium.PtlWebDriver; import com.htmlhifive.pitalium.core.selenium.PtlWebDriverFactory; import com.htmlhifive.pitalium.core.selenium.PtlWebDriverManager; import com.htmlhifive.pitalium.image.model.DiffPoints; import com.htmlhifive.pitalium.image.model.RectangleArea; import com.htmlhifive.pitalium.image.model.ScreenshotImage; import com.htmlhifive.pitalium.image.util.ImageUtils; /** * ?assert????<br/> * ???????@Rule??<br/> * <ul> * <li>??ID?</li> * <li>WebDriver?quit</li> * </ul> * {@link com.htmlhifive.pitalium.core.PtlTestBase}???????????????? */ public class AssertionView extends TestWatcher { private static final Logger LOG = LoggerFactory.getLogger(AssertionView.class); private static final Function<ScreenAreaResult, Rectangle> SCREEN_AREA_RESULT_TO_RECTANGLE_FUNCTION = new Function<ScreenAreaResult, Rectangle>() { @Override public Rectangle apply(ScreenAreaResult input) { return input.getRectangle().toRectangle(); } }; /** * {@link PtlWebDriver}?<br> * WebDriver????????quit??? */ protected PtlWebDriverManager.WebDriverContainer webDriverContainer; /** * ??WebDriver */ protected PtlWebDriver driver; private final Set<String> screenshotIds = new HashSet<String>(); private Description description; private String className; private String methodName; private String currentId; private PtlCapabilities capabilities; private final List<ScreenshotResult> results = new ArrayList<ScreenshotResult>(); private final List<AssertionError> verifyErrors = new ArrayList<AssertionError>(); //<editor-fold desc="Watcher methods"> @Override protected void starting(Description desc) { LOG.info("[Testcase start] (name: {})", desc.getDisplayName()); description = desc; className = getClassName(desc); methodName = getMethodName(desc); currentId = TestResultManager.getInstance().getCurrentId(); } @Override protected void failed(Throwable e, Description desc) { if (e instanceof AssertionError) { LOG.info("[Testcase failed] (assertion error)", e); } else if (e instanceof WebDriverException) { LOG.error("[Testcase failed] (selenium error)", e); } else if (e instanceof TestRuntimeException) { LOG.error("[Testcase failed] (pitalium runtime error)", e); } else { LOG.error("[Testcase failed] (unhandled error)", e); } TestResultManager.getInstance().cancelUpdateExpectedId(className); } @Override protected void succeeded(Description desc) { // ????ExpectedId if (verifyErrors.isEmpty()) { LOG.info("[Testcase succeeded]"); TestResultManager.getInstance().updateExpectedId(className, methodName); return; } LOG.info("[Testcase failed] (verified {} errors)", verifyErrors.size()); TestResultManager.getInstance().cancelUpdateExpectedId(className); String errors = StringUtils .join(FluentIterable.from(verifyErrors).transform(new Function<AssertionError, String>() { @Override public String apply(AssertionError error) { return error.getMessage(); } }).filter(new Predicate<String>() { @Override public boolean apply(String message) { return !Strings.isNullOrEmpty(message); } }), "\n"); throw new AssertionError(String.format(Locale.US, "Verified %d errors: %s", verifyErrors.size(), errors)); } @Override protected void finished(Description desc) { LOG.info("[Testcase finished] (name: {})", desc.getDisplayName()); if (webDriverContainer != null) { webDriverContainer.quit(); driver = null; } if (results.isEmpty()) { return; } synchronized (AssertionView.class) { TestResultManager resultManager = TestResultManager.getInstance(); for (ScreenshotResult result : results) { resultManager.addScreenshotResult(className, result); } } } //</editor-fold> /** * {@link org.openqa.selenium.Capabilities}???{@link PtlWebDriver}?????? * * @param cap * @return ??WebDriver */ public PtlWebDriver createDriver(PtlCapabilities cap) { if (driver != null) { if (!capabilities.equals(cap)) { throw new TestRuntimeException("Capabilities not match"); } return driver; } capabilities = cap; webDriverContainer = PtlWebDriverManager.getInstance().getWebDriver(description.getTestClass(), cap, new Supplier<WebDriver>() { @Override public PtlWebDriver get() { return PtlWebDriverFactory.getInstance(capabilities).getDriver(); } }); driver = webDriverContainer.get(); LOG.debug("[Get WebDriver] Use session ({})", driver); return driver; } //<editor-fold desc="assertView"> /** * ???????{@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}?? * ?????????? ? {@link com.htmlhifive.pitalium.core.config.ExecMode#RUN_TEST}??? * {@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}??????? * * @param screenshotId ?ID */ public void assertView(String screenshotId) { assertView(null, screenshotId); } /** * ???????{@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}?? * ?????????? ? {@link com.htmlhifive.pitalium.core.config.ExecMode#RUN_TEST}??? * {@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}??????? * * @param message {@link AssertionError}? * @param screenshotId ?ID */ public void assertView(String message, String screenshotId) { assertView(message, screenshotId, asList(new CompareTarget(ScreenArea.of(SelectorType.TAG_NAME, "body"))), null); } /** * ???????{@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}?? * ?????????? ? {@link com.htmlhifive.pitalium.core.config.ExecMode#RUN_TEST}??? * {@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}??????? * * @param screenshotId ?ID * @param compareTargets ??? */ public void assertView(String screenshotId, CompareTarget[] compareTargets) { assertView(screenshotId, compareTargets, null); } /** * ???????{@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}?? * ?????????? ? {@link com.htmlhifive.pitalium.core.config.ExecMode#RUN_TEST}??? * {@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}??????? * * @param screenshotId ?ID * @param compareTargets ??? */ public void assertView(String screenshotId, List<CompareTarget> compareTargets) { assertView(null, screenshotId, compareTargets, null); } /** * ???????{@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}?? * ?????????? ? {@link com.htmlhifive.pitalium.core.config.ExecMode#RUN_TEST}??? * {@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}??????? * * @param message {@link AssertionError}? * @param screenshotId ?ID * @param compareTargets ??? */ public void assertView(String message, String screenshotId, List<CompareTarget> compareTargets) { assertView(message, screenshotId, compareTargets, null); } /** * ???????{@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}?? * ?????????? ? {@link com.htmlhifive.pitalium.core.config.ExecMode#RUN_TEST}??? * {@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}??????? * * @param screenshotId ?ID * @param compareTargets ??? * @param hiddenElementsSelectors ????DOM?? */ public void assertView(String screenshotId, CompareTarget[] compareTargets, DomSelector[] hiddenElementsSelectors) { assertView(null, screenshotId, asList(compareTargets), asList(hiddenElementsSelectors)); } /** * ???????{@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}?? * ?????????? ? {@link com.htmlhifive.pitalium.core.config.ExecMode#RUN_TEST}??? * {@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}??????? * * @param screenshotId ?ID * @param compareTargets ??? * @param hiddenElementsSelectors ????DOM?? */ public void assertView(String screenshotId, List<CompareTarget> compareTargets, List<DomSelector> hiddenElementsSelectors) { assertView(null, screenshotId, compareTargets, hiddenElementsSelectors); } /** * ???????{@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}?? * ?????????? ? {@link com.htmlhifive.pitalium.core.config.ExecMode#RUN_TEST}??? * {@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}??????? * * @param arg ????? */ public void assertView(ScreenshotArgument arg) { assertView(null, arg); } /** * ???????{@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}?? * ?????????? ? {@link com.htmlhifive.pitalium.core.config.ExecMode#RUN_TEST}??? * {@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}??????? * * @param message {@link AssertionError}? * @param arg ????? */ public void assertView(String message, ScreenshotArgument arg) { assertView(message, arg.getScreenshotId(), arg.getTargets(), arg.getHiddenElementSelectors()); } /** * ???????{@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}?? * ?????????? ? {@link com.htmlhifive.pitalium.core.config.ExecMode#RUN_TEST}??? * {@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}??????? * * @param message {@link AssertionError}? * @param screenshotId ?ID * @param compareTargets ??? * @param hiddenElementsSelectors ????DOM?? */ public void assertView(String message, String screenshotId, List<CompareTarget> compareTargets, List<DomSelector> hiddenElementsSelectors) { if (driver == null) { throw new TestRuntimeException("Driver is not initialized"); } if (Strings.isNullOrEmpty(screenshotId)) { LOG.error("ScreenshotId cannot be null or empty"); throw new TestRuntimeException("ScreenshotId cannot be null or empty"); } // Check screenshotId if (screenshotIds.contains(screenshotId)) { LOG.error("Duplicate screenshotId ({})", screenshotId); throw new TestRuntimeException("Duplicate screenshotId"); } ExecMode execMode = PtlTestConfig.getInstance().getEnvironment().getExecMode(); LOG.info("[AssertView start] (ssid: {}, Mode: {})", screenshotId, execMode); LOG.trace( "[AssertView start] message: {}, screenshotId: {}, compareTargets: {}, hiddenElementSelectors: {}", message, screenshotId, compareTargets, hiddenElementsSelectors); List<CompareTarget> targets; if (compareTargets == null || compareTargets.isEmpty()) { targets = new ArrayList<CompareTarget>(); targets.add(new CompareTarget()); } else { targets = compareTargets; } screenshotIds.add(screenshotId); // ? ScreenshotResult captureResult = takeCaptureAndPersistImage(screenshotId, targets, hiddenElementsSelectors); List<TargetResult> targetResults = captureResult.getTargetResults(); saveTargetResults(screenshotId, targetResults); ValidateResult validateResult = validateTargetResults(targetResults, targets); // Expected mode if (!execMode.isRunTest()) { ScreenshotResult screenshotResult = getScreenshotResultForExpectedMode(screenshotId, targetResults, validateResult); results.add(screenshotResult); if (!validateResult.isValid()) { LOG.info("[AssertView failed] (validation error, ssid: {})", screenshotId); throw new AssertionError("Invalid selector found"); } LOG.info("[AssertView finished] (ssid: {})", screenshotId); return; } // RunTest mode LOG.info("[AssertView comparison start] (ssid: {})", screenshotId); String expectedId = TestResultManager.getInstance().getExpectedId(className, methodName); PersistMetadata expectedMetadata = new PersistMetadata(expectedId, className, methodName, screenshotId, capabilities); List<TargetResult> expectedTargetResults = TestResultManager.getInstance().getPersister() .loadTargetResults(expectedMetadata); ScreenshotResult screenshotResult = compareTargetResults(screenshotId, expectedId, targetResults, expectedTargetResults, validateResult); results.add(screenshotResult); if (!validateResult.isValid()) { LOG.info("[AssertView failed] (validation error, ssid: {})", screenshotId); throw new AssertionError("Invalid selector found"); } if (!screenshotResult.getResult().isSuccess()) { LOG.info("[AssertView failed] (ssid: {})", screenshotId); throw Strings.isNullOrEmpty(message) ? new AssertionError() : new AssertionError(message); } LOG.info("[AssertView finished] (ssid: {})", screenshotId); } /** * ???????{@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}?? * ?????????? ? {@link com.htmlhifive.pitalium.core.config.ExecMode#RUN_TEST}??? * {@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}???????<br /> * <br /> * {@link #assertView(ScreenshotArgument)}?????{@code RUN_TEST}????????????? * * @param arg ????? */ public void verifyView(ScreenshotArgument arg) { try { LOG.info("[VerifyView start] (ssid: {})", arg.getScreenshotId()); assertView(arg); } catch (AssertionError e) { LOG.info("[VerifyView failed] (ssid: {})", arg.getScreenshotId()); verifyErrors.add(e); } } /** * ???????{@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}?? * ?????????? ? {@link com.htmlhifive.pitalium.core.config.ExecMode#RUN_TEST}??? * {@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}???????<br /> * <br /> * {@link #assertView(ScreenshotArgument)}?????{@code RUN_TEST}????????????? * * @param message {@link AssertionError}? * @param arg ????? */ public void verifyView(String message, ScreenshotArgument arg) { try { LOG.info("[VerifyView start] (ssid: {})", arg.getScreenshotId()); assertView(message, arg); } catch (AssertionError e) { LOG.info("[VerifyView failed] (ssid: {})", arg.getScreenshotId()); verifyErrors.add(e); } } /** * ?????? * * @param targetResults ? * @param compareTargets ??{@link CompareTarget} * @return ?? */ private ValidateResult validateTargetResults(List<TargetResult> targetResults, List<CompareTarget> compareTargets) { return new ValidateResult(validateTargetElementHasSize(targetResults), validateDomSelectorTargetExists(targetResults, compareTargets)); } /** * CompareTarget??????????????????? * * @param targetResults ??{@link CompareTarget} * @return ?????????? */ private List<IndexDomSelector> validateTargetElementHasSize(List<TargetResult> targetResults) { List<IndexDomSelector> selectors = new ArrayList<IndexDomSelector>(); for (TargetResult targetResult : targetResults) { RectangleArea area = targetResult.getTarget().getRectangle(); IndexDomSelector selector = targetResult.getTarget().getSelector(); if (selector != null && (area.getWidth() == 0d || area.getHeight() == 0d)) { selectors.add(selector); LOG.error("[Validation error] element has empty size. ({})", selector); } } return selectors; } /** * CompareTarget?????????????? * * @param targetResults ? * @param compareTargets ??{@link CompareTarget} * @return ???????? */ private List<DomSelector> validateDomSelectorTargetExists(List<TargetResult> targetResults, List<CompareTarget> compareTargets) { Set<DomSelector> selectors = new HashSet<DomSelector>(targetResults.size() * 2); for (TargetResult targetResult : targetResults) { DomSelector selector = targetResult.getTarget().getScreenArea().getSelector(); if (selector != null) { selectors.add(selector); } } List<DomSelector> invalidSelectors = new ArrayList<DomSelector>(); for (CompareTarget compareTarget : compareTargets) { DomSelector selector = compareTarget.getCompareArea().getSelector(); if (selector == null) { continue; } if (!selectors.contains(selector)) { invalidSelectors.add(selector); LOG.error("[Validation error] no element found. ({})", selector); } } return invalidSelectors; } /** * 1??ID??????? * * @param screenshotId ID * @param targetResults ?? */ private void saveTargetResults(String screenshotId, List<TargetResult> targetResults) { PersistMetadata currentMetadata = new PersistMetadata(currentId, className, methodName, screenshotId, capabilities); List<TargetResult> processes = new ArrayList<TargetResult>(targetResults.size()); for (TargetResult target : targetResults) { processes.add(new TargetResult(target.getTarget(), target.getExcludes(), target.getImage())); } TestResultManager.getInstance().getPersister().saveTargetResults(currentMetadata, processes); } /** * ???????? * * @param screenshotId ?ID * @param compareTargets ??? * @param hiddenElementsSelectors ????DOM?? * @return ??{@link ScreenshotResult} */ private ScreenshotResult takeCaptureAndPersistImage(String screenshotId, List<CompareTarget> compareTargets, List<DomSelector> hiddenElementsSelectors) { ScreenshotResult screenshotResult = driver.takeScreenshot(screenshotId, compareTargets, hiddenElementsSelectors); LOG.trace("(takeCaptureAndPersistImage) (ssid: {}) result: {}", screenshotId, screenshotResult); // Persist all screenshots Persister persister = TestResultManager.getInstance().getPersister(); ScreenshotImage entireScreenshotImage = screenshotResult.getEntireScreenshotImage(); if (entireScreenshotImage.isImageCached()) { persister.saveScreenshot( new PersistMetadata(currentId, className, methodName, screenshotId, null, null, capabilities), entireScreenshotImage.get()); } for (TargetResult targetResult : screenshotResult.getTargetResults()) { ScreenshotImage image = targetResult.getImage(); if (!image.isImageCached()) { LOG.debug("(takeCaptureAndPersistImage) Screenshot image was not captured. ({})", targetResult.getTarget()); continue; } ScreenAreaResult target = targetResult.getTarget(); PersistMetadata metadata; if (target.getSelector() == null) { metadata = new PersistMetadata(currentId, className, methodName, screenshotId, null, target.getRectangle(), capabilities); } else { metadata = new PersistMetadata(currentId, className, methodName, screenshotId, target.getSelector(), null, capabilities); } persister.saveScreenshot(metadata, image.get()); } return screenshotResult; } /** * Expected?ScreenshotResult???? * * @param screenshotId ID * @param targetResults ? * @param validateResult ?? * @return ??{@link ScreenshotResult} */ private ScreenshotResult getScreenshotResultForExpectedMode(String screenshotId, List<TargetResult> targetResults, ValidateResult validateResult) { List<TargetResult> processes = new ArrayList<TargetResult>(targetResults.size()); for (TargetResult target : targetResults) { processes.add(new TargetResult(null, target.getTarget(), target.getExcludes(), target.isMoveTarget(), target.getHiddenElementSelectors())); } for (DomSelector selector : validateResult.noElementSelectors) { processes.add(new TargetResult(null, new ScreenAreaResult(null, null, new ScreenArea(selector)), null, null, null)); } ExecResult result = validateResult.isValid() ? null : ExecResult.FAILURE; return new ScreenshotResult(screenshotId, result, null, processes, className, methodName, capabilities.asMap(), null); } /** * Actual?ScreenshotResult???? * * @param screenshotId ID * @param expectedId ?ID * @param currents ?? * @param expects ? * @param validateResult ?? * @return ????{@link ScreenshotResult} */ private ScreenshotResult compareTargetResults(String screenshotId, String expectedId, List<TargetResult> currents, List<TargetResult> expects, ValidateResult validateResult) { boolean assertFail = !validateResult.isValid(); List<TargetResult> processes = new ArrayList<TargetResult>(currents.size()); for (final TargetResult current : currents) { // Target element's area was nothing IndexDomSelector selector = current.getTarget().getSelector(); if (selector != null && validateResult.noAreaElementSelectors.contains(selector)) { processes.add(new TargetResult(ExecResult.FAILURE, current.getTarget(), current.getExcludes(), current.isMoveTarget(), current.getHiddenElementSelectors())); LOG.debug("[Comparison skipped] ({})", current.getTarget()); continue; } TargetResult expected; try { expected = Iterators.find(expects.iterator(), new Predicate<TargetResult>() { @Override public boolean apply(TargetResult input) { return current.getTarget().areaEquals(input.getTarget()); } }); } catch (NoSuchElementException e) { LOG.error("[Comparison failed] No element found for target ({}).", current.getTarget()); processes.add(new TargetResult(null, current.getTarget(), current.getExcludes(), current.isMoveTarget(), current.getHiddenElementSelectors())); assertFail = true; continue; } // ? LOG.debug("[Comparison start] ({})", current); ImageRectanglePair currentImage = prepareScreenshotImageForCompare(current); ImageRectanglePair expectedImage = prepareScreenshotImageForCompare(expected); DiffPoints compareResult = ImageUtils.compare(currentImage.image, currentImage.rectangle, expectedImage.image, expectedImage.rectangle, current.getOptions()); assertFail |= compareResult.isFailed(); if (compareResult.isFailed()) { LOG.error("[Comparison failed] ({})", current); } else { LOG.debug("[Comparison success] ({})", current); } processes.add(new TargetResult(compareResult.isSucceeded() ? ExecResult.SUCCESS : ExecResult.FAILURE, current.getTarget(), current.getExcludes(), current.isMoveTarget(), current.getHiddenElementSelectors())); // ?Fail???????? if (compareResult.isFailed()) { LOG.debug("[Create diff image] ({})", current); BufferedImage diffImage = ImageUtils.getDiffImage(expectedImage.image, currentImage.image, compareResult); // Metadata???? ScreenAreaResult target = current.getTarget(); PersistMetadata metadata; if (target.getSelector() == null) { metadata = new PersistMetadata(currentId, className, methodName, screenshotId, null, target.getRectangle(), capabilities); } else { metadata = new PersistMetadata(currentId, className, methodName, screenshotId, target.getSelector(), null, capabilities); } TestResultManager.getInstance().getPersister().saveDiffImage(metadata, diffImage); } } for (DomSelector selector : validateResult.noElementSelectors) { processes.add(new TargetResult(null, new ScreenAreaResult(null, null, new ScreenArea(selector)), null, null, null)); } return new ScreenshotResult(screenshotId, assertFail ? ExecResult.FAILURE : ExecResult.SUCCESS, expectedId, processes, className, methodName, capabilities.asMap(), null); } /** * ??????????????? * * @param target ? * @return ???? */ private ImageRectanglePair prepareScreenshotImageForCompare(TargetResult target) { BufferedImage image = target.getImage().get(); // Mask List<ScreenAreaResult> excludes = target.getExcludes(); if (!excludes.isEmpty()) { List<Rectangle> maskAreas = Lists.transform(excludes, SCREEN_AREA_RESULT_TO_RECTANGLE_FUNCTION); image = ImageUtils.getMaskedImage(image, maskAreas); } return new ImageRectanglePair(image, target.getTarget().getRectangle().toRectangle()); } //</editor-fold> //<editor-fold desc="assertScreenshot"> /** * ??????????????????????diff?????????? * * @param screenshotResult {@link PtlWebDriver#takeScreenshot(String) takeScreenshot}?????? */ public void assertScreenshot(ScreenshotResult screenshotResult) { assertScreenshot(null, screenshotResult); } /** * ??????????????????????diff?????????? * * @param message ?? * @param screenshotResult {@link PtlWebDriver#takeScreenshot(String) takeScreenshot}?????? */ public void assertScreenshot(String message, ScreenshotResult screenshotResult) { ExecMode execMode = PtlTestConfig.getInstance().getEnvironment().getExecMode(); String screenshotId = screenshotResult.getScreenshotId(); if (!execMode.isRunTest()) { LOG.debug("[AssertScreenshot skipped] (ssid: {}, mode: {})", screenshotId, execMode); return; } String expectedId = TestResultManager.getInstance().getExpectedId(className, methodName); PersistMetadata expectedMetadata = new PersistMetadata(expectedId, className, methodName, screenshotId, capabilities); List<TargetResult> expectedTargetResults = TestResultManager.getInstance().getPersister() .loadTargetResults(expectedMetadata); LOG.info("[AssertScreenshot comparison start] (ssid: {})", screenshotId); ScreenshotResult result = compareTargetResults(screenshotId, expectedId, screenshotResult.getTargetResults(), expectedTargetResults, new ValidateResult()); if (!result.getResult().isSuccess()) { LOG.info("[AssertScreenshot failed] (ssid: {})", screenshotId); throw Strings.isNullOrEmpty(message) ? new AssertionError() : new AssertionError(message); } LOG.info("[AssertScreenshot succeeded] (ssid: {})", screenshotId); } /** * ??????????????????????diff????????<br /> * <br /> * {@link #assertScreenshot(ScreenshotResult)}????????????????? * * @param screenshotResult {@link PtlWebDriver#takeScreenshot(String) takeScreenshot}?????? */ public void verifyScreenshot(ScreenshotResult screenshotResult) { try { LOG.info("[VerifyScreenshot start] (ssid: {})", screenshotResult.getExpectedId()); assertScreenshot(screenshotResult); } catch (AssertionError e) { LOG.info("[VerifyScreenshot failed] (ssid: {})", screenshotResult.getScreenshotId()); verifyErrors.add(e); } } /** * ??????????????????????diff????????<br /> * <br /> * {@link #assertScreenshot(ScreenshotResult)}????????????????? * * @param message ?? * @param screenshotResult {@link PtlWebDriver#takeScreenshot(String) takeScreenshot}?????? */ public void verifyScreenshot(String message, ScreenshotResult screenshotResult) { try { LOG.info("[VerifyScreenshot start] (ssid: {})", screenshotResult.getExpectedId()); assertScreenshot(message, screenshotResult); } catch (AssertionError e) { LOG.info("[VerifyScreenshot failed] (ssid: {})", screenshotResult.getScreenshotId()); verifyErrors.add(e); } } //</editor-fold> //<editor-fold desc="assertExists"> /** * ??????????????????<br /> * ?????{@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}??????? * * @param image ??? */ public void assertExist(BufferedImage image) { assertExist(null, image); } /** * ??????????????????<br /> * ?????{@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}??????? * * @param message {@link AssertionError}? * @param image ??? */ public void assertExist(String message, BufferedImage image) { ExecMode execMode = PtlTestConfig.getInstance().getEnvironment().getExecMode(); if (!execMode.isRunTest()) { LOG.debug("[AssertExist skipped] (mode: {})", execMode); return; } // Capture body LOG.debug("[AssertExist capture start]"); ScreenshotImage screenshot = driver.takeScreenshot("assertExists").getTargetResults().get(0).getImage(); BufferedImage entireScreenshotImage = screenshot.get(); LOG.debug("[AssertExist capture finished]"); if (ImageUtils.isContained(entireScreenshotImage, image)) { LOG.info("[AssertExist succeeded]"); return; } LOG.info("[AssertExist failed]"); throw Strings.isNullOrEmpty(message) ? new AssertionError() : new AssertionError(message); } /** * ??????????????????<br /> * ?????{@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}???????<br /> * <br /> * {@link #assertExist(BufferedImage)}????????????????? * * @param image ??? */ public void verifyExists(BufferedImage image) { try { LOG.info("[VerifyExist start]"); assertExist(image); } catch (AssertionError e) { LOG.info("[VerifyExist failed]"); verifyErrors.add(e); } } /** * ??????????????????<br /> * ?????{@link com.htmlhifive.pitalium.core.config.ExecMode#SET_EXPECTED}???????<br /> * <br /> * {@link #assertExist(BufferedImage)}????????????????? * * @param message {@link AssertionError}? * @param image ??? */ public void verifyExists(String message, BufferedImage image) { try { LOG.info("[VerifyExist start]"); assertExist(message, image); } catch (AssertionError e) { LOG.info("[VerifyExist failed]"); verifyErrors.add(e); } } //</editor-fold> /** * ??????? * * @param description ??Description * @return ?? */ private static String getClassName(Description description) { return description.getTestClass().getSimpleName(); } /** * ??????? * * @param description ??Description * @return ?? */ private static String getMethodName(Description description) { return description.getMethodName().split("\\[")[0]; } /** * ?List????? * * @param <T> ??? * @param array ?? * @return ?List */ @SafeVarargs private static <T> List<T> asList(T... array) { if (array == null || array.length == 0) { return Collections.emptyList(); } else if (array.length == 1) { return Collections.singletonList(array[0]); } else { return Arrays.asList(array); } } /** * ?????? */ private static class ImageRectanglePair { private final BufferedImage image; private final Rectangle rectangle; /** * ?????????? * * @param image ? * @param rectangle */ public ImageRectanglePair(BufferedImage image, Rectangle rectangle) { this.image = image; this.rectangle = rectangle; } } /** * ????? */ private static class ValidateResult { /** * ???????? */ @JsonInclude private final Collection<IndexDomSelector> noAreaElementSelectors; /** * ?????? */ @JsonInclude private final Collection<DomSelector> noElementSelectors; /** * ??????? */ public ValidateResult() { this(new ArrayList<IndexDomSelector>(), new ArrayList<DomSelector>()); } /** * ????????????????<br> * ?????? * * @param noAreaElementSelectors ???????? * @param noElementSelectors ?????? */ public ValidateResult(Collection<IndexDomSelector> noAreaElementSelectors, Collection<DomSelector> noElementSelectors) { this.noAreaElementSelectors = noAreaElementSelectors; this.noElementSelectors = noElementSelectors; } /** * ????Valid??????? * * @return Valid?true?Invalid?false */ public boolean isValid() { return noAreaElementSelectors.isEmpty() && noElementSelectors.isEmpty(); } @Override public String toString() { return "ValidateResult: " + JSONUtils.toString(this); } } }