diff --git a/src/main/java/io/appium/java_client/AppiumDriver.java b/src/main/java/io/appium/java_client/AppiumDriver.java index 58ff20702..843aa3751 100644 --- a/src/main/java/io/appium/java_client/AppiumDriver.java +++ b/src/main/java/io/appium/java_client/AppiumDriver.java @@ -20,13 +20,8 @@ import static com.google.common.base.Preconditions.checkNotNull; import static io.appium.java_client.MobileCommand.GET_SESSION; -import static io.appium.java_client.MobileCommand.GET_SETTINGS; -import static io.appium.java_client.MobileCommand.SET_SETTINGS; -import static io.appium.java_client.MobileCommand.prepareArguments; import com.google.common.collect.ImmutableMap; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; import io.appium.java_client.remote.AppiumCommandExecutor; import io.appium.java_client.remote.MobileCapabilityType; @@ -387,43 +382,6 @@ public void zoom(int x, int y) { multiTouch.perform(); } - /** - * Get settings stored for this test session It's probably better to use a - * convenience function, rather than use this function directly. Try finding - * the method for the specific setting you want to read. - * - * @return JsonObject, a straight-up hash of settings. - */ - public JsonObject getSettings() { - Response response = execute(GET_SETTINGS); - - JsonParser parser = new JsonParser(); - return (JsonObject) parser.parse(response.getValue().toString()); - } - - /** - * Set settings for this test session It's probably better to use a - * convenience function, rather than use this function directly. Try finding - * the method for the specific setting you want to change. - * - * @param settings Map of setting keys and values. - */ - private void setSettings(ImmutableMap settings) { - execute(SET_SETTINGS, prepareArguments("settings", settings)); - } - - /** - * Set a setting for this test session It's probably better to use a - * convenience function, rather than use this function directly. Try finding - * the method for the specific setting you want to change. - * - * @param setting AppiumSetting you wish to set. - * @param value value of the setting. - */ - protected void setSetting(AppiumSetting setting, Object value) { - setSettings(prepareArguments(setting.toString(), value)); - } - @Override public WebDriver context(String name) { checkNotNull(name, "Must supply a context name"); execute(DriverCommand.SWITCH_TO_CONTEXT, ImmutableMap.of("name", name)); diff --git a/src/main/java/io/appium/java_client/AppiumSetting.java b/src/main/java/io/appium/java_client/AppiumSetting.java index 697e1457f..71f632989 100644 --- a/src/main/java/io/appium/java_client/AppiumSetting.java +++ b/src/main/java/io/appium/java_client/AppiumSetting.java @@ -16,9 +16,12 @@ package io.appium.java_client; +import io.appium.java_client.android.Setting; + /** - * Enums defining constants for Appium Settings which can be set and toggled during a test session. + * This enum is deprecated. Was moved to {@link Setting} */ +@Deprecated public enum AppiumSetting { IGNORE_UNIMPORTANT_VIEWS("ignoreUnimportantViews"); diff --git a/src/main/java/io/appium/java_client/MobileCommand.java b/src/main/java/io/appium/java_client/MobileCommand.java index c7131ec15..23a9a3471 100644 --- a/src/main/java/io/appium/java_client/MobileCommand.java +++ b/src/main/java/io/appium/java_client/MobileCommand.java @@ -47,8 +47,6 @@ public class MobileCommand { protected static final String CLOSE_APP = "closeApp"; protected static final String LOCK = "lock"; protected static final String COMPLEX_FIND = "complexFind"; - protected static final String GET_SETTINGS = "getSettings"; - protected static final String SET_SETTINGS = "setSettings"; protected static final String GET_DEVICE_TIME = "getDeviceTime"; protected static final String GET_SESSION = "getSession"; //iOS @@ -67,6 +65,8 @@ public class MobileCommand { protected static final String TOGGLE_LOCATION_SERVICES = "toggleLocationServices"; protected static final String UNLOCK = "unlock"; protected static final String REPLACE_VALUE = "replaceValue"; + protected static final String GET_SETTINGS = "getSettings"; + protected static final String SET_SETTINGS = "setSettings"; public static final Map commandRepository = createCommandRepository(); diff --git a/src/main/java/io/appium/java_client/android/AndroidDriver.java b/src/main/java/io/appium/java_client/android/AndroidDriver.java index 10a1647bb..7b92a2b81 100644 --- a/src/main/java/io/appium/java_client/android/AndroidDriver.java +++ b/src/main/java/io/appium/java_client/android/AndroidDriver.java @@ -21,7 +21,6 @@ import static io.appium.java_client.android.AndroidMobileCommandHelper.toggleLocationServicesCommand; import io.appium.java_client.AppiumDriver; -import io.appium.java_client.AppiumSetting; import io.appium.java_client.CommandExecutionHelper; import io.appium.java_client.FindsByAndroidUIAutomator; import io.appium.java_client.android.internal.JsonToAndroidElementConverter; @@ -48,7 +47,7 @@ public class AndroidDriver extends AppiumDriver implements AndroidDeviceActionShortcuts, HasNetworkConnection, PushesFiles, StartsActivity, - FindsByAndroidUIAutomator, LocksAndroidDevice { + FindsByAndroidUIAutomator, LocksAndroidDevice, HasSettings { private static final String ANDROID_PLATFORM = MobilePlatform.ANDROID; @@ -188,18 +187,4 @@ public void openNotifications() { public void toggleLocationServices() { CommandExecutionHelper.execute(this, toggleLocationServicesCommand()); } - - /** - * Set the `ignoreUnimportantViews` setting. *Android-only method*. - * Sets whether Android devices should use `setCompressedLayoutHeirarchy()` - * which ignores all views which are marked IMPORTANT_FOR_ACCESSIBILITY_NO - * or IMPORTANT_FOR_ACCESSIBILITY_AUTO (and have been deemed not important - * by the system), in an attempt to make things less confusing or faster. - * - * @param compress ignores unimportant views if true, doesn't ignore otherwise. - */ - // Should be moved to the subclass - public void ignoreUnimportantViews(Boolean compress) { - setSetting(AppiumSetting.IGNORE_UNIMPORTANT_VIEWS, compress); - } } diff --git a/src/main/java/io/appium/java_client/android/AndroidMobileCommandHelper.java b/src/main/java/io/appium/java_client/android/AndroidMobileCommandHelper.java index 65db085ee..ff7362857 100644 --- a/src/main/java/io/appium/java_client/android/AndroidMobileCommandHelper.java +++ b/src/main/java/io/appium/java_client/android/AndroidMobileCommandHelper.java @@ -290,4 +290,13 @@ public class AndroidMobileCommandHelper extends MobileCommand { return new AbstractMap.SimpleEntry<>( REPLACE_VALUE, prepareArguments(parameters, values)); } + + public static Map.Entry> getSettingsCommand() { + return new AbstractMap.SimpleEntry<>(GET_SETTINGS, ImmutableMap.of()); + } + + public static Map.Entry> setSettingsCommand(Setting setting, Object value) { + return new AbstractMap.SimpleEntry<>(SET_SETTINGS, prepareArguments("settings", + prepareArguments(setting.toString(), value))); + } } diff --git a/src/main/java/io/appium/java_client/android/ConfiguratorParameters.java b/src/main/java/io/appium/java_client/android/ConfiguratorParameters.java new file mode 100644 index 000000000..b41621b7c --- /dev/null +++ b/src/main/java/io/appium/java_client/android/ConfiguratorParameters.java @@ -0,0 +1,35 @@ +/* + * 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; + +enum ConfiguratorParameters { + WAIT_FOR_IDLE_TIMEOUT("setWaitForIdleTimeout"), + WAIT_FOR_SELECTOR_TIMEOUT("setWaitForSelectorTimeout"), + WAIT_SCROLL_ACKNOWLEDGMENT_TIMEOUT("setScrollAcknowledgmentTimeout"), + WAIT_ACTION_ACKNOWLEDGMENT_TIMEOUT("setActionAcknowledgmentTimeout"), + KEY_INJECTION_DELAY("setKeyInjectionDelay"); + + private final String name; + + ConfiguratorParameters(String name) { + this.name = name; + } + + String format(int value) { + return String.format("{\"method\":\"%s\",\"value\":%d}", name, value); + } +} diff --git a/src/main/java/io/appium/java_client/android/HasSettings.java b/src/main/java/io/appium/java_client/android/HasSettings.java new file mode 100644 index 000000000..0a12e3c9f --- /dev/null +++ b/src/main/java/io/appium/java_client/android/HasSettings.java @@ -0,0 +1,122 @@ +/* + * 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; + +import static io.appium.java_client.android.AndroidMobileCommandHelper.getSettingsCommand; +import static io.appium.java_client.android.AndroidMobileCommandHelper.setSettingsCommand; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +import io.appium.java_client.CommandExecutionHelper; +import io.appium.java_client.ExecutesMethod; + +import org.openqa.selenium.remote.Response; + +import java.util.Map; + +interface HasSettings extends ExecutesMethod { + /** + * Set a setting for this test session It's probably better to use a + * convenience function, rather than use this function directly. Try finding + * the method for the specific setting you want to change. + * + * @param setting Setting you wish to set. + * @param value value of the setting. + */ + default void setSetting(Setting setting, Object value) { + CommandExecutionHelper.execute(this, setSettingsCommand(setting, value)); + } + + /** + * Get settings stored for this test session It's probably better to use a + * convenience function, rather than use this function directly. Try finding + * the method for the specific setting you want to read. + * + * @return JsonObject, a straight-up hash of settings. + */ + default JsonObject getSettings() { + Map.Entry> keyValuePair = getSettingsCommand(); + Response response = execute(keyValuePair.getKey(), keyValuePair.getValue()); + + JsonParser parser = new JsonParser(); + return (JsonObject) parser.parse(response.getValue().toString()); + } + + /** + * Set the `ignoreUnimportantViews` setting. *Android-only method*. + * Sets whether Android devices should use `setCompressedLayoutHeirarchy()` + * which ignores all views which are marked IMPORTANT_FOR_ACCESSIBILITY_NO + * or IMPORTANT_FOR_ACCESSIBILITY_AUTO (and have been deemed not important + * by the system), in an attempt to make things less confusing or faster. + * + * @param compress ignores unimportant views if true, doesn't ignore otherwise. + */ + default void ignoreUnimportantViews(Boolean compress) { + setSetting(Setting.IGNORE_UNIMPORTANT_VIEWS, compress); + } + + /** + * invoke {@code setWaitForIdleTimeout} in {@code com.android.uiautomator.core.Configurator} + * + * @param timeout in milliseconds, 0 would reset to its default value + */ + default void configuratorSetWaitForIdleTimeout(int timeout) { + setSetting(Setting.CONFIGURATOR, + ConfiguratorParameters.WAIT_FOR_IDLE_TIMEOUT.format(timeout)); + } + + /** + * invoke {@code setWaitForSelectorTimeout} in {@code com.android.uiautomator.core.Configurator} + * + * @param timeout in milliseconds, 0 would reset to its default value + */ + default void configuratorSetWaitForSelectorTimeout(int timeout) { + setSetting(Setting.CONFIGURATOR, + ConfiguratorParameters.WAIT_FOR_SELECTOR_TIMEOUT.format(timeout)); + } + + /** + * invoke {@code setScrollAcknowledgmentTimeout} in {@code com.android.uiautomator.core.Configurator} + * + * @param timeout in milliseconds, 0 would reset to its default value + */ + default void configuratorSetScrollAcknowledgmentTimeout(int timeout) { + setSetting(Setting.CONFIGURATOR, + ConfiguratorParameters.WAIT_SCROLL_ACKNOWLEDGMENT_TIMEOUT.format(timeout)); + } + + /** + * invoke {@code configuratorSetKeyInjectionDelay} in {@code com.android.uiautomator.core.Configurator} + * + * @param delay in milliseconds, 0 would reset to its default value + */ + default void configuratorSetKeyInjectionDelay(int delay) { + setSetting(Setting.CONFIGURATOR, + ConfiguratorParameters.KEY_INJECTION_DELAY.format(delay)); + } + + /** + * invoke {@code setActionAcknowledgmentTimeout} in {@code com.android.uiautomator.core.Configurator} + * + * @param timeout in milliseconds, 0 would reset to its default value + */ + default void configuratorSetActionAcknowledgmentTimeout(int timeout) { + setSetting(Setting.CONFIGURATOR, + ConfiguratorParameters.WAIT_ACTION_ACKNOWLEDGMENT_TIMEOUT.format(timeout)); + } +} diff --git a/src/main/java/io/appium/java_client/android/Setting.java b/src/main/java/io/appium/java_client/android/Setting.java new file mode 100644 index 000000000..eca4ba164 --- /dev/null +++ b/src/main/java/io/appium/java_client/android/Setting.java @@ -0,0 +1,36 @@ +/* + * 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; + +/** + * Enums defining constants for Appium Settings which can be set and toggled during a test session. + */ +public enum Setting { + + IGNORE_UNIMPORTANT_VIEWS("ignoreUnimportantViews"), + CONFIGURATOR("configurator"); + + private String name; + + Setting(String name) { + this.name = name; + } + + public String toString() { + return this.name; + } +} diff --git a/src/test/java/io/appium/java_client/android/AndroidDriverTest.java b/src/test/java/io/appium/java_client/android/AndroidDriverTest.java index 26f88bdfb..02387d1d8 100644 --- a/src/test/java/io/appium/java_client/android/AndroidDriverTest.java +++ b/src/test/java/io/appium/java_client/android/AndroidDriverTest.java @@ -22,7 +22,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import io.appium.java_client.AppiumSetting; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.FileUtils; import org.junit.Test; @@ -82,18 +81,6 @@ public class AndroidDriverTest extends BaseAndroidTest { } } - @Test public void ignoreUnimportantViews() { - driver.ignoreUnimportantViews(true); - boolean ignoreViews = - driver.getSettings().get(AppiumSetting.IGNORE_UNIMPORTANT_VIEWS.toString()) - .getAsBoolean(); - assertTrue(ignoreViews); - driver.ignoreUnimportantViews(false); - ignoreViews = driver.getSettings().get(AppiumSetting.IGNORE_UNIMPORTANT_VIEWS.toString()) - .getAsBoolean(); - assertFalse(ignoreViews); - } - @Test public void toggleLocationServicesTest() { driver.toggleLocationServices(); } diff --git a/src/test/java/io/appium/java_client/android/SettingTest.java b/src/test/java/io/appium/java_client/android/SettingTest.java new file mode 100644 index 000000000..5c4ad85db --- /dev/null +++ b/src/test/java/io/appium/java_client/android/SettingTest.java @@ -0,0 +1,47 @@ +package io.appium.java_client.android; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class SettingTest extends BaseAndroidTest { + + @Test public void ignoreUnimportantViewsTest() { + driver.ignoreUnimportantViews(true); + boolean ignoreViews = + driver.getSettings().get(Setting.IGNORE_UNIMPORTANT_VIEWS.toString()) + .getAsBoolean(); + assertTrue(ignoreViews); + driver.ignoreUnimportantViews(false); + ignoreViews = driver.getSettings().get(Setting.IGNORE_UNIMPORTANT_VIEWS.toString()) + .getAsBoolean(); + assertFalse(ignoreViews); + } + + @Test public void configuratorTest() { + driver.configuratorSetActionAcknowledgmentTimeout(5); + assertJSONElementContains("setActionAcknowledgmentTimeout", 5); + + driver.configuratorSetKeyInjectionDelay(4); + assertJSONElementContains("setKeyInjectionDelay", 4); + + driver.configuratorSetScrollAcknowledgmentTimeout(3); + assertJSONElementContains("setScrollAcknowledgmentTimeout", 3); + + driver.configuratorSetWaitForIdleTimeout(6); + assertJSONElementContains("setWaitForIdleTimeout", 6); + + driver.configuratorSetWaitForSelectorTimeout(1); + assertJSONElementContains("setWaitForSelectorTimeout", 1); + } + + private void assertJSONElementContains(String method, int value) { + driver.getSettings().get(Setting.CONFIGURATOR.toString()); + assertEquals(driver.getSettings().get(Setting.CONFIGURATOR.toString()) + .getAsJsonObject().get("method").getAsString(), method); + assertEquals(driver.getSettings().get(Setting.CONFIGURATOR.toString()) + .getAsJsonObject().get("value").getAsInt(), value); + } +}