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

com.paypal.selion.configuration.Config Maven / Gradle / Ivy

/*-------------------------------------------------------------------------------------------------------------------*\
|  Copyright (C) 2014-2016 PayPal                                                                                     |
|                                                                                                                     |
|  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.paypal.selion.configuration;

import static com.google.common.base.Preconditions.checkArgument;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.configuration.XMLConfiguration;
import org.apache.commons.lang.StringUtils;
import org.openqa.selenium.remote.CommandExecutor;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.ISuite;
import org.testng.ITestContext;

import com.paypal.selion.internal.platform.grid.MobileNodeType;
import com.paypal.selion.logger.SeLionLogger;
import com.paypal.selion.platform.grid.EventListener;
import com.paypal.selion.platform.grid.browsercapabilities.DefaultCapabilitiesBuilder;
import com.paypal.selion.platform.html.support.events.ElementEventListener;

/**
 * A configuration object that contains properties needed throughout SeLion. These options can be configured via the
 * TestNG formatted testng-suite.xml file. The testng-suite.xml file is used to override the default settings, so only
 * the data you want to modify from default values should be specified in the suite configuration file. Any data not
 * found in the testng-suite.xml file will use the built-in defaults. 
* * Note that some configuration properties are global-only in scope. Any value set for these applies to all suite tests * executed (possibly in parallel). Properties that must be specified for global use are specified below with * "(GLOBAL)". These properties cannot be used in SeLionLocal configuration instances. The others can be specified for * Global or Local (test) scope. * * *
 * <!-- If parameter is empty string or omitted, please see defaults -->
 * 
 * <!-- SELENIUM CONFIGURATION -->
 * 
 * <!-- optional, defaults to "" or localhost when runLocally is true (GLOBAL) -->
 * <parameter name="seleniumhost" value="" />
 * <!-- optional, defaults to 4444 (GLOBAL) -->
 * <parameter name="seleniumport" value="" />
 * <!-- optional, defaults to *firefox  -->
 * <parameter name="browser" value="*firefox" />
 * <!-- optional, defaults to false  (GLOBAL) -->
 * <parameter name="runLocally" value="true" />
 * <!-- optional, turns automatic screen shots for click handlers on/off, defaults to true (GLOBAL) -->
 * <parameter name="autoScreenShot" value="true" />
 * <!-- optional, used when runLocally is true, defaults to 'default' -->
 * <parameter name="profileName" value="SeleniumProfile" />     
 * 
 * <!-- SELION FILES LOCATION -->
 * 
 * <!-- optional, default to selionFiles (GLOBAL) -->
 * <parameter name="basedir" value=""  />
 * <!-- optional, default to ${selionFiles.basedir}/selionLogs (GLOBAL) -->
 * <parameter name="workDir"  value="" />
 * 
* * All other configuration settings can be set in a similar fashion.
* *
* Also, system properties and/or environment variables can also be used to configure SeLion. The values used should * always start with "SELION_" and end with the value you would like the set. The variable equals the * {@link ConfigProperty} variable name. So, for instance, to set the execution_timeout to "180000", the following * system property or environment variable should be set prior to initializing SeLion: * *
 * SELION_EXECUTION_TIMEOUT = 180000
 * 
* *

The order of initialization for Configuration values is

*
    *
  1. System properties (Highest Precedence) *
  2. Environment variables
  3. *
  4. From a testng-suite.xml file
  5. *
  6. SeLion defaults
  7. *
*/ public final class Config { private static volatile XMLConfiguration xmlConfig; private Config() { // Utility class. So hide the constructor } static XMLConfiguration getConfig() { if (xmlConfig != null) { return xmlConfig; } initConfig(); return xmlConfig; } /** * Parses suite parameters and generates SeLion Config object * * @param suite * list of parameters from configuration file within <suite></suite> tag */ public synchronized static void initConfig(ISuite suite) { SeLionLogger.getLogger().entering(suite); Map initialValues = new HashMap(); for (ConfigProperty prop : ConfigProperty.values()) { String paramValue = suite.getParameter(prop.getName()); // empty values may be valid for some properties if (paramValue != null) { initialValues.put(prop, paramValue); } } initConfig(initialValues); SeLionLogger.getLogger().exiting(); } /** * Parses configuration file and extracts values for test environment * * @param context * list of parameters includes values within <suite></suite> and <test></test> * tags */ public synchronized static void initConfig(ITestContext context) { SeLionLogger.getLogger().entering(context); Map initialValues = new HashMap(); Map testParams = context.getCurrentXmlTest().getLocalParameters(); if (!testParams.isEmpty()) { for (ConfigProperty prop : ConfigProperty.values()) { // Check if a selionConfig param resides in the String newValue = testParams.get(prop.getName()); // accept param values that are empty in initialValues. if (newValue != null) { initialValues.put(prop, newValue); } } } ConfigManager.addConfig(context.getCurrentXmlTest().getName(), new LocalConfig(initialValues)); SeLionLogger.getLogger().exiting(); } /** * Reads and parses configuration file Initializes the configuration, reloading all data */ public synchronized static void initConfig() { SeLionLogger.getLogger().entering(); Map initialValues = new HashMap(); initConfig(initialValues); SeLionLogger.getLogger().exiting(); } /** * Prints SeLion Config Values */ public static void printSeLionConfigValues() { SeLionLogger.getLogger().entering(); StringBuilder builder = new StringBuilder("SeLion configuration: {"); boolean isFirst = true; for (ConfigProperty configProperty : ConfigProperty.values()) { if (!isFirst) { builder.append(", "); } builder.append(String.format("(%s: %s)", configProperty, Config.getConfig().getString(configProperty.getName()))); isFirst = false; } builder.append("}\n"); SeLionLogger.getLogger().info(builder.toString()); SeLionLogger.getLogger().exiting(); } private static void loadInitialValues() { for (ConfigProperty configProps : ConfigProperty.values()) { xmlConfig.setProperty(configProps.getName(), configProps.getDefaultValue()); } } private static void loadValuesFromUser(Map initialValues) { if (!initialValues.isEmpty()) { for (Entry eachConfig : initialValues.entrySet()) { xmlConfig.setProperty(eachConfig.getKey().getName(), eachConfig.getValue()); } } } private static void loadValuesFromEnvironment() { final String PREFIX = "SELION_"; for (ConfigProperty configProps : ConfigProperty.values()) { String envValue = System.getenv(PREFIX + configProps.name()); if (StringUtils.isNotBlank(envValue)) { xmlConfig.setProperty(configProps.getName(), envValue); } // Now load system properties variables (if defined). String sysValue = System.getProperty(PREFIX + configProps.name()); if (StringUtils.isNotBlank(sysValue)) { xmlConfig.setProperty(configProps.getName(), sysValue); } } } /** * Initializes the configuration, reloading all data while adding the supplied initialValues to the * configuration. * * @param initialValues * The initial set of values used to configure SeLion */ public synchronized static void initConfig(Map initialValues) { SeLionLogger.getLogger().entering(initialValues); // only do this if the global config is not already initialized. if (xmlConfig == null) { xmlConfig = new XMLConfiguration(); // don't auto throw, let each config value decide xmlConfig.setThrowExceptionOnMissing(false); // because we can config on the fly, don't auto-save xmlConfig.setAutoSave(false); // Set defaults loadInitialValues(); } /* * otherwise, update the global config */ // Load in our supplied values (if defined) loadValuesFromUser(initialValues); // Load in environment & system variables (if defined) loadValuesFromEnvironment(); // Init Selenium configuration boolean runLocally = xmlConfig.getBoolean(ConfigProperty.SELENIUM_RUN_LOCALLY.getName()); if (runLocally) { xmlConfig.setProperty(ConfigProperty.SELENIUM_HOST.getName(), "localhost"); } SeLionLogger.getLogger().exiting(); } /** * Returns a configuration property String value based off the {@link ConfigProperty} * * @param configProperty * The configuration property value to return * @return The configuration property String value */ public static String getConfigProperty(ConfigProperty configProperty) { checkArgument(configProperty != null, "Config property cannot be null"); return Config.getConfig().getString(configProperty.getName()); } /** * Returns a configuration property String value based off the {@link ConfigProperty} * * @param configProperty * String Property Name * @return The configuration property String values */ public static String getConfigProperty(String configProperty) { checkArgument(configProperty != null, "Config property cannot be null"); return Config.getConfig().getString(configProperty); } /** * Returns a configuration property int value based off the {@link ConfigProperty} * * @param configProperty * The configuration property value to return * @return The configuration property int value */ public static int getIntConfigProperty(ConfigProperty configProperty) { checkArgument(configProperty != null, "Config property cannot be null"); return Config.getConfig().getInt(configProperty.getName()); } /** * Returns a configuration property boolean value based off the {@link ConfigProperty} * * @param configProperty * The configuration property value to return * @return The configuration property boolean value */ public static boolean getBoolConfigProperty(ConfigProperty configProperty) { checkArgument(configProperty != null, "Config property cannot be null"); return Config.getConfig().getBoolean(configProperty.getName()); } /** * Checks if property exists in the configuration * * @param propertyName * String Property Name * @return true or false */ public static boolean checkPropertyExists(String propertyName) { checkArgument(propertyName != null, "Property name cannot be null"); return Config.getConfig().containsKey(propertyName); } /** * Sets a SeLion configuration value. This is useful when you want to override or set a setting. * * @param configProperty * The configuration element to set * @param configPropertyValue * The value of the configuration element * @throws IllegalArgumentException * If problems occur during the set */ public static synchronized void setConfigProperty(ConfigProperty configProperty, String configPropertyValue) { checkArgument(configProperty != null, "Config property cannot be null."); checkArgument(configPropertyValue != null, "Config property value cannot be null."); Config.getConfig().setProperty(configProperty.getName(), configPropertyValue); } /** * SeLion config properties */ public enum ConfigProperty { // Settings specific to SeLion /** * Automatically take screen shots.
*/ AUTO_SCREEN_SHOT("autoScreenShot", "true", true), /** * Selenium host might be localhost or another location where a Selenium server is running. Used when * {@link ConfigProperty#SELENIUM_RUN_LOCALLY} is false.
* Default is set to "" */ SELENIUM_HOST("seleniumhost", "", true), /** * Selenium port, any port where Selenium is running. Used when {@link ConfigProperty#SELENIUM_RUN_LOCALLY} * is false
* Default is set to 4444 */ SELENIUM_PORT("seleniumport", "4444", true), /** * The firefox profile that is to be used for local/remote runs.
* Use this when you would like to have firefox work with your custom firefox profile.
* You can either specify the name of the profile or you can specify the directory location of your firefox * profile.
* The framework internally first assumes it to be a profile name. If that assumption fails we fail-over to * assuming it to be the firefox profile directory. If that also fails we will work with an anonymous firefox * profile.
*
* WARNING:
* Please be aware that if your firefox profile directory is very huge (above ~10 MB) then there are chances * that it can crash your local JVM (be it your desktop or your fusion build job). */ SELENIUM_FIREFOX_PROFILE("firefoxProfile", "", false), /** * The name of the JSON file that contains the configuration customization info needed for saucelabs. By * default, the configurations specified at Sauce labs * Configurations are applicable. */ SELENIUM_SAUCELAB_GRID_CONFIG_FILE("saucelabGridConfigFile", "", true), /** * The path to the chromedriver executable on the local machine. This parameter is taken into consideration for * local runs involving the Google Chrome browser. */ SELENIUM_CHROMEDRIVER_PATH("chromeDriverPath", "", true), /** * The path to the PhantomJS executable on the local machine. This parameter is taken into consideration for * local runs involving the PhantomJS browser. */ SELENIUM_PHANTOMJS_PATH("phantomjsPath", "", true), /** * The path to the IEDriver executable on the local machine. This parameter is taken into consideration for * local runs involving the IE browser. */ SELENIUM_IEDRIVER_PATH("ieDriverPath", "", true), /** * The path to the EdgeDriver executable on the local machine. This parameter is taken into consideration for * local runs involving the Edge browser. */ SELENIUM_EDGEDRIVER_PATH("edgeDriverPath", "", true), /** * Use this parameter to set the user agent for firefox when working with Mobile version. This parameter should * be set in conjunction with the parameter {@link ConfigProperty#BROWSER} */ SELENIUM_USERAGENT("userAgent", "", false), /** * Use this parameter to set the Proxy server name to be used. */ SELENIUM_PROXY_HOST("proxyServerHost", "", true), /** * Use this parameter to set the Proxy server port to be used. */ SELENIUM_PROXY_PORT("proxyServerPort", "", true), /** * Use this parameter to indicate if your remote runs are to be run against the sauce lab grid or against your * own grid. This flag is required when running against the Sauce lab grid because we need to disable fetching * of the WebDriver node IP and Port details. */ SELENIUM_USE_SAUCELAB_GRID("useSauceLabGrid", "false", true), /** * Use this parameter to execute mobile test cases using respective mobile driver. The valid values are * {@link MobileNodeType} */ MOBILE_NODE_TYPE("mobileNodeType", "", false), /** * Use this parameter to provide SeLion with a custom capabilities provider. The value for this parameter * would be the fully qualified class name which is a sub-class of {@link DefaultCapabilitiesBuilder}. * If more than one custom capabilities providers are required, please separate their fully qualified class * names with commas. */ SELENIUM_CUSTOM_CAPABILITIES_PROVIDER("customCapabilities", "", true), /** * Use this parameter to provide SeLion with a custom listener which can be plugged into {@link RemoteWebDriver} * {@link CommandExecutor}. If the fully qualified class implements {@link EventListener} then SeLion will * invoke the custom implementation provided by you as and when the relevant events happen. If more than one * custom listeners are required, please separate the fully qualified class names with commas. */ SELENIUM_WEBDRIVER_EVENT_LISTENER("webDriverEventListener", "", true), /** * Flip this parameter to true if you would like a browser to be spawned locally on your machine * and run automation tests there. Default is set to false which means your tests are always going to be * run against a Remote Grid environment as pointed to by {@link ConfigProperty#SELENIUM_HOST}. */ SELENIUM_RUN_LOCALLY("runLocally", "false", true), /** * This parameter represents the folder which would contain the mobile app. This parameter is currently only * useful for local runs. This is the folder from which applications would be searched for by SeLion when it * comes to mobile automation in local runs. Please ensure that all the built applications reside in this * folder. If no value is provided, SeLion assumes that the application is available under a directory named * "Applications" in the current working directory. */ MOBILE_APP_FOLDER("mobileAppFolder", System.getProperty("user.dir") + File.separator + "Applications", true), /** * This parameter represents the name of the app that is to be spawned. Specifying the name of the mobile app * should suffice. * * Note: Use of this parameter is not recommended for test suites which test different mobile * applications or different versions of the same mobile applications. */ MOBILE_APP_NAME("mobileAppName", "", false), /** * This parameter represents the fully qualified path of the app that is to be spawned. For app exist in the * local disk this should be an absolute path, for app exist in the remote location it should be http URL and * for app exist in sauce cloud it can be sauce storage like "sauce-storage:testApp.apk". */ MOBILE_APP_PATH("appPath", "", false), /** * This parameter represents the language to be used. By default it is always English represented * as en */ MOBILE_APP_LANGUAGE("mobileAppLanguage", "en", false), /** * This parameter represents the locale to be used. By default it is always US English represented * as en_US */ MOBILE_APP_LOCALE("mobileAppLocale", "en_US", false), /** * This parameter represents device. */ MOBILE_DEVICE("mobileDevice", "", false), /** * This parameter represents the device type. */ MOBILE_DEVICE_TYPE("mobileDeviceType", "", false), /** * Use this parameter to provide SeLion with a custom element listener that implements * {@link ElementEventListener}. SeLion will invoke the custom implementation when the relevant events happen. * If more than one custom listeners is needed, please separate the fully qualified class names with commas. */ ELEMENT_EVENT_LISTENER("elementEventListener", "", true), /** * This parameter is used to pass SauceLabs user name */ SAUCELAB_USER_NAME("sauceUserName", "", true), /** * This parameter is used to pass SauceLabs user name */ SAUCELAB_API_KEY("sauceApiKey", "", true), /** * This parameter is used to pass SauceLabs parent tunnel user id */ SAUCELAB_TUNNEL_USER_ID("sauceTunnelUserId", "", true), /** * This parameter is used to pass SauceLabs tunnel identifier */ SAUCELAB_TUNNEL_ID("sauceTunnelId", "", true), /** * Directory with page asset files to read info about GUI controls from.
* Default is set to GUIData in resources */ GUI_DATA_DIR("GUIDataDir", "GUIData", true), /** * Site will show country used for tests.
* Default is set to US */ SITE_LOCALE("siteLocale", "US", false), /** * mobile platform test suite is designed for (iOS or Android)
* Default is set to undefined */ MOBILE_PLATFORM("mobilePlatform", "undefined", false), /** * Browser specified by user.
* Default is set to firefox */ BROWSER("browser", "*firefox", false), /** * version specified by user when working with custom browser needs.
*/ BROWSER_CAPABILITY_VERSION("version", "", false), /** * Turn this flag ON to see GUI actions such as loading a URL, click/setting text etc., being logged into the * test reports that get generated by SeLion. * */ ENABLE_GUI_LOGGING("enableGUILogging", "false", true), /** * The base directory for SeLion files
* Default is set to selionFiles */ BASE_DIR("baseDir", "selionFiles", true), /** * The work directory of SeLion */ WORK_DIR("workDir", BASE_DIR.defaultValue + "/selionWorkDir", true), /** * platform is specified by user.
* Default is set to ANY Supporting values are: ANDROID, ANY, LINUX, MAC, UNIX, VISTA, WINDOWS, XP. */ BROWSER_CAPABILITY_PLATFORM("platform", "ANY", false), /** * Should javascript capability be enabled on the browser for the AUT. By default javascript will be enabled on * the client browser, but this flag can be used to toggle this setting. */ BROWSER_CAPABILITY_SUPPORT_JAVASCRIPT("enableJavaScript", "true", false), /** * Set the Height of the Browser Window
* Should be a whole number
*/ BROWSER_HEIGHT("browserHeight", "", false), /** * Set the Width of the Browser Window
* Should be a whole number
*/ BROWSER_WIDTH("browserWidth", "", false), /** * Timeout for an execution command, in milliseconds.
*
* Used in SeLion to configure Selenium timeouts
* Default is set to 120000 */ EXECUTION_TIMEOUT("executionTimeout", "120000", false), /** * Automatically attempt to download various webdriver dependencies (chromedriver, etc) if they are not * available.
* Default is set to false */ DOWNLOAD_DEPENDENCIES("downloadDependencies", "false", true), /** * Timeout for downloading dependencies, in milliseconds.
*
* Used in SeLion to configure the download timeout
* Default is set to 600000 */ DOWNLOAD_TIMEOUT("downloadTimeout", "600000", true), /** * Automatically log pages source code.
* Used in conjunction with {@link ConfigProperty#AUTO_SCREEN_SHOT}.
* Default is set to true */ LOG_PAGES("logPages", "true", true), /** * Maximum duration of a session duration in milliseconds. Session will be forcefully terminated if it takes * longer.
* The value of this parameter is used as the value of sessionTimeout for ios-driver and selendroid.
* This configuration affects LOCAL EXECUTION RUNS only i.e., when {@link ConfigProperty#SELENIUM_RUN_LOCALLY} * is set to true.
* The unit is milliseconds.
* Default is set to 1800000 milliseconds. */ MOBILE_DRIVER_SESSION_TIMEOUT("sessionTimeout", "1800000", false), /** * Selendroid Server port to use.
* Defaults to the value used by Selendroid (8080) */ SELENDROID_SERVER_PORT("selendroidServerPort", "8080", true), /** * Device Serial to use.
* Default is selected automatically by Selendroid */ SELENDROID_DEVICE_SERIAL("selendroidDeviceSerial", "", true), /** * Force Reinstall the Selendroid Server and AUT.
* Default is set to false */ SELENDROID_SERVER_FORCE_REINSTALL("selendroidServerForceReinstall", "false", true), /** * Timeout that will be used to start Android emulators.
* The value for this parameter is used as the value of timeoutEmulatorStart for selendroid.
* This configuration affects LOCAL EXECUTION RUNS only i.e., when {@link ConfigProperty#SELENIUM_RUN_LOCALLY} * is set to true.
* The unit is milliseconds.
* Default is set to 300000 milliseconds.
*/ SELENDROID_EMULATOR_START_TIMEOUT("timeoutEmulatorStart", "300000", false), /** * Maximum time in milliseconds to wait for the selendroid-server to come up on the device.
* The value for this parameter is used as the value of serverStartTimeout for selendroid.
* This configuration affects LOCAL EXECUTION RUNS only i.e., when {@link ConfigProperty#SELENIUM_RUN_LOCALLY} * is set to true.
* The unit is milliseconds.
* Default is set to 20000 milliseconds.
*/ SELENDROID_SERVER_START_TIMEOUT("serverStartTimeout", "20000", false), /** * To print debug info (about Browser/Selenium Version/Client OS) for user.
* Default is set to true */ PRINT_DEBUG_INFO("printDebugInfo", "true", true); private String name; private String defaultValue; private boolean isGlobalScopeOnly; ConfigProperty(String name, String defaultValue, boolean globalScopeOnly) { checkArgument(name != null, "Config property name can not be null."); checkArgument(defaultValue != null, "Config property default value cannot be null."); this.name = name; this.defaultValue = defaultValue; this.isGlobalScopeOnly = globalScopeOnly; } /** * Returns the name of this configuration property * * @return The name of this configuration property */ public String getName() { return this.name; } /** * Returns the default value for this configuration property * * @return The default String value for this configuration property */ public String getDefaultValue() { return this.defaultValue; } /** * Find the Enum for the specified property name. * * @return The ConfigProperty Enum for the specified name if found or null if not found. */ public static ConfigProperty find(String name) { for (ConfigProperty prop : ConfigProperty.values()) { if (prop.getName().equals(name)) { return prop; } } return null; } /** * Answer if the property is a global only property (i.e only Suite scope param / System / Env Property) * * @return true if the property is only supported as a global property. */ public boolean isGlobalScopeOnly() { return this.isGlobalScopeOnly; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy