diff --git a/src/main/java/io/appium/java_client/AppiumDriver.java b/src/main/java/io/appium/java_client/AppiumDriver.java index ba932c959..abfdf126f 100644 --- a/src/main/java/io/appium/java_client/AppiumDriver.java +++ b/src/main/java/io/appium/java_client/AppiumDriver.java @@ -17,6 +17,7 @@ package io.appium.java_client; import static io.appium.java_client.internal.CapabilityHelpers.APPIUM_PREFIX; +import static io.appium.java_client.remote.MobileCapabilityType.AUTOMATION_NAME; import static io.appium.java_client.remote.MobileCapabilityType.PLATFORM_NAME; import static org.apache.commons.lang3.StringUtils.isBlank; @@ -129,16 +130,36 @@ public AppiumDriver(Capabilities capabilities) { * @param originalCapabilities the given {@link Capabilities}. * @param defaultName a {@link MobileCapabilityType#PLATFORM_NAME} value which has * to be set up - * @return {@link Capabilities} with changed mobile platform name value or the original capabilities + * @return {@link Capabilities} with changed platform name value or the original capabilities */ - protected static Capabilities ensurePlatformName(Capabilities originalCapabilities, - String defaultName) { + protected static Capabilities ensurePlatformName( + Capabilities originalCapabilities, String defaultName) { String currentName = (String) originalCapabilities.getCapability(PLATFORM_NAME); return isBlank(currentName) ? originalCapabilities.merge(new ImmutableCapabilities(PLATFORM_NAME, defaultName)) : originalCapabilities; } + /** + * Changes automation name if it is not set and returns merged capabilities. + * + * @param originalCapabilities the given {@link Capabilities}. + * @param defaultName a {@link MobileCapabilityType#AUTOMATION_NAME} value which has + * to be set up + * @return {@link Capabilities} with changed mobile automation name value or the original capabilities + */ + protected static Capabilities ensureAutomationName( + Capabilities originalCapabilities, String defaultName) { + String currentAutomationName = CapabilityHelpers.getCapability( + originalCapabilities, AUTOMATION_NAME, String.class); + if (isBlank(currentAutomationName)) { + String capabilityName = originalCapabilities.getCapabilityNames() + .contains(AUTOMATION_NAME) ? AUTOMATION_NAME : APPIUM_PREFIX + AUTOMATION_NAME; + return originalCapabilities.merge(new ImmutableCapabilities(capabilityName, defaultName)); + } + return originalCapabilities; + } + /** * Changes platform and automation names if they are not set * and returns merged capabilities. @@ -147,27 +168,12 @@ protected static Capabilities ensurePlatformName(Capabilities originalCapabiliti * @param defaultPlatformName a {@link MobileCapabilityType#PLATFORM_NAME} value which has * to be set up * @param defaultAutomationName The default automation name to set up for this class - * @return {@link Capabilities} with changed mobile platform name value or the original capabilities + * @return {@link Capabilities} with changed platform/automation name value or the original capabilities */ protected static Capabilities ensurePlatformAndAutomationNames( Capabilities originalCapabilities, String defaultPlatformName, String defaultAutomationName) { - MutableCapabilities toMerge = new MutableCapabilities(); - String currentPlatformName = (String) originalCapabilities.getCapability(PLATFORM_NAME); - if (isBlank(currentPlatformName)) { - toMerge.setCapability(PLATFORM_NAME, defaultPlatformName); - } - String currentAutomationName = CapabilityHelpers.getCapability( - originalCapabilities, MobileCapabilityType.AUTOMATION_NAME, String.class); - if (isBlank(currentAutomationName)) { - toMerge.setCapability(originalCapabilities.getCapabilityNames() - .contains(MobileCapabilityType.AUTOMATION_NAME) - ? MobileCapabilityType.AUTOMATION_NAME - : APPIUM_PREFIX + MobileCapabilityType.AUTOMATION_NAME, - defaultAutomationName); - } - return toMerge.getCapabilityNames().isEmpty() - ? originalCapabilities - : originalCapabilities.merge(toMerge); + Capabilities capsWithPlatformFixed = ensurePlatformName(originalCapabilities, defaultPlatformName); + return ensureAutomationName(capsWithPlatformFixed, defaultAutomationName); } @Override diff --git a/src/main/java/io/appium/java_client/gecko/GeckoDriver.java b/src/main/java/io/appium/java_client/gecko/GeckoDriver.java new file mode 100644 index 000000000..bd85fcfc9 --- /dev/null +++ b/src/main/java/io/appium/java_client/gecko/GeckoDriver.java @@ -0,0 +1,79 @@ +/* + * 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.gecko; + +import io.appium.java_client.AppiumDriver; +import io.appium.java_client.remote.AutomationName; +import io.appium.java_client.service.local.AppiumDriverLocalService; +import io.appium.java_client.service.local.AppiumServiceBuilder; +import org.openqa.selenium.Capabilities; +import org.openqa.selenium.remote.HttpCommandExecutor; +import org.openqa.selenium.remote.http.HttpClient; + +import java.net.URL; + +/** + * GeckoDriver is an officially supported Appium driver + * created to automate Mobile browsers and web views based on + * the Gecko engine. The driver uses W3C + * WebDriver protocol and is built on top of Mozilla's geckodriver + * server. Read https://github.com/appium/appium-geckodriver + * for more details on how to configure and use it. + * + * @since Appium 1.20.0 + */ +public class GeckoDriver extends AppiumDriver { + private static final String AUTOMATION_NAME = AutomationName.GECKO; + + public GeckoDriver(HttpCommandExecutor executor, Capabilities capabilities) { + super(executor, ensureAutomationName(capabilities, AUTOMATION_NAME)); + } + + public GeckoDriver(URL remoteAddress, Capabilities capabilities) { + super(remoteAddress, ensureAutomationName(capabilities, AUTOMATION_NAME)); + } + + public GeckoDriver(URL remoteAddress, HttpClient.Factory httpClientFactory, Capabilities capabilities) { + super(remoteAddress, httpClientFactory, ensureAutomationName(capabilities, AUTOMATION_NAME)); + } + + public GeckoDriver(AppiumDriverLocalService service, Capabilities capabilities) { + super(service, ensureAutomationName(capabilities, AUTOMATION_NAME)); + } + + public GeckoDriver(AppiumDriverLocalService service, HttpClient.Factory httpClientFactory, + Capabilities capabilities) { + super(service, httpClientFactory, ensureAutomationName(capabilities, AUTOMATION_NAME)); + } + + public GeckoDriver(AppiumServiceBuilder builder, Capabilities capabilities) { + super(builder, ensureAutomationName(capabilities, AUTOMATION_NAME)); + } + + public GeckoDriver(AppiumServiceBuilder builder, HttpClient.Factory httpClientFactory, + Capabilities capabilities) { + super(builder, httpClientFactory, ensureAutomationName(capabilities, AUTOMATION_NAME)); + } + + public GeckoDriver(HttpClient.Factory httpClientFactory, Capabilities capabilities) { + super(httpClientFactory, ensureAutomationName(capabilities, AUTOMATION_NAME)); + } + + public GeckoDriver(Capabilities capabilities) { + super(ensureAutomationName(capabilities, AUTOMATION_NAME)); + } +} diff --git a/src/main/java/io/appium/java_client/gecko/options/GeckoOptions.java b/src/main/java/io/appium/java_client/gecko/options/GeckoOptions.java new file mode 100644 index 000000000..084400142 --- /dev/null +++ b/src/main/java/io/appium/java_client/gecko/options/GeckoOptions.java @@ -0,0 +1,66 @@ +/* + * 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.gecko.options; + +import io.appium.java_client.mac.options.SupportsSystemPortOption; +import io.appium.java_client.remote.AutomationName; +import io.appium.java_client.remote.options.BaseOptions; +import io.appium.java_client.remote.options.SupportsAcceptInsecureCertsOption; +import io.appium.java_client.remote.options.SupportsBrowserNameOption; +import io.appium.java_client.remote.options.SupportsBrowserVersionOption; +import io.appium.java_client.remote.options.SupportsPageLoadStrategyOption; +import io.appium.java_client.remote.options.SupportsProxyOption; +import io.appium.java_client.remote.options.SupportsSetWindowRectOption; +import io.appium.java_client.remote.options.SupportsUnhandledPromptBehaviorOption; +import org.openqa.selenium.Capabilities; + +import java.util.Map; + +/** + * https://github.com/appium/appium-geckodriver#usage + */ +public class GeckoOptions extends BaseOptions implements + SupportsBrowserNameOption, + SupportsBrowserVersionOption, + SupportsMarionettePortOption, + SupportsSystemPortOption, + SupportsVerbosityOption, + SupportsAndroidStorageOption, + SupportsMozFirefoxOptionsOption, + SupportsAcceptInsecureCertsOption, + SupportsPageLoadStrategyOption, + SupportsSetWindowRectOption, + SupportsProxyOption, + SupportsUnhandledPromptBehaviorOption { + public GeckoOptions() { + setCommonOptions(); + } + + public GeckoOptions(Capabilities source) { + super(source); + setCommonOptions(); + } + + public GeckoOptions(Map source) { + super(source); + setCommonOptions(); + } + + private void setCommonOptions() { + setAutomationName(AutomationName.GECKO); + } +} diff --git a/src/main/java/io/appium/java_client/gecko/options/SupportsAndroidStorageOption.java b/src/main/java/io/appium/java_client/gecko/options/SupportsAndroidStorageOption.java new file mode 100644 index 000000000..b85438271 --- /dev/null +++ b/src/main/java/io/appium/java_client/gecko/options/SupportsAndroidStorageOption.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.gecko.options; + +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 SupportsAndroidStorageOption> extends + Capabilities, CanSetCapability { + String ANDROID_STORAGE_OPTION = "androidStorage"; + + /** + * See + * https://firefox-source-docs.mozilla.org/testing/geckodriver + * /Flags.html#code-android-storage-var-android-storage-var-code + * + * @param storage One of supported Android storage types. + * @return self instance for chaining. + */ + default T setAndroidStorage(String storage) { + return amend(ANDROID_STORAGE_OPTION, storage); + } + + /** + * Get the currently set storage type. + * + * @return String representing the name of the device. + */ + default Optional getAndroidStorage() { + return Optional.ofNullable((String) getCapability(ANDROID_STORAGE_OPTION)); + } +} diff --git a/src/main/java/io/appium/java_client/gecko/options/SupportsMarionettePortOption.java b/src/main/java/io/appium/java_client/gecko/options/SupportsMarionettePortOption.java new file mode 100644 index 000000000..75bbcbf60 --- /dev/null +++ b/src/main/java/io/appium/java_client/gecko/options/SupportsMarionettePortOption.java @@ -0,0 +1,54 @@ +/* + * 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.gecko.options; + +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 SupportsMarionettePortOption> extends + Capabilities, CanSetCapability { + String MARIONETTE_PORT_OPTION = "marionettePort"; + + /** + * Selects the port for Geckodriver’s connection to the Marionette + * remote protocol. The existing Firefox instance must have Marionette + * enabled. To enable the remote protocol in Firefox, you can pass the + * -marionette flag. Unless the marionette.port preference has been + * user-set, Marionette will listen on port 2828, which is the default + * value for this capability. + * + * @param port port number in range 0..65535 + * @return self instance for chaining. + */ + default T setMarionettePort(int port) { + return amend(MARIONETTE_PORT_OPTION, port); + } + + /** + * Get the number of the port for the Marionette server to listen on. + * + * @return Marionette port value. + */ + default Optional getMarionettePort() { + return Optional.ofNullable(toInteger(getCapability(MARIONETTE_PORT_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/gecko/options/SupportsMozFirefoxOptionsOption.java b/src/main/java/io/appium/java_client/gecko/options/SupportsMozFirefoxOptionsOption.java new file mode 100644 index 000000000..16b2d9579 --- /dev/null +++ b/src/main/java/io/appium/java_client/gecko/options/SupportsMozFirefoxOptionsOption.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.gecko.options; + +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 SupportsMozFirefoxOptionsOption> extends + Capabilities, CanSetCapability { + String MOZ_FIREFOX_OPTIONS_OPTION = "moz:firefoxOptions"; + + /** + * See https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions. + * + * @param options Firefox options mapping. + * @return self instance for chaining. + */ + default T setMozFirefoxOptions(Map options) { + return amend(MOZ_FIREFOX_OPTIONS_OPTION, options); + } + + /** + * Get Firefox options mapping. + * + * @return Firefox options mapping. + */ + default Optional> getMozFirefoxOptions() { + //noinspection unchecked + return Optional.ofNullable((Map) getCapability(MOZ_FIREFOX_OPTIONS_OPTION)); + } +} diff --git a/src/main/java/io/appium/java_client/gecko/options/SupportsSystemPortOption.java b/src/main/java/io/appium/java_client/gecko/options/SupportsSystemPortOption.java new file mode 100644 index 000000000..db89a31f4 --- /dev/null +++ b/src/main/java/io/appium/java_client/gecko/options/SupportsSystemPortOption.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.gecko.options; + +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 SupportsSystemPortOption> extends + Capabilities, CanSetCapability { + String SYSTEM_PORT_OPTION = "systemPort"; + + /** + * The number of the port for the driver to listen on. Must be unique + * for each session. If not provided then Appium will try to detect + * it automatically. + * + * @param port port number in range 0..65535 + * @return self instance for chaining. + */ + default T setSystemPort(int port) { + return amend(SYSTEM_PORT_OPTION, port); + } + + /** + * Get the number of the port for the internal server to listen on. + * + * @return System port value. + */ + default Optional getSystemPort() { + return Optional.ofNullable(toInteger(getCapability(SYSTEM_PORT_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/gecko/options/SupportsVerbosityOption.java b/src/main/java/io/appium/java_client/gecko/options/SupportsVerbosityOption.java new file mode 100644 index 000000000..60e479079 --- /dev/null +++ b/src/main/java/io/appium/java_client/gecko/options/SupportsVerbosityOption.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.gecko.options; + +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 SupportsVerbosityOption> extends + Capabilities, CanSetCapability { + String VERBOSITY_OPTION = "verbosity"; + + /** + * The verbosity level of driver logging. + * By default, minimum verbosity is applied. + * + * @param verbosity Verbosity value. + * @return self instance for chaining. + */ + default T setVerbosity(Verbosity verbosity) { + return amend(VERBOSITY_OPTION, verbosity.name().toLowerCase()); + } + + /** + * Get the verbosity level of driver logging. + * + * @return Verbosity value. + */ + default Optional getVerbosity() { + return Optional.ofNullable(getCapability(VERBOSITY_OPTION)) + .map(String::valueOf) + .map(String::toUpperCase) + .map(Verbosity::valueOf); + } +} diff --git a/src/main/java/io/appium/java_client/gecko/options/Verbosity.java b/src/main/java/io/appium/java_client/gecko/options/Verbosity.java new file mode 100644 index 000000000..f9a5c599e --- /dev/null +++ b/src/main/java/io/appium/java_client/gecko/options/Verbosity.java @@ -0,0 +1,21 @@ +/* + * 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.gecko.options; + +public enum Verbosity { + DEBUG, TRACE +} 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 bfa8c3cc4..b54057314 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 @@ -81,7 +81,7 @@ public BaseOptions(Capabilities source) { * Set the kind of mobile device or emulator to use. * * @param platform the kind of mobile device or emulator to use. - * @return this MobileOptions, for chaining. + * @return self instance for chaining. * @see CapabilityType#PLATFORM_NAME */ public T setPlatformName(String platform) { diff --git a/src/main/java/io/appium/java_client/remote/options/SupportsAcceptInsecureCertsOption.java b/src/main/java/io/appium/java_client/remote/options/SupportsAcceptInsecureCertsOption.java new file mode 100644 index 000000000..5146d7991 --- /dev/null +++ b/src/main/java/io/appium/java_client/remote/options/SupportsAcceptInsecureCertsOption.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.remote.options; + +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toSafeBoolean; + +public interface SupportsAcceptInsecureCertsOption> extends + Capabilities, CanSetCapability { + String ACCEPT_INSECURE_CERTS_OPTION = "acceptInsecureCerts"; + + /** + * Enforces untrusted and self-signed TLS certificates are + * implicitly trusted on navigation for the duration of the session. + * + * @return self instance for chaining. + */ + default T acceptInsecureCerts() { + return setAcceptInsecureCerts(true); + } + + /** + * Set whether untrusted and self-signed TLS certificates are + * implicitly trusted on navigation for the duration of the session. + * + * @param bool True or false. + * @return self instance for chaining. + */ + default T setAcceptInsecureCerts(boolean bool) { + return amend(ACCEPT_INSECURE_CERTS_OPTION, bool); + } + + /** + * Get whether untrusted and self-signed TLS certificates are + * implicitly trusted on navigation for the duration of the session. + * + * @return true or false. + */ + default Optional doesAcceptInsecureCerts() { + return Optional.ofNullable(toSafeBoolean(getCapability(ACCEPT_INSECURE_CERTS_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/remote/options/SupportsBrowserVersionOption.java b/src/main/java/io/appium/java_client/remote/options/SupportsBrowserVersionOption.java new file mode 100644 index 000000000..4eece6cdb --- /dev/null +++ b/src/main/java/io/appium/java_client/remote/options/SupportsBrowserVersionOption.java @@ -0,0 +1,37 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.appium.java_client.remote.options; + +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +public interface SupportsBrowserVersionOption> extends + Capabilities, CanSetCapability { + String BROWSER_VERSION_OPTION = "browserVersion"; + + /** + * Provide the version number of the browser to automate if there are multiple + * versions installed on the same machine where the driver is running. + * + * @param version Browser version to use. + * @return self instance for chaining. + */ + default T setBrowserVersion(String version) { + return amend(BROWSER_VERSION_OPTION, version); + } +} diff --git a/src/main/java/io/appium/java_client/remote/options/SupportsClearSystemFilesOption.java b/src/main/java/io/appium/java_client/remote/options/SupportsClearSystemFilesOption.java index 0d652a1da..d30001f3e 100644 --- a/src/main/java/io/appium/java_client/remote/options/SupportsClearSystemFilesOption.java +++ b/src/main/java/io/appium/java_client/remote/options/SupportsClearSystemFilesOption.java @@ -29,7 +29,7 @@ public interface SupportsClearSystemFilesOption> extend /** * Set the app to delete any generated files at the end of a session. * - * @return this MobileOptions, for chaining. + * @return self instance for chaining. */ default T clearSystemFiles() { return setClearSystemFiles(true); @@ -39,7 +39,7 @@ default T clearSystemFiles() { * Set whether the app deletes generated files at the end of a session. * * @param bool is whether the app deletes generated files at the end of a session. - * @return this MobileOptions, for chaining. + * @return self instance for chaining. */ default T setClearSystemFiles(boolean bool) { return amend(CLEAR_SYSTEM_FILES_OPTION, bool); diff --git a/src/main/java/io/appium/java_client/remote/options/SupportsDeviceNameOption.java b/src/main/java/io/appium/java_client/remote/options/SupportsDeviceNameOption.java index 729741bbc..f1d268d1a 100644 --- a/src/main/java/io/appium/java_client/remote/options/SupportsDeviceNameOption.java +++ b/src/main/java/io/appium/java_client/remote/options/SupportsDeviceNameOption.java @@ -28,7 +28,7 @@ public interface SupportsDeviceNameOption> extends * Set the name of the device. * * @param deviceName is the name of the device. - * @return this MobileOptions, for chaining. + * @return self instance for chaining. */ default T setDeviceName(String deviceName) { return amend(DEVICE_NAME_OPTION, deviceName); diff --git a/src/main/java/io/appium/java_client/remote/options/SupportsLanguageOption.java b/src/main/java/io/appium/java_client/remote/options/SupportsLanguageOption.java index 8428d6f45..92b41e9f6 100644 --- a/src/main/java/io/appium/java_client/remote/options/SupportsLanguageOption.java +++ b/src/main/java/io/appium/java_client/remote/options/SupportsLanguageOption.java @@ -28,7 +28,7 @@ public interface SupportsLanguageOption> extends * Set language abbreviation for use in session. * * @param language is the language abbreviation. - * @return this MobileOptions, for chaining. + * @return self instance for chaining. */ default T setLanguage(String language) { return amend(LANGUAGE_OPTION, language); diff --git a/src/main/java/io/appium/java_client/remote/options/SupportsPageLoadStrategyOption.java b/src/main/java/io/appium/java_client/remote/options/SupportsPageLoadStrategyOption.java new file mode 100644 index 000000000..752966ef6 --- /dev/null +++ b/src/main/java/io/appium/java_client/remote/options/SupportsPageLoadStrategyOption.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.remote.options; + +import org.openqa.selenium.Capabilities; +import org.openqa.selenium.PageLoadStrategy; + +import java.util.Optional; + +public interface SupportsPageLoadStrategyOption> extends + Capabilities, CanSetCapability { + String PAGE_LOAD_STRATEGY_OPTION = "pageLoadStrategy"; + + /** + * Defines the current session’s page load strategy. + * + * @param strategy Page load strategy. + * @return self instance for chaining. + */ + default T setPageLoadStrategy(PageLoadStrategy strategy) { + return amend(PAGE_LOAD_STRATEGY_OPTION, strategy.toString()); + } + + /** + * Get the current session’s page load strategy. + * + * @return Page load strategy. + */ + default Optional getPageLoadStrategy() { + return Optional.ofNullable(getCapability(PAGE_LOAD_STRATEGY_OPTION)) + .map(String::valueOf) + .map(String::toUpperCase) + .map(PageLoadStrategy::valueOf); + } +} diff --git a/src/main/java/io/appium/java_client/remote/options/SupportsProxyOption.java b/src/main/java/io/appium/java_client/remote/options/SupportsProxyOption.java new file mode 100644 index 000000000..cb3de55e7 --- /dev/null +++ b/src/main/java/io/appium/java_client/remote/options/SupportsProxyOption.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.remote.options; + +import com.google.gson.Gson; +import org.openqa.selenium.Capabilities; +import org.openqa.selenium.Proxy; + +import java.util.Map; +import java.util.Optional; + +public interface SupportsProxyOption> extends + Capabilities, CanSetCapability { + String PROXY_OPTION = "proxy"; + + /** + * Defines the current session’s proxy configuration. + * + * @param proxy Session proxy config. + * @return self instance for chaining. + */ + default T setProxy(Proxy proxy) { + return amend(PROXY_OPTION, proxy.toJson()); + } + + /** + * Get the current session’s proxy configuration. + * + * @return Proxy config. + */ + default Optional getProxy() { + return Optional.ofNullable(getCapability(PROXY_OPTION)) + .map(String::valueOf) + .map((v) -> new Gson().fromJson(v, Map.class)) + .map(Proxy::new); + } +} diff --git a/src/main/java/io/appium/java_client/remote/options/SupportsSetWindowRectOption.java b/src/main/java/io/appium/java_client/remote/options/SupportsSetWindowRectOption.java new file mode 100644 index 000000000..046fb6cfa --- /dev/null +++ b/src/main/java/io/appium/java_client/remote/options/SupportsSetWindowRectOption.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.remote.options; + +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +import static io.appium.java_client.internal.CapabilityHelpers.toSafeBoolean; + +public interface SupportsSetWindowRectOption> extends + Capabilities, CanSetCapability { + String SET_WINDOW_RECT_OPTION = "setWindowRect"; + + /** + * Indicates whether the remote end supports all + * of the resizing and repositioning commands. + * + * @param bool True or false. + * @return self instance for chaining. + */ + default T setWindowRect(boolean bool) { + return amend(SET_WINDOW_RECT_OPTION, bool); + } + + /** + * Get whether the remote end supports all + * of the resizing and repositioning commands. + * + * @return true or false. + */ + default Optional doesSetWindowRect() { + return Optional.ofNullable(toSafeBoolean(getCapability(SET_WINDOW_RECT_OPTION))); + } +} diff --git a/src/main/java/io/appium/java_client/remote/options/SupportsUnhandledPromptBehaviorOption.java b/src/main/java/io/appium/java_client/remote/options/SupportsUnhandledPromptBehaviorOption.java new file mode 100644 index 000000000..a6fded38a --- /dev/null +++ b/src/main/java/io/appium/java_client/remote/options/SupportsUnhandledPromptBehaviorOption.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.remote.options; + +import org.openqa.selenium.Capabilities; + +import java.util.Optional; + +public interface SupportsUnhandledPromptBehaviorOption> extends + Capabilities, CanSetCapability { + String UNHANDLED_PROMPT_BEHAVIOR_OPTION = "unhandledPromptBehavior"; + + /** + * Defines the current session’s page load strategy. + * + * @param strategy Page load strategy. + * @return self instance for chaining. + */ + default T setUnhandledPromptBehavior(UnhandledPromptBehavior strategy) { + return amend(UNHANDLED_PROMPT_BEHAVIOR_OPTION, strategy.toString()); + } + + /** + * Get the current session’s page load strategy. + * + * @return Page load strategy. + */ + default Optional getUnhandledPromptBehavior() { + return Optional.ofNullable(getCapability(UNHANDLED_PROMPT_BEHAVIOR_OPTION)) + .map(String::valueOf) + .map(UnhandledPromptBehavior::fromString); + } +} diff --git a/src/main/java/io/appium/java_client/remote/options/UnhandledPromptBehavior.java b/src/main/java/io/appium/java_client/remote/options/UnhandledPromptBehavior.java new file mode 100644 index 000000000..0068dfe42 --- /dev/null +++ b/src/main/java/io/appium/java_client/remote/options/UnhandledPromptBehavior.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.remote.options; + +import java.util.Arrays; +import java.util.stream.Collectors; + +public enum UnhandledPromptBehavior { + DISMISS, ACCEPT, + DISMISS_AND_NOTIFY, ACCEPT_AND_NOTIFY, + IGNORE; + + @Override + public String toString() { + return name().toLowerCase().replace("_", " "); + } + + /** + * Converts the given value to an enum member. + * + * @param value The value to convert. + * @return Enum member. + * @throws IllegalArgumentException If the provided value cannot be matched. + */ + public static UnhandledPromptBehavior fromString(String value) { + return Arrays.stream(values()) + .filter((v) -> v.toString().equals(value)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException( + String.format("Unhandled prompt behavior '%s' is not supported. " + + "The only supported values are: %s", value, + Arrays.stream(values()).map(UnhandledPromptBehavior::toString) + .collect(Collectors.joining(","))) + )); + } +}