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

org.openqa.selenium.remote.server.DefaultSession Maven / Gradle / Ivy

There is a newer version: 4.5.0
Show newest version
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you 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.openqa.selenium.remote.server;

import org.openqa.selenium.Capabilities;
import org.openqa.selenium.HasCapabilities;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Platform;
import org.openqa.selenium.Rotatable;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.html5.ApplicationCache;
import org.openqa.selenium.html5.LocationContext;
import org.openqa.selenium.html5.WebStorage;
import org.openqa.selenium.interactions.HasTouchScreen;
import org.openqa.selenium.internal.FindsByCssSelector;
import org.openqa.selenium.io.TemporaryFilesystem;
import org.openqa.selenium.mobile.NetworkConnection;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.support.events.EventFiringWebDriver;

import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;

/**
 * The default session implementation.
 *
 * Thread safety notes:
 *
 * There are basically two different thread types rummaging around in this class: Container listener
 * threads which deliver requests, and the "executor" thread that processes each request. This means
 * there is a minefield of thread constraints/guards, some of which are described in docs for each
 * field.
 */

public class DefaultSession implements Session {

  private static final String QUIET_EXCEPTIONS_KEY = "webdriver.remote.quietExceptions";
  private final SessionId sessionId;
  private final WebDriver driver;
  /**
   * The cache of known elements.
   *
   * Happens-before the exexutor and is thereafter thread-confined to the executor thread.
   */
  private final KnownElements knownElements;
  private final Map capabilities;
  // elements inside capabilities.
  private volatile String base64EncodedImage;
  private TemporaryFilesystem tempFs;

  public static Session createSession(
      DriverFactory factory,
      TemporaryFilesystem tempFs,
      Capabilities capabilities)
      throws Exception {
    return new DefaultSession(factory, tempFs, capabilities);
  }

  private DefaultSession(
      final DriverFactory factory,
      TemporaryFilesystem tempFs,
      final Capabilities capabilities) throws Exception {
    this.knownElements = new KnownElements();
    this.tempFs = tempFs;
    final BrowserCreator browserCreator = new BrowserCreator(factory, capabilities);

    // Ensure that the browser is created on the single thread.
    EventFiringWebDriver initialDriver = browserCreator.call();

    if (!isQuietModeEnabled(browserCreator, capabilities)) {
      // Memo to self; this is not a constructor escape of "this" - probably ;)
      initialDriver.register(new SnapshotScreenListener(this));
    }

    this.driver = initialDriver;
    this.capabilities = browserCreator.getCapabilityDescription();
    this.sessionId = browserCreator.getSessionId();
  }

  private static boolean isQuietModeEnabled(
      BrowserCreator browserCreator,
      Capabilities capabilities) {
    if (browserCreator.isAndroid()) {
      return true;
    }
    boolean propertySaysQuiet = "true".equalsIgnoreCase(System.getProperty(QUIET_EXCEPTIONS_KEY));
    if (capabilities == null) {
      return propertySaysQuiet;
    }
    if (capabilities.is(QUIET_EXCEPTIONS_KEY)) {
      return true;
    }
    Object cap = capabilities.asMap().get(QUIET_EXCEPTIONS_KEY);
    boolean isExplicitlyDisabledByCapability = cap != null && "false".equalsIgnoreCase(cap.toString());
    return propertySaysQuiet && !isExplicitlyDisabledByCapability;
  }

  public void close() {
    try {
      WebDriver driver = getDriver();
      if (driver != null) {
        driver.close();
      }
    } catch (RuntimeException e) {
      // At least we tried.
    }

    if (tempFs != null) {
      tempFs.deleteTemporaryFiles();
      tempFs.deleteBaseDir();
      tempFs = null;
    }
  }

  public WebDriver getDriver() {
    return driver;
  }

  public KnownElements getKnownElements() {
    return knownElements;
  }

  public Map getCapabilities() {
    return capabilities;
  }

  public void attachScreenshot(String base64EncodedImage) {
    this.base64EncodedImage = base64EncodedImage;
  }

  public String getAndClearScreenshot() {
    String temp = this.base64EncodedImage;
    base64EncodedImage = null;
    return temp;
  }

  private class BrowserCreator implements Callable {

    private final DriverFactory factory;
    private final Capabilities capabilities;
    private volatile Map describedCapabilities;
    private volatile SessionId sessionId;
    private volatile boolean isAndroid = false;

    BrowserCreator(DriverFactory factory, Capabilities capabilities) {
      this.factory = factory;
      this.capabilities = capabilities;
    }

    public EventFiringWebDriver call() throws Exception {
      WebDriver rawDriver = factory.newInstance(capabilities);
      Capabilities actualCapabilities = capabilities;
      if (rawDriver instanceof HasCapabilities) {
        actualCapabilities = ((HasCapabilities) rawDriver).getCapabilities();
        isAndroid = actualCapabilities.getPlatform().is(Platform.ANDROID);
      }
      describedCapabilities = getDescription(rawDriver, actualCapabilities);
      if (rawDriver instanceof RemoteWebDriver) {
        sessionId = ((RemoteWebDriver) rawDriver).getSessionId();
      } else {
        sessionId = new SessionId(UUID.randomUUID().toString());
      }
      return new EventFiringWebDriver(rawDriver);
    }

    public Map getCapabilityDescription() {
      return describedCapabilities;
    }

    public SessionId getSessionId() {
      return sessionId;
    }

    public boolean isAndroid() {
      return isAndroid;
    }

    private Map getDescription(WebDriver instance, Capabilities capabilities) {
      DesiredCapabilities caps = new DesiredCapabilities(capabilities.asMap());
      caps.setJavascriptEnabled(instance instanceof JavascriptExecutor);
      if (instance instanceof TakesScreenshot) {
        caps.setCapability(CapabilityType.TAKES_SCREENSHOT, true);
      }
      if (instance instanceof LocationContext) {
        caps.setCapability(CapabilityType.SUPPORTS_LOCATION_CONTEXT, true);
      }
      if (instance instanceof ApplicationCache) {
        caps.setCapability(CapabilityType.SUPPORTS_APPLICATION_CACHE, true);
      }
      if (instance instanceof NetworkConnection) {
        caps.setCapability(CapabilityType.SUPPORTS_NETWORK_CONNECTION, true);
      }
      if (instance instanceof WebStorage) {
        caps.setCapability(CapabilityType.SUPPORTS_WEB_STORAGE, true);
      }
      if (instance instanceof FindsByCssSelector) {
        caps.setCapability(CapabilityType.SUPPORTS_FINDING_BY_CSS, true);
      }
      if (instance instanceof Rotatable) {
        caps.setCapability(CapabilityType.ROTATABLE, true);
      }
      if (instance instanceof HasTouchScreen) {
        caps.setCapability(CapabilityType.HAS_TOUCHSCREEN, true);
      }
      //noinspection unchecked
      return (Map) caps.asMap();
    }
  }

  public SessionId getSessionId() {
    return sessionId;
  }

  public TemporaryFilesystem getTemporaryFileSystem() {
    return tempFs;
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy