
com.applitools.eyes.selenium.rendering.VisualGridEyes Maven / Gradle / Ivy
package com.applitools.eyes.selenium.rendering;
import com.applitools.ICheckSettings;
import com.applitools.ICheckSettingsInternal;
import com.applitools.connectivity.ServerConnector;
import com.applitools.eyes.*;
import com.applitools.eyes.capture.ImageProvider;
import com.applitools.eyes.config.Configuration;
import com.applitools.eyes.config.ConfigurationProvider;
import com.applitools.eyes.debug.DebugScreenshotsProvider;
import com.applitools.eyes.debug.FileDebugScreenshotsProvider;
import com.applitools.eyes.debug.NullDebugScreenshotProvider;
import com.applitools.eyes.fluent.CheckSettings;
import com.applitools.eyes.fluent.GetFloatingRegion;
import com.applitools.eyes.fluent.GetSimpleRegion;
import com.applitools.eyes.logging.Stage;
import com.applitools.eyes.logging.TraceLevel;
import com.applitools.eyes.logging.Type;
import com.applitools.eyes.selenium.*;
import com.applitools.eyes.selenium.fluent.*;
import com.applitools.eyes.selenium.frames.Frame;
import com.applitools.eyes.selenium.frames.FrameChain;
import com.applitools.eyes.selenium.wrappers.EyesSeleniumDriver;
import com.applitools.eyes.selenium.wrappers.EyesTargetLocator;
import com.applitools.eyes.visualgrid.model.*;
import com.applitools.eyes.visualgrid.services.CheckTask;
import com.applitools.eyes.visualgrid.services.VisualGridRunner;
import com.applitools.eyes.visualgrid.services.VisualGridRunningTest;
import com.applitools.utils.ArgumentGuard;
import com.applitools.utils.ClassVersionGetter;
import com.applitools.utils.GeneralUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.http.client.utils.URIBuilder;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;
public class VisualGridEyes implements ISeleniumEyes {
private final Logger logger;
private final String eyesId = UUID.randomUUID().toString();
private final VisualGridRunner runner;
final Map testList = new HashMap<>();
private boolean isOpen = false;
private final String PROCESS_PAGE;
private final String PROCESS_PAGE_FOR_IE;
private final String POLL_RESULT;
private final String POLL_RESULT_FOR_IE;
private EyesSeleniumDriver webDriver;
private String url;
private Boolean isDisabled = Boolean.FALSE;
private final ConfigurationProvider configurationProvider;
private UserAgent userAgent = null;
private RectangleSize viewportSize;
private final List properties = new ArrayList<>();
private ImageProvider imageProvider;
private DebugScreenshotsProvider debugScreenshotsProvider = new NullDebugScreenshotProvider();
private static final String GET_ELEMENT_XPATH_JS =
"var el = arguments[0];" +
"var xpath = '';" +
"do {" +
" var parent = el.parentElement;" +
" var index = 1;" +
" if (parent !== null) {" +
" var children = parent.children;" +
" for (var childIdx in children) {" +
" var child = children[childIdx];" +
" if (child === el) break;" +
" if (child.tagName === el.tagName) index++;" +
" }" +
"}" +
"xpath = '/' + el.tagName + '[' + index + ']' + xpath;" +
" el = parent;" +
"} while (el !== null);" +
"return '/' + xpath;";
public VisualGridEyes(VisualGridRunner renderingGridManager, ConfigurationProvider configurationProvider) {
this.configurationProvider = configurationProvider;
ArgumentGuard.notNull(renderingGridManager, "renderingGridRunner");
this.runner = renderingGridManager;
this.logger = renderingGridManager.getLogger();
try {
PROCESS_PAGE = GeneralUtils.readToEnd(VisualGridEyes.class.getResourceAsStream("/dom-snapshot/dist/processPagePoll.js"));
PROCESS_PAGE_FOR_IE = GeneralUtils.readToEnd(VisualGridEyes.class.getResourceAsStream("/dom-snapshot/dist/processPagePollForIE.js"));
POLL_RESULT = GeneralUtils.readToEnd(VisualGridEyes.class.getResourceAsStream("/dom-snapshot/dist/pollResult.js"));
POLL_RESULT_FOR_IE = GeneralUtils.readToEnd(VisualGridEyes.class.getResourceAsStream("/dom-snapshot/dist/pollResultForIE.js"));
} catch (IOException e) {
throw new EyesException("Failed getting resources for dom scripts", e);
}
}
/**
* Sets a handler of log messages generated by this API.
* @param logHandler Handles log messages generated by this API.
*/
public void setLogHandler(LogHandler logHandler) {
if (getIsDisabled()) {
return;
}
this.logger.setLogHandler(logHandler);
if (!logHandler.isOpen()) {
logHandler.open();
}
}
public LogHandler getLogHandler() {
if (getIsDisabled()) return NullLogHandler.instance;
return this.logger.getLogHandler();
}
public void apiKey(String apiKey) {
setApiKey(apiKey);
}
public void serverUrl(String serverUrl) {
setServerUrl(serverUrl);
}
public void setImageProvider(ImageProvider imageProvider) {
this.imageProvider = imageProvider;
}
public void setSaveDebugScreenshots(boolean saveDebugScreenshots) {
DebugScreenshotsProvider prev = debugScreenshotsProvider;
if (saveDebugScreenshots) {
debugScreenshotsProvider = new FileDebugScreenshotsProvider(logger);
} else {
debugScreenshotsProvider = new NullDebugScreenshotProvider();
}
debugScreenshotsProvider.setPrefix(prev.getPrefix());
debugScreenshotsProvider.setPath(prev.getPath());
}
public void setDebugScreenshotsPath(String pathToSave) {
debugScreenshotsProvider.setPath(pathToSave);
}
public void setDebugScreenshotsPrefix(String prefix) {
debugScreenshotsProvider.setPrefix(prefix);
}
@Override
public WebDriver open(WebDriver driver, String appName, String testName, RectangleSize viewportSize) throws EyesException {
logger.log(TraceLevel.Info, Collections.singleton(eyesId), Stage.OPEN, Type.CALLED,
Pair.of("appName", appName),
Pair.of("testName", testName),
Pair.of("viewportSize", viewportSize == null ? "default" : viewportSize));
getConfiguration().setAppName(appName).setTestName(testName);
if (viewportSize != null && !viewportSize.isEmpty()) {
getConfiguration().setViewportSize(new RectangleSize(viewportSize));
}
return open(driver);
}
public WebDriver open(WebDriver webDriver) {
if (getIsDisabled()) {
return webDriver;
}
runner.setApiKey(getApiKey());
runner.setServerUrl(getServerUrl().toString());
runner.setProxy(getProxy());
ArgumentGuard.notNull(webDriver, "webDriver");
ArgumentGuard.notNullOrEmpty(getConfiguration().getAppName(), "appIdOrName");
ArgumentGuard.notNullOrEmpty(getConfiguration().getTestName(), "scenarioIdOrName");
if (isOpen) {
return this.webDriver != null ? this.webDriver : webDriver;
}
isOpen = true;
initDriver(webDriver);
String uaString = this.webDriver.getUserAgent();
if (uaString != null) {
userAgent = UserAgent.parseUserAgentString(uaString, true);
}
setViewportSize(this.webDriver);
ensureBrowsers();
if (getConfiguration().getBatch() == null) {
getConfiguration().setBatch(new BatchInfo(null));
}
List browserInfoList = getConfiguration().getBrowsersInfo();
getConfiguration().setViewportSize(viewportSize);
if (getConfiguration().getBrowsersInfo() == null) {
RectangleSize viewportSize = getConfiguration().getViewportSize();
getConfiguration().addBrowser(new RenderBrowserInfo(viewportSize.getWidth(), viewportSize.getHeight(), BrowserType.CHROME, getConfiguration().getBaselineEnvName()));
}
if (runner.getAgentId() == null ) {
runner.setAgentId(getFullAgentId());
}
runner.setLogger(logger);
List newTests = new ArrayList<>();
ServerConnector serverConnector = runner.getServerConnector();
for (RenderBrowserInfo browserInfo : browserInfoList) {
if (browserInfo.getEmulationInfo() != null) {
Map deviceSizes = serverConnector.getDevicesSizes(ServerConnector.EMULATED_DEVICES_PATH);
browserInfo.setEmulationDeviceSize(deviceSizes.get(browserInfo.getEmulationInfo().getDeviceName()));
}
if (browserInfo.getIosDeviceInfo() != null) {
Map deviceSizes = serverConnector.getDevicesSizes(ServerConnector.IOS_DEVICES_PATH);
browserInfo.setIosDeviceSize(deviceSizes.get(browserInfo.getIosDeviceInfo().getDeviceName()));
}
VisualGridRunningTest test = new VisualGridRunningTest(logger, eyesId, getConfiguration(), browserInfo, this.properties, serverConnector);
this.testList.put(test.getTestId(), test);
newTests.add(test);
}
try {
runner.open(this, newTests);
} catch (Throwable t) {
for (RunningTest runningTest : testList.values()) {
runningTest.openFailed(t);
}
throw t;
}
return this.webDriver != null ? this.webDriver : webDriver;
}
private void ensureBrowsers() {
if (this.getConfiguration().getBrowsersInfo().isEmpty()) {
getConfiguration().getBrowsersInfo().add(new RenderBrowserInfo(viewportSize, BrowserType.CHROME));
}
}
void setViewportSize(EyesSeleniumDriver webDriver) {
viewportSize = getConfiguration().getViewportSize();
if (viewportSize == null) {
List browserInfoList = getConfiguration().getBrowsersInfo();
if (browserInfoList != null && !browserInfoList.isEmpty()) {
for (RenderBrowserInfo deviceInfo : browserInfoList) {
if (deviceInfo.getEmulationInfo() != null || deviceInfo.getIosDeviceInfo() != null) {
continue;
}
viewportSize = new RectangleSize(deviceInfo.getWidth(), deviceInfo.getHeight());
}
}
}
if (viewportSize == null) {
viewportSize = EyesDriverUtils.getViewportSize(webDriver);
}
try {
EyesDriverUtils.setViewportSize(logger, webDriver, viewportSize);
} catch (Exception e) {
GeneralUtils.logExceptionStackTrace(logger, Stage.OPEN, e);
}
}
private void initDriver(WebDriver webDriver) {
if (webDriver instanceof RemoteWebDriver) {
SeleniumEyes seleniumEyes = new SeleniumEyes(configurationProvider, new ClassicRunner());
this.webDriver = new EyesSeleniumDriver(logger, seleniumEyes, (RemoteWebDriver) webDriver);
}
this.url = webDriver.getCurrentUrl();
}
public TestResults close(boolean throwException) {
closeAsync();
return waitForEyesToFinish(throwException);
}
public TestResults abortIfNotClosed() {
abortAsync();
return waitForEyesToFinish(false);
}
public TestResults abort() {
return abortIfNotClosed();
}
public void closeAsync() {
if (getIsDisabled()) {
return;
}
logger.log(eyesId, Stage.CLOSE, Type.CALLED);
isOpen = false;
for (RunningTest runningTest : testList.values()) {
runningTest.issueClose();
}
}
public void abortAsync() {
logger.log(eyesId, Stage.CLOSE, Type.CALLED);
for (RunningTest runningTest : testList.values()) {
runningTest.issueAbort(new EyesException("eyes.close wasn't called. Aborted the test"), false);
}
}
private TestResults waitForEyesToFinish(boolean throwException) {
while (!isCompleted()) {
try {
Thread.sleep(500);
} catch (InterruptedException ignored) {}
}
List allResults = getAllTestResults();
TestResultContainer errorResult = null;
TestResults firstResult = null;
for (TestResultContainer result : allResults) {
if (firstResult == null) {
firstResult = result.getTestResults();
}
if (result.getException() != null) {
errorResult = result;
break;
}
}
if (errorResult != null) {
if (throwException) {
throw new Error(errorResult.getException());
}
return errorResult.getTestResults();
}
return firstResult;
}
public boolean getIsOpen() {
return !isEyesClosed();
}
public String getApiKey() {
return getConfiguration().getApiKey() == null ? runner.getApiKey() : getConfiguration().getApiKey();
}
public void setApiKey(String apiKey) {
getConfiguration().setApiKey(apiKey);
}
public void setIsDisabled(Boolean disabled) {
this.isDisabled = disabled;
}
public boolean getIsDisabled() {
return this.isDisabled == null ? this.runner.getIsDisabled() : this.isDisabled;
}
public URI getServerUrl() {
String serverUrl = getConfiguration().getServerUrl() == null ? runner.getServerUrl() : getConfiguration().getServerUrl().toString();
try {
return new URI(serverUrl);
} catch (URISyntaxException e) {
GeneralUtils.logExceptionStackTrace(logger, Stage.GENERAL, e);
return null;
}
}
public void setServerUrl(String serverUrl) {
getConfiguration().setServerUrl(serverUrl);
}
@Override
public void proxy(AbstractProxySettings abstractProxySettings) {
getConfiguration().setProxy(abstractProxySettings);
}
public AbstractProxySettings getProxy() {
return getConfiguration().getProxy() == null ? runner.getProxy() : getConfiguration().getProxy();
}
@Override
public boolean isEyesClosed() {
boolean isVGEyesClosed = true;
for (RunningTest runningTest : testList.values()) {
isVGEyesClosed = isVGEyesClosed && runningTest.isCompleted();
}
return isVGEyesClosed;
}
public void check(ICheckSettings... checkSettings) {
if (getIsDisabled()) {
return;
}
for (ICheckSettings checkSetting : checkSettings) {
this.check(checkSetting);
}
}
public void check(String name, ICheckSettings checkSettings) {
if (getIsDisabled()) {
return;
}
ArgumentGuard.notNull(checkSettings, "checkSettings");
if (name != null) {
checkSettings = checkSettings.withName(name);
}
this.check(checkSettings);
}
public void check(ICheckSettings checkSettings) {
if (getIsDisabled()) {
return;
}
String source = webDriver.getCurrentUrl();
logger.log(TraceLevel.Info, Collections.singleton(eyesId), Stage.CHECK, Type.CALLED,
Pair.of("configuration", getConfiguration()),
Pair.of("checkSettings", checkSettings),
Pair.of("source", source));
FrameChain originalFC = webDriver.getFrameChain().clone();
EyesTargetLocator switchTo = ((EyesTargetLocator) webDriver.switchTo());
try {
ArgumentGuard.notOfType(checkSettings, ICheckSettings.class, "checkSettings");
if (checkSettings instanceof ISeleniumCheckTarget) {
((ISeleniumCheckTarget) checkSettings).init(logger, webDriver);
}
waitBeforeDomSnapshot();
checkSettings = switchFramesAsNeeded(checkSettings, switchTo);
ICheckSettingsInternal checkSettingsInternal = (ICheckSettingsInternal) checkSettings;
SeleniumCheckSettings seleniumCheckSettings = (SeleniumCheckSettings) checkSettings;
List regionsXPaths = getRegionsXPaths(checkSettingsInternal);
trySetTargetSelector(seleniumCheckSettings);
checkSettingsInternal = updateCheckSettings(checkSettings);
Map> requiredWidths = mapRunningTestsToRequiredBrowserWidth(seleniumCheckSettings);
if (requiredWidths.isEmpty()) {
captureDomForResourceCollection(0, testList.values(), switchTo, checkSettingsInternal, regionsXPaths, source);
return;
}
for (Map.Entry> entry : requiredWidths.entrySet()) {
captureDomForResourceCollection(entry.getKey(), entry.getValue(), switchTo, checkSettingsInternal, regionsXPaths, source);
}
} catch (Throwable e) {
Error error = new Error(e);
for (RunningTest runningTest : testList.values()) {
runningTest.setTestInExceptionMode(error);
}
} finally {
switchTo.frames(originalFC);
}
}
private ICheckSettings switchFramesAsNeeded(ICheckSettings checkSettings, EyesTargetLocator switchTo) {
int switchedToCount = switchToFrame((ISeleniumCheckTarget) checkSettings);
boolean isFullPage = isFullPage((ICheckSettingsInternal) checkSettings);
if (switchedToCount > 0 && isFullPage) {
FrameChain frameChain = webDriver.getFrameChain().clone();
Frame frame = frameChain.pop();
checkSettings = ((SeleniumCheckSettings) checkSettings).region(frame.getReference());
switchTo.parentFrame();
}
return checkSettings;
}
private boolean isFullPage(ICheckSettingsInternal checkSettingsInternal) {
boolean isFullPage = true;
Boolean b;
if ((b = checkSettingsInternal.isStitchContent()) != null) {
isFullPage = b;
} else if ((b = getConfiguration().isForceFullPageScreenshot()) != null) {
isFullPage = b;
}
return isFullPage;
}
Map> mapRunningTestsToRequiredBrowserWidth(SeleniumCheckSettings seleniumCheckSettings) {
List layoutBreakpoint;
boolean isDefaultLayoutBreakpointsSet;
if (!seleniumCheckSettings.getLayoutBreakpoints().isEmpty() || seleniumCheckSettings.isDefaultLayoutBreakpointsSet()) {
layoutBreakpoint = seleniumCheckSettings.getLayoutBreakpoints();
isDefaultLayoutBreakpointsSet = seleniumCheckSettings.isDefaultLayoutBreakpointsSet();
} else {
layoutBreakpoint = getConfiguration().getLayoutBreakpoints();
isDefaultLayoutBreakpointsSet = getConfiguration().isDefaultLayoutBreakpointsSet();
}
Set testIds = new HashSet<>();
for (RunningTest runningTest : testList.values()) {
testIds.add(runningTest.getTestId());
}
Map> requiredWidths = new HashMap<>();
if (isDefaultLayoutBreakpointsSet || !layoutBreakpoint.isEmpty()) {
for (RunningTest runningTest : testList.values()) {
int width = runningTest.getBrowserInfo().getDeviceSize().getWidth();
if (width <= 0) {
width = viewportSize.getWidth();
}
if (!layoutBreakpoint.isEmpty()) {
for (int i = layoutBreakpoint.size() - 1; i >= 0; i--) {
if (width >= layoutBreakpoint.get(i)) {
width = layoutBreakpoint.get(i);
break;
}
}
if (width < layoutBreakpoint.get(0)) {
width = layoutBreakpoint.get(0) - 1;
logger.log(TraceLevel.Warn, testIds, Stage.CHECK, Type.DOM_SCRIPT, Pair.of("message",String.format("Device width is smaller than the smallest breakpoint %d", layoutBreakpoint.get(0))));
}
}
if (requiredWidths.containsKey(width)) {
requiredWidths.get(width).add(runningTest);
} else {
List list = new ArrayList<>();
list.add(runningTest);
requiredWidths.put(width, list);
}
}
}
return requiredWidths;
}
private void captureDomForResourceCollection(int width, Collection tests, EyesTargetLocator switchTo,
ICheckSettingsInternal checkSettingsInternal,
List regionsXPaths,String source) throws Exception {
Set testIds = new HashSet<>();
for (RunningTest runningTest : tests) {
testIds.add(runningTest.getTestId());
}
if (width != 0) {
try {
EyesDriverUtils.setViewportSize(logger, webDriver, new RectangleSize(width, viewportSize.getHeight()));
Thread.sleep(300);
} catch (Throwable t) {
GeneralUtils.logExceptionStackTrace(logger, Stage.CHECK, Type.DOM_SCRIPT, t, testIds.toArray(new String[0]));
}
}
if (width != 0) {
RectangleSize viewportSize = EyesDriverUtils.getViewportSize(webDriver);
logger.log(TraceLevel.Info, testIds, Stage.CHECK, Type.DOM_SCRIPT,
Pair.of("requiredWidth", width),
Pair.of("viewportSize", viewportSize));
BufferedImage bufferedImage = imageProvider.getImage();
debugScreenshotsProvider.save(bufferedImage, String.format("snapshot_%s", viewportSize.toString()));
}
FrameData scriptResult = captureDomSnapshot(testIds, switchTo);
String[] blobsUrls = new String[scriptResult.getBlobs().size()];
for (int i = 0; i< scriptResult.getBlobs().size(); i++) {
blobsUrls[i] = scriptResult.getBlobs().get(i).getUrl();
}
logger.log(TraceLevel.Info, testIds, Stage.CHECK, Type.DOM_SCRIPT,
Pair.of("cdtSize", scriptResult.getCdt().size()),
Pair.of("blobs", blobsUrls),
Pair.of("resourceUrls", scriptResult.getResourceUrls()));
List checkTasks = new ArrayList<>();
for (RunningTest runningTest : tests) {
if (runningTest.isCloseTaskIssued()) {
continue;
}
checkTasks.add(runningTest.issueCheck((ICheckSettings) checkSettingsInternal, regionsXPaths, source));
}
if (checkTasks.isEmpty()) {
logger.log(TraceLevel.Warn, testIds, Stage.CHECK, null, Pair.of("message", "No check tasks created. Tests were probably aborted"));
return;
}
scriptResult.setUserAgent(userAgent);
this.runner.setDebugResourceWriter(getConfiguration().getDebugResourceWriter());
this.runner.check(scriptResult, checkTasks);
}
FrameData captureDomSnapshot(Set testIds, EyesTargetLocator switchTo) throws Exception {
String domScript = userAgent.isInternetExplorer() ? PROCESS_PAGE_FOR_IE : PROCESS_PAGE;
String pollingScript = userAgent.isInternetExplorer() ? POLL_RESULT_FOR_IE : POLL_RESULT;
final String skipList;
synchronized (runner.getResourcesCacheMap()) {
skipList = new ObjectMapper().writeValueAsString(new HashSet<>(runner.getResourcesCacheMap().keySet()));
}
Map arguments = new HashMap() {{
put("serializeResources", true);
put("dontFetchResources", getConfiguration().isDisableBrowserFetching());
//put("skipResources", skipList);
}};
String result = EyesSeleniumUtils.runDomScript(logger, webDriver, userAgent, testIds, domScript, arguments, pollingScript);
FrameData frameData = GeneralUtils.parseJsonToObject(result, FrameData.class);
analyzeFrameData(testIds, frameData, switchTo);
return frameData;
}
private void analyzeFrameData(Set testIds, FrameData frameData, EyesTargetLocator switchTo) {
FrameChain frameChain = webDriver.getFrameChain().clone();
for (FrameData.CrossFrame crossFrame : frameData.getCrossFrames()) {
if (crossFrame.getSelector() == null) {
continue;
}
try {
WebElement frame = webDriver.findElement(By.cssSelector(crossFrame.getSelector()));
switchTo.frame(frame);
FrameData result = captureDomSnapshot(testIds, switchTo);
try {
String url = GeneralUtils.sanitizeURL(result.getUrl());
URIBuilder builder = new URIBuilder(url);
builder.addParameter("applitools-iframe", UUID.randomUUID().toString());
result.setUrl(builder.toString());
} catch (Throwable t) {
GeneralUtils.logExceptionStackTrace(logger, Stage.CHECK, Type.DOM_SCRIPT, t, testIds.toArray(new String[0]));
}
frameData.addFrame(result);
List attributeData = (List) frameData.getCdt().get(crossFrame.getIndex()).get("attributes");
attributeData.add(new AttributeData("data-applitools-src", result.getUrl()));
} catch (Throwable t) {
GeneralUtils.logExceptionStackTrace(logger, Stage.CHECK, Type.DOM_SCRIPT, t, testIds.toArray(new String[0]));
} finally {
switchTo.frames(frameChain);
}
}
for (FrameData frame : frameData.getFrames()) {
if (frame.getSelector() == null) {
continue;
}
try {
WebElement frameElement = webDriver.findElement(By.cssSelector(frame.getSelector()));
switchTo.frame(frameElement);
analyzeFrameData(testIds, frame, switchTo);
} catch (Throwable t) {
GeneralUtils.logExceptionStackTrace(logger, Stage.CHECK, Type.DOM_SCRIPT, t, testIds.toArray(new String[0]));
} finally {
switchTo.frames(frameChain);
}
}
}
private void waitBeforeDomSnapshot() {
int waitBeforeScreenshots = this.getConfiguration().getWaitBeforeScreenshots();
try {
Thread.sleep(waitBeforeScreenshots);
} catch (InterruptedException ignored) {}
}
ICheckSettingsInternal updateCheckSettings(ICheckSettings checkSettings) {
ICheckSettingsInternal checkSettingsInternal = (ICheckSettingsInternal) checkSettings;
MatchLevel matchLevel = checkSettingsInternal.getMatchLevel();
Boolean fully = checkSettingsInternal.isStitchContent();
Boolean sendDom = checkSettingsInternal.isSendDom();
Boolean ignoreDisplacements = checkSettingsInternal.isIgnoreDisplacements();
if (matchLevel == null) {
checkSettings = checkSettings.matchLevel(getConfiguration().getMatchLevel());
}
if (fully == null) {
Boolean isForceFullPageScreenshot = getConfiguration().isForceFullPageScreenshot();
boolean stitchContent = isForceFullPageScreenshot == null ? checkSettings.isCheckWindow() : isForceFullPageScreenshot;
checkSettings = checkSettings.fully(stitchContent);
}
if (sendDom == null) {
Boolean isSendDom = getConfiguration().isSendDom();
checkSettings = checkSettings.sendDom(isSendDom == null || isSendDom);
}
if (ignoreDisplacements == null) {
checkSettings = checkSettings.ignoreDisplacements(getConfiguration().getIgnoreDisplacements());
}
List options = new ArrayList<>();
options.addAll(getConfiguration().getVisualGridOptions());
options.addAll(checkSettingsInternal.getVisualGridOptions());
checkSettings = checkSettings.visualGridOptions(options.size() > 0 ? options.toArray(new VisualGridOption[]{}) : null);
return (ICheckSettingsInternal) checkSettings;
}
private void trySetTargetSelector(SeleniumCheckSettings checkSettings) {
WebElement element = checkSettings.getTargetElement();
FrameChain frameChain = webDriver.getFrameChain().clone();
EyesTargetLocator switchTo = (EyesTargetLocator) webDriver.switchTo();
switchToFrame(checkSettings);
if (element == null) {
By targetSelector = checkSettings.getTargetSelector();
if (targetSelector != null) {
element = webDriver.findElement(targetSelector);
}
}
if (element != null) {
String xpath = (String) webDriver.executeScript(GET_ELEMENT_XPATH_JS, element);
VisualGridSelector vgs = new VisualGridSelector(xpath, "target");
checkSettings.setTargetSelector(vgs);
}
switchTo.frames(frameChain);
}
@SuppressWarnings("UnusedReturnValue")
private int switchToFrame(ISeleniumCheckTarget checkTarget) {
if (checkTarget == null) {
return 0;
}
List frameChain = checkTarget.getFrameChain();
int switchedToFrameCount = 0;
for (FrameLocator frameLocator : frameChain) {
if (switchToFrame(frameLocator)) {
switchedToFrameCount++;
}
}
return switchedToFrameCount;
}
private boolean switchToFrame(ISeleniumFrameCheckTarget frameTarget) {
WebDriver.TargetLocator switchTo = this.webDriver.switchTo();
if (frameTarget.getFrameIndex() != null) {
switchTo.frame(frameTarget.getFrameIndex());
updateFrameScrollRoot(frameTarget);
return true;
}
if (frameTarget.getFrameNameOrId() != null) {
switchTo.frame(frameTarget.getFrameNameOrId());
updateFrameScrollRoot(frameTarget);
return true;
}
if (frameTarget.getFrameReference() != null) {
switchTo.frame(frameTarget.getFrameReference());
updateFrameScrollRoot(frameTarget);
return true;
}
if (frameTarget.getFrameSelector() != null) {
WebElement frameElement = this.webDriver.findElement(frameTarget.getFrameSelector());
if (frameElement != null) {
switchTo.frame(frameElement);
updateFrameScrollRoot(frameTarget);
return true;
}
}
return false;
}
private void updateFrameScrollRoot(IScrollRootElementContainer frameTarget) {
WebElement rootElement = EyesSeleniumUtils.getScrollRootElement(logger, webDriver, frameTarget);
Frame frame = webDriver.getFrameChain().peek();
frame.setScrollRootElement(rootElement);
}
public Logger getLogger() {
return logger;
}
public Map getAllRunningTests() {
return testList;
}
@Override
public String toString() {
return "SeleniumVGEyes - url: " + url;
}
public void setServerConnector(ServerConnector serverConnector) {
if (serverConnector != null && serverConnector.getAgentId() == null) {
serverConnector.setAgentId(getFullAgentId());
}
runner.setServerConnector(serverConnector);
}
/**
* @return The full agent id composed of both the base agent id and the
* user given agent id.
*/
public String getFullAgentId() {
String agentId = getConfiguration().getAgentId();
if (agentId == null) {
return getBaseAgentId();
}
return String.format("%s [%s]", agentId, getBaseAgentId());
}
private Configuration getConfiguration() {
return configurationProvider.get();
}
private String getBaseAgentId() {
return "eyes.selenium.visualgrid.java/" + ClassVersionGetter.CURRENT_VERSION;
}
/**
* Sets the batch in which context future tests will run or {@code null}
* if tests are to run standalone.
* @param batch The batch info to set.
*/
public void setBatch(BatchInfo batch) {
if (getIsDisabled()) {
return;
}
this.getConfiguration().setBatch(batch);
}
private List getRegionsXPaths(ICheckSettingsInternal csInternal) {
List result = new ArrayList<>();
List[] elementLists = collectSeleniumRegions(csInternal);
for (List elementList : elementLists) {
List xPaths = new ArrayList<>();
for (WebElementRegion webElementRegion : elementList) {
if (webElementRegion.getElement() == null) continue;
String xpath = (String) webDriver.executeScript(GET_ELEMENT_XPATH_JS, webElementRegion.getElement());
xPaths.add(new VisualGridSelector(xpath, webElementRegion.getRegion()));
}
result.add(xPaths.toArray(new VisualGridSelector[0]));
}
return result;
}
private List[] collectSeleniumRegions(ICheckSettingsInternal csInternal) {
CheckSettings settings = (CheckSettings) csInternal;
GetSimpleRegion[] ignoreRegions = settings.getIgnoreRegions();
GetSimpleRegion[] layoutRegions = settings.getLayoutRegions();
GetSimpleRegion[] strictRegions = settings.getStrictRegions();
GetSimpleRegion[] contentRegions = settings.getContentRegions();
GetFloatingRegion[] floatingRegions = settings.getFloatingRegions();
GetAccessibilityRegion[] accessibilityRegions = settings.getAccessibilityRegions();
List ignoreElements = getElementsFromRegions(Arrays.asList(ignoreRegions));
List layoutElements = getElementsFromRegions(Arrays.asList(layoutRegions));
List strictElements = getElementsFromRegions(Arrays.asList(strictRegions));
List contentElements = getElementsFromRegions(Arrays.asList(contentRegions));
List floatingElements = getElementsFromRegions(Arrays.asList(floatingRegions));
List accessibilityElements = getElementsFromRegions(Arrays.asList(accessibilityRegions));
return (List[]) new List[]{ignoreElements, layoutElements, strictElements, contentElements, floatingElements, accessibilityElements};
}
private List getElementsFromRegions(List regionsProvider) {
List elements = new ArrayList<>();
for (Object getRegion : regionsProvider) {
if (getRegion instanceof IGetSeleniumRegion) {
IGetSeleniumRegion getSeleniumRegion = (IGetSeleniumRegion) getRegion;
List webElements = getSeleniumRegion.getElements();
for (WebElement webElement : webElements) {
elements.add(new WebElementRegion(webElement, getRegion));
}
}
}
return elements;
}
/**
* Adds a property to be sent to the server.
* @param name The property name.
* @param value The property value.
*/
public void addProperty(String name, String value) {
PropertyData pd = new PropertyData(name, value);
properties.add(pd);
}
/**
* Clears the list of custom properties.
*/
public void clearProperties() {
properties.clear();
}
public EyesSeleniumDriver getDriver() {
return webDriver;
}
@Override
public IBatchCloser getBatchCloser() {
return this.testList.values().iterator().next();
}
@Override
public String getBatchId() {
return this.getConfiguration().getBatch().getId();
}
/**
*
* @return If all tests completed, returns their results. Otherwise, returns null
*/
public List getAllTestResults() {
List allResults = new ArrayList<>();
for (RunningTest runningTest : testList.values()) {
if (!runningTest.isCompleted()) {
if (runner.getError() != null) {
throw new EyesException("Execution crashed", runner.getError());
}
return null;
}
allResults.add(runningTest.getTestResultContainer());
}
return allResults;
}
@Override
public boolean isCompleted() {
return getAllTestResults() != null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy