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

org.openqa.selenium.iphone.IPhoneSimulatorBinary Maven / Gradle / Ivy

There is a newer version: 2.39.0
Show newest version
//
//  IPhoneSimulatorBinary.java
//  IPhoneSimulatorBinary
//
//  Created by Jason Leyba on 12/10/09.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

package org.openqa.selenium.iphone;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.logging.Logger;

import com.google.common.annotations.VisibleForTesting;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.io.TemporaryFilesystem;
import org.openqa.selenium.remote.internal.CircularOutputStream;
import org.openqa.selenium.remote.internal.SubProcess;

/**
 * Handles launching the iWebDriver app on the iPhone Simulator in a
 * subprocess.
 *
 * 

Only one instance of the iPhone Simulator may be run at once, so all * other instances will be killed before a new one is started. * *

The iPhone Simulator will be run in a headless mode against the SDK * specified by the {@code webdriver.iphone.sdk} system property. A temporary * directory will be used as the user home so the application need not be * pre-installed. * * @author [email protected] (Jason Leyba) */ public class IPhoneSimulatorBinary extends SubProcess { /* TODO: Figure out how to launch iWebDriver on the simulator in a non-headless mode. * (Without using the private iPhoneSimulatorRemoteClient.framework) */ private static final Logger LOG = Logger.getLogger(IPhoneSimulatorBinary.class.getName()); private static final String IPHONE_LOG_FILE_PROPERTY = "webdriver.iphone.logFile"; /** * System property used to specificy which iPhone SDK to run the * iPhone Simulator against. If not specified, will default to * {@link #DEFAULT_SDK}. */ private static final String IPHONE_SDK_PROPERTY = "webdriver.iphone.sdk"; /** The default iPhone SDK to use. */ private static final String DEFAULT_SDK = "3.2"; private static final String SDK_LOCATION_FORMAT = "/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator%s.sdk"; /** * Temporary directory used to store all generated iPhone Simulator scripts. */ private static final File SCRIPT_DIRECTORY = TemporaryFilesystem.getDefaultTmpFS().createTempDir("webdriver", "iWebDriver"); /** * Utility script used to kill the iWebDriver process when * {@link #shutdown()} is called. This is necessary since * {@link Process#destroy()} sends a {@code SIGKILL} to this binary's * sub process so we cannot trap it and explicitly kill iWebDriver. */ private final ProcessBuilder killScript; /** * Creates a new IPhoneSimulatorBinary that will run the given application on * the iPhone Simulator. The simulator will be run using the SDK specified by * the {@code webdriver.iphone.sdk} system property. * * @param iWebDriverApp Path to the executable to run on the simulator. This * file should specify the executable that is an immedidate child of the * {@code iwebDriver.app} directory. * @throws IOException If an I/O error occurs. */ public IPhoneSimulatorBinary(File iWebDriverApp) throws IOException { super(new ProcessBuilder("/bin/bash", createRunScript(iWebDriverApp).getAbsolutePath()), createOutputStream()); File killScriptFile = createKillScript(iWebDriverApp.getName()); this.killScript = new ProcessBuilder("/bin/bash", killScriptFile.getAbsolutePath()); } private static OutputStream createOutputStream() { String logFileString = System.getProperty(IPHONE_LOG_FILE_PROPERTY); File logFile = logFileString == null ? null : new File(logFileString); return new CircularOutputStream(logFile); } private static File createRunScript(File executable) throws IOException { String sdkRoot = String.format(SDK_LOCATION_FORMAT, System.getProperty(IPHONE_SDK_PROPERTY, DEFAULT_SDK)); String exe = executable.getCanonicalFile().getAbsolutePath(); String scriptText = new StringBuilder() .append("#!/bin/bash\n") // TODO: this will fail spectacularly if the iPhone Simulator is running from Xcode. Need to // TODO: write an AppleScript to test if Xcode is running the simulator and to make it stop. .append("function shutdown() {\n") .append(" echo \"killing iWebDriver...\"\n") .append(" /usr/bin/killall \"iWebDriver\" || :\n") .append(" echo \"killing iPhone Simulator...\"\n") .append(" /usr/bin/killall \"iPhone Simulator\" || :\n") .append("}\n") // We need to make sure iWebDriver and the iPhone Simulator are not running before // attempting to restart the app. .append("shutdown\n") .append(String.format("export DYLD_ROOT_PATH=%s\n", sdkRoot)) .append(String.format("export IPHONE_SIMULATOR_ROOT=%s\n", sdkRoot)) .append(String.format("export CFFIXED_USER_HOME=%s\n", SCRIPT_DIRECTORY.getAbsolutePath())) // Be a good citizen; make sure we quit when #shutdown() is called. .append("trap \"shutdown\" SIGINT SIGTERM\n") .append(String.format("\"%s\" -RegisterForSystemEvents &\n", exe)) .append("iwebdriver_pid=$!\n") .append("echo \"Waiting on iWebDriver (pid=$iwebdriver_pid)\"...\n") .append("wait $iwebdriver_pid\n") .append("echo \"Finished running iWebDriver (pid=$iwebdriver_pid)\"!\n") .toString(); return writeScript(scriptText); } private static File createKillScript(String appName) throws IOException { // TODO: this will fail spectacularly if the iPhone Simulator is running from Xcode. Need to // TODO: write an AppleScript to test if Xcode is running the simulator and to make it stop. String scriptText = new StringBuilder() .append("#!/bin/bash\n") .append("echo \"killing ").append(appName).append("...\"\n") .append("/usr/bin/killall \"").append(appName).append("\" || :\n") .append("echo \"killing iPhone Simulator...\"\n") .append("/usr/bin/killall \"iPhone Simulator\" || :\n") .toString(); return writeScript(scriptText); } private static File writeScript(String scriptText) throws IOException { File scriptFile = File.createTempFile("iWebDriver.", ".script", SCRIPT_DIRECTORY); LOG.fine(String.format("%s:\n----------------------------------------------\n%s\n\n", scriptFile.getAbsolutePath(), scriptText)); FileWriter writer = new FileWriter(scriptFile); writer.write(scriptText); writer.flush(); writer.close(); return scriptFile.getCanonicalFile(); } @VisibleForTesting ProcessBuilder getKillScript() { return killScript; } /** * Kills iWebDriver and the iPhone Simulator. * * @see SubProcess#shutdown() */ @Override public void shutdown() { // This will kill iWebDriver, which will in turn terminate our run script. try { killScript.start().waitFor(); } catch (InterruptedException e) { throw new WebDriverException(e); } catch (IOException e) { throw new WebDriverException(e); } super.shutdown(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy