Package ch.inftec.ju.ee.webtest

Source Code of ch.inftec.ju.ee.webtest.DriverRule

package ch.inftec.ju.ee.webtest;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.junit.Assert;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.inftec.ju.testing.db.DbTestAnnotationHandler;
import ch.inftec.ju.testing.db.JuTestEnv;
import ch.inftec.ju.util.AssertUtil;
import ch.inftec.ju.util.JuRuntimeException;
import ch.inftec.ju.util.JuStringUtils;
import ch.inftec.ju.util.JuUrl;
import ch.inftec.ju.util.JuUtils;
import ch.inftec.ju.util.PropertyChain;
import ch.inftec.ju.util.ReflectUtils;
import ch.inftec.ju.util.ReflectUtils.AnnotationInfo;
import ch.inftec.ju.util.SystemPropertyTempSetter;
import ch.inftec.ju.util.TestUtils;

/**
* JUnit rule to run web tests with (multiple) selenium drivers.
* @author Martin
*
*/
public class DriverRule implements TestRule {
  private static boolean copiedChromeDriverExe = false;
 
  private static final String PROP_DRIVER = "ju-testing-ee.selenium.driver";
  private static final String CHROME_DRIVER_EXE_PATH = "target/chromedriver.exe";
 
  private static final Logger logger = LoggerFactory.getLogger(DriverRule.class);
 
  private final WebTest testClass;
 
  private static List<WebDriver> openDrivers = new ArrayList<>();
  private Map<String, WebDriver> drivers = new LinkedHashMap<>();
 
  DriverRule(WebTest testClass) {
    this.testClass = testClass;
  }
 
  @Override
  public Statement apply(final Statement base, Description description) {
    // Handle JuTestEnv annotations
    Method method = TestUtils.getTestMethod(description);
    List<AnnotationInfo<JuTestEnv>> testEnvAnnos = ReflectUtils.getAnnotationsWithInfo(method, JuTestEnv.class, false, true, true);
    Collections.reverse(testEnvAnnos);
    final SystemPropertyTempSetter tempSetter = DbTestAnnotationHandler.setTestEnvProperties(testEnvAnnos);
   
    try {
      PropertyChain pc = JuUtils.getJuPropertyChain();
     
      if (this.drivers.isEmpty()) {
        // Get from the properties which drivers we should use to run the tests
        String drivers[] = JuStringUtils.split(pc.get(PROP_DRIVER, true), ",", true);
        Assert.assertTrue(String.format("No drivers specified in property %s", DriverRule.PROP_DRIVER), drivers.length > 0);
       
        logger.debug("Initialize WebDrivers: " + Arrays.toString(drivers));
        for (String driverType : drivers) {
          WebDriver driver = null;
         
          logger.debug("Creating driver: " + driverType);
          if ("HtmlUnit".equals(driverType)) {
            boolean enableJavaScript = pc.get("ju-testing-ee.selenium.htmlUnit.enableJavascript", Boolean.class);
            driver = new HtmlUnitDriver(enableJavaScript);
          } else if ("Chrome".equals(driverType)) {
            System.setProperty("webdriver.chrome.driver", DriverRule.getChromeDriverExePath().toAbsolutePath().toString());
                driver = new ChromeDriver();
          } else {
            throw new JuRuntimeException(String.format("Unsupported selenium driver type: %s. Check value of property %s"
                , driverType
                , PROP_DRIVER));
          }
         
          this.drivers.put(driverType, driver);
          DriverRule.openDrivers.add(driver);
        }
      }
     
      return new Statement() {
        public void evaluate() throws Throwable {
          try {
            // Run test case for with all drivers
            for (String driverType : drivers.keySet()) {
              logger.info("Running test with WebDriver " + driverType);
              testClass.driver = drivers.get(driverType);
             
              // If the evaluation fails, it will break our loop, i.e. if we want to run drivers
              // d1 and d2 and in d1, we have an exception, d2 won't be executed at all...
              base.evaluate();
            }
          } finally {
            tempSetter.close();
          }
        }
      };
    } catch (Exception ex) {
      tempSetter.close();
      throw ex;
    }
  }
 
  /**
   * Quits all open WebDriver instances.
   */
  public static void closeAll() {
    for (WebDriver driver : DriverRule.openDrivers) {
      driver.quit();
    }
  }
 
  private static Path getChromeDriverExePath() {
    // We'll store the chromedriver in the target directory of the current working folder
    Path chromeDriverExePath = Paths.get(DriverRule.CHROME_DRIVER_EXE_PATH);
   
    try {
      if (Files.notExists(chromeDriverExePath) || !DriverRule.copiedChromeDriverExe) {
        URL chromedriverResourceUrl = JuUrl.resource("chromedriver.exe");
        AssertUtil.assertNotNull("Couldn't find chromedriver.exe on classpath", chromedriverResourceUrl);
       
        logger.debug("Copying chromedriver.exe from resource {} to {}"
            , chromedriverResourceUrl
            , chromeDriverExePath.toAbsolutePath());
        try (InputStream is = new BufferedInputStream(chromedriverResourceUrl.openStream())) {
          Files.copy(is, chromeDriverExePath, StandardCopyOption.REPLACE_EXISTING);
        }
       
        DriverRule.copiedChromeDriverExe = true;
      }
    } catch (Exception ex) {
      throw new JuRuntimeException("Couldn't copy chromedriver.exe to " + chromeDriverExePath, ex);
    }
   
    return chromeDriverExePath;
  }
}
TOP

Related Classes of ch.inftec.ju.ee.webtest.DriverRule

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.