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

com.nordstrom.automation.selenium.SeleniumConfig Maven / Gradle / Ivy

Go to download

Selenium3 Foundation is an automation framework designed to extend and enhance the capabilities provided by Selenium 3.0 (WebDriver).

There is a newer version: 1.0.4
Show newest version
package com.nordstrom.automation.selenium;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystemAlreadyExistsException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.Objects;
import javax.ws.rs.core.UriBuilder;
import org.apache.commons.configuration2.ex.ConfigurationException;
import org.apache.commons.configuration2.io.FileHandler;
import org.apache.commons.configuration2.io.FileLocationStrategy;
import org.apache.commons.configuration2.io.FileLocator;
import org.apache.commons.configuration2.io.FileLocatorUtils;
import org.apache.commons.configuration2.io.FileSystem;
import org.apache.commons.io.IOUtils;
import org.openqa.grid.internal.utils.configuration.GridHubConfiguration;
import org.openqa.grid.internal.utils.configuration.GridNodeConfiguration;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.SearchContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.nordstrom.automation.selenium.support.SearchContextWait;
import com.nordstrom.automation.settings.SettingsCore;
import com.nordstrom.common.file.PathUtils;

/**
 * This class declares settings and methods related to Selenium WebDriver and Grid configuration.
 * 
 * @see SettingsCore
 */
public class SeleniumConfig extends SettingsCore {
    
    private static final String SETTINGS_FILE = "settings.properties";
    private static final String JSON_HEAD = "{ \"capabilities\": [";
    private static final String JSON_TAIL = "] }";
    private static final String CAPS_PATTERN = "{\"browserName\": \"%s\"}";
    private static final Logger LOGGER = LoggerFactory.getLogger(SeleniumConfig.class);
    
    /** value: {"browserName": "phantomjs"} */
    private static final String DEFAULT_CAPS = String.format(CAPS_PATTERN, "phantomjs");
    /** value: 5555 */
    private static final Integer DEFAULT_NODE_PORT = Integer.valueOf(5555);
    
