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

io.github.martinschneider.justtestlah.base.BasePage Maven / Gradle / Ivy

package io.github.martinschneider.justtestlah.base;

import com.applitools.eyes.selenium.Eyes;
import com.codeborne.selenide.ElementsCollection;
import com.codeborne.selenide.Selenide;
import com.codeborne.selenide.SelenideElement;
import com.codeborne.selenide.WebDriverRunner;
import com.galenframework.api.Galen;
import com.galenframework.reports.GalenTestInfo;
import com.galenframework.reports.model.LayoutReport;
import io.github.martinschneider.justtestlah.configuration.JustTestLahConfiguration;
import io.github.martinschneider.justtestlah.locator.LocatorMap;
import io.github.martinschneider.justtestlah.locator.LocatorParser;
import io.github.martinschneider.justtestlah.visual.TemplateMatcher;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import javax.annotation.PostConstruct;
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;

/** Base class for page objects. */
public abstract class BasePage extends Base {
  private static final Logger LOG = LoggerFactory.getLogger(BasePage.class);
  private static final String IMAGE_FOLDER = "images";
  private static final double DEFAULT_MATCHING_THRESHOLD = 0.9; // for visual template matching
  protected JustTestLahConfiguration configuration;
  private LocatorMap locators;

  protected LocatorMap getLocators() {
    return locators;
  }

  @Autowired private LocatorParser locatorParser;

  @Autowired private TemplateMatcher templateMatcher;

  @Autowired private Eyes eyes;

  @Autowired private List galenTests;

  /**
   * Selenide style locator.
   *
   * @param locatorKey locator key (can include placeholders)
   * @param params parameters to replace the placeholders
   * @return {@link SelenideElement}
   */
  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}
   */
  protected ElementsCollection $$(String locatorKey, Object... params) {
    return Selenide.$$(
        locators.getCollectionLocator(locatorKey, configuration.getPlatform(), params));
  }

  public boolean hasImage(String imageName) {
    return hasImage(imageName, DEFAULT_MATCHING_THRESHOLD);
  }

  /**
   * 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) {
    WebDriver driver = WebDriverRunner.getWebDriver();
    if (driver instanceof TakesScreenshot) {
      File screenshotFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
      return templateMatcher
          .match(
              screenshotFile.getAbsolutePath(),
              this.getClass()
                  .getClassLoader()
                  .getResource(IMAGE_FOLDER + "/" + imageName)
                  .getFile(),
              threshold)
          .isFound();
    } 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().replaceAll("\\.", "/");
      fileName = baseFolder + "/" + 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));
  }

  /**
   * Performs visual checks using Applitools.
   *
   * @return this
   */
  @SuppressWarnings("unchecked")
  public T checkWindow() {
    if (configuration.isEyesEnabled()) {
      LOG.info("Eyes enabled, performing check on class {}", this.getClass().getSimpleName());
      eyes.checkWindow();
    } else {
      LOG.info(
          "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")
  public T checkLayout() {
    if (configuration.isGalenEnabled()) {
      String baseName = this.getClass().getSimpleName();
      String baseFolder = this.getClass().getPackage().getName().replaceAll("\\.", "/");
      String specPath = baseFolder + "/" + configuration.getPlatform() + "/" + baseName + ".spec";
      LOG.info("Checking layout {}", specPath);
      String title = "Check layout " + specPath;
      LayoutReport layoutReport;
      try {
        layoutReport =
            Galen.checkLayout(
                WebDriverRunner.getWebDriver(),
                this.getClass().getClassLoader().getResource(specPath).getPath(),
                Collections.singletonList(configuration.getPlatform()));
        GalenTestInfo test = GalenTestInfo.fromString(this.getClass().getSimpleName());
        test.getReport().layout(layoutReport, title);
        galenTests.add(test);
      } catch (IOException e) {
        LOG.warn("Error checking layout", e);
      }
    } else {
      LOG.info(
          "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;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy