
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.config.Configuration;
import com.applitools.eyes.fluent.CheckSettings;
import com.applitools.eyes.fluent.GetFloatingRegion;
import com.applitools.eyes.fluent.GetSimpleRegion;
import com.applitools.eyes.selenium.*;
import com.applitools.eyes.config.ConfigurationProvider;
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.EyesTargetLocator;
import com.applitools.eyes.selenium.wrappers.EyesSeleniumDriver;
import com.applitools.eyes.visualgrid.model.*;
import com.applitools.eyes.visualgrid.services.*;
import com.applitools.utils.ArgumentGuard;
import com.applitools.utils.ClassVersionGetter;
import com.applitools.utils.GeneralUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.io.IOException;
import java.net.URI;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.atomic.AtomicBoolean;
public class VisualGridEyes implements ISeleniumEyes, IRenderingEyes {
private static final long DOM_EXTRACTION_TIMEOUT = 5 * 60 * 1000;
private final Logger logger;
private String apiKey;
private String serverUrl;
private final VisualGridRunner renderingGridRunner;
private final List testList = Collections.synchronizedList(new ArrayList());
private final List testsInCloseProcess = Collections.synchronizedList(new ArrayList());
List allTestResults = new ArrayList<>();
private String PROCESS_PAGE;
private String PROCESS_PAGE_FOR_IE;
private EyesSeleniumDriver webDriver;
private RenderingInfo renderingInfo;
private IEyesConnector VGEyesConnector;
private IDebugResourceWriter debugResourceWriter;
private String url;
private Set> closeFuturesSet = new HashSet<>();
private Boolean isDisabled = Boolean.FALSE;
private ServerConnector serverConnector = null;
private final ConfigurationProvider configurationProvider;
private UserAgent userAgent = null;
private RectangleSize viewportSize;
private final AtomicBoolean isCheckTimerTimedOut = new AtomicBoolean(false);
private Timer timer = null;
private final List properties = new ArrayList<>();
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;";
{
try {
PROCESS_PAGE = GeneralUtils.readToEnd(VisualGridEyes.class.getResourceAsStream("/processPageAndSerializePoll.js"));
PROCESS_PAGE += "return __processPageAndSerializePoll();";
PROCESS_PAGE_FOR_IE = GeneralUtils.readToEnd(VisualGridEyes.class.getResourceAsStream("/processPageAndSerializePollForIE.js"));
PROCESS_PAGE_FOR_IE += "return __processPageAndSerializePollForIE();";
} catch (IOException e) {
e.printStackTrace();
}
}
public VisualGridEyes(VisualGridRunner renderingGridManager, ConfigurationProvider configurationProvider) {
this.configurationProvider = configurationProvider;
ArgumentGuard.notNull(renderingGridManager, "renderingGridRunner");
this.renderingGridRunner = renderingGridManager;
this.logger = renderingGridManager.getLogger();
}
/**
* 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;
LogHandler currentLogHandler = logger.getLogHandler();
this.logger.setLogHandler(new MultiLogHandler(currentLogHandler, logHandler));
if (currentLogHandler.isOpen() && !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 serverUrl(URI serverUrl) {
setServerUrl(serverUrl.toString());
}
@Override
public WebDriver open(WebDriver driver, String appName, String testName, RectangleSize viewportSize) throws EyesException {
getConfiguration().setAppName(appName).setTestName(testName);
if (viewportSize != null && !viewportSize.isEmpty()) {
getConfiguration().setViewportSize(new RectangleSize(viewportSize));
}
return open(driver);
}
public WebDriver open(WebDriver webDriver) {
logger.verbose("enter");
if (!validateEyes()) return webDriver;
ArgumentGuard.notNull(webDriver, "webDriver");
ArgumentGuard.notNullOrEmpty(getConfiguration().getAppName(), "appIdOrName");
ArgumentGuard.notNullOrEmpty(getConfiguration().getTestName(), "scenarioIdOrName");
initDriver(webDriver);
String uaString = this.webDriver.getUserAgent();
if (uaString != null) {
logger.verbose(String.format("User-Agent: %s", uaString));
userAgent = UserAgent.parseUserAgentString(uaString, true);
}
setViewportSize(this.webDriver);
ensureBrowsers();
if (getConfiguration().getBatch() == null) {
getConfiguration().setBatch(new BatchInfo(null));
}
logger.verbose("getting all browsers info...");
List browserInfoList = getConfiguration().getBrowsersInfo();
logger.verbose("creating test descriptors for each browser info...");
getConfiguration().setViewportSize(viewportSize);
if (getConfiguration().getBrowsersInfo() == null) {
RectangleSize viewportSize = getConfiguration().getViewportSize();
getConfiguration().addBrowser(new RenderBrowserInfo(viewportSize.getWidth(), viewportSize.getHeight(), BrowserType.CHROME, getConfiguration().getBaselineEnvName()));
}
for (RenderBrowserInfo browserInfo : browserInfoList) {
logger.verbose("creating test descriptor");
RunningTest test = new RunningTest(this, createVGEyesConnector(browserInfo), configurationProvider, browserInfo, logger);
this.testList.add(test);
}
logger.verbose(String.format("opening %d tests...", testList.size()));
this.renderingGridRunner.open(this, renderingInfo);
logger.verbose("done");
return this.webDriver != null ? this.webDriver : webDriver;
}
private void ensureBrowsers() {
if (this.getConfiguration().getBrowsersInfo().isEmpty()) {
getConfiguration().getBrowsersInfo().add(new RenderBrowserInfo(viewportSize, BrowserType.CHROME));
}
}
private 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) {
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, e);
}
}
private IEyesConnector createVGEyesConnector(RenderBrowserInfo browserInfo) {
logger.verbose("creating VisualGridEyes server connector");
EyesConnector VGEyesConnector = new EyesConnector(getConfiguration(), this.properties, browserInfo);
if (browserInfo.getEmulationInfo() != null) {
VGEyesConnector.setDevice(browserInfo.getEmulationInfo().getDeviceName() + " (Chrome emulation)");
} else if (browserInfo.getIosDeviceInfo() != null) {
VGEyesConnector.setDevice(browserInfo.getIosDeviceInfo().getDeviceName());
}
VGEyesConnector.setLogHandler(this.logger.getLogHandler());
VGEyesConnector.setProxy(this.getConfiguration().getProxy());
if (serverConnector != null) {
VGEyesConnector.setServerConnector(serverConnector);
}
URI serverUri = this.getServerUrl();
if (serverUri != null) {
VGEyesConnector.setServerUrl(serverUri.toString());
}
String apiKey = this.getApiKey();
if (apiKey != null) {
VGEyesConnector.setApiKey(apiKey);
} else {
throw new EyesException("Missing API key");
}
if (this.renderingInfo == null) {
logger.verbose("initializing rendering info...");
this.renderingInfo = VGEyesConnector.getRenderingInfo();
}
VGEyesConnector.setRenderInfo(this.renderingInfo);
this.VGEyesConnector = VGEyesConnector;
return VGEyesConnector;
}
private void initDriver(WebDriver webDriver) {
if (webDriver instanceof RemoteWebDriver) {
SeleniumEyes seleniumEyes = new SeleniumEyes(configurationProvider, new ClassicRunner());
this.webDriver = new EyesSeleniumDriver(logger, seleniumEyes, (RemoteWebDriver) webDriver);
}
@SuppressWarnings("UnnecessaryLocalVariable") String currentUrl = webDriver.getCurrentUrl();
this.url = currentUrl;
}
public RunningTest getNextTestToClose() {
synchronized (testsInCloseProcess) {
synchronized (testList) {
for (RunningTest runningTest : testList) {
if (!runningTest.isTestClose() && runningTest.isTestReadyToClose() &&
!this.testsInCloseProcess.contains(runningTest)) {
return runningTest;
}
}
}
}
return null;
}
public Collection> close() {
logger.verbose("enter");
if (!validateEyes()) {
return new ArrayList<>();
}
return closeAndReturnResults(false);
}
public TestResults close(boolean throwException) {
Collection> close = close();
return parseCloseFutures(close, throwException);
}
private TestResults parseCloseFutures(Collection> close, boolean shouldThrowException) {
if (close != null && !close.isEmpty()) {
TestResultContainer errorResult = null;
TestResultContainer firstResult = null;
try {
for (Future closeFuture : close) {
TestResultContainer testResultContainer = closeFuture.get();
if (firstResult == null) {
firstResult = testResultContainer;
}
Throwable error = testResultContainer.getException();
if (error != null && errorResult == null) {
errorResult = testResultContainer;
}
}
// return firstCloseFuture.get().getTestResults();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
if (errorResult != null) {
if (shouldThrowException) {
throw new Error(errorResult.getException());
} else {
return errorResult.getTestResults();
}
} else { // returning the first result
if (firstResult != null) {
return firstResult.getTestResults();
}
}
}
return null;
}
public TestResults abortIfNotClosed() {
List> futures = abortAndCollectTasks();
return parseCloseFutures(futures, false);
}
public boolean getIsOpen() {
return !isEyesClosed();
}
public String getApiKey() {
return this.apiKey == null ? this.renderingGridRunner.getApiKey() : this.apiKey;
}
public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}
public void setIsDisabled(Boolean disabled) {
this.isDisabled = disabled;
}
public boolean getIsDisabled() {
return this.isDisabled == null ? this.renderingGridRunner.getIsDisabled() : this.isDisabled;
}
public URI getServerUrl() {
if (this.VGEyesConnector != null) {
URI uri = this.VGEyesConnector.getServerUrl();
if (uri != null) return uri;
}
String str = this.serverUrl == null ? this.renderingGridRunner.getServerUrl() : this.serverUrl;
return str == null ? null : URI.create(str);
}
private Collection> closeAndReturnResults(boolean throwException) {
logger.verbose("enter " + getConfiguration().getBatch());
if (!validateEyes()) {
return new ArrayList<>();
}
if (this.closeFuturesSet == null) {
closeFuturesSet = new HashSet<>();
}
Throwable exception = null;
try {
Collection> futureList = closeAsync();
this.renderingGridRunner.close(this);
for (Future future : futureList) {
try {
TestResultContainer testResultContainer = future.get();
if (exception == null && testResultContainer.getException() != null) {
exception = testResultContainer.getException();
}
} catch (Throwable e) {
GeneralUtils.logExceptionStackTrace(logger, e);
if (exception == null) {
exception = e;
}
}
}
} catch (Throwable e) {
GeneralUtils.logExceptionStackTrace(logger, e);
}
if (throwException && exception != null) {
throw new Error(exception);
}
return closeFuturesSet;
}
public Collection> closeAsync() {
logger.verbose("enter");
if (!validateEyes()) {
return new ArrayList<>();
}
List> futureList = null;
try {
futureList = new ArrayList<>();
logger.verbose(String.format("closing %d running tests", testList.size()));
for (RunningTest runningTest : testList) {
logger.verbose("running test name: " + getConfiguration().getTestName());
logger.verbose("running test device info: " + runningTest.getBrowserInfo());
logger.verbose("is current running test open: " + runningTest.isTestOpen());
logger.verbose("is current running test ready to close: " + runningTest.isTestReadyToClose());
logger.verbose("is current running test closed: " + runningTest.isTestClose());
logger.verbose("closing current running test");
FutureTask closeFuture = runningTest.close();
if (closeFuture == null) {
continue;
}
futureList.addAll(Collections.singleton(closeFuture));
logger.verbose("adding closeFuture to futureList");
}
closeFuturesSet.addAll(futureList);
} catch (Throwable e) {
GeneralUtils.logExceptionStackTrace(logger, e);
}
logger.verbose("exit");
return futureList;
}
@Override
public synchronized ScoreTask getBestScoreTaskForCheck() {
int bestScore = -1;
ScoreTask currentBest = null;
for (RunningTest runningTest : testList) {
List visualGridTaskList = runningTest.getVisualGridTaskList();
VisualGridTask visualGridTask;
//noinspection SynchronizationOnLocalVariableOrMethodParameter
synchronized (visualGridTaskList) {
if (visualGridTaskList.isEmpty()) continue;
visualGridTask = visualGridTaskList.get(0);
if (!runningTest.isTestOpen() || visualGridTask.getType() != VisualGridTask.TaskType.CHECK || !visualGridTask.isTaskReadyToCheck())
continue;
}
ScoreTask scoreTask = runningTest.getScoreTaskObjectByType(VisualGridTask.TaskType.CHECK);
if (scoreTask == null) continue;
if (bestScore < scoreTask.getScore()) {
currentBest = scoreTask;
bestScore = scoreTask.getScore();
}
}
return currentBest;
}
@Override
public ScoreTask getBestScoreTaskForOpen() {
int bestMark = -1;
ScoreTask currentBest = null;
synchronized (testList) {
for (RunningTest runningTest : testList) {
ScoreTask currentScoreTask = runningTest.getScoreTaskObjectByType(VisualGridTask.TaskType.OPEN);
if (currentScoreTask == null) continue;
if (bestMark < currentScoreTask.getScore()) {
bestMark = currentScoreTask.getScore();
currentBest = currentScoreTask;
}
}
}
return currentBest;
}
public void setServerUrl(String serverUrl) {
this.serverUrl = serverUrl;
}
@Override
public boolean isEyesClosed() {
boolean isVGEyesClosed = true;
for (RunningTest runningTest : testList) {
isVGEyesClosed = isVGEyesClosed && runningTest.isTestClose();
}
return isVGEyesClosed;
}
public void setListener(EyesListener listener) {
for (RunningTest test : testList) {
test.setListener(listener);
}
}
public void check(ICheckSettings... checkSettings) {
if (!validateEyes()) return;
for (ICheckSettings checkSetting : checkSettings) {
this.check(checkSetting);
}
}
public void check(String name, ICheckSettings checkSettings) {
if (!validateEyes()) return;
ArgumentGuard.notNull(checkSettings, "checkSettings");
if (name != null) {
checkSettings = checkSettings.withName(name);
}
this.check(checkSettings);
}
public void check(ICheckSettings checkSettings) {
logger.verbose("enter");
if (!validateEyes()) {
return;
}
ArgumentGuard.notOfType(checkSettings, ICheckSettings.class, "checkSettings");
if (checkSettings instanceof ISeleniumCheckTarget) {
((ISeleniumCheckTarget) checkSettings).init(logger, webDriver);
}
waitBeforeDomSnapshot();
try {
FrameChain originalFC = webDriver.getFrameChain().clone();
EyesTargetLocator switchTo = ((EyesTargetLocator) webDriver.switchTo());
checkSettings = switchFramesAsNeeded(checkSettings, switchTo);
ICheckSettingsInternal checkSettingsInternal = (ICheckSettingsInternal) checkSettings;
isCheckTimerTimedOut.set(false);
List openVisualGridTasks = addOpenTaskToAllRunningTest();
List visualGridTaskList = new ArrayList<>();
FrameData scriptResult = captureDomSnapshot(originalFC, switchTo, checkSettingsInternal);
List regionsXPaths = getRegionsXPaths(checkSettingsInternal);
logger.verbose("regionXPaths : " + regionsXPaths);
trySetTargetSelector((SeleniumCheckSettings) checkSettings);
checkSettingsInternal = updateCheckSettings(checkSettings);
List filteredTests = collectTestsForCheck(testList);
String source = webDriver.getCurrentUrl();
for (RunningTest runningTest : filteredTests) {
VisualGridTask checkVisualGridTask = runningTest.check((ICheckSettings) checkSettingsInternal, regionsXPaths, source);
visualGridTaskList.add(checkVisualGridTask);
}
logger.verbose("added check tasks (" + checkSettingsInternal.toString() + ")");
this.renderingGridRunner.check((ICheckSettings) checkSettingsInternal, debugResourceWriter, scriptResult,
this.VGEyesConnector, visualGridTaskList, openVisualGridTasks,
new VisualGridRunner.RenderListener() {
@Override
public void onRenderSuccess() {
}
@Override
public void onRenderFailed(Exception e) {
GeneralUtils.logExceptionStackTrace(logger, e);
}
}, regionsXPaths, userAgent);
logger.verbose("created renderTask (" + checkSettings.toString() + ")");
switchTo.frames(originalFC);
} catch (Throwable e) {
Error error = new Error(e);
abort(e);
for (RunningTest runningTest : testList) {
runningTest.setTestInExceptionMode(error);
}
GeneralUtils.logExceptionStackTrace(logger, e);
} finally {
if (timer != null) {
timer.cancel();
}
}
}
/******** BEGIN - PUBLIC FOR TESTING PURPOSES ONLY ********/
public static List collectTestsForCheck(List tests) {
List filteredTests = new ArrayList<>();
for (final RunningTest test : tests) {
List taskList = test.getVisualGridTaskList();
VisualGridTask visualGridTask = null;
if (!taskList.isEmpty()) {
visualGridTask = taskList.get(taskList.size() - 1);
}
VisualGridTask.TaskType lastTaskType = null;
if (visualGridTask != null) {
lastTaskType = visualGridTask.getType();
}
boolean testIsOpenAndNotClosed = lastTaskType == null && test.isOpenTaskIssued() && !test.isCloseTaskIssued();
boolean lastTaskIsNotAClosingTask = lastTaskType != null && lastTaskType != VisualGridTask.TaskType.CLOSE && lastTaskType != VisualGridTask.TaskType.ABORT;
// We are interested in tests which should be opened or are open.
if (testIsOpenAndNotClosed || lastTaskIsNotAClosingTask) {
filteredTests.add(test);
}
}
return filteredTests;
}
/******** END - PUBLIC FOR TESTING PURPOSES ONLY ********/
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;
}
private FrameData captureDomSnapshot(FrameChain originalFC, EyesTargetLocator switchTo, ICheckSettingsInternal checkSettingsInternal) throws InterruptedException {
logger.verbose("Dom extraction starting (" + checkSettingsInternal.toString() + ")");
timer = new Timer("VG_Check_StopWatch", true);
timer.schedule(new TimeoutTask(), DOM_EXTRACTION_TIMEOUT);
String resultAsString;
ScriptResponse.Status status = null;
ScriptResponse scriptResponse = null;
do {
if (userAgent.isInternetExplorer()) {
resultAsString = (String) this.webDriver.executeScript(PROCESS_PAGE_FOR_IE);
} else {
resultAsString = (String) this.webDriver.executeScript(PROCESS_PAGE);
}
try {
scriptResponse = GeneralUtils.parseJsonToObject(resultAsString, ScriptResponse.class);
logger.verbose("Dom extraction polling...");
status = scriptResponse.getStatus();
} catch (IOException e) {
GeneralUtils.logExceptionStackTrace(logger, e);
}
Thread.sleep(200);
} while (status == ScriptResponse.Status.WIP && !isCheckTimerTimedOut.get());
timer.cancel();
if (status == ScriptResponse.Status.ERROR) {
switchTo.frames(originalFC);
throw new EyesException("DomSnapshot Error: " + scriptResponse.getError());
}
if (isCheckTimerTimedOut.get()) {
switchTo.frames(originalFC);
throw new EyesException("Domsnapshot Timed out");
}
FrameData scriptResult = scriptResponse != null ? scriptResponse.getValue() : null;
logger.verbose("Dom extracted (" + checkSettingsInternal.toString() + ")");
return scriptResult;
}
private void waitBeforeDomSnapshot() {
int waitBeforeScreenshots = this.getConfiguration().getWaitBeforeScreenshots();
try {
Thread.sleep(waitBeforeScreenshots);
} catch (InterruptedException e) {
GeneralUtils.logExceptionStackTrace(logger, e);
}
}
private ICheckSettingsInternal updateCheckSettings(ICheckSettings checkSettings) {
ICheckSettingsInternal checkSettingsInternal = (ICheckSettingsInternal) checkSettings;
MatchLevel matchLevel = checkSettingsInternal.getMatchLevel();
Boolean fully = checkSettingsInternal.isStitchContent();
Boolean sendDom = checkSettingsInternal.isSendDom();
Boolean ignoreDisplacements = checkSettingsInternal.isIgnoreDisplacements();
Boolean b;
if (matchLevel == null) {
checkSettings = checkSettings.matchLevel(getConfiguration().getMatchLevel());
}
if (fully == null) {
checkSettings = checkSettings.fully((b = getConfiguration().isForceFullPageScreenshot()) == null || b);
}
if (sendDom == null) {
checkSettings = checkSettings.sendDom((b = getConfiguration().isSendDom()) == null || b);
}
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);
}
private synchronized List addOpenTaskToAllRunningTest() {
logger.verbose("enter");
List visualGridTasks = new ArrayList<>();
for (RunningTest runningTest : testList) {
if (!runningTest.isOpenTaskIssued()) {
VisualGridTask visualGridTask = runningTest.open();
visualGridTasks.add(visualGridTask);
}
}
logger.verbose("calling addOpenTaskToAllRunningTest.open");
logger.verbose("exit");
return visualGridTasks;
}
public Logger getLogger() {
return logger;
}
public List getAllRunningTests() {
return testList;
}
public void setDebugResourceWriter(IDebugResourceWriter debugResourceWriter) {
this.debugResourceWriter = debugResourceWriter;
}
@Override
public String toString() {
return "SeleniumVGEyes - url: " + url;
}
public void setServerConnector(ServerConnector serverConnector) {
this.serverConnector = 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();
}
@SuppressWarnings("WeakerAccess")
public String getBaseAgentId() {
//noinspection SpellCheckingInspection
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 (isDisabled) {
logger.verbose("Ignored");
return;
}
logger.verbose("setBatch(" + batch + ")");
this.getConfiguration().setBatch(batch);
}
private List getRegionsXPaths(ICheckSettingsInternal csInternal) {
List result = new ArrayList<>();
List[] elementLists = collectSeleniumRegions(csInternal);
for (List elementList : elementLists) {
//noinspection SpellCheckingInspection
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));
ISeleniumCheckTarget iSeleniumCheckTarget = (ISeleniumCheckTarget) csInternal;
WebElement targetElement = iSeleniumCheckTarget.getTargetElement();
if (targetElement == null) {
By targetSelector = iSeleniumCheckTarget.getTargetSelector();
if (targetSelector != null) {
targetElement = webDriver.findElement(targetSelector);
}
}
WebElementRegion target = new WebElementRegion(targetElement, "target");
List targetElementList = new ArrayList<>();
targetElementList.add(target);
//noinspection UnnecessaryLocalVariable,unchecked
List[] lists = new List[]{ignoreElements, layoutElements, strictElements, contentElements, floatingElements, accessibilityElements, targetElementList};
return lists;
}
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();
}
private class TimeoutTask extends TimerTask {
@Override
public void run() {
logger.verbose("Check Timer timeout.");
isCheckTimerTimedOut.set(true);
}
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private boolean validateEyes() {
if (isDisabled) {
logger.verbose("WARNING! Invalid Operation - Eyes Disabled!");
return false;
}
if (!renderingGridRunner.isServicesOn()) {
logger.verbose("WARNING! Invalid Operation - visualGridRunner.getAllTestResults already called!");
return false;
}
return true;
}
@Override
public List getAllTestResults() {
return allTestResults;
}
public EyesSeleniumDriver getDriver() {
return webDriver;
}
@Override
public IBatchCloser getBatchCloser() {
return this.testList.get(0).getBatchCloser();
}
@Override
public String getBatchId() {
return this.getConfiguration().getBatch().getId();
}
private void abort(Throwable e) {
for (RunningTest runningTest : testList) {
runningTest.abort(true, e);
}
}
public void abortAsync() {
abortAndCollectTasks();
}
public TestResults abort() {
List> tasks = abortAndCollectTasks();
return parseCloseFutures(tasks, false);
}
private List> abortAndCollectTasks() {
List> tasks = new ArrayList<>();
for (RunningTest runningTest : testList) {
Future task = runningTest.abort(false, null);
tasks.add(task);
}
return tasks;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy