Skip to content

Commit b6b60e4

Browse files
feat: Add Gecko driver options (#1573)
1 parent c8d451e commit b6b60e4

20 files changed

+794
-26
lines changed

src/main/java/io/appium/java_client/AppiumDriver.java

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package io.appium.java_client;
1818

1919
import static io.appium.java_client.internal.CapabilityHelpers.APPIUM_PREFIX;
20+
import static io.appium.java_client.remote.MobileCapabilityType.AUTOMATION_NAME;
2021
import static io.appium.java_client.remote.MobileCapabilityType.PLATFORM_NAME;
2122
import static org.apache.commons.lang3.StringUtils.isBlank;
2223

@@ -129,16 +130,36 @@ public AppiumDriver(Capabilities capabilities) {
129130
* @param originalCapabilities the given {@link Capabilities}.
130131
* @param defaultName a {@link MobileCapabilityType#PLATFORM_NAME} value which has
131132
* to be set up
132-
* @return {@link Capabilities} with changed mobile platform name value or the original capabilities
133+
* @return {@link Capabilities} with changed platform name value or the original capabilities
133134
*/
134-
protected static Capabilities ensurePlatformName(Capabilities originalCapabilities,
135-
String defaultName) {
135+
protected static Capabilities ensurePlatformName(
136+
Capabilities originalCapabilities, String defaultName) {
136137
String currentName = (String) originalCapabilities.getCapability(PLATFORM_NAME);
137138
return isBlank(currentName)
138139
? originalCapabilities.merge(new ImmutableCapabilities(PLATFORM_NAME, defaultName))
139140
: originalCapabilities;
140141
}
141142

143+
/**
144+
* Changes automation name if it is not set and returns merged capabilities.
145+
*
146+
* @param originalCapabilities the given {@link Capabilities}.
147+
* @param defaultName a {@link MobileCapabilityType#AUTOMATION_NAME} value which has
148+
* to be set up
149+
* @return {@link Capabilities} with changed mobile automation name value or the original capabilities
150+
*/
151+
protected static Capabilities ensureAutomationName(
152+
Capabilities originalCapabilities, String defaultName) {
153+
String currentAutomationName = CapabilityHelpers.getCapability(
154+
originalCapabilities, AUTOMATION_NAME, String.class);
155+
if (isBlank(currentAutomationName)) {
156+
String capabilityName = originalCapabilities.getCapabilityNames()
157+
.contains(AUTOMATION_NAME) ? AUTOMATION_NAME : APPIUM_PREFIX + AUTOMATION_NAME;
158+
return originalCapabilities.merge(new ImmutableCapabilities(capabilityName, defaultName));
159+
}
160+
return originalCapabilities;
161+
}
162+
142163
/**
143164
* Changes platform and automation names if they are not set
144165
* and returns merged capabilities.
@@ -147,27 +168,12 @@ protected static Capabilities ensurePlatformName(Capabilities originalCapabiliti
147168
* @param defaultPlatformName a {@link MobileCapabilityType#PLATFORM_NAME} value which has
148169
* to be set up
149170
* @param defaultAutomationName The default automation name to set up for this class
150-
* @return {@link Capabilities} with changed mobile platform name value or the original capabilities
171+
* @return {@link Capabilities} with changed platform/automation name value or the original capabilities
151172
*/
152173
protected static Capabilities ensurePlatformAndAutomationNames(
153174
Capabilities originalCapabilities, String defaultPlatformName, String defaultAutomationName) {
154-
MutableCapabilities toMerge = new MutableCapabilities();
155-
String currentPlatformName = (String) originalCapabilities.getCapability(PLATFORM_NAME);
156-
if (isBlank(currentPlatformName)) {
157-
toMerge.setCapability(PLATFORM_NAME, defaultPlatformName);
158-
}
159-
String currentAutomationName = CapabilityHelpers.getCapability(
160-
originalCapabilities, MobileCapabilityType.AUTOMATION_NAME, String.class);
161-
if (isBlank(currentAutomationName)) {
162-
toMerge.setCapability(originalCapabilities.getCapabilityNames()
163-
.contains(MobileCapabilityType.AUTOMATION_NAME)
164-
? MobileCapabilityType.AUTOMATION_NAME
165-
: APPIUM_PREFIX + MobileCapabilityType.AUTOMATION_NAME,
166-
defaultAutomationName);
167-
}
168-
return toMerge.getCapabilityNames().isEmpty()
169-
? originalCapabilities
170-
: originalCapabilities.merge(toMerge);
175+
Capabilities capsWithPlatformFixed = ensurePlatformName(originalCapabilities, defaultPlatformName);
176+
return ensureAutomationName(capsWithPlatformFixed, defaultAutomationName);
171177
}
172178

173179
@Override
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* See the NOTICE file distributed with this work for additional
5+
* information regarding copyright ownership.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.appium.java_client.gecko;
18+
19+
import io.appium.java_client.AppiumDriver;
20+
import io.appium.java_client.remote.AutomationName;
21+
import io.appium.java_client.service.local.AppiumDriverLocalService;
22+
import io.appium.java_client.service.local.AppiumServiceBuilder;
23+
import org.openqa.selenium.Capabilities;
24+
import org.openqa.selenium.remote.HttpCommandExecutor;
25+
import org.openqa.selenium.remote.http.HttpClient;
26+
27+
import java.net.URL;
28+
29+
/**
30+
* GeckoDriver is an officially supported Appium driver
31+
* created to automate Mobile browsers and web views based on
32+
* the Gecko engine. The driver uses W3C
33+
* WebDriver protocol and is built on top of Mozilla's geckodriver
34+
* server. Read https://github.com/appium/appium-geckodriver
35+
* for more details on how to configure and use it.
36+
*
37+
* @since Appium 1.20.0
38+
*/
39+
public class GeckoDriver extends AppiumDriver {
40+
private static final String AUTOMATION_NAME = AutomationName.GECKO;
41+
42+
public GeckoDriver(HttpCommandExecutor executor, Capabilities capabilities) {
43+
super(executor, ensureAutomationName(capabilities, AUTOMATION_NAME));
44+
}
45+
46+
public GeckoDriver(URL remoteAddress, Capabilities capabilities) {
47+
super(remoteAddress, ensureAutomationName(capabilities, AUTOMATION_NAME));
48+
}
49+
50+
public GeckoDriver(URL remoteAddress, HttpClient.Factory httpClientFactory, Capabilities capabilities) {
51+
super(remoteAddress, httpClientFactory, ensureAutomationName(capabilities, AUTOMATION_NAME));
52+
}
53+
54+
public GeckoDriver(AppiumDriverLocalService service, Capabilities capabilities) {
55+
super(service, ensureAutomationName(capabilities, AUTOMATION_NAME));
56+
}
57+
58+
public GeckoDriver(AppiumDriverLocalService service, HttpClient.Factory httpClientFactory,
59+
Capabilities capabilities) {
60+
super(service, httpClientFactory, ensureAutomationName(capabilities, AUTOMATION_NAME));
61+
}
62+
63+
public GeckoDriver(AppiumServiceBuilder builder, Capabilities capabilities) {
64+
super(builder, ensureAutomationName(capabilities, AUTOMATION_NAME));
65+
}
66+
67+
public GeckoDriver(AppiumServiceBuilder builder, HttpClient.Factory httpClientFactory,
68+
Capabilities capabilities) {
69+
super(builder, httpClientFactory, ensureAutomationName(capabilities, AUTOMATION_NAME));
70+
}
71+
72+
public GeckoDriver(HttpClient.Factory httpClientFactory, Capabilities capabilities) {
73+
super(httpClientFactory, ensureAutomationName(capabilities, AUTOMATION_NAME));
74+
}
75+
76+
public GeckoDriver(Capabilities capabilities) {
77+
super(ensureAutomationName(capabilities, AUTOMATION_NAME));
78+
}
79+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* See the NOTICE file distributed with this work for additional
5+
* information regarding copyright ownership.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.appium.java_client.gecko.options;
18+
19+
import io.appium.java_client.mac.options.SupportsSystemPortOption;
20+
import io.appium.java_client.remote.AutomationName;
21+
import io.appium.java_client.remote.options.BaseOptions;
22+
import io.appium.java_client.remote.options.SupportsAcceptInsecureCertsOption;
23+
import io.appium.java_client.remote.options.SupportsBrowserNameOption;
24+
import io.appium.java_client.remote.options.SupportsBrowserVersionOption;
25+
import io.appium.java_client.remote.options.SupportsPageLoadStrategyOption;
26+
import io.appium.java_client.remote.options.SupportsProxyOption;
27+
import io.appium.java_client.remote.options.SupportsSetWindowRectOption;
28+
import io.appium.java_client.remote.options.SupportsUnhandledPromptBehaviorOption;
29+
import org.openqa.selenium.Capabilities;
30+
31+
import java.util.Map;
32+
33+
/**
34+
* https://github.com/appium/appium-geckodriver#usage
35+
*/
36+
public class GeckoOptions extends BaseOptions<GeckoOptions> implements
37+
SupportsBrowserNameOption<GeckoOptions>,
38+
SupportsBrowserVersionOption<GeckoOptions>,
39+
SupportsMarionettePortOption<GeckoOptions>,
40+
SupportsSystemPortOption<GeckoOptions>,
41+
SupportsVerbosityOption<GeckoOptions>,
42+
SupportsAndroidStorageOption<GeckoOptions>,
43+
SupportsMozFirefoxOptionsOption<GeckoOptions>,
44+
SupportsAcceptInsecureCertsOption<GeckoOptions>,
45+
SupportsPageLoadStrategyOption<GeckoOptions>,
46+
SupportsSetWindowRectOption<GeckoOptions>,
47+
SupportsProxyOption<GeckoOptions>,
48+
SupportsUnhandledPromptBehaviorOption<GeckoOptions> {
49+
public GeckoOptions() {
50+
setCommonOptions();
51+
}
52+
53+
public GeckoOptions(Capabilities source) {
54+
super(source);
55+
setCommonOptions();
56+
}
57+
58+
public GeckoOptions(Map<String, ?> source) {
59+
super(source);
60+
setCommonOptions();
61+
}
62+
63+
private void setCommonOptions() {
64+
setAutomationName(AutomationName.GECKO);
65+
}
66+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* See the NOTICE file distributed with this work for additional
5+
* information regarding copyright ownership.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.appium.java_client.gecko.options;
18+
19+
import io.appium.java_client.remote.options.BaseOptions;
20+
import io.appium.java_client.remote.options.CanSetCapability;
21+
import org.openqa.selenium.Capabilities;
22+
23+
import java.util.Optional;
24+
25+
public interface SupportsAndroidStorageOption<T extends BaseOptions<T>> extends
26+
Capabilities, CanSetCapability<T> {
27+
String ANDROID_STORAGE_OPTION = "androidStorage";
28+
29+
/**
30+
* See
31+
* https://firefox-source-docs.mozilla.org/testing/geckodriver
32+
* /Flags.html#code-android-storage-var-android-storage-var-code
33+
*
34+
* @param storage One of supported Android storage types.
35+
* @return self instance for chaining.
36+
*/
37+
default T setAndroidStorage(String storage) {
38+
return amend(ANDROID_STORAGE_OPTION, storage);
39+
}
40+
41+
/**
42+
* Get the currently set storage type.
43+
*
44+
* @return String representing the name of the device.
45+
*/
46+
default Optional<String> getAndroidStorage() {
47+
return Optional.ofNullable((String) getCapability(ANDROID_STORAGE_OPTION));
48+
}
49+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* See the NOTICE file distributed with this work for additional
5+
* information regarding copyright ownership.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.appium.java_client.gecko.options;
18+
19+
import io.appium.java_client.remote.options.BaseOptions;
20+
import io.appium.java_client.remote.options.CanSetCapability;
21+
import org.openqa.selenium.Capabilities;
22+
23+
import java.util.Optional;
24+
25+
import static io.appium.java_client.internal.CapabilityHelpers.toInteger;
26+
27+
public interface SupportsMarionettePortOption<T extends BaseOptions<T>> extends
28+
Capabilities, CanSetCapability<T> {
29+
String MARIONETTE_PORT_OPTION = "marionettePort";
30+
31+
/**
32+
* Selects the port for Geckodriver’s connection to the Marionette
33+
* remote protocol. The existing Firefox instance must have Marionette
34+
* enabled. To enable the remote protocol in Firefox, you can pass the
35+
* -marionette flag. Unless the marionette.port preference has been
36+
* user-set, Marionette will listen on port 2828, which is the default
37+
* value for this capability.
38+
*
39+
* @param port port number in range 0..65535
40+
* @return self instance for chaining.
41+
*/
42+
default T setMarionettePort(int port) {
43+
return amend(MARIONETTE_PORT_OPTION, port);
44+
}
45+
46+
/**
47+
* Get the number of the port for the Marionette server to listen on.
48+
*
49+
* @return Marionette port value.
50+
*/
51+
default Optional<Integer> getMarionettePort() {
52+
return Optional.ofNullable(toInteger(getCapability(MARIONETTE_PORT_OPTION)));
53+
}
54+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* See the NOTICE file distributed with this work for additional
5+
* information regarding copyright ownership.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.appium.java_client.gecko.options;
18+
19+
import io.appium.java_client.remote.options.BaseOptions;
20+
import io.appium.java_client.remote.options.CanSetCapability;
21+
import org.openqa.selenium.Capabilities;
22+
23+
import java.util.Map;
24+
import java.util.Optional;
25+
26+
public interface SupportsMozFirefoxOptionsOption<T extends BaseOptions<T>> extends
27+
Capabilities, CanSetCapability<T> {
28+
String MOZ_FIREFOX_OPTIONS_OPTION = "moz:firefoxOptions";
29+
30+
/**
31+
* See https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions.
32+
*
33+
* @param options Firefox options mapping.
34+
* @return self instance for chaining.
35+
*/
36+
default T setMozFirefoxOptions(Map<String, Object> options) {
37+
return amend(MOZ_FIREFOX_OPTIONS_OPTION, options);
38+
}
39+
40+
/**
41+
* Get Firefox options mapping.
42+
*
43+
* @return Firefox options mapping.
44+
*/
45+
default Optional<Map<String, Object>> getMozFirefoxOptions() {
46+
//noinspection unchecked
47+
return Optional.ofNullable((Map<String, Object>) getCapability(MOZ_FIREFOX_OPTIONS_OPTION));
48+
}
49+
}

0 commit comments

Comments
 (0)