Package com.codeborne.selenide

Source Code of com.codeborne.selenide.WebDriverRunner

package com.codeborne.selenide;

import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.internal.Killable;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;

import static com.codeborne.selenide.Configuration.*;
import static java.io.File.separatorChar;
import static org.openqa.selenium.OutputType.FILE;

public class WebDriverRunner {
  public static final String CHROME = "chrome";
  public static final String INTERNET_EXPLORER = "ie";
  public static final String FIREFOX = "firefox";

  /**
   * To use HtmlUnitDriver, you need to include extra dependency to your project:
   * <dependency org="org.seleniumhq.selenium" name="selenium-htmlunit-driver" rev="2.33.0" conf="test->default"/>
   *
   * It's also possible to run HtmlUnit driver emulating different browsers:
   * <p>
   * java -Dbrowser=htmlunit:firefox
   * </p>
   * <p>
   * java -Dbrowser=htmlunit:chrome
   * </p>
   * <p>
   * java -Dbrowser=htmlunit:internet explorer   (default)
   * </p>
   * etc.
   */
  public static final String HTMLUNIT = "htmlunit";

  /**
   * To use OperaDriver, you need to include extra dependency to your project:
   * <dependency org="com.github.detro.ghostdriver" name="phantomjsdriver" rev="1.+" conf="test->default"/>
   */
  public static final String PHANTOMJS = "phantomjs";

  /**
   * To use OperaDriver, you need to include extra dependency to your project:
   * <dependency org="com.opera" name="operadriver" rev="0.18" conf="test->default"/>
   */
  public static final String OPERA = "opera";

  private static WebDriver webdriver;

  static {
    Runtime.getRuntime().addShutdownHook(new Thread() {
      @Override
      public void run() {
        closeWebDriver();
      }
    });
  }

  /**
   * Tell Selenide use your provided WebDriver instance.
   * Use it if you need a custom logic for creating WebDriver.
   *
   * It's recommended not to use implicit wait with this driver, because Selenide handles timing issues explicitly.
   *
   * <p/>
   * <p/>
   *
   * NB! Be sure to call this method before calling <code>open(url)</code>.
   * Otherwise Selenide will create its own WebDriver instance and would not close it.
   *
   * <p/>
   * <p/>
   * P.S. Alternatively, you can run tests with system property
   * <pre>  -Dbrowser=com.my.WebDriverFactory</pre>
   *
   * which should implement interface com.codeborne.selenide.WebDriverProvider
   */
  public static void setWebDriver(WebDriver webDriver) {
    webdriver = webDriver;
  }

  /**
   * Get the underlying instance of Selenium WebDriver.
   * This can be used for any operations directly with WebDriver.
   */
  public static WebDriver getWebDriver() {
    if (webdriver == null) {
      webdriver = createDriver();
    }
    return webdriver;
  }

  public static void closeWebDriver() {
    if (webdriver != null) {
      if (!holdBrowserOpen) {
        try {
          webdriver.quit();
        } catch (WebDriverException cannotCloseBrowser) {
          System.err.println("Cannot close browser normally: " + cleanupWebDriverExceptionMessage(cannotCloseBrowser));
        }
        finally {
          killBrowser();
        }
      }
      webdriver = null;
    }
  }

  static void killBrowser() {
    if (webdriver instanceof Killable) {
      try {
        ((Killable) webdriver).kill();
      } catch (Exception e) {
        System.err.println("Failed to kill browser " + webdriver + ':');
        e.printStackTrace();
      }
    }
  }

  public static boolean ie() {
    return INTERNET_EXPLORER.equalsIgnoreCase(browser);
  }

  public static boolean htmlUnit() {
    return browser != null && browser.startsWith(HTMLUNIT);
  }

  public static boolean phantomjs() {
    return PHANTOMJS.equalsIgnoreCase(browser);
  }

  public static void clearBrowserCache() {
    if (webdriver != null) {
      webdriver.manage().deleteAllCookies();
    }
  }

  public static String source() {
    return getWebDriver().getPageSource();
  }

  public static String url() {
    return getWebDriver().getCurrentUrl();
  }

  public static String takeScreenShot(String className, String methodName) {
    return takeScreenShot(getScreenshotFileName(className, methodName));
  }

  static String getScreenshotFileName(String className, String methodName) {
    return className.replace('.', separatorChar) + separatorChar + methodName;
  }

  public static String takeScreenShot(String fileName) {
    if (webdriver == null) {
      System.err.println("Cannot take screenshot because browser is not started");
      return null;
    }

    File targetFile = new File(reportsFolder, fileName + ".html");

    try {
      writeToFile(webdriver.getPageSource(), targetFile);
    } catch (Exception e) {
      System.err.println(e);
    }

    if (webdriver instanceof TakesScreenshot) {
      targetFile = takeScreenshotImage((TakesScreenshot) webdriver, fileName, targetFile);
    }
    else if (webdriver instanceof RemoteWebDriver) {
      WebDriver remoteDriver = new Augmenter().augment(webdriver);
      if (webdriver instanceof TakesScreenshot) {
        targetFile = takeScreenshotImage((TakesScreenshot) remoteDriver, fileName, targetFile);
      }
    }

    return targetFile.getAbsolutePath();
  }

