com.codacy.scoobydoo.BaseTest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of scooby-doo-fwk Show documentation
Show all versions of scooby-doo-fwk Show documentation
Automated testing framework
package com.codacy.scoobydoo;
import com.codacy.scoobydoo.Constant.Attribute;
import com.codacy.scoobydoo.Constant.Browser;
import com.codacy.scoobydoo.Constant.Status;
import com.codacy.scoobydoo.Constant.TestType;
import com.codacy.scoobydoo.configuration.Configuration;
import com.codacy.scoobydoo.web.ScreenShotHelper;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.v109.network.Network;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.ITestContext;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import java.net.URL;
import java.util.Arrays;
public abstract class BaseTest {
protected Configuration config;
protected RemoteWebDriver driver;
// Or either the driver is always called directly or this get method is always used instead. Using both doesn't make sense.
@Deprecated
public RemoteWebDriver getDriver() {
return driver;
}
@BeforeSuite(alwaysRun = true)
public void setupTestSuite() {
// necessary for the driver Augmenter to work.
System.setProperty("webdriver.http.factory", "jdk-http-client");
}
@BeforeTest(alwaysRun = true)
@Parameters({"type", "environment", "browser", "aws"})
public void configFactory(ITestContext testContext,
String type,
String environment,
@Optional String browser,
@Optional(Status.ENABLED) String aws) {
switch (type.toLowerCase()) {
case TestType.API -> setConfiguration(environment, aws);
case TestType.END, TestType.WEB -> {
setConfiguration(environment, aws);
setDriver(browser);
setTestContext(testContext);
}
default -> throw logAndGetIllegalArgumentException("type", type);
}
}
@AfterTest(alwaysRun = true)
public void cleanup() {
try {
if (driver != null) {
LoggingHelper.info("Deleting all cookies and quitting driver.");
driver.manage().deleteAllCookies();
driver.quit();
}
} catch (Exception e) {
LoggingHelper.error("Error doing the test cleanup.", e);
} finally {
driver = null;
}
}
private void blockChatPopups() {
DevTools devTools = ((HasDevTools) new Augmenter().augment(driver)).getDevTools();
// DevTools logging is too verbose, so it was disabled.
// Do NOT import java.util.logging, since otherwise it will break javadoc generation for Java >8 due to
// conflicts with jackson-annotations, for some reason.
java.util.logging.Logger.getLogger("org.openqa.selenium.devtools").setLevel(java.util.logging.Level.OFF);
devTools.createSession();
java.util.Optional empty = java.util.Optional.empty();
devTools.send(Network.enable(empty, empty, empty));
devTools.send(Network.setBlockedURLs(Arrays.asList(
"https://api-iam.intercom.io/*",
"https://codacy.zendesk.com/*",
"https://api.segment.io/*",
"https://q.clarity.ms/*",
"https://surveystats.hotjar.io/*",
"https://script.hotjar.com/*"
)));
}
private IllegalArgumentException logAndGetIllegalArgumentException(String variableName, String variableValue) {
final String errorMessage = String.format("The %s [%s] is not known.", variableName, variableValue);
IllegalArgumentException exception = new IllegalArgumentException(errorMessage);
LoggingHelper.error(errorMessage, exception);
return exception;
}
private void setConfiguration(String environment, String aws) {
LoggingHelper.info("Setting environment configuration for [" + environment + "].");
try {
config = new Configuration(environment, aws);
} catch (Exception e) {
LoggingHelper.error("Failed while setting environment configuration.", e);
if(driver != null) {
driver.quit();
}
throw e;
}
}
private void setDriver(String browser) {
int retries = 0;
String hubUrl = config.getData("HUB_URL");
boolean isHeadless = config.getProperty("headlessMode").equals(Constant.Status.ENABLED);
if (Browser.CHROME.equalsIgnoreCase(browser)) {
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-dev-shm-usage"); // overcome limited resource problems
options.addArguments("--disable-blink-features=AutomationControlled");
options.addArguments("--start-maximized");
// if some external sites (apart from Google and GitLab) start to block our calls, review this argument.
options.addArguments("--enable-automation");
options.setPageLoadStrategy(PageLoadStrategy.EAGER);
options.setScriptTimeout(config.getTimeout().SCRIPT_TIMEOUT);
if(isHeadless) {
LoggingHelper.info("Activating headless mode for Chrome.");
options.addArguments("--headless=new");
}
while (retries <= 5) {
try {
driver = new RemoteWebDriver(new URL(hubUrl), options, false);
if(isHeadless) {
// This prevents cropped screenshots, since for some reason the headless option breaks the
// default window size. Note that the screen dimensions are, for now, hardcoded to Selenium
// Grid's default resolution.
Dimension seleniumGridDefaultResolution = new Dimension(1300, 1000);
driver.manage().window().setSize(seleniumGridDefaultResolution);
}
blockChatPopups();
break;
} catch (Exception e) {
LoggingHelper.error("Retrying Webdriver after error.", e);
if(driver != null) {
driver.navigate().refresh();
}
retries++;
}
}
} else {
throw new IllegalArgumentException("No logic is currently implemented for browser [" + browser + "].");
}
if(driver == null) {
throw new NullPointerException("Driver did not started correctly. Check previously logged error messages. \n" +
"If you're running in a local machine, ensure that Selenium Grid is running (i.e. check your docker container status).");
}
// To prevent Selenium logging messages, set this logging level BELOW the root level set in the logback.xml file.
// Do NOT import java.util.logging, since otherwise it will break javadoc generation for Java >8 due to
// conflicts with jackson-annotations, for some reason.
driver.setLogLevel(java.util.logging.Level.CONFIG);
driver.manage().timeouts().implicitlyWait(config.getTimeout().LONG_POLLING);
driver.manage().timeouts().pageLoadTimeout(config.getTimeout().PAGE_LOAD_TIMEOUT);
}
private void setTestContext(ITestContext testContext) {
testContext.setAttribute(Attribute.WEB_DRIVER, driver);
testContext.setAttribute(Attribute.SCREENSHOT_HELPER, new ScreenShotHelper(driver, config));
testContext.setAttribute(Attribute.SHOULD_LOG_PAGE_SOURCE, shouldLogPageSource());
}
private boolean shouldLogPageSource() {
final String status = config.getProperty("logPageSourceOnError");
switch (status) {
case Status.ENABLED, Status.ENABLED_ON_FAILURE -> {return true;}
case Status.DISABLED -> {return false;}
default -> throw logAndGetIllegalArgumentException("status", status);
}
}
}