Package com.google.caja.plugin

Source Code of com.google.caja.plugin.WebDriverHandle

// Copyright (C) 2013 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.caja.plugin;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.Capabilities;
import org.openqa.selenium.OutputType;
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.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.Logs;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.safari.SafariDriver;

import com.google.caja.SomethingWidgyHappenedError;
import com.google.caja.util.TestFlag;
import com.google.gwt.thirdparty.guava.common.base.Charsets;

/**
* Wrapper around a WebDriver instance.
*/

class WebDriverHandle {
  private RemoteWebDriver driver = null;
  private boolean canExecuteScript = true;
  private boolean reportedVersion = false;
  private String firstWindow = null;
  private int windowSeq = 0;
  private boolean windowOpened = false;

  // Don't keep more than this many failed test windows. (Otherwise
  // a broken tree can overload a machine with browser windows.)
  private static final int MAX_FAILS_KEPT = 9;
  private static int failsKept = 0;

  WebDriver begin() {
    if (driver == null) {
      driver = makeDriver();
      firstWindow = driver.getWindowHandle();
      reportVersion(driver);
      try {
        driver.manage().timeouts().pageLoadTimeout(15, TimeUnit.SECONDS);
      } catch (WebDriverException e) {
        Echo.echo("failed to set pageLoadTimeout: " + e);
        // harmless, ignore
      }
      try {
        driver.manage().timeouts().setScriptTimeout(5, TimeUnit.SECONDS);
      } catch (WebDriverException e) {
        Echo.echo("failed to setScriptTimeout: " + e);
        // harmless, ignore
      }
    }
    // Try to open a new window
    String name = "cajatest" + (windowSeq++);
    windowOpened = (Boolean) executeScript(
        "return !!window.open('', '" + name + "');");
    if (windowOpened) {
      driver.switchTo().window(name);
    }
    return driver;
  }

  // Selenium 2.33 has trouble executing script on Firefox 23 and later
  private Object executeScript(String script) {
    if (canExecuteScript) {
      try {
        return driver.executeScript(script);
      } catch (WebDriverException e) {
        canExecuteScript = false;
        Echo.echo("executeScript failed: " + e);
      }
    }
    return null;
  }

  private void reportVersion(RemoteWebDriver driver) {
    if (reportedVersion) { return; }
    reportedVersion = true;
    Capabilities caps = driver.getCapabilities();
    String name = caps.getBrowserName();
    if (name == null) { name = "unknown"; }
    String version = caps.getVersion();
    if (version == null) { version = "unknown"; }
    // Firefox's version is something like "20.0", which doesn't tell
    // you the exact build, so we also try to report buildID.
    String build = (String) executeScript(
        "return String(navigator.buildID || '')");
    if (build != null && !"".equals(build)) {
      version += " build " + build;
    }
    Echo.echo("webdriver: browser " + name + " version " + version);
  }

  void end(boolean passed) {
    // If a test fails, drop the driver handle without close or quit,
    // leaving the browser open, which is helpful for debugging.
    if (!passed && !TestFlag.BROWSER_CLOSE.truthy()
        && failsKept++ < MAX_FAILS_KEPT) {
      driver = null;
    } else {
      try {
        // If we're reusing the same browser, close the current window.
        if (windowOpened) {
          driver.close();
          driver.switchTo().window(firstWindow);
        } else {
          driver.get("about:blank");
        }
      } catch (Exception e) {
        Echo.echo("window cleanup failed: " + e);
        closeDriver();
      }
    }
  }

  void release() {
    closeDriver();
  }

  private void closeDriver() {
    if (driver != null) {
      try {
        driver.quit();
      } finally {
        driver = null;
      }
    }
  }

  private static RemoteWebDriver makeDriver() {
    DesiredCapabilities dc = new DesiredCapabilities();

    String browserType = TestFlag.BROWSER.getString("firefox");

    if ("chrome".equals(browserType)) {
      // Chrome driver is odd in that the path to Chrome is specified
      // by a desiredCapability when you start a session. The other
      // browser drivers will read a java system property on start.
      // This applies to both remote Chrome and local Chrome.
      ChromeOptions chromeOpts = new ChromeOptions();
      String chromeBin = TestFlag.CHROME_BINARY.getString(null);
      if (chromeBin != null) {
        chromeOpts.setBinary(chromeBin);
      }
      String chromeArgs = TestFlag.CHROME_ARGS.getString(null);
      if (chromeArgs != null) {
        String[] args = chromeArgs.split(";");
        chromeOpts.addArguments(args);
      }
      dc.setCapability(ChromeOptions.CAPABILITY, chromeOpts);
    }

    String url = TestFlag.WEBDRIVER_URL.getString("");

    if (!"".equals(url)) {
      dc.setBrowserName(browserType);
      dc.setJavascriptEnabled(true);
      try {
        return new RemoteWebDriver(new URL(url), dc);
      } catch (MalformedURLException e) {
        throw new RuntimeException(e);
      }
    } else if ("chrome".equals(browserType)) {
      return new ChromeDriver(dc);
    } else if ("firefox".equals(browserType)) {
      return new FirefoxDriver();
    } else if ("safari".equals(browserType)) {
      // TODO(felix8a): local safari doesn't work yet
      return new SafariDriver();
    } else {
      throw new RuntimeException("No local driver for browser type '"
          + browserType + "'");
    }
  }

  public void captureResults(String name) {
    if (driver == null) { return; }

    String dir = TestFlag.CAPTURE_TO.getString("");
    if ("".equals(dir)) { return; }

    if (!dir.endsWith("/")) { dir = dir + "/"; }
    mkdirs(dir);

    // Try to capture the final html
    try {
      String source = driver.getPageSource();
      if (source != null) {
        saveToFile(dir + name + ".capture.html", source);
      }
    } catch (WebDriverException e) {
      Echo.echo("capture html failed: " + e);
    }

    // Try to capture a screenshot
    if (driver instanceof TakesScreenshot) {
      TakesScreenshot ss = (TakesScreenshot) driver;
      try {
        byte[] bytes = ss.getScreenshotAs(OutputType.BYTES);
        saveToFile(dir + name + ".capture.png", bytes);
      } catch (WebDriverException e) {
        Echo.echo("capture screenshot failed: " + e);
      }
    }

    // Try to capture logs
    try {
      Logs logs = driver.manage().logs();
      if (logs != null) {
        if (logs.getAvailableLogTypes().contains(LogType.BROWSER)) {
          LogEntries entries = logs.get(LogType.BROWSER);
          if (entries != null) {
            StringBuilder sb = new StringBuilder();
            for (LogEntry e : entries) {
              sb.append(e.toString() + "\n");
            }
            saveToFile(dir + name + ".capture.log", sb.toString());
          }
        }
      }
    } catch (WebDriverException e) {
      Echo.echo("capture logs failed: " + e);
    }
  }

  private static void mkdirs(String dirName) {
    File dir = new File(dirName);
    if (!dir.isDirectory() && !dir.mkdirs()) {
      Echo.echo("couldn't mkdir " + dirName);
    }
  }

  private static void saveToFile(String fileName, String str) {
    saveToFile(fileName, str.getBytes(Charsets.UTF_8));
  }

  private static void saveToFile(String fileName, byte[] bytes) {
    FileOutputStream out = null;
    try {
      out = new FileOutputStream(fileName);
      try {
        out.write(bytes);
      } finally {
        out.close();
      }
    } catch (IOException e) {
      throw new SomethingWidgyHappenedError(e);
    }
  }
}
TOP

Related Classes of com.google.caja.plugin.WebDriverHandle

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.