From 55039abff9f271e93a0ea4f75dc2eb0354924f5d Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Mon, 16 Oct 2017 10:43:52 +0200 Subject: [PATCH 01/14] Refactor setting of touch actions options --- .../io/appium/java_client/TouchAction.java | 306 +++++++++++++----- .../android/AndroidTouchAction.java | 29 ++ .../java_client/ios/IOSTouchAction.java | 39 ++- .../ios/touch/DoubleTapOptions.java | 26 ++ .../java_client/touch/ActionOptions.java | 40 +++ .../java_client/touch/LongPressOptions.java | 51 +++ .../java_client/touch/MoveToOptions.java | 20 ++ .../touch/OptionsWithAbsolutePositioning.java | 107 ++++++ .../touch/OptionsWithRelativePositioning.java | 79 +++++ .../java_client/touch/PressOptions.java | 20 ++ .../appium/java_client/touch/TapOptions.java | 47 +++ .../appium/java_client/touch/WaitOptions.java | 56 ++++ .../AndroidAbilityToUseSupplierTest.java | 28 +- .../java_client/android/AndroidTouchTest.java | 95 ++++-- 14 files changed, 820 insertions(+), 123 deletions(-) create mode 100644 src/main/java/io/appium/java_client/android/AndroidTouchAction.java create mode 100644 src/main/java/io/appium/java_client/ios/touch/DoubleTapOptions.java create mode 100644 src/main/java/io/appium/java_client/touch/ActionOptions.java create mode 100644 src/main/java/io/appium/java_client/touch/LongPressOptions.java create mode 100644 src/main/java/io/appium/java_client/touch/MoveToOptions.java create mode 100644 src/main/java/io/appium/java_client/touch/OptionsWithAbsolutePositioning.java create mode 100644 src/main/java/io/appium/java_client/touch/OptionsWithRelativePositioning.java create mode 100644 src/main/java/io/appium/java_client/touch/PressOptions.java create mode 100644 src/main/java/io/appium/java_client/touch/TapOptions.java create mode 100644 src/main/java/io/appium/java_client/touch/WaitOptions.java diff --git a/src/main/java/io/appium/java_client/TouchAction.java b/src/main/java/io/appium/java_client/TouchAction.java index ca30fde11..968d776b3 100644 --- a/src/main/java/io/appium/java_client/TouchAction.java +++ b/src/main/java/io/appium/java_client/TouchAction.java @@ -19,11 +19,18 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import io.appium.java_client.touch.ActionOptions; +import io.appium.java_client.touch.LongPressOptions; +import io.appium.java_client.touch.MoveToOptions; +import io.appium.java_client.touch.PressOptions; +import io.appium.java_client.touch.TapOptions; +import io.appium.java_client.touch.WaitOptions; import org.openqa.selenium.WebElement; -import org.openqa.selenium.internal.HasIdentity; import java.time.Duration; +import static com.google.common.base.Preconditions.checkNotNull; + /** * Used for Webdriver 3 touch actions * See the Webriver 3 spec @@ -34,7 +41,7 @@ * Calling perform() sends the action command to the Mobile Driver. Otherwise, * more and more actions can be chained. */ -public class TouchAction implements PerformsActions { +public class TouchAction> implements PerformsActions { protected ImmutableList.Builder parameterBuilder; private PerformsTouchActions performsTouchActions; @@ -44,16 +51,33 @@ public TouchAction(PerformsTouchActions performsTouchActions) { parameterBuilder = ImmutableList.builder(); } + /** + * Press on an element. + * + * @param pressOptions see {@link PressOptions}. + * @return this TouchAction, for chaining. + */ + public T press(ActionOptions pressOptions) { + parameterBuilder.add(new ActionParameter("press", pressOptions)); + //noinspection unchecked + return (T) this; + } + /** * Press on the center of an element. * * @param el element to press on. * @return this TouchAction, for chaining. + * @deprecated use {@link #press(ActionOptions)} instead */ - public TouchAction press(WebElement el) { - ActionParameter action = new ActionParameter("press", (HasIdentity) el); + @Deprecated + public T press(WebElement el) { + ActionParameter action = new ActionParameter("press", + new PressOptions() + .withElement(el)); parameterBuilder.add(action); - return this; + //noinspection unchecked + return (T) this; } /** @@ -62,13 +86,16 @@ public TouchAction press(WebElement el) { * @param x x coordinate. * @param y y coordinate. * @return this TouchAction, for chaining. + * @deprecated use {@link #press(ActionOptions)} instead */ - public TouchAction press(int x, int y) { - ActionParameter action = new ActionParameter("press"); - action.addParameter("x", x); - action.addParameter("y", y); + @Deprecated + public T press(int x, int y) { + ActionParameter action = new ActionParameter("press", + new PressOptions() + .withAbsoluteOffset(x, y)); parameterBuilder.add(action); - return this; + //noinspection unchecked + return (T) this; } /** @@ -78,13 +105,17 @@ public TouchAction press(int x, int y) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. + * @deprecated use {@link #press(ActionOptions)} instead */ - public TouchAction press(WebElement el, int x, int y) { - ActionParameter action = new ActionParameter("press", (HasIdentity) el); - action.addParameter("x", x); - action.addParameter("y", y); + @Deprecated + public T press(WebElement el, int x, int y) { + ActionParameter action = new ActionParameter("press", + new PressOptions() + .withElement(el) + .withRelativeOffset(x, y)); parameterBuilder.add(action); - return this; + //noinspection unchecked + return (T) this; } /** @@ -92,10 +123,24 @@ public TouchAction press(WebElement el, int x, int y) { * * @return this TouchAction, for chaining. */ - public TouchAction release() { + public T release() { ActionParameter action = new ActionParameter("release"); parameterBuilder.add(action); - return this; + //noinspection unchecked + return (T) this; + } + + /** + * Move current touch to center of an element. + * + * @param moveToOptions see {@link MoveToOptions}. + * @return this TouchAction, for chaining. + */ + public T moveTo(ActionOptions moveToOptions) { + ActionParameter action = new ActionParameter("moveTo", moveToOptions); + parameterBuilder.add(action); + //noinspection unchecked + return (T) this; } /** @@ -103,11 +148,16 @@ public TouchAction release() { * * @param el element to move to. * @return this TouchAction, for chaining. + * @deprecated {@link #moveTo(ActionOptions)} instead */ - public TouchAction moveTo(WebElement el) { - ActionParameter action = new ActionParameter("moveTo", (HasIdentity) el); + @Deprecated + public T moveTo(WebElement el) { + ActionParameter action = new ActionParameter("moveTo", + new MoveToOptions() + .withElement(el)); parameterBuilder.add(action); - return this; + //noinspection unchecked + return (T) this; } /** @@ -118,13 +168,16 @@ public TouchAction moveTo(WebElement el) { * @param x change in x coordinate to move through. * @param y change in y coordinate to move through. * @return this TouchAction, for chaining. + * @deprecated {@link #moveTo(ActionOptions)} instead */ - public TouchAction moveTo(int x, int y) { - ActionParameter action = new ActionParameter("moveTo"); - action.addParameter("x", x); - action.addParameter("y", y); + @Deprecated + public T moveTo(int x, int y) { + ActionParameter action = new ActionParameter("moveTo", + new MoveToOptions() + .withRelativeOffset(x, y)); parameterBuilder.add(action); - return this; + //noinspection unchecked + return (T) this; } /** @@ -134,11 +187,27 @@ public TouchAction moveTo(int x, int y) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. + * @deprecated {@link #moveTo(ActionOptions)} instead */ - public TouchAction moveTo(WebElement el, int x, int y) { - ActionParameter action = new ActionParameter("moveTo", (HasIdentity) el); - action.addParameter("x", x); - action.addParameter("y", y); + @Deprecated + public T moveTo(WebElement el, int x, int y) { + ActionParameter action = new ActionParameter("moveTo", + new MoveToOptions() + .withElement(el) + .withRelativeOffset(x, y)); + parameterBuilder.add(action); + //noinspection unchecked + return (T) this; + } + + /** + * Tap the center of an element. + * + * @param tapOptions see {@link TapOptions}. + * @return this TouchAction, for chaining. + */ + public TouchAction tap(ActionOptions tapOptions) { + ActionParameter action = new ActionParameter("tap", tapOptions); parameterBuilder.add(action); return this; } @@ -148,11 +217,16 @@ public TouchAction moveTo(WebElement el, int x, int y) { * * @param el element to tap. * @return this TouchAction, for chaining. + * @deprecated use {@link #tap(ActionOptions)} instead. */ - public TouchAction tap(WebElement el) { - ActionParameter action = new ActionParameter("tap", (HasIdentity) el); + @Deprecated + public T tap(WebElement el) { + ActionParameter action = new ActionParameter("tap", + new TapOptions() + .withElement(el)); parameterBuilder.add(action); - return this; + //noinspection unchecked + return (T) this; } /** @@ -161,13 +235,16 @@ public TouchAction tap(WebElement el) { * @param x x coordinate. * @param y y coordinate. * @return this TouchAction, for chaining. + * @deprecated use {@link #tap(ActionOptions)} instead. */ - public TouchAction tap(int x, int y) { - ActionParameter action = new ActionParameter("tap"); - action.addParameter("x", x); - action.addParameter("y", y); + @Deprecated + public T tap(int x, int y) { + ActionParameter action = new ActionParameter("tap", + new TapOptions() + .withAbsoluteOffset(x, y)); parameterBuilder.add(action); - return this; + //noinspection unchecked + return (T) this; } /** @@ -177,13 +254,17 @@ public TouchAction tap(int x, int y) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. + * @deprecated use {@link #tap(ActionOptions)} instead. */ - public TouchAction tap(WebElement el, int x, int y) { - ActionParameter action = new ActionParameter("tap", (HasIdentity) el); - action.addParameter("x", x); - action.addParameter("y", y); + @Deprecated + public T tap(WebElement el, int x, int y) { + ActionParameter action = new ActionParameter("tap", + new TapOptions() + .withElement(el) + .withRelativeOffset(x, y)); parameterBuilder.add(action); - return this; + //noinspection unchecked + return (T) this; } /** @@ -191,10 +272,24 @@ public TouchAction tap(WebElement el, int x, int y) { * * @return this TouchAction, for chaining. */ - public TouchAction waitAction() { + public T waitAction() { ActionParameter action = new ActionParameter("wait"); parameterBuilder.add(action); - return this; + //noinspection unchecked + return (T) this; + } + + /** + * Waits for specified amount of time to pass before continue to next touch action. + * + * @param waitOptions see {@link WaitOptions}. + * @return this TouchAction, for chaining. + */ + public T waitAction(ActionOptions waitOptions) { + ActionParameter action = new ActionParameter("wait", waitOptions); + parameterBuilder.add(action); + //noinspection unchecked + return (T) this; } /** @@ -202,12 +297,29 @@ public TouchAction waitAction() { * * @param duration of the wait action. Minimum time reolution unit is one millisecond. * @return this TouchAction, for chaining. + * @deprecated use {@link #waitAction(ActionOptions)} instead. */ - public TouchAction waitAction(Duration duration) { - ActionParameter action = new ActionParameter("wait"); - action.addParameter("ms", duration.toMillis()); + @Deprecated + public T waitAction(Duration duration) { + ActionParameter action = new ActionParameter("wait", + new WaitOptions() + .withDuration(duration)); parameterBuilder.add(action); - return this; + //noinspection unchecked + return (T) this; + } + + /** + * Press and hold the at the center of an element until the context menu event has fired. + * + * @param longPressOptions see {@link LongPressOptions}. + * @return this TouchAction, for chaining. + */ + public T longPress(ActionOptions longPressOptions) { + ActionParameter action = new ActionParameter("longPress", longPressOptions); + parameterBuilder.add(action); + //noinspection unchecked + return (T) this; } /** @@ -215,11 +327,16 @@ public TouchAction waitAction(Duration duration) { * * @param el element to long-press. * @return this TouchAction, for chaining. + * @deprecated use {@link #longPress(ActionOptions)} instead */ - public TouchAction longPress(WebElement el) { - ActionParameter action = new ActionParameter("longPress", (HasIdentity) el); + @Deprecated + public T longPress(WebElement el) { + ActionParameter action = new ActionParameter("longPress", + new LongPressOptions() + .withElement(el)); parameterBuilder.add(action); - return this; + //noinspection unchecked + return (T) this; } /** @@ -228,12 +345,17 @@ public TouchAction longPress(WebElement el) { * @param el element to long-press. * @param duration of the long-press. Minimum time resolution unit is one millisecond. * @return this TouchAction, for chaining. + * @deprecated use {@link #longPress(ActionOptions)} instead */ - public TouchAction longPress(WebElement el, Duration duration) { - ActionParameter action = new ActionParameter("longPress", (HasIdentity) el); - action.addParameter("duration", duration.toMillis()); + @Deprecated + public T longPress(WebElement el, Duration duration) { + ActionParameter action = new ActionParameter("longPress", + new LongPressOptions() + .withElement(el) + .withDuration(duration)); parameterBuilder.add(action); - return this; + //noinspection unchecked + return (T) this; } /** @@ -243,13 +365,16 @@ public TouchAction longPress(WebElement el, Duration duration) { * @param x x coordinate. * @param y y coordinate. * @return this TouchAction, for chaining. + * @deprecated use {@link #longPress(ActionOptions)} instead */ - public TouchAction longPress(int x, int y) { - ActionParameter action = new ActionParameter("longPress"); - action.addParameter("x", x); - action.addParameter("y", y); + @Deprecated + public T longPress(int x, int y) { + ActionParameter action = new ActionParameter("longPress", + new LongPressOptions() + .withAbsoluteOffset(x, y)); parameterBuilder.add(action); - return this; + //noinspection unchecked + return (T) this; } /** @@ -260,17 +385,19 @@ public TouchAction longPress(int x, int y) { * @param y y coordinate. * @param duration of the long-press. Minimum time resolution unit is one millisecond. * @return this TouchAction, for chaining. + * @deprecated use {@link #longPress(ActionOptions)} instead */ - public TouchAction longPress(int x, int y, Duration duration) { - ActionParameter action = new ActionParameter("longPress"); - action.addParameter("x", x); - action.addParameter("y", y); - action.addParameter("duration", duration.toMillis()); + @Deprecated + public T longPress(int x, int y, Duration duration) { + ActionParameter action = new ActionParameter("longPress", + new LongPressOptions() + .withAbsoluteOffset(x, y) + .withDuration(duration)); parameterBuilder.add(action); - return this; + //noinspection unchecked + return (T) this; } - /** * Press and hold the at an elements upper-left corner, offset by the given amount, * until the contextmenu event has fired. @@ -279,13 +406,17 @@ public TouchAction longPress(int x, int y, Duration duration) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. + * @deprecated use {@link #longPress(ActionOptions)} instead */ - public TouchAction longPress(WebElement el, int x, int y) { - ActionParameter action = new ActionParameter("longPress", (HasIdentity) el); - action.addParameter("x", x); - action.addParameter("y", y); + @Deprecated + public T longPress(WebElement el, int x, int y) { + ActionParameter action = new ActionParameter("longPress", + new LongPressOptions() + .withElement(el) + .withRelativeOffset(x, y)); parameterBuilder.add(action); - return this; + //noinspection unchecked + return (T) this; } /** @@ -297,12 +428,15 @@ public TouchAction longPress(WebElement el, int x, int y) { * @param y y offset. * @param duration of the long-press. Minimum time resolution unit is one millisecond. * @return this TouchAction, for chaining. + * @deprecated use {@link #longPress(ActionOptions)} instead */ + @Deprecated public TouchAction longPress(WebElement el, int x, int y, Duration duration) { - ActionParameter action = new ActionParameter("longPress", (HasIdentity) el); - action.addParameter("x", x); - action.addParameter("y", y); - action.addParameter("duration", duration.toMillis()); + ActionParameter action = new ActionParameter("longPress", + new LongPressOptions() + .withElement(el) + .withRelativeOffset(x, y) + .withDuration(duration)); parameterBuilder.add(action); return this; } @@ -321,9 +455,10 @@ public void cancel() { * * @return this TouchAction, for possible segmented-touches. */ - public TouchAction perform() { + public T perform() { performsTouchActions.performTouchAction(this); - return this; + //noinspection unchecked + return (T) this; } /** @@ -345,9 +480,10 @@ protected ImmutableMap> getParameters() { * * @return this TouchAction, for possible segmented-touches. */ - protected TouchAction clearParameters() { + protected T clearParameters() { parameterBuilder = ImmutableList.builder(); - return this; + //noinspection unchecked + return (T) this; } /** @@ -362,10 +498,12 @@ public ActionParameter(String actionName) { optionsBuilder = ImmutableMap.builder(); } - public ActionParameter(String actionName, HasIdentity el) { + public ActionParameter(String actionName, ActionOptions opts) { + checkNotNull(opts); this.actionName = actionName; optionsBuilder = ImmutableMap.builder(); - addParameter("element", el.getId()); + //noinspection unchecked + optionsBuilder.putAll(opts.build()); } public ImmutableMap getParameterMap() { @@ -373,9 +511,5 @@ public ImmutableMap getParameterMap() { builder.put("action", actionName).put("options", optionsBuilder.build()); return builder.build(); } - - public void addParameter(String name, Object value) { - optionsBuilder.put(name, value); - } } } diff --git a/src/main/java/io/appium/java_client/android/AndroidTouchAction.java b/src/main/java/io/appium/java_client/android/AndroidTouchAction.java new file mode 100644 index 000000000..e1af310df --- /dev/null +++ b/src/main/java/io/appium/java_client/android/AndroidTouchAction.java @@ -0,0 +1,29 @@ +/* + * 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 io.appium.java_client.PerformsTouchActions; +import io.appium.java_client.TouchAction; + + +public class AndroidTouchAction extends TouchAction { + + public AndroidTouchAction(PerformsTouchActions performsTouchActions) { + super(performsTouchActions); + } + +} diff --git a/src/main/java/io/appium/java_client/ios/IOSTouchAction.java b/src/main/java/io/appium/java_client/ios/IOSTouchAction.java index 104fc8f8b..2b0ed79af 100644 --- a/src/main/java/io/appium/java_client/ios/IOSTouchAction.java +++ b/src/main/java/io/appium/java_client/ios/IOSTouchAction.java @@ -1,12 +1,28 @@ +/* + * 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.ios; import io.appium.java_client.PerformsTouchActions; import io.appium.java_client.TouchAction; +import io.appium.java_client.ios.touch.DoubleTapOptions; import org.openqa.selenium.WebElement; -import org.openqa.selenium.internal.HasIdentity; -public class IOSTouchAction extends TouchAction { +public class IOSTouchAction extends TouchAction { public IOSTouchAction(PerformsTouchActions performsTouchActions) { super(performsTouchActions); @@ -18,12 +34,15 @@ public IOSTouchAction(PerformsTouchActions performsTouchActions) { * @param el element to tap. * @param x x offset. * @param y y offset. - * @return this TouchAction, for chaining. + * @return this IOSTouchAction, for chaining. + * @deprecated use {@link #tap(ActionOptions)} with count=2 instead. */ + @Deprecated public IOSTouchAction doubleTap(WebElement el, int x, int y) { - ActionParameter action = new ActionParameter("doubleTap", (HasIdentity) el); - action.addParameter("x", x); - action.addParameter("y", y); + ActionParameter action = new ActionParameter("doubleTap", + new DoubleTapOptions() + .withElement(el) + .withRelativeOffset(x, y)); parameterBuilder.add(action); return this; } @@ -32,10 +51,14 @@ public IOSTouchAction doubleTap(WebElement el, int x, int y) { * Double taps an element, offset from upper left corner. * * @param el element to tap. - * @return this TouchAction, for chaining. + * @return this IOSTouchAction, for chaining. + * @deprecated use {@link #tap(ActionOptions)} with count=2 instead. */ + @Deprecated public IOSTouchAction doubleTap(WebElement el) { - ActionParameter action = new ActionParameter("doubleTap", (HasIdentity) el); + ActionParameter action = new ActionParameter("doubleTap", + new DoubleTapOptions() + .withElement(el)); parameterBuilder.add(action); return this; } diff --git a/src/main/java/io/appium/java_client/ios/touch/DoubleTapOptions.java b/src/main/java/io/appium/java_client/ios/touch/DoubleTapOptions.java new file mode 100644 index 000000000..3149d287f --- /dev/null +++ b/src/main/java/io/appium/java_client/ios/touch/DoubleTapOptions.java @@ -0,0 +1,26 @@ +/* + * 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.ios.touch; + +import io.appium.java_client.touch.OptionsWithAbsolutePositioning; + +/** + * @deprecated this class will be removed + */ +@Deprecated +public class DoubleTapOptions extends OptionsWithAbsolutePositioning { +} diff --git a/src/main/java/io/appium/java_client/touch/ActionOptions.java b/src/main/java/io/appium/java_client/touch/ActionOptions.java new file mode 100644 index 000000000..2673142e4 --- /dev/null +++ b/src/main/java/io/appium/java_client/touch/ActionOptions.java @@ -0,0 +1,40 @@ +/* + * 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.touch; + +import java.util.HashMap; +import java.util.Map; + +public abstract class ActionOptions> { + /** + * This method is automatically called before building + * options map to verify the consistency of the instance. + * + * @throws IllegalArgumentException if there are problems with this options map. + */ + protected abstract void verify(); + + /** + * Creates a map based on the provided options. + * + * @return options mapping. + */ + public Map build() { + verify(); + return new HashMap<>(); + } +} diff --git a/src/main/java/io/appium/java_client/touch/LongPressOptions.java b/src/main/java/io/appium/java_client/touch/LongPressOptions.java new file mode 100644 index 000000000..42d63aabf --- /dev/null +++ b/src/main/java/io/appium/java_client/touch/LongPressOptions.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.touch; + +import java.time.Duration; +import java.util.Map; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +public class LongPressOptions extends OptionsWithAbsolutePositioning { + protected Duration duration = null; + + /** + * Set the long press duration. + * + * @param duration the duration value to set. + * Time resolution unit is 1 ms. + * @return this instance for chaining. + */ + public LongPressOptions withDuration(Duration duration) { + checkNotNull(duration); + checkArgument(duration.toMillis() >= 0, + "Duration value should be greater or equal to zero"); + this.duration = duration; + return this; + } + + @Override + public Map build() { + final Map result = super.build(); + if (duration != null) { + result.put("duration", this.duration.toMillis()); + } + return result; + } +} diff --git a/src/main/java/io/appium/java_client/touch/MoveToOptions.java b/src/main/java/io/appium/java_client/touch/MoveToOptions.java new file mode 100644 index 000000000..b081ef973 --- /dev/null +++ b/src/main/java/io/appium/java_client/touch/MoveToOptions.java @@ -0,0 +1,20 @@ +/* + * 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.touch; + +public class MoveToOptions extends OptionsWithRelativePositioning { +} diff --git a/src/main/java/io/appium/java_client/touch/OptionsWithAbsolutePositioning.java b/src/main/java/io/appium/java_client/touch/OptionsWithAbsolutePositioning.java new file mode 100644 index 000000000..989059f50 --- /dev/null +++ b/src/main/java/io/appium/java_client/touch/OptionsWithAbsolutePositioning.java @@ -0,0 +1,107 @@ +/* + * 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.touch; + +import org.openqa.selenium.Point; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.internal.HasIdentity; + +import java.util.Map; + +import static com.google.common.base.Preconditions.checkNotNull; + +public abstract class OptionsWithAbsolutePositioning> + extends ActionOptions { + private String elementId = null; + private Point absoluteOffset = null; + private Point relativeOffset = null; + + /** + * Set the destination element for the corresponding action. + * + * @param element the destination element. + * @return this instance for chaining. + */ + public T withElement(WebElement element) { + checkNotNull(element); + this.elementId = ((HasIdentity) element).getId(); + //noinspection unchecked + return (T) this; + } + + /** + * Set the absolute offset for the corresponding action. + * + * @param xOffset the absolute distance from the left screen corner (the element must not be set). + * @param yOffset the absolute distance from the top screen corner. + * @return this instance for chaining. + */ + public T withAbsoluteOffset(int xOffset, int yOffset) { + this.absoluteOffset = new Point(xOffset, yOffset); + //noinspection unchecked + return (T) this; + } + + /** + * Set the relative offset for the corresponding action. + * + * @param xOffset the relative distance from the left element corner (the element must be set). + * @param yOffset the relative distance from the top element corner (the element must be set). + * @return this instance for chaining. + */ + public T withRelativeOffset(int xOffset, int yOffset) { + this.relativeOffset = new Point(xOffset, yOffset); + //noinspection unchecked + return (T) this; + } + + @Override + protected void verify() { + if (elementId == null) { + if (absoluteOffset != null) { + throw new IllegalArgumentException("Absolute offset must not be defined if 'element' option is set"); + } + if (relativeOffset == null) { + throw new IllegalArgumentException("Relative offset must be defined if 'element' option is set"); + } + } else { + if (absoluteOffset == null) { + throw new IllegalArgumentException("Absolute offset must be defined if 'element' option not set"); + } + if (relativeOffset != null) { + throw new IllegalArgumentException("Relative offset must not be defined if 'element' option not set"); + } + } + } + + @Override + public Map build() { + final Map result = super.build(); + if (absoluteOffset != null) { + result.put("x", absoluteOffset.x); + result.put("y", absoluteOffset.y); + } + if (relativeOffset != null) { + result.put("x", relativeOffset.x); + result.put("y", relativeOffset.y); + } + if (elementId != null) { + result.put("element", elementId); + } + return result; + } +} diff --git a/src/main/java/io/appium/java_client/touch/OptionsWithRelativePositioning.java b/src/main/java/io/appium/java_client/touch/OptionsWithRelativePositioning.java new file mode 100644 index 000000000..786101b73 --- /dev/null +++ b/src/main/java/io/appium/java_client/touch/OptionsWithRelativePositioning.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.touch; + +import org.openqa.selenium.Point; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.internal.HasIdentity; + +import java.util.Map; + +import static com.google.common.base.Preconditions.checkNotNull; + +public abstract class OptionsWithRelativePositioning> + extends ActionOptions { + private String elementId = null; + private Point relativeOffset = null; + + /** + * Set the destination element for the corresponding action. + * + * @param element the destination element. + * @return this instance for chaining. + */ + public T withElement(WebElement element) { + checkNotNull(element); + this.elementId = ((HasIdentity) element).getId(); + //noinspection unchecked + return (T) this; + } + + /** + * Set the relative offset for the corresponding action. + * + * @param xOffset the relative distance from the left element corner + * (if set) or from the left corner of the preceding chain action. + * @param yOffset the relative distance from the top element corner + * (if set) or from the top corner of the preceding chain action. + * @return this instance for chaining. + */ + public T withRelativeOffset(int xOffset, int yOffset) { + this.relativeOffset = new Point(xOffset, yOffset); + //noinspection unchecked + return (T) this; + } + + @Override + protected void verify() { + if (elementId == null && relativeOffset == null) { + throw new IllegalArgumentException("Either element or relative offset should be defined"); + } + } + + @Override + public Map build() { + final Map result = super.build(); + if (relativeOffset != null) { + result.put("x", relativeOffset.x); + result.put("y", relativeOffset.y); + } + if (elementId != null) { + result.put("element", elementId); + } + return result; + } +} diff --git a/src/main/java/io/appium/java_client/touch/PressOptions.java b/src/main/java/io/appium/java_client/touch/PressOptions.java new file mode 100644 index 000000000..1d51fe720 --- /dev/null +++ b/src/main/java/io/appium/java_client/touch/PressOptions.java @@ -0,0 +1,20 @@ +/* + * 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.touch; + +public class PressOptions extends OptionsWithAbsolutePositioning { +} diff --git a/src/main/java/io/appium/java_client/touch/TapOptions.java b/src/main/java/io/appium/java_client/touch/TapOptions.java new file mode 100644 index 000000000..35fe5cb78 --- /dev/null +++ b/src/main/java/io/appium/java_client/touch/TapOptions.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.touch; + +import java.util.Map; + +import static com.google.common.base.Preconditions.checkArgument; + +public class TapOptions extends OptionsWithAbsolutePositioning { + private Integer tapsCount = null; + + /** + * Set the count of taps to perform. + * + * @param tapsCount the taps count to perform. + * The value should be greater than zero. + * @return this instance for chaining. + */ + public TapOptions withTapsCount(int tapsCount) { + checkArgument(tapsCount > 0, "Taps count should be greater than zero"); + this.tapsCount = tapsCount; + return this; + } + + @Override + public Map build() { + final Map result = super.build(); + if (tapsCount != null) { + result.put("count", this.tapsCount); + } + return result; + } +} diff --git a/src/main/java/io/appium/java_client/touch/WaitOptions.java b/src/main/java/io/appium/java_client/touch/WaitOptions.java new file mode 100644 index 000000000..784329e69 --- /dev/null +++ b/src/main/java/io/appium/java_client/touch/WaitOptions.java @@ -0,0 +1,56 @@ +/* + * 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.touch; + +import java.time.Duration; +import java.util.Map; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +public class WaitOptions extends ActionOptions { + protected Duration duration = Duration.ofMillis(0); + + /** + * Set the wait duration. + * + * @param duration the duration value to set. + * Time resolution unit is 1 ms. + * @return this instance for chaining. + */ + public WaitOptions withDuration(Duration duration) { + checkNotNull(duration); + checkArgument(duration.toMillis() >= 0, + "Duration value should be greater or equal to zero"); + this.duration = duration; + return this; + } + + @Override + protected void verify() { + // Wait options have nothing to verify + } + + @Override + public Map build() { + final Map result = super.build(); + if (duration != null) { + result.put("ms", this.duration.toMillis()); + } + return result; + } +} diff --git a/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java b/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java index 607f84a7f..b4d12cf84 100644 --- a/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java +++ b/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java @@ -3,8 +3,10 @@ import static org.junit.Assert.assertNotEquals; import io.appium.java_client.MobileElement; -import io.appium.java_client.TouchAction; import io.appium.java_client.functions.ActionSupplier; +import io.appium.java_client.touch.MoveToOptions; +import io.appium.java_client.touch.PressOptions; +import io.appium.java_client.touch.WaitOptions; import org.junit.Test; import org.openqa.selenium.Point; @@ -13,7 +15,7 @@ public class AndroidAbilityToUseSupplierTest extends BaseAndroidTest { - private final ActionSupplier horizontalSwipe = () -> { + private final ActionSupplier horizontalSwipe = () -> { driver.findElementById("io.appium.android.apis:id/gallery"); AndroidElement gallery = driver.findElementById("io.appium.android.apis:id/gallery"); @@ -22,13 +24,25 @@ public class AndroidAbilityToUseSupplierTest extends BaseAndroidTest { Point location = gallery.getLocation(); Point center = gallery.getCenter(); - return new TouchAction(driver).press(images.get(2), -10, center.y - location.y) - .waitAction(Duration.ofSeconds(2)).moveTo(gallery, 10, center.y - location.y).release(); + return new AndroidTouchAction(driver) + .press(new PressOptions() + .withElement(images.get(2)) + .withRelativeOffset( -10, center.y - location.y)) + .waitAction(new WaitOptions().withDuration(Duration.ofSeconds(2))) + .moveTo(new MoveToOptions() + .withElement(gallery) + .withRelativeOffset( 10, center.y - location.y)) + .release(); }; - private final ActionSupplier verticalSwiping = () -> - new TouchAction(driver).press(driver.findElementByAccessibilityId("Gallery")) - .waitAction(Duration.ofSeconds(2)).moveTo(driver.findElementByAccessibilityId("Auto Complete")) + private final ActionSupplier verticalSwiping = () -> + new AndroidTouchAction(driver) + .press(new PressOptions() + .withElement(driver.findElementByAccessibilityId("Gallery"))) + .waitAction(new WaitOptions() + .withDuration(Duration.ofSeconds(2))) + .moveTo(new MoveToOptions() + .withElement(driver.findElementByAccessibilityId("Auto Complete"))) .release(); @Test public void horizontalSwipingWithSupplier() throws Exception { diff --git a/src/test/java/io/appium/java_client/android/AndroidTouchTest.java b/src/test/java/io/appium/java_client/android/AndroidTouchTest.java index 3a4cc3651..21a15c4fd 100644 --- a/src/test/java/io/appium/java_client/android/AndroidTouchTest.java +++ b/src/test/java/io/appium/java_client/android/AndroidTouchTest.java @@ -6,6 +6,11 @@ import io.appium.java_client.MobileElement; import io.appium.java_client.MultiTouchAction; import io.appium.java_client.TouchAction; +import io.appium.java_client.touch.LongPressOptions; +import io.appium.java_client.touch.MoveToOptions; +import io.appium.java_client.touch.PressOptions; +import io.appium.java_client.touch.TapOptions; +import io.appium.java_client.touch.WaitOptions; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.By; @@ -31,8 +36,12 @@ public void setUp() throws Exception { WebElement dragText = driver.findElement(By.id("io.appium.android.apis:id/drag_text")); assertEquals("Drag text not empty", "", dragText.getText()); - TouchAction dragNDrop = - new TouchAction(driver).longPress(dragDot1).moveTo(dragDot3).release(); + TouchAction dragNDrop = new TouchAction(driver) + .longPress(new LongPressOptions() + .withElement(dragDot1)) + .moveTo(new MoveToOptions() + .withElement(dragDot3)) + .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); } @@ -46,8 +55,13 @@ public void setUp() throws Exception { WebElement dragText = driver.findElement(By.id("io.appium.android.apis:id/drag_text")); assertEquals("Drag text not empty", "", dragText.getText()); - TouchAction dragNDrop = - new TouchAction(driver).longPress(dragDot1, Duration.ofSeconds(2)).moveTo(dragDot3).release(); + TouchAction dragNDrop = new TouchAction(driver) + .longPress(new LongPressOptions() + .withElement(dragDot1) + .withDuration(Duration.ofSeconds(2))) + .moveTo(new MoveToOptions() + .withElement(dragDot3)) + .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); } @@ -64,8 +78,12 @@ public void setUp() throws Exception { Point center1 = dragDot1.getCenter(); Point center2 = dragDot3.getCenter(); - TouchAction dragNDrop = - new TouchAction(driver).longPress(center1.x, center1.y).moveTo(center2.x, center2.y).release(); + TouchAction dragNDrop = new TouchAction(driver) + .longPress(new LongPressOptions() + .withAbsoluteOffset(center1.x, center1.y)) + .moveTo(new MoveToOptions() + .withRelativeOffset(center2.x, center2.y)) + .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); } @@ -82,9 +100,13 @@ public void setUp() throws Exception { Point center1 = dragDot1.getCenter(); Point center2 = dragDot3.getCenter(); - TouchAction dragNDrop = - new TouchAction(driver).longPress(center1.x, center1.y, Duration.ofSeconds(2)) - .moveTo(center2.x, center2.y).release(); + TouchAction dragNDrop = new TouchAction(driver) + .longPress(new LongPressOptions() + .withAbsoluteOffset(center1.x, center1.y) + .withDuration(Duration.ofSeconds(2))) + .moveTo(new MoveToOptions() + .withRelativeOffset(center2.x, center2.y)) + .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); } @@ -94,8 +116,13 @@ public void setUp() throws Exception { driver.startActivity(activity); Point point = driver.findElementById("io.appium.android.apis:id/button_toggle").getLocation(); - new TouchAction(driver).press(point.x + 20, point.y + 30).waitAction(Duration.ofSeconds(1)) - .release().perform(); + new TouchAction(driver) + .press(new PressOptions() + .withAbsoluteOffset(point.x + 20, point.y + 30)) + .waitAction(new WaitOptions() + .withDuration(Duration.ofSeconds(1))) + .release() + .perform(); assertEquals("ON" ,driver .findElementById("io.appium.android.apis:id/button_toggle").getText()); } @@ -103,8 +130,13 @@ public void setUp() throws Exception { @Test public void pressByElementTest() throws Exception { Activity activity = new Activity("io.appium.android.apis", ".view.Buttons1"); driver.startActivity(activity); - new TouchAction(driver).press(driver.findElementById("io.appium.android.apis:id/button_toggle")) - .waitAction(Duration.ofSeconds(1)).release().perform(); + new TouchAction(driver) + .press(new PressOptions() + .withElement(driver.findElementById("io.appium.android.apis:id/button_toggle"))) + .waitAction(new WaitOptions() + .withDuration(Duration.ofSeconds(1))) + .release() + .perform(); assertEquals("ON" ,driver .findElementById("io.appium.android.apis:id/button_toggle").getText()); } @@ -116,8 +148,12 @@ public void setUp() throws Exception { driver.findElementById("io.appium.android.apis:id/chronometer"); TouchAction startStop = new TouchAction(driver) - .tap(driver.findElementById("io.appium.android.apis:id/start")).waitAction(Duration.ofSeconds(2)) - .tap(driver.findElementById("io.appium.android.apis:id/stop")); + .tap(new TapOptions() + .withElement(driver.findElementById("io.appium.android.apis:id/start"))) + .waitAction(new WaitOptions() + .withDuration(Duration.ofSeconds(2))) + .tap(new TapOptions() + .withElement(driver.findElementById("io.appium.android.apis:id/stop"))); startStop.perform(); @@ -136,8 +172,11 @@ public void setUp() throws Exception { Point center1 = driver.findElementById("io.appium.android.apis:id/start").getCenter(); TouchAction startStop = new TouchAction(driver) - .tap(center1.x, center1.y) - .tap(driver.findElementById("io.appium.android.apis:id/stop"), 5, 5); + .tap(new TapOptions() + .withAbsoluteOffset(center1.x, center1.y)) + .tap(new TapOptions() + .withElement(driver.findElementById("io.appium.android.apis:id/stop")) + .withRelativeOffset(5, 5)); startStop.perform(); String time = chronometer.getText(); @@ -157,8 +196,16 @@ public void setUp() throws Exception { Point location = gallery.getLocation(); Point center = gallery.getCenter(); - TouchAction swipe = new TouchAction(driver).press(images.get(2), -10, center.y - location.y) - .waitAction(Duration.ofSeconds(2)).moveTo(gallery, 10, center.y - location.y).release(); + TouchAction swipe = new TouchAction(driver) + .press(new PressOptions() + .withElement(images.get(2)) + .withRelativeOffset( -10, center.y - location.y)) + .waitAction(new WaitOptions() + .withDuration(Duration.ofSeconds(2))) + .moveTo(new MoveToOptions() + .withElement(gallery) + .withRelativeOffset( 10, center.y - location.y)) + .release(); swipe.perform(); assertNotEquals(originalImageCount, gallery .findElementsByClassName("android.widget.ImageView").size()); @@ -167,10 +214,14 @@ public void setUp() throws Exception { @Test public void multiTouchTest() throws Exception { Activity activity = new Activity("io.appium.android.apis", ".view.Buttons1"); driver.startActivity(activity); - TouchAction press = new TouchAction(driver); - press.press(driver.findElementById("io.appium.android.apis:id/button_toggle")).waitAction(Duration.ofSeconds(1)) + TouchAction press = new TouchAction(driver) + .press(new PressOptions() + .withElement(driver.findElementById("io.appium.android.apis:id/button_toggle"))) + .waitAction(new WaitOptions() + .withDuration(Duration.ofSeconds(1))) .release(); - new MultiTouchAction(driver).add(press) + new MultiTouchAction(driver) + .add(press) .perform(); assertEquals("ON" ,driver .findElementById("io.appium.android.apis:id/button_toggle").getText()); From 5fdf0e190178b8ec0d873ae967d9536e91cecf32 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Mon, 16 Oct 2017 20:22:41 +0200 Subject: [PATCH 02/14] Add unit tests --- .../touch/OptionsWithAbsolutePositioning.java | 15 +-- .../java_client/touch/DummyElement.java | 104 +++++++++++++++ .../java_client/touch/FailsWithMatcher.java | 44 +++++++ .../java_client/touch/IThrowingRunnable.java | 6 + .../java_client/touch/TouchOptionsTests.java | 120 ++++++++++++++++++ 5 files changed, 280 insertions(+), 9 deletions(-) create mode 100644 src/test/java/io/appium/java_client/touch/DummyElement.java create mode 100644 src/test/java/io/appium/java_client/touch/FailsWithMatcher.java create mode 100644 src/test/java/io/appium/java_client/touch/IThrowingRunnable.java create mode 100644 src/test/java/io/appium/java_client/touch/TouchOptionsTests.java diff --git a/src/main/java/io/appium/java_client/touch/OptionsWithAbsolutePositioning.java b/src/main/java/io/appium/java_client/touch/OptionsWithAbsolutePositioning.java index 989059f50..ef2c804fd 100644 --- a/src/main/java/io/appium/java_client/touch/OptionsWithAbsolutePositioning.java +++ b/src/main/java/io/appium/java_client/touch/OptionsWithAbsolutePositioning.java @@ -72,18 +72,15 @@ public T withRelativeOffset(int xOffset, int yOffset) { @Override protected void verify() { if (elementId == null) { - if (absoluteOffset != null) { - throw new IllegalArgumentException("Absolute offset must not be defined if 'element' option is set"); - } - if (relativeOffset == null) { - throw new IllegalArgumentException("Relative offset must be defined if 'element' option is set"); - } - } else { if (absoluteOffset == null) { - throw new IllegalArgumentException("Absolute offset must be defined if 'element' option not set"); + throw new IllegalArgumentException("Absolute offset must be defined if 'element' option is not set"); } if (relativeOffset != null) { - throw new IllegalArgumentException("Relative offset must not be defined if 'element' option not set"); + throw new IllegalArgumentException("Relative offset must not be defined if 'element' option is not set"); + } + } else { + if (absoluteOffset != null) { + throw new IllegalArgumentException("Absolute offset must not be defined if 'element' option set"); } } } diff --git a/src/test/java/io/appium/java_client/touch/DummyElement.java b/src/test/java/io/appium/java_client/touch/DummyElement.java new file mode 100644 index 000000000..345409054 --- /dev/null +++ b/src/test/java/io/appium/java_client/touch/DummyElement.java @@ -0,0 +1,104 @@ +package io.appium.java_client.touch; + + +import org.openqa.selenium.By; +import org.openqa.selenium.Dimension; +import org.openqa.selenium.Point; +import org.openqa.selenium.Rectangle; +import org.openqa.selenium.OutputType; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.internal.HasIdentity; + +import java.util.List; + +public class DummyElement implements WebElement, HasIdentity { + @Override + public void click() { + // dummy + } + + @Override + public void submit() { + // dummy + } + + @Override + public void sendKeys(CharSequence... charSequences) { + // dummy + } + + @Override + public void clear() { + // dummy + } + + @Override + public String getTagName() { + return ""; + } + + @Override + public String getAttribute(String s) { + return ""; + } + + @Override + public boolean isSelected() { + return false; + } + + @Override + public boolean isEnabled() { + return false; + } + + @Override + public String getText() { + return ""; + } + + @Override + public List findElements(By by) { + return null; + } + + @Override + public WebElement findElement(By by) { + return null; + } + + @Override + public boolean isDisplayed() { + return false; + } + + @Override + public Point getLocation() { + return null; + } + + @Override + public Dimension getSize() { + return null; + } + + @Override + public Rectangle getRect() { + return null; + } + + @Override + public String getCssValue(String s) { + return ""; + } + + @Override + public X getScreenshotAs(OutputType outputType) { + return null; + } + + @Override + public String getId() { + return "123"; + } +} \ No newline at end of file diff --git a/src/test/java/io/appium/java_client/touch/FailsWithMatcher.java b/src/test/java/io/appium/java_client/touch/FailsWithMatcher.java new file mode 100644 index 000000000..9db19e38b --- /dev/null +++ b/src/test/java/io/appium/java_client/touch/FailsWithMatcher.java @@ -0,0 +1,44 @@ +package io.appium.java_client.touch; + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.TypeSafeMatcher; + +import static org.hamcrest.core.AllOf.allOf; +import static org.hamcrest.core.IsInstanceOf.instanceOf; + +public final class FailsWithMatcher + extends TypeSafeMatcher> { + + private final Matcher matcher; + + private FailsWithMatcher(final Matcher matcher) { + this.matcher = matcher; + } + + public static Matcher> failsWith( + final Class throwableType) { + return new FailsWithMatcher<>(instanceOf(throwableType)); + } + + public static Matcher> failsWith( + final Class throwableType, final Matcher throwableMatcher) { + return new FailsWithMatcher<>(allOf(instanceOf(throwableType), throwableMatcher)); + } + + @Override + protected boolean matchesSafely(final IThrowingRunnable runnable) { + try { + runnable.run(); + return false; + } catch (final Throwable ex) { + return matcher.matches(ex); + } + } + + @Override + public void describeTo(final Description description) { + description.appendText("fails with ").appendDescriptionOf(matcher); + } + +} diff --git a/src/test/java/io/appium/java_client/touch/IThrowingRunnable.java b/src/test/java/io/appium/java_client/touch/IThrowingRunnable.java new file mode 100644 index 000000000..5ab472f89 --- /dev/null +++ b/src/test/java/io/appium/java_client/touch/IThrowingRunnable.java @@ -0,0 +1,6 @@ +package io.appium.java_client.touch; + +@FunctionalInterface +public interface IThrowingRunnable { + void run() throws E; +} diff --git a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java new file mode 100644 index 000000000..3e0caf168 --- /dev/null +++ b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java @@ -0,0 +1,120 @@ +package io.appium.java_client.touch; + +import org.junit.Test; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.internal.HasIdentity; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static io.appium.java_client.touch.FailsWithMatcher.failsWith; +import static org.hamcrest.CoreMatchers.everyItem; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.isIn; + +public class TouchOptionsTests { + private static final WebElement dummyElement = new DummyElement(); + + @Test + public void invalidAbsolutePositionOptionsShouldFailOnBuild() throws Exception { + final List invalidOptions = new ArrayList<>(); + invalidOptions.add(new PressOptions() + .withElement(dummyElement) + .withAbsoluteOffset(0, 0)); + invalidOptions.add(new LongPressOptions() + .withRelativeOffset(0, 0)); + invalidOptions.add(new TapOptions()); + invalidOptions.add(new TapOptions() + .withAbsoluteOffset(0, 0) + .withRelativeOffset(0, 0)); + invalidOptions.forEach(opts -> assertThat(opts::build, failsWith(IllegalArgumentException.class))); + } + + @Test + public void invalidRelativePositionOptionsShouldFailOnBuild() throws Exception { + final List invalidOptions = new ArrayList<>(); + invalidOptions.add(new MoveToOptions()); + invalidOptions.forEach(opts -> assertThat(opts::build, failsWith(IllegalArgumentException.class))); + } + + @Test + public void invalidOptionsArgumentsShouldFailOnAltering() throws Exception { + final List> invalidOptions = new ArrayList<>(); + invalidOptions.add(() -> new WaitOptions().withDuration(Duration.ofMillis(-1))); + invalidOptions.add(() -> new PressOptions().withElement(null)); + invalidOptions.add(() -> new MoveToOptions().withElement(null)); + invalidOptions.add(() -> new WaitOptions().withDuration(null)); + for (IThrowingRunnable item : invalidOptions) { + assertThat(item, failsWith(RuntimeException.class)); + } + } + + @Test + public void longPressOptionsShouldBuildProperly() throws Exception { + final Map actualOpts = new LongPressOptions() + .withElement(dummyElement) + .withRelativeOffset(0, 0) + .withDuration(Duration.ofMillis(1)) + .build(); + final Map expectedOpts = new HashMap<>(); + expectedOpts.put("element", ((HasIdentity) dummyElement).getId()); + expectedOpts.put("x", 0); + expectedOpts.put("y", 0); + expectedOpts.put("duration", 1L); + assertThat(actualOpts.entrySet(), everyItem(isIn(expectedOpts.entrySet()))); + assertThat(expectedOpts.entrySet(), everyItem(isIn(actualOpts.entrySet()))); + } + + @Test + public void tapOptionsShouldBuildProperly() throws Exception { + final Map actualOpts = new TapOptions() + .withAbsoluteOffset(0, 0) + .withTapsCount(2) + .build(); + final Map expectedOpts = new HashMap<>(); + expectedOpts.put("x", 0); + expectedOpts.put("y", 0); + expectedOpts.put("count", 2); + assertThat(actualOpts.entrySet(), everyItem(isIn(expectedOpts.entrySet()))); + assertThat(expectedOpts.entrySet(), everyItem(isIn(actualOpts.entrySet()))); + } + + @Test + public void pressOptionsShouldBuildProperly() throws Exception { + final Map actualOpts = new PressOptions() + .withElement(dummyElement) + .build(); + final Map expectedOpts = new HashMap<>(); + expectedOpts.put("element", ((HasIdentity) dummyElement).getId()); + assertThat(actualOpts.entrySet(), everyItem(isIn(expectedOpts.entrySet()))); + assertThat(expectedOpts.entrySet(), everyItem(isIn(actualOpts.entrySet()))); + } + + @Test + public void moveToOptionsShouldBuildProperly() throws Exception { + final Map actualOpts = new MoveToOptions() + .withElement(dummyElement) + .withRelativeOffset(-1,-1) + .build(); + final Map expectedOpts = new HashMap<>(); + expectedOpts.put("element", ((HasIdentity) dummyElement).getId()); + expectedOpts.put("x", -1); + expectedOpts.put("y", -1); + assertThat(actualOpts.entrySet(), everyItem(isIn(expectedOpts.entrySet()))); + assertThat(expectedOpts.entrySet(), everyItem(isIn(actualOpts.entrySet()))); + } + + @Test + public void waitOptionsShouldBuildProperly() throws Exception { + final Map actualOpts = new WaitOptions() + .withDuration(Duration.ofSeconds(1)) + .build(); + final Map expectedOpts = new HashMap<>(); + expectedOpts.put("ms", 1000L); + assertThat(actualOpts.entrySet(), everyItem(isIn(expectedOpts.entrySet()))); + assertThat(expectedOpts.entrySet(), everyItem(isIn(actualOpts.entrySet()))); + } +} From 95e40426fc9fc4bcaf660bce6d4213baee32df76 Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Tue, 17 Oct 2017 07:36:48 +0200 Subject: [PATCH 03/14] Fix checkstyle issues --- .../io/appium/java_client/TouchAction.java | 4 +-- .../java_client/touch/LongPressOptions.java | 6 ++-- .../touch/OptionsWithAbsolutePositioning.java | 13 ++++--- .../touch/OptionsWithRelativePositioning.java | 4 +-- .../appium/java_client/touch/TapOptions.java | 4 +-- .../appium/java_client/touch/WaitOptions.java | 6 ++-- .../java_client/touch/FailsWithMatcher.java | 23 ++++++------- .../java_client/touch/TouchOptionsTests.java | 34 +++++++++++-------- 8 files changed, 50 insertions(+), 44 deletions(-) diff --git a/src/main/java/io/appium/java_client/TouchAction.java b/src/main/java/io/appium/java_client/TouchAction.java index 968d776b3..d35d07221 100644 --- a/src/main/java/io/appium/java_client/TouchAction.java +++ b/src/main/java/io/appium/java_client/TouchAction.java @@ -16,6 +16,8 @@ package io.appium.java_client; +import static com.google.common.base.Preconditions.checkNotNull; + import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -29,8 +31,6 @@ import java.time.Duration; -import static com.google.common.base.Preconditions.checkNotNull; - /** * Used for Webdriver 3 touch actions * See the Webriver 3 spec diff --git a/src/main/java/io/appium/java_client/touch/LongPressOptions.java b/src/main/java/io/appium/java_client/touch/LongPressOptions.java index 42d63aabf..3a03dd311 100644 --- a/src/main/java/io/appium/java_client/touch/LongPressOptions.java +++ b/src/main/java/io/appium/java_client/touch/LongPressOptions.java @@ -16,12 +16,12 @@ package io.appium.java_client.touch; -import java.time.Duration; -import java.util.Map; - import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import java.time.Duration; +import java.util.Map; + public class LongPressOptions extends OptionsWithAbsolutePositioning { protected Duration duration = null; diff --git a/src/main/java/io/appium/java_client/touch/OptionsWithAbsolutePositioning.java b/src/main/java/io/appium/java_client/touch/OptionsWithAbsolutePositioning.java index ef2c804fd..56d13bfa8 100644 --- a/src/main/java/io/appium/java_client/touch/OptionsWithAbsolutePositioning.java +++ b/src/main/java/io/appium/java_client/touch/OptionsWithAbsolutePositioning.java @@ -16,14 +16,14 @@ package io.appium.java_client.touch; +import static com.google.common.base.Preconditions.checkNotNull; + import org.openqa.selenium.Point; import org.openqa.selenium.WebElement; import org.openqa.selenium.internal.HasIdentity; import java.util.Map; -import static com.google.common.base.Preconditions.checkNotNull; - public abstract class OptionsWithAbsolutePositioning> extends ActionOptions { private String elementId = null; @@ -73,14 +73,17 @@ public T withRelativeOffset(int xOffset, int yOffset) { protected void verify() { if (elementId == null) { if (absoluteOffset == null) { - throw new IllegalArgumentException("Absolute offset must be defined if 'element' option is not set"); + throw new IllegalArgumentException( + "Absolute offset must be defined if 'element' option is not set"); } if (relativeOffset != null) { - throw new IllegalArgumentException("Relative offset must not be defined if 'element' option is not set"); + throw new IllegalArgumentException( + "Relative offset must not be defined if 'element' option is not set"); } } else { if (absoluteOffset != null) { - throw new IllegalArgumentException("Absolute offset must not be defined if 'element' option set"); + throw new IllegalArgumentException( + "Absolute offset must not be defined if 'element' option set"); } } } diff --git a/src/main/java/io/appium/java_client/touch/OptionsWithRelativePositioning.java b/src/main/java/io/appium/java_client/touch/OptionsWithRelativePositioning.java index 786101b73..8046f982d 100644 --- a/src/main/java/io/appium/java_client/touch/OptionsWithRelativePositioning.java +++ b/src/main/java/io/appium/java_client/touch/OptionsWithRelativePositioning.java @@ -16,14 +16,14 @@ package io.appium.java_client.touch; +import static com.google.common.base.Preconditions.checkNotNull; + import org.openqa.selenium.Point; import org.openqa.selenium.WebElement; import org.openqa.selenium.internal.HasIdentity; import java.util.Map; -import static com.google.common.base.Preconditions.checkNotNull; - public abstract class OptionsWithRelativePositioning> extends ActionOptions { private String elementId = null; diff --git a/src/main/java/io/appium/java_client/touch/TapOptions.java b/src/main/java/io/appium/java_client/touch/TapOptions.java index 35fe5cb78..ae2c777c4 100644 --- a/src/main/java/io/appium/java_client/touch/TapOptions.java +++ b/src/main/java/io/appium/java_client/touch/TapOptions.java @@ -16,10 +16,10 @@ package io.appium.java_client.touch; -import java.util.Map; - import static com.google.common.base.Preconditions.checkArgument; +import java.util.Map; + public class TapOptions extends OptionsWithAbsolutePositioning { private Integer tapsCount = null; diff --git a/src/main/java/io/appium/java_client/touch/WaitOptions.java b/src/main/java/io/appium/java_client/touch/WaitOptions.java index 784329e69..e5a2d6be8 100644 --- a/src/main/java/io/appium/java_client/touch/WaitOptions.java +++ b/src/main/java/io/appium/java_client/touch/WaitOptions.java @@ -16,12 +16,12 @@ package io.appium.java_client.touch; -import java.time.Duration; -import java.util.Map; - import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import java.time.Duration; +import java.util.Map; + public class WaitOptions extends ActionOptions { protected Duration duration = Duration.ofMillis(0); diff --git a/src/test/java/io/appium/java_client/touch/FailsWithMatcher.java b/src/test/java/io/appium/java_client/touch/FailsWithMatcher.java index 9db19e38b..edd16e026 100644 --- a/src/test/java/io/appium/java_client/touch/FailsWithMatcher.java +++ b/src/test/java/io/appium/java_client/touch/FailsWithMatcher.java @@ -1,33 +1,32 @@ package io.appium.java_client.touch; +import static org.hamcrest.core.AllOf.allOf; +import static org.hamcrest.core.IsInstanceOf.instanceOf; + import org.hamcrest.Description; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; -import static org.hamcrest.core.AllOf.allOf; -import static org.hamcrest.core.IsInstanceOf.instanceOf; - -public final class FailsWithMatcher - extends TypeSafeMatcher> { +public final class FailsWithMatcher extends TypeSafeMatcher> { - private final Matcher matcher; + private final Matcher matcher; - private FailsWithMatcher(final Matcher matcher) { + private FailsWithMatcher(final Matcher matcher) { this.matcher = matcher; } - public static Matcher> failsWith( - final Class throwableType) { + public static Matcher> failsWith( + final Class throwableType) { return new FailsWithMatcher<>(instanceOf(throwableType)); } - public static Matcher> failsWith( - final Class throwableType, final Matcher throwableMatcher) { + public static Matcher> failsWith( + final Class throwableType, final Matcher throwableMatcher) { return new FailsWithMatcher<>(allOf(instanceOf(throwableType), throwableMatcher)); } @Override - protected boolean matchesSafely(final IThrowingRunnable runnable) { + protected boolean matchesSafely(final IThrowingRunnable runnable) { try { runnable.run(); return false; diff --git a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java index 3e0caf168..1ed86199f 100644 --- a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java +++ b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java @@ -4,25 +4,25 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.internal.HasIdentity; +import static io.appium.java_client.touch.FailsWithMatcher.failsWith; +import static org.hamcrest.CoreMatchers.everyItem; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.isIn; + import java.time.Duration; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import static io.appium.java_client.touch.FailsWithMatcher.failsWith; -import static org.hamcrest.CoreMatchers.everyItem; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.isIn; - public class TouchOptionsTests { - private static final WebElement dummyElement = new DummyElement(); + private static final WebElement DUMMY_ELEMENT = new DummyElement(); @Test public void invalidAbsolutePositionOptionsShouldFailOnBuild() throws Exception { final List invalidOptions = new ArrayList<>(); invalidOptions.add(new PressOptions() - .withElement(dummyElement) + .withElement(DUMMY_ELEMENT) .withAbsoluteOffset(0, 0)); invalidOptions.add(new LongPressOptions() .withRelativeOffset(0, 0)); @@ -30,14 +30,18 @@ public void invalidAbsolutePositionOptionsShouldFailOnBuild() throws Exception { invalidOptions.add(new TapOptions() .withAbsoluteOffset(0, 0) .withRelativeOffset(0, 0)); - invalidOptions.forEach(opts -> assertThat(opts::build, failsWith(IllegalArgumentException.class))); + for (ActionOptions opts : invalidOptions) { + assertThat(opts::build, failsWith(IllegalArgumentException.class)); + } } @Test public void invalidRelativePositionOptionsShouldFailOnBuild() throws Exception { final List invalidOptions = new ArrayList<>(); invalidOptions.add(new MoveToOptions()); - invalidOptions.forEach(opts -> assertThat(opts::build, failsWith(IllegalArgumentException.class))); + for (ActionOptions opts : invalidOptions) { + assertThat(opts::build, failsWith(IllegalArgumentException.class)); + } } @Test @@ -55,12 +59,12 @@ public void invalidOptionsArgumentsShouldFailOnAltering() throws Exception { @Test public void longPressOptionsShouldBuildProperly() throws Exception { final Map actualOpts = new LongPressOptions() - .withElement(dummyElement) + .withElement(DUMMY_ELEMENT) .withRelativeOffset(0, 0) .withDuration(Duration.ofMillis(1)) .build(); final Map expectedOpts = new HashMap<>(); - expectedOpts.put("element", ((HasIdentity) dummyElement).getId()); + expectedOpts.put("element", ((HasIdentity) DUMMY_ELEMENT).getId()); expectedOpts.put("x", 0); expectedOpts.put("y", 0); expectedOpts.put("duration", 1L); @@ -85,10 +89,10 @@ public void tapOptionsShouldBuildProperly() throws Exception { @Test public void pressOptionsShouldBuildProperly() throws Exception { final Map actualOpts = new PressOptions() - .withElement(dummyElement) + .withElement(DUMMY_ELEMENT) .build(); final Map expectedOpts = new HashMap<>(); - expectedOpts.put("element", ((HasIdentity) dummyElement).getId()); + expectedOpts.put("element", ((HasIdentity) DUMMY_ELEMENT).getId()); assertThat(actualOpts.entrySet(), everyItem(isIn(expectedOpts.entrySet()))); assertThat(expectedOpts.entrySet(), everyItem(isIn(actualOpts.entrySet()))); } @@ -96,11 +100,11 @@ public void pressOptionsShouldBuildProperly() throws Exception { @Test public void moveToOptionsShouldBuildProperly() throws Exception { final Map actualOpts = new MoveToOptions() - .withElement(dummyElement) + .withElement(DUMMY_ELEMENT) .withRelativeOffset(-1,-1) .build(); final Map expectedOpts = new HashMap<>(); - expectedOpts.put("element", ((HasIdentity) dummyElement).getId()); + expectedOpts.put("element", ((HasIdentity) DUMMY_ELEMENT).getId()); expectedOpts.put("x", -1); expectedOpts.put("y", -1); assertThat(actualOpts.entrySet(), everyItem(isIn(expectedOpts.entrySet()))); From f525ae366d0c9950aa9a801b5a6a59a0552d2d68 Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Tue, 31 Oct 2017 00:14:39 +0300 Subject: [PATCH 04/14] The addition to the #756: - the draft of architectural improvements --- .../io/appium/java_client/TouchAction.java | 245 +++++++++--------- .../java_client/ios/IOSTouchAction.java | 22 +- .../ios/touch/DoubleTapOptions.java | 26 -- .../pagefactory/AppiumFieldDecorator.java | 2 +- .../touch/AbsoluteOffsetOption.java | 60 +++++ .../java_client/touch/LongPressOptions.java | 12 +- .../java_client/touch/MoveToOptions.java | 20 -- .../touch/OptionsCombinedWithOffset.java | 48 ++++ .../touch/OptionsWithAbsolutePositioning.java | 107 -------- .../java_client/touch/PressOptions.java | 20 -- ...tioning.java => RelativeOffsetOption.java} | 54 ++-- .../appium/java_client/touch/TapOptions.java | 6 +- .../appium/java_client/touch/WaitOptions.java | 12 +- .../pagefactory_tests/TimeoutTest.java | 2 +- .../java_client/touch/TouchOptionsTests.java | 2 +- 15 files changed, 293 insertions(+), 345 deletions(-) delete mode 100644 src/main/java/io/appium/java_client/ios/touch/DoubleTapOptions.java create mode 100644 src/main/java/io/appium/java_client/touch/AbsoluteOffsetOption.java delete mode 100644 src/main/java/io/appium/java_client/touch/MoveToOptions.java create mode 100644 src/main/java/io/appium/java_client/touch/OptionsCombinedWithOffset.java delete mode 100644 src/main/java/io/appium/java_client/touch/OptionsWithAbsolutePositioning.java delete mode 100644 src/main/java/io/appium/java_client/touch/PressOptions.java rename src/main/java/io/appium/java_client/touch/{OptionsWithRelativePositioning.java => RelativeOffsetOption.java} (61%) diff --git a/src/main/java/io/appium/java_client/TouchAction.java b/src/main/java/io/appium/java_client/TouchAction.java index d35d07221..46a446919 100644 --- a/src/main/java/io/appium/java_client/TouchAction.java +++ b/src/main/java/io/appium/java_client/TouchAction.java @@ -17,14 +17,17 @@ package io.appium.java_client; import static com.google.common.base.Preconditions.checkNotNull; +import static io.appium.java_client.touch.AbsoluteOffsetOption.useAbsolute; +import static io.appium.java_client.touch.LongPressOptions.longPressOptions; +import static io.appium.java_client.touch.RelativeOffsetOption.useRelative; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import io.appium.java_client.touch.ActionOptions; +import io.appium.java_client.touch.AbsoluteOffsetOption; import io.appium.java_client.touch.LongPressOptions; -import io.appium.java_client.touch.MoveToOptions; -import io.appium.java_client.touch.PressOptions; +import io.appium.java_client.touch.RelativeOffsetOption; import io.appium.java_client.touch.TapOptions; import io.appium.java_client.touch.WaitOptions; import org.openqa.selenium.WebElement; @@ -54,10 +57,22 @@ public TouchAction(PerformsTouchActions performsTouchActions) { /** * Press on an element. * - * @param pressOptions see {@link PressOptions}. + * @param pressOptions see {@link RelativeOffsetOption}. * @return this TouchAction, for chaining. */ - public T press(ActionOptions pressOptions) { + public T press(RelativeOffsetOption pressOptions) { + parameterBuilder.add(new ActionParameter("press", pressOptions)); + //noinspection unchecked + return (T) this; + } + + /** + * Press on an element. + * + * @param pressOptions see {@link AbsoluteOffsetOption}. + * @return this TouchAction, for chaining. + */ + public T press(AbsoluteOffsetOption pressOptions) { parameterBuilder.add(new ActionParameter("press", pressOptions)); //noinspection unchecked return (T) this; @@ -68,16 +83,11 @@ public T press(ActionOptions pressOptions) { * * @param el element to press on. * @return this TouchAction, for chaining. - * @deprecated use {@link #press(ActionOptions)} instead + * @deprecated use {@link #press(RelativeOffsetOption)} instead */ @Deprecated public T press(WebElement el) { - ActionParameter action = new ActionParameter("press", - new PressOptions() - .withElement(el)); - parameterBuilder.add(action); - //noinspection unchecked - return (T) this; + return press(useRelative(el)); } /** @@ -86,16 +96,11 @@ public T press(WebElement el) { * @param x x coordinate. * @param y y coordinate. * @return this TouchAction, for chaining. - * @deprecated use {@link #press(ActionOptions)} instead + * @deprecated use {@link #press(AbsoluteOffsetOption)} instead */ @Deprecated public T press(int x, int y) { - ActionParameter action = new ActionParameter("press", - new PressOptions() - .withAbsoluteOffset(x, y)); - parameterBuilder.add(action); - //noinspection unchecked - return (T) this; + return press(useAbsolute(x, y)); } /** @@ -105,17 +110,11 @@ public T press(int x, int y) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. - * @deprecated use {@link #press(ActionOptions)} instead + * @deprecated use {@link #press(RelativeOffsetOption)} instead */ @Deprecated public T press(WebElement el, int x, int y) { - ActionParameter action = new ActionParameter("press", - new PressOptions() - .withElement(el) - .withRelativeOffset(x, y)); - parameterBuilder.add(action); - //noinspection unchecked - return (T) this; + return press(useRelative(el, x, y)); } /** @@ -133,10 +132,10 @@ public T release() { /** * Move current touch to center of an element. * - * @param moveToOptions see {@link MoveToOptions}. + * @param moveToOptions see {@link AbsoluteOffsetOption}. * @return this TouchAction, for chaining. */ - public T moveTo(ActionOptions moveToOptions) { + public T moveTo(AbsoluteOffsetOption moveToOptions) { ActionParameter action = new ActionParameter("moveTo", moveToOptions); parameterBuilder.add(action); //noinspection unchecked @@ -146,20 +145,28 @@ public T moveTo(ActionOptions moveToOptions) { /** * Move current touch to center of an element. * - * @param el element to move to. + * @param moveToOptions see {@link RelativeOffsetOption}. * @return this TouchAction, for chaining. - * @deprecated {@link #moveTo(ActionOptions)} instead */ - @Deprecated - public T moveTo(WebElement el) { - ActionParameter action = new ActionParameter("moveTo", - new MoveToOptions() - .withElement(el)); + public T moveTo(RelativeOffsetOption moveToOptions) { + ActionParameter action = new ActionParameter("moveTo", moveToOptions); parameterBuilder.add(action); //noinspection unchecked return (T) this; } + /** + * Move current touch to center of an element. + * + * @param el element to move to. + * @return this TouchAction, for chaining. + * @deprecated {@link #moveTo(RelativeOffsetOption)} instead + */ + @Deprecated + public T moveTo(WebElement el) { + return moveTo(useRelative(el)); + } + /** * Move current touch to a new position relative to the current position on * the screen. If the current position of this TouchAction is (xOld, yOld), @@ -168,16 +175,11 @@ public T moveTo(WebElement el) { * @param x change in x coordinate to move through. * @param y change in y coordinate to move through. * @return this TouchAction, for chaining. - * @deprecated {@link #moveTo(ActionOptions)} instead + * @deprecated {@link #moveTo(AbsoluteOffsetOption)} instead */ @Deprecated public T moveTo(int x, int y) { - ActionParameter action = new ActionParameter("moveTo", - new MoveToOptions() - .withRelativeOffset(x, y)); - parameterBuilder.add(action); - //noinspection unchecked - return (T) this; + return moveTo(useAbsolute(x, y)); } /** @@ -187,46 +189,59 @@ public T moveTo(int x, int y) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. - * @deprecated {@link #moveTo(ActionOptions)} instead + * @deprecated {@link #moveTo(RelativeOffsetOption)} instead */ @Deprecated public T moveTo(WebElement el, int x, int y) { - ActionParameter action = new ActionParameter("moveTo", - new MoveToOptions() - .withElement(el) - .withRelativeOffset(x, y)); - parameterBuilder.add(action); - //noinspection unchecked - return (T) this; + return moveTo(useRelative(el, x, y)); } /** - * Tap the center of an element. + * Tap on an element. * * @param tapOptions see {@link TapOptions}. * @return this TouchAction, for chaining. */ - public TouchAction tap(ActionOptions tapOptions) { + public TouchAction tap(TapOptions tapOptions) { ActionParameter action = new ActionParameter("tap", tapOptions); parameterBuilder.add(action); return this; } + /** + * Tap on an element. + * + * @param tapOptions see {@link RelativeOffsetOption}. + * @return this TouchAction, for chaining. + */ + public T tap(RelativeOffsetOption tapOptions) { + ActionParameter action = new ActionParameter("tap", tapOptions); + parameterBuilder.add(action); + return (T) this; + } + + /** + * Tap on an element. + * + * @param tapOptions see {@link AbsoluteOffsetOption}. + * @return this TouchAction, for chaining. + */ + public T tap(AbsoluteOffsetOption tapOptions) { + ActionParameter action = new ActionParameter("tap", tapOptions); + parameterBuilder.add(action); + return (T) this; + } + /** * Tap the center of an element. * * @param el element to tap. * @return this TouchAction, for chaining. - * @deprecated use {@link #tap(ActionOptions)} instead. + * @deprecated use {@link #tap(RelativeOffsetOption)} instead. */ @Deprecated public T tap(WebElement el) { - ActionParameter action = new ActionParameter("tap", - new TapOptions() - .withElement(el)); - parameterBuilder.add(action); - //noinspection unchecked - return (T) this; + return tap(useRelative(el)); } /** @@ -235,16 +250,11 @@ public T tap(WebElement el) { * @param x x coordinate. * @param y y coordinate. * @return this TouchAction, for chaining. - * @deprecated use {@link #tap(ActionOptions)} instead. + * @deprecated use {@link #tap(AbsoluteOffsetOption)} instead. */ @Deprecated public T tap(int x, int y) { - ActionParameter action = new ActionParameter("tap", - new TapOptions() - .withAbsoluteOffset(x, y)); - parameterBuilder.add(action); - //noinspection unchecked - return (T) this; + return tap(useAbsolute(x, y)); } /** @@ -254,17 +264,11 @@ public T tap(int x, int y) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. - * @deprecated use {@link #tap(ActionOptions)} instead. + * @deprecated use {@link #tap(RelativeOffsetOption)} instead. */ @Deprecated public T tap(WebElement el, int x, int y) { - ActionParameter action = new ActionParameter("tap", - new TapOptions() - .withElement(el) - .withRelativeOffset(x, y)); - parameterBuilder.add(action); - //noinspection unchecked - return (T) this; + return tap(useRelative(el, x, y)); } /** @@ -285,7 +289,7 @@ public T waitAction() { * @param waitOptions see {@link WaitOptions}. * @return this TouchAction, for chaining. */ - public T waitAction(ActionOptions waitOptions) { + public T waitAction(WaitOptions waitOptions) { ActionParameter action = new ActionParameter("wait", waitOptions); parameterBuilder.add(action); //noinspection unchecked @@ -297,7 +301,7 @@ public T waitAction(ActionOptions waitOptions) { * * @param duration of the wait action. Minimum time reolution unit is one millisecond. * @return this TouchAction, for chaining. - * @deprecated use {@link #waitAction(ActionOptions)} instead. + * @deprecated use {@link #waitAction(WaitOptions)} instead. */ @Deprecated public T waitAction(Duration duration) { @@ -315,7 +319,33 @@ public T waitAction(Duration duration) { * @param longPressOptions see {@link LongPressOptions}. * @return this TouchAction, for chaining. */ - public T longPress(ActionOptions longPressOptions) { + public T longPress(LongPressOptions longPressOptions) { + ActionParameter action = new ActionParameter("longPress", longPressOptions); + parameterBuilder.add(action); + //noinspection unchecked + return (T) this; + } + + /** + * Press and hold the at the center of an element until the context menu event has fired. + * + * @param longPressOptions see {@link RelativeOffsetOption}. + * @return this TouchAction, for chaining. + */ + public T longPress(RelativeOffsetOption longPressOptions) { + ActionParameter action = new ActionParameter("longPress", longPressOptions); + parameterBuilder.add(action); + //noinspection unchecked + return (T) this; + } + + /** + * Press and hold the at the center of an element until the context menu event has fired. + * + * @param longPressOptions see {@link AbsoluteOffsetOption}. + * @return this TouchAction, for chaining. + */ + public T longPress(AbsoluteOffsetOption longPressOptions) { ActionParameter action = new ActionParameter("longPress", longPressOptions); parameterBuilder.add(action); //noinspection unchecked @@ -327,16 +357,11 @@ public T longPress(ActionOptions longPressOptions) { * * @param el element to long-press. * @return this TouchAction, for chaining. - * @deprecated use {@link #longPress(ActionOptions)} instead + * @deprecated use {@link #longPress(RelativeOffsetOption)} instead */ @Deprecated public T longPress(WebElement el) { - ActionParameter action = new ActionParameter("longPress", - new LongPressOptions() - .withElement(el)); - parameterBuilder.add(action); - //noinspection unchecked - return (T) this; + return longPress(useRelative(el)); } /** @@ -345,17 +370,12 @@ public T longPress(WebElement el) { * @param el element to long-press. * @param duration of the long-press. Minimum time resolution unit is one millisecond. * @return this TouchAction, for chaining. - * @deprecated use {@link #longPress(ActionOptions)} instead + * @deprecated use {@link #longPress(LongPressOptions)} instead */ @Deprecated public T longPress(WebElement el, Duration duration) { - ActionParameter action = new ActionParameter("longPress", - new LongPressOptions() - .withElement(el) - .withDuration(duration)); - parameterBuilder.add(action); - //noinspection unchecked - return (T) this; + return longPress(longPressOptions() + .withDuration(duration).withOffset(useRelative(el))); } /** @@ -365,16 +385,11 @@ public T longPress(WebElement el, Duration duration) { * @param x x coordinate. * @param y y coordinate. * @return this TouchAction, for chaining. - * @deprecated use {@link #longPress(ActionOptions)} instead + * @deprecated use {@link #longPress(AbsoluteOffsetOption)} instead */ @Deprecated public T longPress(int x, int y) { - ActionParameter action = new ActionParameter("longPress", - new LongPressOptions() - .withAbsoluteOffset(x, y)); - parameterBuilder.add(action); - //noinspection unchecked - return (T) this; + return longPress(useAbsolute(x, y)); } /** @@ -385,17 +400,12 @@ public T longPress(int x, int y) { * @param y y coordinate. * @param duration of the long-press. Minimum time resolution unit is one millisecond. * @return this TouchAction, for chaining. - * @deprecated use {@link #longPress(ActionOptions)} instead + * @deprecated use {@link #longPress(LongPressOptions)} instead */ @Deprecated public T longPress(int x, int y, Duration duration) { - ActionParameter action = new ActionParameter("longPress", - new LongPressOptions() - .withAbsoluteOffset(x, y) - .withDuration(duration)); - parameterBuilder.add(action); - //noinspection unchecked - return (T) this; + return longPress(longPressOptions() + .withDuration(duration).withOffset(useAbsolute(x, y))); } /** @@ -406,17 +416,11 @@ public T longPress(int x, int y, Duration duration) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. - * @deprecated use {@link #longPress(ActionOptions)} instead + * @deprecated use {@link #longPress(RelativeOffsetOption)} instead */ @Deprecated public T longPress(WebElement el, int x, int y) { - ActionParameter action = new ActionParameter("longPress", - new LongPressOptions() - .withElement(el) - .withRelativeOffset(x, y)); - parameterBuilder.add(action); - //noinspection unchecked - return (T) this; + return longPress(useRelative(el, x, y)); } /** @@ -428,17 +432,12 @@ public T longPress(WebElement el, int x, int y) { * @param y y offset. * @param duration of the long-press. Minimum time resolution unit is one millisecond. * @return this TouchAction, for chaining. - * @deprecated use {@link #longPress(ActionOptions)} instead + * @deprecated use {@link #longPress(LongPressOptions)} instead */ @Deprecated public TouchAction longPress(WebElement el, int x, int y, Duration duration) { - ActionParameter action = new ActionParameter("longPress", - new LongPressOptions() - .withElement(el) - .withRelativeOffset(x, y) - .withDuration(duration)); - parameterBuilder.add(action); - return this; + return longPress(longPressOptions() + .withOffset(useRelative(el, x, y)).withDuration(duration)); } /** diff --git a/src/main/java/io/appium/java_client/ios/IOSTouchAction.java b/src/main/java/io/appium/java_client/ios/IOSTouchAction.java index 2b0ed79af..99bbbe1a0 100644 --- a/src/main/java/io/appium/java_client/ios/IOSTouchAction.java +++ b/src/main/java/io/appium/java_client/ios/IOSTouchAction.java @@ -18,9 +18,11 @@ import io.appium.java_client.PerformsTouchActions; import io.appium.java_client.TouchAction; -import io.appium.java_client.ios.touch.DoubleTapOptions; +import io.appium.java_client.touch.RelativeOffsetOption; import org.openqa.selenium.WebElement; +import static io.appium.java_client.touch.RelativeOffsetOption.useRelative; + public class IOSTouchAction extends TouchAction { @@ -35,16 +37,11 @@ public IOSTouchAction(PerformsTouchActions performsTouchActions) { * @param x x offset. * @param y y offset. * @return this IOSTouchAction, for chaining. - * @deprecated use {@link #tap(ActionOptions)} with count=2 instead. + * @deprecated use {@link #tap(RelativeOffsetOption)} with count=2 instead. */ @Deprecated public IOSTouchAction doubleTap(WebElement el, int x, int y) { - ActionParameter action = new ActionParameter("doubleTap", - new DoubleTapOptions() - .withElement(el) - .withRelativeOffset(x, y)); - parameterBuilder.add(action); - return this; + return doubleTap(useRelative(el, x, y)); } /** @@ -52,13 +49,16 @@ public IOSTouchAction doubleTap(WebElement el, int x, int y) { * * @param el element to tap. * @return this IOSTouchAction, for chaining. - * @deprecated use {@link #tap(ActionOptions)} with count=2 instead. + * @deprecated use {@link #tap(RelativeOffsetOption)} with count=2 instead. */ @Deprecated public IOSTouchAction doubleTap(WebElement el) { + return doubleTap(useRelative(el)); + } + + public IOSTouchAction doubleTap(RelativeOffsetOption doubleTapOption) { ActionParameter action = new ActionParameter("doubleTap", - new DoubleTapOptions() - .withElement(el)); + doubleTapOption); parameterBuilder.add(action); return this; } diff --git a/src/main/java/io/appium/java_client/ios/touch/DoubleTapOptions.java b/src/main/java/io/appium/java_client/ios/touch/DoubleTapOptions.java deleted file mode 100644 index 3149d287f..000000000 --- a/src/main/java/io/appium/java_client/ios/touch/DoubleTapOptions.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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.ios.touch; - -import io.appium.java_client.touch.OptionsWithAbsolutePositioning; - -/** - * @deprecated this class will be removed - */ -@Deprecated -public class DoubleTapOptions extends OptionsWithAbsolutePositioning { -} diff --git a/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java b/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java index 9753736e9..fc3d73bc8 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java +++ b/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java @@ -84,7 +84,7 @@ public AppiumFieldDecorator(SearchContext context, long timeout, * or {@link org.openqa.selenium.WebElement} or * {@link io.appium.java_client.pagefactory.Widget} or some other user's * extension/implementation. - * @param duration is a desired duration of the waiting for an element presence. + * @param duration is a desired waitOptoins of the waiting for an element presence. */ public AppiumFieldDecorator(SearchContext context, TimeOutDuration duration) { this.originalDriver = unpackWebDriverFromSearchContext(context); diff --git a/src/main/java/io/appium/java_client/touch/AbsoluteOffsetOption.java b/src/main/java/io/appium/java_client/touch/AbsoluteOffsetOption.java new file mode 100644 index 000000000..24547b1e2 --- /dev/null +++ b/src/main/java/io/appium/java_client/touch/AbsoluteOffsetOption.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.touch; + +import org.openqa.selenium.Point; + +import java.util.Map; + +import static java.util.Optional.ofNullable; + +public class AbsoluteOffsetOption extends ActionOptions { + private Point absoluteOffset = null; + + public static AbsoluteOffsetOption useAbsolute(int xOffset, int yOffset) { + return new AbsoluteOffsetOption().withAbsoluteOffset(xOffset, yOffset); + } + + /** + * Set the absolute offset for the corresponding action. + * + * @param xOffset the absolute distance from the left screen corner. + * @param yOffset the absolute distance from the top screen corner. + * @return this instance for chaining. + */ + public AbsoluteOffsetOption withAbsoluteOffset(int xOffset, int yOffset) { + this.absoluteOffset = new Point(xOffset, yOffset); + //noinspection unchecked + return this; + } + + @Override + protected void verify() { + ofNullable(absoluteOffset).orElseThrow(() -> new IllegalArgumentException( + "Absolute offset must not be defined")); + } + + @Override + public Map build() { + final Map result = super.build(); + ofNullable(absoluteOffset).ifPresent(point -> { + result.put("x", point.x); + result.put("y", point.y); + }); + return result; + } +} diff --git a/src/main/java/io/appium/java_client/touch/LongPressOptions.java b/src/main/java/io/appium/java_client/touch/LongPressOptions.java index 3a03dd311..07c4ff268 100644 --- a/src/main/java/io/appium/java_client/touch/LongPressOptions.java +++ b/src/main/java/io/appium/java_client/touch/LongPressOptions.java @@ -22,13 +22,17 @@ import java.time.Duration; import java.util.Map; -public class LongPressOptions extends OptionsWithAbsolutePositioning { +public class LongPressOptions extends OptionsCombinedWithOffset { protected Duration duration = null; + public static LongPressOptions longPressOptions() { + return new LongPressOptions(); + } + /** - * Set the long press duration. + * Set the long press waitOptoins. * - * @param duration the duration value to set. + * @param duration the waitOptoins value to set. * Time resolution unit is 1 ms. * @return this instance for chaining. */ @@ -44,7 +48,7 @@ public LongPressOptions withDuration(Duration duration) { public Map build() { final Map result = super.build(); if (duration != null) { - result.put("duration", this.duration.toMillis()); + result.put("waitOptoins", this.duration.toMillis()); } return result; } diff --git a/src/main/java/io/appium/java_client/touch/MoveToOptions.java b/src/main/java/io/appium/java_client/touch/MoveToOptions.java deleted file mode 100644 index b081ef973..000000000 --- a/src/main/java/io/appium/java_client/touch/MoveToOptions.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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.touch; - -public class MoveToOptions extends OptionsWithRelativePositioning { -} diff --git a/src/main/java/io/appium/java_client/touch/OptionsCombinedWithOffset.java b/src/main/java/io/appium/java_client/touch/OptionsCombinedWithOffset.java new file mode 100644 index 000000000..a480a46e3 --- /dev/null +++ b/src/main/java/io/appium/java_client/touch/OptionsCombinedWithOffset.java @@ -0,0 +1,48 @@ +package io.appium.java_client.touch; + +import java.util.Map; + +import static java.util.Optional.ofNullable; + +public abstract class OptionsCombinedWithOffset + extends ActionOptions< OptionsCombinedWithOffset> { + private ActionOptions offsetOption; + + /** + * Some actions may require some absolute offset value to be performed. + * Invocation of this method replaces the result of previous invocation of + * the {@link #withOffset(RelativeOffsetOption)} + * + * @param offset is the values of required absolute offset from the left corner of a screen. * + * @return self-reference + */ + public T withOffset(AbsoluteOffsetOption offset) { + offsetOption = offset; + return (T) this; + } + + /** + * Some actions may require some relative offset value to be performed. + * Invocation of this method replaces the result of previous invocation of + * the {@link #withOffset(AbsoluteOffsetOption)} + * + * @param offset is the values of required offset from the left corner of an element. * + * @return self-reference + */ + public T withOffset(RelativeOffsetOption offset) { + offsetOption = offset; + return (T) this; + } + + protected void verify() { + ofNullable(offsetOption).orElseThrow(() -> + new IllegalArgumentException("Some relative or absolute offset should be defined. Use one of withOffset methods")); + } + + @Override + public Map build() { + final Map result = super.build(); + result.putAll(offsetOption.build()); + return result; + } +} diff --git a/src/main/java/io/appium/java_client/touch/OptionsWithAbsolutePositioning.java b/src/main/java/io/appium/java_client/touch/OptionsWithAbsolutePositioning.java deleted file mode 100644 index 56d13bfa8..000000000 --- a/src/main/java/io/appium/java_client/touch/OptionsWithAbsolutePositioning.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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.touch; - -import static com.google.common.base.Preconditions.checkNotNull; - -import org.openqa.selenium.Point; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.internal.HasIdentity; - -import java.util.Map; - -public abstract class OptionsWithAbsolutePositioning> - extends ActionOptions { - private String elementId = null; - private Point absoluteOffset = null; - private Point relativeOffset = null; - - /** - * Set the destination element for the corresponding action. - * - * @param element the destination element. - * @return this instance for chaining. - */ - public T withElement(WebElement element) { - checkNotNull(element); - this.elementId = ((HasIdentity) element).getId(); - //noinspection unchecked - return (T) this; - } - - /** - * Set the absolute offset for the corresponding action. - * - * @param xOffset the absolute distance from the left screen corner (the element must not be set). - * @param yOffset the absolute distance from the top screen corner. - * @return this instance for chaining. - */ - public T withAbsoluteOffset(int xOffset, int yOffset) { - this.absoluteOffset = new Point(xOffset, yOffset); - //noinspection unchecked - return (T) this; - } - - /** - * Set the relative offset for the corresponding action. - * - * @param xOffset the relative distance from the left element corner (the element must be set). - * @param yOffset the relative distance from the top element corner (the element must be set). - * @return this instance for chaining. - */ - public T withRelativeOffset(int xOffset, int yOffset) { - this.relativeOffset = new Point(xOffset, yOffset); - //noinspection unchecked - return (T) this; - } - - @Override - protected void verify() { - if (elementId == null) { - if (absoluteOffset == null) { - throw new IllegalArgumentException( - "Absolute offset must be defined if 'element' option is not set"); - } - if (relativeOffset != null) { - throw new IllegalArgumentException( - "Relative offset must not be defined if 'element' option is not set"); - } - } else { - if (absoluteOffset != null) { - throw new IllegalArgumentException( - "Absolute offset must not be defined if 'element' option set"); - } - } - } - - @Override - public Map build() { - final Map result = super.build(); - if (absoluteOffset != null) { - result.put("x", absoluteOffset.x); - result.put("y", absoluteOffset.y); - } - if (relativeOffset != null) { - result.put("x", relativeOffset.x); - result.put("y", relativeOffset.y); - } - if (elementId != null) { - result.put("element", elementId); - } - return result; - } -} diff --git a/src/main/java/io/appium/java_client/touch/PressOptions.java b/src/main/java/io/appium/java_client/touch/PressOptions.java deleted file mode 100644 index 1d51fe720..000000000 --- a/src/main/java/io/appium/java_client/touch/PressOptions.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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.touch; - -public class PressOptions extends OptionsWithAbsolutePositioning { -} diff --git a/src/main/java/io/appium/java_client/touch/OptionsWithRelativePositioning.java b/src/main/java/io/appium/java_client/touch/RelativeOffsetOption.java similarity index 61% rename from src/main/java/io/appium/java_client/touch/OptionsWithRelativePositioning.java rename to src/main/java/io/appium/java_client/touch/RelativeOffsetOption.java index 8046f982d..b424e8871 100644 --- a/src/main/java/io/appium/java_client/touch/OptionsWithRelativePositioning.java +++ b/src/main/java/io/appium/java_client/touch/RelativeOffsetOption.java @@ -16,64 +16,64 @@ package io.appium.java_client.touch; -import static com.google.common.base.Preconditions.checkNotNull; - import org.openqa.selenium.Point; import org.openqa.selenium.WebElement; import org.openqa.selenium.internal.HasIdentity; import java.util.Map; -public abstract class OptionsWithRelativePositioning> - extends ActionOptions { +import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Optional.ofNullable; + +public class RelativeOffsetOption extends ActionOptions { private String elementId = null; private Point relativeOffset = null; - /** - * Set the destination element for the corresponding action. - * - * @param element the destination element. - * @return this instance for chaining. - */ - public T withElement(WebElement element) { - checkNotNull(element); - this.elementId = ((HasIdentity) element).getId(); - //noinspection unchecked - return (T) this; + public static RelativeOffsetOption useRelative(WebElement element, int xOffset, int yOffset) { + return new RelativeOffsetOption().withRelativeOffset(element, xOffset, yOffset); + } + + public static RelativeOffsetOption useRelative(WebElement element) { + return useRelative(element, 0, 0); } /** * Set the relative offset for the corresponding action. * + * @param element the destination element. * @param xOffset the relative distance from the left element corner * (if set) or from the left corner of the preceding chain action. + * This value might be zero if it is necessary. * @param yOffset the relative distance from the top element corner * (if set) or from the top corner of the preceding chain action. + * This value might be zero if it is necessary. * @return this instance for chaining. */ - public T withRelativeOffset(int xOffset, int yOffset) { + public RelativeOffsetOption withRelativeOffset(WebElement element, int xOffset, int yOffset) { + checkNotNull(element); + this.elementId = ((HasIdentity) element).getId(); this.relativeOffset = new Point(xOffset, yOffset); //noinspection unchecked - return (T) this; + return this; } @Override protected void verify() { - if (elementId == null && relativeOffset == null) { - throw new IllegalArgumentException("Either element or relative offset should be defined"); - } + ofNullable(elementId).orElseThrow(() -> + new IllegalArgumentException("Element should be defined")); + ofNullable(relativeOffset).orElseThrow(() -> + new IllegalArgumentException("Relative offset should be defined")); } @Override public Map build() { final Map result = super.build(); - if (relativeOffset != null) { - result.put("x", relativeOffset.x); - result.put("y", relativeOffset.y); - } - if (elementId != null) { - result.put("element", elementId); - } + ofNullable(relativeOffset).ifPresent(point -> { + result.put("x", point.x); + result.put("y", point.y); + }); + + ofNullable(elementId).ifPresent(s -> result.put("element", s)); return result; } } diff --git a/src/main/java/io/appium/java_client/touch/TapOptions.java b/src/main/java/io/appium/java_client/touch/TapOptions.java index ae2c777c4..bed5aab8d 100644 --- a/src/main/java/io/appium/java_client/touch/TapOptions.java +++ b/src/main/java/io/appium/java_client/touch/TapOptions.java @@ -20,9 +20,13 @@ import java.util.Map; -public class TapOptions extends OptionsWithAbsolutePositioning { +public class TapOptions extends OptionsCombinedWithOffset { private Integer tapsCount = null; + public static TapOptions tapOptions() { + return new TapOptions(); + } + /** * Set the count of taps to perform. * diff --git a/src/main/java/io/appium/java_client/touch/WaitOptions.java b/src/main/java/io/appium/java_client/touch/WaitOptions.java index e5a2d6be8..dafbd1ae9 100644 --- a/src/main/java/io/appium/java_client/touch/WaitOptions.java +++ b/src/main/java/io/appium/java_client/touch/WaitOptions.java @@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Optional.ofNullable; import java.time.Duration; import java.util.Map; @@ -25,10 +26,14 @@ public class WaitOptions extends ActionOptions { protected Duration duration = Duration.ofMillis(0); + public static WaitOptions waitOptoins(Duration duration) { + return new WaitOptions().withDuration(duration); + } + /** - * Set the wait duration. + * Set the wait waitOptoins. * - * @param duration the duration value to set. + * @param duration the waitOptoins value to set. * Time resolution unit is 1 ms. * @return this instance for chaining. */ @@ -42,7 +47,8 @@ public WaitOptions withDuration(Duration duration) { @Override protected void verify() { - // Wait options have nothing to verify + ofNullable(duration).orElseThrow(() -> + new IllegalArgumentException("Duration value should not be a null value")); } @Override diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/TimeoutTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/TimeoutTest.java index 286e46607..a8f555967 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/TimeoutTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/TimeoutTest.java @@ -49,7 +49,7 @@ public class TimeoutTest { private static final long ACCEPTABLE_TIME_DIFF_MS = 1500; - private static final String MESSAGE = "Check difference from the expected waiting duration %s %s"; + private static final String MESSAGE = "Check difference from the expected waiting waitOptoins %s %s"; private WebDriver driver; diff --git a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java index 1ed86199f..7cbea8464 100644 --- a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java +++ b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java @@ -67,7 +67,7 @@ public void longPressOptionsShouldBuildProperly() throws Exception { expectedOpts.put("element", ((HasIdentity) DUMMY_ELEMENT).getId()); expectedOpts.put("x", 0); expectedOpts.put("y", 0); - expectedOpts.put("duration", 1L); + expectedOpts.put("waitOptoins", 1L); assertThat(actualOpts.entrySet(), everyItem(isIn(expectedOpts.entrySet()))); assertThat(expectedOpts.entrySet(), everyItem(isIn(actualOpts.entrySet()))); } From 42f4a9681e1081d57c6a0840768cf20f2c9c916b Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Wed, 1 Nov 2017 00:19:34 +0300 Subject: [PATCH 05/14] The addition to the #756: - reversion of accidentally changed strings/javadocs. - javadocs were added to new-designed static methods - ability to take x&y offsets by RelativeOffsetOption --- .../pagefactory/AppiumFieldDecorator.java | 2 +- .../touch/AbsoluteOffsetOption.java | 8 ++++ .../java_client/touch/LongPressOptions.java | 6 +-- .../touch/RelativeOffsetOption.java | 48 +++++++++++++++++-- .../appium/java_client/touch/TapOptions.java | 5 ++ .../appium/java_client/touch/WaitOptions.java | 12 +++-- .../pagefactory_tests/TimeoutTest.java | 2 +- .../java_client/touch/TouchOptionsTests.java | 2 +- 8 files changed, 72 insertions(+), 13 deletions(-) diff --git a/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java b/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java index fc3d73bc8..9753736e9 100644 --- a/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java +++ b/src/main/java/io/appium/java_client/pagefactory/AppiumFieldDecorator.java @@ -84,7 +84,7 @@ public AppiumFieldDecorator(SearchContext context, long timeout, * or {@link org.openqa.selenium.WebElement} or * {@link io.appium.java_client.pagefactory.Widget} or some other user's * extension/implementation. - * @param duration is a desired waitOptoins of the waiting for an element presence. + * @param duration is a desired duration of the waiting for an element presence. */ public AppiumFieldDecorator(SearchContext context, TimeOutDuration duration) { this.originalDriver = unpackWebDriverFromSearchContext(context); diff --git a/src/main/java/io/appium/java_client/touch/AbsoluteOffsetOption.java b/src/main/java/io/appium/java_client/touch/AbsoluteOffsetOption.java index 24547b1e2..a1048f578 100644 --- a/src/main/java/io/appium/java_client/touch/AbsoluteOffsetOption.java +++ b/src/main/java/io/appium/java_client/touch/AbsoluteOffsetOption.java @@ -25,6 +25,14 @@ public class AbsoluteOffsetOption extends ActionOptions { private Point absoluteOffset = null; + /** + * It creates an instance of {@link AbsoluteOffsetOption } which takes absolute + * x and y offsets. + * + * @param xOffset the absolute distance from the left screen corner. + * @param yOffset the absolute distance from the top screen corner. + * @return a built option + */ public static AbsoluteOffsetOption useAbsolute(int xOffset, int yOffset) { return new AbsoluteOffsetOption().withAbsoluteOffset(xOffset, yOffset); } diff --git a/src/main/java/io/appium/java_client/touch/LongPressOptions.java b/src/main/java/io/appium/java_client/touch/LongPressOptions.java index 07c4ff268..f7207ec92 100644 --- a/src/main/java/io/appium/java_client/touch/LongPressOptions.java +++ b/src/main/java/io/appium/java_client/touch/LongPressOptions.java @@ -30,9 +30,9 @@ public static LongPressOptions longPressOptions() { } /** - * Set the long press waitOptoins. + * Set the long press duration. * - * @param duration the waitOptoins value to set. + * @param duration the value to set. * Time resolution unit is 1 ms. * @return this instance for chaining. */ @@ -48,7 +48,7 @@ public LongPressOptions withDuration(Duration duration) { public Map build() { final Map result = super.build(); if (duration != null) { - result.put("waitOptoins", this.duration.toMillis()); + result.put("duration", this.duration.toMillis()); } return result; } diff --git a/src/main/java/io/appium/java_client/touch/RelativeOffsetOption.java b/src/main/java/io/appium/java_client/touch/RelativeOffsetOption.java index b424e8871..b68d3a7f3 100644 --- a/src/main/java/io/appium/java_client/touch/RelativeOffsetOption.java +++ b/src/main/java/io/appium/java_client/touch/RelativeOffsetOption.java @@ -29,14 +29,42 @@ public class RelativeOffsetOption extends ActionOptions { private String elementId = null; private Point relativeOffset = null; + /** + * It creates an instance of {@link RelativeOffsetOption } which takes an element + * and x and y offsets. These offsets are relative to the given element. + * + * @param element is the target element + * @param xOffset x-offset which is relative to the given element + * @param yOffset y-offset which is relative to the given element + * @return a built option + */ public static RelativeOffsetOption useRelative(WebElement element, int xOffset, int yOffset) { return new RelativeOffsetOption().withRelativeOffset(element, xOffset, yOffset); } + /** + * * It creates an instance of {@link RelativeOffsetOption } which takes an element + * and 0-value x and y offsets. + * + * @param element is the target element + * @return a built option + */ public static RelativeOffsetOption useRelative(WebElement element) { return useRelative(element, 0, 0); } + /** + * It creates an instance of {@link RelativeOffsetOption } which takes x and y offsets. + * These offsets are relative to to the previous chain element position. + * + * @param xOffset x offset that is relative to the previous chain element position. + * @param yOffset y offset that is relative to the previous chain element position. + * @return a built option + */ + public static RelativeOffsetOption useRelative(int xOffset, int yOffset) { + return new RelativeOffsetOption().withRelativeOffset(xOffset, yOffset); + } + /** * Set the relative offset for the corresponding action. * @@ -57,12 +85,24 @@ public RelativeOffsetOption withRelativeOffset(WebElement element, int xOffset, return this; } + /** + * Set the relative offset for the corresponding action. + * + * @param xOffset is x-axis offset that is relative to the previous chain element position. + * @param yOffset is y-axis offset that is relative to the previous chain element position. + * @return this instance for chaining. + */ + public RelativeOffsetOption withRelativeOffset(int xOffset, int yOffset) { + this.relativeOffset = new Point(xOffset, yOffset); + //noinspection unchecked + return this; + } + @Override protected void verify() { - ofNullable(elementId).orElseThrow(() -> - new IllegalArgumentException("Element should be defined")); - ofNullable(relativeOffset).orElseThrow(() -> - new IllegalArgumentException("Relative offset should be defined")); + if (elementId == null && relativeOffset == null) { + throw new IllegalArgumentException("Either element or relative offset should be defined"); + } } @Override diff --git a/src/main/java/io/appium/java_client/touch/TapOptions.java b/src/main/java/io/appium/java_client/touch/TapOptions.java index bed5aab8d..716e2db05 100644 --- a/src/main/java/io/appium/java_client/touch/TapOptions.java +++ b/src/main/java/io/appium/java_client/touch/TapOptions.java @@ -23,6 +23,11 @@ public class TapOptions extends OptionsCombinedWithOffset { private Integer tapsCount = null; + /** + * It creates an empty instance of {@link TapOptions}. + * + * @return the empty instance of {@link TapOptions} + */ public static TapOptions tapOptions() { return new TapOptions(); } diff --git a/src/main/java/io/appium/java_client/touch/WaitOptions.java b/src/main/java/io/appium/java_client/touch/WaitOptions.java index dafbd1ae9..5a9e0183c 100644 --- a/src/main/java/io/appium/java_client/touch/WaitOptions.java +++ b/src/main/java/io/appium/java_client/touch/WaitOptions.java @@ -26,14 +26,20 @@ public class WaitOptions extends ActionOptions { protected Duration duration = Duration.ofMillis(0); - public static WaitOptions waitOptoins(Duration duration) { + /** + * Creates and instance of {@link WaitOptions}. + * + * @param duration is the duration of the waiting. + * @return a built option. + */ + public static WaitOptions waitOptions(Duration duration) { return new WaitOptions().withDuration(duration); } /** - * Set the wait waitOptoins. + * Set the wait duration. * - * @param duration the waitOptoins value to set. + * @param duration the value to set. * Time resolution unit is 1 ms. * @return this instance for chaining. */ diff --git a/src/test/java/io/appium/java_client/pagefactory_tests/TimeoutTest.java b/src/test/java/io/appium/java_client/pagefactory_tests/TimeoutTest.java index a8f555967..286e46607 100644 --- a/src/test/java/io/appium/java_client/pagefactory_tests/TimeoutTest.java +++ b/src/test/java/io/appium/java_client/pagefactory_tests/TimeoutTest.java @@ -49,7 +49,7 @@ public class TimeoutTest { private static final long ACCEPTABLE_TIME_DIFF_MS = 1500; - private static final String MESSAGE = "Check difference from the expected waiting waitOptoins %s %s"; + private static final String MESSAGE = "Check difference from the expected waiting duration %s %s"; private WebDriver driver; diff --git a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java index 7cbea8464..1ed86199f 100644 --- a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java +++ b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java @@ -67,7 +67,7 @@ public void longPressOptionsShouldBuildProperly() throws Exception { expectedOpts.put("element", ((HasIdentity) DUMMY_ELEMENT).getId()); expectedOpts.put("x", 0); expectedOpts.put("y", 0); - expectedOpts.put("waitOptoins", 1L); + expectedOpts.put("duration", 1L); assertThat(actualOpts.entrySet(), everyItem(isIn(expectedOpts.entrySet()))); assertThat(expectedOpts.entrySet(), everyItem(isIn(actualOpts.entrySet()))); } From cbd9f5d839fbbe95245d79203c203587365d6cc7 Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Thu, 2 Nov 2017 23:13:19 +0300 Subject: [PATCH 06/14] The addition to the #756: - old integration tests were updated --- .../java_client/touch/LongPressOptions.java | 5 ++ .../AndroidAbilityToUseSupplierTest.java | 26 ++---- .../java_client/android/AndroidTouchTest.java | 86 +++++++------------ 3 files changed, 45 insertions(+), 72 deletions(-) diff --git a/src/main/java/io/appium/java_client/touch/LongPressOptions.java b/src/main/java/io/appium/java_client/touch/LongPressOptions.java index f7207ec92..ecb0105be 100644 --- a/src/main/java/io/appium/java_client/touch/LongPressOptions.java +++ b/src/main/java/io/appium/java_client/touch/LongPressOptions.java @@ -25,6 +25,11 @@ public class LongPressOptions extends OptionsCombinedWithOffset { protected Duration duration = null; + /** + * It creates an empty instance of {@link LongPressOptions} + * + * @return an empty instance of {@link LongPressOptions} + */ public static LongPressOptions longPressOptions() { return new LongPressOptions(); } diff --git a/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java b/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java index b4d12cf84..5184a76ac 100644 --- a/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java +++ b/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java @@ -1,16 +1,15 @@ package io.appium.java_client.android; +import static io.appium.java_client.touch.RelativeOffsetOption.useRelative; +import static io.appium.java_client.touch.WaitOptions.waitOptions; +import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertNotEquals; import io.appium.java_client.MobileElement; import io.appium.java_client.functions.ActionSupplier; -import io.appium.java_client.touch.MoveToOptions; -import io.appium.java_client.touch.PressOptions; -import io.appium.java_client.touch.WaitOptions; import org.junit.Test; import org.openqa.selenium.Point; -import java.time.Duration; import java.util.List; public class AndroidAbilityToUseSupplierTest extends BaseAndroidTest { @@ -25,24 +24,17 @@ public class AndroidAbilityToUseSupplierTest extends BaseAndroidTest { Point center = gallery.getCenter(); return new AndroidTouchAction(driver) - .press(new PressOptions() - .withElement(images.get(2)) - .withRelativeOffset( -10, center.y - location.y)) - .waitAction(new WaitOptions().withDuration(Duration.ofSeconds(2))) - .moveTo(new MoveToOptions() - .withElement(gallery) - .withRelativeOffset( 10, center.y - location.y)) + .press(useRelative(images.get(2),-10,center.y - location.y)) + .waitAction(waitOptions(ofSeconds(2))) + .moveTo(useRelative(gallery,10,center.y - location.y)) .release(); }; private final ActionSupplier verticalSwiping = () -> new AndroidTouchAction(driver) - .press(new PressOptions() - .withElement(driver.findElementByAccessibilityId("Gallery"))) - .waitAction(new WaitOptions() - .withDuration(Duration.ofSeconds(2))) - .moveTo(new MoveToOptions() - .withElement(driver.findElementByAccessibilityId("Auto Complete"))) + .press(useRelative(driver.findElementByAccessibilityId("Gallery"))) + .waitAction(waitOptions(ofSeconds(2))) + .moveTo(useRelative(driver.findElementByAccessibilityId("Auto Complete"))) .release(); @Test public void horizontalSwipingWithSupplier() throws Exception { diff --git a/src/test/java/io/appium/java_client/android/AndroidTouchTest.java b/src/test/java/io/appium/java_client/android/AndroidTouchTest.java index 21a15c4fd..998e59d21 100644 --- a/src/test/java/io/appium/java_client/android/AndroidTouchTest.java +++ b/src/test/java/io/appium/java_client/android/AndroidTouchTest.java @@ -1,23 +1,22 @@ package io.appium.java_client.android; +import static io.appium.java_client.touch.AbsoluteOffsetOption.useAbsolute; +import static io.appium.java_client.touch.LongPressOptions.longPressOptions; +import static io.appium.java_client.touch.RelativeOffsetOption.useRelative; +import static io.appium.java_client.touch.WaitOptions.waitOptions; +import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import io.appium.java_client.MobileElement; import io.appium.java_client.MultiTouchAction; import io.appium.java_client.TouchAction; -import io.appium.java_client.touch.LongPressOptions; -import io.appium.java_client.touch.MoveToOptions; -import io.appium.java_client.touch.PressOptions; -import io.appium.java_client.touch.TapOptions; -import io.appium.java_client.touch.WaitOptions; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.Point; import org.openqa.selenium.WebElement; -import java.time.Duration; import java.util.List; public class AndroidTouchTest extends BaseAndroidTest { @@ -37,10 +36,8 @@ public void setUp() throws Exception { assertEquals("Drag text not empty", "", dragText.getText()); TouchAction dragNDrop = new TouchAction(driver) - .longPress(new LongPressOptions() - .withElement(dragDot1)) - .moveTo(new MoveToOptions() - .withElement(dragDot3)) + .longPress(useRelative(dragDot1)) + .moveTo(useRelative(dragDot3)) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -56,11 +53,10 @@ public void setUp() throws Exception { assertEquals("Drag text not empty", "", dragText.getText()); TouchAction dragNDrop = new TouchAction(driver) - .longPress(new LongPressOptions() - .withElement(dragDot1) - .withDuration(Duration.ofSeconds(2))) - .moveTo(new MoveToOptions() - .withElement(dragDot3)) + .longPress(longPressOptions() + .withOffset(useRelative(dragDot1)) + .withDuration(ofSeconds(2))) + .moveTo(useRelative(dragDot3)) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -79,10 +75,8 @@ public void setUp() throws Exception { Point center2 = dragDot3.getCenter(); TouchAction dragNDrop = new TouchAction(driver) - .longPress(new LongPressOptions() - .withAbsoluteOffset(center1.x, center1.y)) - .moveTo(new MoveToOptions() - .withRelativeOffset(center2.x, center2.y)) + .longPress(useAbsolute(center1.x, center1.y)) + .moveTo(useRelative(center2.x, center2.y)) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -101,11 +95,10 @@ public void setUp() throws Exception { Point center2 = dragDot3.getCenter(); TouchAction dragNDrop = new TouchAction(driver) - .longPress(new LongPressOptions() - .withAbsoluteOffset(center1.x, center1.y) - .withDuration(Duration.ofSeconds(2))) - .moveTo(new MoveToOptions() - .withRelativeOffset(center2.x, center2.y)) + .longPress(longPressOptions() + .withOffset(useAbsolute(center1.x, center1.y)) + .withDuration(ofSeconds(2))) + .moveTo(useRelative(center2.x, center2.y)) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -117,10 +110,8 @@ public void setUp() throws Exception { Point point = driver.findElementById("io.appium.android.apis:id/button_toggle").getLocation(); new TouchAction(driver) - .press(new PressOptions() - .withAbsoluteOffset(point.x + 20, point.y + 30)) - .waitAction(new WaitOptions() - .withDuration(Duration.ofSeconds(1))) + .press(useAbsolute(point.x + 20, point.y + 30)) + .waitAction(waitOptions(ofSeconds(1))) .release() .perform(); assertEquals("ON" ,driver @@ -131,10 +122,8 @@ public void setUp() throws Exception { Activity activity = new Activity("io.appium.android.apis", ".view.Buttons1"); driver.startActivity(activity); new TouchAction(driver) - .press(new PressOptions() - .withElement(driver.findElementById("io.appium.android.apis:id/button_toggle"))) - .waitAction(new WaitOptions() - .withDuration(Duration.ofSeconds(1))) + .press(useRelative(driver.findElementById("io.appium.android.apis:id/button_toggle"))) + .waitAction(waitOptions(ofSeconds(1))) .release() .perform(); assertEquals("ON" ,driver @@ -148,12 +137,9 @@ public void setUp() throws Exception { driver.findElementById("io.appium.android.apis:id/chronometer"); TouchAction startStop = new TouchAction(driver) - .tap(new TapOptions() - .withElement(driver.findElementById("io.appium.android.apis:id/start"))) - .waitAction(new WaitOptions() - .withDuration(Duration.ofSeconds(2))) - .tap(new TapOptions() - .withElement(driver.findElementById("io.appium.android.apis:id/stop"))); + .tap(useRelative(driver.findElementById("io.appium.android.apis:id/start"))) + .waitAction(waitOptions(ofSeconds(2))) + .tap(useRelative(driver.findElementById("io.appium.android.apis:id/stop"))); startStop.perform(); @@ -172,11 +158,8 @@ public void setUp() throws Exception { Point center1 = driver.findElementById("io.appium.android.apis:id/start").getCenter(); TouchAction startStop = new TouchAction(driver) - .tap(new TapOptions() - .withAbsoluteOffset(center1.x, center1.y)) - .tap(new TapOptions() - .withElement(driver.findElementById("io.appium.android.apis:id/stop")) - .withRelativeOffset(5, 5)); + .tap(useAbsolute(center1.x, center1.y)) + .tap(useRelative(driver.findElementById("io.appium.android.apis:id/stop"), 5, 5)); startStop.perform(); String time = chronometer.getText(); @@ -197,14 +180,9 @@ public void setUp() throws Exception { Point center = gallery.getCenter(); TouchAction swipe = new TouchAction(driver) - .press(new PressOptions() - .withElement(images.get(2)) - .withRelativeOffset( -10, center.y - location.y)) - .waitAction(new WaitOptions() - .withDuration(Duration.ofSeconds(2))) - .moveTo(new MoveToOptions() - .withElement(gallery) - .withRelativeOffset( 10, center.y - location.y)) + .press(useRelative(images.get(2),-10, center.y - location.y)) + .waitAction(waitOptions(ofSeconds(2))) + .moveTo(useRelative(gallery,10,center.y - location.y)) .release(); swipe.perform(); assertNotEquals(originalImageCount, gallery @@ -215,10 +193,8 @@ public void setUp() throws Exception { Activity activity = new Activity("io.appium.android.apis", ".view.Buttons1"); driver.startActivity(activity); TouchAction press = new TouchAction(driver) - .press(new PressOptions() - .withElement(driver.findElementById("io.appium.android.apis:id/button_toggle"))) - .waitAction(new WaitOptions() - .withDuration(Duration.ofSeconds(1))) + .press(useRelative(driver.findElementById("io.appium.android.apis:id/button_toggle"))) + .waitAction(waitOptions(ofSeconds(1))) .release(); new MultiTouchAction(driver) .add(press) From 0b185e0972a04581f70da32aa7862998a2c79831 Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Sat, 4 Nov 2017 01:56:39 +0300 Subject: [PATCH 07/14] The addition to the #756. The final commit. --- .../io/appium/java_client/TouchAction.java | 2 +- .../java_client/ios/IOSTouchAction.java | 11 ++- .../touch/AbsoluteOffsetOption.java | 4 +- .../java_client/touch/LongPressOptions.java | 8 +- .../touch/OptionsCombinedWithOffset.java | 11 +-- .../touch/RelativeOffsetOption.java | 6 +- .../appium/java_client/touch/TapOptions.java | 5 +- .../appium/java_client/touch/WaitOptions.java | 5 +- .../appium/java_client/ios/IOSTouchTest.java | 15 ++-- .../java_client/ios/XCUIAutomationTest.java | 3 +- .../java_client/touch/DummyElement.java | 3 +- .../java_client/touch/TouchOptionsTests.java | 74 ++++++------------- 12 files changed, 64 insertions(+), 83 deletions(-) diff --git a/src/main/java/io/appium/java_client/TouchAction.java b/src/main/java/io/appium/java_client/TouchAction.java index 46a446919..cc0d8ea7c 100644 --- a/src/main/java/io/appium/java_client/TouchAction.java +++ b/src/main/java/io/appium/java_client/TouchAction.java @@ -24,8 +24,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import io.appium.java_client.touch.ActionOptions; import io.appium.java_client.touch.AbsoluteOffsetOption; +import io.appium.java_client.touch.ActionOptions; import io.appium.java_client.touch.LongPressOptions; import io.appium.java_client.touch.RelativeOffsetOption; import io.appium.java_client.touch.TapOptions; diff --git a/src/main/java/io/appium/java_client/ios/IOSTouchAction.java b/src/main/java/io/appium/java_client/ios/IOSTouchAction.java index 99bbbe1a0..ffb382d10 100644 --- a/src/main/java/io/appium/java_client/ios/IOSTouchAction.java +++ b/src/main/java/io/appium/java_client/ios/IOSTouchAction.java @@ -16,14 +16,13 @@ package io.appium.java_client.ios; +import static io.appium.java_client.touch.RelativeOffsetOption.useRelative; + import io.appium.java_client.PerformsTouchActions; import io.appium.java_client.TouchAction; import io.appium.java_client.touch.RelativeOffsetOption; import org.openqa.selenium.WebElement; -import static io.appium.java_client.touch.RelativeOffsetOption.useRelative; - - public class IOSTouchAction extends TouchAction { public IOSTouchAction(PerformsTouchActions performsTouchActions) { @@ -56,6 +55,12 @@ public IOSTouchAction doubleTap(WebElement el) { return doubleTap(useRelative(el)); } + /** + * Double taps using relative offset from an element. + * + * @param doubleTapOption is the relative offset parameter from the element + * @return self-reference + */ public IOSTouchAction doubleTap(RelativeOffsetOption doubleTapOption) { ActionParameter action = new ActionParameter("doubleTap", doubleTapOption); diff --git a/src/main/java/io/appium/java_client/touch/AbsoluteOffsetOption.java b/src/main/java/io/appium/java_client/touch/AbsoluteOffsetOption.java index a1048f578..9884c5c90 100644 --- a/src/main/java/io/appium/java_client/touch/AbsoluteOffsetOption.java +++ b/src/main/java/io/appium/java_client/touch/AbsoluteOffsetOption.java @@ -16,12 +16,12 @@ package io.appium.java_client.touch; +import static java.util.Optional.ofNullable; + import org.openqa.selenium.Point; import java.util.Map; -import static java.util.Optional.ofNullable; - public class AbsoluteOffsetOption extends ActionOptions { private Point absoluteOffset = null; diff --git a/src/main/java/io/appium/java_client/touch/LongPressOptions.java b/src/main/java/io/appium/java_client/touch/LongPressOptions.java index ecb0105be..149975479 100644 --- a/src/main/java/io/appium/java_client/touch/LongPressOptions.java +++ b/src/main/java/io/appium/java_client/touch/LongPressOptions.java @@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Optional.ofNullable; import java.time.Duration; import java.util.Map; @@ -26,7 +27,7 @@ public class LongPressOptions extends OptionsCombinedWithOffset build() { final Map result = super.build(); - if (duration != null) { - result.put("duration", this.duration.toMillis()); - } + ofNullable(duration).ifPresent(durationParam -> + result.put("duration", durationParam.toMillis())); return result; } } diff --git a/src/main/java/io/appium/java_client/touch/OptionsCombinedWithOffset.java b/src/main/java/io/appium/java_client/touch/OptionsCombinedWithOffset.java index a480a46e3..1859a8625 100644 --- a/src/main/java/io/appium/java_client/touch/OptionsCombinedWithOffset.java +++ b/src/main/java/io/appium/java_client/touch/OptionsCombinedWithOffset.java @@ -1,11 +1,11 @@ package io.appium.java_client.touch; -import java.util.Map; - import static java.util.Optional.ofNullable; -public abstract class OptionsCombinedWithOffset - extends ActionOptions< OptionsCombinedWithOffset> { +import java.util.Map; + +public abstract class OptionsCombinedWithOffset + extends ActionOptions> { private ActionOptions offsetOption; /** @@ -36,7 +36,8 @@ public T withOffset(RelativeOffsetOption offset) { protected void verify() { ofNullable(offsetOption).orElseThrow(() -> - new IllegalArgumentException("Some relative or absolute offset should be defined. Use one of withOffset methods")); + new IllegalArgumentException("Some relative or absolute offset should " + + "be defined. Use one of withOffset methods")); } @Override diff --git a/src/main/java/io/appium/java_client/touch/RelativeOffsetOption.java b/src/main/java/io/appium/java_client/touch/RelativeOffsetOption.java index b68d3a7f3..45352caec 100644 --- a/src/main/java/io/appium/java_client/touch/RelativeOffsetOption.java +++ b/src/main/java/io/appium/java_client/touch/RelativeOffsetOption.java @@ -16,15 +16,15 @@ package io.appium.java_client.touch; +import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Optional.ofNullable; + import org.openqa.selenium.Point; import org.openqa.selenium.WebElement; import org.openqa.selenium.internal.HasIdentity; import java.util.Map; -import static com.google.common.base.Preconditions.checkNotNull; -import static java.util.Optional.ofNullable; - public class RelativeOffsetOption extends ActionOptions { private String elementId = null; private Point relativeOffset = null; diff --git a/src/main/java/io/appium/java_client/touch/TapOptions.java b/src/main/java/io/appium/java_client/touch/TapOptions.java index 716e2db05..16a8034b7 100644 --- a/src/main/java/io/appium/java_client/touch/TapOptions.java +++ b/src/main/java/io/appium/java_client/touch/TapOptions.java @@ -17,6 +17,7 @@ package io.appium.java_client.touch; import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Optional.ofNullable; import java.util.Map; @@ -48,9 +49,7 @@ public TapOptions withTapsCount(int tapsCount) { @Override public Map build() { final Map result = super.build(); - if (tapsCount != null) { - result.put("count", this.tapsCount); - } + ofNullable(tapsCount).ifPresent(integer -> result.put("count", integer)); return result; } } diff --git a/src/main/java/io/appium/java_client/touch/WaitOptions.java b/src/main/java/io/appium/java_client/touch/WaitOptions.java index 5a9e0183c..de5ff79d8 100644 --- a/src/main/java/io/appium/java_client/touch/WaitOptions.java +++ b/src/main/java/io/appium/java_client/touch/WaitOptions.java @@ -60,9 +60,8 @@ protected void verify() { @Override public Map build() { final Map result = super.build(); - if (duration != null) { - result.put("ms", this.duration.toMillis()); - } + ofNullable(duration).ifPresent(durationParam -> + result.put("ms", durationParam.toMillis())); return result; } } diff --git a/src/test/java/io/appium/java_client/ios/IOSTouchTest.java b/src/test/java/io/appium/java_client/ios/IOSTouchTest.java index ddd5b8e8c..fcd460209 100644 --- a/src/test/java/io/appium/java_client/ios/IOSTouchTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSTouchTest.java @@ -1,5 +1,8 @@ package io.appium.java_client.ios; +import static io.appium.java_client.touch.RelativeOffsetOption.useRelative; +import static io.appium.java_client.touch.WaitOptions.waitOptions; +import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.openqa.selenium.support.ui.ExpectedConditions.alertIsPresent; @@ -29,7 +32,7 @@ public void tapTest() { intB.sendKeys("4"); MobileElement e = driver.findElementByAccessibilityId("ComputeSumButton"); - new TouchAction(driver).tap(e).perform(); + new TouchAction(driver).tap(useRelative(e)).perform(); assertEquals(driver.findElementByXPath("//*[@name = \"Answer\"]").getText(), "6"); } @@ -37,17 +40,17 @@ public void tapTest() { MobileElement slider = driver.findElementByClassName("UIASlider"); Dimension size = slider.getSize(); - TouchAction swipe = new TouchAction(driver).press(slider, size.width / 2 + 2, size.height / 2) - .waitAction(Duration.ofSeconds(2)).moveTo(slider, 1, size.height / 2).release(); + TouchAction swipe = new TouchAction(driver).press(useRelative(slider, size.width / 2 + 2, size.height / 2)) + .waitAction(waitOptions(ofSeconds(2))).moveTo(useRelative(slider, 1, size.height / 2)).release(); swipe.perform(); assertEquals("0%", slider.getAttribute("value")); } @Test public void multiTouchTest() { MobileElement e = driver.findElementByAccessibilityId("ComputeSumButton"); - TouchAction tap1 = new TouchAction(driver).tap(e); - TouchAction tap2 = new TouchAction(driver).tap(driver.findElement(MobileBy - .IosUIAutomation(".elements().withName(\"show alert\")"))); + TouchAction tap1 = new TouchAction(driver).tap(useRelative(e)); + TouchAction tap2 = new TouchAction(driver).tap(useRelative(driver.findElement(MobileBy + .IosUIAutomation(".elements().withName(\"show alert\")")))); new MultiTouchAction(driver).add(tap1).add(tap2).perform(); diff --git a/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java b/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java index 907a3a746..a85007aac 100644 --- a/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java +++ b/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java @@ -16,6 +16,7 @@ package io.appium.java_client.ios; +import static io.appium.java_client.touch.RelativeOffsetOption.useRelative; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.is; @@ -76,7 +77,7 @@ public class XCUIAutomationTest extends AppXCUITTest { firstField.sendKeys("2"); IOSTouchAction iosTouchAction = new IOSTouchAction(driver); - iosTouchAction.doubleTap(firstField); + iosTouchAction.doubleTap(useRelative(firstField)); IOSElement editingMenu = driver.findElementByClassName("UIAEditingMenu"); assertNotNull(editingMenu); } diff --git a/src/test/java/io/appium/java_client/touch/DummyElement.java b/src/test/java/io/appium/java_client/touch/DummyElement.java index 345409054..cf98bcb55 100644 --- a/src/test/java/io/appium/java_client/touch/DummyElement.java +++ b/src/test/java/io/appium/java_client/touch/DummyElement.java @@ -1,11 +1,10 @@ package io.appium.java_client.touch; - import org.openqa.selenium.By; import org.openqa.selenium.Dimension; +import org.openqa.selenium.OutputType; import org.openqa.selenium.Point; import org.openqa.selenium.Rectangle; -import org.openqa.selenium.OutputType; import org.openqa.selenium.WebElement; import org.openqa.selenium.internal.HasIdentity; diff --git a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java index 1ed86199f..5c24ad1fe 100644 --- a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java +++ b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java @@ -1,15 +1,21 @@ package io.appium.java_client.touch; -import org.junit.Test; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.internal.HasIdentity; - +import static io.appium.java_client.touch.AbsoluteOffsetOption.useAbsolute; import static io.appium.java_client.touch.FailsWithMatcher.failsWith; +import static io.appium.java_client.touch.LongPressOptions.longPressOptions; +import static io.appium.java_client.touch.RelativeOffsetOption.useRelative; +import static io.appium.java_client.touch.TapOptions.tapOptions; +import static io.appium.java_client.touch.WaitOptions.waitOptions; +import static java.time.Duration.ofMillis; +import static java.time.Duration.ofSeconds; import static org.hamcrest.CoreMatchers.everyItem; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.isIn; -import java.time.Duration; +import org.junit.Test; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.internal.HasIdentity; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -21,15 +27,7 @@ public class TouchOptionsTests { @Test public void invalidAbsolutePositionOptionsShouldFailOnBuild() throws Exception { final List invalidOptions = new ArrayList<>(); - invalidOptions.add(new PressOptions() - .withElement(DUMMY_ELEMENT) - .withAbsoluteOffset(0, 0)); - invalidOptions.add(new LongPressOptions() - .withRelativeOffset(0, 0)); - invalidOptions.add(new TapOptions()); - invalidOptions.add(new TapOptions() - .withAbsoluteOffset(0, 0) - .withRelativeOffset(0, 0)); + invalidOptions.add(new AbsoluteOffsetOption()); for (ActionOptions opts : invalidOptions) { assertThat(opts::build, failsWith(IllegalArgumentException.class)); } @@ -38,7 +36,7 @@ public void invalidAbsolutePositionOptionsShouldFailOnBuild() throws Exception { @Test public void invalidRelativePositionOptionsShouldFailOnBuild() throws Exception { final List invalidOptions = new ArrayList<>(); - invalidOptions.add(new MoveToOptions()); + invalidOptions.add(new RelativeOffsetOption()); for (ActionOptions opts : invalidOptions) { assertThat(opts::build, failsWith(IllegalArgumentException.class)); } @@ -47,10 +45,12 @@ public void invalidRelativePositionOptionsShouldFailOnBuild() throws Exception { @Test public void invalidOptionsArgumentsShouldFailOnAltering() throws Exception { final List> invalidOptions = new ArrayList<>(); - invalidOptions.add(() -> new WaitOptions().withDuration(Duration.ofMillis(-1))); - invalidOptions.add(() -> new PressOptions().withElement(null)); - invalidOptions.add(() -> new MoveToOptions().withElement(null)); + invalidOptions.add(() -> waitOptions(ofMillis(-1))); + invalidOptions.add(() -> new RelativeOffsetOption().withRelativeOffset(null, 0, 0)); invalidOptions.add(() -> new WaitOptions().withDuration(null)); + invalidOptions.add(() -> tapOptions().withTapsCount(-1)); + invalidOptions.add(() -> longPressOptions().withDuration(null)); + invalidOptions.add(() -> longPressOptions().withDuration(ofMillis(-1))); for (IThrowingRunnable item : invalidOptions) { assertThat(item, failsWith(RuntimeException.class)); } @@ -58,10 +58,9 @@ public void invalidOptionsArgumentsShouldFailOnAltering() throws Exception { @Test public void longPressOptionsShouldBuildProperly() throws Exception { - final Map actualOpts = new LongPressOptions() - .withElement(DUMMY_ELEMENT) - .withRelativeOffset(0, 0) - .withDuration(Duration.ofMillis(1)) + final Map actualOpts = longPressOptions() + .withOffset(useRelative(DUMMY_ELEMENT).withRelativeOffset(0, 0)) + .withDuration(ofMillis(1)) .build(); final Map expectedOpts = new HashMap<>(); expectedOpts.put("element", ((HasIdentity) DUMMY_ELEMENT).getId()); @@ -74,8 +73,8 @@ public void longPressOptionsShouldBuildProperly() throws Exception { @Test public void tapOptionsShouldBuildProperly() throws Exception { - final Map actualOpts = new TapOptions() - .withAbsoluteOffset(0, 0) + final Map actualOpts = tapOptions() + .withOffset(useAbsolute(0, 0)) .withTapsCount(2) .build(); final Map expectedOpts = new HashMap<>(); @@ -86,35 +85,10 @@ public void tapOptionsShouldBuildProperly() throws Exception { assertThat(expectedOpts.entrySet(), everyItem(isIn(actualOpts.entrySet()))); } - @Test - public void pressOptionsShouldBuildProperly() throws Exception { - final Map actualOpts = new PressOptions() - .withElement(DUMMY_ELEMENT) - .build(); - final Map expectedOpts = new HashMap<>(); - expectedOpts.put("element", ((HasIdentity) DUMMY_ELEMENT).getId()); - assertThat(actualOpts.entrySet(), everyItem(isIn(expectedOpts.entrySet()))); - assertThat(expectedOpts.entrySet(), everyItem(isIn(actualOpts.entrySet()))); - } - - @Test - public void moveToOptionsShouldBuildProperly() throws Exception { - final Map actualOpts = new MoveToOptions() - .withElement(DUMMY_ELEMENT) - .withRelativeOffset(-1,-1) - .build(); - final Map expectedOpts = new HashMap<>(); - expectedOpts.put("element", ((HasIdentity) DUMMY_ELEMENT).getId()); - expectedOpts.put("x", -1); - expectedOpts.put("y", -1); - assertThat(actualOpts.entrySet(), everyItem(isIn(expectedOpts.entrySet()))); - assertThat(expectedOpts.entrySet(), everyItem(isIn(actualOpts.entrySet()))); - } - @Test public void waitOptionsShouldBuildProperly() throws Exception { final Map actualOpts = new WaitOptions() - .withDuration(Duration.ofSeconds(1)) + .withDuration(ofSeconds(1)) .build(); final Map expectedOpts = new HashMap<>(); expectedOpts.put("ms", 1000L); From c8185da6554759722b2c886974702672b990215f Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Sun, 5 Nov 2017 21:56:58 +0300 Subject: [PATCH 08/14] The addition to the #756. Code improvements: - removal of redundant code from the WaitOptions. - code of test was optimized. --- .../appium/java_client/touch/WaitOptions.java | 7 ++---- .../java_client/touch/FailsWithMatcher.java | 8 +++---- .../java_client/touch/IThrowingRunnable.java | 6 ----- .../java_client/touch/TouchOptionsTests.java | 23 ++++++++----------- 4 files changed, 15 insertions(+), 29 deletions(-) delete mode 100644 src/test/java/io/appium/java_client/touch/IThrowingRunnable.java diff --git a/src/main/java/io/appium/java_client/touch/WaitOptions.java b/src/main/java/io/appium/java_client/touch/WaitOptions.java index de5ff79d8..e5b219246 100644 --- a/src/main/java/io/appium/java_client/touch/WaitOptions.java +++ b/src/main/java/io/appium/java_client/touch/WaitOptions.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import static java.util.Optional.ofNullable; import java.time.Duration; import java.util.Map; @@ -53,15 +52,13 @@ public WaitOptions withDuration(Duration duration) { @Override protected void verify() { - ofNullable(duration).orElseThrow(() -> - new IllegalArgumentException("Duration value should not be a null value")); + //there is nothing to check } @Override public Map build() { final Map result = super.build(); - ofNullable(duration).ifPresent(durationParam -> - result.put("ms", durationParam.toMillis())); + result.put("ms", duration.toMillis()); return result; } } diff --git a/src/test/java/io/appium/java_client/touch/FailsWithMatcher.java b/src/test/java/io/appium/java_client/touch/FailsWithMatcher.java index edd16e026..93c1dd804 100644 --- a/src/test/java/io/appium/java_client/touch/FailsWithMatcher.java +++ b/src/test/java/io/appium/java_client/touch/FailsWithMatcher.java @@ -7,7 +7,7 @@ import org.hamcrest.Matcher; import org.hamcrest.TypeSafeMatcher; -public final class FailsWithMatcher extends TypeSafeMatcher> { +public final class FailsWithMatcher extends TypeSafeMatcher { private final Matcher matcher; @@ -15,18 +15,18 @@ private FailsWithMatcher(final Matcher matcher) { this.matcher = matcher; } - public static Matcher> failsWith( + public static Matcher failsWith( final Class throwableType) { return new FailsWithMatcher<>(instanceOf(throwableType)); } - public static Matcher> failsWith( + public static Matcher failsWith( final Class throwableType, final Matcher throwableMatcher) { return new FailsWithMatcher<>(allOf(instanceOf(throwableType), throwableMatcher)); } @Override - protected boolean matchesSafely(final IThrowingRunnable runnable) { + protected boolean matchesSafely(final Runnable runnable) { try { runnable.run(); return false; diff --git a/src/test/java/io/appium/java_client/touch/IThrowingRunnable.java b/src/test/java/io/appium/java_client/touch/IThrowingRunnable.java deleted file mode 100644 index 5ab472f89..000000000 --- a/src/test/java/io/appium/java_client/touch/IThrowingRunnable.java +++ /dev/null @@ -1,6 +0,0 @@ -package io.appium.java_client.touch; - -@FunctionalInterface -public interface IThrowingRunnable { - void run() throws E; -} diff --git a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java index 5c24ad1fe..23e7f79a6 100644 --- a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java +++ b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java @@ -8,6 +8,7 @@ import static io.appium.java_client.touch.WaitOptions.waitOptions; import static java.time.Duration.ofMillis; import static java.time.Duration.ofSeconds; +import static junit.framework.TestCase.fail; import static org.hamcrest.CoreMatchers.everyItem; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.isIn; @@ -24,34 +25,28 @@ public class TouchOptionsTests { private static final WebElement DUMMY_ELEMENT = new DummyElement(); - @Test + @Test(expected = IllegalArgumentException.class) public void invalidAbsolutePositionOptionsShouldFailOnBuild() throws Exception { - final List invalidOptions = new ArrayList<>(); - invalidOptions.add(new AbsoluteOffsetOption()); - for (ActionOptions opts : invalidOptions) { - assertThat(opts::build, failsWith(IllegalArgumentException.class)); - } + new AbsoluteOffsetOption().build(); + fail("The exception throwing was expected"); } - @Test + @Test(expected = IllegalArgumentException.class) public void invalidRelativePositionOptionsShouldFailOnBuild() throws Exception { - final List invalidOptions = new ArrayList<>(); - invalidOptions.add(new RelativeOffsetOption()); - for (ActionOptions opts : invalidOptions) { - assertThat(opts::build, failsWith(IllegalArgumentException.class)); - } + new RelativeOffsetOption().build(); + fail("The exception throwing was expected"); } @Test public void invalidOptionsArgumentsShouldFailOnAltering() throws Exception { - final List> invalidOptions = new ArrayList<>(); + final List invalidOptions = new ArrayList<>(); invalidOptions.add(() -> waitOptions(ofMillis(-1))); invalidOptions.add(() -> new RelativeOffsetOption().withRelativeOffset(null, 0, 0)); invalidOptions.add(() -> new WaitOptions().withDuration(null)); invalidOptions.add(() -> tapOptions().withTapsCount(-1)); invalidOptions.add(() -> longPressOptions().withDuration(null)); invalidOptions.add(() -> longPressOptions().withDuration(ofMillis(-1))); - for (IThrowingRunnable item : invalidOptions) { + for (Runnable item : invalidOptions) { assertThat(item, failsWith(RuntimeException.class)); } } From c89209840a7fb235df5ca850d34ba5ed38dfc4ed Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Mon, 6 Nov 2017 01:49:00 +0300 Subject: [PATCH 09/14] The addition to the #756. archetetural improvement: - PositionOffsetOption and WebElementOption instead of AbsoluteOffsetOption and RelativeOffsetOption. --- .../io/appium/java_client/TouchAction.java | 136 ++++++------------ .../java_client/ios/IOSTouchAction.java | 19 +-- .../touch/AbsoluteOffsetOption.java | 68 --------- .../touch/OptionsCombinedWithOffset.java | 23 +-- .../touch/PositionOffsetOption.java | 51 +++++++ .../touch/RelativeOffsetOption.java | 119 --------------- .../appium/java_client/touch/WaitOptions.java | 3 +- .../java_client/touch/WebElementOption.java | 66 +++++++++ .../AndroidAbilityToUseSupplierTest.java | 10 +- .../java_client/android/AndroidTouchTest.java | 38 ++--- .../appium/java_client/ios/IOSTouchTest.java | 14 +- .../java_client/ios/XCUIAutomationTest.java | 18 +-- .../java_client/touch/TouchOptionsTests.java | 20 +-- 13 files changed, 222 insertions(+), 363 deletions(-) delete mode 100644 src/main/java/io/appium/java_client/touch/AbsoluteOffsetOption.java create mode 100644 src/main/java/io/appium/java_client/touch/PositionOffsetOption.java delete mode 100644 src/main/java/io/appium/java_client/touch/RelativeOffsetOption.java create mode 100644 src/main/java/io/appium/java_client/touch/WebElementOption.java diff --git a/src/main/java/io/appium/java_client/TouchAction.java b/src/main/java/io/appium/java_client/TouchAction.java index cc0d8ea7c..97a3931a5 100644 --- a/src/main/java/io/appium/java_client/TouchAction.java +++ b/src/main/java/io/appium/java_client/TouchAction.java @@ -17,19 +17,19 @@ package io.appium.java_client; import static com.google.common.base.Preconditions.checkNotNull; -import static io.appium.java_client.touch.AbsoluteOffsetOption.useAbsolute; import static io.appium.java_client.touch.LongPressOptions.longPressOptions; -import static io.appium.java_client.touch.RelativeOffsetOption.useRelative; +import static io.appium.java_client.touch.PositionOffsetOption.positionOffsetOption; +import static io.appium.java_client.touch.WebElementOption.elementOption; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import io.appium.java_client.touch.AbsoluteOffsetOption; import io.appium.java_client.touch.ActionOptions; import io.appium.java_client.touch.LongPressOptions; -import io.appium.java_client.touch.RelativeOffsetOption; +import io.appium.java_client.touch.PositionOffsetOption; import io.appium.java_client.touch.TapOptions; import io.appium.java_client.touch.WaitOptions; +import io.appium.java_client.touch.WebElementOption; import org.openqa.selenium.WebElement; import java.time.Duration; @@ -55,24 +55,12 @@ public TouchAction(PerformsTouchActions performsTouchActions) { } /** - * Press on an element. + * Press action on the screen. * - * @param pressOptions see {@link RelativeOffsetOption}. + * @param pressOptions see {@link WebElementOption} and {@link PositionOffsetOption}. * @return this TouchAction, for chaining. */ - public T press(RelativeOffsetOption pressOptions) { - parameterBuilder.add(new ActionParameter("press", pressOptions)); - //noinspection unchecked - return (T) this; - } - - /** - * Press on an element. - * - * @param pressOptions see {@link AbsoluteOffsetOption}. - * @return this TouchAction, for chaining. - */ - public T press(AbsoluteOffsetOption pressOptions) { + public T press(S pressOptions) { parameterBuilder.add(new ActionParameter("press", pressOptions)); //noinspection unchecked return (T) this; @@ -83,11 +71,11 @@ public T press(AbsoluteOffsetOption pressOptions) { * * @param el element to press on. * @return this TouchAction, for chaining. - * @deprecated use {@link #press(RelativeOffsetOption)} instead + * @deprecated use {@link #press(PositionOffsetOption)} instead */ @Deprecated public T press(WebElement el) { - return press(useRelative(el)); + return press(elementOption(el)); } /** @@ -96,11 +84,11 @@ public T press(WebElement el) { * @param x x coordinate. * @param y y coordinate. * @return this TouchAction, for chaining. - * @deprecated use {@link #press(AbsoluteOffsetOption)} instead + * @deprecated use {@link #press(PositionOffsetOption)} instead */ @Deprecated public T press(int x, int y) { - return press(useAbsolute(x, y)); + return (T) press(positionOffsetOption(x, y)); } /** @@ -110,11 +98,11 @@ public T press(int x, int y) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. - * @deprecated use {@link #press(RelativeOffsetOption)} instead + * @deprecated use {@link #press(PositionOffsetOption)} instead */ @Deprecated public T press(WebElement el, int x, int y) { - return press(useRelative(el, x, y)); + return press(elementOption(el, x, y)); } /** @@ -130,25 +118,12 @@ public T release() { } /** - * Move current touch to center of an element. - * - * @param moveToOptions see {@link AbsoluteOffsetOption}. - * @return this TouchAction, for chaining. - */ - public T moveTo(AbsoluteOffsetOption moveToOptions) { - ActionParameter action = new ActionParameter("moveTo", moveToOptions); - parameterBuilder.add(action); - //noinspection unchecked - return (T) this; - } - - /** - * Move current touch to center of an element. + * Moves current touch to a new position. * - * @param moveToOptions see {@link RelativeOffsetOption}. + * @param moveToOptions see {@link WebElementOption} and {@link PositionOffsetOption}. * @return this TouchAction, for chaining. */ - public T moveTo(RelativeOffsetOption moveToOptions) { + public T moveTo(S moveToOptions) { ActionParameter action = new ActionParameter("moveTo", moveToOptions); parameterBuilder.add(action); //noinspection unchecked @@ -160,11 +135,11 @@ public T moveTo(RelativeOffsetOption moveToOptions) { * * @param el element to move to. * @return this TouchAction, for chaining. - * @deprecated {@link #moveTo(RelativeOffsetOption)} instead + * @deprecated {@link #moveTo(PositionOffsetOption)} instead */ @Deprecated public T moveTo(WebElement el) { - return moveTo(useRelative(el)); + return moveTo(elementOption(el)); } /** @@ -175,11 +150,11 @@ public T moveTo(WebElement el) { * @param x change in x coordinate to move through. * @param y change in y coordinate to move through. * @return this TouchAction, for chaining. - * @deprecated {@link #moveTo(AbsoluteOffsetOption)} instead + * @deprecated {@link #moveTo(PositionOffsetOption)} instead */ @Deprecated public T moveTo(int x, int y) { - return moveTo(useAbsolute(x, y)); + return (T) moveTo(positionOffsetOption(x, y)); } /** @@ -189,11 +164,11 @@ public T moveTo(int x, int y) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. - * @deprecated {@link #moveTo(RelativeOffsetOption)} instead + * @deprecated {@link #moveTo(PositionOffsetOption)} instead */ @Deprecated public T moveTo(WebElement el, int x, int y) { - return moveTo(useRelative(el, x, y)); + return moveTo(elementOption(el, x, y)); } /** @@ -209,24 +184,12 @@ public TouchAction tap(TapOptions tapOptions) { } /** - * Tap on an element. - * - * @param tapOptions see {@link RelativeOffsetOption}. - * @return this TouchAction, for chaining. - */ - public T tap(RelativeOffsetOption tapOptions) { - ActionParameter action = new ActionParameter("tap", tapOptions); - parameterBuilder.add(action); - return (T) this; - } - - /** - * Tap on an element. + * Tap on a position. * - * @param tapOptions see {@link AbsoluteOffsetOption}. + * @param tapOptions see {@link WebElementOption} and {@link PositionOffsetOption}. * @return this TouchAction, for chaining. */ - public T tap(AbsoluteOffsetOption tapOptions) { + public T tap(S tapOptions) { ActionParameter action = new ActionParameter("tap", tapOptions); parameterBuilder.add(action); return (T) this; @@ -237,11 +200,11 @@ public T tap(AbsoluteOffsetOption tapOptions) { * * @param el element to tap. * @return this TouchAction, for chaining. - * @deprecated use {@link #tap(RelativeOffsetOption)} instead. + * @deprecated use {@link #tap(PositionOffsetOption)} instead. */ @Deprecated public T tap(WebElement el) { - return tap(useRelative(el)); + return tap(elementOption(el)); } /** @@ -250,11 +213,11 @@ public T tap(WebElement el) { * @param x x coordinate. * @param y y coordinate. * @return this TouchAction, for chaining. - * @deprecated use {@link #tap(AbsoluteOffsetOption)} instead. + * @deprecated use {@link #tap(PositionOffsetOption)} instead. */ @Deprecated public T tap(int x, int y) { - return tap(useAbsolute(x, y)); + return (T) tap(positionOffsetOption(x, y)); } /** @@ -264,11 +227,11 @@ public T tap(int x, int y) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. - * @deprecated use {@link #tap(RelativeOffsetOption)} instead. + * @deprecated use {@link #tap(PositionOffsetOption)} instead. */ @Deprecated public T tap(WebElement el, int x, int y) { - return tap(useRelative(el, x, y)); + return tap(elementOption(el, x, y)); } /** @@ -329,23 +292,10 @@ public T longPress(LongPressOptions longPressOptions) { /** * Press and hold the at the center of an element until the context menu event has fired. * - * @param longPressOptions see {@link RelativeOffsetOption}. - * @return this TouchAction, for chaining. - */ - public T longPress(RelativeOffsetOption longPressOptions) { - ActionParameter action = new ActionParameter("longPress", longPressOptions); - parameterBuilder.add(action); - //noinspection unchecked - return (T) this; - } - - /** - * Press and hold the at the center of an element until the context menu event has fired. - * - * @param longPressOptions see {@link AbsoluteOffsetOption}. + * @param longPressOptions see {@link WebElementOption} and {@link PositionOffsetOption}. * @return this TouchAction, for chaining. */ - public T longPress(AbsoluteOffsetOption longPressOptions) { + public T longPress(S longPressOptions) { ActionParameter action = new ActionParameter("longPress", longPressOptions); parameterBuilder.add(action); //noinspection unchecked @@ -357,11 +307,11 @@ public T longPress(AbsoluteOffsetOption longPressOptions) { * * @param el element to long-press. * @return this TouchAction, for chaining. - * @deprecated use {@link #longPress(RelativeOffsetOption)} instead + * @deprecated use {@link #longPress(PositionOffsetOption)} instead */ @Deprecated public T longPress(WebElement el) { - return longPress(useRelative(el)); + return longPress(elementOption(el)); } /** @@ -375,7 +325,7 @@ public T longPress(WebElement el) { @Deprecated public T longPress(WebElement el, Duration duration) { return longPress(longPressOptions() - .withDuration(duration).withOffset(useRelative(el))); + .withDuration(duration).withOffset(elementOption(el))); } /** @@ -385,11 +335,11 @@ public T longPress(WebElement el, Duration duration) { * @param x x coordinate. * @param y y coordinate. * @return this TouchAction, for chaining. - * @deprecated use {@link #longPress(AbsoluteOffsetOption)} instead + * @deprecated use {@link #longPress(PositionOffsetOption)} instead */ @Deprecated public T longPress(int x, int y) { - return longPress(useAbsolute(x, y)); + return (T) longPress(positionOffsetOption(x, y)); } /** @@ -404,8 +354,8 @@ public T longPress(int x, int y) { */ @Deprecated public T longPress(int x, int y, Duration duration) { - return longPress(longPressOptions() - .withDuration(duration).withOffset(useAbsolute(x, y))); + return (T) longPress(longPressOptions() + .withDuration(duration).withOffset(positionOffsetOption(x, y))); } /** @@ -416,11 +366,11 @@ public T longPress(int x, int y, Duration duration) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. - * @deprecated use {@link #longPress(RelativeOffsetOption)} instead + * @deprecated use {@link #longPress(PositionOffsetOption)} instead */ @Deprecated public T longPress(WebElement el, int x, int y) { - return longPress(useRelative(el, x, y)); + return longPress(elementOption(el, x, y)); } /** @@ -437,7 +387,7 @@ public T longPress(WebElement el, int x, int y) { @Deprecated public TouchAction longPress(WebElement el, int x, int y, Duration duration) { return longPress(longPressOptions() - .withOffset(useRelative(el, x, y)).withDuration(duration)); + .withOffset(elementOption(el, x, y)).withDuration(duration)); } /** diff --git a/src/main/java/io/appium/java_client/ios/IOSTouchAction.java b/src/main/java/io/appium/java_client/ios/IOSTouchAction.java index ffb382d10..2751d2dce 100644 --- a/src/main/java/io/appium/java_client/ios/IOSTouchAction.java +++ b/src/main/java/io/appium/java_client/ios/IOSTouchAction.java @@ -16,11 +16,13 @@ package io.appium.java_client.ios; -import static io.appium.java_client.touch.RelativeOffsetOption.useRelative; +import static io.appium.java_client.touch.WebElementOption.elementOption; import io.appium.java_client.PerformsTouchActions; import io.appium.java_client.TouchAction; -import io.appium.java_client.touch.RelativeOffsetOption; +import io.appium.java_client.touch.ActionOptions; +import io.appium.java_client.touch.PositionOffsetOption; +import io.appium.java_client.touch.WebElementOption; import org.openqa.selenium.WebElement; public class IOSTouchAction extends TouchAction { @@ -36,11 +38,11 @@ public IOSTouchAction(PerformsTouchActions performsTouchActions) { * @param x x offset. * @param y y offset. * @return this IOSTouchAction, for chaining. - * @deprecated use {@link #tap(RelativeOffsetOption)} with count=2 instead. + * @deprecated use {@link #tap(PositionOffsetOption)} with count=2 instead. */ @Deprecated public IOSTouchAction doubleTap(WebElement el, int x, int y) { - return doubleTap(useRelative(el, x, y)); + return doubleTap(elementOption(el, x, y)); } /** @@ -48,20 +50,21 @@ public IOSTouchAction doubleTap(WebElement el, int x, int y) { * * @param el element to tap. * @return this IOSTouchAction, for chaining. - * @deprecated use {@link #tap(RelativeOffsetOption)} with count=2 instead. + * @deprecated use {@link #tap(PositionOffsetOption)} with count=2 instead. */ @Deprecated public IOSTouchAction doubleTap(WebElement el) { - return doubleTap(useRelative(el)); + return doubleTap(elementOption(el)); } /** * Double taps using relative offset from an element. * - * @param doubleTapOption is the relative offset parameter from the element + * @param doubleTapOption is the relative offset parameter from the element. + * see {@link WebElementOption} and {@link PositionOffsetOption}. * @return self-reference */ - public IOSTouchAction doubleTap(RelativeOffsetOption doubleTapOption) { + public IOSTouchAction doubleTap(ActionOptions doubleTapOption) { ActionParameter action = new ActionParameter("doubleTap", doubleTapOption); parameterBuilder.add(action); diff --git a/src/main/java/io/appium/java_client/touch/AbsoluteOffsetOption.java b/src/main/java/io/appium/java_client/touch/AbsoluteOffsetOption.java deleted file mode 100644 index 9884c5c90..000000000 --- a/src/main/java/io/appium/java_client/touch/AbsoluteOffsetOption.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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.touch; - -import static java.util.Optional.ofNullable; - -import org.openqa.selenium.Point; - -import java.util.Map; - -public class AbsoluteOffsetOption extends ActionOptions { - private Point absoluteOffset = null; - - /** - * It creates an instance of {@link AbsoluteOffsetOption } which takes absolute - * x and y offsets. - * - * @param xOffset the absolute distance from the left screen corner. - * @param yOffset the absolute distance from the top screen corner. - * @return a built option - */ - public static AbsoluteOffsetOption useAbsolute(int xOffset, int yOffset) { - return new AbsoluteOffsetOption().withAbsoluteOffset(xOffset, yOffset); - } - - /** - * Set the absolute offset for the corresponding action. - * - * @param xOffset the absolute distance from the left screen corner. - * @param yOffset the absolute distance from the top screen corner. - * @return this instance for chaining. - */ - public AbsoluteOffsetOption withAbsoluteOffset(int xOffset, int yOffset) { - this.absoluteOffset = new Point(xOffset, yOffset); - //noinspection unchecked - return this; - } - - @Override - protected void verify() { - ofNullable(absoluteOffset).orElseThrow(() -> new IllegalArgumentException( - "Absolute offset must not be defined")); - } - - @Override - public Map build() { - final Map result = super.build(); - ofNullable(absoluteOffset).ifPresent(point -> { - result.put("x", point.x); - result.put("y", point.y); - }); - return result; - } -} diff --git a/src/main/java/io/appium/java_client/touch/OptionsCombinedWithOffset.java b/src/main/java/io/appium/java_client/touch/OptionsCombinedWithOffset.java index 1859a8625..765e87ad1 100644 --- a/src/main/java/io/appium/java_client/touch/OptionsCombinedWithOffset.java +++ b/src/main/java/io/appium/java_client/touch/OptionsCombinedWithOffset.java @@ -9,27 +9,14 @@ public abstract class OptionsCombinedWithOffset offsetOption; /** - * Some actions may require some absolute offset value to be performed. - * Invocation of this method replaces the result of previous invocation of - * the {@link #withOffset(RelativeOffsetOption)} + * Some actions may require offset. It may be option which contains x,y - offset + * from the left corner of the screen or from the current point on the screen + * or x,y - offset from the left corner of the element. * - * @param offset is the values of required absolute offset from the left corner of a screen. * + * @param offset required absolute offset option. * * @return self-reference */ - public T withOffset(AbsoluteOffsetOption offset) { - offsetOption = offset; - return (T) this; - } - - /** - * Some actions may require some relative offset value to be performed. - * Invocation of this method replaces the result of previous invocation of - * the {@link #withOffset(AbsoluteOffsetOption)} - * - * @param offset is the values of required offset from the left corner of an element. * - * @return self-reference - */ - public T withOffset(RelativeOffsetOption offset) { + public T withOffset(S offset) { offsetOption = offset; return (T) this; } diff --git a/src/main/java/io/appium/java_client/touch/PositionOffsetOption.java b/src/main/java/io/appium/java_client/touch/PositionOffsetOption.java new file mode 100644 index 000000000..83907c579 --- /dev/null +++ b/src/main/java/io/appium/java_client/touch/PositionOffsetOption.java @@ -0,0 +1,51 @@ +package io.appium.java_client.touch; + +import static java.util.Optional.ofNullable; + +import org.openqa.selenium.Point; + +import java.util.Map; + +public class PositionOffsetOption> extends ActionOptions { + private Point offset = new Point(0, 0); + + /** + * It creates a built instance of {@link PositionOffsetOption} which takes x and y position + * offsets. This is offset from the upper left corner of the screen/element or + * from the corresponding action. + * + * @param xOffset is x-axis offset. + * @param yOffset is y-axis offset. + * @return a built option + */ + public static PositionOffsetOption positionOffsetOption(int xOffset, int yOffset) { + return new PositionOffsetOption().withOffet(xOffset, yOffset); + } + + /** + * Sets the offset from the upper left corner of the screen/element or + * from the corresponding action. + * + * @param xOffset is x-axis offset. + * @param yOffset is y-axis offset. + * @return this instance for chaining. + */ + public T withOffet(int xOffset, int yOffset) { + this.offset = new Point(xOffset, yOffset); + return (T) this; + } + + @Override + protected void verify() { + ofNullable(offset).orElseThrow(() -> new IllegalArgumentException( + "X and Y offset values must be defined")); + } + + @Override + public Map build() { + final Map result = super.build(); + result.put("x", offset.x); + result.put("y", offset.y); + return result; + } +} diff --git a/src/main/java/io/appium/java_client/touch/RelativeOffsetOption.java b/src/main/java/io/appium/java_client/touch/RelativeOffsetOption.java deleted file mode 100644 index 45352caec..000000000 --- a/src/main/java/io/appium/java_client/touch/RelativeOffsetOption.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * 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.touch; - -import static com.google.common.base.Preconditions.checkNotNull; -import static java.util.Optional.ofNullable; - -import org.openqa.selenium.Point; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.internal.HasIdentity; - -import java.util.Map; - -public class RelativeOffsetOption extends ActionOptions { - private String elementId = null; - private Point relativeOffset = null; - - /** - * It creates an instance of {@link RelativeOffsetOption } which takes an element - * and x and y offsets. These offsets are relative to the given element. - * - * @param element is the target element - * @param xOffset x-offset which is relative to the given element - * @param yOffset y-offset which is relative to the given element - * @return a built option - */ - public static RelativeOffsetOption useRelative(WebElement element, int xOffset, int yOffset) { - return new RelativeOffsetOption().withRelativeOffset(element, xOffset, yOffset); - } - - /** - * * It creates an instance of {@link RelativeOffsetOption } which takes an element - * and 0-value x and y offsets. - * - * @param element is the target element - * @return a built option - */ - public static RelativeOffsetOption useRelative(WebElement element) { - return useRelative(element, 0, 0); - } - - /** - * It creates an instance of {@link RelativeOffsetOption } which takes x and y offsets. - * These offsets are relative to to the previous chain element position. - * - * @param xOffset x offset that is relative to the previous chain element position. - * @param yOffset y offset that is relative to the previous chain element position. - * @return a built option - */ - public static RelativeOffsetOption useRelative(int xOffset, int yOffset) { - return new RelativeOffsetOption().withRelativeOffset(xOffset, yOffset); - } - - /** - * Set the relative offset for the corresponding action. - * - * @param element the destination element. - * @param xOffset the relative distance from the left element corner - * (if set) or from the left corner of the preceding chain action. - * This value might be zero if it is necessary. - * @param yOffset the relative distance from the top element corner - * (if set) or from the top corner of the preceding chain action. - * This value might be zero if it is necessary. - * @return this instance for chaining. - */ - public RelativeOffsetOption withRelativeOffset(WebElement element, int xOffset, int yOffset) { - checkNotNull(element); - this.elementId = ((HasIdentity) element).getId(); - this.relativeOffset = new Point(xOffset, yOffset); - //noinspection unchecked - return this; - } - - /** - * Set the relative offset for the corresponding action. - * - * @param xOffset is x-axis offset that is relative to the previous chain element position. - * @param yOffset is y-axis offset that is relative to the previous chain element position. - * @return this instance for chaining. - */ - public RelativeOffsetOption withRelativeOffset(int xOffset, int yOffset) { - this.relativeOffset = new Point(xOffset, yOffset); - //noinspection unchecked - return this; - } - - @Override - protected void verify() { - if (elementId == null && relativeOffset == null) { - throw new IllegalArgumentException("Either element or relative offset should be defined"); - } - } - - @Override - public Map build() { - final Map result = super.build(); - ofNullable(relativeOffset).ifPresent(point -> { - result.put("x", point.x); - result.put("y", point.y); - }); - - ofNullable(elementId).ifPresent(s -> result.put("element", s)); - return result; - } -} diff --git a/src/main/java/io/appium/java_client/touch/WaitOptions.java b/src/main/java/io/appium/java_client/touch/WaitOptions.java index e5b219246..422f0b052 100644 --- a/src/main/java/io/appium/java_client/touch/WaitOptions.java +++ b/src/main/java/io/appium/java_client/touch/WaitOptions.java @@ -18,12 +18,13 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import static java.time.Duration.ofMillis; import java.time.Duration; import java.util.Map; public class WaitOptions extends ActionOptions { - protected Duration duration = Duration.ofMillis(0); + protected Duration duration = ofMillis(0); /** * Creates and instance of {@link WaitOptions}. diff --git a/src/main/java/io/appium/java_client/touch/WebElementOption.java b/src/main/java/io/appium/java_client/touch/WebElementOption.java new file mode 100644 index 000000000..a83951afc --- /dev/null +++ b/src/main/java/io/appium/java_client/touch/WebElementOption.java @@ -0,0 +1,66 @@ +package io.appium.java_client.touch; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Optional.ofNullable; + +import org.openqa.selenium.WebElement; +import org.openqa.selenium.internal.HasIdentity; + +import java.util.Map; + +public class WebElementOption extends PositionOffsetOption { + + private HasIdentity elementId; + + /** + * This method creates a build instance of the {@link WebElementOption} + * + * @param element is the element to calculate offset from. + * @param x is the x-offset from the upper left corner of the given element. + * @param y is the y-offset from the upper left corner of the given element. + * @return the built option + */ + public static WebElementOption elementOption(WebElement element, int x, int y) { + return new WebElementOption().withElement(element).withOffet(x, y); + } + + /** + * This method creates a build instance of the {@link WebElementOption} + * + * @param element is the element to calculate offset from. + * @return the built option + */ + public static WebElementOption elementOption(WebElement element) { + return elementOption(element, 0, 0); + } + + /** + * This method sets the element as an option. It means that x/y offset is the offset + * from the upper left corner of the given element. + * + * @param element is the element to calculate offset from. + * @return self-reference + */ + public WebElementOption withElement(WebElement element) { + checkNotNull(element); + checkArgument(true, "Element should be an instance of the class which " + + "implements org.openqa.selenium.internal.HasIdentity", + (HasIdentity.class.isAssignableFrom(element.getClass()))); + elementId = HasIdentity.class.cast(element); + return this; + } + + @Override + protected void verify() { + ofNullable(elementId).orElseThrow(() -> + new IllegalArgumentException("Element should be defined")); + } + + @Override + public Map build() { + final Map result = super.build(); + result.put("element", elementId.getId()); + return result; + } +} diff --git a/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java b/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java index 5184a76ac..d7502cbea 100644 --- a/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java +++ b/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java @@ -1,7 +1,7 @@ package io.appium.java_client.android; -import static io.appium.java_client.touch.RelativeOffsetOption.useRelative; import static io.appium.java_client.touch.WaitOptions.waitOptions; +import static io.appium.java_client.touch.WebElementOption.elementOption; import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertNotEquals; @@ -24,17 +24,17 @@ public class AndroidAbilityToUseSupplierTest extends BaseAndroidTest { Point center = gallery.getCenter(); return new AndroidTouchAction(driver) - .press(useRelative(images.get(2),-10,center.y - location.y)) + .press(elementOption(images.get(2),-10,center.y - location.y)) .waitAction(waitOptions(ofSeconds(2))) - .moveTo(useRelative(gallery,10,center.y - location.y)) + .moveTo(elementOption(gallery, 10,center.y - location.y)) .release(); }; private final ActionSupplier verticalSwiping = () -> new AndroidTouchAction(driver) - .press(useRelative(driver.findElementByAccessibilityId("Gallery"))) + .press(elementOption(driver.findElementByAccessibilityId("Gallery"))) .waitAction(waitOptions(ofSeconds(2))) - .moveTo(useRelative(driver.findElementByAccessibilityId("Auto Complete"))) + .moveTo(elementOption(driver.findElementByAccessibilityId("Auto Complete"))) .release(); @Test public void horizontalSwipingWithSupplier() throws Exception { diff --git a/src/test/java/io/appium/java_client/android/AndroidTouchTest.java b/src/test/java/io/appium/java_client/android/AndroidTouchTest.java index 998e59d21..497250c94 100644 --- a/src/test/java/io/appium/java_client/android/AndroidTouchTest.java +++ b/src/test/java/io/appium/java_client/android/AndroidTouchTest.java @@ -1,9 +1,9 @@ package io.appium.java_client.android; -import static io.appium.java_client.touch.AbsoluteOffsetOption.useAbsolute; import static io.appium.java_client.touch.LongPressOptions.longPressOptions; -import static io.appium.java_client.touch.RelativeOffsetOption.useRelative; +import static io.appium.java_client.touch.PositionOffsetOption.positionOffsetOption; import static io.appium.java_client.touch.WaitOptions.waitOptions; +import static io.appium.java_client.touch.WebElementOption.elementOption; import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; @@ -36,8 +36,8 @@ public void setUp() throws Exception { assertEquals("Drag text not empty", "", dragText.getText()); TouchAction dragNDrop = new TouchAction(driver) - .longPress(useRelative(dragDot1)) - .moveTo(useRelative(dragDot3)) + .longPress(elementOption(dragDot1)) + .moveTo(elementOption(dragDot3)) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -54,9 +54,9 @@ public void setUp() throws Exception { TouchAction dragNDrop = new TouchAction(driver) .longPress(longPressOptions() - .withOffset(useRelative(dragDot1)) + .withOffset(elementOption(dragDot1)) .withDuration(ofSeconds(2))) - .moveTo(useRelative(dragDot3)) + .moveTo(elementOption(dragDot3)) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -75,8 +75,8 @@ public void setUp() throws Exception { Point center2 = dragDot3.getCenter(); TouchAction dragNDrop = new TouchAction(driver) - .longPress(useAbsolute(center1.x, center1.y)) - .moveTo(useRelative(center2.x, center2.y)) + .longPress(positionOffsetOption(center1.x, center1.y)) + .moveTo(positionOffsetOption(center2.x, center2.y)) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -96,9 +96,9 @@ public void setUp() throws Exception { TouchAction dragNDrop = new TouchAction(driver) .longPress(longPressOptions() - .withOffset(useAbsolute(center1.x, center1.y)) + .withOffset(positionOffsetOption(center1.x, center1.y)) .withDuration(ofSeconds(2))) - .moveTo(useRelative(center2.x, center2.y)) + .moveTo(positionOffsetOption(center2.x, center2.y)) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -110,7 +110,7 @@ public void setUp() throws Exception { Point point = driver.findElementById("io.appium.android.apis:id/button_toggle").getLocation(); new TouchAction(driver) - .press(useAbsolute(point.x + 20, point.y + 30)) + .press(positionOffsetOption(point.x + 20, point.y + 30)) .waitAction(waitOptions(ofSeconds(1))) .release() .perform(); @@ -122,7 +122,7 @@ public void setUp() throws Exception { Activity activity = new Activity("io.appium.android.apis", ".view.Buttons1"); driver.startActivity(activity); new TouchAction(driver) - .press(useRelative(driver.findElementById("io.appium.android.apis:id/button_toggle"))) + .press(elementOption(driver.findElementById("io.appium.android.apis:id/button_toggle"))) .waitAction(waitOptions(ofSeconds(1))) .release() .perform(); @@ -137,9 +137,9 @@ public void setUp() throws Exception { driver.findElementById("io.appium.android.apis:id/chronometer"); TouchAction startStop = new TouchAction(driver) - .tap(useRelative(driver.findElementById("io.appium.android.apis:id/start"))) + .tap(elementOption(driver.findElementById("io.appium.android.apis:id/start"))) .waitAction(waitOptions(ofSeconds(2))) - .tap(useRelative(driver.findElementById("io.appium.android.apis:id/stop"))); + .tap(elementOption(driver.findElementById("io.appium.android.apis:id/stop"))); startStop.perform(); @@ -158,8 +158,8 @@ public void setUp() throws Exception { Point center1 = driver.findElementById("io.appium.android.apis:id/start").getCenter(); TouchAction startStop = new TouchAction(driver) - .tap(useAbsolute(center1.x, center1.y)) - .tap(useRelative(driver.findElementById("io.appium.android.apis:id/stop"), 5, 5)); + .tap(positionOffsetOption(center1.x, center1.y)) + .tap(elementOption(driver.findElementById("io.appium.android.apis:id/stop"), 5, 5)); startStop.perform(); String time = chronometer.getText(); @@ -180,9 +180,9 @@ public void setUp() throws Exception { Point center = gallery.getCenter(); TouchAction swipe = new TouchAction(driver) - .press(useRelative(images.get(2),-10, center.y - location.y)) + .press(elementOption(images.get(2),-10, center.y - location.y)) .waitAction(waitOptions(ofSeconds(2))) - .moveTo(useRelative(gallery,10,center.y - location.y)) + .moveTo(elementOption(gallery,10,center.y - location.y)) .release(); swipe.perform(); assertNotEquals(originalImageCount, gallery @@ -193,7 +193,7 @@ public void setUp() throws Exception { Activity activity = new Activity("io.appium.android.apis", ".view.Buttons1"); driver.startActivity(activity); TouchAction press = new TouchAction(driver) - .press(useRelative(driver.findElementById("io.appium.android.apis:id/button_toggle"))) + .press(elementOption(driver.findElementById("io.appium.android.apis:id/button_toggle"))) .waitAction(waitOptions(ofSeconds(1))) .release(); new MultiTouchAction(driver) diff --git a/src/test/java/io/appium/java_client/ios/IOSTouchTest.java b/src/test/java/io/appium/java_client/ios/IOSTouchTest.java index fcd460209..013237c87 100644 --- a/src/test/java/io/appium/java_client/ios/IOSTouchTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSTouchTest.java @@ -1,7 +1,7 @@ package io.appium.java_client.ios; -import static io.appium.java_client.touch.RelativeOffsetOption.useRelative; import static io.appium.java_client.touch.WaitOptions.waitOptions; +import static io.appium.java_client.touch.WebElementOption.elementOption; import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -17,8 +17,6 @@ import org.openqa.selenium.Dimension; import org.openqa.selenium.support.ui.WebDriverWait; -import java.time.Duration; - @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class IOSTouchTest extends AppIOSTest { @@ -32,7 +30,7 @@ public void tapTest() { intB.sendKeys("4"); MobileElement e = driver.findElementByAccessibilityId("ComputeSumButton"); - new TouchAction(driver).tap(useRelative(e)).perform(); + new TouchAction(driver).tap(elementOption(e)).perform(); assertEquals(driver.findElementByXPath("//*[@name = \"Answer\"]").getText(), "6"); } @@ -40,16 +38,16 @@ public void tapTest() { MobileElement slider = driver.findElementByClassName("UIASlider"); Dimension size = slider.getSize(); - TouchAction swipe = new TouchAction(driver).press(useRelative(slider, size.width / 2 + 2, size.height / 2)) - .waitAction(waitOptions(ofSeconds(2))).moveTo(useRelative(slider, 1, size.height / 2)).release(); + TouchAction swipe = new TouchAction(driver).press(elementOption(slider, size.width / 2 + 2, size.height / 2)) + .waitAction(waitOptions(ofSeconds(2))).moveTo(elementOption(slider, 1, size.height / 2)).release(); swipe.perform(); assertEquals("0%", slider.getAttribute("value")); } @Test public void multiTouchTest() { MobileElement e = driver.findElementByAccessibilityId("ComputeSumButton"); - TouchAction tap1 = new TouchAction(driver).tap(useRelative(e)); - TouchAction tap2 = new TouchAction(driver).tap(useRelative(driver.findElement(MobileBy + TouchAction tap1 = new TouchAction(driver).tap(elementOption(e)); + TouchAction tap2 = new TouchAction(driver).tap(elementOption(driver.findElement(MobileBy .IosUIAutomation(".elements().withName(\"show alert\")")))); new MultiTouchAction(driver).add(tap1).add(tap2).perform(); diff --git a/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java b/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java index a85007aac..9f3436196 100644 --- a/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java +++ b/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java @@ -16,7 +16,7 @@ package io.appium.java_client.ios; -import static io.appium.java_client.touch.RelativeOffsetOption.useRelative; +import static io.appium.java_client.touch.WebElementOption.elementOption; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.is; @@ -49,15 +49,11 @@ public class XCUIAutomationTest extends AppXCUITTest { assertEquals(driver.rotation(), landscapeLeftRotation); } - @Test public void testTouchId() { - try { - driver.toggleTouchIDEnrollment(true); - driver.performTouchID(true); - driver.performTouchID(false); - assertEquals(true, true); - } catch (Exception e) { - throw e; - } + @Test public void testTouchId() throws Exception { + driver.toggleTouchIDEnrollment(true); + driver.performTouchID(true); + driver.performTouchID(false); + assertEquals(true, true); } @Test public void testPutIntoBackgroundAndRestore() { @@ -77,7 +73,7 @@ public class XCUIAutomationTest extends AppXCUITTest { firstField.sendKeys("2"); IOSTouchAction iosTouchAction = new IOSTouchAction(driver); - iosTouchAction.doubleTap(useRelative(firstField)); + iosTouchAction.doubleTap(elementOption(firstField)); IOSElement editingMenu = driver.findElementByClassName("UIAEditingMenu"); assertNotNull(editingMenu); } diff --git a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java index 23e7f79a6..8db49a971 100644 --- a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java +++ b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java @@ -1,11 +1,11 @@ package io.appium.java_client.touch; -import static io.appium.java_client.touch.AbsoluteOffsetOption.useAbsolute; import static io.appium.java_client.touch.FailsWithMatcher.failsWith; import static io.appium.java_client.touch.LongPressOptions.longPressOptions; -import static io.appium.java_client.touch.RelativeOffsetOption.useRelative; +import static io.appium.java_client.touch.PositionOffsetOption.positionOffsetOption; import static io.appium.java_client.touch.TapOptions.tapOptions; import static io.appium.java_client.touch.WaitOptions.waitOptions; +import static io.appium.java_client.touch.WebElementOption.elementOption; import static java.time.Duration.ofMillis; import static java.time.Duration.ofSeconds; import static junit.framework.TestCase.fail; @@ -26,14 +26,8 @@ public class TouchOptionsTests { private static final WebElement DUMMY_ELEMENT = new DummyElement(); @Test(expected = IllegalArgumentException.class) - public void invalidAbsolutePositionOptionsShouldFailOnBuild() throws Exception { - new AbsoluteOffsetOption().build(); - fail("The exception throwing was expected"); - } - - @Test(expected = IllegalArgumentException.class) - public void invalidRelativePositionOptionsShouldFailOnBuild() throws Exception { - new RelativeOffsetOption().build(); + public void invalidElementOptionsShouldFailOnBuild() throws Exception { + new WebElementOption().build(); fail("The exception throwing was expected"); } @@ -41,7 +35,7 @@ public void invalidRelativePositionOptionsShouldFailOnBuild() throws Exception { public void invalidOptionsArgumentsShouldFailOnAltering() throws Exception { final List invalidOptions = new ArrayList<>(); invalidOptions.add(() -> waitOptions(ofMillis(-1))); - invalidOptions.add(() -> new RelativeOffsetOption().withRelativeOffset(null, 0, 0)); + invalidOptions.add(() -> new WebElementOption().withOffet(0, 0).withElement(null)); invalidOptions.add(() -> new WaitOptions().withDuration(null)); invalidOptions.add(() -> tapOptions().withTapsCount(-1)); invalidOptions.add(() -> longPressOptions().withDuration(null)); @@ -54,7 +48,7 @@ public void invalidOptionsArgumentsShouldFailOnAltering() throws Exception { @Test public void longPressOptionsShouldBuildProperly() throws Exception { final Map actualOpts = longPressOptions() - .withOffset(useRelative(DUMMY_ELEMENT).withRelativeOffset(0, 0)) + .withOffset(elementOption(DUMMY_ELEMENT).withOffet(0, 0)) .withDuration(ofMillis(1)) .build(); final Map expectedOpts = new HashMap<>(); @@ -69,7 +63,7 @@ public void longPressOptionsShouldBuildProperly() throws Exception { @Test public void tapOptionsShouldBuildProperly() throws Exception { final Map actualOpts = tapOptions() - .withOffset(useAbsolute(0, 0)) + .withOffset(positionOffsetOption(0, 0)) .withTapsCount(2) .build(); final Map expectedOpts = new HashMap<>(); From 483ba5a5d85b7d75e264a0e82be016da02f3ffd6 Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Mon, 6 Nov 2017 23:12:10 +0300 Subject: [PATCH 10/14] The addition to the #756. Method renaming Also issues whick were pointed out by @mykola-mokhnach were fixed out --- .../io/appium/java_client/TouchAction.java | 34 ++++++++-------- .../java_client/ios/IOSTouchAction.java | 6 +-- .../touch/PositionOffsetOption.java | 8 ++-- .../java_client/touch/WebElementOption.java | 23 +++++++---- .../AndroidAbilityToUseSupplierTest.java | 10 ++--- .../java_client/android/AndroidTouchTest.java | 39 ++++++++++--------- .../appium/java_client/ios/IOSTouchTest.java | 12 +++--- .../java_client/ios/XCUIAutomationTest.java | 4 +- .../java_client/touch/TouchOptionsTests.java | 16 +++++--- 9 files changed, 83 insertions(+), 69 deletions(-) diff --git a/src/main/java/io/appium/java_client/TouchAction.java b/src/main/java/io/appium/java_client/TouchAction.java index 97a3931a5..09149fb5d 100644 --- a/src/main/java/io/appium/java_client/TouchAction.java +++ b/src/main/java/io/appium/java_client/TouchAction.java @@ -18,8 +18,8 @@ import static com.google.common.base.Preconditions.checkNotNull; import static io.appium.java_client.touch.LongPressOptions.longPressOptions; -import static io.appium.java_client.touch.PositionOffsetOption.positionOffsetOption; -import static io.appium.java_client.touch.WebElementOption.elementOption; +import static io.appium.java_client.touch.PositionOffsetOption.offset; +import static io.appium.java_client.touch.WebElementOption.element; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -75,7 +75,7 @@ public T press(S pressOptions) { */ @Deprecated public T press(WebElement el) { - return press(elementOption(el)); + return press(element(el)); } /** @@ -88,7 +88,7 @@ public T press(WebElement el) { */ @Deprecated public T press(int x, int y) { - return (T) press(positionOffsetOption(x, y)); + return (T) press(offset(x, y)); } /** @@ -102,7 +102,7 @@ public T press(int x, int y) { */ @Deprecated public T press(WebElement el, int x, int y) { - return press(elementOption(el, x, y)); + return press(WebElementOption.element(el, x, y)); } /** @@ -139,7 +139,7 @@ public T moveTo(S moveToOptions) { */ @Deprecated public T moveTo(WebElement el) { - return moveTo(elementOption(el)); + return moveTo(element(el)); } /** @@ -154,7 +154,7 @@ public T moveTo(WebElement el) { */ @Deprecated public T moveTo(int x, int y) { - return (T) moveTo(positionOffsetOption(x, y)); + return (T) moveTo(offset(x, y)); } /** @@ -168,7 +168,7 @@ public T moveTo(int x, int y) { */ @Deprecated public T moveTo(WebElement el, int x, int y) { - return moveTo(elementOption(el, x, y)); + return moveTo(WebElementOption.element(el, x, y)); } /** @@ -204,7 +204,7 @@ public T tap(S tapOptions) { */ @Deprecated public T tap(WebElement el) { - return tap(elementOption(el)); + return tap(element(el)); } /** @@ -217,7 +217,7 @@ public T tap(WebElement el) { */ @Deprecated public T tap(int x, int y) { - return (T) tap(positionOffsetOption(x, y)); + return (T) tap(offset(x, y)); } /** @@ -231,7 +231,7 @@ public T tap(int x, int y) { */ @Deprecated public T tap(WebElement el, int x, int y) { - return tap(elementOption(el, x, y)); + return tap(WebElementOption.element(el, x, y)); } /** @@ -311,7 +311,7 @@ public T longPress(S longPressOptions) { */ @Deprecated public T longPress(WebElement el) { - return longPress(elementOption(el)); + return longPress(element(el)); } /** @@ -325,7 +325,7 @@ public T longPress(WebElement el) { @Deprecated public T longPress(WebElement el, Duration duration) { return longPress(longPressOptions() - .withDuration(duration).withOffset(elementOption(el))); + .withDuration(duration).withOffset(element(el))); } /** @@ -339,7 +339,7 @@ public T longPress(WebElement el, Duration duration) { */ @Deprecated public T longPress(int x, int y) { - return (T) longPress(positionOffsetOption(x, y)); + return (T) longPress(offset(x, y)); } /** @@ -355,7 +355,7 @@ public T longPress(int x, int y) { @Deprecated public T longPress(int x, int y, Duration duration) { return (T) longPress(longPressOptions() - .withDuration(duration).withOffset(positionOffsetOption(x, y))); + .withDuration(duration).withOffset(offset(x, y))); } /** @@ -370,7 +370,7 @@ public T longPress(int x, int y, Duration duration) { */ @Deprecated public T longPress(WebElement el, int x, int y) { - return longPress(elementOption(el, x, y)); + return longPress(WebElementOption.element(el, x, y)); } /** @@ -387,7 +387,7 @@ public T longPress(WebElement el, int x, int y) { @Deprecated public TouchAction longPress(WebElement el, int x, int y, Duration duration) { return longPress(longPressOptions() - .withOffset(elementOption(el, x, y)).withDuration(duration)); + .withOffset(WebElementOption.element(el, x, y)).withDuration(duration)); } /** diff --git a/src/main/java/io/appium/java_client/ios/IOSTouchAction.java b/src/main/java/io/appium/java_client/ios/IOSTouchAction.java index 2751d2dce..7422c4bd2 100644 --- a/src/main/java/io/appium/java_client/ios/IOSTouchAction.java +++ b/src/main/java/io/appium/java_client/ios/IOSTouchAction.java @@ -16,7 +16,7 @@ package io.appium.java_client.ios; -import static io.appium.java_client.touch.WebElementOption.elementOption; +import static io.appium.java_client.touch.WebElementOption.element; import io.appium.java_client.PerformsTouchActions; import io.appium.java_client.TouchAction; @@ -42,7 +42,7 @@ public IOSTouchAction(PerformsTouchActions performsTouchActions) { */ @Deprecated public IOSTouchAction doubleTap(WebElement el, int x, int y) { - return doubleTap(elementOption(el, x, y)); + return doubleTap(element(el, x, y)); } /** @@ -54,7 +54,7 @@ public IOSTouchAction doubleTap(WebElement el, int x, int y) { */ @Deprecated public IOSTouchAction doubleTap(WebElement el) { - return doubleTap(elementOption(el)); + return doubleTap(element(el)); } /** diff --git a/src/main/java/io/appium/java_client/touch/PositionOffsetOption.java b/src/main/java/io/appium/java_client/touch/PositionOffsetOption.java index 83907c579..049366d6f 100644 --- a/src/main/java/io/appium/java_client/touch/PositionOffsetOption.java +++ b/src/main/java/io/appium/java_client/touch/PositionOffsetOption.java @@ -7,7 +7,7 @@ import java.util.Map; public class PositionOffsetOption> extends ActionOptions { - private Point offset = new Point(0, 0); + protected Point offset; /** * It creates a built instance of {@link PositionOffsetOption} which takes x and y position @@ -18,8 +18,8 @@ public class PositionOffsetOption> extends Act * @param yOffset is y-axis offset. * @return a built option */ - public static PositionOffsetOption positionOffsetOption(int xOffset, int yOffset) { - return new PositionOffsetOption().withOffet(xOffset, yOffset); + public static PositionOffsetOption offset(int xOffset, int yOffset) { + return new PositionOffsetOption().setOffset(xOffset, yOffset); } /** @@ -30,7 +30,7 @@ public static PositionOffsetOption positionOffsetOption(int xOffset, int yOffset * @param yOffset is y-axis offset. * @return this instance for chaining. */ - public T withOffet(int xOffset, int yOffset) { + public T setOffset(int xOffset, int yOffset) { this.offset = new Point(xOffset, yOffset); return (T) this; } diff --git a/src/main/java/io/appium/java_client/touch/WebElementOption.java b/src/main/java/io/appium/java_client/touch/WebElementOption.java index a83951afc..56090ae50 100644 --- a/src/main/java/io/appium/java_client/touch/WebElementOption.java +++ b/src/main/java/io/appium/java_client/touch/WebElementOption.java @@ -7,11 +7,12 @@ import org.openqa.selenium.WebElement; import org.openqa.selenium.internal.HasIdentity; +import java.util.HashMap; import java.util.Map; public class WebElementOption extends PositionOffsetOption { - private HasIdentity elementId; + private String elementId; /** * This method creates a build instance of the {@link WebElementOption} @@ -21,8 +22,8 @@ public class WebElementOption extends PositionOffsetOption { * @param y is the y-offset from the upper left corner of the given element. * @return the built option */ - public static WebElementOption elementOption(WebElement element, int x, int y) { - return new WebElementOption().withElement(element).withOffet(x, y); + public static WebElementOption element(WebElement element, int x, int y) { + return new WebElementOption().withElement(element).setOffset(x, y); } /** @@ -31,8 +32,8 @@ public static WebElementOption elementOption(WebElement element, int x, int y) { * @param element is the element to calculate offset from. * @return the built option */ - public static WebElementOption elementOption(WebElement element) { - return elementOption(element, 0, 0); + public static WebElementOption element(WebElement element) { + return new WebElementOption().withElement(element); } /** @@ -47,7 +48,7 @@ public WebElementOption withElement(WebElement element) { checkArgument(true, "Element should be an instance of the class which " + "implements org.openqa.selenium.internal.HasIdentity", (HasIdentity.class.isAssignableFrom(element.getClass()))); - elementId = HasIdentity.class.cast(element); + elementId = HasIdentity.class.cast(element).getId(); return this; } @@ -59,8 +60,14 @@ protected void verify() { @Override public Map build() { - final Map result = super.build(); - result.put("element", elementId.getId()); + verify(); + final Map result = new HashMap<>(); + result.put("element", elementId); + + ofNullable(offset).ifPresent(point -> { + result.put("x", point.x); + result.put("y", point.y); + }); return result; } } diff --git a/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java b/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java index d7502cbea..5c95cf9b9 100644 --- a/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java +++ b/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java @@ -1,7 +1,7 @@ package io.appium.java_client.android; import static io.appium.java_client.touch.WaitOptions.waitOptions; -import static io.appium.java_client.touch.WebElementOption.elementOption; +import static io.appium.java_client.touch.WebElementOption.element; import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertNotEquals; @@ -24,17 +24,17 @@ public class AndroidAbilityToUseSupplierTest extends BaseAndroidTest { Point center = gallery.getCenter(); return new AndroidTouchAction(driver) - .press(elementOption(images.get(2),-10,center.y - location.y)) + .press(element(images.get(2),-10,center.y - location.y)) .waitAction(waitOptions(ofSeconds(2))) - .moveTo(elementOption(gallery, 10,center.y - location.y)) + .moveTo(element(gallery, 10,center.y - location.y)) .release(); }; private final ActionSupplier verticalSwiping = () -> new AndroidTouchAction(driver) - .press(elementOption(driver.findElementByAccessibilityId("Gallery"))) + .press(element(driver.findElementByAccessibilityId("Gallery"))) .waitAction(waitOptions(ofSeconds(2))) - .moveTo(elementOption(driver.findElementByAccessibilityId("Auto Complete"))) + .moveTo(element(driver.findElementByAccessibilityId("Auto Complete"))) .release(); @Test public void horizontalSwipingWithSupplier() throws Exception { diff --git a/src/test/java/io/appium/java_client/android/AndroidTouchTest.java b/src/test/java/io/appium/java_client/android/AndroidTouchTest.java index 497250c94..7abbe354c 100644 --- a/src/test/java/io/appium/java_client/android/AndroidTouchTest.java +++ b/src/test/java/io/appium/java_client/android/AndroidTouchTest.java @@ -1,9 +1,9 @@ package io.appium.java_client.android; import static io.appium.java_client.touch.LongPressOptions.longPressOptions; -import static io.appium.java_client.touch.PositionOffsetOption.positionOffsetOption; +import static io.appium.java_client.touch.PositionOffsetOption.offset; import static io.appium.java_client.touch.WaitOptions.waitOptions; -import static io.appium.java_client.touch.WebElementOption.elementOption; +import static io.appium.java_client.touch.WebElementOption.element; import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; @@ -11,6 +11,7 @@ import io.appium.java_client.MobileElement; import io.appium.java_client.MultiTouchAction; import io.appium.java_client.TouchAction; +import io.appium.java_client.touch.WebElementOption; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.By; @@ -36,8 +37,8 @@ public void setUp() throws Exception { assertEquals("Drag text not empty", "", dragText.getText()); TouchAction dragNDrop = new TouchAction(driver) - .longPress(elementOption(dragDot1)) - .moveTo(elementOption(dragDot3)) + .longPress(element(dragDot1)) + .moveTo(element(dragDot3)) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -54,9 +55,9 @@ public void setUp() throws Exception { TouchAction dragNDrop = new TouchAction(driver) .longPress(longPressOptions() - .withOffset(elementOption(dragDot1)) + .withOffset(element(dragDot1)) .withDuration(ofSeconds(2))) - .moveTo(elementOption(dragDot3)) + .moveTo(element(dragDot3)) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -75,8 +76,8 @@ public void setUp() throws Exception { Point center2 = dragDot3.getCenter(); TouchAction dragNDrop = new TouchAction(driver) - .longPress(positionOffsetOption(center1.x, center1.y)) - .moveTo(positionOffsetOption(center2.x, center2.y)) + .longPress(offset(center1.x, center1.y)) + .moveTo(offset(center2.x, center2.y)) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -96,9 +97,9 @@ public void setUp() throws Exception { TouchAction dragNDrop = new TouchAction(driver) .longPress(longPressOptions() - .withOffset(positionOffsetOption(center1.x, center1.y)) + .withOffset(offset(center1.x, center1.y)) .withDuration(ofSeconds(2))) - .moveTo(positionOffsetOption(center2.x, center2.y)) + .moveTo(offset(center2.x, center2.y)) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -110,7 +111,7 @@ public void setUp() throws Exception { Point point = driver.findElementById("io.appium.android.apis:id/button_toggle").getLocation(); new TouchAction(driver) - .press(positionOffsetOption(point.x + 20, point.y + 30)) + .press(offset(point.x + 20, point.y + 30)) .waitAction(waitOptions(ofSeconds(1))) .release() .perform(); @@ -122,7 +123,7 @@ public void setUp() throws Exception { Activity activity = new Activity("io.appium.android.apis", ".view.Buttons1"); driver.startActivity(activity); new TouchAction(driver) - .press(elementOption(driver.findElementById("io.appium.android.apis:id/button_toggle"))) + .press(element(driver.findElementById("io.appium.android.apis:id/button_toggle"))) .waitAction(waitOptions(ofSeconds(1))) .release() .perform(); @@ -137,9 +138,9 @@ public void setUp() throws Exception { driver.findElementById("io.appium.android.apis:id/chronometer"); TouchAction startStop = new TouchAction(driver) - .tap(elementOption(driver.findElementById("io.appium.android.apis:id/start"))) + .tap(element(driver.findElementById("io.appium.android.apis:id/start"))) .waitAction(waitOptions(ofSeconds(2))) - .tap(elementOption(driver.findElementById("io.appium.android.apis:id/stop"))); + .tap(element(driver.findElementById("io.appium.android.apis:id/stop"))); startStop.perform(); @@ -158,8 +159,8 @@ public void setUp() throws Exception { Point center1 = driver.findElementById("io.appium.android.apis:id/start").getCenter(); TouchAction startStop = new TouchAction(driver) - .tap(positionOffsetOption(center1.x, center1.y)) - .tap(elementOption(driver.findElementById("io.appium.android.apis:id/stop"), 5, 5)); + .tap(offset(center1.x, center1.y)) + .tap(WebElementOption.element(driver.findElementById("io.appium.android.apis:id/stop"), 5, 5)); startStop.perform(); String time = chronometer.getText(); @@ -180,9 +181,9 @@ public void setUp() throws Exception { Point center = gallery.getCenter(); TouchAction swipe = new TouchAction(driver) - .press(elementOption(images.get(2),-10, center.y - location.y)) + .press(WebElementOption.element(images.get(2),-10, center.y - location.y)) .waitAction(waitOptions(ofSeconds(2))) - .moveTo(elementOption(gallery,10,center.y - location.y)) + .moveTo(WebElementOption.element(gallery,10,center.y - location.y)) .release(); swipe.perform(); assertNotEquals(originalImageCount, gallery @@ -193,7 +194,7 @@ public void setUp() throws Exception { Activity activity = new Activity("io.appium.android.apis", ".view.Buttons1"); driver.startActivity(activity); TouchAction press = new TouchAction(driver) - .press(elementOption(driver.findElementById("io.appium.android.apis:id/button_toggle"))) + .press(element(driver.findElementById("io.appium.android.apis:id/button_toggle"))) .waitAction(waitOptions(ofSeconds(1))) .release(); new MultiTouchAction(driver) diff --git a/src/test/java/io/appium/java_client/ios/IOSTouchTest.java b/src/test/java/io/appium/java_client/ios/IOSTouchTest.java index 013237c87..06088f819 100644 --- a/src/test/java/io/appium/java_client/ios/IOSTouchTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSTouchTest.java @@ -1,7 +1,7 @@ package io.appium.java_client.ios; import static io.appium.java_client.touch.WaitOptions.waitOptions; -import static io.appium.java_client.touch.WebElementOption.elementOption; +import static io.appium.java_client.touch.WebElementOption.element; import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -30,7 +30,7 @@ public void tapTest() { intB.sendKeys("4"); MobileElement e = driver.findElementByAccessibilityId("ComputeSumButton"); - new TouchAction(driver).tap(elementOption(e)).perform(); + new TouchAction(driver).tap(element(e)).perform(); assertEquals(driver.findElementByXPath("//*[@name = \"Answer\"]").getText(), "6"); } @@ -38,16 +38,16 @@ public void tapTest() { MobileElement slider = driver.findElementByClassName("UIASlider"); Dimension size = slider.getSize(); - TouchAction swipe = new TouchAction(driver).press(elementOption(slider, size.width / 2 + 2, size.height / 2)) - .waitAction(waitOptions(ofSeconds(2))).moveTo(elementOption(slider, 1, size.height / 2)).release(); + TouchAction swipe = new TouchAction(driver).press(element(slider, size.width / 2 + 2, size.height / 2)) + .waitAction(waitOptions(ofSeconds(2))).moveTo(element(slider, 1, size.height / 2)).release(); swipe.perform(); assertEquals("0%", slider.getAttribute("value")); } @Test public void multiTouchTest() { MobileElement e = driver.findElementByAccessibilityId("ComputeSumButton"); - TouchAction tap1 = new TouchAction(driver).tap(elementOption(e)); - TouchAction tap2 = new TouchAction(driver).tap(elementOption(driver.findElement(MobileBy + TouchAction tap1 = new TouchAction(driver).tap(element(e)); + TouchAction tap2 = new TouchAction(driver).tap(element(driver.findElement(MobileBy .IosUIAutomation(".elements().withName(\"show alert\")")))); new MultiTouchAction(driver).add(tap1).add(tap2).perform(); diff --git a/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java b/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java index 9f3436196..a1307985c 100644 --- a/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java +++ b/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java @@ -16,7 +16,7 @@ package io.appium.java_client.ios; -import static io.appium.java_client.touch.WebElementOption.elementOption; +import static io.appium.java_client.touch.WebElementOption.element; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.is; @@ -73,7 +73,7 @@ public class XCUIAutomationTest extends AppXCUITTest { firstField.sendKeys("2"); IOSTouchAction iosTouchAction = new IOSTouchAction(driver); - iosTouchAction.doubleTap(elementOption(firstField)); + iosTouchAction.doubleTap(element(firstField)); IOSElement editingMenu = driver.findElementByClassName("UIAEditingMenu"); assertNotNull(editingMenu); } diff --git a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java index 8db49a971..6446c14aa 100644 --- a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java +++ b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java @@ -2,10 +2,10 @@ import static io.appium.java_client.touch.FailsWithMatcher.failsWith; import static io.appium.java_client.touch.LongPressOptions.longPressOptions; -import static io.appium.java_client.touch.PositionOffsetOption.positionOffsetOption; +import static io.appium.java_client.touch.PositionOffsetOption.offset; import static io.appium.java_client.touch.TapOptions.tapOptions; import static io.appium.java_client.touch.WaitOptions.waitOptions; -import static io.appium.java_client.touch.WebElementOption.elementOption; +import static io.appium.java_client.touch.WebElementOption.element; import static java.time.Duration.ofMillis; import static java.time.Duration.ofSeconds; import static junit.framework.TestCase.fail; @@ -25,6 +25,12 @@ public class TouchOptionsTests { private static final WebElement DUMMY_ELEMENT = new DummyElement(); + @Test(expected = IllegalArgumentException.class) + public void invalidPositionOptionsShouldFailOnBuild() throws Exception { + new PositionOffsetOption<>().build(); + fail("The exception throwing was expected"); + } + @Test(expected = IllegalArgumentException.class) public void invalidElementOptionsShouldFailOnBuild() throws Exception { new WebElementOption().build(); @@ -35,7 +41,7 @@ public void invalidElementOptionsShouldFailOnBuild() throws Exception { public void invalidOptionsArgumentsShouldFailOnAltering() throws Exception { final List invalidOptions = new ArrayList<>(); invalidOptions.add(() -> waitOptions(ofMillis(-1))); - invalidOptions.add(() -> new WebElementOption().withOffet(0, 0).withElement(null)); + invalidOptions.add(() -> new WebElementOption().setOffset(0, 0).withElement(null)); invalidOptions.add(() -> new WaitOptions().withDuration(null)); invalidOptions.add(() -> tapOptions().withTapsCount(-1)); invalidOptions.add(() -> longPressOptions().withDuration(null)); @@ -48,7 +54,7 @@ public void invalidOptionsArgumentsShouldFailOnAltering() throws Exception { @Test public void longPressOptionsShouldBuildProperly() throws Exception { final Map actualOpts = longPressOptions() - .withOffset(elementOption(DUMMY_ELEMENT).withOffet(0, 0)) + .withOffset(element(DUMMY_ELEMENT).setOffset(0, 0)) .withDuration(ofMillis(1)) .build(); final Map expectedOpts = new HashMap<>(); @@ -63,7 +69,7 @@ public void longPressOptionsShouldBuildProperly() throws Exception { @Test public void tapOptionsShouldBuildProperly() throws Exception { final Map actualOpts = tapOptions() - .withOffset(positionOffsetOption(0, 0)) + .withOffset(offset(0, 0)) .withTapsCount(2) .build(); final Map expectedOpts = new HashMap<>(); From ee55d22b9d7f96e84f5400810db3f2d648d8fde4 Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Mon, 6 Nov 2017 23:26:19 +0300 Subject: [PATCH 11/14] The addition to the #756. Bug fix --- src/main/java/io/appium/java_client/TouchAction.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/appium/java_client/TouchAction.java b/src/main/java/io/appium/java_client/TouchAction.java index 09149fb5d..3d0666876 100644 --- a/src/main/java/io/appium/java_client/TouchAction.java +++ b/src/main/java/io/appium/java_client/TouchAction.java @@ -177,10 +177,10 @@ public T moveTo(WebElement el, int x, int y) { * @param tapOptions see {@link TapOptions}. * @return this TouchAction, for chaining. */ - public TouchAction tap(TapOptions tapOptions) { + public T tap(TapOptions tapOptions) { ActionParameter action = new ActionParameter("tap", tapOptions); parameterBuilder.add(action); - return this; + return (T) this; } /** @@ -385,7 +385,7 @@ public T longPress(WebElement el, int x, int y) { * @deprecated use {@link #longPress(LongPressOptions)} instead */ @Deprecated - public TouchAction longPress(WebElement el, int x, int y, Duration duration) { + public T longPress(WebElement el, int x, int y, Duration duration) { return longPress(longPressOptions() .withOffset(WebElementOption.element(el, x, y)).withDuration(duration)); } From 6ddbd2e8bb54448566a704c4ba8e9556360f11df Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Thu, 9 Nov 2017 00:50:57 +0300 Subject: [PATCH 12/14] The addition to the #756. Archetectural improvement: - offsets were divided to absolute(PointOption) relative(OffsetOption) and relative to an element (ElementOption) - The PointOption which may take any position option - signature of TouchAction was changed --- .../io/appium/java_client/TouchAction.java | 89 ++++++++++--------- .../java_client/ios/IOSTouchAction.java | 22 +++-- .../java_client/touch/LongPressOptions.java | 6 +- .../touch/OptionsCombinedWithOffset.java | 36 -------- .../touch/PositionOffsetOption.java | 51 ----------- .../appium/java_client/touch/TapOptions.java | 5 +- .../AbstractOptionCombinedWithPosition.java | 53 +++++++++++ .../touch/offset/AbstractPositionOption.java | 18 ++++ .../ElementOption.java} | 18 ++-- .../touch/offset/OffsetOption.java | 50 +++++++++++ .../java_client/touch/offset/PointOption.java | 56 ++++++++++++ .../java_client/touch/offset/Position.java | 13 +++ .../AndroidAbilityToUseSupplierTest.java | 23 +++-- .../java_client/android/AndroidTouchTest.java | 49 +++++----- .../appium/java_client/ios/IOSTouchTest.java | 27 ++++-- .../java_client/ios/XCUIAutomationTest.java | 6 +- .../java_client/touch/TouchOptionsTests.java | 23 +++-- 17 files changed, 348 insertions(+), 197 deletions(-) delete mode 100644 src/main/java/io/appium/java_client/touch/OptionsCombinedWithOffset.java delete mode 100644 src/main/java/io/appium/java_client/touch/PositionOffsetOption.java create mode 100644 src/main/java/io/appium/java_client/touch/offset/AbstractOptionCombinedWithPosition.java create mode 100644 src/main/java/io/appium/java_client/touch/offset/AbstractPositionOption.java rename src/main/java/io/appium/java_client/touch/{WebElementOption.java => offset/ElementOption.java} (75%) create mode 100644 src/main/java/io/appium/java_client/touch/offset/OffsetOption.java create mode 100644 src/main/java/io/appium/java_client/touch/offset/PointOption.java create mode 100644 src/main/java/io/appium/java_client/touch/offset/Position.java diff --git a/src/main/java/io/appium/java_client/TouchAction.java b/src/main/java/io/appium/java_client/TouchAction.java index 3d0666876..c04c18a9d 100644 --- a/src/main/java/io/appium/java_client/TouchAction.java +++ b/src/main/java/io/appium/java_client/TouchAction.java @@ -17,19 +17,23 @@ package io.appium.java_client; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.ImmutableList.builder; import static io.appium.java_client.touch.LongPressOptions.longPressOptions; -import static io.appium.java_client.touch.PositionOffsetOption.offset; -import static io.appium.java_client.touch.WebElementOption.element; +import static io.appium.java_client.touch.offset.ElementOption.element; +import static io.appium.java_client.touch.offset.OffsetOption.offset; +import static io.appium.java_client.touch.offset.PointOption.coordinates; +import static io.appium.java_client.touch.offset.Position.position; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import io.appium.java_client.touch.ActionOptions; import io.appium.java_client.touch.LongPressOptions; -import io.appium.java_client.touch.PositionOffsetOption; import io.appium.java_client.touch.TapOptions; import io.appium.java_client.touch.WaitOptions; -import io.appium.java_client.touch.WebElementOption; +import io.appium.java_client.touch.offset.AbstractPositionOption; +import io.appium.java_client.touch.offset.PointOption; +import io.appium.java_client.touch.offset.Position; import org.openqa.selenium.WebElement; import java.time.Duration; @@ -51,16 +55,16 @@ public class TouchAction> implements PerformsActions public TouchAction(PerformsTouchActions performsTouchActions) { this.performsTouchActions = performsTouchActions; - parameterBuilder = ImmutableList.builder(); + parameterBuilder = builder(); } /** * Press action on the screen. * - * @param pressOptions see {@link WebElementOption} and {@link PositionOffsetOption}. + * @param pressOptions see {@link Position}. * @return this TouchAction, for chaining. */ - public T press(S pressOptions) { + public T press(Position pressOptions) { parameterBuilder.add(new ActionParameter("press", pressOptions)); //noinspection unchecked return (T) this; @@ -71,11 +75,11 @@ public T press(S pressOptions) { * * @param el element to press on. * @return this TouchAction, for chaining. - * @deprecated use {@link #press(PositionOffsetOption)} instead + * @deprecated use {@link #press(Position)} instead */ @Deprecated public T press(WebElement el) { - return press(element(el)); + return press(Position.position().withElement(element(el))); } /** @@ -84,11 +88,11 @@ public T press(WebElement el) { * @param x x coordinate. * @param y y coordinate. * @return this TouchAction, for chaining. - * @deprecated use {@link #press(PositionOffsetOption)} instead + * @deprecated use {@link #press(Position)} instead */ @Deprecated public T press(int x, int y) { - return (T) press(offset(x, y)); + return press(Position.position().withPosition(coordinates(x, y))); } /** @@ -98,11 +102,11 @@ public T press(int x, int y) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. - * @deprecated use {@link #press(PositionOffsetOption)} instead + * @deprecated use {@link #press(Position)} instead */ @Deprecated public T press(WebElement el, int x, int y) { - return press(WebElementOption.element(el, x, y)); + return press(Position.position().withElement(element(el, x, y))); } /** @@ -120,13 +124,12 @@ public T release() { /** * Moves current touch to a new position. * - * @param moveToOptions see {@link WebElementOption} and {@link PositionOffsetOption}. + * @param moveToOptions see {@link Position} * @return this TouchAction, for chaining. */ - public T moveTo(S moveToOptions) { + public T moveTo(Position moveToOptions) { ActionParameter action = new ActionParameter("moveTo", moveToOptions); parameterBuilder.add(action); - //noinspection unchecked return (T) this; } @@ -135,11 +138,11 @@ public T moveTo(S moveToOptions) { * * @param el element to move to. * @return this TouchAction, for chaining. - * @deprecated {@link #moveTo(PositionOffsetOption)} instead + * @deprecated {@link #moveTo(Position)} instead */ @Deprecated public T moveTo(WebElement el) { - return moveTo(element(el)); + return moveTo(position().withElement(element(el))); } /** @@ -150,11 +153,11 @@ public T moveTo(WebElement el) { * @param x change in x coordinate to move through. * @param y change in y coordinate to move through. * @return this TouchAction, for chaining. - * @deprecated {@link #moveTo(PositionOffsetOption)} instead + * @deprecated {@link #moveTo(Position)} instead */ @Deprecated public T moveTo(int x, int y) { - return (T) moveTo(offset(x, y)); + return moveTo(position().withPosition(offset(x, y))); } /** @@ -164,11 +167,11 @@ public T moveTo(int x, int y) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. - * @deprecated {@link #moveTo(PositionOffsetOption)} instead + * @deprecated {@link #moveTo(Position)} instead */ @Deprecated public T moveTo(WebElement el, int x, int y) { - return moveTo(WebElementOption.element(el, x, y)); + return moveTo(position().withElement(element(el, x, y))); } /** @@ -186,10 +189,10 @@ public T tap(TapOptions tapOptions) { /** * Tap on a position. * - * @param tapOptions see {@link WebElementOption} and {@link PositionOffsetOption}. + * @param tapOptions see {@link Position} * @return this TouchAction, for chaining. */ - public T tap(S tapOptions) { + public T tap(Position tapOptions) { ActionParameter action = new ActionParameter("tap", tapOptions); parameterBuilder.add(action); return (T) this; @@ -200,11 +203,11 @@ public T tap(S tapOptions) { * * @param el element to tap. * @return this TouchAction, for chaining. - * @deprecated use {@link #tap(PositionOffsetOption)} instead. + * @deprecated use {@link #tap(Position)} instead. */ @Deprecated public T tap(WebElement el) { - return tap(element(el)); + return tap(Position.position().withElement(element(el))); } /** @@ -213,11 +216,11 @@ public T tap(WebElement el) { * @param x x coordinate. * @param y y coordinate. * @return this TouchAction, for chaining. - * @deprecated use {@link #tap(PositionOffsetOption)} instead. + * @deprecated use {@link #tap(Position)} instead. */ @Deprecated public T tap(int x, int y) { - return (T) tap(offset(x, y)); + return (T) tap(Position.position().withPosition(coordinates(x, y))); } /** @@ -227,11 +230,11 @@ public T tap(int x, int y) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. - * @deprecated use {@link #tap(PositionOffsetOption)} instead. + * @deprecated use {@link #tap(Position)} instead. */ @Deprecated public T tap(WebElement el, int x, int y) { - return tap(WebElementOption.element(el, x, y)); + return tap(Position.position().withElement(element(el, x, y))); } /** @@ -292,10 +295,10 @@ public T longPress(LongPressOptions longPressOptions) { /** * Press and hold the at the center of an element until the context menu event has fired. * - * @param longPressOptions see {@link WebElementOption} and {@link PositionOffsetOption}. + * @param longPressOptions see {@link Position}. * @return this TouchAction, for chaining. */ - public T longPress(S longPressOptions) { + public T longPress(Position longPressOptions) { ActionParameter action = new ActionParameter("longPress", longPressOptions); parameterBuilder.add(action); //noinspection unchecked @@ -307,11 +310,11 @@ public T longPress(S longPressOptions) { * * @param el element to long-press. * @return this TouchAction, for chaining. - * @deprecated use {@link #longPress(PositionOffsetOption)} instead + * @deprecated use {@link #longPress(Position)} instead */ @Deprecated public T longPress(WebElement el) { - return longPress(element(el)); + return longPress(Position.position().withElement(element(el))); } /** @@ -325,7 +328,7 @@ public T longPress(WebElement el) { @Deprecated public T longPress(WebElement el, Duration duration) { return longPress(longPressOptions() - .withDuration(duration).withOffset(element(el))); + .withDuration(duration).withElement(element(el))); } /** @@ -335,11 +338,11 @@ public T longPress(WebElement el, Duration duration) { * @param x x coordinate. * @param y y coordinate. * @return this TouchAction, for chaining. - * @deprecated use {@link #longPress(PositionOffsetOption)} instead + * @deprecated use {@link #longPress(Position)} instead */ @Deprecated public T longPress(int x, int y) { - return (T) longPress(offset(x, y)); + return longPress(Position.position().withPosition(coordinates(x, y))); } /** @@ -355,7 +358,7 @@ public T longPress(int x, int y) { @Deprecated public T longPress(int x, int y, Duration duration) { return (T) longPress(longPressOptions() - .withDuration(duration).withOffset(offset(x, y))); + .withDuration(duration).withPosition(coordinates(x, y))); } /** @@ -366,11 +369,11 @@ public T longPress(int x, int y, Duration duration) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. - * @deprecated use {@link #longPress(PositionOffsetOption)} instead + * @deprecated use {@link #longPress(Position)} instead */ @Deprecated public T longPress(WebElement el, int x, int y) { - return longPress(WebElementOption.element(el, x, y)); + return longPress(Position.position().withElement(element(el, x, y))); } /** @@ -387,7 +390,7 @@ public T longPress(WebElement el, int x, int y) { @Deprecated public T longPress(WebElement el, int x, int y, Duration duration) { return longPress(longPressOptions() - .withOffset(WebElementOption.element(el, x, y)).withDuration(duration)); + .withElement(element(el, x, y)).withDuration(duration)); } /** @@ -417,7 +420,7 @@ public T perform() { */ protected ImmutableMap> getParameters() { - ImmutableList.Builder parameters = ImmutableList.builder(); + ImmutableList.Builder parameters = builder(); ImmutableList actionList = parameterBuilder.build(); actionList.forEach(action -> parameters.add(action.getParameterMap())); @@ -430,7 +433,7 @@ protected ImmutableMap> getParameters() { * @return this TouchAction, for possible segmented-touches. */ protected T clearParameters() { - parameterBuilder = ImmutableList.builder(); + parameterBuilder = builder(); //noinspection unchecked return (T) this; } diff --git a/src/main/java/io/appium/java_client/ios/IOSTouchAction.java b/src/main/java/io/appium/java_client/ios/IOSTouchAction.java index 7422c4bd2..f5a09a3a3 100644 --- a/src/main/java/io/appium/java_client/ios/IOSTouchAction.java +++ b/src/main/java/io/appium/java_client/ios/IOSTouchAction.java @@ -16,13 +16,12 @@ package io.appium.java_client.ios; -import static io.appium.java_client.touch.WebElementOption.element; +import static io.appium.java_client.touch.offset.ElementOption.element; import io.appium.java_client.PerformsTouchActions; import io.appium.java_client.TouchAction; -import io.appium.java_client.touch.ActionOptions; -import io.appium.java_client.touch.PositionOffsetOption; -import io.appium.java_client.touch.WebElementOption; +import io.appium.java_client.touch.offset.PointOption; +import io.appium.java_client.touch.offset.Position; import org.openqa.selenium.WebElement; public class IOSTouchAction extends TouchAction { @@ -38,11 +37,11 @@ public IOSTouchAction(PerformsTouchActions performsTouchActions) { * @param x x offset. * @param y y offset. * @return this IOSTouchAction, for chaining. - * @deprecated use {@link #tap(PositionOffsetOption)} with count=2 instead. + * @deprecated use {@link #tap(Position)} with count=2 instead. */ @Deprecated public IOSTouchAction doubleTap(WebElement el, int x, int y) { - return doubleTap(element(el, x, y)); + return doubleTap(Position.position().withElement(element(el, x, y))); } /** @@ -50,21 +49,20 @@ public IOSTouchAction doubleTap(WebElement el, int x, int y) { * * @param el element to tap. * @return this IOSTouchAction, for chaining. - * @deprecated use {@link #tap(PositionOffsetOption)} with count=2 instead. + * @deprecated use {@link #tap(Position)} with count=2 instead. */ @Deprecated public IOSTouchAction doubleTap(WebElement el) { - return doubleTap(element(el)); + return doubleTap(Position.position().withElement(element(el))); } /** - * Double taps using relative offset from an element. + * Double taps using coordinates. * - * @param doubleTapOption is the relative offset parameter from the element. - * see {@link WebElementOption} and {@link PositionOffsetOption}. + * @param doubleTapOption see {@link Position}. * @return self-reference */ - public IOSTouchAction doubleTap(ActionOptions doubleTapOption) { + public IOSTouchAction doubleTap(Position doubleTapOption) { ActionParameter action = new ActionParameter("doubleTap", doubleTapOption); parameterBuilder.add(action); diff --git a/src/main/java/io/appium/java_client/touch/LongPressOptions.java b/src/main/java/io/appium/java_client/touch/LongPressOptions.java index 149975479..355a04b9b 100644 --- a/src/main/java/io/appium/java_client/touch/LongPressOptions.java +++ b/src/main/java/io/appium/java_client/touch/LongPressOptions.java @@ -20,10 +20,14 @@ import static com.google.common.base.Preconditions.checkNotNull; import static java.util.Optional.ofNullable; +import io.appium.java_client.touch.offset.AbstractOptionCombinedWithPosition; +import io.appium.java_client.touch.offset.PointOption; + import java.time.Duration; import java.util.Map; -public class LongPressOptions extends OptionsCombinedWithOffset { +public class LongPressOptions + extends AbstractOptionCombinedWithPosition { protected Duration duration = null; /** diff --git a/src/main/java/io/appium/java_client/touch/OptionsCombinedWithOffset.java b/src/main/java/io/appium/java_client/touch/OptionsCombinedWithOffset.java deleted file mode 100644 index 765e87ad1..000000000 --- a/src/main/java/io/appium/java_client/touch/OptionsCombinedWithOffset.java +++ /dev/null @@ -1,36 +0,0 @@ -package io.appium.java_client.touch; - -import static java.util.Optional.ofNullable; - -import java.util.Map; - -public abstract class OptionsCombinedWithOffset - extends ActionOptions> { - private ActionOptions offsetOption; - - /** - * Some actions may require offset. It may be option which contains x,y - offset - * from the left corner of the screen or from the current point on the screen - * or x,y - offset from the left corner of the element. - * - * @param offset required absolute offset option. * - * @return self-reference - */ - public T withOffset(S offset) { - offsetOption = offset; - return (T) this; - } - - protected void verify() { - ofNullable(offsetOption).orElseThrow(() -> - new IllegalArgumentException("Some relative or absolute offset should " - + "be defined. Use one of withOffset methods")); - } - - @Override - public Map build() { - final Map result = super.build(); - result.putAll(offsetOption.build()); - return result; - } -} diff --git a/src/main/java/io/appium/java_client/touch/PositionOffsetOption.java b/src/main/java/io/appium/java_client/touch/PositionOffsetOption.java deleted file mode 100644 index 049366d6f..000000000 --- a/src/main/java/io/appium/java_client/touch/PositionOffsetOption.java +++ /dev/null @@ -1,51 +0,0 @@ -package io.appium.java_client.touch; - -import static java.util.Optional.ofNullable; - -import org.openqa.selenium.Point; - -import java.util.Map; - -public class PositionOffsetOption> extends ActionOptions { - protected Point offset; - - /** - * It creates a built instance of {@link PositionOffsetOption} which takes x and y position - * offsets. This is offset from the upper left corner of the screen/element or - * from the corresponding action. - * - * @param xOffset is x-axis offset. - * @param yOffset is y-axis offset. - * @return a built option - */ - public static PositionOffsetOption offset(int xOffset, int yOffset) { - return new PositionOffsetOption().setOffset(xOffset, yOffset); - } - - /** - * Sets the offset from the upper left corner of the screen/element or - * from the corresponding action. - * - * @param xOffset is x-axis offset. - * @param yOffset is y-axis offset. - * @return this instance for chaining. - */ - public T setOffset(int xOffset, int yOffset) { - this.offset = new Point(xOffset, yOffset); - return (T) this; - } - - @Override - protected void verify() { - ofNullable(offset).orElseThrow(() -> new IllegalArgumentException( - "X and Y offset values must be defined")); - } - - @Override - public Map build() { - final Map result = super.build(); - result.put("x", offset.x); - result.put("y", offset.y); - return result; - } -} diff --git a/src/main/java/io/appium/java_client/touch/TapOptions.java b/src/main/java/io/appium/java_client/touch/TapOptions.java index 16a8034b7..51bbbe32e 100644 --- a/src/main/java/io/appium/java_client/touch/TapOptions.java +++ b/src/main/java/io/appium/java_client/touch/TapOptions.java @@ -19,9 +19,12 @@ import static com.google.common.base.Preconditions.checkArgument; import static java.util.Optional.ofNullable; +import io.appium.java_client.touch.offset.AbstractOptionCombinedWithPosition; +import io.appium.java_client.touch.offset.PointOption; + import java.util.Map; -public class TapOptions extends OptionsCombinedWithOffset { +public class TapOptions extends AbstractOptionCombinedWithPosition { private Integer tapsCount = null; /** diff --git a/src/main/java/io/appium/java_client/touch/offset/AbstractOptionCombinedWithPosition.java b/src/main/java/io/appium/java_client/touch/offset/AbstractOptionCombinedWithPosition.java new file mode 100644 index 000000000..22b358a18 --- /dev/null +++ b/src/main/java/io/appium/java_client/touch/offset/AbstractOptionCombinedWithPosition.java @@ -0,0 +1,53 @@ +package io.appium.java_client.touch.offset; + +import static java.util.Optional.ofNullable; + +import io.appium.java_client.touch.ActionOptions; + +import java.util.Map; + +public abstract class AbstractOptionCombinedWithPosition, + S extends AbstractPositionOption> + extends ActionOptions> { + private ActionOptions offsetOption; + + /** + * Some actions may require offset. It may be option which contains x,y - offset + * from the left corner of the screen or from the current point on the screen + * or x,y - offset from the left corner of the element. Invocation of this method + * replaces the result of previous {@link #withElement(ElementOption)} invocation. + * + * @param offset required offset option. * + * @return self-reference + */ + public T withPosition(S offset) { + offsetOption = offset; + return (T) this; + } + + /** + * Most of touch action may use position which is relative to some element. In order to unify + * this behaviour this method was added. Invocation of this method + * replaces the result of previous {@link #withPosition(AbstractPositionOption)} invocation. + * + * @param element required position which is relative to some element + * @return self-reference + */ + public T withElement(ElementOption element) { + offsetOption = element; + return (T) this; + } + + protected void verify() { + ofNullable(offsetOption).orElseThrow(() -> + new IllegalArgumentException("Some relative or absolute position should " + + "be defined. Use withPosition or withElement methods")); + } + + @Override + public Map build() { + final Map result = super.build(); + result.putAll(offsetOption.build()); + return result; + } +} diff --git a/src/main/java/io/appium/java_client/touch/offset/AbstractPositionOption.java b/src/main/java/io/appium/java_client/touch/offset/AbstractPositionOption.java new file mode 100644 index 000000000..572c6d2a1 --- /dev/null +++ b/src/main/java/io/appium/java_client/touch/offset/AbstractPositionOption.java @@ -0,0 +1,18 @@ +package io.appium.java_client.touch.offset; + +import io.appium.java_client.touch.ActionOptions; +import org.openqa.selenium.Point; + +public abstract class AbstractPositionOption> extends ActionOptions { + protected Point offset; + + /** + * Defines the offset or coordinates + * from the corresponding action. + * + * @param xOffset is x offset/value. + * @param yOffset is y offset/value. + * @return this instance for chaining. + */ + public abstract T position(int xOffset, int yOffset); +} diff --git a/src/main/java/io/appium/java_client/touch/WebElementOption.java b/src/main/java/io/appium/java_client/touch/offset/ElementOption.java similarity index 75% rename from src/main/java/io/appium/java_client/touch/WebElementOption.java rename to src/main/java/io/appium/java_client/touch/offset/ElementOption.java index 56090ae50..d474b2ada 100644 --- a/src/main/java/io/appium/java_client/touch/WebElementOption.java +++ b/src/main/java/io/appium/java_client/touch/offset/ElementOption.java @@ -1,4 +1,4 @@ -package io.appium.java_client.touch; +package io.appium.java_client.touch.offset; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; @@ -10,30 +10,30 @@ import java.util.HashMap; import java.util.Map; -public class WebElementOption extends PositionOffsetOption { +public class ElementOption extends OffsetOption { private String elementId; /** - * This method creates a build instance of the {@link WebElementOption} + * This method creates a build instance of the {@link ElementOption} * * @param element is the element to calculate offset from. * @param x is the x-offset from the upper left corner of the given element. * @param y is the y-offset from the upper left corner of the given element. * @return the built option */ - public static WebElementOption element(WebElement element, int x, int y) { - return new WebElementOption().withElement(element).setOffset(x, y); + public static ElementOption element(WebElement element, int x, int y) { + return new ElementOption().withElement(element).position(x, y); } /** - * This method creates a build instance of the {@link WebElementOption} + * This method creates a build instance of the {@link ElementOption} * * @param element is the element to calculate offset from. * @return the built option */ - public static WebElementOption element(WebElement element) { - return new WebElementOption().withElement(element); + public static ElementOption element(WebElement element) { + return new ElementOption().withElement(element); } /** @@ -43,7 +43,7 @@ public static WebElementOption element(WebElement element) { * @param element is the element to calculate offset from. * @return self-reference */ - public WebElementOption withElement(WebElement element) { + public ElementOption withElement(WebElement element) { checkNotNull(element); checkArgument(true, "Element should be an instance of the class which " + "implements org.openqa.selenium.internal.HasIdentity", diff --git a/src/main/java/io/appium/java_client/touch/offset/OffsetOption.java b/src/main/java/io/appium/java_client/touch/offset/OffsetOption.java new file mode 100644 index 000000000..a90c297a6 --- /dev/null +++ b/src/main/java/io/appium/java_client/touch/offset/OffsetOption.java @@ -0,0 +1,50 @@ +package io.appium.java_client.touch.offset; + +import static java.util.Optional.ofNullable; + +import org.openqa.selenium.Point; + +import java.util.Map; + +public class OffsetOption> extends AbstractPositionOption { + + /** + * It creates a built instance of {@link PointOption} which takes x and y relative offsets. + * This is offset from the upper left corner of an element or the position of the previous action. + * + * @param xOffset is x-offset value. + * @param yOffset is y-offset value. + * @return a built option + */ + public static OffsetOption offset(int xOffset, int yOffset) { + return new OffsetOption().position(xOffset, yOffset); + } + + /** + * It defines x and y relative offsets. + * This is offset from the upper left corner of an element or from the position of the previous action. + * + * @param xOffset is x-offset value. + * @param yOffset is y-offset value. + * @return self-reference + */ + @Override + public T position(int xOffset, int yOffset) { + this.offset = new Point(xOffset, yOffset); + return (T) this; + } + + @Override + protected void verify() { + ofNullable(offset).orElseThrow(() -> new IllegalArgumentException( + "Relative X and Y offset values must be defined")); + } + + @Override + public Map build() { + final Map result = super.build(); + result.put("x", offset.x); + result.put("y", offset.y); + return result; + } +} diff --git a/src/main/java/io/appium/java_client/touch/offset/PointOption.java b/src/main/java/io/appium/java_client/touch/offset/PointOption.java new file mode 100644 index 000000000..39676f3ec --- /dev/null +++ b/src/main/java/io/appium/java_client/touch/offset/PointOption.java @@ -0,0 +1,56 @@ +package io.appium.java_client.touch.offset; + +import static com.google.common.base.Preconditions.checkArgument; +import static java.lang.String.format; +import static java.util.Optional.ofNullable; + +import org.openqa.selenium.Point; + +import java.util.Map; + +public class PointOption extends AbstractPositionOption { + + private static final String ERROR_MESSAGE_TEMPLATE = "%s coordinate value should be equal or greater than zero"; + + /** + * It creates a built instance of {@link PointOption} which takes x and y coordinates. + * This is offset from the upper left corner of the screen. + * + * @param xOffset is x value. + * @param yOffset is y value. + * @return a built option + */ + public static PointOption coordinates(int xOffset, int yOffset) { + return new PointOption().position(xOffset, yOffset); + } + + /** + * It defines x and y coordinates. + * This is offset from the upper left corner of the screen. + * + * @param xOffset is x value. + * @param yOffset is y value. + * @return self-reference + */ + @Override + public PointOption position(int xOffset, int yOffset) { + checkArgument(xOffset >= 0, format(ERROR_MESSAGE_TEMPLATE, "X")); + checkArgument(yOffset >= 0, format(ERROR_MESSAGE_TEMPLATE, "Y")); + offset = new Point(xOffset, yOffset); + return this; + } + + @Override + protected void verify() { + ofNullable(offset).orElseThrow(() -> new IllegalArgumentException( + "Coordinate values must be defined")); + } + + @Override + public Map build() { + final Map result = super.build(); + result.put("x", offset.x); + result.put("y", offset.y); + return result; + } +} diff --git a/src/main/java/io/appium/java_client/touch/offset/Position.java b/src/main/java/io/appium/java_client/touch/offset/Position.java new file mode 100644 index 000000000..b22a174c4 --- /dev/null +++ b/src/main/java/io/appium/java_client/touch/offset/Position.java @@ -0,0 +1,13 @@ +package io.appium.java_client.touch.offset; + +/** + * This is the default superclass of the {@link AbstractOptionCombinedWithPosition} + * @param is the sub type of {@link AbstractPositionOption} which instances should be + * consumed. + */ +public class Position extends AbstractOptionCombinedWithPosition, S> { + + public static Position position() { + return new Position(); + } +} diff --git a/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java b/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java index 5c95cf9b9..69c1e5aad 100644 --- a/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java +++ b/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java @@ -1,12 +1,16 @@ package io.appium.java_client.android; import static io.appium.java_client.touch.WaitOptions.waitOptions; -import static io.appium.java_client.touch.WebElementOption.element; +import static io.appium.java_client.touch.offset.ElementOption.element; +import static io.appium.java_client.touch.offset.PointOption.coordinates; +import static io.appium.java_client.touch.offset.Position.position; import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertNotEquals; import io.appium.java_client.MobileElement; import io.appium.java_client.functions.ActionSupplier; +import io.appium.java_client.touch.offset.PointOption; +import io.appium.java_client.touch.offset.Position; import org.junit.Test; import org.openqa.selenium.Point; @@ -23,18 +27,27 @@ public class AndroidAbilityToUseSupplierTest extends BaseAndroidTest { Point location = gallery.getLocation(); Point center = gallery.getCenter(); + Position pressOption = Position.position() + .withElement(element(images.get(2),-10,center.y - location.y)); + + Position moveOption = position().withElement(element(gallery, 10,center.y - location.y)); + return new AndroidTouchAction(driver) - .press(element(images.get(2),-10,center.y - location.y)) + .press(pressOption) .waitAction(waitOptions(ofSeconds(2))) - .moveTo(element(gallery, 10,center.y - location.y)) + .moveTo(moveOption) .release(); }; private final ActionSupplier verticalSwiping = () -> new AndroidTouchAction(driver) - .press(element(driver.findElementByAccessibilityId("Gallery"))) + .press(Position.position() + .withElement(element(driver.findElementByAccessibilityId("Gallery")))) + .waitAction(waitOptions(ofSeconds(2))) - .moveTo(element(driver.findElementByAccessibilityId("Auto Complete"))) + + .moveTo(position() + .withElement(element(driver.findElementByAccessibilityId("Auto Complete")))) .release(); @Test public void horizontalSwipingWithSupplier() throws Exception { diff --git a/src/test/java/io/appium/java_client/android/AndroidTouchTest.java b/src/test/java/io/appium/java_client/android/AndroidTouchTest.java index 7abbe354c..815444802 100644 --- a/src/test/java/io/appium/java_client/android/AndroidTouchTest.java +++ b/src/test/java/io/appium/java_client/android/AndroidTouchTest.java @@ -1,9 +1,11 @@ package io.appium.java_client.android; import static io.appium.java_client.touch.LongPressOptions.longPressOptions; -import static io.appium.java_client.touch.PositionOffsetOption.offset; +import static io.appium.java_client.touch.TapOptions.tapOptions; import static io.appium.java_client.touch.WaitOptions.waitOptions; -import static io.appium.java_client.touch.WebElementOption.element; +import static io.appium.java_client.touch.offset.ElementOption.element; +import static io.appium.java_client.touch.offset.PointOption.coordinates; +import static io.appium.java_client.touch.offset.Position.position; import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; @@ -11,7 +13,8 @@ import io.appium.java_client.MobileElement; import io.appium.java_client.MultiTouchAction; import io.appium.java_client.TouchAction; -import io.appium.java_client.touch.WebElementOption; +import io.appium.java_client.touch.offset.PointOption; +import io.appium.java_client.touch.offset.Position; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.By; @@ -37,8 +40,8 @@ public void setUp() throws Exception { assertEquals("Drag text not empty", "", dragText.getText()); TouchAction dragNDrop = new TouchAction(driver) - .longPress(element(dragDot1)) - .moveTo(element(dragDot3)) + .longPress(Position.position().withElement(element(dragDot1))) + .moveTo(position().withElement(element(dragDot3))) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -55,9 +58,9 @@ public void setUp() throws Exception { TouchAction dragNDrop = new TouchAction(driver) .longPress(longPressOptions() - .withOffset(element(dragDot1)) + .withElement(element(dragDot1)) .withDuration(ofSeconds(2))) - .moveTo(element(dragDot3)) + .moveTo(position().withElement(element(dragDot3))) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -76,8 +79,8 @@ public void setUp() throws Exception { Point center2 = dragDot3.getCenter(); TouchAction dragNDrop = new TouchAction(driver) - .longPress(offset(center1.x, center1.y)) - .moveTo(offset(center2.x, center2.y)) + .longPress(Position.position().withPosition(coordinates(center1.x, center1.y))) + .moveTo(position().withPosition(coordinates(center2.x, center2.y))) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -97,9 +100,10 @@ public void setUp() throws Exception { TouchAction dragNDrop = new TouchAction(driver) .longPress(longPressOptions() - .withOffset(offset(center1.x, center1.y)) + .withPosition(coordinates(center1.x, center1.y)) .withDuration(ofSeconds(2))) - .moveTo(offset(center2.x, center2.y)) + .moveTo(position() + .withPosition(coordinates(center2.x, center2.y))) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -111,7 +115,8 @@ public void setUp() throws Exception { Point point = driver.findElementById("io.appium.android.apis:id/button_toggle").getLocation(); new TouchAction(driver) - .press(offset(point.x + 20, point.y + 30)) + .press(Position.position() + .withPosition(coordinates(point.x + 20, point.y + 30))) .waitAction(waitOptions(ofSeconds(1))) .release() .perform(); @@ -123,7 +128,8 @@ public void setUp() throws Exception { Activity activity = new Activity("io.appium.android.apis", ".view.Buttons1"); driver.startActivity(activity); new TouchAction(driver) - .press(element(driver.findElementById("io.appium.android.apis:id/button_toggle"))) + .press(Position.position() + .withElement(element(driver.findElementById("io.appium.android.apis:id/button_toggle")))) .waitAction(waitOptions(ofSeconds(1))) .release() .perform(); @@ -138,9 +144,9 @@ public void setUp() throws Exception { driver.findElementById("io.appium.android.apis:id/chronometer"); TouchAction startStop = new TouchAction(driver) - .tap(element(driver.findElementById("io.appium.android.apis:id/start"))) + .tap(tapOptions().withElement(element(driver.findElementById("io.appium.android.apis:id/start")))) .waitAction(waitOptions(ofSeconds(2))) - .tap(element(driver.findElementById("io.appium.android.apis:id/stop"))); + .tap(tapOptions().withElement(element(driver.findElementById("io.appium.android.apis:id/stop")))); startStop.perform(); @@ -159,8 +165,9 @@ public void setUp() throws Exception { Point center1 = driver.findElementById("io.appium.android.apis:id/start").getCenter(); TouchAction startStop = new TouchAction(driver) - .tap(offset(center1.x, center1.y)) - .tap(WebElementOption.element(driver.findElementById("io.appium.android.apis:id/stop"), 5, 5)); + .tap(Position.position().withPosition(coordinates(center1.x, center1.y))) + .tap(Position.position() + .withElement(element(driver.findElementById("io.appium.android.apis:id/stop"), 5, 5))); startStop.perform(); String time = chronometer.getText(); @@ -181,9 +188,10 @@ public void setUp() throws Exception { Point center = gallery.getCenter(); TouchAction swipe = new TouchAction(driver) - .press(WebElementOption.element(images.get(2),-10, center.y - location.y)) + .press(Position.position() + .withElement(element(images.get(2),-10, center.y - location.y))) .waitAction(waitOptions(ofSeconds(2))) - .moveTo(WebElementOption.element(gallery,10,center.y - location.y)) + .moveTo(position().withElement(element(gallery,10,center.y - location.y))) .release(); swipe.perform(); assertNotEquals(originalImageCount, gallery @@ -194,7 +202,8 @@ public void setUp() throws Exception { Activity activity = new Activity("io.appium.android.apis", ".view.Buttons1"); driver.startActivity(activity); TouchAction press = new TouchAction(driver) - .press(element(driver.findElementById("io.appium.android.apis:id/button_toggle"))) + .press(Position.position() + .withElement(element(driver.findElementById("io.appium.android.apis:id/button_toggle")))) .waitAction(waitOptions(ofSeconds(1))) .release(); new MultiTouchAction(driver) diff --git a/src/test/java/io/appium/java_client/ios/IOSTouchTest.java b/src/test/java/io/appium/java_client/ios/IOSTouchTest.java index 06088f819..d79987c7c 100644 --- a/src/test/java/io/appium/java_client/ios/IOSTouchTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSTouchTest.java @@ -1,16 +1,20 @@ package io.appium.java_client.ios; +import static io.appium.java_client.MobileBy.IosUIAutomation; +import static io.appium.java_client.touch.TapOptions.tapOptions; import static io.appium.java_client.touch.WaitOptions.waitOptions; -import static io.appium.java_client.touch.WebElementOption.element; +import static io.appium.java_client.touch.offset.ElementOption.element; +import static io.appium.java_client.touch.offset.Position.position; import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.openqa.selenium.support.ui.ExpectedConditions.alertIsPresent; -import io.appium.java_client.MobileBy; import io.appium.java_client.MobileElement; import io.appium.java_client.MultiTouchAction; import io.appium.java_client.TouchAction; +import io.appium.java_client.touch.offset.PointOption; +import io.appium.java_client.touch.offset.Position; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; @@ -30,7 +34,7 @@ public void tapTest() { intB.sendKeys("4"); MobileElement e = driver.findElementByAccessibilityId("ComputeSumButton"); - new TouchAction(driver).tap(element(e)).perform(); + new TouchAction(driver).tap(tapOptions().withElement(element(e))).perform(); assertEquals(driver.findElementByXPath("//*[@name = \"Answer\"]").getText(), "6"); } @@ -38,17 +42,24 @@ public void tapTest() { MobileElement slider = driver.findElementByClassName("UIASlider"); Dimension size = slider.getSize(); - TouchAction swipe = new TouchAction(driver).press(element(slider, size.width / 2 + 2, size.height / 2)) - .waitAction(waitOptions(ofSeconds(2))).moveTo(element(slider, 1, size.height / 2)).release(); + Position press = Position.position() + .withElement(element(slider, size.width / 2 + 2, size.height / 2)); + Position move = position().withElement(element(slider, 1, size.height / 2)); + + TouchAction swipe = new TouchAction(driver).press(press) + .waitAction(waitOptions(ofSeconds(2))) + .moveTo(move).release(); + swipe.perform(); assertEquals("0%", slider.getAttribute("value")); } @Test public void multiTouchTest() { MobileElement e = driver.findElementByAccessibilityId("ComputeSumButton"); - TouchAction tap1 = new TouchAction(driver).tap(element(e)); - TouchAction tap2 = new TouchAction(driver).tap(element(driver.findElement(MobileBy - .IosUIAutomation(".elements().withName(\"show alert\")")))); + MobileElement e2 = driver.findElement(IosUIAutomation(".elements().withName(\"show alert\")")); + + TouchAction tap1 = new TouchAction(driver).tap(tapOptions().withElement(element(e))); + TouchAction tap2 = new TouchAction(driver).tap(tapOptions().withElement(element(e2))); new MultiTouchAction(driver).add(tap1).add(tap2).perform(); diff --git a/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java b/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java index a1307985c..adbed9c7a 100644 --- a/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java +++ b/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java @@ -16,7 +16,7 @@ package io.appium.java_client.ios; -import static io.appium.java_client.touch.WebElementOption.element; +import static io.appium.java_client.touch.offset.ElementOption.element; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.is; @@ -25,6 +25,8 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; +import io.appium.java_client.touch.offset.PointOption; +import io.appium.java_client.touch.offset.Position; import org.junit.After; import org.junit.Test; import org.openqa.selenium.DeviceRotation; @@ -73,7 +75,7 @@ public class XCUIAutomationTest extends AppXCUITTest { firstField.sendKeys("2"); IOSTouchAction iosTouchAction = new IOSTouchAction(driver); - iosTouchAction.doubleTap(element(firstField)); + iosTouchAction.doubleTap(Position.position().withElement(element(firstField))); IOSElement editingMenu = driver.findElementByClassName("UIAEditingMenu"); assertNotNull(editingMenu); } diff --git a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java index 6446c14aa..205b07c6f 100644 --- a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java +++ b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java @@ -2,10 +2,11 @@ import static io.appium.java_client.touch.FailsWithMatcher.failsWith; import static io.appium.java_client.touch.LongPressOptions.longPressOptions; -import static io.appium.java_client.touch.PositionOffsetOption.offset; import static io.appium.java_client.touch.TapOptions.tapOptions; import static io.appium.java_client.touch.WaitOptions.waitOptions; -import static io.appium.java_client.touch.WebElementOption.element; +import static io.appium.java_client.touch.offset.ElementOption.element; +import static io.appium.java_client.touch.offset.PointOption.coordinates; +import static io.appium.java_client.touch.offset.Position.position; import static java.time.Duration.ofMillis; import static java.time.Duration.ofSeconds; import static junit.framework.TestCase.fail; @@ -13,6 +14,8 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.isIn; +import io.appium.java_client.touch.offset.ElementOption; +import io.appium.java_client.touch.offset.PointOption; import org.junit.Test; import org.openqa.selenium.WebElement; import org.openqa.selenium.internal.HasIdentity; @@ -26,14 +29,14 @@ public class TouchOptionsTests { private static final WebElement DUMMY_ELEMENT = new DummyElement(); @Test(expected = IllegalArgumentException.class) - public void invalidPositionOptionsShouldFailOnBuild() throws Exception { - new PositionOffsetOption<>().build(); + public void invalidEmptyPositionOptionsShouldFailOnBuild() throws Exception { + position().build(); fail("The exception throwing was expected"); } @Test(expected = IllegalArgumentException.class) - public void invalidElementOptionsShouldFailOnBuild() throws Exception { - new WebElementOption().build(); + public void invalidEmptyElementOptionsShouldFailOnBuild() throws Exception { + new ElementOption().build(); fail("The exception throwing was expected"); } @@ -41,7 +44,9 @@ public void invalidElementOptionsShouldFailOnBuild() throws Exception { public void invalidOptionsArgumentsShouldFailOnAltering() throws Exception { final List invalidOptions = new ArrayList<>(); invalidOptions.add(() -> waitOptions(ofMillis(-1))); - invalidOptions.add(() -> new WebElementOption().setOffset(0, 0).withElement(null)); + invalidOptions.add(() -> new ElementOption().position(0, 0).withElement(null)); + invalidOptions.add(() -> new PointOption().position(0, -1)); + invalidOptions.add(() -> new PointOption().position(-1, 0)); invalidOptions.add(() -> new WaitOptions().withDuration(null)); invalidOptions.add(() -> tapOptions().withTapsCount(-1)); invalidOptions.add(() -> longPressOptions().withDuration(null)); @@ -54,7 +59,7 @@ public void invalidOptionsArgumentsShouldFailOnAltering() throws Exception { @Test public void longPressOptionsShouldBuildProperly() throws Exception { final Map actualOpts = longPressOptions() - .withOffset(element(DUMMY_ELEMENT).setOffset(0, 0)) + .withElement(element(DUMMY_ELEMENT).position(0, 0)) .withDuration(ofMillis(1)) .build(); final Map expectedOpts = new HashMap<>(); @@ -69,7 +74,7 @@ public void longPressOptionsShouldBuildProperly() throws Exception { @Test public void tapOptionsShouldBuildProperly() throws Exception { final Map actualOpts = tapOptions() - .withOffset(offset(0, 0)) + .withPosition(coordinates(0, 0)) .withTapsCount(2) .build(); final Map expectedOpts = new HashMap<>(); From 92ab4c6268b7322540058292a4719fe11226c30f Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Sat, 11 Nov 2017 00:31:54 +0300 Subject: [PATCH 13/14] The addition to the #756. Archetectural improvement. AbstractPositionOption, OffsetOption, Position were removed. The set of class was simplified. Signature of TouchAction methods was changed and simplified. --- .../io/appium/java_client/TouchAction.java | 75 +++++++++---------- .../java_client/ios/IOSTouchAction.java | 14 ++-- .../java_client/touch/LongPressOptions.java | 4 +- .../appium/java_client/touch/TapOptions.java | 3 +- .../AbstractOptionCombinedWithPosition.java | 27 +++---- .../touch/offset/AbstractPositionOption.java | 18 ----- .../touch/offset/ElementOption.java | 21 +++++- .../touch/offset/OffsetOption.java | 50 ------------- .../java_client/touch/offset/PointOption.java | 22 +++--- .../java_client/touch/offset/Position.java | 13 ---- .../AndroidAbilityToUseSupplierTest.java | 17 ++--- .../java_client/android/AndroidTouchTest.java | 39 ++++------ .../appium/java_client/ios/IOSTouchTest.java | 9 +-- .../java_client/ios/XCUIAutomationTest.java | 4 +- .../java_client/touch/TouchOptionsTests.java | 17 ++--- 15 files changed, 119 insertions(+), 214 deletions(-) delete mode 100644 src/main/java/io/appium/java_client/touch/offset/AbstractPositionOption.java delete mode 100644 src/main/java/io/appium/java_client/touch/offset/OffsetOption.java delete mode 100644 src/main/java/io/appium/java_client/touch/offset/Position.java diff --git a/src/main/java/io/appium/java_client/TouchAction.java b/src/main/java/io/appium/java_client/TouchAction.java index c04c18a9d..41b847877 100644 --- a/src/main/java/io/appium/java_client/TouchAction.java +++ b/src/main/java/io/appium/java_client/TouchAction.java @@ -20,9 +20,7 @@ import static com.google.common.collect.ImmutableList.builder; import static io.appium.java_client.touch.LongPressOptions.longPressOptions; import static io.appium.java_client.touch.offset.ElementOption.element; -import static io.appium.java_client.touch.offset.OffsetOption.offset; -import static io.appium.java_client.touch.offset.PointOption.coordinates; -import static io.appium.java_client.touch.offset.Position.position; +import static io.appium.java_client.touch.offset.PointOption.point; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -31,9 +29,8 @@ import io.appium.java_client.touch.LongPressOptions; import io.appium.java_client.touch.TapOptions; import io.appium.java_client.touch.WaitOptions; -import io.appium.java_client.touch.offset.AbstractPositionOption; +import io.appium.java_client.touch.offset.ElementOption; import io.appium.java_client.touch.offset.PointOption; -import io.appium.java_client.touch.offset.Position; import org.openqa.selenium.WebElement; import java.time.Duration; @@ -61,10 +58,10 @@ public TouchAction(PerformsTouchActions performsTouchActions) { /** * Press action on the screen. * - * @param pressOptions see {@link Position}. + * @param pressOptions see {@link PointOption} and {@link ElementOption}. * @return this TouchAction, for chaining. */ - public T press(Position pressOptions) { + public T press(PointOption pressOptions) { parameterBuilder.add(new ActionParameter("press", pressOptions)); //noinspection unchecked return (T) this; @@ -75,11 +72,11 @@ public T press(Position pressOptions) { * * @param el element to press on. * @return this TouchAction, for chaining. - * @deprecated use {@link #press(Position)} instead + * @deprecated use {@link #press(PointOption)} instead */ @Deprecated public T press(WebElement el) { - return press(Position.position().withElement(element(el))); + return press(element(el)); } /** @@ -88,11 +85,11 @@ public T press(WebElement el) { * @param x x coordinate. * @param y y coordinate. * @return this TouchAction, for chaining. - * @deprecated use {@link #press(Position)} instead + * @deprecated use {@link #press(PointOption)} instead */ @Deprecated public T press(int x, int y) { - return press(Position.position().withPosition(coordinates(x, y))); + return press(point(x, y)); } /** @@ -102,11 +99,11 @@ public T press(int x, int y) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. - * @deprecated use {@link #press(Position)} instead + * @deprecated use {@link #press(PointOption)} instead */ @Deprecated public T press(WebElement el, int x, int y) { - return press(Position.position().withElement(element(el, x, y))); + return press(element(el, x, y)); } /** @@ -124,10 +121,10 @@ public T release() { /** * Moves current touch to a new position. * - * @param moveToOptions see {@link Position} + * @param moveToOptions see {@link PointOption} and {@link ElementOption} * @return this TouchAction, for chaining. */ - public T moveTo(Position moveToOptions) { + public T moveTo(PointOption moveToOptions) { ActionParameter action = new ActionParameter("moveTo", moveToOptions); parameterBuilder.add(action); return (T) this; @@ -138,11 +135,11 @@ public T moveTo(Position moveToOptions) { * * @param el element to move to. * @return this TouchAction, for chaining. - * @deprecated {@link #moveTo(Position)} instead + * @deprecated {@link #moveTo(PointOption)} instead */ @Deprecated public T moveTo(WebElement el) { - return moveTo(position().withElement(element(el))); + return moveTo(element(el)); } /** @@ -153,11 +150,11 @@ public T moveTo(WebElement el) { * @param x change in x coordinate to move through. * @param y change in y coordinate to move through. * @return this TouchAction, for chaining. - * @deprecated {@link #moveTo(Position)} instead + * @deprecated {@link #moveTo(PointOption)} instead */ @Deprecated public T moveTo(int x, int y) { - return moveTo(position().withPosition(offset(x, y))); + return moveTo(point(x, y)); } /** @@ -167,11 +164,11 @@ public T moveTo(int x, int y) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. - * @deprecated {@link #moveTo(Position)} instead + * @deprecated {@link #moveTo(PointOption)} instead */ @Deprecated public T moveTo(WebElement el, int x, int y) { - return moveTo(position().withElement(element(el, x, y))); + return moveTo(element(el, x, y)); } /** @@ -189,10 +186,10 @@ public T tap(TapOptions tapOptions) { /** * Tap on a position. * - * @param tapOptions see {@link Position} + * @param tapOptions see {@link PointOption} and {@link ElementOption} * @return this TouchAction, for chaining. */ - public T tap(Position tapOptions) { + public T tap(PointOption tapOptions) { ActionParameter action = new ActionParameter("tap", tapOptions); parameterBuilder.add(action); return (T) this; @@ -203,11 +200,11 @@ public T tap(Position tapOptions) { * * @param el element to tap. * @return this TouchAction, for chaining. - * @deprecated use {@link #tap(Position)} instead. + * @deprecated use {@link #tap(PointOption)} instead. */ @Deprecated public T tap(WebElement el) { - return tap(Position.position().withElement(element(el))); + return tap(element(el)); } /** @@ -216,11 +213,11 @@ public T tap(WebElement el) { * @param x x coordinate. * @param y y coordinate. * @return this TouchAction, for chaining. - * @deprecated use {@link #tap(Position)} instead. + * @deprecated use {@link #tap(PointOption)} instead. */ @Deprecated public T tap(int x, int y) { - return (T) tap(Position.position().withPosition(coordinates(x, y))); + return tap(point(x, y)); } /** @@ -230,11 +227,11 @@ public T tap(int x, int y) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. - * @deprecated use {@link #tap(Position)} instead. + * @deprecated use {@link #tap(PointOption)} instead. */ @Deprecated public T tap(WebElement el, int x, int y) { - return tap(Position.position().withElement(element(el, x, y))); + return tap(element(el, x, y)); } /** @@ -295,10 +292,10 @@ public T longPress(LongPressOptions longPressOptions) { /** * Press and hold the at the center of an element until the context menu event has fired. * - * @param longPressOptions see {@link Position}. + * @param longPressOptions see {@link PointOption} and {@link ElementOption}. * @return this TouchAction, for chaining. */ - public T longPress(Position longPressOptions) { + public T longPress(PointOption longPressOptions) { ActionParameter action = new ActionParameter("longPress", longPressOptions); parameterBuilder.add(action); //noinspection unchecked @@ -310,11 +307,11 @@ public T longPress(Position longPressOptions) { * * @param el element to long-press. * @return this TouchAction, for chaining. - * @deprecated use {@link #longPress(Position)} instead + * @deprecated use {@link #longPress(PointOption)} instead */ @Deprecated public T longPress(WebElement el) { - return longPress(Position.position().withElement(element(el))); + return longPress(element(el)); } /** @@ -338,11 +335,11 @@ public T longPress(WebElement el, Duration duration) { * @param x x coordinate. * @param y y coordinate. * @return this TouchAction, for chaining. - * @deprecated use {@link #longPress(Position)} instead + * @deprecated use {@link #longPress(PointOption)} instead */ @Deprecated public T longPress(int x, int y) { - return longPress(Position.position().withPosition(coordinates(x, y))); + return longPress(point(x, y)); } /** @@ -357,8 +354,8 @@ public T longPress(int x, int y) { */ @Deprecated public T longPress(int x, int y, Duration duration) { - return (T) longPress(longPressOptions() - .withDuration(duration).withPosition(coordinates(x, y))); + return longPress(longPressOptions() + .withDuration(duration).withPosition(point(x, y))); } /** @@ -369,11 +366,11 @@ public T longPress(int x, int y, Duration duration) { * @param x x offset. * @param y y offset. * @return this TouchAction, for chaining. - * @deprecated use {@link #longPress(Position)} instead + * @deprecated use {@link #longPress(PointOption)} instead */ @Deprecated public T longPress(WebElement el, int x, int y) { - return longPress(Position.position().withElement(element(el, x, y))); + return longPress(element(el, x, y)); } /** diff --git a/src/main/java/io/appium/java_client/ios/IOSTouchAction.java b/src/main/java/io/appium/java_client/ios/IOSTouchAction.java index f5a09a3a3..aa9736892 100644 --- a/src/main/java/io/appium/java_client/ios/IOSTouchAction.java +++ b/src/main/java/io/appium/java_client/ios/IOSTouchAction.java @@ -20,8 +20,8 @@ import io.appium.java_client.PerformsTouchActions; import io.appium.java_client.TouchAction; +import io.appium.java_client.touch.offset.ElementOption; import io.appium.java_client.touch.offset.PointOption; -import io.appium.java_client.touch.offset.Position; import org.openqa.selenium.WebElement; public class IOSTouchAction extends TouchAction { @@ -37,11 +37,11 @@ public IOSTouchAction(PerformsTouchActions performsTouchActions) { * @param x x offset. * @param y y offset. * @return this IOSTouchAction, for chaining. - * @deprecated use {@link #tap(Position)} with count=2 instead. + * @deprecated use {@link #doubleTap(PointOption)} with count=2 instead. */ @Deprecated public IOSTouchAction doubleTap(WebElement el, int x, int y) { - return doubleTap(Position.position().withElement(element(el, x, y))); + return doubleTap(element(el, x, y)); } /** @@ -49,20 +49,20 @@ public IOSTouchAction doubleTap(WebElement el, int x, int y) { * * @param el element to tap. * @return this IOSTouchAction, for chaining. - * @deprecated use {@link #tap(Position)} with count=2 instead. + * @deprecated use {@link #doubleTap(PointOption)} with count=2 instead. */ @Deprecated public IOSTouchAction doubleTap(WebElement el) { - return doubleTap(Position.position().withElement(element(el))); + return doubleTap(element(el)); } /** * Double taps using coordinates. * - * @param doubleTapOption see {@link Position}. + * @param doubleTapOption see {@link PointOption} and {@link ElementOption}.. * @return self-reference */ - public IOSTouchAction doubleTap(Position doubleTapOption) { + public IOSTouchAction doubleTap(PointOption doubleTapOption) { ActionParameter action = new ActionParameter("doubleTap", doubleTapOption); parameterBuilder.add(action); diff --git a/src/main/java/io/appium/java_client/touch/LongPressOptions.java b/src/main/java/io/appium/java_client/touch/LongPressOptions.java index 355a04b9b..198f476b5 100644 --- a/src/main/java/io/appium/java_client/touch/LongPressOptions.java +++ b/src/main/java/io/appium/java_client/touch/LongPressOptions.java @@ -21,13 +21,11 @@ import static java.util.Optional.ofNullable; import io.appium.java_client.touch.offset.AbstractOptionCombinedWithPosition; -import io.appium.java_client.touch.offset.PointOption; import java.time.Duration; import java.util.Map; -public class LongPressOptions - extends AbstractOptionCombinedWithPosition { +public class LongPressOptions extends AbstractOptionCombinedWithPosition { protected Duration duration = null; /** diff --git a/src/main/java/io/appium/java_client/touch/TapOptions.java b/src/main/java/io/appium/java_client/touch/TapOptions.java index 51bbbe32e..7c4a1e1a0 100644 --- a/src/main/java/io/appium/java_client/touch/TapOptions.java +++ b/src/main/java/io/appium/java_client/touch/TapOptions.java @@ -20,11 +20,10 @@ import static java.util.Optional.ofNullable; import io.appium.java_client.touch.offset.AbstractOptionCombinedWithPosition; -import io.appium.java_client.touch.offset.PointOption; import java.util.Map; -public class TapOptions extends AbstractOptionCombinedWithPosition { +public class TapOptions extends AbstractOptionCombinedWithPosition { private Integer tapsCount = null; /** diff --git a/src/main/java/io/appium/java_client/touch/offset/AbstractOptionCombinedWithPosition.java b/src/main/java/io/appium/java_client/touch/offset/AbstractOptionCombinedWithPosition.java index 22b358a18..a497ab4a8 100644 --- a/src/main/java/io/appium/java_client/touch/offset/AbstractOptionCombinedWithPosition.java +++ b/src/main/java/io/appium/java_client/touch/offset/AbstractOptionCombinedWithPosition.java @@ -6,48 +6,45 @@ import java.util.Map; -public abstract class AbstractOptionCombinedWithPosition, - S extends AbstractPositionOption> - extends ActionOptions> { - private ActionOptions offsetOption; +public abstract class AbstractOptionCombinedWithPosition> + extends ActionOptions> { + private ActionOptions positionOption; /** - * Some actions may require offset. It may be option which contains x,y - offset - * from the left corner of the screen or from the current point on the screen - * or x,y - offset from the left corner of the element. Invocation of this method + * Some actions may require coordinates. Invocation of this method * replaces the result of previous {@link #withElement(ElementOption)} invocation. * - * @param offset required offset option. * + * @param positionOption required coordinates. * * @return self-reference */ - public T withPosition(S offset) { - offsetOption = offset; + public T withPosition(PointOption positionOption) { + this.positionOption = positionOption; return (T) this; } /** * Most of touch action may use position which is relative to some element. In order to unify * this behaviour this method was added. Invocation of this method - * replaces the result of previous {@link #withPosition(AbstractPositionOption)} invocation. + * replaces the result of previous {@link #withPosition(PointOption)} invocation. * * @param element required position which is relative to some element * @return self-reference */ public T withElement(ElementOption element) { - offsetOption = element; + positionOption = element; return (T) this; } protected void verify() { - ofNullable(offsetOption).orElseThrow(() -> - new IllegalArgumentException("Some relative or absolute position should " + ofNullable(positionOption).orElseThrow(() -> + new IllegalArgumentException("Some coordinates or an offset from an element should " + "be defined. Use withPosition or withElement methods")); } @Override public Map build() { final Map result = super.build(); - result.putAll(offsetOption.build()); + result.putAll(positionOption.build()); return result; } } diff --git a/src/main/java/io/appium/java_client/touch/offset/AbstractPositionOption.java b/src/main/java/io/appium/java_client/touch/offset/AbstractPositionOption.java deleted file mode 100644 index 572c6d2a1..000000000 --- a/src/main/java/io/appium/java_client/touch/offset/AbstractPositionOption.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.appium.java_client.touch.offset; - -import io.appium.java_client.touch.ActionOptions; -import org.openqa.selenium.Point; - -public abstract class AbstractPositionOption> extends ActionOptions { - protected Point offset; - - /** - * Defines the offset or coordinates - * from the corresponding action. - * - * @param xOffset is x offset/value. - * @param yOffset is y offset/value. - * @return this instance for chaining. - */ - public abstract T position(int xOffset, int yOffset); -} diff --git a/src/main/java/io/appium/java_client/touch/offset/ElementOption.java b/src/main/java/io/appium/java_client/touch/offset/ElementOption.java index d474b2ada..73c33e5fa 100644 --- a/src/main/java/io/appium/java_client/touch/offset/ElementOption.java +++ b/src/main/java/io/appium/java_client/touch/offset/ElementOption.java @@ -2,15 +2,17 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import static java.lang.String.format; import static java.util.Optional.ofNullable; +import org.openqa.selenium.Point; import org.openqa.selenium.WebElement; import org.openqa.selenium.internal.HasIdentity; import java.util.HashMap; import java.util.Map; -public class ElementOption extends OffsetOption { +public class ElementOption extends PointOption { private String elementId; @@ -23,7 +25,7 @@ public class ElementOption extends OffsetOption { * @return the built option */ public static ElementOption element(WebElement element, int x, int y) { - return new ElementOption().withElement(element).position(x, y); + return new ElementOption().withElement(element).coordinates(x, y); } /** @@ -36,6 +38,19 @@ public static ElementOption element(WebElement element) { return new ElementOption().withElement(element); } + /** + * It defines x and y offset from the upper left corner of an element. + * + * @param xOffset is x value. + * @param yOffset is y value. + * @return self-reference + */ + @Override + public ElementOption coordinates(int xOffset, int yOffset) { + coordinates = new Point(xOffset, yOffset); + return this; + } + /** * This method sets the element as an option. It means that x/y offset is the offset * from the upper left corner of the given element. @@ -64,7 +79,7 @@ public Map build() { final Map result = new HashMap<>(); result.put("element", elementId); - ofNullable(offset).ifPresent(point -> { + ofNullable(coordinates).ifPresent(point -> { result.put("x", point.x); result.put("y", point.y); }); diff --git a/src/main/java/io/appium/java_client/touch/offset/OffsetOption.java b/src/main/java/io/appium/java_client/touch/offset/OffsetOption.java deleted file mode 100644 index a90c297a6..000000000 --- a/src/main/java/io/appium/java_client/touch/offset/OffsetOption.java +++ /dev/null @@ -1,50 +0,0 @@ -package io.appium.java_client.touch.offset; - -import static java.util.Optional.ofNullable; - -import org.openqa.selenium.Point; - -import java.util.Map; - -public class OffsetOption> extends AbstractPositionOption { - - /** - * It creates a built instance of {@link PointOption} which takes x and y relative offsets. - * This is offset from the upper left corner of an element or the position of the previous action. - * - * @param xOffset is x-offset value. - * @param yOffset is y-offset value. - * @return a built option - */ - public static OffsetOption offset(int xOffset, int yOffset) { - return new OffsetOption().position(xOffset, yOffset); - } - - /** - * It defines x and y relative offsets. - * This is offset from the upper left corner of an element or from the position of the previous action. - * - * @param xOffset is x-offset value. - * @param yOffset is y-offset value. - * @return self-reference - */ - @Override - public T position(int xOffset, int yOffset) { - this.offset = new Point(xOffset, yOffset); - return (T) this; - } - - @Override - protected void verify() { - ofNullable(offset).orElseThrow(() -> new IllegalArgumentException( - "Relative X and Y offset values must be defined")); - } - - @Override - public Map build() { - final Map result = super.build(); - result.put("x", offset.x); - result.put("y", offset.y); - return result; - } -} diff --git a/src/main/java/io/appium/java_client/touch/offset/PointOption.java b/src/main/java/io/appium/java_client/touch/offset/PointOption.java index 39676f3ec..57402f188 100644 --- a/src/main/java/io/appium/java_client/touch/offset/PointOption.java +++ b/src/main/java/io/appium/java_client/touch/offset/PointOption.java @@ -4,11 +4,14 @@ import static java.lang.String.format; import static java.util.Optional.ofNullable; +import io.appium.java_client.touch.ActionOptions; import org.openqa.selenium.Point; import java.util.Map; -public class PointOption extends AbstractPositionOption { +public class PointOption> extends ActionOptions { + + protected Point coordinates; private static final String ERROR_MESSAGE_TEMPLATE = "%s coordinate value should be equal or greater than zero"; @@ -20,8 +23,8 @@ public class PointOption extends AbstractPositionOption { * @param yOffset is y value. * @return a built option */ - public static PointOption coordinates(int xOffset, int yOffset) { - return new PointOption().position(xOffset, yOffset); + public static PointOption point(int xOffset, int yOffset) { + return new PointOption().coordinates(xOffset, yOffset); } /** @@ -32,25 +35,24 @@ public static PointOption coordinates(int xOffset, int yOffset) { * @param yOffset is y value. * @return self-reference */ - @Override - public PointOption position(int xOffset, int yOffset) { + public T coordinates(int xOffset, int yOffset) { checkArgument(xOffset >= 0, format(ERROR_MESSAGE_TEMPLATE, "X")); checkArgument(yOffset >= 0, format(ERROR_MESSAGE_TEMPLATE, "Y")); - offset = new Point(xOffset, yOffset); - return this; + coordinates = new Point(xOffset, yOffset); + return (T) this; } @Override protected void verify() { - ofNullable(offset).orElseThrow(() -> new IllegalArgumentException( + ofNullable(coordinates).orElseThrow(() -> new IllegalArgumentException( "Coordinate values must be defined")); } @Override public Map build() { final Map result = super.build(); - result.put("x", offset.x); - result.put("y", offset.y); + result.put("x", coordinates.x); + result.put("y", coordinates.y); return result; } } diff --git a/src/main/java/io/appium/java_client/touch/offset/Position.java b/src/main/java/io/appium/java_client/touch/offset/Position.java deleted file mode 100644 index b22a174c4..000000000 --- a/src/main/java/io/appium/java_client/touch/offset/Position.java +++ /dev/null @@ -1,13 +0,0 @@ -package io.appium.java_client.touch.offset; - -/** - * This is the default superclass of the {@link AbstractOptionCombinedWithPosition} - * @param is the sub type of {@link AbstractPositionOption} which instances should be - * consumed. - */ -public class Position extends AbstractOptionCombinedWithPosition, S> { - - public static Position position() { - return new Position(); - } -} diff --git a/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java b/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java index 69c1e5aad..f7baf466e 100644 --- a/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java +++ b/src/test/java/io/appium/java_client/android/AndroidAbilityToUseSupplierTest.java @@ -2,15 +2,12 @@ import static io.appium.java_client.touch.WaitOptions.waitOptions; import static io.appium.java_client.touch.offset.ElementOption.element; -import static io.appium.java_client.touch.offset.PointOption.coordinates; -import static io.appium.java_client.touch.offset.Position.position; import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertNotEquals; import io.appium.java_client.MobileElement; import io.appium.java_client.functions.ActionSupplier; -import io.appium.java_client.touch.offset.PointOption; -import io.appium.java_client.touch.offset.Position; +import io.appium.java_client.touch.offset.ElementOption; import org.junit.Test; import org.openqa.selenium.Point; @@ -27,10 +24,8 @@ public class AndroidAbilityToUseSupplierTest extends BaseAndroidTest { Point location = gallery.getLocation(); Point center = gallery.getCenter(); - Position pressOption = Position.position() - .withElement(element(images.get(2),-10,center.y - location.y)); - - Position moveOption = position().withElement(element(gallery, 10,center.y - location.y)); + ElementOption pressOption = element(images.get(2),-10,center.y - location.y); + ElementOption moveOption = element(gallery, 10,center.y - location.y); return new AndroidTouchAction(driver) .press(pressOption) @@ -41,13 +36,11 @@ public class AndroidAbilityToUseSupplierTest extends BaseAndroidTest { private final ActionSupplier verticalSwiping = () -> new AndroidTouchAction(driver) - .press(Position.position() - .withElement(element(driver.findElementByAccessibilityId("Gallery")))) + .press(element(driver.findElementByAccessibilityId("Gallery"))) .waitAction(waitOptions(ofSeconds(2))) - .moveTo(position() - .withElement(element(driver.findElementByAccessibilityId("Auto Complete")))) + .moveTo(element(driver.findElementByAccessibilityId("Auto Complete"))) .release(); @Test public void horizontalSwipingWithSupplier() throws Exception { diff --git a/src/test/java/io/appium/java_client/android/AndroidTouchTest.java b/src/test/java/io/appium/java_client/android/AndroidTouchTest.java index 815444802..a562f273a 100644 --- a/src/test/java/io/appium/java_client/android/AndroidTouchTest.java +++ b/src/test/java/io/appium/java_client/android/AndroidTouchTest.java @@ -4,8 +4,7 @@ import static io.appium.java_client.touch.TapOptions.tapOptions; import static io.appium.java_client.touch.WaitOptions.waitOptions; import static io.appium.java_client.touch.offset.ElementOption.element; -import static io.appium.java_client.touch.offset.PointOption.coordinates; -import static io.appium.java_client.touch.offset.Position.position; +import static io.appium.java_client.touch.offset.PointOption.point; import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; @@ -13,8 +12,6 @@ import io.appium.java_client.MobileElement; import io.appium.java_client.MultiTouchAction; import io.appium.java_client.TouchAction; -import io.appium.java_client.touch.offset.PointOption; -import io.appium.java_client.touch.offset.Position; import org.junit.Before; import org.junit.Test; import org.openqa.selenium.By; @@ -40,8 +37,8 @@ public void setUp() throws Exception { assertEquals("Drag text not empty", "", dragText.getText()); TouchAction dragNDrop = new TouchAction(driver) - .longPress(Position.position().withElement(element(dragDot1))) - .moveTo(position().withElement(element(dragDot3))) + .longPress(element(dragDot1)) + .moveTo(element(dragDot3)) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -60,7 +57,7 @@ public void setUp() throws Exception { .longPress(longPressOptions() .withElement(element(dragDot1)) .withDuration(ofSeconds(2))) - .moveTo(position().withElement(element(dragDot3))) + .moveTo(element(dragDot3)) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -79,8 +76,8 @@ public void setUp() throws Exception { Point center2 = dragDot3.getCenter(); TouchAction dragNDrop = new TouchAction(driver) - .longPress(Position.position().withPosition(coordinates(center1.x, center1.y))) - .moveTo(position().withPosition(coordinates(center2.x, center2.y))) + .longPress(point(center1.x, center1.y)) + .moveTo(point(center2.x, center2.y)) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -100,10 +97,9 @@ public void setUp() throws Exception { TouchAction dragNDrop = new TouchAction(driver) .longPress(longPressOptions() - .withPosition(coordinates(center1.x, center1.y)) + .withPosition(point(center1.x, center1.y)) .withDuration(ofSeconds(2))) - .moveTo(position() - .withPosition(coordinates(center2.x, center2.y))) + .moveTo(point(center2.x, center2.y)) .release(); dragNDrop.perform(); assertNotEquals("Drag text empty", "", dragText.getText()); @@ -115,8 +111,7 @@ public void setUp() throws Exception { Point point = driver.findElementById("io.appium.android.apis:id/button_toggle").getLocation(); new TouchAction(driver) - .press(Position.position() - .withPosition(coordinates(point.x + 20, point.y + 30))) + .press(point(point.x + 20, point.y + 30)) .waitAction(waitOptions(ofSeconds(1))) .release() .perform(); @@ -128,8 +123,7 @@ public void setUp() throws Exception { Activity activity = new Activity("io.appium.android.apis", ".view.Buttons1"); driver.startActivity(activity); new TouchAction(driver) - .press(Position.position() - .withElement(element(driver.findElementById("io.appium.android.apis:id/button_toggle")))) + .press(element(driver.findElementById("io.appium.android.apis:id/button_toggle"))) .waitAction(waitOptions(ofSeconds(1))) .release() .perform(); @@ -165,9 +159,8 @@ public void setUp() throws Exception { Point center1 = driver.findElementById("io.appium.android.apis:id/start").getCenter(); TouchAction startStop = new TouchAction(driver) - .tap(Position.position().withPosition(coordinates(center1.x, center1.y))) - .tap(Position.position() - .withElement(element(driver.findElementById("io.appium.android.apis:id/stop"), 5, 5))); + .tap(point(center1.x, center1.y)) + .tap(element(driver.findElementById("io.appium.android.apis:id/stop"), 5, 5)); startStop.perform(); String time = chronometer.getText(); @@ -188,10 +181,9 @@ public void setUp() throws Exception { Point center = gallery.getCenter(); TouchAction swipe = new TouchAction(driver) - .press(Position.position() - .withElement(element(images.get(2),-10, center.y - location.y))) + .press(element(images.get(2),-10, center.y - location.y)) .waitAction(waitOptions(ofSeconds(2))) - .moveTo(position().withElement(element(gallery,10,center.y - location.y))) + .moveTo(element(gallery,10,center.y - location.y)) .release(); swipe.perform(); assertNotEquals(originalImageCount, gallery @@ -202,8 +194,7 @@ public void setUp() throws Exception { Activity activity = new Activity("io.appium.android.apis", ".view.Buttons1"); driver.startActivity(activity); TouchAction press = new TouchAction(driver) - .press(Position.position() - .withElement(element(driver.findElementById("io.appium.android.apis:id/button_toggle")))) + .press(element(driver.findElementById("io.appium.android.apis:id/button_toggle"))) .waitAction(waitOptions(ofSeconds(1))) .release(); new MultiTouchAction(driver) diff --git a/src/test/java/io/appium/java_client/ios/IOSTouchTest.java b/src/test/java/io/appium/java_client/ios/IOSTouchTest.java index d79987c7c..e8daa149f 100644 --- a/src/test/java/io/appium/java_client/ios/IOSTouchTest.java +++ b/src/test/java/io/appium/java_client/ios/IOSTouchTest.java @@ -4,7 +4,6 @@ import static io.appium.java_client.touch.TapOptions.tapOptions; import static io.appium.java_client.touch.WaitOptions.waitOptions; import static io.appium.java_client.touch.offset.ElementOption.element; -import static io.appium.java_client.touch.offset.Position.position; import static java.time.Duration.ofSeconds; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -13,8 +12,7 @@ import io.appium.java_client.MobileElement; import io.appium.java_client.MultiTouchAction; import io.appium.java_client.TouchAction; -import io.appium.java_client.touch.offset.PointOption; -import io.appium.java_client.touch.offset.Position; +import io.appium.java_client.touch.offset.ElementOption; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; @@ -42,9 +40,8 @@ public void tapTest() { MobileElement slider = driver.findElementByClassName("UIASlider"); Dimension size = slider.getSize(); - Position press = Position.position() - .withElement(element(slider, size.width / 2 + 2, size.height / 2)); - Position move = position().withElement(element(slider, 1, size.height / 2)); + ElementOption press = element(slider, size.width / 2 + 2, size.height / 2); + ElementOption move = element(slider, 1, size.height / 2); TouchAction swipe = new TouchAction(driver).press(press) .waitAction(waitOptions(ofSeconds(2))) diff --git a/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java b/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java index adbed9c7a..03fd20358 100644 --- a/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java +++ b/src/test/java/io/appium/java_client/ios/XCUIAutomationTest.java @@ -25,8 +25,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; -import io.appium.java_client.touch.offset.PointOption; -import io.appium.java_client.touch.offset.Position; import org.junit.After; import org.junit.Test; import org.openqa.selenium.DeviceRotation; @@ -75,7 +73,7 @@ public class XCUIAutomationTest extends AppXCUITTest { firstField.sendKeys("2"); IOSTouchAction iosTouchAction = new IOSTouchAction(driver); - iosTouchAction.doubleTap(Position.position().withElement(element(firstField))); + iosTouchAction.doubleTap(element(firstField)); IOSElement editingMenu = driver.findElementByClassName("UIAEditingMenu"); assertNotNull(editingMenu); } diff --git a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java index 205b07c6f..fc7093dde 100644 --- a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java +++ b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java @@ -5,8 +5,7 @@ import static io.appium.java_client.touch.TapOptions.tapOptions; import static io.appium.java_client.touch.WaitOptions.waitOptions; import static io.appium.java_client.touch.offset.ElementOption.element; -import static io.appium.java_client.touch.offset.PointOption.coordinates; -import static io.appium.java_client.touch.offset.Position.position; +import static io.appium.java_client.touch.offset.PointOption.point; import static java.time.Duration.ofMillis; import static java.time.Duration.ofSeconds; import static junit.framework.TestCase.fail; @@ -29,8 +28,8 @@ public class TouchOptionsTests { private static final WebElement DUMMY_ELEMENT = new DummyElement(); @Test(expected = IllegalArgumentException.class) - public void invalidEmptyPositionOptionsShouldFailOnBuild() throws Exception { - position().build(); + public void invalidEmptyPointOptionsShouldFailOnBuild() throws Exception { + new PointOption().build(); fail("The exception throwing was expected"); } @@ -44,9 +43,9 @@ public void invalidEmptyElementOptionsShouldFailOnBuild() throws Exception { public void invalidOptionsArgumentsShouldFailOnAltering() throws Exception { final List invalidOptions = new ArrayList<>(); invalidOptions.add(() -> waitOptions(ofMillis(-1))); - invalidOptions.add(() -> new ElementOption().position(0, 0).withElement(null)); - invalidOptions.add(() -> new PointOption().position(0, -1)); - invalidOptions.add(() -> new PointOption().position(-1, 0)); + invalidOptions.add(() -> new ElementOption().coordinates(0, 0).withElement(null)); + invalidOptions.add(() -> new PointOption().coordinates(0, -1)); + invalidOptions.add(() -> new PointOption().coordinates(-1, 0)); invalidOptions.add(() -> new WaitOptions().withDuration(null)); invalidOptions.add(() -> tapOptions().withTapsCount(-1)); invalidOptions.add(() -> longPressOptions().withDuration(null)); @@ -59,7 +58,7 @@ public void invalidOptionsArgumentsShouldFailOnAltering() throws Exception { @Test public void longPressOptionsShouldBuildProperly() throws Exception { final Map actualOpts = longPressOptions() - .withElement(element(DUMMY_ELEMENT).position(0, 0)) + .withElement(element(DUMMY_ELEMENT).coordinates(0, 0)) .withDuration(ofMillis(1)) .build(); final Map expectedOpts = new HashMap<>(); @@ -74,7 +73,7 @@ public void longPressOptionsShouldBuildProperly() throws Exception { @Test public void tapOptionsShouldBuildProperly() throws Exception { final Map actualOpts = tapOptions() - .withPosition(coordinates(0, 0)) + .withPosition(point(0, 0)) .withTapsCount(2) .build(); final Map expectedOpts = new HashMap<>(); From 52492ec423979c51a7d08228c59d9caefd340eac Mon Sep 17 00:00:00 2001 From: Sergey Tikhomirov Date: Sat, 11 Nov 2017 22:38:42 +0300 Subject: [PATCH 14/14] The addition to the #756. The fixing out of minor issues: - the `coordinates` method was renamed to `withCoordinates` - removal of unused imports from ElementOption --- .../io/appium/java_client/touch/offset/ElementOption.java | 5 ++--- .../io/appium/java_client/touch/offset/PointOption.java | 4 ++-- .../io/appium/java_client/touch/TouchOptionsTests.java | 8 ++++---- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/java/io/appium/java_client/touch/offset/ElementOption.java b/src/main/java/io/appium/java_client/touch/offset/ElementOption.java index 73c33e5fa..0840ea077 100644 --- a/src/main/java/io/appium/java_client/touch/offset/ElementOption.java +++ b/src/main/java/io/appium/java_client/touch/offset/ElementOption.java @@ -2,7 +2,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import static java.lang.String.format; import static java.util.Optional.ofNullable; import org.openqa.selenium.Point; @@ -25,7 +24,7 @@ public class ElementOption extends PointOption { * @return the built option */ public static ElementOption element(WebElement element, int x, int y) { - return new ElementOption().withElement(element).coordinates(x, y); + return new ElementOption().withElement(element).withCoordinates(x, y); } /** @@ -46,7 +45,7 @@ public static ElementOption element(WebElement element) { * @return self-reference */ @Override - public ElementOption coordinates(int xOffset, int yOffset) { + public ElementOption withCoordinates(int xOffset, int yOffset) { coordinates = new Point(xOffset, yOffset); return this; } diff --git a/src/main/java/io/appium/java_client/touch/offset/PointOption.java b/src/main/java/io/appium/java_client/touch/offset/PointOption.java index 57402f188..9eeaaecd9 100644 --- a/src/main/java/io/appium/java_client/touch/offset/PointOption.java +++ b/src/main/java/io/appium/java_client/touch/offset/PointOption.java @@ -24,7 +24,7 @@ public class PointOption> extends ActionOptions { * @return a built option */ public static PointOption point(int xOffset, int yOffset) { - return new PointOption().coordinates(xOffset, yOffset); + return new PointOption().withCoordinates(xOffset, yOffset); } /** @@ -35,7 +35,7 @@ public static PointOption point(int xOffset, int yOffset) { * @param yOffset is y value. * @return self-reference */ - public T coordinates(int xOffset, int yOffset) { + public T withCoordinates(int xOffset, int yOffset) { checkArgument(xOffset >= 0, format(ERROR_MESSAGE_TEMPLATE, "X")); checkArgument(yOffset >= 0, format(ERROR_MESSAGE_TEMPLATE, "Y")); coordinates = new Point(xOffset, yOffset); diff --git a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java index fc7093dde..9822b0c9e 100644 --- a/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java +++ b/src/test/java/io/appium/java_client/touch/TouchOptionsTests.java @@ -43,9 +43,9 @@ public void invalidEmptyElementOptionsShouldFailOnBuild() throws Exception { public void invalidOptionsArgumentsShouldFailOnAltering() throws Exception { final List invalidOptions = new ArrayList<>(); invalidOptions.add(() -> waitOptions(ofMillis(-1))); - invalidOptions.add(() -> new ElementOption().coordinates(0, 0).withElement(null)); - invalidOptions.add(() -> new PointOption().coordinates(0, -1)); - invalidOptions.add(() -> new PointOption().coordinates(-1, 0)); + invalidOptions.add(() -> new ElementOption().withCoordinates(0, 0).withElement(null)); + invalidOptions.add(() -> new PointOption().withCoordinates(0, -1)); + invalidOptions.add(() -> new PointOption().withCoordinates(-1, 0)); invalidOptions.add(() -> new WaitOptions().withDuration(null)); invalidOptions.add(() -> tapOptions().withTapsCount(-1)); invalidOptions.add(() -> longPressOptions().withDuration(null)); @@ -58,7 +58,7 @@ public void invalidOptionsArgumentsShouldFailOnAltering() throws Exception { @Test public void longPressOptionsShouldBuildProperly() throws Exception { final Map actualOpts = longPressOptions() - .withElement(element(DUMMY_ELEMENT).coordinates(0, 0)) + .withElement(element(DUMMY_ELEMENT).withCoordinates(0, 0)) .withDuration(ofMillis(1)) .build(); final Map expectedOpts = new HashMap<>();