    /**
     * This enumeration declares the settings that enable you to control the parameters used by
     * Selenium Foundation.
     * 

* Each setting is defined by a constant name and System property key. Many settings also define * default values. Note that all of these settings can be overridden via the * {@code settings.properties} file and System property declarations. */ public enum SeleniumSettings implements SettingsCore.SettingsAPI { /** name: selenium.target.scheme
default: http */ TARGET_SCHEME("selenium.target.scheme", "http"), /** name: selenium.target.creds
default: {@code null} */ TARGET_CREDS("selenium.target.creds", null), /** name: selenium.target.host
default: localhost */ TARGET_HOST("selenium.target.host", "localhost"), /** name: selenium.target.port
default: {@code null} */ TARGET_PORT("selenium.target.port", null), /** name: selenium.target.path
default: / */ TARGET_PATH("selenium.target.path", "/"), /** name: selenium.hub.config
default: hubConfig.json */ HUB_CONFIG("selenium.hub.config", "hubConfig.json"), /** name: selenium.hub.host
default: {@code null} */ HUB_HOST("selenium.hub.host", null), /** name: selenium.hub.port
default: {@code null} */ HUB_PORT("selenuim.hub.port", null), /** name: selenium.node.config
default: nodeConfig.json */ NODE_CONFIG("selenium.node.config", "nodeConfig.json"), /** name: selenium.node.host
default: {@code null} */ NODE_HOST("selenium.node.host", null), /** name: selenium.node.port
default: 5555 */ NODE_PORT("selenium.node.port", "5555"), /** name: selenium.browser.name
default: {@code null} */ BROWSER_NAME("selenium.browser.name", null), /** name: selenium.browser.caps
default: {@link SeleniumConfig#DEFAULT_CAPS DEFAULT_CAPS} */ BROWSER_CAPS("selenium.browser.caps", DEFAULT_CAPS), /** name: selenium.timeout.pageload
default: 30 */ PAGE_LOAD_TIMEOUT("selenium.timeout.pageload", "30"), /** name: selenium.timeout.implied
default: 15 */ IMPLIED_TIMEOUT("selenium.timeout.implied", "15"), /** name: selenium.timeout.script
default: 30 */ SCRIPT_TIMEOUT("selenium.timeout.script", "30"), /** name: selenium.timeout.wait
default: 15 */ WAIT_TIMEOUT("selenium.timeout.wait", "15"), /** name: selenium.timeout.host
default: 30 */ HOST_TIMEOUT("selenium.timeout.host", "30"), /** name: google.dns.socket.host
default: 8.8.8.8 */ GOOGLE_DNS_SOCKET_HOST("google.dns.socket.host", "8.8.8.8"), //NOSONAR /** name: google.dns.socket.port
default: 10002 */ GOOGLE_DNS_SOCKET_PORT("google.dns.socket.port", "10002"); private String propertyName; private String defaultValue; SeleniumSettings(String propertyName, String defaultValue) { this.propertyName = propertyName; this.defaultValue = defaultValue; } @Override public String key() { return propertyName; } @Override public String val() { return defaultValue; } } /** * This enumeration provides easy access to the timeout intervals defined in {@link SeleniumSettings}. */ public enum WaitType { /** * purpose: The maximum allowed interval for a page to finish loading.
* setting: {@link SeleniumSettings#PAGE_LOAD_TIMEOUT page load timeout} */ PAGE_LOAD(SeleniumSettings.PAGE_LOAD_TIMEOUT), /** * purpose: The maximum amount of time the driver will search for an element.
* setting: {@link SeleniumSettings#IMPLIED_TIMEOUT implicit timeout} */ IMPLIED(SeleniumSettings.IMPLIED_TIMEOUT), /** * purpose: The maximum allowed interval for an asynchronous script to finish.
* setting: {@link SeleniumSettings#SCRIPT_TIMEOUT script timeout} */ SCRIPT(SeleniumSettings.SCRIPT_TIMEOUT), /** * purpose: The maximum amount of time to wait for a search context event.
* setting: {@link SeleniumSettings#WAIT_TIMEOUT wait timeout} */ WAIT(SeleniumSettings.WAIT_TIMEOUT), /** * purpose: The maximum amount of time to wait for a Grid server to launch.
* setting: {@link SeleniumSettings#HOST_TIMEOUT host timeout} */ HOST(SeleniumSettings.HOST_TIMEOUT); private SeleniumSettings timeoutSetting; private Long timeoutInterval; WaitType(SeleniumSettings timeoutSetting) { this.timeoutSetting = timeoutSetting; } /** * Get the timeout interval for this wait type * * @return wait type timeout interval */ public long getInterval() { return getInterval(getConfig()); } /** * Get the timeout interval for this wait type.
* * @param config {@link SeleniumConfig} object to interrogate * @return wait type timeout interval */ public long getInterval(SeleniumConfig config) { if (timeoutInterval == null) { Objects.requireNonNull(config, "[config] must be non-null"); timeoutInterval = config.getLong(timeoutSetting.key()); } return timeoutInterval; } /** * Get a search context wait object for the specified context * * @param context context for which timeout is needed * @return {@link SearchContextWait} object for the specified context */ public SearchContextWait getWait(SearchContext context) { return new SearchContextWait(context, getInterval()); } } private static final SeleniumConfig seleniumConfig; static { try { seleniumConfig = new SeleniumConfig(); } catch (ConfigurationException | IOException e) { throw new RuntimeException("Failed to instantiate settings", e); } } private URI targetUri; private String nodeConfigPath; private GridNodeConfiguration nodeConfig; private String[] nodeArgs; private String hubConfigPath; private GridHubConfiguration hubConfig; private String[] hubArgs; private Capabilities browserCaps; /** * Instantiate a Selenium Foundation configuration object. * * @throws ConfigurationException If a failure is encountered while initializing this configuration object. * @throws IOException If a failure is encountered while reading from a configuration input stream. */ public SeleniumConfig() throws ConfigurationException, IOException { super(SeleniumSettings.class); } /** * Get the Selenium configuration object. * * @return Selenium configuration object */ public static SeleniumConfig getConfig() { return seleniumConfig; } /** * Get the configured target URI as specified by its component parts. *

* NOTE: The target URI is assembled from following components: * {@link SeleniumSettings#TARGET_SCHEME scheme}, {@link SeleniumSettings#TARGET_CREDS credentials}, * {@link SeleniumSettings#TARGET_HOST host}, {@link SeleniumSettings#TARGET_PORT port}, and * {@link SeleniumSettings#TARGET_PATH base path} * * @return assembled target URI */ public URI getTargetUri() { if (targetUri == null) { UriBuilder builder = UriBuilder.fromPath(getString(SeleniumSettings.TARGET_PATH.key())) .scheme(getString(SeleniumSettings.TARGET_SCHEME.key())) .host(getString(SeleniumSettings.TARGET_HOST.key())); String creds = getString(SeleniumSettings.TARGET_CREDS.key()); if (creds != null) { builder.userInfo(creds); } String port = getString(SeleniumSettings.TARGET_PORT.key()); if (port != null) { builder.port(Integer.parseInt(port)); } targetUri = builder.build(); } return targetUri; } /** * Get the path to the Selenium Grid node configuration. * * @return Selenium Grid node configuration path */ private String getNodeConfigPath() { if (nodeConfigPath == null) { nodeConfigPath = getConfigPath(getString(SeleniumSettings.NODE_CONFIG.key())); LOGGER.debug("nodeConfigPath = {}", nodeConfigPath); } return nodeConfigPath; } /** * Get the Selenium Grid node configuration. * * @return Selenium Grid node configuration */ public GridNodeConfiguration getNodeConfig() { if (nodeConfig == null) { nodeConfig = GridNodeConfiguration.loadFromJSON(getNodeConfigPath()); nodeConfig = resolveNodeSettings(nodeConfig); } return nodeConfig; } /** * Get the arguments needed to launch a local Selenium Grid node. * * @return array of node launch arguments */ public String[] getNodeArgs() { if (nodeArgs == null) { String configPath = getNodeConfigPath(); GridNodeConfiguration config = getNodeConfig(); nodeArgs = new String[] {"-role", "node", "-nodeConfig", configPath, "-host", config.host, "-port", config.port.toString(), "-hub", config.hub, "-servlet", "org.openqa.grid.web.servlet.LifecycleServlet"}; } return Arrays.copyOf(nodeArgs, nodeArgs.length); } /** * Resolve Selenium Grid node settings for host, port, and hub. * * @param nodeConfig node configuration with unresolved settings * @return node configuration with resolved settings */ private GridNodeConfiguration resolveNodeSettings(GridNodeConfiguration nodeConfig) { String nodeHost = getString(SeleniumSettings.NODE_HOST.key()); if (nodeHost != null) { nodeConfig.host = nodeHost; } if (nodeConfig.host == null) { nodeConfig.host = getLocalHost(); } nodeConfig.port = getInteger(SeleniumSettings.NODE_PORT.key(), DEFAULT_NODE_PORT); nodeConfig.hub = "http://" + getHubConfig().host + ":" + getHubConfig().port + "/grid/register/"; return nodeConfig; } /** * Get the path to the Selenium Grid hub configuration. * * @return Selenium Grid hub configuration path */ private String getHubConfigPath() { if (hubConfigPath == null) { hubConfigPath = getConfigPath(getString(SeleniumSettings.HUB_CONFIG.key())); LOGGER.debug("hubConfigPath = {}", hubConfigPath); } return hubConfigPath; } /** * Get the Selenium Grid hub configuration. * * @return Selenium Grid hub configuration */ public GridHubConfiguration getHubConfig() { if (hubConfig == null) { hubConfig = GridHubConfiguration.loadFromJSON(getHubConfigPath()); hubConfig = resolveHubSettings(hubConfig); } return hubConfig; } /** * Get the arguments needed to launch a local Selenium Grid hub. * * @return array of hub launch arguments */ public String[] getHubArgs() { if (hubArgs == null) { String configPath = getHubConfigPath(); GridHubConfiguration config = getHubConfig(); hubArgs = new String[] {"-role", "hub", "-hubConfig", configPath, "-host", config.host, "-port", config.port.toString()}; } return Arrays.copyOf(hubArgs, hubArgs.length); } /** * Resolve Selenium Grid hub settings for host and port. * * @param hubConfig node configuration with unresolved settings * @return hub configuration with resolved settings */ private GridHubConfiguration resolveHubSettings(GridHubConfiguration hubConfig) { String hubHost = getString(SeleniumSettings.HUB_HOST.key()); if (hubHost != null) { hubConfig.host = hubHost; } if (hubConfig.host == null) { hubConfig.host = getLocalHost(); } Integer hubPort = getInteger(SeleniumSettings.HUB_PORT.key(), null); if (hubPort != null) { hubConfig.port = hubPort; } return hubConfig; } /** * Get Internet protocol (IP) address for the machine we're running on. * * @return IP address for the machine we're running on (a.k.a. - 'localhost') */ private String getLocalHost() { String host = getString(SeleniumSettings.GOOGLE_DNS_SOCKET_HOST.key()); int port = getInt(SeleniumSettings.GOOGLE_DNS_SOCKET_PORT.key()); try (final DatagramSocket socket = new DatagramSocket()) { // use Google Public DNS to discover preferred local IP socket.connect(InetAddress.getByName(host), port); return socket.getLocalAddress().getHostAddress(); } catch (SocketException | UnknownHostException eaten) { LOGGER.warn("Unable to get 'localhost' IP address: {}", eaten.getMessage()); return "localhost"; } } /** * Convert the configured browser specification from JSON to {@link Capabilities} object. * * @return {@link Capabilities} object for the configured browser specification */ public Capabilities getBrowserCaps() { if (browserCaps == null) { String jsonStr = null; String nameStr = getString(SeleniumSettings.BROWSER_NAME.key()); if (nameStr != null) { InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(nameStr + "Caps.json"); if (inputStream != null) { try { jsonStr = IOUtils.toString(inputStream, StandardCharsets.UTF_8); } catch (IOException eaten) { LOGGER.warn("Unable to get browser configuration file contents: {}", eaten.getMessage()); } } if (jsonStr == null) { jsonStr = String.format(CAPS_PATTERN, nameStr); } } if (jsonStr == null) { jsonStr = getString(SeleniumSettings.BROWSER_CAPS.key()); } JsonObject json = new JsonParser().parse(JSON_HEAD + jsonStr + JSON_TAIL).getAsJsonObject(); GridNodeConfiguration config = GridNodeConfiguration.loadFromJSON(json); browserCaps = config.capabilities.get(0); } return browserCaps; } /** * Get the path to the specified configuration file. * * @param path configuration file path (absolute, relative, or simple filename) * @return resolved absolute path of specified file; 'null' if file not found */ private static String getConfigPath(String path) { FileHandler handler = new FileHandler(); handler.setPath(path); FileLocator locator = handler.getFileLocator(); FileSystem fileSystem = FileLocatorUtils.DEFAULT_FILE_SYSTEM; FileLocationStrategy strategy = FileLocatorUtils.DEFAULT_LOCATION_STRATEGY; URL url = strategy.locate(fileSystem, locator); if (url != null) { try { URI uri = url.toURI(); if ("jar".equals(uri.getScheme())) { try { FileSystems.newFileSystem(uri, Collections.emptyMap()); } catch (FileSystemAlreadyExistsException eaten) { LOGGER.warn("Specified file system already exists: {}", eaten.getMessage()); } String outputDir = PathUtils.getBaseDir(); File outputFile = new File(outputDir, path); Path outputPath = outputFile.toPath(); if (!outputPath.toFile().exists()) { Files.copy(Paths.get(uri), outputPath); } uri = outputPath.toUri(); } File file = new File(uri); return file.getAbsolutePath(); } catch (URISyntaxException eaten) { LOGGER.warn("Invalid URL returned by file locator: {}", eaten.getMessage()); } catch (IOException eaten) { LOGGER.warn("Failed to construct file system or extract configuration file: {}", eaten.getMessage()); } } return null; } @Override public String getSettingsPath() { return SETTINGS_FILE; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy