com.shaft.validation.internal.ValidationsHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of SHAFT_ENGINE Show documentation
Show all versions of SHAFT_ENGINE Show documentation
SHAFT is a unified test automation engine. Powered by best-in-class frameworks, SHAFT provides a
wizard-like syntax to drive your automation efficiently, maximize your ROI, and minimize your learning curve.
Stop reinventing the wheel. Upgrade now!
package com.shaft.validation.internal;
import com.shaft.api.RestActions;
import com.shaft.cli.FileActions;
import com.shaft.driver.SHAFT;
import com.shaft.driver.internal.DriverFactoryHelper;
import com.shaft.gui.browser.internal.BrowserActionsHelpers;
import com.shaft.gui.browser.internal.FluentBrowserActions;
import com.shaft.gui.element.ElementActions;
import com.shaft.gui.element.internal.ElementActionsHelper;
import com.shaft.gui.internal.image.ImageProcessingActions;
import com.shaft.gui.internal.image.ScreenshotManager;
import com.shaft.properties.internal.Properties;
import com.shaft.tools.internal.support.JavaHelper;
import com.shaft.tools.io.internal.FailureReporter;
import com.shaft.tools.io.internal.ReportManagerHelper;
import com.shaft.validation.ValidationEnums.*;
import io.restassured.response.Response;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.Browser;
import org.testng.Assert;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.shaft.gui.element.internal.ElementActionsHelper.formatLocatorToString;
import static io.restassured.module.jsv.JsonSchemaValidator.matchesJsonSchema;
public class ValidationsHelper {
//TODO: implement element attribute and element exists validations for sikuli actions
static final ThreadLocal> optionalCustomLogMessage = new ThreadLocal<>();
private static By lastUsedElementLocator = null;
private static final Boolean discreetLoggingState = SHAFT.Properties.reporting.alwaysLogDiscreetly();
private static List verificationFailuresList = new ArrayList<>();
private static AssertionError verificationError = null;
private static final String WHEN_TO_TAKE_PAGE_SOURCE_SNAPSHOT = SHAFT.Properties.visuals.whenToTakePageSourceSnapshot().trim();
private ValidationsHelper() {
throw new IllegalStateException("Utility class");
}
public static AssertionError getVerificationErrorToForceFail() {
return verificationError;
}
public static void resetVerificationStateAfterFailing() {
verificationFailuresList = new ArrayList<>();
verificationError = null;
}
protected static void validateFail(ValidationCategory validationCategory, String... optionalCustomLogMessage) {
processCustomLogMessage(optionalCustomLogMessage);
fail(validationCategory, null, null, null, null, null);
}
protected static void validateEquals(ValidationCategory validationCategory, Object expectedValue, Object actualValue,
ValidationComparisonType validationComparisonType, ValidationType validationType,
String... optionalCustomLogMessage) {
processCustomLogMessage(optionalCustomLogMessage);
if (JavaHelper.compareTwoObjects(expectedValue, actualValue, validationComparisonType.getValue(),
validationType.getValue()) == 1) {
pass(validationCategory, String.valueOf(expectedValue), String.valueOf(actualValue), validationComparisonType, validationType);
} else {
// failed comparison, invalid operator (not reachable) or exception
fail(validationCategory, String.valueOf(expectedValue), String.valueOf(actualValue), validationComparisonType, validationType,
null);
}
}
protected static void validateNull(ValidationCategory validationCategory, Object object, ValidationType validationType, String... optionalCustomLogMessage) {
processCustomLogMessage(optionalCustomLogMessage);
if (validationType.getValue()) {
try {
Assert.assertNull(object);
pass(validationCategory, "NULL", "NULL", ValidationComparisonType.EQUALS, validationType);
} catch (Exception | AssertionError failureReason) {
fail(validationCategory, "NULL", String.valueOf(object), ValidationComparisonType.EQUALS, validationType, failureReason);
}
} else {
try {
Assert.assertNotNull(object);
pass(validationCategory, "NULL", String.valueOf(object), ValidationComparisonType.EQUALS, validationType);
} catch (Exception | AssertionError failureReason) {
fail(validationCategory, "NULL", "NULL", ValidationComparisonType.EQUALS, validationType, failureReason);
}
}
}
protected static void validateElementExists(ValidationCategory validationCategory, WebDriver driver, By elementLocator, ValidationType validationType,
String... optionalCustomLogMessage) {
processCustomLogMessage(optionalCustomLogMessage);
String[] expectedElementStates = {"Element Should Exist", "Element Should not Exist"};
String[] actualElementStates = {"Element Exists", "Element Doesn't Exists",
"Element Exists but is not unique"};
String locatorSeparator = ", locator '";
lastUsedElementLocator = elementLocator;
int elementsCount = ElementActionsHelper.getElementsCount(driver, elementLocator);
if (validationType.getValue()) {
// expecting a unique element to be present
final String expectedValue = expectedElementStates[0] + locatorSeparator + formatLocatorToString(elementLocator) + "'";
switch (elementsCount) {
case 0 -> {
lastUsedElementLocator = null; //reset lastUsedElementLocator to avoid attempting to find the element again
fail(validationCategory, expectedValue,
actualElementStates[1], ValidationComparisonType.EQUALS, validationType, null);
}
case 1 -> pass(validationCategory, expectedValue,
actualElementStates[0], ValidationComparisonType.EQUALS, validationType);
default -> fail(validationCategory, expectedValue,
actualElementStates[2], ValidationComparisonType.EQUALS, validationType, null);
}
} else {
// not expecting the element to be present
final String expectedValue = expectedElementStates[1] + locatorSeparator + formatLocatorToString(elementLocator) + "'";
switch (elementsCount) {
case 0 -> {
lastUsedElementLocator = null; //reset lastUsedElementLocator to avoid attempting to find the element again
pass(validationCategory, expectedValue,
actualElementStates[1], ValidationComparisonType.EQUALS, validationType);
}
case 1 -> fail(validationCategory, expectedValue,
actualElementStates[0], ValidationComparisonType.EQUALS, validationType, null);
default -> fail(validationCategory, expectedValue,
actualElementStates[2], ValidationComparisonType.EQUALS, validationType, null);
}
}
}
@SuppressWarnings("SpellCheckingInspection")
protected static void validateElementAttribute(ValidationCategory validationCategory, WebDriver driver, By elementLocator, String elementAttribute,
String expectedValue, ValidationComparisonType validationComparisonType, ValidationType validationType,
String... optionalCustomLogMessage) {
processCustomLogMessage(optionalCustomLogMessage);
String[] expectedAttributeStates = {"Value Should be", "Value Should not be"};
String attributeSeparator = "' for the '";
String locatorSeparator = "' attribute, element locator '";
var isDiscrete = ReportManagerHelper.getDiscreteLogging();
ReportManagerHelper.setDiscreteLogging(true);
String actualValue;
try {
actualValue = switch (elementAttribute.toLowerCase()) {
case "text" -> ElementActions.getInstance().getText(elementLocator);
case "texttrimmed" -> ElementActions.getInstance().getText(elementLocator).trim();
case "tagname" ->
((WebElement) ElementActionsHelper.identifyUniqueElementIgnoringVisibility(driver, elementLocator).get(1)).getTagName();
case "size" ->
((WebElement) ElementActionsHelper.identifyUniqueElementIgnoringVisibility(driver, elementLocator).get(1)).getSize().toString();
case "selectedtext" -> ElementActions.getInstance().getSelectedText(elementLocator);
default -> ElementActions.getInstance().getAttribute(elementLocator, elementAttribute);
};
} catch (Throwable e) {
// force fail due to upstream failure
if (validationType.getValue()) {
fail(validationCategory, expectedAttributeStates[0] + " '" + expectedValue + attributeSeparator + elementAttribute
+ locatorSeparator + formatLocatorToString(elementLocator) + "'",
"Failed to read the desired element attribute", validationComparisonType, validationType, e);
} else {
fail(validationCategory, expectedAttributeStates[1] + " '" + expectedValue + attributeSeparator + elementAttribute
+ locatorSeparator + formatLocatorToString(elementLocator) + "'",
"Failed to read the desired element attribute", validationComparisonType, validationType, e);
}
return;
}
ReportManagerHelper.setDiscreteLogging(isDiscrete);
lastUsedElementLocator = elementLocator;
int comparisonResult = JavaHelper.compareTwoObjects(expectedValue, actualValue,
validationComparisonType.getValue(), validationType.getValue());
reportValidationResultOfElementAttribute(new Object[]{expectedAttributeStates, attributeSeparator,
locatorSeparator, comparisonResult, elementLocator, elementAttribute, expectedValue, actualValue,
validationComparisonType, validationType, validationCategory});
}
protected static void validateElementCSSProperty(ValidationCategory validationCategory, WebDriver driver, By elementLocator, String propertyName,
String expectedValue, ValidationComparisonType validationComparisonType, ValidationType validationType,
String... optionalCustomLogMessage) {
processCustomLogMessage(optionalCustomLogMessage);
String[] expectedAttributeStates = {"Value Should be", "Value Should not be"};
String propertySeparator = "' for the '";
String locatorSeparator = "' CSS property, element locator '";
String actualValue;
try {
actualValue = new ElementActions(driver).getCSSProperty(elementLocator, propertyName);
} catch (Throwable e) {
// force fail due to upstream failure
if (validationType.getValue()) {
fail(validationCategory, expectedAttributeStates[0] + " '" + expectedValue + propertySeparator + propertyName
+ locatorSeparator + formatLocatorToString(elementLocator) + "'",
"Failed to read the desired element CSS property", validationComparisonType, validationType, e);
} else {
fail(validationCategory, expectedAttributeStates[1] + " '" + expectedValue + propertySeparator + propertyName
+ locatorSeparator + formatLocatorToString(elementLocator) + "'",
"Failed to read the desired element CSS property", validationComparisonType, validationType, e);
}
return;
}
lastUsedElementLocator = elementLocator;
int comparisonResult = JavaHelper.compareTwoObjects(expectedValue, actualValue,
validationComparisonType.getValue(), validationType.getValue());
reportValidationResultOfElementAttribute(new Object[]{expectedAttributeStates, propertySeparator,
locatorSeparator, comparisonResult, elementLocator, propertyName, expectedValue, actualValue,
validationComparisonType, validationType, validationCategory});
}
@SuppressWarnings({"SpellCheckingInspection", "unused"})
protected static void validateBrowserAttribute(ValidationCategory validationCategory, WebDriver driver, String browserAttribute,
String expectedValue, ValidationComparisonType validationComparisonType, ValidationType validationType,
String... optionalCustomLogMessage) {
processCustomLogMessage(optionalCustomLogMessage);
String[] expectedAttributeStates = {"Value Should be", "Value Should not be"};
String attributeSeparator = "' for the '";
String attributeClosure = "' attribute";
String actualValue;
try {
actualValue = switch (browserAttribute.toLowerCase()) {
case "currenturl", "url" -> FluentBrowserActions.getInstance().getCurrentURL();
case "pagesource" -> FluentBrowserActions.getInstance().getPageSource();
case "title" -> FluentBrowserActions.getInstance().getCurrentWindowTitle();
case "windowhandle" -> FluentBrowserActions.getInstance().getWindowHandle();
case "windowposition" -> FluentBrowserActions.getInstance().getWindowPosition();
case "windowsize" -> FluentBrowserActions.getInstance().getWindowSize();
default -> "";
};
} catch (Throwable e) {
// force fail due to upstream failure
if (validationType.getValue()) {
fail(validationCategory, expectedAttributeStates[0] + " '" + expectedValue + attributeSeparator + browserAttribute
+ attributeClosure,
"Failed to read the desired browser attribute", validationComparisonType, validationType, e);
} else {
fail(validationCategory, expectedAttributeStates[1] + " '" + expectedValue + attributeSeparator + browserAttribute
+ attributeClosure,
"Failed to read the desired browser attribute", validationComparisonType, validationType, e);
}
return;
}
int comparisonResult = JavaHelper.compareTwoObjects(expectedValue, actualValue,
validationComparisonType.getValue(), validationType.getValue());
reportValidationResultOfBrowserAttribute(new Object[]{expectedAttributeStates, attributeSeparator,
attributeClosure, comparisonResult, null, browserAttribute, expectedValue, actualValue,
validationComparisonType, validationType, validationCategory});
}
protected static void validateComparativeRelation(ValidationCategory validationCategory, Number expectedValue, Number actualValue,
NumbersComparativeRelation numbersComparativeRelation, ValidationType validationType,
String... optionalCustomLogMessage) {
processCustomLogMessage(optionalCustomLogMessage);
Boolean comparisonState = switch (numbersComparativeRelation.getValue()) {
case ">" -> actualValue.floatValue() > expectedValue.floatValue();
case ">=" -> actualValue.floatValue() >= expectedValue.floatValue();
case "<" -> actualValue.floatValue() < expectedValue.floatValue();
case "<=" -> actualValue.floatValue() <= expectedValue.floatValue();
case "==" -> actualValue.floatValue() == expectedValue.floatValue();
default -> false;
};
if ((ValidationType.POSITIVE.equals(validationType) && comparisonState.equals(true)) || (ValidationType.NEGATIVE.equals(validationType) && comparisonState.equals(false))) {
pass(validationCategory, expectedValue, actualValue, numbersComparativeRelation, validationType);
} else {
fail(validationCategory, expectedValue, actualValue, numbersComparativeRelation, validationType);
}
}
protected static void validateTrue(ValidationCategory validationCategory, Boolean conditionalStatement, ValidationType validationType, String... optionalCustomLogMessage) {
processCustomLogMessage(optionalCustomLogMessage);
Boolean expectedValue = false;
if (ValidationType.POSITIVE.equals(validationType)) {
expectedValue = true;
}
if ((expectedValue && conditionalStatement) || (!expectedValue && !conditionalStatement)) {
pass(validationCategory, String.valueOf(expectedValue).toUpperCase(), String.valueOf(conditionalStatement).toUpperCase(), null, validationType);
} else {
fail(validationCategory, String.valueOf(expectedValue).toUpperCase(), String.valueOf(conditionalStatement).toUpperCase(), null, validationType, null);
}
}
protected static void validateFileExists(ValidationCategory validationCategory, String fileFolderName, String fileName, @SuppressWarnings("SameParameterValue") int numberOfRetries,
ValidationType validationType, String... optionalCustomLogMessage) {
processCustomLogMessage(optionalCustomLogMessage);
boolean expectedValue = ValidationType.POSITIVE.equals(validationType);
boolean actualValue = FileActions.getInstance().doesFileExist(fileFolderName, fileName, numberOfRetries);
String filePrefix = "File '";
String[] expectedAttributeStates = {"' should exist, after up to '", "' should not exist, after up to '"};
String numberOfRetriesPostfix = "' retries";
String reportedExpectedValue = filePrefix + fileFolderName + fileName + expectedAttributeStates[0] + numberOfRetries + numberOfRetriesPostfix;
if (!expectedValue) {
reportedExpectedValue = filePrefix + fileFolderName + fileName + expectedAttributeStates[1] + numberOfRetries + numberOfRetriesPostfix;
}
String reportedActualValue = "File exists";
if (!actualValue) {
reportedActualValue = "File does not exist";
}
if ((expectedValue && actualValue) || (!expectedValue && !actualValue)) {
pass(validationCategory, reportedExpectedValue, reportedActualValue, null, validationType);
} else {
fail(validationCategory, reportedExpectedValue, reportedActualValue, null, validationType, null);
}
}
protected static void validateElementMatches(ValidationCategory validationCategory, WebDriver driver, By elementLocator, VisualValidationEngine visualValidationEngine, ValidationType validationType,
String... optionalCustomLogMessage) {
lastUsedElementLocator = elementLocator;
//TODO: remove this temporary fix when this bug is fixed with shutterbug
//https://github.com/assertthat/selenium-shutterbug/issues/105
if (Properties.web.targetBrowserName().equalsIgnoreCase(Browser.SAFARI.browserName())) {
visualValidationEngine = VisualValidationEngine.EXACT_OPENCV;
}
processCustomLogMessage(optionalCustomLogMessage);
StringBuilder reportedExpectedResult = new StringBuilder();
reportedExpectedResult.append("Element should ");
Boolean expectedResult = validationType.getValue();
if (!expectedResult) {
reportedExpectedResult.append("not ");
}
reportedExpectedResult.append("match the reference screenshot");
List> attachments = new ArrayList<>();
byte[] referenceImage = ImageProcessingActions.getReferenceImage(elementLocator);
if (!Arrays.equals(new byte[0], referenceImage)) {
List