All Downloads are FREE. Search and download functionalities are using the official Maven repository.

qa.justtestlah.base.BasePage Maven / Gradle / Ivy

Go to download

JustTestLah! is a JAVA test framework targeting projects that support multiple platforms, in particular Web, Android and iOS. It follows a BDD approach and allows testing against all platforms using the same feature files. JustTestLah's main aim is to make the configuration and the actual test code as easy as possible.

There is a newer version: 1.9-RC4
Show newest version
package qa.justtestlah.base;

import static com.codeborne.selenide.Condition.appear;

import com.codeborne.selenide.ElementsCollection;
import com.codeborne.selenide.Selenide;
import com.codeborne.selenide.SelenideElement;
import com.codeborne.selenide.WebDriverRunner;
import com.codeborne.selenide.ex.ElementNotFound;
import io.appium.java_client.HasSettings;
import io.appium.java_client.Setting;
import java.io.File;
import javax.annotation.PostConstruct;
import org.apache.commons.lang3.tuple.Pair;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import qa.justtestlah.annotations.ScreenIdentifier;
import qa.justtestlah.configuration.JustTestLahConfiguration;
import qa.justtestlah.exception.ScreenVerificationException;
import qa.justtestlah.locator.LocatorMap;
import qa.justtestlah.locator.LocatorParser;
import qa.justtestlah.locator.LocatorPlaceholders;
import qa.justtestlah.log.LogLevel;
import qa.justtestlah.log.TestLogWriter;
import qa.justtestlah.stubs.AppiumTemplateMatcher;
import qa.justtestlah.stubs.Applitools;
import qa.justtestlah.stubs.Galen;
import qa.justtestlah.stubs.Match;
import qa.justtestlah.stubs.TemplateMatcher;
import qa.justtestlah.utils.ImageUtils;

/** Base class for page objects. */
public abstract class BasePage extends Base {
  protected static final Logger LOG = LoggerFactory.getLogger(BasePage.class);
  protected static final Logger TESTLOG =
      LoggerFactory.getLogger(TestLogWriter.TESTLOG_LOGGER_NAME);
  protected static final int DEFAULT_VERIFICATION_TIMEOUT = 2000; // milliseconds
  protected JustTestLahConfiguration configuration;
  private LocatorMap locators;

  @Autowired private LocatorParser locatorParser;

  @Autowired private TemplateMatcher templateMatcher;

  @Autowired private LocatorPlaceholders globalPlaceholders;

  @Autowired private Applitools applitools;

  @Autowired private Galen galen;

  @Autowired private TestLogWriter logWriter;

  protected LocatorMap getLocators() {
    return locators;
  }

  /**
   * Selenide style locator.
   *
   * @param locatorKey locator key (can include placeholders)
   * @param params parameters to replace the placeholders
   * @return {@link SelenideElement}
   */
  @SuppressWarnings("squid:S00100")
  protected SelenideElement $(String locatorKey, Object... params) {
    return Selenide.$(locators.getLocator(locatorKey, configuration.getPlatform(), params));
  }

  /**
   * Selenide style collection locator.
   *
   * @param locatorKey locator key (can include placeholders)
   * @param params parameters to replace the placeholders
   * @return {@link ElementsCollection}
   */
  @SuppressWarnings("squid:S00100")
  protected ElementsCollection $$(String locatorKey, Object... params) {
    return Selenide.$$(
        locators.getCollectionLocator(locatorKey, configuration.getPlatform(), params));
  }

  /**
   * @param imageName image to check for
   * @return true, if the image has been found on the current screen
   */
  public boolean hasImage(String imageName) {
    return hasImage(imageName, 0.9);
  }

  /**
   * Checks for the given image within the current screen.
   *
   * @param imageName image to check for
   * @param threshold matching threshold
   * @return true, if the image has been found on the current screen
   */
  public boolean hasImage(String imageName, double threshold) {
    return findImage(imageName, threshold).isFound();
  }

  /**
   * Finds the given image within the current screen.
   *
   * @param imageName image to check for
   * @param threshold matching threshold
   * @return {@link Match}
   */
  public Match findImage(String imageName, double threshold) {
    WebDriver driver = WebDriverRunner.getWebDriver();
    if (driver instanceof TakesScreenshot) {
      File screenshotFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
      if (templateMatcher instanceof AppiumTemplateMatcher) {
        if (driver instanceof HasSettings) {
          LOG.info("Setting image matching threshold to {}", threshold);
          HasSettings settingsDriver = ((HasSettings) driver);
          settingsDriver.setSetting(Setting.IMAGE_MATCH_THRESHOLD, threshold);
        }
        ((AppiumTemplateMatcher) templateMatcher).setDriver(WebDriverRunner.getWebDriver());
      }
      return templateMatcher.match(
          screenshotFile.getAbsolutePath(), ImageUtils.getFullPath(imageName), threshold);
    } else {
      throw new UnsupportedOperationException(
          "This operation is not supported for the current WebDriver: "
              + driver.getClass().getSimpleName()
              + ".");
    }
  }

