From a50215c338fdb23bb62934482a3220d05c243a82 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Mon, 25 Oct 2021 19:13:34 +0200 Subject: [PATCH 1/7] chore: Finish creating options for UiAutomator2 driver --- .../android/options/UiAutomator2Options.java | 67 ++++++++++++++++-- .../SupportsAutoWebviewTimeoutOption.java | 53 ++++++++++++++ .../SupportsChromeLoggingPrefsOption.java | 52 ++++++++++++++ .../context/SupportsChromeOptionsOption.java | 51 ++++++++++++++ .../SupportsChromedriverArgsOption.java | 52 ++++++++++++++ ...tsChromedriverChromeMappingFileOption.java | 52 ++++++++++++++ ...tsChromedriverDisableBuildCheckOption.java | 62 ++++++++++++++++ ...pportsChromedriverExecutableDirOption.java | 52 ++++++++++++++ .../SupportsChromedriverExecutableOption.java | 47 +++++++++++++ .../SupportsChromedriverPortOption.java | 50 +++++++++++++ .../SupportsChromedriverPortsOption.java | 50 +++++++++++++ ...ChromedriverUseSystemExecutableOption.java | 61 ++++++++++++++++ ...SupportsEnsureWebviewsHavePagesOption.java | 60 ++++++++++++++++ ...meAndroidPackageFromContextNameOption.java | 64 +++++++++++++++++ .../SupportsNativeWebScreenshotOption.java | 61 ++++++++++++++++ ...rtsRecreateChromeDriverSessionsOption.java | 62 ++++++++++++++++ .../SupportsShowChromedriverLogOption.java | 62 ++++++++++++++++ .../SupportsWebviewDevtoolsPortOption.java | 51 ++++++++++++++ .../locking/SupportsSkipUnlockOption.java | 62 ++++++++++++++++ .../locking/SupportsUnlockKeyOption.java | 49 +++++++++++++ .../locking/SupportsUnlockStrategyOption.java | 49 +++++++++++++ .../SupportsUnlockSuccessTimeoutOption.java | 53 ++++++++++++++ .../locking/SupportsUnlockTypeOption.java | 49 +++++++++++++ .../SupportsMjpegScreenshotUrlOption.java | 70 +++++++++++++++++++ .../mjpeg/SupportsMjpegServerPortOption.java | 52 ++++++++++++++ ...bleSuppressAccessibilityServiceOption.java | 63 +++++++++++++++++ .../other/SupportsSkipLogCaptureOption.java | 59 ++++++++++++++++ .../other/SupportsUserProfileOption.java | 53 ++++++++++++++ .../java_client/remote/MobileBrowserType.java | 2 +- .../service/local/AppiumServiceBuilder.java | 29 ++++---- .../java_client/android/BaseAndroidTest.java | 16 ++--- .../service/local/StartingAppLocallyTest.java | 68 +++++++++--------- 32 files changed, 1615 insertions(+), 68 deletions(-) create mode 100644 src/main/java/io/appium/java_client/android/options/context/SupportsAutoWebviewTimeoutOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/context/SupportsChromeLoggingPrefsOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/context/SupportsChromeOptionsOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverArgsOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverChromeMappingFileOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverDisableBuildCheckOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverExecutableDirOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverExecutableOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverPortOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverPortsOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverUseSystemExecutableOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/context/SupportsEnsureWebviewsHavePagesOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/context/SupportsExtractChromeAndroidPackageFromContextNameOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/context/SupportsNativeWebScreenshotOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/context/SupportsRecreateChromeDriverSessionsOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/context/SupportsShowChromedriverLogOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/context/SupportsWebviewDevtoolsPortOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/locking/SupportsSkipUnlockOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/locking/SupportsUnlockKeyOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/locking/SupportsUnlockStrategyOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/locking/SupportsUnlockSuccessTimeoutOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/locking/SupportsUnlockTypeOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/mjpeg/SupportsMjpegScreenshotUrlOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/mjpeg/SupportsMjpegServerPortOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/other/SupportsDisableSuppressAccessibilityServiceOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/other/SupportsSkipLogCaptureOption.java create mode 100644 src/main/java/io/appium/java_client/android/options/other/SupportsUserProfileOption.java diff --git a/src/main/java/io/appium/java_client/android/options/UiAutomator2Options.java b/src/main/java/io/appium/java_client/android/options/UiAutomator2Options.java index f13dda020..9185994f1 100644 --- a/src/main/java/io/appium/java_client/android/options/UiAutomator2Options.java +++ b/src/main/java/io/appium/java_client/android/options/UiAutomator2Options.java @@ -52,7 +52,34 @@ import io.appium.java_client.android.options.avd.SupportsGpsEnabledOption; import io.appium.java_client.android.options.avd.SupportsIsHeadlessOption; import io.appium.java_client.android.options.avd.SupportsNetworkSpeedOption; +import io.appium.java_client.android.options.context.SupportsAutoWebviewTimeoutOption; +import io.appium.java_client.android.options.context.SupportsChromeLoggingPrefsOption; +import io.appium.java_client.android.options.context.SupportsChromeOptionsOption; +import io.appium.java_client.android.options.context.SupportsChromedriverArgsOption; +import io.appium.java_client.android.options.context.SupportsChromedriverChromeMappingFileOption; +import io.appium.java_client.android.options.context.SupportsChromedriverDisableBuildCheckOption; +import io.appium.java_client.android.options.context.SupportsChromedriverExecutableDirOption; +import io.appium.java_client.android.options.context.SupportsChromedriverExecutableOption; +import io.appium.java_client.android.options.context.SupportsChromedriverPortOption; +import io.appium.java_client.android.options.context.SupportsChromedriverPortsOption; +import io.appium.java_client.android.options.context.SupportsChromedriverUseSystemExecutableOption; +import io.appium.java_client.android.options.context.SupportsEnsureWebviewsHavePagesOption; +import io.appium.java_client.android.options.context.SupportsExtractChromeAndroidPackageFromContextNameOption; +import io.appium.java_client.android.options.context.SupportsNativeWebScreenshotOption; +import io.appium.java_client.android.options.context.SupportsRecreateChromeDriverSessionsOption; +import io.appium.java_client.android.options.context.SupportsShowChromedriverLogOption; +import io.appium.java_client.android.options.context.SupportsWebviewDevtoolsPortOption; import io.appium.java_client.android.options.localization.SupportsLocaleScriptOption; +import io.appium.java_client.android.options.locking.SupportsSkipUnlockOption; +import io.appium.java_client.android.options.locking.SupportsUnlockKeyOption; +import io.appium.java_client.android.options.locking.SupportsUnlockStrategyOption; +import io.appium.java_client.android.options.locking.SupportsUnlockSuccessTimeoutOption; +import io.appium.java_client.android.options.locking.SupportsUnlockTypeOption; +import io.appium.java_client.android.options.mjpeg.SupportsMjpegScreenshotUrlOption; +import io.appium.java_client.android.options.mjpeg.SupportsMjpegServerPortOption; +import io.appium.java_client.android.options.other.SupportsDisableSuppressAccessibilityServiceOption; +import io.appium.java_client.android.options.other.SupportsSkipLogCaptureOption; +import io.appium.java_client.android.options.other.SupportsUserProfileOption; import io.appium.java_client.android.options.server.SupportsDisableWindowAnimationOption; import io.appium.java_client.android.options.server.SupportsSkipDeviceInitializationOption; import io.appium.java_client.android.options.server.SupportsSkipServerInstallationOption; @@ -81,12 +108,6 @@ * https://github.com/appium/appium-uiautomator2-driver#capabilities */ public class UiAutomator2Options extends BaseOptions implements - // TODO: Device locking options: https://github.com/appium/appium-uiautomator2-driver#device-locking - // TODO: MJPEG options: https://github.com/appium/appium-uiautomator2-driver#mjpeg - // TODO: Web Context options: https://github.com/appium/appium-uiautomator2-driver#web-context - // TODO: Other options: https://github.com/appium/appium-uiautomator2-driver#other - // TODO: Shared options - SupportsAutoWebViewOption, // General options: https://github.com/appium/appium-uiautomator2-driver#general SupportsDeviceNameOption, SupportsUdidOption, @@ -148,7 +169,39 @@ public class UiAutomator2Options extends BaseOptions implem SupportsIsHeadlessOption, // App signing options: https://github.com/appium/appium-uiautomator2-driver#app-signing SupportsKeystoreOptions, - SupportsNoSignOption { + SupportsNoSignOption, + // Device locking options: https://github.com/appium/appium-uiautomator2-driver#device-locking + SupportsSkipUnlockOption, + SupportsUnlockTypeOption, + SupportsUnlockKeyOption, + SupportsUnlockStrategyOption, + SupportsUnlockSuccessTimeoutOption, + // MJPEG options: https://github.com/appium/appium-uiautomator2-driver#mjpeg + SupportsMjpegServerPortOption, + SupportsMjpegScreenshotUrlOption, + // Web Context options: https://github.com/appium/appium-uiautomator2-driver#web-context + SupportsAutoWebViewOption, + SupportsWebviewDevtoolsPortOption, + SupportsEnsureWebviewsHavePagesOption, + SupportsChromedriverPortOption, + SupportsChromedriverPortsOption, + SupportsChromedriverArgsOption, + SupportsChromedriverExecutableOption, + SupportsChromedriverExecutableDirOption, + SupportsChromedriverChromeMappingFileOption, + SupportsChromedriverUseSystemExecutableOption, + SupportsChromedriverDisableBuildCheckOption, + SupportsAutoWebviewTimeoutOption, + SupportsRecreateChromeDriverSessionsOption, + SupportsNativeWebScreenshotOption, + SupportsExtractChromeAndroidPackageFromContextNameOption, + SupportsShowChromedriverLogOption, + SupportsChromeOptionsOption, + SupportsChromeLoggingPrefsOption, + // Other options: https://github.com/appium/appium-uiautomator2-driver#other + SupportsDisableSuppressAccessibilityServiceOption, + SupportsUserProfileOption, + SupportsSkipLogCaptureOption { public UiAutomator2Options() { setCommonOptions(); } diff --git a/src/main/java/io/appium/java_client/android/options/context/SupportsAutoWebviewTimeoutOption.java b/src/main/java/io/appium/java_client/android/options/context/SupportsAutoWebviewTimeoutOption.java new file mode 100644 index 000000000..0f0a07967 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/context/SupportsAutoWebviewTimeoutOption.java @@ -0,0 +1,53 @@ +/* + * 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.android.options.context; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.time.Duration; +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toDuration; + +public interface SupportsAutoWebviewTimeoutOption> extends + Capabilities, CanSetCapability { + String AUTO_WEBVIEW_TIMEOUT_OPTION = "autoWebviewTimeout"; + + /** + * Set the maximum timeout to wait until a web view is + * available if autoWebview capability is set to true. 2000 ms by default. + * + * @param timeout Timeout value. + * @return self instance for chaining. + */ + default T setAutoWebviewTimeout(Duration timeout) { + return amend(AUTO_WEBVIEW_TIMEOUT_OPTION, timeout.toMillis()); + } + + /** + * Get the timeout to wait until a web view is available. + * + * @return The timeout value. + */ + default Optional getAutoWebviewTimeout() { + return Optional.ofNullable( + toDuration(getCapability(AUTO_WEBVIEW_TIMEOUT_OPTION)) + ); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/context/SupportsChromeLoggingPrefsOption.java b/src/main/java/io/appium/java_client/android/options/context/SupportsChromeLoggingPrefsOption.java new file mode 100644 index 000000000..f47f4d865 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/context/SupportsChromeLoggingPrefsOption.java @@ -0,0 +1,52 @@ +/* + * 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.android.options.context; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Map; +import java.util.Optional; + +public interface SupportsChromeLoggingPrefsOption> extends + Capabilities, CanSetCapability { + String CHROME_LOGGING_PREFS_OPTION = "chromeLoggingPrefs"; + + /** + * Chrome logging preferences mapping. Basically the same as + * [goog:loggingPrefs](https://newbedev.com/ + * getting-console-log-output-from-chrome-with-selenium-python-api-bindings). + * It is set to {"browser": "ALL"} by default. + * + * @param opts Chrome logging preferences. + * @return self instance for chaining. + */ + default T setChromeLoggingPrefs(Map opts) { + return amend(CHROME_LOGGING_PREFS_OPTION, opts); + } + + /** + * Get chrome logging preferences. + * + * @return Chrome logging preferences. + */ + default Optional> getChromeLoggingPrefs() { + //noinspection unchecked + return Optional.ofNullable((Map) getCapability(CHROME_LOGGING_PREFS_OPTION)); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/context/SupportsChromeOptionsOption.java b/src/main/java/io/appium/java_client/android/options/context/SupportsChromeOptionsOption.java new file mode 100644 index 000000000..955a6c2a7 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/context/SupportsChromeOptionsOption.java @@ -0,0 +1,51 @@ +/* + * 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.android.options.context; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Map; +import java.util.Optional; + +public interface SupportsChromeOptionsOption> extends + Capabilities, CanSetCapability { + String CHROME_OPTIONS_OPTION = "chromeOptions"; + + /** + * A mapping, that allows to customize chromedriver options. + * See https://chromedriver.chromium.org/capabilities for the list + * of available entries. + * + * @param opts Chrome options. + * @return self instance for chaining. + */ + default T setChromeOptions(Map opts) { + return amend(CHROME_OPTIONS_OPTION, opts); + } + + /** + * Get chrome options. + * + * @return Chrome options. + */ + default Optional> getChromeOptions() { + //noinspection unchecked + return Optional.ofNullable((Map) getCapability(CHROME_OPTIONS_OPTION)); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverArgsOption.java b/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverArgsOption.java new file mode 100644 index 000000000..227088b35 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverArgsOption.java @@ -0,0 +1,52 @@ +/* + * 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.android.options.context; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.List; +import java.util.Optional; + +public interface SupportsChromedriverArgsOption> extends + Capabilities, CanSetCapability { + String CHROMEDRIVER_ARGS_OPTION = "chromedriverArgs"; + + /** + * Array of chromedriver [command line + * arguments](http://www.assertselenium.com/java/list-of-chrome-driver-command-line-arguments/). + * Note, that not all command line arguments that are available for the desktop + * browser are also available for the mobile one. + * + * @param args Chromedriver command line arguments. + * @return self instance for chaining. + */ + default T setChromedriverArgs(List args) { + return amend(CHROMEDRIVER_ARGS_OPTION, args); + } + + /** + * Get the array of chromedriver CLI arguments. + * + * @return Arguments list. + */ + default Optional> getChromedriverArgs() { + //noinspection unchecked + return Optional.ofNullable((List) getCapability(CHROMEDRIVER_ARGS_OPTION)); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverChromeMappingFileOption.java b/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverChromeMappingFileOption.java new file mode 100644 index 000000000..83faaef42 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverChromeMappingFileOption.java @@ -0,0 +1,52 @@ +/* + * 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.android.options.context; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +public interface SupportsChromedriverChromeMappingFileOption> extends + Capabilities, CanSetCapability { + String CHROMEDRIVER_CHROME_MAPPING_FILE_OPTION = "chromedriverChromeMappingFile"; + + /** + * Full path to the chromedrivers mapping file. This file is used to statically + * map webview/browser versions to the chromedriver versions that are capable + * of automating them. Read [Automatic Chromedriver Discovery](https://github.com/ + * appium/appium/blob/master/docs/en/writing-running-appium/web/ + * chromedriver.md#automatic-discovery-of-compatible-chromedriver) + * article for more details. + * + * @param path Path to chromedrivers mapping file. + * @return self instance for chaining. + */ + default T setChromedriverChromeMappingFile(String path) { + return amend(CHROMEDRIVER_CHROME_MAPPING_FILE_OPTION, path); + } + + /** + * Get full path to the chromedrivers mapping file is located. + * + * @return Path to chromedrivers mapping file. + */ + default Optional getChromedriverChromeMappingFile() { + return Optional.ofNullable((String) getCapability(CHROMEDRIVER_CHROME_MAPPING_FILE_OPTION)); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverDisableBuildCheckOption.java b/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverDisableBuildCheckOption.java new file mode 100644 index 000000000..7757b0ed3 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverDisableBuildCheckOption.java @@ -0,0 +1,62 @@ +/* + * 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.android.options.context; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toSafeBoolean; + +public interface SupportsChromedriverDisableBuildCheckOption> extends + Capabilities, CanSetCapability { + String CHROMEDRIVER_DISABLE_BUILD_CHECK_OPTION = "chromedriverDisableBuildCheck"; + + /** + * Disables the compatibility validation between the current chromedriver + * and the destination browser/web view. + * + * @return self instance for chaining. + */ + default T chromedriverDisableBuildCheck() { + return amend(CHROMEDRIVER_DISABLE_BUILD_CHECK_OPTION, true); + } + + /** + * Being set to true disables the compatibility validation between the current + * chromedriver and the destination browser/web view. Use it with care. + * false by default. + * + * @param value Whether to enable the validation. + * @return self instance for chaining. + */ + default T setChromedriverDisableBuildCheck(boolean value) { + return amend(CHROMEDRIVER_DISABLE_BUILD_CHECK_OPTION, value); + } + + /** + * Get whether to disable the compatibility validation between the current + * chromedriver and the destination browser/web view. + * + * @return True or false. + */ + default Optional doesChromedriverDisableBuildCheck() { + return Optional.ofNullable(toSafeBoolean(getCapability(CHROMEDRIVER_DISABLE_BUILD_CHECK_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverExecutableDirOption.java b/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverExecutableDirOption.java new file mode 100644 index 000000000..994021a5f --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverExecutableDirOption.java @@ -0,0 +1,52 @@ +/* + * 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.android.options.context; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +public interface SupportsChromedriverExecutableDirOption> extends + Capabilities, CanSetCapability { + String CHROMEDRIVER_EXECUTABLE_DIR_OPTION = "chromedriverExecutableDir"; + + /** + * Full path to the folder where chromedriver executables are located. + * This folder is used then to store the downloaded chromedriver executables + * if automatic download is enabled. Read [Automatic Chromedriver + * Discovery](https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/ + * web/chromedriver.md#automatic-discovery-of-compatible-chromedriver) + * article for more details. + * + * @param path Path to chromedriver executable. + * @return self instance for chaining. + */ + default T setChromedriverExecutableDir(String path) { + return amend(CHROMEDRIVER_EXECUTABLE_DIR_OPTION, path); + } + + /** + * Get full path to the folder where chromedriver executables are located. + * + * @return Path to chromedriver executable dir. + */ + default Optional getChromedriverExecutableDir() { + return Optional.ofNullable((String) getCapability(CHROMEDRIVER_EXECUTABLE_DIR_OPTION)); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverExecutableOption.java b/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverExecutableOption.java new file mode 100644 index 000000000..4f73b42a2 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverExecutableOption.java @@ -0,0 +1,47 @@ +/* + * 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.android.options.context; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +public interface SupportsChromedriverExecutableOption> extends + Capabilities, CanSetCapability { + String CHROMEDRIVER_EXECUTABLE_OPTION = "chromedriverExecutable"; + + /** + * Full path to the chromedriver executable on the server file system. + * + * @param path Path to chromedriver executable. + * @return self instance for chaining. + */ + default T setChromedriverExecutable(String path) { + return amend(CHROMEDRIVER_EXECUTABLE_OPTION, path); + } + + /** + * Get the path to the chromedriver executable on the server file system.. + * + * @return Path to chromedriver executable. + */ + default Optional getChromedriverExecutable() { + return Optional.ofNullable((String) getCapability(CHROMEDRIVER_EXECUTABLE_OPTION)); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverPortOption.java b/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverPortOption.java new file mode 100644 index 000000000..fa6cc1f5a --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverPortOption.java @@ -0,0 +1,50 @@ +/* + * 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.android.options.context; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toInteger; + +public interface SupportsChromedriverPortOption> extends + Capabilities, CanSetCapability { + String CHROMEDRIVER_PORT_OPTION = "chromedriverPort"; + + /** + * The port number to use for Chromedriver communication. + * Any free port number is selected by default if unset. + * + * @param port port number in range 0..65535 + * @return self instance for chaining. + */ + default T setChromedriverPort(int port) { + return amend(CHROMEDRIVER_PORT_OPTION, port); + } + + /** + * Get the local port number to use for Chromedriver communication. + * + * @return Port number. + */ + default Optional getChromedriverPort() { + return Optional.ofNullable(toInteger(getCapability(CHROMEDRIVER_PORT_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverPortsOption.java b/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverPortsOption.java new file mode 100644 index 000000000..eb0a4630c --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverPortsOption.java @@ -0,0 +1,50 @@ +/* + * 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.android.options.context; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.List; +import java.util.Optional; + +public interface SupportsChromedriverPortsOption> extends + Capabilities, CanSetCapability { + String CHROMEDRIVER_PORTS_OPTION = "chromedriverPorts"; + + /** + * Array of possible port numbers to assign for Chromedriver communication. + * If none of the port in this array is free then a server error is thrown. + * + * @param ports one or more port numbers in range 0..65535 + * @return self instance for chaining. + */ + default T setChromedriverPorts(List ports) { + return amend(CHROMEDRIVER_PORTS_OPTION, ports); + } + + /** + * Get the local port number to use for Chromedriver communication. + * + * @return Port number. + */ + default Optional> getChromedriverPorts() { + //noinspection unchecked + return Optional.ofNullable((List) getCapability(CHROMEDRIVER_PORTS_OPTION)); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverUseSystemExecutableOption.java b/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverUseSystemExecutableOption.java new file mode 100644 index 000000000..62e653cb0 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/context/SupportsChromedriverUseSystemExecutableOption.java @@ -0,0 +1,61 @@ +/* + * 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.android.options.context; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toSafeBoolean; + +public interface SupportsChromedriverUseSystemExecutableOption> extends + Capabilities, CanSetCapability { + String CHROMEDRIVER_USE_SYSTEM_EXECUTABLE_OPTION = "chromedriverUseSystemExecutable"; + + /** + * Enforce the usage of chromedriver, + * which gets downloaded by Appium automatically upon installation. + * + * @return self instance for chaining. + */ + default T chromedriverUseSystemExecutable() { + return amend(CHROMEDRIVER_USE_SYSTEM_EXECUTABLE_OPTION, true); + } + + /** + * Set it to true in order to enforce the usage of chromedriver, which gets + * downloaded by Appium automatically upon installation. This driver might not + * be compatible with the destination browser or a web view. false by default. + * + * @param value Whether to use the system chromedriver. + * @return self instance for chaining. + */ + default T setChromedriverUseSystemExecutable(boolean value) { + return amend(CHROMEDRIVER_USE_SYSTEM_EXECUTABLE_OPTION, value); + } + + /** + * Get whether to use the system chromedriver. + * + * @return True or false. + */ + default Optional doesChromedriverUseSystemExecutable() { + return Optional.ofNullable(toSafeBoolean(getCapability(CHROMEDRIVER_USE_SYSTEM_EXECUTABLE_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/context/SupportsEnsureWebviewsHavePagesOption.java b/src/main/java/io/appium/java_client/android/options/context/SupportsEnsureWebviewsHavePagesOption.java new file mode 100644 index 000000000..d72cbe066 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/context/SupportsEnsureWebviewsHavePagesOption.java @@ -0,0 +1,60 @@ +/* + * 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.android.options.context; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toSafeBoolean; + +public interface SupportsEnsureWebviewsHavePagesOption> extends + Capabilities, CanSetCapability { + String ENSURE_WEBVIEWS_HAVE_PAGES_OPTION = "ensureWebviewsHavePages"; + + /** + * Set to skip web views that have no pages from being shown in getContexts output. + * + * @return self instance for chaining. + */ + default T ensureWebviewsHavePages() { + return amend(ENSURE_WEBVIEWS_HAVE_PAGES_OPTION, true); + } + + /** + * Whether to skip web views that have no pages from being shown in getContexts + * output. The driver uses devtools connection to retrieve the information about + * existing pages. true by default since Appium 1.19.0, false if lower than 1.19.0. + * + * @param value Whether to ensure if web views have pages. + * @return self instance for chaining. + */ + default T setEnsureWebviewsHavePages(boolean value) { + return amend(ENSURE_WEBVIEWS_HAVE_PAGES_OPTION, value); + } + + /** + * Get whether to ensure if web views have pages. + * + * @return True or false. + */ + default Optional doesEnsureWebviewsHavePages() { + return Optional.ofNullable(toSafeBoolean(getCapability(ENSURE_WEBVIEWS_HAVE_PAGES_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/context/SupportsExtractChromeAndroidPackageFromContextNameOption.java b/src/main/java/io/appium/java_client/android/options/context/SupportsExtractChromeAndroidPackageFromContextNameOption.java new file mode 100644 index 000000000..447a1f2f4 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/context/SupportsExtractChromeAndroidPackageFromContextNameOption.java @@ -0,0 +1,64 @@ +/* + * 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.android.options.context; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toSafeBoolean; + +public interface SupportsExtractChromeAndroidPackageFromContextNameOption + > extends Capabilities, CanSetCapability { + String EXTRACT_CHROME_ANDROID_PACKAGE_FROM_CONTEXT_NAME_OPTION = + "extractChromeAndroidPackageFromContextName"; + + /** + * Tell chromedriver to attach to the android package we have associated + * with the context name, rather than the package of the application under test. + * + * @return self instance for chaining. + */ + default T extractChromeAndroidPackageFromContextName() { + return amend(EXTRACT_CHROME_ANDROID_PACKAGE_FROM_CONTEXT_NAME_OPTION, true); + } + + /** + * If set to true, tell chromedriver to attach to the android package we have associated + * with the context name, rather than the package of the application under test. + * false by default. + * + * @param value Whether to use the android package identifier associated with the context name. + * @return self instance for chaining. + */ + default T setExtractChromeAndroidPackageFromContextName(boolean value) { + return amend(EXTRACT_CHROME_ANDROID_PACKAGE_FROM_CONTEXT_NAME_OPTION, value); + } + + /** + * Get whether to use the android package identifier associated with the context name. + * + * @return True or false. + */ + default Optional doesExtractChromeAndroidPackageFromContextName() { + return Optional.ofNullable( + toSafeBoolean(getCapability(EXTRACT_CHROME_ANDROID_PACKAGE_FROM_CONTEXT_NAME_OPTION)) + ); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/context/SupportsNativeWebScreenshotOption.java b/src/main/java/io/appium/java_client/android/options/context/SupportsNativeWebScreenshotOption.java new file mode 100644 index 000000000..71e5934ff --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/context/SupportsNativeWebScreenshotOption.java @@ -0,0 +1,61 @@ +/* + * 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.android.options.context; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toSafeBoolean; + +public interface SupportsNativeWebScreenshotOption> extends + Capabilities, CanSetCapability { + String NATIVE_WEB_SCREENSHOT_OPTION = "nativeWebScreenshot"; + + /** + * Enforce to use screenshoting endpoint provided by UiAutomator framework + * rather than the one provided by chromedriver. + * + * @return self instance for chaining. + */ + default T nativeWebScreenshot() { + return amend(NATIVE_WEB_SCREENSHOT_OPTION, true); + } + + /** + * Whether to use screenshoting endpoint provided by UiAutomator framework (true) + * rather than the one provided by chromedriver (false, the default value). + * Use it when you experience issues with the latter. + * + * @param value Whether to use native screenshots in web view context. + * @return self instance for chaining. + */ + default T setNativeWebScreenshot(boolean value) { + return amend(NATIVE_WEB_SCREENSHOT_OPTION, value); + } + + /** + * Get whether to use native screenshots in web view context. + * + * @return True or false. + */ + default Optional doesNativeWebScreenshot() { + return Optional.ofNullable(toSafeBoolean(getCapability(NATIVE_WEB_SCREENSHOT_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/context/SupportsRecreateChromeDriverSessionsOption.java b/src/main/java/io/appium/java_client/android/options/context/SupportsRecreateChromeDriverSessionsOption.java new file mode 100644 index 000000000..a47ade424 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/context/SupportsRecreateChromeDriverSessionsOption.java @@ -0,0 +1,62 @@ +/* + * 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.android.options.context; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toSafeBoolean; + +public interface SupportsRecreateChromeDriverSessionsOption> extends + Capabilities, CanSetCapability { + String RECREATE_CHROME_DRIVER_SESSIONS = "recreateChromeDriverSessions"; + + /** + * Enforce chromedriver sessions to be killed and then recreated instead + * of just suspending it on context switch. + * + * @return self instance for chaining. + */ + default T recreateChromeDriverSessions() { + return amend(RECREATE_CHROME_DRIVER_SESSIONS, true); + } + + /** + * If this capability is set to true then chromedriver session is always going + * to be killed and then recreated instead of just suspending it on context + * switching. false by default. + * + * @param value Whether to recreate chromedriver sessions. + * @return self instance for chaining. + */ + default T setRecreateChromeDriverSessions(boolean value) { + return amend(RECREATE_CHROME_DRIVER_SESSIONS, value); + } + + /** + * Get whether chromedriver sessions should be killed and then recreated instead + * of just suspending it on context switch. + * + * @return True or false. + */ + default Optional doesRecreateChromeDriverSessions() { + return Optional.ofNullable(toSafeBoolean(getCapability(RECREATE_CHROME_DRIVER_SESSIONS))); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/context/SupportsShowChromedriverLogOption.java b/src/main/java/io/appium/java_client/android/options/context/SupportsShowChromedriverLogOption.java new file mode 100644 index 000000000..d201069e5 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/context/SupportsShowChromedriverLogOption.java @@ -0,0 +1,62 @@ +/* + * 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.android.options.context; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toSafeBoolean; + +public interface SupportsShowChromedriverLogOption> + extends Capabilities, CanSetCapability { + String SHOW_CHROMEDRIVER_LOG_OPTION = "showChromedriverLog"; + + /** + * Enforces all the output from chromedriver binary to be + * forwarded to the Appium server log. + * + * @return self instance for chaining. + */ + default T showChromedriverLog() { + return amend(SHOW_CHROMEDRIVER_LOG_OPTION, true); + } + + /** + * If set to true then all the output from chromedriver binary will be + * forwarded to the Appium server log. false by default. + * + * @param value Whether to forward chromedriver output to the Appium server log. + * @return self instance for chaining. + */ + default T setDhowChromedriverLog(boolean value) { + return amend(SHOW_CHROMEDRIVER_LOG_OPTION, value); + } + + /** + * Get whether to forward chromedriver output to the Appium server log. + * + * @return True or false. + */ + default Optional doesDhowChromedriverLog() { + return Optional.ofNullable( + toSafeBoolean(getCapability(SHOW_CHROMEDRIVER_LOG_OPTION)) + ); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/context/SupportsWebviewDevtoolsPortOption.java b/src/main/java/io/appium/java_client/android/options/context/SupportsWebviewDevtoolsPortOption.java new file mode 100644 index 000000000..e48e73fad --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/context/SupportsWebviewDevtoolsPortOption.java @@ -0,0 +1,51 @@ +/* + * 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.android.options.context; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toInteger; + +public interface SupportsWebviewDevtoolsPortOption> extends + Capabilities, CanSetCapability { + String WEBVIEW_DEVTOOLS_PORT_OPTION = "webviewDevtoolsPort"; + + /** + * The local port number to use for devtools communication. By default, the first + * free port from 10900..11000 range is selected. Consider setting the custom + * value if you are running parallel tests. + * + * @param port port number in range 0..65535 + * @return self instance for chaining. + */ + default T setWebviewDevtoolsPort(int port) { + return amend(WEBVIEW_DEVTOOLS_PORT_OPTION, port); + } + + /** + * Get the local port number to use for devtools communication. + * + * @return Port number. + */ + default Optional getWebviewDevtoolsPort() { + return Optional.ofNullable(toInteger(getCapability(WEBVIEW_DEVTOOLS_PORT_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/locking/SupportsSkipUnlockOption.java b/src/main/java/io/appium/java_client/android/options/locking/SupportsSkipUnlockOption.java new file mode 100644 index 000000000..0846dddfe --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/locking/SupportsSkipUnlockOption.java @@ -0,0 +1,62 @@ +/* + * 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.android.options.locking; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toSafeBoolean; + +public interface SupportsSkipUnlockOption> extends + Capabilities, CanSetCapability { + String SKIP_UNLOCK_OPTION = "skipUnlock"; + + /** + * Skip the check for lock screen presence. + * + * @return self instance for chaining. + */ + default T skipUnlock() { + return amend(SKIP_UNLOCK_OPTION, true); + } + + /** + * Whether to skip the check for lock screen presence (true). By default, + * UiAutomator2 driver tries to detect if the device's screen is locked + * before starting the test and to unlock that (which sometimes might be unstable). + * Note, that this operation takes some time, so it is highly recommended to set + * this capability to true and disable screen locking on devices under test. + * + * @param value Set it to true in order to skip screen unlock checks. + * @return self instance for chaining. + */ + default T setSkipUnlock(boolean value) { + return amend(SKIP_UNLOCK_OPTION, value); + } + + /** + * Get whether to skip the check for lock screen presence. + * + * @return True or false. + */ + default Optional doesSkipUnlock() { + return Optional.ofNullable(toSafeBoolean(getCapability(SKIP_UNLOCK_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/locking/SupportsUnlockKeyOption.java b/src/main/java/io/appium/java_client/android/options/locking/SupportsUnlockKeyOption.java new file mode 100644 index 000000000..011ca2c87 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/locking/SupportsUnlockKeyOption.java @@ -0,0 +1,49 @@ +/* + * 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.android.options.locking; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +public interface SupportsUnlockKeyOption> extends + Capabilities, CanSetCapability { + String UNLOCK_KEY_OPTION = "unlockKey"; + + /** + * Allows to set an unlock key. + * Read [Unlock tutorial](https://github.com/appium/appium-android-driver/blob/master/docs/UNLOCK.md) + * for more details. + * + * @param unlockKey The unlock key. + * @return self instance for chaining. + */ + default T setUnlockKey(String unlockKey) { + return amend(UNLOCK_KEY_OPTION, unlockKey); + } + + /** + * Get the unlock key. + * + * @return Unlock key. + */ + default Optional getUnlockKey() { + return Optional.ofNullable((String) getCapability(UNLOCK_KEY_OPTION)); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/locking/SupportsUnlockStrategyOption.java b/src/main/java/io/appium/java_client/android/options/locking/SupportsUnlockStrategyOption.java new file mode 100644 index 000000000..6329d6861 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/locking/SupportsUnlockStrategyOption.java @@ -0,0 +1,49 @@ +/* + * 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.android.options.locking; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +public interface SupportsUnlockStrategyOption> extends + Capabilities, CanSetCapability { + String UNLOCK_STRATEGY_OPTION = "unlockStrategy"; + + /** + * Either 'locksettings' (default) or 'uiautomator'. + * Setting it to 'uiautomator' will enforce the driver to avoid using special + * ADB shortcuts in order to speed up the unlock procedure. + * + * @param strategy The unlock strategy. + * @return self instance for chaining. + */ + default T setUnlockStrategy(String strategy) { + return amend(UNLOCK_STRATEGY_OPTION, strategy); + } + + /** + * Get the strategy key. + * + * @return Unlock strategy. + */ + default Optional getUnlockStrategy() { + return Optional.ofNullable((String) getCapability(UNLOCK_STRATEGY_OPTION)); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/locking/SupportsUnlockSuccessTimeoutOption.java b/src/main/java/io/appium/java_client/android/options/locking/SupportsUnlockSuccessTimeoutOption.java new file mode 100644 index 000000000..487fbbdca --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/locking/SupportsUnlockSuccessTimeoutOption.java @@ -0,0 +1,53 @@ +/* + * 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.android.options.locking; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.time.Duration; +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toDuration; + +public interface SupportsUnlockSuccessTimeoutOption> extends + Capabilities, CanSetCapability { + String UNLOCK_SUCCESS_TIMEOUT_OPTION = "unlockSuccessTimeout"; + + /** + * Maximum timeout to wait until the device is unlocked. + * 2000 ms by default. + * + * @param timeout Timeout value. + * @return self instance for chaining. + */ + default T setUnlockSuccessTimeout(Duration timeout) { + return amend(UNLOCK_SUCCESS_TIMEOUT_OPTION, timeout.toMillis()); + } + + /** + * Get the timeout to wait until the device is unlocked. + * + * @return The timeout value. + */ + default Optional getUnlockSuccessTimeout() { + return Optional.ofNullable( + toDuration(getCapability(UNLOCK_SUCCESS_TIMEOUT_OPTION)) + ); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/locking/SupportsUnlockTypeOption.java b/src/main/java/io/appium/java_client/android/options/locking/SupportsUnlockTypeOption.java new file mode 100644 index 000000000..76b749fef --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/locking/SupportsUnlockTypeOption.java @@ -0,0 +1,49 @@ +/* + * 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.android.options.locking; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +public interface SupportsUnlockTypeOption> extends + Capabilities, CanSetCapability { + String UNLOCK_TYPE_OPTION = "unlockType"; + + /** + * Set one of the possible types of Android lock screens to unlock. + * Read the [Unlock tutorial](https://github.com/appium/appium-android-driver/blob/master/docs/UNLOCK.md) + * for more details. + * + * @param unlockType One of possible unlock types. + * @return self instance for chaining. + */ + default T setUnlockType(String unlockType) { + return amend(UNLOCK_TYPE_OPTION, unlockType); + } + + /** + * Get the unlock type. + * + * @return Unlock type. + */ + default Optional getUnlockType() { + return Optional.ofNullable((String) getCapability(UNLOCK_TYPE_OPTION)); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/mjpeg/SupportsMjpegScreenshotUrlOption.java b/src/main/java/io/appium/java_client/android/options/mjpeg/SupportsMjpegScreenshotUrlOption.java new file mode 100644 index 000000000..bb78ed30a --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/mjpeg/SupportsMjpegScreenshotUrlOption.java @@ -0,0 +1,70 @@ +/* + * 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.android.options.mjpeg; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Optional; + +public interface SupportsMjpegScreenshotUrlOption> extends + Capabilities, CanSetCapability { + String MJPEG_SCREENSHOT_URL_OPTION = "mjpegScreenshotUrl"; + + /** + * The URL of a service that provides realtime device screenshots in MJPEG format. + * If provided then the actual command to retrieve a screenshot will be + * requesting pictures from this service rather than directly from the server. + * + * @param url URL value. + * @return self instance for chaining. + */ + default T setMjpegScreenshotUrl(URL url) { + return amend(MJPEG_SCREENSHOT_URL_OPTION, url.toString()); + } + + /** + * The URL of a service that provides realtime device screenshots in MJPEG format. + * If provided then the actual command to retrieve a screenshot will be + * requesting pictures from this service rather than directly from the server. + * + * @param url URL value. + * @return self instance for chaining. + */ + default T setMjpegScreenshotUrl(String url) { + return amend(MJPEG_SCREENSHOT_URL_OPTION, url); + } + + /** + * Get URL of a service that provides realtime device screenshots in MJPEG format. + * + * @return URL value. + */ + default Optional getMjpegScreenshotUrl() { + return Optional.ofNullable(getCapability(MJPEG_SCREENSHOT_URL_OPTION)) + .map((v) -> { + try { + return new URL(String.valueOf(v)); + } catch (MalformedURLException e) { + throw new IllegalArgumentException(e); + } + }); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/mjpeg/SupportsMjpegServerPortOption.java b/src/main/java/io/appium/java_client/android/options/mjpeg/SupportsMjpegServerPortOption.java new file mode 100644 index 000000000..2649a5eb0 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/mjpeg/SupportsMjpegServerPortOption.java @@ -0,0 +1,52 @@ +/* + * 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.android.options.mjpeg; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toInteger; + +public interface SupportsMjpegServerPortOption> extends + Capabilities, CanSetCapability { + String MJPEG_SERVER_PORT_OPTION = "mjpegServerPort"; + + /** + * The number of the port UiAutomator2 server starts the MJPEG server on. + * If not provided then the screenshots broadcasting service on the remote + * device does not get exposed to a local port (e.g. no adb port forwarding + * is happening). + * + * @param port port number in range 0..65535 + * @return self instance for chaining. + */ + default T setMjpegServerPort(int port) { + return amend(MJPEG_SERVER_PORT_OPTION, port); + } + + /** + * Get the number of the port UiAutomator2 server starts the MJPEG server on. + * + * @return Port number. + */ + default Optional getMjpegServerPort() { + return Optional.ofNullable(toInteger(getCapability(MJPEG_SERVER_PORT_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/other/SupportsDisableSuppressAccessibilityServiceOption.java b/src/main/java/io/appium/java_client/android/options/other/SupportsDisableSuppressAccessibilityServiceOption.java new file mode 100644 index 000000000..eab017873 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/other/SupportsDisableSuppressAccessibilityServiceOption.java @@ -0,0 +1,63 @@ +/* + * 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.android.options.other; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toSafeBoolean; + +public interface SupportsDisableSuppressAccessibilityServiceOption> extends + Capabilities, CanSetCapability { + String DISABLE_SUPPRESS_ACCESSIBILITY_SERVICE_OPTION = "disableSuppressAccessibilityService"; + + /** + * Tells the instrumentation process to not suppress accessibility services + * during the automated test. + * + * @return self instance for chaining. + */ + default T disableSuppressAccessibilityService() { + return amend(DISABLE_SUPPRESS_ACCESSIBILITY_SERVICE_OPTION, true); + } + + /** + * Being set to true tells the instrumentation process to not suppress + * accessibility services during the automated test. This might be useful + * if your automated test needs these services. false by default. + * + * @param value Set it to true in order to suppress accessibility services. + * @return self instance for chaining. + */ + default T setDisableSuppressAccessibilityService(boolean value) { + return amend(DISABLE_SUPPRESS_ACCESSIBILITY_SERVICE_OPTION, value); + } + + /** + * Get whether to suppress accessibility services. + * + * @return True or false. + */ + default Optional doesDisableSuppressAccessibilityService() { + return Optional.ofNullable( + toSafeBoolean(getCapability(DISABLE_SUPPRESS_ACCESSIBILITY_SERVICE_OPTION)) + ); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/other/SupportsSkipLogCaptureOption.java b/src/main/java/io/appium/java_client/android/options/other/SupportsSkipLogCaptureOption.java new file mode 100644 index 000000000..79c48e2a2 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/other/SupportsSkipLogCaptureOption.java @@ -0,0 +1,59 @@ +/* + * 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.android.options.other; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toSafeBoolean; + +public interface SupportsSkipLogCaptureOption> extends + Capabilities, CanSetCapability { + String SKIP_LOG_CAPTURE_OPTION = "skipLogCapture"; + + /** + * Skips capturing logs such as logcat. + * + * @return self instance for chaining. + */ + default T skipLogCapture() { + return amend(SKIP_LOG_CAPTURE_OPTION, true); + } + + /** + * Skips to start capturing logs such as logcat. It might improve network performance. + * Log-related commands won't work if the capability is enabled. Defaults to false. + * + * @param value Set it to true in order to skip logcat capture. + * @return self instance for chaining. + */ + default T setSkipLogCapture(boolean value) { + return amend(SKIP_LOG_CAPTURE_OPTION, value); + } + + /** + * Get whether to skip capturing logs such as logcat. + * + * @return True or false. + */ + default Optional doesSkipLogCapture() { + return Optional.ofNullable(toSafeBoolean(getCapability(SKIP_LOG_CAPTURE_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/android/options/other/SupportsUserProfileOption.java b/src/main/java/io/appium/java_client/android/options/other/SupportsUserProfileOption.java new file mode 100644 index 000000000..0408abb1c --- /dev/null +++ b/src/main/java/io/appium/java_client/android/options/other/SupportsUserProfileOption.java @@ -0,0 +1,53 @@ +/* + * 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.android.options.other; + +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.CanSetCapability; +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toInteger; + +public interface SupportsUserProfileOption> extends + Capabilities, CanSetCapability { + String USER_PROFILE_OPTION = "userProfile"; + + /** + * Integer identifier of a user profile. By default, the app under test is + * installed for the currently active user, but in case it is necessary to + * test how the app performs while being installed for a user profile, + * which is different from the current one, then this capability might + * come in handy. + * + * @param profileId User profile identifier. + * @return self instance for chaining. + */ + default T setUserProfile(int profileId) { + return amend(USER_PROFILE_OPTION, profileId); + } + + /** + * Get the integer identifier of a user profile. + * + * @return User profile id. + */ + default Optional getUserProfile() { + return Optional.ofNullable(toInteger(getCapability(USER_PROFILE_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/remote/MobileBrowserType.java b/src/main/java/io/appium/java_client/remote/MobileBrowserType.java index 9ca3c79ed..bcd0382a2 100644 --- a/src/main/java/io/appium/java_client/remote/MobileBrowserType.java +++ b/src/main/java/io/appium/java_client/remote/MobileBrowserType.java @@ -17,7 +17,7 @@ package io.appium.java_client.remote; public interface MobileBrowserType { - + String ANDROID = "Android"; String SAFARI = "Safari"; String BROWSER = "Browser"; String CHROMIUM = "Chromium"; 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 30147838e..4a93d6774 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 @@ -16,8 +16,6 @@ package io.appium.java_client.service.local; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; import static org.openqa.selenium.remote.CapabilityType.PLATFORM_NAME; import com.google.common.collect.ImmutableList; @@ -25,6 +23,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import io.appium.java_client.remote.AndroidMobileCapabilityType; +import io.appium.java_client.remote.MobileBrowserType; import io.appium.java_client.remote.MobileCapabilityType; import io.appium.java_client.service.local.flags.ServerArgument; @@ -33,11 +32,10 @@ import org.apache.commons.lang3.SystemUtils; import org.apache.commons.validator.routines.InetAddressValidator; import org.openqa.selenium.Capabilities; +import org.openqa.selenium.MutableCapabilities; import org.openqa.selenium.Platform; import org.openqa.selenium.os.ExecutableFinder; import org.openqa.selenium.remote.Browser; -import org.openqa.selenium.remote.BrowserType; -import org.openqa.selenium.remote.DesiredCapabilities; import org.openqa.selenium.remote.service.DriverService; import javax.annotation.Nullable; @@ -54,7 +52,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.TimeUnit; import java.util.function.Function; public final class AppiumServiceBuilder @@ -81,7 +78,7 @@ public final class AppiumServiceBuilder private File appiumJS; private File node; private String ipAddress = BROADCAST_IP_ADDRESS; - private DesiredCapabilities capabilities; + private MutableCapabilities capabilities; private boolean autoQuoteCapabilitiesOnWindows = false; private static final Function APPIUM_JS_NOT_EXIST_ERROR = (fullPath) -> String.format( "The main Appium script does not exist at '%s'", fullPath.getAbsolutePath()); @@ -114,7 +111,7 @@ public int score(Capabilities capabilities) { } String browserName = capabilities.getBrowserName(); - if (Browser.CHROME.is(browserName) || browserName.equals(BrowserType.ANDROID) + if (Browser.CHROME.is(browserName) || browserName.equalsIgnoreCase(MobileBrowserType.ANDROID) || Browser.SAFARI.is(browserName)) { score++; } @@ -229,16 +226,16 @@ public AppiumServiceBuilder withArgument(ServerArgument argument, String value) /** * Adds a desired capabilities. * - * @param capabilities is an instance of {@link DesiredCapabilities}. + * @param capabilities is an instance of {@link Capabilities}. * @return the self-reference. */ - public AppiumServiceBuilder withCapabilities(DesiredCapabilities capabilities) { + public AppiumServiceBuilder withCapabilities(Capabilities capabilities) { if (this.capabilities == null) { - this.capabilities = capabilities; + this.capabilities = new MutableCapabilities(capabilities); } else { - DesiredCapabilities desiredCapabilities = new DesiredCapabilities(); - desiredCapabilities.merge(this.capabilities).merge(capabilities); - this.capabilities = desiredCapabilities; + MutableCapabilities caps = new MutableCapabilities(); + caps.merge(this.capabilities).merge(capabilities); + this.capabilities = caps; } return this; } @@ -246,13 +243,13 @@ public AppiumServiceBuilder withCapabilities(DesiredCapabilities capabilities) { /** * Adds a desired capabilities. * - * @param capabilities is an instance of {@link DesiredCapabilities}. + * @param capabilities is an instance of {@link Capabilities}. * @param autoQuoteCapabilitiesOnWindows automatically escape quote all * capabilities when calling appium. * This is required on windows systems only. * @return the self-reference. */ - public AppiumServiceBuilder withCapabilities(DesiredCapabilities capabilities, + public AppiumServiceBuilder withCapabilities(Capabilities capabilities, boolean autoQuoteCapabilitiesOnWindows) { this.autoQuoteCapabilitiesOnWindows = autoQuoteCapabilitiesOnWindows; return withCapabilities(capabilities); @@ -333,7 +330,7 @@ private String capabilitiesToQuotedCmdlineArg() { result.append(key).append(": ").append(value); } - return "{" + result.toString() + "}"; + return "{" + result + "}"; } private String capabilitiesToCmdlineArg() { diff --git a/src/test/java/io/appium/java_client/android/BaseAndroidTest.java b/src/test/java/io/appium/java_client/android/BaseAndroidTest.java index 3ebaa5dbf..5108c98ac 100644 --- a/src/test/java/io/appium/java_client/android/BaseAndroidTest.java +++ b/src/test/java/io/appium/java_client/android/BaseAndroidTest.java @@ -16,16 +16,13 @@ package io.appium.java_client.android; -import io.appium.java_client.remote.AutomationName; -import io.appium.java_client.remote.MobileCapabilityType; +import io.appium.java_client.android.options.UiAutomator2Options; import io.appium.java_client.service.local.AppiumDriverLocalService; import io.appium.java_client.service.local.AppiumServerHasNotBeenStartedLocallyException; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.openqa.selenium.remote.DesiredCapabilities; - import static io.appium.java_client.TestResources.apiDemosApk; public class BaseAndroidTest { @@ -44,12 +41,11 @@ public class BaseAndroidTest { "An appium server node is not started!"); } - DesiredCapabilities capabilities = new DesiredCapabilities(); - capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.ANDROID_UIAUTOMATOR2); - capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator"); - capabilities.setCapability(MobileCapabilityType.APP, apiDemosApk().toAbsolutePath().toString()); - capabilities.setCapability("eventTimings", true); - driver = new AndroidDriver<>(service.getUrl(), capabilities); + UiAutomator2Options options = new UiAutomator2Options() + .setDeviceName("Android Emulator") + .setApp(apiDemosApk().toAbsolutePath().toString()) + .setEventTimings(); + driver = new AndroidDriver<>(service.getUrl(), options); } /** diff --git a/src/test/java/io/appium/java_client/service/local/StartingAppLocallyTest.java b/src/test/java/io/appium/java_client/service/local/StartingAppLocallyTest.java index a3d1d0e60..e4db8038b 100644 --- a/src/test/java/io/appium/java_client/service/local/StartingAppLocallyTest.java +++ b/src/test/java/io/appium/java_client/service/local/StartingAppLocallyTest.java @@ -26,9 +26,9 @@ import static org.junit.Assert.assertTrue; import io.appium.java_client.android.AndroidDriver; +import io.appium.java_client.android.options.UiAutomator2Options; import io.appium.java_client.ios.BaseIOSTest; import io.appium.java_client.ios.IOSDriver; -import io.appium.java_client.remote.AndroidMobileCapabilityType; import io.appium.java_client.remote.AutomationName; import io.appium.java_client.remote.IOSMobileCapabilityType; import io.appium.java_client.remote.MobileCapabilityType; @@ -39,21 +39,22 @@ import org.openqa.selenium.Capabilities; import org.openqa.selenium.remote.DesiredCapabilities; +import java.time.Duration; + public class StartingAppLocallyTest { @Test public void startingAndroidAppWithCapabilitiesOnlyTest() { - DesiredCapabilities capabilities = new DesiredCapabilities(); - capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator"); - capabilities.setCapability(MobileCapabilityType.APP, apiDemosApk().toAbsolutePath().toString()); - capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.ANDROID_UIAUTOMATOR2); - - AndroidDriver driver = new AndroidDriver<>(capabilities); + AndroidDriver driver = new AndroidDriver<>(new UiAutomator2Options() + .setDeviceName("Android Emulator") + .setApp(apiDemosApk().toAbsolutePath().toString())); try { Capabilities caps = driver.getCapabilities(); - assertEquals(AutomationName.APPIUM, caps.getCapability(MobileCapabilityType.AUTOMATION_NAME)); - assertEquals(MobilePlatform.ANDROID, caps.getCapability(MobileCapabilityType.PLATFORM_NAME)); - assertNotEquals(null, caps.getCapability(MobileCapabilityType.DEVICE_NAME)); + assertTrue(MobilePlatform.ANDROID.equalsIgnoreCase( + (String) caps.getCapability(MobileCapabilityType.PLATFORM_NAME)) + ); + assertNotNull(AutomationName.ANDROID_UIAUTOMATOR2, caps.getCapability(MobileCapabilityType.AUTOMATION_NAME)); + assertNotNull(caps.getCapability(MobileCapabilityType.DEVICE_NAME)); assertEquals(apiDemosApk().toAbsolutePath().toString(), caps.getCapability(MobileCapabilityType.APP)); } finally { driver.quit(); @@ -61,54 +62,53 @@ public class StartingAppLocallyTest { } @Test public void startingAndroidAppWithCapabilitiesAndServiceTest() { - DesiredCapabilities capabilities = new DesiredCapabilities(); - capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "Android Emulator"); - capabilities.setCapability(MobileCapabilityType.APP, apiDemosApk().toAbsolutePath().toString()); - AppiumServiceBuilder builder = new AppiumServiceBuilder() .withArgument(GeneralServerFlag.SESSION_OVERRIDE) .withArgument(GeneralServerFlag.STRICT_CAPS); - AndroidDriver driver = new AndroidDriver<>(builder, capabilities); + AndroidDriver driver = new AndroidDriver<>(builder, new UiAutomator2Options() + .setDeviceName("Android Emulator") + .setApp(apiDemosApk().toAbsolutePath().toString())); try { Capabilities caps = driver.getCapabilities(); - assertEquals(MobilePlatform.ANDROID, caps.getCapability(MobileCapabilityType.PLATFORM_NAME)); - assertNotEquals(null, caps.getCapability(MobileCapabilityType.DEVICE_NAME)); + assertTrue(MobilePlatform.ANDROID.equalsIgnoreCase( + (String) caps.getCapability(MobileCapabilityType.PLATFORM_NAME)) + ); + assertNotNull(caps.getCapability(MobileCapabilityType.DEVICE_NAME)); } finally { driver.quit(); } } @Test public void startingAndroidAppWithCapabilitiesAndFlagsOnServerSideTest() { - 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, apiDemosApk().toAbsolutePath().toString()); + UiAutomator2Options serverOptions = new UiAutomator2Options() + .setDeviceName("Android Emulator") + .fullReset() + .setNewCommandTimeout(Duration.ofSeconds(60)) + .setApp(apiDemosApk().toAbsolutePath().toString()); WebDriverManager chromeManager = chromedriver(); chromeManager.setup(); - serverCapabilities.setCapability(AndroidMobileCapabilityType.CHROMEDRIVER_EXECUTABLE, - chromeManager.getDownloadedDriverPath()); + serverOptions.setChromedriverExecutable(chromeManager.getDownloadedDriverPath()); AppiumServiceBuilder builder = new AppiumServiceBuilder() .withArgument(GeneralServerFlag.SESSION_OVERRIDE) - .withArgument(GeneralServerFlag.STRICT_CAPS).withCapabilities(serverCapabilities); + .withArgument(GeneralServerFlag.STRICT_CAPS) + .withCapabilities(serverOptions); - DesiredCapabilities clientCapabilities = new DesiredCapabilities(); - clientCapabilities - .setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "io.appium.android.apis"); - clientCapabilities - .setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".view.WebView1"); + UiAutomator2Options clientOptions = new UiAutomator2Options() + .setAppPackage("io.appium.android.apis") + .setAppActivity(".view.WebView1"); - AndroidDriver driver = new AndroidDriver<>(builder, clientCapabilities); + AndroidDriver driver = new AndroidDriver<>(builder, clientOptions); try { Capabilities caps = driver.getCapabilities(); - assertEquals(MobilePlatform.ANDROID, caps.getCapability(MobileCapabilityType.PLATFORM_NAME)); - assertNotEquals(null, caps.getCapability(MobileCapabilityType.DEVICE_NAME)); + assertTrue(MobilePlatform.ANDROID.equalsIgnoreCase( + (String) caps.getCapability(MobileCapabilityType.PLATFORM_NAME)) + ); + assertNotNull(caps.getCapability(MobileCapabilityType.DEVICE_NAME)); } finally { driver.quit(); } From 197fbb57702e897872a532639e8c61e482d7033e Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Mon, 25 Oct 2021 19:52:56 +0200 Subject: [PATCH 2/7] Tune caps cloning --- .../java_client/remote/options/BaseOptions.java | 13 +++++++++++++ .../service/local/AppiumServiceBuilder.java | 15 +++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/main/java/io/appium/java_client/remote/options/BaseOptions.java b/src/main/java/io/appium/java_client/remote/options/BaseOptions.java index ff575989f..303127a8e 100644 --- a/src/main/java/io/appium/java_client/remote/options/BaseOptions.java +++ b/src/main/java/io/appium/java_client/remote/options/BaseOptions.java @@ -23,6 +23,8 @@ import org.openqa.selenium.remote.CapabilityType; import javax.annotation.Nullable; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import java.util.Map; import java.util.stream.Collectors; @@ -84,6 +86,17 @@ public T merge(Capabilities extraCapabilities) { return (T) this; } + @SuppressWarnings("MethodDoesntCallSuperMethod") + public T clone() { + try { + Constructor constructor = getClass().getConstructor(Capabilities.class); + //noinspection unchecked + return (T) constructor.newInstance(this); + } catch (InvocationTargetException | NoSuchMethodException | InstantiationException | IllegalAccessException e) { + throw new IllegalStateException(e); + } + } + @Override public void setCapability(String key, @Nullable Object value) { Require.nonNull("Capability name", key); 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 4a93d6774..806248ed3 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 @@ -25,6 +25,7 @@ import io.appium.java_client.remote.AndroidMobileCapabilityType; import io.appium.java_client.remote.MobileBrowserType; import io.appium.java_client.remote.MobileCapabilityType; +import io.appium.java_client.remote.options.BaseOptions; import io.appium.java_client.service.local.flags.ServerArgument; import org.apache.commons.io.IOUtils; @@ -78,7 +79,7 @@ public final class AppiumServiceBuilder private File appiumJS; private File node; private String ipAddress = BROADCAST_IP_ADDRESS; - private MutableCapabilities capabilities; + private Capabilities capabilities; private boolean autoQuoteCapabilitiesOnWindows = false; private static final Function APPIUM_JS_NOT_EXIST_ERROR = (fullPath) -> String.format( "The main Appium script does not exist at '%s'", fullPath.getAbsolutePath()); @@ -224,16 +225,18 @@ public AppiumServiceBuilder withArgument(ServerArgument argument, String value) } /** - * Adds a desired capabilities. + * Adds capabilities. * * @param capabilities is an instance of {@link Capabilities}. * @return the self-reference. */ public AppiumServiceBuilder withCapabilities(Capabilities capabilities) { + MutableCapabilities caps = capabilities instanceof BaseOptions + ? ((BaseOptions) capabilities).clone() + : new MutableCapabilities(); if (this.capabilities == null) { - this.capabilities = new MutableCapabilities(capabilities); + this.capabilities = caps.merge(capabilities); } else { - MutableCapabilities caps = new MutableCapabilities(); caps.merge(this.capabilities).merge(capabilities); this.capabilities = caps; } @@ -241,9 +244,9 @@ public AppiumServiceBuilder withCapabilities(Capabilities capabilities) { } /** - * Adds a desired capabilities. + * Adds capabilities. * - * @param capabilities is an instance of {@link Capabilities}. + * @param capabilities is an instance of {@link Capabilities}. * @param autoQuoteCapabilitiesOnWindows automatically escape quote all * capabilities when calling appium. * This is required on windows systems only. From 3cef0b90b6e07a3045e15c9caaa88af1fab828ff Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Mon, 25 Oct 2021 20:02:02 +0200 Subject: [PATCH 3/7] Fix style --- .../io/appium/java_client/remote/options/BaseOptions.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/appium/java_client/remote/options/BaseOptions.java b/src/main/java/io/appium/java_client/remote/options/BaseOptions.java index 303127a8e..e2bfb9e49 100644 --- a/src/main/java/io/appium/java_client/remote/options/BaseOptions.java +++ b/src/main/java/io/appium/java_client/remote/options/BaseOptions.java @@ -86,13 +86,19 @@ public T merge(Capabilities extraCapabilities) { return (T) this; } + /** + * Makes a deep clone of the current Options instance. + * + * @return A deep instance clone. + */ @SuppressWarnings("MethodDoesntCallSuperMethod") public T clone() { try { Constructor constructor = getClass().getConstructor(Capabilities.class); //noinspection unchecked return (T) constructor.newInstance(this); - } catch (InvocationTargetException | NoSuchMethodException | InstantiationException | IllegalAccessException e) { + } catch (InvocationTargetException | NoSuchMethodException + | InstantiationException | IllegalAccessException e) { throw new IllegalStateException(e); } } From 66818111f57f1c6d1c4e27721ebb9907c45f75aa Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Mon, 25 Oct 2021 20:13:10 +0200 Subject: [PATCH 4/7] Update merge implementation --- .../remote/options/BaseOptions.java | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/main/java/io/appium/java_client/remote/options/BaseOptions.java b/src/main/java/io/appium/java_client/remote/options/BaseOptions.java index e2bfb9e49..bb597d195 100644 --- a/src/main/java/io/appium/java_client/remote/options/BaseOptions.java +++ b/src/main/java/io/appium/java_client/remote/options/BaseOptions.java @@ -38,10 +38,14 @@ * @param The child class for a proper chaining. */ @SuppressWarnings({"unused", "UnusedReturnValue"}) -public class BaseOptions> extends MutableCapabilities - implements CanSetCapability, SupportsAutomationNameOption, - SupportsEventTimingsOption, SupportsPrintPageSourceOnFindFailureOption, - SupportsNoResetOption, SupportsFullResetOption, SupportsNewCommandTimeoutOption, +public class BaseOptions> extends MutableCapabilities implements + CanSetCapability, + SupportsAutomationNameOption, + SupportsEventTimingsOption, + SupportsPrintPageSourceOnFindFailureOption, + SupportsNoResetOption, + SupportsFullResetOption, + SupportsNewCommandTimeoutOption, SupportsPlatformVersionOption { private static final AcceptedW3CCapabilityKeys W3C_KEY_PATTERNS = new AcceptedW3CCapabilityKeys(); @@ -81,9 +85,13 @@ public Map asMap() { @Override public T merge(Capabilities extraCapabilities) { - super.merge(extraCapabilities); - //noinspection unchecked - return (T) this; + T result = this.clone(); + extraCapabilities.asMap().forEach((key, value) -> { + if (value != null) { + result.setCapability(key, value); + } + }); + return result; } /** From a359d07143ed742e91f48f47b4f981d2d10e6e00 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Mon, 25 Oct 2021 21:19:54 +0200 Subject: [PATCH 5/7] Simplify merge --- .../service/local/AppiumServiceBuilder.java | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) 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 806248ed3..93124226a 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 @@ -25,7 +25,6 @@ import io.appium.java_client.remote.AndroidMobileCapabilityType; import io.appium.java_client.remote.MobileBrowserType; import io.appium.java_client.remote.MobileCapabilityType; -import io.appium.java_client.remote.options.BaseOptions; import io.appium.java_client.service.local.flags.ServerArgument; import org.apache.commons.io.IOUtils; @@ -33,7 +32,6 @@ import org.apache.commons.lang3.SystemUtils; import org.apache.commons.validator.routines.InetAddressValidator; import org.openqa.selenium.Capabilities; -import org.openqa.selenium.MutableCapabilities; import org.openqa.selenium.Platform; import org.openqa.selenium.os.ExecutableFinder; import org.openqa.selenium.remote.Browser; @@ -231,15 +229,8 @@ public AppiumServiceBuilder withArgument(ServerArgument argument, String value) * @return the self-reference. */ public AppiumServiceBuilder withCapabilities(Capabilities capabilities) { - MutableCapabilities caps = capabilities instanceof BaseOptions - ? ((BaseOptions) capabilities).clone() - : new MutableCapabilities(); - if (this.capabilities == null) { - this.capabilities = caps.merge(capabilities); - } else { - caps.merge(this.capabilities).merge(capabilities); - this.capabilities = caps; - } + this.capabilities = (this.capabilities == null ? capabilities : this.capabilities) + .merge(capabilities); return this; } From 7974600c1bd380b0142a74c225b35bdac29a1f50 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Tue, 26 Oct 2021 07:53:40 +0200 Subject: [PATCH 6/7] fix: Update Service to properly work with options --- .../options/app/SupportsAutoGrantPermissionsOption.java | 2 +- .../java_client/service/local/StartingAppLocallyTest.java | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/appium/java_client/android/options/app/SupportsAutoGrantPermissionsOption.java b/src/main/java/io/appium/java_client/android/options/app/SupportsAutoGrantPermissionsOption.java index 97402c867..7a7d6cde1 100644 --- a/src/main/java/io/appium/java_client/android/options/app/SupportsAutoGrantPermissionsOption.java +++ b/src/main/java/io/appium/java_client/android/options/app/SupportsAutoGrantPermissionsOption.java @@ -34,7 +34,7 @@ public interface SupportsAutoGrantPermissionsOption> ex * * @return self instance for chaining. */ - default T setAutoGrantPermissions() { + default T autoGrantPermissions() { return amend(AUTO_GRANT_PERMISSIONS_OPTION, true); } diff --git a/src/test/java/io/appium/java_client/service/local/StartingAppLocallyTest.java b/src/test/java/io/appium/java_client/service/local/StartingAppLocallyTest.java index e4db8038b..b31ec5440 100644 --- a/src/test/java/io/appium/java_client/service/local/StartingAppLocallyTest.java +++ b/src/test/java/io/appium/java_client/service/local/StartingAppLocallyTest.java @@ -46,6 +46,7 @@ public class StartingAppLocallyTest { @Test public void startingAndroidAppWithCapabilitiesOnlyTest() { AndroidDriver driver = new AndroidDriver<>(new UiAutomator2Options() .setDeviceName("Android Emulator") + .autoGrantPermissions() .setApp(apiDemosApk().toAbsolutePath().toString())); try { Capabilities caps = driver.getCapabilities(); @@ -53,7 +54,7 @@ public class StartingAppLocallyTest { assertTrue(MobilePlatform.ANDROID.equalsIgnoreCase( (String) caps.getCapability(MobileCapabilityType.PLATFORM_NAME)) ); - assertNotNull(AutomationName.ANDROID_UIAUTOMATOR2, caps.getCapability(MobileCapabilityType.AUTOMATION_NAME)); + assertEquals(AutomationName.ANDROID_UIAUTOMATOR2, caps.getCapability(MobileCapabilityType.AUTOMATION_NAME)); assertNotNull(caps.getCapability(MobileCapabilityType.DEVICE_NAME)); assertEquals(apiDemosApk().toAbsolutePath().toString(), caps.getCapability(MobileCapabilityType.APP)); } finally { @@ -68,6 +69,7 @@ public class StartingAppLocallyTest { AndroidDriver driver = new AndroidDriver<>(builder, new UiAutomator2Options() .setDeviceName("Android Emulator") + .autoGrantPermissions() .setApp(apiDemosApk().toAbsolutePath().toString())); try { Capabilities caps = driver.getCapabilities(); @@ -85,6 +87,7 @@ public class StartingAppLocallyTest { UiAutomator2Options serverOptions = new UiAutomator2Options() .setDeviceName("Android Emulator") .fullReset() + .autoGrantPermissions() .setNewCommandTimeout(Duration.ofSeconds(60)) .setApp(apiDemosApk().toAbsolutePath().toString()); From 085794eb21d1a87c21355607b84223673e965d17 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Tue, 26 Oct 2021 08:06:20 +0200 Subject: [PATCH 7/7] Update checks --- .../service/local/StartingAppLocallyTest.java | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/test/java/io/appium/java_client/service/local/StartingAppLocallyTest.java b/src/test/java/io/appium/java_client/service/local/StartingAppLocallyTest.java index b31ec5440..612db0aed 100644 --- a/src/test/java/io/appium/java_client/service/local/StartingAppLocallyTest.java +++ b/src/test/java/io/appium/java_client/service/local/StartingAppLocallyTest.java @@ -21,7 +21,6 @@ import static io.github.bonigarcia.wdm.WebDriverManager.chromedriver; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -43,7 +42,8 @@ public class StartingAppLocallyTest { - @Test public void startingAndroidAppWithCapabilitiesOnlyTest() { + @Test + public void startingAndroidAppWithCapabilitiesOnlyTest() { AndroidDriver driver = new AndroidDriver<>(new UiAutomator2Options() .setDeviceName("Android Emulator") .autoGrantPermissions() @@ -62,7 +62,8 @@ public class StartingAppLocallyTest { } } - @Test public void startingAndroidAppWithCapabilitiesAndServiceTest() { + @Test + public void startingAndroidAppWithCapabilitiesAndServiceTest() { AppiumServiceBuilder builder = new AppiumServiceBuilder() .withArgument(GeneralServerFlag.SESSION_OVERRIDE) .withArgument(GeneralServerFlag.STRICT_CAPS); @@ -83,7 +84,8 @@ public class StartingAppLocallyTest { } } - @Test public void startingAndroidAppWithCapabilitiesAndFlagsOnServerSideTest() { + @Test + public void startingAndroidAppWithCapabilitiesAndFlagsOnServerSideTest() { UiAutomator2Options serverOptions = new UiAutomator2Options() .setDeviceName("Android Emulator") .fullReset() @@ -117,7 +119,8 @@ public class StartingAppLocallyTest { } } - @Test public void startingIOSAppWithCapabilitiesOnlyTest() { + @Test + public void startingIOSAppWithCapabilitiesOnlyTest() { DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, BaseIOSTest.PLATFORM_VERSION); //sometimes environment has performance problems @@ -133,7 +136,7 @@ public class StartingAppLocallyTest { assertEquals(AutomationName.IOS_XCUI_TEST, caps.getCapability(MobileCapabilityType.AUTOMATION_NAME)); assertEquals(MobilePlatform.IOS, caps.getCapability(MobileCapabilityType.PLATFORM_NAME)); - assertNotEquals(null, caps.getCapability(MobileCapabilityType.DEVICE_NAME)); + assertNotNull(caps.getCapability(MobileCapabilityType.DEVICE_NAME)); assertEquals(BaseIOSTest.PLATFORM_VERSION, caps.getCapability(MobileCapabilityType.PLATFORM_VERSION)); assertEquals(uiCatalogAppZip().toAbsolutePath().toString(), caps.getCapability(MobileCapabilityType.APP)); } finally { @@ -142,7 +145,8 @@ public class StartingAppLocallyTest { } - @Test public void startingIOSAppWithCapabilitiesAndServiceTest() { + @Test + public void startingIOSAppWithCapabilitiesAndServiceTest() { DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, BaseIOSTest.DEVICE_NAME); capabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.IOS_XCUI_TEST); @@ -161,18 +165,19 @@ public class StartingAppLocallyTest { Capabilities caps = driver.getCapabilities(); assertTrue(caps.getCapability(MobileCapabilityType.PLATFORM_NAME) .toString().equalsIgnoreCase(MobilePlatform.IOS)); - assertNotNull(null, caps.getCapability(MobileCapabilityType.DEVICE_NAME)); + assertNotNull(caps.getCapability(MobileCapabilityType.DEVICE_NAME)); } finally { driver.quit(); } } - @Test public void startingIOSAppWithCapabilitiesAndFlagsOnServerSideTest() { + @Test + public void startingIOSAppWithCapabilitiesAndFlagsOnServerSideTest() { DesiredCapabilities serverCapabilities = new DesiredCapabilities(); serverCapabilities.setCapability(MobileCapabilityType.DEVICE_NAME, BaseIOSTest.DEVICE_NAME); serverCapabilities.setCapability(MobileCapabilityType.AUTOMATION_NAME, AutomationName.IOS_XCUI_TEST); serverCapabilities.setCapability(IOSMobileCapabilityType.WDA_LAUNCH_TIMEOUT, - BaseIOSTest.WDA_LAUNCH_TIMEOUT.toMillis()); //some environment is too slow + BaseIOSTest.WDA_LAUNCH_TIMEOUT.toMillis()); //some environment is too slow serverCapabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, BaseIOSTest.PLATFORM_VERSION); serverCapabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, MobilePlatform.IOS); @@ -188,7 +193,7 @@ public class StartingAppLocallyTest { Capabilities caps = driver.getCapabilities(); assertTrue(caps.getCapability(MobileCapabilityType.PLATFORM_NAME) .toString().equalsIgnoreCase(MobilePlatform.IOS)); - assertNotEquals(null, caps.getCapability(MobileCapabilityType.DEVICE_NAME)); + assertNotNull(caps.getCapability(MobileCapabilityType.DEVICE_NAME)); assertFalse(driver.isBrowser()); } finally { driver.quit();