diff --git a/src/main/java/io/appium/java_client/remote/AndroidMobileCapabilityType.java b/src/main/java/io/appium/java_client/remote/AndroidMobileCapabilityType.java new file mode 100644 index 000000000..524940827 --- /dev/null +++ b/src/main/java/io/appium/java_client/remote/AndroidMobileCapabilityType.java @@ -0,0 +1,209 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * 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 io.appium.java_client.remote; + + +import org.openqa.selenium.remote.CapabilityType; + +/** + * The list of Android-specific capabilities + * Read: https://github.com/appium/appium/blob/1.5/docs/en/writing-running-appium/caps.md#android-only + */ +public interface AndroidMobileCapabilityType extends CapabilityType { + /** + * Activity name for the Android activity you want to launch from your package. This often needs to be preceded + * by a . (e.g., .MainActivity instead of MainActivity) + */ + String APP_ACTIVITY = "appActivity"; + + /** + * Java package of the Android app you want to run + */ + String APP_PACKAGE = "appPackage"; + + /** + * Activity name for the Android activity you want to wait for + */ + String APP_WAIT_ACTIVITY = "appWaitActivity"; + + /** + * Java package of the Android app you want to wait for + */ + String APP_WAIT_PACKAGE = "appWaitPackage"; + + /** + * Timeout in seconds while waiting for device to become ready + */ + String DEVICE_READY_TIMEOUT = "deviceReadyTimeout"; + + /** + * Fully qualified instrumentation class. Passed to -w in adb shell am instrument -e coverage true -w + */ + String ANDROID_COVERAGE = "androidCoverage"; + + /** + * (Chrome and webview only) Enable Chromedriver's performance logging (default false) + */ + String ENABLE_PERFORMANCE_LOGGING = "enablePerformanceLogging"; + + /** + * Timeout in seconds used to wait for a device to become ready after booting + */ + String ANDROID_DEVICE_READY_TIMEOUT = "androidDeviceReadyTimeout"; + + /** + * Port used to connect to the ADB server (default 5037) + */ + String ADB_PORT = "adbPort"; + + /** + * Devtools socket name. Needed only when tested app is a Chromium embedding browser. + * The socket is open by the browser and Chromedriver connects to it as a devtools client. + */ + String ANDROID_DEVICE_SOCKET = "androidDeviceSocket"; + + /** + * Name of avd to launch + */ + String AVD = "avd"; + + /** + * How long to wait in milliseconds for an avd to launch and connect to ADB (default 120000) + */ + String AVD_LAUNCH_TIMEOUT = "avdLaunchTimeout"; + + /** + * How long to wait in milliseconds for an avd to finish its boot animations (default 120000) + */ + String AVD_READY_TIMEOUT = "avdReadyTimeout"; + + /** + * Additional emulator arguments used when launching an avd + */ + String AVD_ARGS = "avdArgs"; + + /** + * Use a custom keystore to sign apks, default false + */ + String USE_KEYSTORE = "useKeystore"; + + /** + * Path to custom keystore, default ~/.android/debug.keystore + */ + String KEYSTORE_PATH = "keystorePath"; + + /** + * Password for custom keystore + */ + String KEYSTORE_PASSWORD = "keystorePassword"; + + /** + * Alias for key + */ + String KEY_ALIAS = "keyAlias"; + + /** + * Password for key + */ + String KEY_PASSWORD = "keyPassword"; + + /** + * The absolute local path to webdriver executable (if Chromium embedder provides its own webdriver, + * it should be used instead of original chromedriver bundled with Appium) + */ + String CHROMEDRIVER_EXECUTABLE = "chromedriverExecutable"; + + /** + * Amount of time to wait for Webview context to become active, in ms. Defaults to 2000 + */ + String AUTO_WEBVIEW_TIMEOUT = "autoWebviewTimeout"; + + /** + * Intent action which will be used to start activity (default android.intent.action.MAIN) + */ + String INTENT_ACTION = "intentAction"; + + /** + * Intent category which will be used to start activity (default android.intent.category.LAUNCHER) + */ + String INTENT_CATEGORY = "intentCategory"; + + /** + * Flags that will be used to start activity (default 0x10200000) + */ + String INTENT_FLAGS = "intentFlags"; + + /** + * Additional intent arguments that will be used to start activity. See Intent arguments: + * http://developer.android.com/tools/help/adb.html#IntentSpec + */ + String OPTIONAL_INTENT_ARGUMENTS = "optionalIntentArguments"; + + /** + * Doesn't stop the process of the app under test, before starting the app using adb. + * If the app under test is created by another anchor app, setting this false, + * allows the process of the anchor app to be still alive, during the start of the test app using adb. + * In other words, with dontStopAppOnReset set to true, we will not include the -S flag in the adb shell am start call. + * With this capability omitted or set to false, we include the -S flag. Default false + */ + String DONT_STOP_APP_ON_RESET = "dontStopAppOnReset"; + + /** + * Enable Unicode input, default false + */ + String UNICODE_KEYBOARD = "unicodeKeyboard"; + + /** + * Reset keyboard to its original state, after running Unicode tests with unicodeKeyboard capability. + * Ignored if used alone. Default false + */ + String RESET_KEYBOARD = "resetKeyboard"; + + /** + * Skip checking and signing of app with debug keys, will work only with + * UiAutomator and not with selendroid, default false + */ + String NO_SIGN = "noSign"; + + /** + * Calls the setCompressedLayoutHierarchy() uiautomator function. This capability can speed up test execution, + * since Accessibility commands will run faster ignoring some elements. The ignored elements will not be findable, + * which is why this capability has also been implemented as a toggle-able setting as well as a capability. + * Defaults to false + */ + String IGNORE_UNIMPORTANT_VIEWS = "ignoreUnimportantViews"; + + /** + * Disables android watchers that watch for application not responding and application crash, + * this will reduce cpu usage on android device/emulator. This capability will work only with + * UiAutomator and not with selendroid, default false + */ + String DISABLE_ANDROID_WATCHERS = "disableAndroidWatchers"; + + /** + * Allows passing chromeOptions capability for ChromeDriver. For more information see chromeOptions: + * https://sites.google.com/a/chromium.org/chromedriver/capabilities + */ + String CHROME_OPTIONS = "chromeOptions"; + + /** + * Kill ChromeDriver session when moving to a non-ChromeDriver webview. Defaults to false + */ + String RECREATE_CHROME_DRIVER_SESSIONS = "recreateChromeDriverSessions"; + + String SELENDROID_PORT = "selendroidPort"; +} diff --git a/src/main/java/io/appium/java_client/remote/IOSMobileCapabilityType.java b/src/main/java/io/appium/java_client/remote/IOSMobileCapabilityType.java new file mode 100644 index 000000000..6004cff44 --- /dev/null +++ b/src/main/java/io/appium/java_client/remote/IOSMobileCapabilityType.java @@ -0,0 +1,150 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * 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 io.appium.java_client.remote; + +import org.openqa.selenium.remote.CapabilityType; + +/** + * The list of iOS-specific capabilities + * Read: https://github.com/appium/appium/blob/1.5/docs/en/writing-running-appium/caps.md#ios-only + */ +public interface IOSMobileCapabilityType extends CapabilityType { + + /** + * (Sim-only) Calendar format to set for the iOS Simulator + */ + String CALENDAR_FORMAT = "calendarFormat"; + + /** + * Bundle ID of the app under test. Useful for starting an app on a real device or for using other caps which require + * the bundle ID during test startup. To run a test on a real device using the bundle ID, + * you may omit the 'app' capability, but you must provide 'udid'. + */ + String BUNDLE_ID = "bundleId"; + + /** + * Amount of time in ms to wait for instruments before assuming it hung and failing the session + */ + String LAUNCH_TIMEOUT = "launchTimeout"; + + /** + * (Sim-only) Force location services to be either on or off. Default is to keep current sim setting. + */ + String LOCATION_SERVICES_ENABLED = "locationServicesEnabled"; + + /** + * (Sim-only) Set location services to be authorized or not authorized for app via plist, so that location services + * alert doesn't pop up. Default is to keep current sim setting. Note that + * if you use this setting you MUST also use the bundleId capability to send in your app's bundle ID. + */ + String LOCATION_SERVICES_AUTHORIZED = "locationServicesAuthorized"; + + /** + * Accept all iOS alerts automatically if they pop up. This includes privacy access permission alerts + * (e.g., location, contacts, photos). Default is false. + */ + String AUTO_ACCEPT_ALERTS = "autoAcceptAlerts"; + + /** + * Dismiss all iOS alerts automatically if they pop up. + * This includes privacy access permission alerts (e.g., + * location, contacts, photos). Default is false. + */ + String AUTO_DISMISS_ALERTS = "autoDismissAlerts"; + + /** + * Use native intruments lib (ie disable instruments-without-delay). + */ + String NATIVE_INSTRUMENTS_LIB = "nativeInstrumentsLib"; + + /** + * (Sim-only) Enable "real", non-javascript-based web taps in Safari. + * Default: false. + * Warning: depending on viewport size/ratio this might not accurately tap an element + */ + String NATIVE_WEB_TAP = "nativeWebTap"; + + /** + * (Sim-only) (>= 8.1) Initial safari url, default is a local welcome page + */ + String SAFARI_INITIAL_URL = "safariInitialUrl"; + + /** + * (Sim-only) Allow javascript to open new windows in Safari. Default keeps current sim setting + */ + String SAFARI_ALLOW_POPUPS = "safariAllowPopups"; + + /** + * (Sim-only) Prevent Safari from showing a fraudulent website warning. Default keeps current sim setting. + */ + String SAFARI_IGNORE_FRAUD_WARNING = "safariIgnoreFraudWarning"; + + /** + * (Sim-only) Whether Safari should allow links to open in new windows. Default keeps current sim setting. + */ + String SAFARI_OPEN_LINKS_IN_BACKGROUND = "safariOpenLinksInBackground"; + + /** + * (Sim-only) Whether to keep keychains (Library/Keychains) when appium session is started/finished + */ + String KEEP_KEY_CHAINS = "keepKeyChains"; + + /** + * Where to look for localizable strings. Default en.lproj + */ + String LOCALIZABLE_STRINGS_DIR = "localizableStringsDir"; + + /** + * Arguments to pass to the AUT using instruments + */ + String PROCESS_ARGUMENTS = "processArguments"; + + /** + * The delay, in ms, between keystrokes sent to an element when typing. + */ + String INTER_KEY_DELAY = "interKeyDelay"; + + /** + * Whether to show any logs captured from a device in the appium logs. Default false + */ + String SHOW_IOS_LOG = "showIOSLog"; + + /** + * strategy to use to type test into a test field. Simulator default: oneByOne. Real device default: grouped + */ + String SEND_KEY_STRATEGY = "sendKeyStrategy"; + + /** + * Max timeout in sec to wait for a screenshot to be generated. default: 10 + */ + String SCREENSHOT_WAIT_TIMEOUT = "screenshotWaitTimeout"; + + /** + * The ios automation script used to determined if the app has been launched, + * by default the system wait for the page source not to be empty. The result must be a boolean + */ + String WAIT_FOR_APP_SCRIPT = "waitForAppScript"; + + /** + * Number of times to send connection message to remote debugger, to get webview. Default: 8 + */ + String WEBVIEW_CONNECT_RETRIES = "webviewConnectRetries"; + + /** + * The display name of the application under test. Used to automate backgrounding the app in iOS 9+. + */ + String APP_NAME = "appName"; +} diff --git a/src/main/java/io/appium/java_client/remote/MobileCapabilityType.java b/src/main/java/io/appium/java_client/remote/MobileCapabilityType.java index 0eebc7f88..2266a6760 100644 --- a/src/main/java/io/appium/java_client/remote/MobileCapabilityType.java +++ b/src/main/java/io/appium/java_client/remote/MobileCapabilityType.java @@ -18,31 +18,144 @@ import org.openqa.selenium.remote.CapabilityType; +/** + * The list of common capabilities + * Read: https://github.com/appium/appium/blob/1.5/docs/en/writing-running-appium/caps.md#appium-server-capabilities + */ public interface MobileCapabilityType extends CapabilityType { - + + /** + * Which automation engine to use + */ String AUTOMATION_NAME = "automationName"; + /** + * Which mobile OS platform to use + */ String PLATFORM_NAME = "platformName"; + + /** + * Mobile OS version + */ String PLATFORM_VERSION = "platformVersion"; + /** + * The kind of mobile device or emulator to use + */ String DEVICE_NAME = "deviceName"; + /** + * How long (in seconds) Appium will wait for a new command from the + * client before assuming the client quit and ending the session + */ String NEW_COMMAND_TIMEOUT = "newCommandTimeout"; + + /** + * Deprecated. Moved to {@link AndroidMobileCapabilityType#DEVICE_READY_TIMEOUT} + */ + @Deprecated String DEVICE_READY_TIMEOUT = "deviceReadyTimeout"; + + /** + * Deprecated. Moved to {@link IOSMobileCapabilityType#LAUNCH_TIMEOUT} + */ + @Deprecated String LAUNCH_TIMEOUT = "launchTimeout"; + /** + * The absolute local path or remote http URL to an .ipa or .apk file, or a .zip containing one of these. + * Appium will attempt to install this app binary on the appropriate device first. + * Note that this capability is not required for Android if you specify appPackage and appActivity + * capabilities (see below). Incompatible with browserName. + */ String APP = "app"; + + /** + * Name of mobile web browser to automate. Should be an empty string if automating an app instead. + */ + String BROWSER_NAME = "browserName"; + + + /** + * Deprecated. Moved to {@link AndroidMobileCapabilityType#APP_PACKAGE} + */ + @Deprecated String APP_PACKAGE = "appPackage"; + + /** + * Deprecated. Moved to {@link AndroidMobileCapabilityType#APP_ACTIVITY} + */ + @Deprecated String APP_ACTIVITY = "appActivity"; + + /** + * Deprecated. Moved to {@link AndroidMobileCapabilityType#APP_WAIT_ACTIVITY} + */ + @Deprecated String APP_WAIT_ACTIVITY = "appWaitActivity"; + + /** + * Deprecated. Moved to {@link AndroidMobileCapabilityType#APP_WAIT_PACKAGE} + */ + @Deprecated String APP_WAIT_PACKAGE = "appWaitPackage"; + + /** + * Deprecated. Moved to {@link AndroidMobileCapabilityType#DONT_STOP_APP_ON_RESET} + */ + @Deprecated String DONT_STOP_APP_ON_RESET = "dontStopAppOnReset"; - String SELENDROID_PORT = "selendroidPort"; + + /** + * Unique device identifier of the connected physical device + */ String UDID = "udid"; - //Sauce-specific + /** + * Sauce-specific + */ String APPIUM_VERSION = "appiumVersion"; - - // capability to accept accento on keyboard + + /** + * Deprecated. Moved to {@link AndroidMobileCapabilityType#UNICODE_KEYBOARD} + */ + @Deprecated String UNICODE_KEYBOARD = "unicodeKeyboard"; + + /** + * (Sim/Emu-only) Language to set for the simulator / emulator + */ + String LANGUAGE = "language"; + + /** + * (Sim/Emu-only) Locale to set for the simulator / emulator + */ + String LOCALE = "locale"; + + /** + * (Sim/Emu-only) start in a certain orientation + */ + String ORIENTATION = "orientation"; + + /** + * Move directly into Webview context. Default false + */ + String AUTO_WEBVIEW = "autoWebview"; + + /** + * Don't reset app state before this session. Default false + */ + String NO_RESET = "noReset"; + + /** + * (iOS) Delete the entire simulator folder. (Android) Reset app state by uninstalling app instead of clearing app data. + * On Android, this will also remove the app after the session is complete. Default false + */ + String FULL_RESET = "fullReset"; + + @Deprecated + /** + * Deprecated. Moved to {@link AndroidMobileCapabilityType#SELENDROID_PORT} + */ + String SELENDROID_PORT = "selendroidPort"; } diff --git a/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java b/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java index 01b0f431e..72e1e629a 100644 --- a/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java +++ b/src/main/java/io/appium/java_client/service/local/AppiumServiceBuilder.java @@ -18,12 +18,15 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import io.appium.java_client.remote.AndroidMobileCapabilityType; +import io.appium.java_client.remote.MobileCapabilityType; import io.appium.java_client.service.local.flags.ServerArgument; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.validator.routines.InetAddressValidator; import org.openqa.selenium.Platform; import org.openqa.selenium.os.CommandLine; +import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.service.DriverService; import java.io.*; @@ -50,6 +53,14 @@ public final class AppiumServiceBuilder extends DriverService.Builder PATH_CAPABILITIES = new ArrayList() { + { + add(AndroidMobileCapabilityType.KEYSTORE_PATH); + add(AndroidMobileCapabilityType.CHROMEDRIVER_EXECUTABLE); + add(MobileCapabilityType.APP); + } + }; + private static final String APPIUM_FOLDER = "appium"; private static final String BIN_FOLDER = "bin"; @@ -73,12 +84,12 @@ public final class AppiumServiceBuilder extends DriverService.Builder serverArguments = new HashMap<>(); private File appiumJS; private String ipAddress = DEFAULT_LOCAL_IP_ADDRESS; private File npmScript; private File getNodeJSExecutable; + private DesiredCapabilities capabilities; //The first starting is slow sometimes on some //environment @@ -232,6 +243,27 @@ public AppiumServiceBuilder withArgument(ServerArgument argument, String value){ return this; } + /** + * @param capabilities is an instance of {@link org.openqa.selenium.remote.DesiredCapabilities} + * @return the self-reference + */ + public AppiumServiceBuilder withCapabilities(DesiredCapabilities capabilities) { + if (this.capabilities == null) { + this.capabilities = capabilities; + } + else { + DesiredCapabilities desiredCapabilities = new DesiredCapabilities(); + desiredCapabilities.merge(this.capabilities).merge(capabilities); + this.capabilities = desiredCapabilities; + } + return this; + } + + /** + * @param appiumJS an executable appium.js (1.4.x and lower) or + * main.js (1.5.x and higher) + * @return the self-reference + */ public AppiumServiceBuilder withAppiumJS(File appiumJS){ this.appiumJS = appiumJS; return this; @@ -276,6 +308,84 @@ void checkAppiumJS(){ this.appiumJS = findNodeInCurrentFileSystem(); } + + private String parseCapabilitiesIfWindows() { + String result = StringUtils.EMPTY; + + if (capabilities != null) { + Map capabilitiesMap = (Map) capabilities.asMap(); + Set> entries = capabilitiesMap.entrySet(); + + for (Map.Entry entry : entries) { + Object value = entry.getValue(); + + if (value == null) { + continue; + } + + if (String.class.isAssignableFrom(value.getClass())) { + if (PATH_CAPABILITIES.contains(entry.getKey())) { + value = "\\\"" + String.valueOf(value).replace("\\", "/") + "\\\""; + } + else { + value = "\\\"" + String.valueOf(value) + "\\\""; + } + } else { + value = String.valueOf(value); + } + + String key = "\\\"" + String.valueOf(entry.getKey()) + "\\\""; + if (StringUtils.isBlank(result)) { + result = key + ": " + value; + } else { + result = result + ", " + key + ": " + value; + } + } + } + + return "{" + result + "}"; + } + + private String parseCapabilitiesIfUNIX() { + String result = StringUtils.EMPTY; + + if (capabilities != null) { + Map capabilitiesMap = (Map) capabilities.asMap(); + Set> entries = capabilitiesMap.entrySet(); + + for (Map.Entry entry : entries) { + Object value = entry.getValue(); + + if (value == null) { + continue; + } + + if (String.class.isAssignableFrom(value.getClass())) { + value = "\"" + String.valueOf(value) + "\""; + } else { + value = String.valueOf(value); + } + + String key = "\"" + String.valueOf(entry.getKey()) + "\""; + if (StringUtils.isBlank(result)) { + result = key + ": " + value; + } else { + result = result + ", " + key + ": " + value; + } + } + } + + return "{" + result + "}"; + } + + @SuppressWarnings("unchecked") + private String parseCapabilities() { + if (Platform.getCurrent().is(Platform.WINDOWS)) { + return parseCapabilitiesIfWindows(); + } + return parseCapabilitiesIfUNIX(); + } + @Override protected ImmutableList createArgs() { List argList = new ArrayList<>(); @@ -314,6 +424,11 @@ protected ImmutableList createArgs() { argList.add(value); } + if (capabilities != null) { + argList.add("--default-capabilities"); + argList.add(parseCapabilities()); + } + return new ImmutableList.Builder().addAll(argList).build(); } diff --git a/src/main/java/io/appium/java_client/service/local/flags/AndroidServerFlag.java b/src/main/java/io/appium/java_client/service/local/flags/AndroidServerFlag.java index 1ae137be5..ec6b80462 100644 --- a/src/main/java/io/appium/java_client/service/local/flags/AndroidServerFlag.java +++ b/src/main/java/io/appium/java_client/service/local/flags/AndroidServerFlag.java @@ -18,9 +18,6 @@ /** * Here is the list of Android specific server arguments. -* All flags are optional, but some are required in conjunction with certain others. -* The full list is available here: http://appium.io/slate/en/master/?ruby#appium-server-arguments -* Android specific arguments are marked by (Android-only) */ public enum AndroidServerFlag implements ServerArgument{ /** @@ -29,50 +26,82 @@ public enum AndroidServerFlag implements ServerArgument{ */ BOOTSTRAP_PORT_NUMBER("--bootstrap-port"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Java package of the Android app you want to run (e.g., * com.example.android.MyApp). Sample: * --app-pkg com.example.android.MyApp */ + @Deprecated PACKAGE("--app-pkg"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Activity name for the Android activity you want to launch * from your package (e.g., MainActivity). Sample: * --app-activity MainActivity */ + @Deprecated ACTIVITY("--app-activity"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Package name for the Android activity you want to wait for * (e.g., com.example.android.MyApp). Sample: * --app-wait-package com.example.android.MyApp */ + @Deprecated APP_WAIT_PACKAGE("--app-wait-package"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Activity name for the Android activity you want to wait * for (e.g., SplashActivity). Sample: * --app-wait-activity SplashActivity */ + @Deprecated APP_WAIT_ACTIVITY("--app-wait-activity"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Fully qualified instrumentation class. * Passed to -w in adb shell am instrument -e coverage true -w. Sample: * --android-coverage com.my.Pkg/com.my.Pkg.instrumentation.MyInstrumentation */ + @Deprecated ANDROID_COVERAGE("--android-coverage"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Name of the avd to launch. Sample: * --avd @default */ + @Deprecated AVD("--avd"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Additional emulator arguments to launch the avd. Sample: * --avd-args -no-snapshot-load */ + @Deprecated AVD_ARGS("--avd-args"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Timeout in seconds while waiting for device to become * ready. Sample: * --device-ready-timeout 5 */ + @Deprecated DEVICE_READY_TIMEOUT("--device-ready-timeout"), /** * Local port used for communication with Selendroid. Sample: @@ -80,57 +109,106 @@ public enum AndroidServerFlag implements ServerArgument{ */ SELENDROID_PORT("--selendroid-port"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * When set the keystore will be used to sign apks. Default: false */ + @Deprecated USE_KEY_STORE("--use-keystore"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Path to keystore. Sample: * --keystore-path /Users/user/.android/debug.keystore */ + @Deprecated KEY_STORE_PATH("--keystore-path"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Password to keystore. Default: android */ + @Deprecated KEY_STORE_PASSWORD("--keystore-password"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Key alias. Default: androiddebugkey */ + @Deprecated KEY_ALIAS("--key-alias"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Key password. Default: android */ + @Deprecated KEY_PASSWORD("--key-password"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Intent action which will be used to start activity. Default: * android.intent.action.MAIN. Sample: --intent-action android.intent.action.MAIN */ + @Deprecated INTENT_ACTION("--intent-action"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Intent category which will be used to start activity. Default: android.intent.category.LAUNCHER. * Sample:s --intent-category android.intent.category.APP_CONTACTS */ + @Deprecated INTENT_CATEGORY("--intent-category"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Flags that will be used to start activity. Default: 0x10200000. * Sample: --intent-flags 0x10200000 */ + @Deprecated INTENT_FLAGS("--intent-flags"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Additional intent arguments that will be used to start * activity. Default: null. * Sample: --intent-args 0x10200000 */ + @Deprecated INTENT_ARGUMENTS("--intent-args"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * When included, refrains from stopping the app before * restart. Default: false */ + @Deprecated DO_NOT_STOP_APP_ON_RESET("--dont-stop-app-on-reset"), /** * If set, prevents Appium from killing the adb server * instance. Default: false */ - SUPPRESS_ADB_KILL_SERVER("--suppress-adb-kill-server"); + SUPPRESS_ADB_KILL_SERVER("--suppress-adb-kill-server"), + + /** + * Port upon which ChromeDriver will run. Sample: --chromedriver-port 9515 + */ + CHROME_DRIVER_PORT("--chromedriver-port"), + /** + * ChromeDriver executable full path + */ + CHROME_DRIVER_EXECUTABLE("--chromedriver-executable"); private final String arg; diff --git a/src/main/java/io/appium/java_client/service/local/flags/GeneralServerFlag.java b/src/main/java/io/appium/java_client/service/local/flags/GeneralServerFlag.java index 5c0aeb545..05134b0e8 100644 --- a/src/main/java/io/appium/java_client/service/local/flags/GeneralServerFlag.java +++ b/src/main/java/io/appium/java_client/service/local/flags/GeneralServerFlag.java @@ -16,26 +16,34 @@ package io.appium.java_client.service.local.flags; + /** * Here is the list of common Appium server arguments. - * All flags are optional, but some are required in conjunction with certain others. - * The full list is available here: @link http://appium.io/slate/en/master/?ruby#appium-server-arguments */ public enum GeneralServerFlag implements ServerArgument{ /** * Enter REPL mode */ SHELL("--shell"), + + @Deprecated /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * IOS: abs path to simulator-compiled .app file or the bundle_id of the desired target on device; Android: abs path to .apk file. * Sample: --app /abs/path/to/my.app */ APP("--app"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Unique device identifier of the connected physical device. * Sample: * --udid 1adsf-sdfas-asdf-123sdf */ + @Deprecated UIID("--udid"), /** * callback IP Address (default: same as address). @@ -52,9 +60,13 @@ public enum GeneralServerFlag implements ServerArgument{ */ SESSION_OVERRIDE("--session-override"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Don’t reset app state between sessions (IOS: don’t delete app plist files; Android: don’t uninstall app before new session). * Default: false */ + @Deprecated NO_RESET("--no-reset"), /** * Pre-launch the application before allowing the first session (Requires –app and, for Android, –app-pkg and –app-activity). @@ -87,34 +99,62 @@ public enum GeneralServerFlag implements ServerArgument{ */ WEB_HOOK("--webhook"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Name of the mobile device to use. * Sample: --device-name iPhone Retina (4-inch), Android Emulator */ + @Deprecated DEVICE_NAME("--device-name"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Name of the mobile platform: iOS, Android, or FirefoxOS * Sample: --platform-name iOS */ + @Deprecated PLATFORM_NAME("--platform-name"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Version of the mobile platform. Sample: --platform-version 7.1 */ + @Deprecated PLATFORM_VERSION("--platform-version"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Name of the automation tool: Appium or Selendroid. Sample: --automation-name Appium */ + @Deprecated AUTOMATION_NAME("--automation-name"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Name of the mobile browser: Safari or Chrome. Sample: --browser-name Safari */ + @Deprecated BROWSER_NAME("--browser-name"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Language for the iOS simulator / Android Emulator. Sample: --language en */ + @Deprecated LANGUAGE("--language"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Locale for the iOS simulator / Android Emulator. Sample: --locale en_US */ + @Deprecated LOCALE("--locale"), /** * Configuration JSON file to register Appium with selenium grid. Sample: @@ -129,11 +169,20 @@ public enum GeneralServerFlag implements ServerArgument{ * Port for robot. Sample: --robot-port 4242 */ ROBOT_PORT("--robot-port"), + + @Deprecated /** + * This flag IS deprecated because it is moved to + * {@link AndroidServerFlag#CHROME_DRIVER_PORT} + * * Port upon which ChromeDriver will run. Sample: --chromedriver-port 9515 */ CHROME_DRIVER_PORT("--chromedriver-port"), + @Deprecated /** + * This flag IS deprecated because it is moved to + * {@link AndroidServerFlag#CHROME_DRIVER_EXECUTABLE} + * * ChromeDriver executable full path */ CHROME_DRIVER_EXECUTABLE("--chromedriver-executable"), @@ -146,9 +195,13 @@ public enum GeneralServerFlag implements ServerArgument{ */ NO_PERMS_CHECKS( "--no-perms-check"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * The default command timeout for the server to use for all sessions. Will * still be overridden by newCommandTimeout cap. Default: 60 */ + @Deprecated COMMAND_TIMEOUT("--command-timeout"), /** * Cause sessions to fail if desired caps are sent in that Appium does not diff --git a/src/main/java/io/appium/java_client/service/local/flags/IOSServerFlag.java b/src/main/java/io/appium/java_client/service/local/flags/IOSServerFlag.java index 40d7a285f..0c337ba7d 100644 --- a/src/main/java/io/appium/java_client/service/local/flags/IOSServerFlag.java +++ b/src/main/java/io/appium/java_client/service/local/flags/IOSServerFlag.java @@ -18,15 +18,16 @@ /** * Here is the list of iOS specific server arguments. -* All flags are optional, but some are required in conjunction with certain others. -* The full list is available here: http://appium.io/slate/en/master/?ruby#appium-server-arguments -* iOS specific arguments are marked by (IOS-only) */ public enum IOSServerFlag implements ServerArgument{ /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * the relative path of the dir where Localizable.strings file * resides. Default: en.lproj. Sample: --localizable-strings-dir en.lproj */ + @Deprecated LOCALIZABLE_STRING_PATH("--localizable-strings-dir"), /** * absolute path to compiled .ipa file. Sample: --ipa /abs/path/to/my.ipa @@ -38,13 +39,21 @@ public enum IOSServerFlag implements ServerArgument{ */ BACK_END_RETRIES("--backend-retries"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * how long in ms to wait for Instruments to launch. Default: 90000 */ + @Deprecated LAUNCH_TIMEOUT("--launch-timeout"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * IOS has a weird built-in unavoidable delay. We patch this in * appium. If you do not want it patched, pass in this flag. Default: false */ + @Deprecated USE_NATIVE_INSTRUMENTS("--native-instruments-lib"), /** * Use the safari app. Default: false @@ -65,15 +74,23 @@ public enum IOSServerFlag implements ServerArgument{ */ FORCE_IPAD_SIMULATOR("--force-ipad"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Calendar format for the iOS simulator. * Default: null * Sample: --calendar-format gregorian */ + @Deprecated CALENDAR_FORMAT("--calendar-format"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * use LANDSCAPE or PORTRAIT to initialize all requests to this * orientation. Sample: --orientation LANDSCAPE */ + @Deprecated ORIENTATION("--orientation"), /** * .tracetemplate file to use with Instruments. Sample: --tracetemplate /Users/me/Automation.tracetemplate @@ -84,17 +101,29 @@ public enum IOSServerFlag implements ServerArgument{ */ CUSTOM_INSTRUMENTS_PATH("--instruments"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * if set, the iOS simulator log will be written to the console. Default: false */ + @Deprecated SHOW_SIMULATOR_LOG("--show-sim-log"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * if set, the iOS system log will be written to the console. Default: false */ + @Deprecated SHOW_IOS_LOG("--show-ios-log"), /** + * This flag IS deprecated since appium node 1.5.x. It will be removed in the next release. + * Be careful. + * * Whether to keep keychains (Library/Keychains) when reset app * between sessions. Default: false */ + @Deprecated KEEP_KEYCHAINS("--keep-keychains"), /** * Xcode 6 has a bug on some platforms where a certain simulator can only be diff --git a/src/test/java/io/appium/java_client/localserver/ServerBuilderTest.java b/src/test/java/io/appium/java_client/localserver/ServerBuilderTest.java index e57519294..09601b110 100644 --- a/src/test/java/io/appium/java_client/localserver/ServerBuilderTest.java +++ b/src/test/java/io/appium/java_client/localserver/ServerBuilderTest.java @@ -1,37 +1,32 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * See the NOTICE file distributed with this work for additional - * information regarding copyright ownership. - * 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 io.appium.java_client.localserver; + +import io.appium.java_client.remote.AndroidMobileCapabilityType; +import io.appium.java_client.remote.MobileCapabilityType; import io.appium.java_client.service.local.AppiumDriverLocalService; import io.appium.java_client.service.local.AppiumServiceBuilder; import io.appium.java_client.service.local.flags.GeneralServerFlag; +import org.apache.commons.validator.routines.InetAddressValidator; import org.junit.BeforeClass; import org.junit.Test; import org.openqa.selenium.Platform; +import org.openqa.selenium.remote.DesiredCapabilities; -import java.io.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.util.Enumeration; import java.util.Properties; - -import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; public class ServerBuilderTest { private static Properties properties; + private static String testIP; @BeforeClass public static void beforeClass() throws Exception{ @@ -40,6 +35,27 @@ public static void beforeClass() throws Exception{ properties = new Properties(); properties.load(fileInput); fileInput.close(); + + for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) + { + NetworkInterface intf = en.nextElement(); + for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) + { + InetAddress inetAddress = enumIpAddr.nextElement(); + if (!inetAddress.isLoopbackAddress()) + { + InetAddressValidator validator = InetAddressValidator.getInstance(); + testIP = inetAddress.getHostAddress().toString(); + if (validator.isValid(testIP)) { + break; + } + testIP = null; + } + } + if (testIP != null) { + break; + } + } } private static File findCustomNode(){ @@ -55,86 +71,158 @@ private static File findCustomNode(){ @Test public void checkAbilityToBuildDefaultService(){ - AppiumDriverLocalService.buildDefaultService(); + AppiumDriverLocalService service = AppiumDriverLocalService.buildDefaultService(); + try { + service.start(); + assertEquals(true, service.isRunning()); + } + finally { + service.stop(); + } } @Test - public void checkAbilityToBuildServiceWithDefinedParametersAndNodeSetInProperties(){ + public void checkAbilityToBuildServiceUsingNodeDefinedInProperties(){ + AppiumDriverLocalService service = null; try { String definedNode = findCustomNode().getAbsolutePath(); System.setProperty(AppiumServiceBuilder.APPIUM_PATH, definedNode); - AppiumDriverLocalService.buildService(new AppiumServiceBuilder().withIPAddress("127.0.0.1"). - usingPort(4000).withArgument(GeneralServerFlag.SESSION_OVERRIDE,"")); + service = AppiumDriverLocalService.buildDefaultService(); + service.start(); + assertEquals(true, service.isRunning()); } finally { + if (service != null) { + service.stop(); + } System.clearProperty(AppiumServiceBuilder.APPIUM_PATH); } } @Test - public void checkAbilityToStartServiceOnAFreePort(){ + public void checkAbilityToBuildServiceUsingNodeDefinedExplicitly(){ + AppiumDriverLocalService service = null; try { - String definedNode = findCustomNode().getAbsolutePath(); - System.setProperty(AppiumServiceBuilder.APPIUM_PATH, definedNode); - AppiumDriverLocalService service = AppiumDriverLocalService.buildService(new AppiumServiceBuilder().withIPAddress("127.0.0.1"). - usingAnyFreePort().withArgument(GeneralServerFlag.SESSION_OVERRIDE)); + File node = findCustomNode(); + service = new AppiumServiceBuilder().withAppiumJS(node).build(); service.start(); assertEquals(true, service.isRunning()); - service.stop(); } finally { - System.clearProperty(AppiumServiceBuilder.APPIUM_PATH); + if (service != null) { + service.stop(); + } } } @Test - public void checkAbilityToBuildServiceWithDefinedParametersAndExternallyDefinedNode(){ - File definedNode = findCustomNode(); - AppiumDriverLocalService.buildService(new AppiumServiceBuilder().withAppiumJS(definedNode).withIPAddress("127.0.0.1"). - usingPort(4000).withArgument(GeneralServerFlag.SESSION_OVERRIDE,"")); + public void checkAbilityToStartServiceOnAFreePort() { + AppiumDriverLocalService service = null; + try { + service = new AppiumServiceBuilder().usingAnyFreePort().build(); + service.start(); + assertEquals(true, service.isRunning()); + } + finally { + if (service != null) { + service.stop(); + } + } } @Test - public void checkStartingOfDefaultService(){ - AppiumDriverLocalService service = AppiumDriverLocalService.buildDefaultService(); - service.start(); - assertEquals(true, service.isRunning()); - service.stop(); + public void checkAbilityToStartServiceUsingNonLocalhostIP() throws Exception { + AppiumDriverLocalService service = null; + try { + service = new AppiumServiceBuilder().withIPAddress(testIP).build(); + service.start(); + assertEquals(true, service.isRunning()); + } + finally { + if (service != null) { + service.stop(); + } + } } @Test - public void checkStartingOfDefaultServiceWithNonDefaultArguments(){ - AppiumDriverLocalService service = new AppiumServiceBuilder(). - withArgument(GeneralServerFlag.LOG_NO_COLORS).withIPAddress("127.0.0.1").build(); - service.start(); - assertEquals(true, service.isRunning()); - service.stop(); + public void checkAbilityToStartServiceUsingFlags() throws Exception { + AppiumDriverLocalService service = null; + try { + service = new AppiumServiceBuilder().withArgument(GeneralServerFlag.CALLBACK_ADDRESS, testIP). + withArgument(GeneralServerFlag.SESSION_OVERRIDE).withArgument(GeneralServerFlag.PRE_LAUNCH).build(); + service.start(); + assertEquals(true, service.isRunning()); + } + finally { + if (service != null) { + service.stop(); + } + } } @Test - public void checkStartingOfTheServiceDefinedByProperty(){ + public void checkAbilityToStartServiceUsingCapabilities() throws Exception { + File appDir = new File("src/test/java/io/appium/java_client"); + File app = new File(appDir, "ApiDemos-debug.apk"); + + + File pageFactoryDir = new File("src/test/java/io/appium/java_client/pagefactory_tests"); + File chrome = new File(pageFactoryDir, "chromedriver.exe"); + + DesiredCapabilities capabilities = new DesiredCapabilities(); + capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android"); + capabilities.setCapability(MobileCapabilityType.FULL_RESET, true); + capabilities.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 60); + capabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "io.appium.android.apis"); + capabilities.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".view.WebView1"); + capabilities.setCapability(MobileCapabilityType.APP, app.getAbsolutePath()); + capabilities.setCapability(AndroidMobileCapabilityType.CHROMEDRIVER_EXECUTABLE, chrome.getAbsolutePath()); + + AppiumDriverLocalService service = null; try { - String definedNode = findCustomNode().getAbsolutePath(); - System.setProperty(AppiumServiceBuilder.APPIUM_PATH, definedNode); - AppiumDriverLocalService service = AppiumDriverLocalService.buildService(new AppiumServiceBuilder().withIPAddress("127.0.0.1"). - usingPort(4000).withArgument(GeneralServerFlag.SESSION_OVERRIDE)); + service = new AppiumServiceBuilder().withCapabilities(capabilities).build(); service.start(); assertEquals(true, service.isRunning()); - service.stop(); } finally { - System.clearProperty(AppiumServiceBuilder.APPIUM_PATH); + if (service != null) { + service.stop(); + } } } @Test - public void checkStartingOfTheServiceDefinedExternally(){ - File definedNode = findCustomNode(); - AppiumDriverLocalService service = AppiumDriverLocalService.buildService(new AppiumServiceBuilder().withAppiumJS(definedNode).withIPAddress("127.0.0.1"). - usingPort(4000).withArgument(GeneralServerFlag.SESSION_OVERRIDE,"")); - service.start(); - assertEquals(true, service.isRunning()); - service.stop(); + public void checkAbilityToStartServiceUsingCapabilitiesAndFlags() throws Exception { + File appDir = new File("src/test/java/io/appium/java_client"); + File app = new File(appDir, "ApiDemos-debug.apk"); + + + File pageFactoryDir = new File("src/test/java/io/appium/java_client/pagefactory_tests"); + File chrome = new File(pageFactoryDir, "chromedriver.exe"); + + DesiredCapabilities capabilities = new DesiredCapabilities(); + capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android"); + capabilities.setCapability(MobileCapabilityType.FULL_RESET, true); + capabilities.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 60); + capabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "io.appium.android.apis"); + capabilities.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".view.WebView1"); + capabilities.setCapability(MobileCapabilityType.APP, app.getAbsolutePath()); + capabilities.setCapability(AndroidMobileCapabilityType.CHROMEDRIVER_EXECUTABLE, chrome.getAbsolutePath()); + + AppiumDriverLocalService service = null; + try { + service = new AppiumServiceBuilder().withArgument(GeneralServerFlag.CALLBACK_ADDRESS, testIP). + withArgument(GeneralServerFlag.SESSION_OVERRIDE).withArgument(GeneralServerFlag.PRE_LAUNCH). + withCapabilities(capabilities).build(); + service.start(); + assertEquals(true, service.isRunning()); + } + finally { + if (service != null) { + service.stop(); + } + } } @Test @@ -210,4 +298,26 @@ public void checkAbilityToStartAndShutDownFewServices() throws Exception{ assertTrue(!service3.isRunning()); assertTrue(!service4.isRunning()); } + + @Test + public void checkAbilityToStartServiceWithLogFile() throws Exception { + AppiumDriverLocalService service = null; + File rootLogDir = new File("target/"); + File log = new File(rootLogDir, "Log.txt"); + log.createNewFile(); + try { + service = new AppiumServiceBuilder().withLogFile(log).build(); + service.start(); + assertEquals(true, log.exists()); + assertEquals(true, log.length() > 0); + } + finally { + if (log.exists()) { + log.delete(); + } + if (service != null) { + service.stop(); + } + } + } } diff --git a/src/test/java/io/appium/java_client/localserver/StartingAppLocallyTest.java b/src/test/java/io/appium/java_client/localserver/StartingAppLocallyTest.java index c12463237..4a69df1c9 100644 --- a/src/test/java/io/appium/java_client/localserver/StartingAppLocallyTest.java +++ b/src/test/java/io/appium/java_client/localserver/StartingAppLocallyTest.java @@ -19,9 +19,7 @@ import io.appium.java_client.MobileElement; import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.ios.IOSDriver; -import io.appium.java_client.remote.AutomationName; -import io.appium.java_client.remote.MobileCapabilityType; -import io.appium.java_client.remote.MobilePlatform; +import io.appium.java_client.remote.*; import io.appium.java_client.service.local.AppiumServiceBuilder; import io.appium.java_client.service.local.flags.GeneralServerFlag; import org.junit.Test; @@ -64,11 +62,81 @@ public void startingAndroidAppWithCapabilitiesAndServiceTest(){ File app = new File(appDir, "ApiDemos-debug.apk"); DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator"); + capabilities.setCapability(MobileCapabilityType.APP, app.getAbsolutePath()); + + AppiumServiceBuilder builder = new AppiumServiceBuilder().withArgument(GeneralServerFlag.SESSION_OVERRIDE). + withArgument(GeneralServerFlag.STRICT_CAPS); + + AndroidDriver driver = new AndroidDriver<>(builder, capabilities); + try { + Capabilities caps = driver.getCapabilities(); + + assertEquals(true, caps.getCapability(MobileCapabilityType.PLATFORM_NAME).equals(MobilePlatform.ANDROID)); + assertNotEquals(null, caps.getCapability(MobileCapabilityType.DEVICE_NAME)); + } + finally { + driver.quit(); + } + } + + @Test + public void startingAndroidAppWithCapabilitiesOnServerSideTest(){ + File appDir = new File("src/test/java/io/appium/java_client"); + File app = new File(appDir, "ApiDemos-debug.apk"); + + File pageFactoryDir = new File("src/test/java/io/appium/java_client/pagefactory_tests"); + File chrome = new File(pageFactoryDir, "chromedriver.exe"); + + DesiredCapabilities serverCapabilities = new DesiredCapabilities(); + serverCapabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android"); + serverCapabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator"); + serverCapabilities.setCapability(MobileCapabilityType.FULL_RESET, true); + serverCapabilities.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 60); + serverCapabilities.setCapability(MobileCapabilityType.APP, app.getAbsolutePath()); + serverCapabilities.setCapability(AndroidMobileCapabilityType.CHROMEDRIVER_EXECUTABLE, chrome.getAbsolutePath()); + + AppiumServiceBuilder builder = new AppiumServiceBuilder().withCapabilities(serverCapabilities); + + DesiredCapabilities clientCapabilities = new DesiredCapabilities(); + clientCapabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "io.appium.android.apis"); + clientCapabilities.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".view.WebView1"); + + AndroidDriver driver = new AndroidDriver<>(builder, clientCapabilities); + try { + Capabilities caps = driver.getCapabilities(); + + assertEquals(true, caps.getCapability(MobileCapabilityType.PLATFORM_NAME).equals(MobilePlatform.ANDROID)); + assertNotEquals(null, caps.getCapability(MobileCapabilityType.DEVICE_NAME)); + } + finally { + driver.quit(); + } + } + + @Test + public void startingAndroidAppWithCapabilitiesAndFlagsOnServerSideTest(){ + File appDir = new File("src/test/java/io/appium/java_client"); + File app = new File(appDir, "ApiDemos-debug.apk"); + + File pageFactoryDir = new File("src/test/java/io/appium/java_client/pagefactory_tests"); + File chrome = new File(pageFactoryDir, "chromedriver.exe"); + + DesiredCapabilities serverCapabilities = new DesiredCapabilities(); + serverCapabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android"); + serverCapabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator"); + serverCapabilities.setCapability(MobileCapabilityType.FULL_RESET, true); + serverCapabilities.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 60); + serverCapabilities.setCapability(MobileCapabilityType.APP, app.getAbsolutePath()); + serverCapabilities.setCapability(AndroidMobileCapabilityType.CHROMEDRIVER_EXECUTABLE, chrome.getAbsolutePath()); + + AppiumServiceBuilder builder = new AppiumServiceBuilder().withArgument(GeneralServerFlag.SESSION_OVERRIDE). + withArgument(GeneralServerFlag.STRICT_CAPS).withCapabilities(serverCapabilities); - AppiumServiceBuilder builder = new AppiumServiceBuilder().withArgument(GeneralServerFlag.AUTOMATION_NAME, AutomationName.APPIUM). - withArgument(GeneralServerFlag.APP, app.getAbsolutePath()); + DesiredCapabilities clientCapabilities = new DesiredCapabilities(); + clientCapabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "io.appium.android.apis"); + clientCapabilities.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".view.WebView1"); - AndroidDriver driver = new AndroidDriver<>(builder, capabilities);; + AndroidDriver driver = new AndroidDriver<>(builder, clientCapabilities); try { Capabilities caps = driver.getCapabilities(); @@ -114,11 +182,41 @@ public void startingIOSAppWithCapabilitiesAndServiseTest(){ DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone Simulator"); + capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.APPIUM); + capabilities.setCapability(MobileCapabilityType.APP, app.getAbsolutePath()); + capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "8.4"); + + AppiumServiceBuilder builder = new AppiumServiceBuilder().withArgument(GeneralServerFlag.SESSION_OVERRIDE). + withArgument(GeneralServerFlag.STRICT_CAPS); + + IOSDriver driver = new IOSDriver<>(builder, capabilities); + try { + Capabilities caps = driver.getCapabilities(); + assertEquals(true, caps.getCapability(MobileCapabilityType.PLATFORM_NAME).equals(MobilePlatform.IOS)); + assertNotEquals(null, caps.getCapability(MobileCapabilityType.DEVICE_NAME)); + } + finally { + driver.quit(); + } + } + + @Test + public void startingIOSAppWithCapabilitiesOnServerSideTest(){ + File appDir = new File("src/test/java/io/appium/java_client"); + File app = new File(appDir, "UICatalog.app.zip"); + + DesiredCapabilities serverCapabilities = new DesiredCapabilities(); + serverCapabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone Simulator"); + serverCapabilities.setCapability(IOSMobileCapabilityType.LAUNCH_TIMEOUT, 500000); //some environment is too slow + serverCapabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "8.4"); - AppiumServiceBuilder builder = new AppiumServiceBuilder().withArgument(GeneralServerFlag.AUTOMATION_NAME, AutomationName.APPIUM). - withArgument(GeneralServerFlag.APP, app.getAbsolutePath()).withArgument(GeneralServerFlag.PLATFORM_VERSION, "8.4"); - IOSDriver driver = new IOSDriver<>(builder, capabilities);; + DesiredCapabilities clientCapabilities = new DesiredCapabilities(); + clientCapabilities.setCapability(MobileCapabilityType.APP, app.getAbsolutePath()); + + AppiumServiceBuilder builder = new AppiumServiceBuilder().withCapabilities(serverCapabilities); + + IOSDriver driver = new IOSDriver<>(builder, clientCapabilities);; try { Capabilities caps = driver.getCapabilities(); assertEquals(true, caps.getCapability(MobileCapabilityType.PLATFORM_NAME).equals(MobilePlatform.IOS)); @@ -129,4 +227,31 @@ public void startingIOSAppWithCapabilitiesAndServiseTest(){ } } + @Test + public void startingIOSAppWithCapabilitiesAndFlagsOnServerSideTest(){ + File appDir = new File("src/test/java/io/appium/java_client"); + File app = new File(appDir, "UICatalog.app.zip"); + + DesiredCapabilities serverCapabilities = new DesiredCapabilities(); + serverCapabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "iPhone Simulator"); + serverCapabilities.setCapability(IOSMobileCapabilityType.LAUNCH_TIMEOUT, 500000); //some environment is too slow + serverCapabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "8.4"); + + + DesiredCapabilities clientCapabilities = new DesiredCapabilities(); + clientCapabilities.setCapability(MobileCapabilityType.APP, app.getAbsolutePath()); + + AppiumServiceBuilder builder = new AppiumServiceBuilder().withArgument(GeneralServerFlag.SESSION_OVERRIDE). + withArgument(GeneralServerFlag.STRICT_CAPS).withCapabilities(serverCapabilities); + + IOSDriver driver = new IOSDriver<>(builder, clientCapabilities);; + try { + Capabilities caps = driver.getCapabilities(); + assertEquals(true, caps.getCapability(MobileCapabilityType.PLATFORM_NAME).equals(MobilePlatform.IOS)); + assertNotEquals(null, caps.getCapability(MobileCapabilityType.DEVICE_NAME)); + } + finally { + driver.quit(); + } + } } \ No newline at end of file diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/SelendroidModeTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/SelendroidModeTest.java index fd15db3fb..55519e1d9 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/SelendroidModeTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/SelendroidModeTest.java @@ -19,6 +19,7 @@ import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.android.AndroidElement; import io.appium.java_client.pagefactory.*; +import io.appium.java_client.remote.AndroidMobileCapabilityType; import io.appium.java_client.remote.AutomationName; import io.appium.java_client.remote.MobileCapabilityType; import io.appium.java_client.service.local.AppiumDriverLocalService; @@ -89,7 +90,7 @@ public class SelendroidModeTest { @BeforeClass public static void beforeClass() throws Exception { - AppiumServiceBuilder builder = new AppiumServiceBuilder().withArgument(GeneralServerFlag.AUTOMATION_NAME, AutomationName.SELENDROID); + AppiumServiceBuilder builder = new AppiumServiceBuilder(); service = builder.build(); service.start(); @@ -98,7 +99,8 @@ public static void beforeClass() throws Exception { DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator"); capabilities.setCapability(MobileCapabilityType.APP, app.getAbsolutePath()); - capabilities.setCapability(MobileCapabilityType.SELENDROID_PORT, SELENDROID_PORT); + capabilities.setCapability(AndroidMobileCapabilityType.SELENDROID_PORT, SELENDROID_PORT); + capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.SELENDROID); driver = new AndroidDriver(service.getUrl(), capabilities); } diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/SelendroidOverrideWidgetTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/SelendroidOverrideWidgetTest.java index 00129fe65..309b21bfd 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/SelendroidOverrideWidgetTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/SelendroidOverrideWidgetTest.java @@ -3,6 +3,7 @@ import io.appium.java_client.android.AndroidDriver; import io.appium.java_client.pagefactory.AppiumFieldDecorator; import io.appium.java_client.pagefactory.TimeOutDuration; +import io.appium.java_client.remote.AndroidMobileCapabilityType; import io.appium.java_client.remote.AutomationName; import io.appium.java_client.remote.MobileCapabilityType; import io.appium.java_client.service.local.AppiumDriverLocalService; @@ -30,7 +31,7 @@ public class SelendroidOverrideWidgetTest implements WidgetTest{ @BeforeClass public static void beforeClass() throws Exception { - AppiumServiceBuilder builder = new AppiumServiceBuilder().withArgument(GeneralServerFlag.AUTOMATION_NAME, AutomationName.SELENDROID); + AppiumServiceBuilder builder = new AppiumServiceBuilder(); service = builder.build(); service.start(); } @@ -42,7 +43,8 @@ public void setUp() throws Exception { DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator"); capabilities.setCapability(MobileCapabilityType.APP, app.getAbsolutePath()); - capabilities.setCapability(MobileCapabilityType.SELENDROID_PORT, SELENDROID_PORT); + capabilities.setCapability(AndroidMobileCapabilityType.SELENDROID_PORT, SELENDROID_PORT); + capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.SELENDROID); driver = new AndroidDriver<>(service.getUrl(), capabilities); duration = new TimeOutDuration(20, TimeUnit.SECONDS); diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/combined/SelendroidCombinedWidgetTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/combined/SelendroidCombinedWidgetTest.java index ddb908600..0388341aa 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/combined/SelendroidCombinedWidgetTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/combined/SelendroidCombinedWidgetTest.java @@ -32,7 +32,7 @@ public class SelendroidCombinedWidgetTest implements WidgetTest{ @BeforeClass public static void beforeClass() throws Exception { - AppiumServiceBuilder builder = new AppiumServiceBuilder().withArgument(GeneralServerFlag.AUTOMATION_NAME, AutomationName.SELENDROID); + AppiumServiceBuilder builder = new AppiumServiceBuilder(); service = builder.build(); service.start(); } @@ -44,7 +44,7 @@ public void setUp() throws Exception { DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator"); capabilities.setCapability(MobileCapabilityType.APP, app.getAbsolutePath()); - capabilities.setCapability(MobileCapabilityType.SELENDROID_PORT, SELENDROID_PORT); + capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.SELENDROID); driver = new AndroidDriver<>(service.getUrl(), capabilities); duration = new TimeOutDuration(20, TimeUnit.SECONDS); diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/selendroid/SelendroidWidgetTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/selendroid/SelendroidWidgetTest.java index 7ed3f03a7..17c54be09 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/widgets/selendroid/SelendroidWidgetTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/widgets/selendroid/SelendroidWidgetTest.java @@ -5,6 +5,7 @@ import io.appium.java_client.pagefactory.TimeOutDuration; import io.appium.java_client.pagefactory_tests.widgets.Movie; import io.appium.java_client.pagefactory_tests.widgets.WidgetTest; +import io.appium.java_client.remote.AndroidMobileCapabilityType; import io.appium.java_client.remote.AutomationName; import io.appium.java_client.remote.MobileCapabilityType; import io.appium.java_client.service.local.AppiumDriverLocalService; @@ -32,7 +33,7 @@ public class SelendroidWidgetTest implements WidgetTest{ @BeforeClass public static void beforeClass() throws Exception { - AppiumServiceBuilder builder = new AppiumServiceBuilder().withArgument(GeneralServerFlag.AUTOMATION_NAME, AutomationName.SELENDROID); + AppiumServiceBuilder builder = new AppiumServiceBuilder(); service = builder.build(); service.start(); } @@ -44,7 +45,8 @@ public void setUp() throws Exception { DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator"); capabilities.setCapability(MobileCapabilityType.APP, app.getAbsolutePath()); - capabilities.setCapability(MobileCapabilityType.SELENDROID_PORT, SELENDROID_PORT); + capabilities.setCapability(AndroidMobileCapabilityType.SELENDROID_PORT, SELENDROID_PORT); + capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.SELENDROID); driver = new AndroidDriver<>(service.getUrl(), capabilities); duration = new TimeOutDuration(20, TimeUnit.SECONDS);