  /** Initialize the {@link LocatorMap}. */
  @PostConstruct
  public void initializeLocatorMap() {
    Class parent = this.getClass();
    String fileName = null;
    do {
      String baseName = parent.getSimpleName();
      String baseFolder = parent.getPackage().getName().replace(".", File.separator);
      fileName = baseFolder + File.separator + baseName + ".yaml";
      parent = parent.getSuperclass();
    } while (!parent.equals(BasePage.class));
    loadLocators(fileName);
  }

  private void loadLocators(String fileName) {
    LOG.info("Loading locators from {}", fileName);
    locators = new LocatorMap(locatorParser.parse(fileName), globalPlaceholders.getProps());
  }

  /**
   * Performs visual checks using Applitools.
   *
   * @return this
   */
  @SuppressWarnings("unchecked")
  private T checkWindow() {
    if (configuration.isEyesEnabled()) {
      logWriter.log(
          LogLevel.INFO,
          TestLogWriter.WEBDRIVER_INDENTATION,
          "Performing visual checks on class {}",
          this.getClass().getSimpleName());
      applitools.checkWindow();
    } else {
      LOG.debug(
          "Eyes disabled, skipping check on class {}. You can enable visual testing with "
              + "Applitools Eyes by setting eyes.enabled = true in justtestlah.properties.",
          this.getClass().getSimpleName());
    }
    return (T) this;
  }

  /**
   * Performs layout checks using Galen.
   *
   * @return this
   */
  @SuppressWarnings("unchecked")
  private T checkLayout() {
    if (configuration.isGalenEnabled()) {
      String baseName = this.getClass().getSimpleName();
      String baseFolder = this.getClass().getPackage().getName().replaceAll("\\.", File.separator);
      String specPath =
          baseFolder
              + File.separator
              + configuration.getPlatform()
              + File.separator
              + baseName
              + ".spec";
      galen.checkLayout(specPath, locators);
    } else {
      LOG.debug(
          "Galen checks disabled, skipping checks for class {}. "
              + "You can enable Galen by setting galen.enabled = true in justtestlah.properties.",
          this.getClass().getSimpleName());
    }
    return (T) this;
  }

  @Autowired
  public void setConfiguration(JustTestLahConfiguration configuration) {
    this.configuration = configuration;
  }

  /** @return this page object */
  public T verify() {
    return verify(DEFAULT_VERIFICATION_TIMEOUT);
  }

  /**
   * Verifies, that all UI elements defined for the given page object using {@link ScreenIdentifier}
   * are displayed.
   *
   * 

Performs Galen and Applitools checks, if enabled. * * @param timeout the timeout for identifying the first element. Note, that there is no timeout * for any subsequent checks! * @return this page object */ @SuppressWarnings("unchecked") public T verify(int timeout) { boolean initialCheck = true; // Applitools checkWindow(); // Galen checkLayout(); Class clazz = this.getClass(); logWriter.log( LogLevel.INFO, TestLogWriter.WEBDRIVER_INDENTATION, "Verifying screen identifiers for {}", clazz.getSimpleName()); while (clazz != Base.class) { for (ScreenIdentifier identifiers : clazz.getAnnotationsByType(ScreenIdentifier.class)) { for (String identifier : identifiers.value()) { // rawLocator is only used for logging purposes Pair rawLocator = locators.getRawLocator(identifier, configuration.getPlatform()); try { // only use the timeout for the first check if (initialCheck) { $(identifier).waitUntil(appear, timeout).isDisplayed(); } else { $(identifier).waitUntil(appear, 0).isDisplayed(); } initialCheck = false; } catch (ElementNotFound exception) { throw new ScreenVerificationException( identifier, rawLocator, this.getClass().getSimpleName(), timeout); } logWriter.log( LogLevel.INFO, TestLogWriter.WEBDRIVER_INDENTATION, "[OK] {} is displayed {}:{}", identifier, rawLocator.getLeft(), rawLocator.getRight()); } } clazz = clazz.getSuperclass(); } return (T) this; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy