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

org.uiautomation.ios.server.ServerSideSession Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2012-2013 eBay Software Foundation and ios-driver committers
 *
 * 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 org.uiautomation.ios.server;

import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.NoSuchWindowException;
import org.openqa.selenium.SessionNotCreatedException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.remote.SessionId;
import org.uiautomation.ios.IOSCapabilities;
import org.uiautomation.ios.UIAModels.Session;
import org.uiautomation.ios.UIAModels.configuration.CommandConfiguration;
import org.uiautomation.ios.UIAModels.configuration.DriverConfiguration;
import org.uiautomation.ios.UIAModels.configuration.WorkingMode;
import org.uiautomation.ios.client.uiamodels.impl.RemoteIOSDriver;
import org.uiautomation.ios.client.uiamodels.impl.ServerSideNativeDriver;
import org.uiautomation.ios.communication.WebDriverLikeCommand;
import org.uiautomation.ios.communication.device.DeviceVariation;
import org.uiautomation.ios.server.application.APPIOSApplication;
import org.uiautomation.ios.server.application.AppleLanguage;
import org.uiautomation.ios.server.application.IOSRunningApplication;
import org.uiautomation.ios.server.configuration.Configuration;
import org.uiautomation.ios.server.configuration.DriverConfigurationStore;
import org.uiautomation.ios.server.instruments.communication.CommunicationChannel;
import org.uiautomation.ios.server.instruments.InstrumentsManager;
import org.uiautomation.ios.server.utils.IOSVersion;
import org.uiautomation.ios.server.utils.ZipUtils;
import org.uiautomation.ios.utils.ApplicationCrashDetails;
import org.uiautomation.ios.utils.ClassicCommands;
import org.uiautomation.ios.wkrdp.RemoteIOSWebDriver;
import org.uiautomation.ios.wkrdp.internal.AlertDetector;

import java.io.File;
import java.net.URL;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.logging.Logger;

public class ServerSideSession extends Session {

  private static final Logger log = Logger.getLogger(ServerSideSession.class.getName());
  private IOSRunningApplication application;
  private Device device;
  private final IOSCapabilities capabilities;
  private final InstrumentsManager instruments;
  private final IOSServerConfiguration options;
  public final IOSServerManager driver;
  private boolean sessionCrashed;
  private ApplicationCrashDetails  applicationCrashDetails;

  //private WebInspector inspector;

  private RemoteIOSDriver nativeDriver;
  private RemoteIOSWebDriver webDriver;

  private WorkingMode mode = WorkingMode.Native;

  private final DriverConfiguration configuration;

  private Timer stopSessionTimer = new Timer(true);

  private Thread shutdownHook = new Thread() {
    @Override
    public void run() {
      forceStop();
    }
  };


  public IOSCapabilities getCapabilities() {
    return capabilities;
  }

  ServerSideSession(IOSServerManager driver, IOSCapabilities desiredCapabilities,
                    IOSServerConfiguration options) {
    super(UUID.randomUUID().toString());

    this.driver = driver;
    this.capabilities = desiredCapabilities;
    this.options = options;

    this.sessionCrashed = false;
    this.applicationCrashDetails = null;

    String appCapability = (String) desiredCapabilities.getCapability("app");
    if (appCapability != null) {
      if (!Configuration.BETA_FEATURE)
        Configuration.off();
      try {
        File appFile = ZipUtils.extractAppFromURL(appCapability);
        if (appFile.getName().endsWith(".app"))
          desiredCapabilities.setCapability(IOSCapabilities.SIMULATOR, true);
        APPIOSApplication app = APPIOSApplication.createFrom(appFile);
        AppleLanguage lang = AppleLanguage.valueOf(desiredCapabilities.getLanguage());
        application = app.createInstance(lang);
      } catch (Exception ex) {
        throw new SessionNotCreatedException("cannot create app from " + appCapability + ": " + ex);
      }
    } else {
      application = driver.findAndCreateInstanceMatchingApplication(desiredCapabilities);
    }

    try {
      device = driver.findAndReserveMatchingDevice(desiredCapabilities);

      // update capabilities and put default values in the missing fields.
      if (capabilities.getDeviceVariation() == null) {
        capabilities.setDeviceVariation(DeviceVariation.Regular);
      }
      capabilities.setBundleId(application.getBundleId());
      // TODO device.getSDK()
      if (capabilities.getSDKVersion() == null) {
        capabilities.setSDKVersion(ClassicCommands.getDefaultSDK());
      } else {
        String version = capabilities.getSDKVersion();

        if (!new IOSVersion(version).isGreaterOrEqualTo("5.0")) {
          throw new SessionNotCreatedException(version + " is too old. Only support SDK 5.0 and above.");
        }
        if (!driver.getHostInfo().getInstalledSDKs().contains(version)) {
          throw new SessionNotCreatedException(
              "SDK " + version + " not installed on this machine.");
        }

        if (!driver.getHostInfo().getInstalledSDKs().contains(version)) {
          throw new SessionNotCreatedException(
              "Cannot start on version " + version + ".Installed : "
              + driver.getHostInfo().getInstalledSDKs());
        }
      }

      instruments = new InstrumentsManager(this);
      configuration = new DriverConfigurationStore();

      Runtime.getRuntime().addShutdownHook(shutdownHook);
    } catch (WebDriverException e) {
      if (device != null) {
        device.release();
      }
      throw e;
    }
  }

