Package com.google.gwt.junit

Source Code of com.google.gwt.junit.RunStyleSelenium$RCSelenium

/*
* Copyright 2008 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.gwt.junit;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;

import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;
import com.thoughtworks.selenium.SeleniumException;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Runs in web mode via browsers managed by Selenium.
*/
public class RunStyleSelenium extends RunStyleRemote {

  private static class RCSelenium {
    final String browser;
    final String host;
    final int port;
    Selenium selenium;

    public RCSelenium(String browser, String host, int port) {
      this.browser = browser;
      this.host = host;
      this.port = port;
    }

    public void createSelenium(String domain) {
      this.selenium = new DefaultSelenium(host, port, browser, domain);
    }

    public String getBrowser() {
      return browser;
    }

    public String getHost() {
      return host;
    }

    public int getPort() {
      return port;
    }

    public Selenium getSelenium() {
      return selenium;
    }
  }

  public static RunStyle create(JUnitShell shell, String[] targetsIn) {
    RCSelenium targets[] = new RCSelenium[targetsIn.length];

    Pattern pattern = Pattern.compile("([\\w\\.-]+):([\\d]+)/([\\w\\s\\*]+)");
    for (int i = 0; i < targets.length; ++i) {
      Matcher matcher = pattern.matcher(targetsIn[i]);
      if (!matcher.matches()) {
        throw new JUnitFatalLaunchException("Unable to parse Selenium target " + targetsIn[i]
            + " (expected format is [host]:[port]/[browser])");
      }
      RCSelenium instance =
          new RCSelenium(matcher.group(3), matcher.group(1), Integer.parseInt(matcher.group(2)));
      targets[i] = instance;
    }

    RunStyleSelenium runStyle = new RunStyleSelenium(shell, targets);
    runStyle.start();
    return runStyle;
  }

  private RCSelenium remotes[];

  /**
   * Whether one of the remote browsers was interrupted.
   */
  private boolean wasInterrupted;

  /**
   * A separate lock to control access to {@link #wasInterrupted}. This keeps
   * the main thread calls into {@link #wasInterrupted()} from having to be
   * synchronized on the containing instance and potentially block on RPC calls.
   * It is okay to take the {@link #wasInterruptedLock} while locking the
   * containing instance; it is NOT okay to do the opposite or deadlock could
   * occur.
   */
  private final Object wasInterruptedLock = new Object();

  protected RunStyleSelenium(final JUnitShell shell, RCSelenium targets[]) {
    super(shell);
    this.remotes = targets;

    // Install a shutdown hook that will close all of our outstanding Selenium
    // sessions.
    Runtime.getRuntime().addShutdownHook(new Thread() {
      @Override
      public void run() {
        for (RCSelenium remote : remotes) {
          if (remote.getSelenium() != null) {
            try {
              remote.getSelenium().stop();
            } catch (SeleniumException se) {
              shell.getTopLogger().log(TreeLogger.WARN, "Error stoping selenium session", se);
            }
          }
        }
      }
    });
  }

  @Override
  public synchronized void launchModule(String moduleName) throws UnableToCompleteException {
    // Get the localhost address.
    String domain;
    try {
      String localhost = InetAddress.getLocalHost().getHostAddress();
      domain = "http://" + localhost + ":" + shell.getPort() + "/";
    } catch (UnknownHostException e) {
      throw new RuntimeException("Unable to determine my ip address", e);
    }

    // Startup all the selenia and point them at the module url.
    for (RCSelenium remote : remotes) {
      try {
        shell.getTopLogger().log(TreeLogger.TRACE,
            "Starting with domain: " + domain + " Opening URL: " + getMyUrl(moduleName));
        remote.createSelenium(domain);
        remote.getSelenium().start();
        remote.getSelenium().open(getMyUrl(moduleName));
      } catch (Exception e) {
        shell.getTopLogger().log(TreeLogger.ERROR,
            "Error launching browser via Selenium-RC at " + remote.getHost(), e);
      }
    }
  }

  @Override
  public boolean wasInterrupted() {
    synchronized (wasInterruptedLock) {
      return wasInterrupted;
    }
  }

  /**
   * Create the keep-alive thread.
   */
  protected void start() {
    // This will periodically check for failure of the Selenium session and stop
    // the test if something goes wrong.
    Thread keepAliveThread = new Thread() {
      @Override
      public void run() {
        do {
          try {
            Thread.sleep(1000);
          } catch (InterruptedException ignored) {
          }
        } while (doKeepAlives());
      }
    };
    keepAliveThread.setDaemon(true);
    keepAliveThread.start();
  }

  private synchronized boolean doKeepAlives() {
    if (remotes != null) {
      for (RCSelenium remote : remotes) {
        // Use getTitle() as a cheap way to see if the Selenium server's still
        // responding (Selenium seems to provide no way to check the server
        // status directly).
        try {
          if (remote.getSelenium() != null) {
            remote.getSelenium().getTitle();
          }
        } catch (Throwable e) {
          setWasInterrupted(true);
        }
      }
    }

    return !wasInterrupted();
  }

  private void setWasInterrupted(boolean wasInterrupted) {
    synchronized (wasInterruptedLock) {
      this.wasInterrupted = wasInterrupted;
    }
  }
}
TOP

Related Classes of com.google.gwt.junit.RunStyleSelenium$RCSelenium

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.