  private static File takeScreenshotImage(TakesScreenshot driver, String fileName, final File targetFile) {
    try {
      File scrFile = driver.getScreenshotAs(FILE);
      File imageFile = new File(reportsFolder, fileName + ".png");
      copyFile(scrFile, imageFile);
      return imageFile;
    } catch (Exception e) {
      System.err.println(e);
    }
    return targetFile;
  }

  private static void copyFile(File sourceFile, File targetFile) throws IOException {
    copyFile(new FileInputStream(sourceFile), targetFile);
  }

  private static void copyFile(InputStream in, File targetFile) throws IOException {
    ensureFolderExists(targetFile);

    byte[] buffer = new byte[1024];
    int len;
    try {
      final FileOutputStream out = new FileOutputStream(targetFile);
      try {
        while ((len = in.read(buffer)) != -1) {
          out.write(buffer, 0, len);
        }
      } finally {
        out.close();
      }
    } finally {
      in.close();
    }
  }

  private static void writeToFile(String content, File targetFile) throws IOException {
    copyFile(new ByteArrayInputStream(content.getBytes()), targetFile);
  }

  private static File ensureFolderExists(File targetFile) {
    File folder = targetFile.getParentFile();
    if (!folder.exists()) {
      System.err.println("Creating folder: " + folder);
      if (!folder.mkdirs()) {
        System.err.println("Failed to create " + folder);
      }
    }
    return targetFile;
  }

  private static WebDriver createDriver() {
    if (remote != null) {
      return createRemoteDriver(remote, browser);
    }
    else if (CHROME.equalsIgnoreCase(browser)) {
      ChromeOptions options = new ChromeOptions();
      if (startMaximized) {
        // Due do bug in ChromeDriver we need this workaround
        // http://stackoverflow.com/questions/3189430/how-do-i-maximize-the-browser-window-using-webdriver-selenium-2
        options.addArguments("chrome.switches", "--start-maximized");
      }
      return new ChromeDriver(options);
    }
    else if (ie()) {
      return maximize(new InternetExplorerDriver());
    }
    else if (htmlUnit()) {
      DesiredCapabilities capabilities = DesiredCapabilities.htmlUnit();
      capabilities.setCapability(HtmlUnitDriver.INVALIDSELECTIONERROR, true);
      capabilities.setCapability(HtmlUnitDriver.INVALIDXPATHERROR, false);
      capabilities.setJavascriptEnabled(true);
      if (browser.indexOf(':') > -1) {
        // Use constants BrowserType.IE, BrowserType.FIREFOX, BrowserType.CHROME etc.
        String emulatedBrowser = browser.replaceFirst("htmlunit:(.*)", "$1");
        capabilities.setVersion(emulatedBrowser);
      }
      return new HtmlUnitDriver(capabilities);
    }
    else if (FIREFOX.equalsIgnoreCase(browser)) {
      return maximize(new FirefoxDriver());
    }
    else if (OPERA.equalsIgnoreCase(browser)) {
      return createInstanceOf("com.opera.core.systems.OperaDriver");
    }
    else if (PHANTOMJS.equals(browser)) {
      DesiredCapabilities capabilities = new DesiredCapabilities();
      capabilities.setJavascriptEnabled(true);
      capabilities.setCapability("takesScreenshot", true);
      return new org.openqa.selenium.phantomjs.PhantomJSDriver(capabilities);
    }
    else {
      return createInstanceOf(browser);
    }
  }

  private static RemoteWebDriver maximize(RemoteWebDriver driver) {
    if (startMaximized) {
      driver.manage().window().maximize();
    }
    return driver;
  }

  private static WebDriver createInstanceOf(String className) {
    try {
      Class<?> clazz = Class.forName(className);
      if (WebDriverProvider.class.isAssignableFrom(clazz)) {
        return ((WebDriverProvider)clazz.newInstance()).createDriver();
      } else {
        return (WebDriver) Class.forName(className).newInstance();
      }
    }
    catch (Exception invalidClassName) {
      throw new IllegalArgumentException(invalidClassName);
    }
  }

  private static WebDriver createRemoteDriver(String remote, String browser) {
    try {
      DesiredCapabilities capabilities = new DesiredCapabilities();
      capabilities.setBrowserName(browser);
      return new RemoteWebDriver(new URL(remote), capabilities);
    } catch (MalformedURLException e) {
      throw new IllegalArgumentException("Invalid 'remote' parameter: " + remote, e);
    }
  }

  public static String cleanupWebDriverExceptionMessage(WebDriverException webDriverException) {
    return cleanupWebDriverExceptionMessage(webDriverException.toString());
  }

  static String cleanupWebDriverExceptionMessage(String webDriverExceptionInfo) {
    return webDriverExceptionInfo == null || webDriverExceptionInfo.indexOf('\n') == -1 ?
        webDriverExceptionInfo :
        webDriverExceptionInfo
            .substring(0, webDriverExceptionInfo.indexOf('\n'))
            .replaceFirst("(.*)\\(WARNING: The server did not provide any stacktrace.*", "$1")
            .replaceFirst("org\\.openqa\\.selenium\\.(.*)", "$1")
            .trim();
  }
}
TOP

Related Classes of com.codeborne.selenide.WebDriverRunner

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.