  public Device getDevice() {
    return device;
  }

  public CommandConfiguration configure(WebDriverLikeCommand command) {
    return configuration.configure(command);
  }

  public RemoteIOSDriver getNativeDriver() {
    return nativeDriver;
  }

  public IOSRunningApplication getApplication() {
    return application;
  }

  public CommunicationChannel communication() {
    return instruments.communicate();
  }

  public void stop() {
    // nativeDriver should have instruments within it.
    instruments.stop();
    if (webDriver != null) {
      webDriver.stop();
      webDriver = null;
    }

    stopSessionTimer.cancel();
    stopSessionTimer = null;
    Runtime.getRuntime().removeShutdownHook(shutdownHook);
    shutdownHook = null;
  }

  public void forceStop() {
    instruments.forceStop();
  }

  private void hardForceStop() {
    try {
      instruments.forceStop();
    } catch (Exception ignore) {
    }
    if (webDriver != null) {
      try {
        webDriver.stop();
      } catch (Exception ignore) {
      }
      webDriver = null;
    }
    if (nativeDriver != null) {
      try {
        nativeDriver.quit();
      } catch (Exception ignore) {
      }
      nativeDriver = null;
    }
  }

  public File getOutputFolder() {
    return instruments.getOutput();
  }

  public InstrumentsManager getInstruments() {
    return instruments;

  }

  public void start() {
    instruments.startSession(getSessionId(), application, device, capabilities);

    // force stop session if running for too long
    final int sessionTimeoutMillis = options.getSessionTimeoutMillis();
    stopSessionTimer.schedule(new TimerTask() {
      @Override
      public void run() {
        log.warning("forcing stop session that has been running for " + sessionTimeoutMillis / 1000
                    + " seconds");
        hardForceStop();
      }
    }, sessionTimeoutMillis);

    URL url = null;
    try {
      url = new URL("http://localhost:" + driver.getHostInfo().getPort() + "/wd/hub");
    } catch (Exception e) {
      e.printStackTrace();
    }
    nativeDriver = new ServerSideNativeDriver(url, new SessionId(instruments.getSessionId()));

    if ("Safari".equals(capabilities.getBundleName())) {
      setMode(WorkingMode.Web);
      getRemoteWebDriver().get("about:blank");
    }

  }


  public synchronized RemoteIOSWebDriver getRemoteWebDriver() {
    if (webDriver == null) {
      String version = capabilities.getSDKVersion();
      if (new IOSVersion(version).isGreaterOrEqualTo("6.0")) {
        webDriver = new RemoteIOSWebDriver(this, new AlertDetector(nativeDriver));
      } else {
        log.warning("Cannot create a driver. Version too old " + version);
      }
    }
    return webDriver;
  }

  public void setMode(WorkingMode mode) throws NoSuchWindowException {
    if (mode == WorkingMode.Web) {
      checkWebModeIsAvailable();
      /*try {
        if (!getRemoteWebDriver().isConnected()) {
          //String bundleId = application.getMetadata("CFBundleIdentifier");
          //webDriver.connect(bundleId);
          getRemoteWebDriver().switchTo(webDriver.getPages().get(0));
        }
      } catch (Exception e) {
        e.printStackTrace();
        throw new NoSuchWindowException("Cannot switch to window " + mode, e);
      }   */
    }
    this.mode = mode;
  }

  public WorkingMode getWorkingMode() {
    return this.mode;
  }

  private void checkWebModeIsAvailable() {
    if (webDriver != null) {
      return;
    } else {
      try {
        getNativeDriver().findElement(By.className("UIAWebView"));
      } catch (NoSuchElementException e) {
        throw new NoSuchWindowException("The app currently doesn't have a webview displayed.");
      }
    }

  }

  public boolean  hasCrashed(){
    return sessionCrashed;
  }

  public void sessionHasCrashed(String log){
    sessionCrashed = true;
    applicationCrashDetails = new ApplicationCrashDetails(log);
  }

  public ApplicationCrashDetails getCrashDetails(){
    return applicationCrashDetails;
  }

  public void restartWebkit() {
    int currentPageID = webDriver.getCurrentPageID();
    webDriver.stop();
    webDriver = new RemoteIOSWebDriver(this, new AlertDetector(nativeDriver));
    webDriver.switchTo(String.valueOf(currentPageID));
  }

  public IOSServerManager getIOSServerManager(){
    return driver;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy