diff --git a/docs/modules/plugins/pages/plugin-mobile-app.adoc b/docs/modules/plugins/pages/plugin-mobile-app.adoc
index 05cd791826..7cb54f5d16 100644
--- a/docs/modules/plugins/pages/plugin-mobile-app.adoc
+++ b/docs/modules/plugins/pages/plugin-mobile-app.adoc
@@ -436,6 +436,9 @@ When I clear field located `accessibilityId(username)`
Swipes to an element in either UP, DOWN, LEFT, or RIGHT direction with the specified swipe duration
+[INFO]
+The step takes into account current context. If you need to perform swipe on the element, you need to switch the context to this element.
+
==== *_Wording_*
[source,gherkin]
@@ -467,6 +470,16 @@ When I swipe UP to element located `accessibilityId(end-of-screen)` with duratio
Then number of elements found by `accessibilityId(end-of-screen)` is equal to `1`
----
+.Swipe context element.story
+[source,gherkin]
+----
+Scenario: Switch slides
+When I change context to element located `accessibilityId(carousel)`
+Then number of elements found by `accessibilityId(slide 2)` is equal to `0`
+When I swipe LEFT to element located `accessibilityId(slide 2)` with duration PT1S
+Then number of elements found by `accessibilityId(slide 2)` is equal to `1`
+----
+
=== Upload a file to a device
==== *_Info_*
diff --git a/vividus-plugin-mobile-app/src/main/java/org/vividus/bdd/mobileapp/model/SwipeDirection.java b/vividus-plugin-mobile-app/src/main/java/org/vividus/bdd/mobileapp/model/SwipeDirection.java
index d4a2b6fc1e..644fce3d02 100644
--- a/vividus-plugin-mobile-app/src/main/java/org/vividus/bdd/mobileapp/model/SwipeDirection.java
+++ b/vividus-plugin-mobile-app/src/main/java/org/vividus/bdd/mobileapp/model/SwipeDirection.java
@@ -17,6 +17,8 @@
package org.vividus.bdd.mobileapp.model;
import org.openqa.selenium.Dimension;
+import org.openqa.selenium.Point;
+import org.openqa.selenium.Rectangle;
import org.vividus.bdd.mobileapp.configuration.MobileApplicationConfiguration;
public enum SwipeDirection
@@ -24,60 +26,68 @@ public enum SwipeDirection
UP
{
@Override
- public SwipeCoordinates calculateCoordinates(Dimension dimension,
+ public SwipeCoordinates calculateCoordinates(Rectangle swipeArea,
MobileApplicationConfiguration mobileApplicationConfiguration)
{
- int indent = dimension.getHeight() / VERTICAL_INDENT_COEFFICIENT;
- return createCoordinates(dimension.getHeight() - indent, indent, dimension.getWidth(),
- mobileApplicationConfiguration.getSwipeVerticalXPosition());
+ int indent = swipeArea.getHeight() / VERTICAL_INDENT_COEFFICIENT;
+ return createCoordinates(swipeArea.getHeight() - indent, indent, swipeArea.getWidth(),
+ mobileApplicationConfiguration.getSwipeVerticalXPosition(), swipeArea.getPoint());
}
},
DOWN
{
@Override
- public SwipeCoordinates calculateCoordinates(Dimension dimension,
+ public SwipeCoordinates calculateCoordinates(Rectangle swipeArea,
MobileApplicationConfiguration mobileApplicationConfiguration)
{
- int indent = dimension.getHeight() / VERTICAL_INDENT_COEFFICIENT;
- return createCoordinates(indent, dimension.getHeight() - indent, dimension.getWidth(),
- mobileApplicationConfiguration.getSwipeVerticalXPosition());
+ int indent = swipeArea.getHeight() / VERTICAL_INDENT_COEFFICIENT;
+ return createCoordinates(indent, swipeArea.getHeight() - indent, swipeArea.getWidth(),
+ mobileApplicationConfiguration.getSwipeVerticalXPosition(), swipeArea.getPoint());
}
},
LEFT
{
@Override
- public SwipeCoordinates calculateCoordinates(Dimension dimension,
+ public SwipeCoordinates calculateCoordinates(Rectangle swipeArea,
MobileApplicationConfiguration mobileApplicationConfiguration)
{
- int indent = dimension.getWidth() / HORIZONTAL_INDENT_COEFFICIENT;
- int y = calculateCoordinate(dimension.getHeight(),
+ int indent = swipeArea.getWidth() / HORIZONTAL_INDENT_COEFFICIENT;
+ int y = calculateCoordinate(swipeArea.getHeight(),
mobileApplicationConfiguration.getSwipeHorizontalYPosition());
- return new SwipeCoordinates(dimension.getWidth() - indent, y, indent, y);
+ return createAdjustedCoordinates(swipeArea.getWidth() - indent, y, indent, y, swipeArea.getPoint());
}
},
RIGHT
{
@Override
- public SwipeCoordinates calculateCoordinates(Dimension dimension,
+ public SwipeCoordinates calculateCoordinates(Rectangle swipeArea,
MobileApplicationConfiguration mobileApplicationConfiguration)
{
+ Dimension dimension = swipeArea.getDimension();
+ Point point = swipeArea.getPoint();
int indent = dimension.getWidth() / HORIZONTAL_INDENT_COEFFICIENT;
int y = calculateCoordinate(dimension.getHeight(),
mobileApplicationConfiguration.getSwipeHorizontalYPosition());
- return new SwipeCoordinates(indent, y, dimension.getWidth() - indent, y);
+ return createAdjustedCoordinates(indent, y, dimension.getWidth() - indent, y, point);
}
};
private static final int VERTICAL_INDENT_COEFFICIENT = 5;
private static final int HORIZONTAL_INDENT_COEFFICIENT = 8;
- public abstract SwipeCoordinates calculateCoordinates(Dimension dimension,
+ public abstract SwipeCoordinates calculateCoordinates(Rectangle swipeArea,
MobileApplicationConfiguration mobileApplicationConfiguration);
- public static SwipeCoordinates createCoordinates(int startY, int endY, int width, int xOffsetPercentage)
+ public static SwipeCoordinates createCoordinates(int startY, int endY, int width, int xOffsetPercentage,
+ Point point)
{
int x = calculateCoordinate(width, xOffsetPercentage);
- return new SwipeCoordinates(x, startY, x, endY);
+ return createAdjustedCoordinates(x, startY, x, endY, point);
+ }
+
+ private static SwipeCoordinates createAdjustedCoordinates(int startX, int startY, int endX, int endY, Point point)
+ {
+ return new SwipeCoordinates(startX + point.x, startY + point.y, endX + point.getX(), endY + point.getY());
}
@SuppressWarnings("MagicNumber")
diff --git a/vividus-plugin-mobile-app/src/main/java/org/vividus/bdd/mobileapp/steps/TouchSteps.java b/vividus-plugin-mobile-app/src/main/java/org/vividus/bdd/mobileapp/steps/TouchSteps.java
index f9bc6507fc..d0972de645 100644
--- a/vividus-plugin-mobile-app/src/main/java/org/vividus/bdd/mobileapp/steps/TouchSteps.java
+++ b/vividus-plugin-mobile-app/src/main/java/org/vividus/bdd/mobileapp/steps/TouchSteps.java
@@ -20,8 +20,12 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
+import java.util.function.Supplier;
import org.jbehave.core.annotations.When;
+import org.openqa.selenium.Point;
+import org.openqa.selenium.Rectangle;
+import org.openqa.selenium.SearchContext;
import org.openqa.selenium.WebElement;
import org.vividus.bdd.mobileapp.model.SwipeDirection;
import org.vividus.bdd.monitor.TakeScreenshotOnFailure;
@@ -31,6 +35,7 @@
import org.vividus.selenium.manager.GenericWebDriverManager;
import org.vividus.ui.action.ISearchActions;
import org.vividus.ui.action.search.Locator;
+import org.vividus.ui.context.IUiContext;
@TakeScreenshotOnFailure
public class TouchSteps
@@ -42,14 +47,16 @@ public class TouchSteps
private final IBaseValidations baseValidations;
private final ISearchActions searchActions;
private final GenericWebDriverManager genericWebDriverManager;
+ private final IUiContext uiContext;
public TouchSteps(TouchActions touchActions, IBaseValidations baseValidations,
- ISearchActions searchActions, GenericWebDriverManager genericWebDriverManager)
+ ISearchActions searchActions, GenericWebDriverManager genericWebDriverManager, IUiContext uiContext)
{
this.touchActions = touchActions;
this.baseValidations = baseValidations;
this.searchActions = searchActions;
this.genericWebDriverManager = genericWebDriverManager;
+ this.uiContext = uiContext;
}
/**
@@ -89,6 +96,8 @@ public void tapByLocator(Locator locator)
/**
* Swipes to element in direction direction with duration duration
+ * The step takes into account current context. If you need to perform swipe on the element,
+ * you need to switch the context to this element.
* @param direction direction to swipe, either UP or DOWN
* @param locator locator to find an element
* @param swipeDuration swipe duration in ISO 8601 format
@@ -97,44 +106,54 @@ public void tapByLocator(Locator locator)
public void swipeToElement(SwipeDirection direction, Locator locator, Duration swipeDuration)
{
locator.getSearchParameters().setWaitForElement(false);
-
+ Supplier swipeArea = createSwipeArea();
List elements = new ArrayList<>(searchActions.findElements(locator));
if (elements.isEmpty())
{
- touchActions.swipeUntil(direction, swipeDuration, () ->
+ touchActions.swipeUntil(direction, swipeDuration, swipeArea.get(), () ->
{
elements.addAll(searchActions.findElements(locator));
return !elements.isEmpty();
});
}
-
if (baseValidations.assertElementsNumber(String.format("The element by locator %s exists", locator), elements,
ComparisonRule.EQUAL_TO, 1) && (SwipeDirection.UP == direction || SwipeDirection.DOWN == direction))
{
- adjustVerticalPosition(elements.get(0), swipeDuration);
+ adjustVerticalPosition(elements.get(0), swipeArea.get(), swipeDuration);
+ }
+ }
+
+ private Supplier createSwipeArea()
+ {
+ SearchContext searchContext = uiContext.getSearchContext();
+ if (searchContext instanceof WebElement)
+ {
+ WebElement contextElement = (WebElement) searchContext;
+ return contextElement::getRect;
}
+ return () -> new Rectangle(new Point(0, 0), genericWebDriverManager.getSize());
}
- private void adjustVerticalPosition(WebElement element, Duration swipeDuration)
+ private void adjustVerticalPosition(WebElement element, Rectangle swipeArea, Duration swipeDuration)
{
- int windowSizeHeight = genericWebDriverManager.getSize().getHeight();
- int windowCenterY = windowSizeHeight / 2;
+ int swipeAreaSizeHeight = swipeArea.getHeight();
+ int swipeAreaCenterY = swipeAreaSizeHeight / 2;
int elementTopCoordinateY = element.getLocation().getY();
- int bottomVisibilityIndent = (int) (VISIBILITY_BOTTOM_INDENT_COEFFICIENT * windowSizeHeight);
- int visibilityY = windowSizeHeight - bottomVisibilityIndent;
+ int bottomVisibilityIndent = (int) (VISIBILITY_BOTTOM_INDENT_COEFFICIENT * swipeAreaSizeHeight);
+ int visibilityY = swipeAreaSizeHeight - bottomVisibilityIndent;
if (elementTopCoordinateY > visibilityY)
{
- touchActions.performVerticalSwipe(windowCenterY, windowCenterY - (elementTopCoordinateY - visibilityY),
- swipeDuration);
+ touchActions.performVerticalSwipe(swipeAreaCenterY,
+ swipeAreaCenterY - (elementTopCoordinateY - visibilityY), swipeArea, swipeDuration);
return;
}
- int topVisibilityIndent = (int) (VISIBILITY_TOP_INDENT_COEFFICIENT * windowSizeHeight);
+ int topVisibilityIndent = (int) (VISIBILITY_TOP_INDENT_COEFFICIENT * swipeAreaSizeHeight);
if (elementTopCoordinateY < topVisibilityIndent)
{
- touchActions.performVerticalSwipe(windowCenterY,
- windowCenterY + topVisibilityIndent - elementTopCoordinateY, swipeDuration);
+ touchActions.performVerticalSwipe(swipeAreaCenterY,
+ swipeAreaCenterY + topVisibilityIndent - elementTopCoordinateY, swipeArea, swipeDuration);
}
}
diff --git a/vividus-plugin-mobile-app/src/main/java/org/vividus/mobileapp/action/TouchActions.java b/vividus-plugin-mobile-app/src/main/java/org/vividus/mobileapp/action/TouchActions.java
index f69dc775b7..5f37d20fce 100644
--- a/vividus-plugin-mobile-app/src/main/java/org/vividus/mobileapp/action/TouchActions.java
+++ b/vividus-plugin-mobile-app/src/main/java/org/vividus/mobileapp/action/TouchActions.java
@@ -29,6 +29,7 @@
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;
+import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebElement;
import org.vividus.bdd.mobileapp.configuration.MobileApplicationConfiguration;
@@ -131,11 +132,13 @@ private TouchAction> buildTapAction(WebElement element, BiConsumerthe end of mobile scroll view is reached
* the swipe limit is exceeded
*
- * @param direction direction to swipe, either UP or DOWN
+ * @param direction direction to swipe, either UP or DOWN
* @param swipeDuration duration between a pointer moves from the start to the end of the swipe coordinates
+ * @param swipeArea the area to execute the swipe
* @param stopCondition condition to stop swiping
*/
- public void swipeUntil(SwipeDirection direction, Duration swipeDuration, BooleanSupplier stopCondition)
+ public void swipeUntil(SwipeDirection direction, Duration swipeDuration, Rectangle swipeArea,
+ BooleanSupplier stopCondition)
{
/*
* mobile:scroll
@@ -156,8 +159,7 @@ public void swipeUntil(SwipeDirection direction, Duration swipeDuration, Boolean
Duration stabilizationDuration = mobileApplicationConfiguration.getSwipeStabilizationDuration();
int swipeLimit = mobileApplicationConfiguration.getSwipeLimit();
BufferedImage previousFrame = null;
- SwipeCoordinates swipeCoordinates = direction.calculateCoordinates(genericWebDriverManager.getSize(),
- mobileApplicationConfiguration);
+ SwipeCoordinates swipeCoordinates = direction.calculateCoordinates(swipeArea, mobileApplicationConfiguration);
for (int count = 0; count <= swipeLimit; count++)
{
swipe(swipeCoordinates, swipeDuration);
@@ -185,14 +187,15 @@ public void swipeUntil(SwipeDirection direction, Duration swipeDuration, Boolean
/**
* Performs vertical swipe from startY to endY with swipeDuration
*
- * @param startY start Y coordinate
- * @param endY end Y coordinate
+ * @param startY start Y coordinate
+ * @param endY end Y coordinate
+ * @param swipeArea the area to execute the swipe
* @param swipeDuration swipe duration in ISO 8601 format
*/
- public void performVerticalSwipe(int startY, int endY, Duration swipeDuration)
+ public void performVerticalSwipe(int startY, int endY, Rectangle swipeArea, Duration swipeDuration)
{
- swipe(SwipeDirection.createCoordinates(startY, endY, genericWebDriverManager.getSize().getWidth(),
- mobileApplicationConfiguration.getSwipeVerticalXPosition()), swipeDuration);
+ swipe(SwipeDirection.createCoordinates(startY, endY, swipeArea.getWidth(),
+ mobileApplicationConfiguration.getSwipeVerticalXPosition(), swipeArea.getPoint()), swipeDuration);
}
private BufferedImage takeScreenshot()
diff --git a/vividus-plugin-mobile-app/src/test/java/io/appium/java_client/TouchActionsTests.java b/vividus-plugin-mobile-app/src/test/java/io/appium/java_client/TouchActionsTests.java
index 89a78f0557..11b1666be0 100644
--- a/vividus-plugin-mobile-app/src/test/java/io/appium/java_client/TouchActionsTests.java
+++ b/vividus-plugin-mobile-app/src/test/java/io/appium/java_client/TouchActionsTests.java
@@ -48,6 +48,7 @@
import org.mockito.junit.jupiter.MockitoExtension;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;
+import org.openqa.selenium.Rectangle;
import org.openqa.selenium.remote.RemoteWebElement;
import org.vividus.bdd.mobileapp.configuration.MobileApplicationConfiguration;
import org.vividus.bdd.mobileapp.model.SwipeDirection;
@@ -78,6 +79,7 @@ class TouchActionsTests
private static final String WHITE_IMAGE = "white.png";
private static final String ELEMENT_ID = "elementId";
private static final Dimension DIMENSION = new Dimension(600, 800);
+ private static final Rectangle SWIPE_AREA = new Rectangle(new Point(0, 0), DIMENSION);
@Spy private final MobileApplicationConfiguration mobileApplicationConfiguration =
new MobileApplicationConfiguration(Duration.ZERO, 5, 50, 0);
@@ -181,7 +183,7 @@ void shouldSwipeUntilConditionIsTrue() throws IOException
when(screenshotTaker.takeViewportScreenshot()).thenReturn(getImage(BLACK_IMAGE))
.thenReturn(getImage(WHITE_IMAGE));
- touchActions.swipeUntil(SwipeDirection.UP, DURATION, stopCondition);
+ touchActions.swipeUntil(SwipeDirection.UP, DURATION, SWIPE_AREA, stopCondition);
verifySwipe(3);
verifyConfiguration();
@@ -200,7 +202,7 @@ void shouldNotExceedSwipeLimit() throws IOException
.thenReturn(getImage(WHITE_IMAGE));
IllegalStateException exception = assertThrows(IllegalStateException.class,
- () -> touchActions.swipeUntil(SwipeDirection.UP, DURATION, stopCondition));
+ () -> touchActions.swipeUntil(SwipeDirection.UP, DURATION, SWIPE_AREA, stopCondition));
assertEquals("Swiping is stopped due to exceeded swipe limit '5'", exception.getMessage());
verifySwipe(6);
@@ -217,7 +219,7 @@ void shouldStopSwipeOnceEndOfPageIsReached() throws IOException
.thenReturn(getImage(BLACK_IMAGE))
.thenReturn(getImage(BLACK_IMAGE));
- touchActions.swipeUntil(SwipeDirection.UP, DURATION, stopCondition);
+ touchActions.swipeUntil(SwipeDirection.UP, DURATION, SWIPE_AREA, stopCondition);
verifySwipe(4);
verifyConfiguration();
@@ -233,7 +235,7 @@ void shouldWrapIOException() throws IOException
doThrow(exception).when(screenshotTaker).takeViewportScreenshot();
UncheckedIOException wrapper = assertThrows(UncheckedIOException.class,
- () -> touchActions.swipeUntil(SwipeDirection.UP, DURATION, stopCondition));
+ () -> touchActions.swipeUntil(SwipeDirection.UP, DURATION, SWIPE_AREA, stopCondition));
assertEquals(exception, wrapper.getCause());
verifySwipe(1);
@@ -243,8 +245,7 @@ void shouldWrapIOException() throws IOException
@Test
void shouldPerformVerticalSwipe()
{
- when(genericWebDriverManager.getSize()).thenReturn(DIMENSION);
- touchActions.performVerticalSwipe(640, 160, DURATION);
+ touchActions.performVerticalSwipe(640, 160, SWIPE_AREA, DURATION);
verifySwipe(1);
}
diff --git a/vividus-plugin-mobile-app/src/test/java/org/vividus/bdd/mobileapp/model/SwipeDirectionTests.java b/vividus-plugin-mobile-app/src/test/java/org/vividus/bdd/mobileapp/model/SwipeDirectionTests.java
index 6cad146744..029e93c85a 100644
--- a/vividus-plugin-mobile-app/src/test/java/org/vividus/bdd/mobileapp/model/SwipeDirectionTests.java
+++ b/vividus-plugin-mobile-app/src/test/java/org/vividus/bdd/mobileapp/model/SwipeDirectionTests.java
@@ -24,40 +24,52 @@
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;
+import org.openqa.selenium.Rectangle;
import org.vividus.bdd.mobileapp.configuration.MobileApplicationConfiguration;
class SwipeDirectionTests
{
@CsvSource({
- "UP, 1436, 358, 50, 540",
- "DOWN, 358 , 1436, 0, 1",
- "DOWN, 358 , 1436, 100, 1079"
+ "UP, 1436, 358, 0, 0, 50, 540",
+ "DOWN, 358 , 1436, 0, 0, 0, 1",
+ "DOWN, 358 , 1436, 0, 0, 100, 1079",
+ "UP, 1446, 368, 10, 10, 50, 550",
+ "DOWN, 368 , 1446, 10, 10, 0, 11",
+ "DOWN, 368 , 1446, 10, 10, 100, 1089"
})
@ParameterizedTest
- void shouldCalculateCoordinates(SwipeDirection direction, int fromY, int toY, int xPercentage, int x)
+ void shouldCalculateCoordinates(SwipeDirection direction, int fromY, int toY, int pointX, int pointY,
+ int xPercentage, int x)
{
Dimension dimension = new Dimension(1080, 1794);
+ Point point = new Point(pointX, pointY);
+ Rectangle swipeArea = new Rectangle(point, dimension);
MobileApplicationConfiguration configuration = mock(MobileApplicationConfiguration.class);
when(configuration.getSwipeVerticalXPosition()).thenReturn(xPercentage);
- SwipeCoordinates coordinates = direction.calculateCoordinates(dimension, configuration);
+ SwipeCoordinates coordinates = direction.calculateCoordinates(swipeArea, configuration);
assertPoint(coordinates.getStart(), x, fromY);
assertPoint(coordinates.getEnd(), x, toY);
}
@CsvSource({
- "LEFT, 945, 135, 50, 897",
- "RIGHT, 135 , 945, 0, 1",
- "RIGHT, 135 , 945, 100, 1793"
+ "LEFT, 945, 135, 0, 0, 50, 897",
+ "RIGHT, 135 , 945, 0, 0, 0, 1",
+ "RIGHT, 135 , 945, 0, 0, 100, 1793",
+ "LEFT, 955, 145, 10, 10, 50, 907",
+ "RIGHT, 145 , 955, 10, 10, 0, 11",
+ "RIGHT, 145 , 955, 10, 10, 100, 1803"
})
@ParameterizedTest
- void shouldCalculateCoordinatesForHorizontalSwipe(SwipeDirection direction, int fromX, int toX, int yPercentage,
- int y)
+ void shouldCalculateCoordinatesForHorizontalSwipe(SwipeDirection direction, int fromX, int toX,
+ int pointX, int pointY, int yPercentage, int y)
{
Dimension dimension = new Dimension(1080, 1794);
+ Point point = new Point(pointX, pointY);
+ Rectangle swipeArea = new Rectangle(point, dimension);
MobileApplicationConfiguration configuration = mock(MobileApplicationConfiguration.class);
when(configuration.getSwipeHorizontalYPosition()).thenReturn(yPercentage);
- SwipeCoordinates coordinates = direction.calculateCoordinates(dimension, configuration);
+ SwipeCoordinates coordinates = direction.calculateCoordinates(swipeArea, configuration);
assertPoint(coordinates.getStart(), fromX, y);
assertPoint(coordinates.getEnd(), toX, y);
diff --git a/vividus-plugin-mobile-app/src/test/java/org/vividus/bdd/mobileapp/steps/TouchStepsTests.java b/vividus-plugin-mobile-app/src/test/java/org/vividus/bdd/mobileapp/steps/TouchStepsTests.java
index 5bfaf2a4f8..3e205ba73e 100644
--- a/vividus-plugin-mobile-app/src/test/java/org/vividus/bdd/mobileapp/steps/TouchStepsTests.java
+++ b/vividus-plugin-mobile-app/src/test/java/org/vividus/bdd/mobileapp/steps/TouchStepsTests.java
@@ -17,6 +17,7 @@
package org.vividus.bdd.mobileapp.steps;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
@@ -42,6 +43,7 @@
import org.mockito.junit.jupiter.MockitoExtension;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;
+import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.vividus.bdd.mobileapp.model.SwipeDirection;
import org.vividus.bdd.steps.ComparisonRule;
@@ -52,10 +54,13 @@
import org.vividus.ui.action.ISearchActions;
import org.vividus.ui.action.search.Locator;
import org.vividus.ui.action.search.SearchParameters;
+import org.vividus.ui.context.IUiContext;
@ExtendWith(MockitoExtension.class)
class TouchStepsTests
{
+ private static final Dimension DIMENSION = new Dimension(0, 1184);
+
private static final String ELEMENT_TO_TAP = "The element to tap";
@Mock private IBaseValidations baseValidations;
@@ -64,6 +69,7 @@ class TouchStepsTests
@Mock private Locator locator;
@Mock private GenericWebDriverManager genericWebDriverManager;
@Mock private IWebDriverProvider webDriverProvider;
+ @Mock private IUiContext uiContext;
@InjectMocks private TouchSteps touchSteps;
@AfterEach
@@ -122,36 +128,74 @@ void shouldSwipeToElement(int elementY, int endY)
.thenReturn(List.of(element));
doAnswer(a ->
{
- BooleanSupplier condition = a.getArgument(2, BooleanSupplier.class);
+ BooleanSupplier condition = a.getArgument(3, BooleanSupplier.class);
condition.getAsBoolean();
condition.getAsBoolean();
return null;
- }).when(touchActions).swipeUntil(eq(SwipeDirection.UP), eq(Duration.ZERO),
+ }).when(touchActions).swipeUntil(eq(SwipeDirection.UP), eq(Duration.ZERO), any(Rectangle.class),
any(BooleanSupplier.class));
touchSteps.swipeToElement(SwipeDirection.UP, locator, Duration.ZERO);
verifyNoMoreInteractions(parameters);
- verify(touchActions).performVerticalSwipe(592, endY, Duration.ZERO);
+ verify(touchActions).performVerticalSwipe(eq(592), eq(endY), argThat(sa ->
+ DIMENSION.equals(sa.getDimension()) && sa.getPoint().equals(new Point(0, 0))), eq(Duration.ZERO));
+ }
+
+ @Test
+ void shouldSwipeToElementUsingContextElement()
+ {
+ WebElement element = mock(WebElement.class);
+ mockAssertElementsNumber(List.of(element), true);
+ when(element.getLocation()).thenReturn(new Point(-1, 138));
+ WebElement searchContext = mock(WebElement.class);
+ Point point = new Point(10, 10);
+ Dimension contextDimension = new Dimension(1920, 1080);
+ when(searchContext.getRect()).thenReturn(new Rectangle(point, contextDimension));
+ when(uiContext.getSearchContext()).thenReturn(searchContext);
+
+ when(searchActions.findElements(locator)).thenReturn(new ArrayList<>())
+ .thenReturn(List.of())
+ .thenReturn(List.of(element));
+ doAnswer(a ->
+ {
+ BooleanSupplier condition = a.getArgument(3, BooleanSupplier.class);
+ condition.getAsBoolean();
+ condition.getAsBoolean();
+ return null;
+ }).when(touchActions).swipeUntil(eq(SwipeDirection.UP), eq(Duration.ZERO), argThat(sa ->
+ contextDimension.equals(sa.getDimension()) && sa.getPoint().equals(point)),
+ any(BooleanSupplier.class));
+ SearchParameters parameters = initSwipeMocks();
+
+ touchSteps.swipeToElement(SwipeDirection.UP, locator, Duration.ZERO);
+
+ verifyNoMoreInteractions(parameters);
+ verify(touchActions).performVerticalSwipe(eq(540), eq(564), argThat(sa ->
+ contextDimension.equals(sa.getDimension()) && sa.getPoint().equals(point)), eq(Duration.ZERO));
}
@Test
void shouldSwipeToElementToTryToFindItButThatDoesntExist()
{
+ mockScreenSize();
mockAssertElementsNumber(List.of(), false);
initSwipeMocks();
when(searchActions.findElements(locator)).thenReturn(List.of());
doAnswer(a ->
{
- BooleanSupplier condition = a.getArgument(2, BooleanSupplier.class);
+ BooleanSupplier condition = a.getArgument(3, BooleanSupplier.class);
condition.getAsBoolean();
return null;
- }).when(touchActions).swipeUntil(eq(SwipeDirection.UP), eq(Duration.ZERO),
- any(BooleanSupplier.class));
+ }).when(touchActions).swipeUntil(eq(SwipeDirection.UP), eq(Duration.ZERO), argThat(sa ->
+ DIMENSION.equals(sa.getDimension()) && sa.getPoint().equals(new Point(0, 0))), any(BooleanSupplier.class));
touchSteps.swipeToElement(SwipeDirection.UP, locator, Duration.ZERO);
- verifyNoInteractions(genericWebDriverManager);
+ verify(touchActions).swipeUntil(eq(SwipeDirection.UP), eq(Duration.ZERO),
+ argThat(sa -> DIMENSION.equals(sa.getDimension()) && sa.getPoint().equals(new Point(0, 0))),
+ any(BooleanSupplier.class));
+ verifyNoMoreInteractions(touchActions);
}
@ParameterizedTest
@@ -159,12 +203,11 @@ void shouldSwipeToElementToTryToFindItButThatDoesntExist()
void shouldNotSwipeToElementIfItAlreadyExists(SwipeDirection swipeDireciton)
{
mockScreenSize();
- SearchParameters parameters = initSwipeMocks();
WebElement element = mock(WebElement.class);
when(element.getLocation()).thenReturn(new Point(-1, 500));
mockAssertElementsNumber(List.of(element), true);
-
when(searchActions.findElements(locator)).thenReturn(List.of(element));
+ SearchParameters parameters = initSwipeMocks();
touchSteps.swipeToElement(swipeDireciton, locator, Duration.ZERO);
@@ -201,8 +244,6 @@ private void mockAssertElementsNumber(List elements, boolean result)
private void mockScreenSize()
{
- Dimension dimension = mock(Dimension.class);
- when(dimension.getHeight()).thenReturn(1184);
- when(genericWebDriverManager.getSize()).thenReturn(dimension);
+ when(genericWebDriverManager.getSize()).thenReturn(DIMENSION);
}
}
diff --git a/vividus-plugin-mobile-app/src/test/java/org/vividus/selenium/mobileapp/screenshot/NativeHeaderAwareCoordsProviderTests.java b/vividus-plugin-mobile-app/src/test/java/org/vividus/selenium/mobileapp/screenshot/NativeHeaderAwareCoordsProviderTests.java
index 8facabc06d..1d1bd534f0 100644
--- a/vividus-plugin-mobile-app/src/test/java/org/vividus/selenium/mobileapp/screenshot/NativeHeaderAwareCoordsProviderTests.java
+++ b/vividus-plugin-mobile-app/src/test/java/org/vividus/selenium/mobileapp/screenshot/NativeHeaderAwareCoordsProviderTests.java
@@ -17,6 +17,7 @@
package org.vividus.selenium.mobileapp.screenshot;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -25,12 +26,13 @@
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
+import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebElement;
import org.vividus.selenium.mobileapp.MobileAppWebDriverManager;
-import org.vividus.ui.context.IUiContext;
+import org.vividus.ui.context.UiContext;
import ru.yandex.qatools.ashot.coordinates.Coords;
@@ -39,7 +41,7 @@ class NativeHeaderAwareCoordsProviderTests
{
@Mock private MobileAppWebDriverManager driverManager;
@Mock private WebElement webElement;
- @Mock private IUiContext uiContext;
+ @Spy private UiContext uiContext;
@InjectMocks private NativeHeaderAwareCoordsProvider coordsProvider;
@@ -49,6 +51,7 @@ void shoudProvideAdjustedWithNativeHeaderHeightCoordinates()
when(driverManager.getStatusBarSize()).thenReturn(100);
when(webElement.getLocation()).thenReturn(new Point(0, 234));
when(webElement.getSize()).thenReturn(new Dimension(1, 1));
+ doReturn(null).when(uiContext).getSearchContext();
Coords coords = coordsProvider.ofElement(null, webElement);
Assertions.assertAll(() -> assertEquals(0, coords.getX()),
() -> assertEquals(134, coords.getY()),
@@ -64,7 +67,7 @@ void shouldAdjustElementCoordsToTheCurrentSearchContext()
when(contextElement.getSize()).thenReturn(new Dimension(100, 50));
when(webElement.getLocation()).thenReturn(new Point(5, 15));
when(webElement.getSize()).thenReturn(new Dimension(150, 30));
- when(uiContext.getSearchContext()).thenReturn(contextElement);
+ doReturn(contextElement).when(uiContext).getSearchContext();
Coords coords = coordsProvider.ofElement(null, webElement);
Assertions.assertAll(() -> assertEquals(0, coords.getX()),
() -> assertEquals(5, coords.getY()),
@@ -78,7 +81,7 @@ void shouldNotAdjustCoordsForTheCurrentSearchContext()
WebElement contextElement = mock(WebElement.class);
when(contextElement.getLocation()).thenReturn(new Point(10, 10));
when(contextElement.getSize()).thenReturn(new Dimension(100, 50));
- when(uiContext.getSearchContext()).thenReturn(contextElement);
+ doReturn(contextElement).when(uiContext).getSearchContext();
Coords coords = coordsProvider.ofElement(null, contextElement);
Assertions.assertAll(
() -> assertEquals(10, coords.getX()),
diff --git a/vividus-tests/src/main/resources/data/tables/system/mobile_app/locators/android.table b/vividus-tests/src/main/resources/data/tables/system/mobile_app/locators/android.table
index 1e269d4f85..714a9e9f0d 100644
--- a/vividus-tests/src/main/resources/data/tables/system/mobile_app/locators/android.table
+++ b/vividus-tests/src/main/resources/data/tables/system/mobile_app/locators/android.table
@@ -17,3 +17,4 @@
|action |COMPARE_AGAINST |
|scrollViewXpath |//android.widget.ScrollView |
|carouselViewXpath |//android.widget.TextView[@text='Carousel'] |
+|swipeableAreaXpath |//android.widget.HorizontalScrollView |
diff --git a/vividus-tests/src/main/resources/data/tables/system/mobile_app/locators/ios.table b/vividus-tests/src/main/resources/data/tables/system/mobile_app/locators/ios.table
index 5b8af7ccea..a34e41a812 100644
--- a/vividus-tests/src/main/resources/data/tables/system/mobile_app/locators/ios.table
+++ b/vividus-tests/src/main/resources/data/tables/system/mobile_app/locators/ios.table
@@ -17,3 +17,4 @@
|action |COMPARE_AGAINST |
|scrollViewXpath |//XCUIElementTypeScrollView |
|carouselViewXpath |//XCUIElementTypeButton[@name='Carousel'] |
+|swipeableAreaXpath |(//XCUIElementTypeScrollView)[2] |
diff --git a/vividus-tests/src/main/resources/story/system/mobile_app/MobileAppStepsTests.story b/vividus-tests/src/main/resources/story/system/mobile_app/MobileAppStepsTests.story
index 5224dd16c8..6d789ac04e 100644
--- a/vividus-tests/src/main/resources/story/system/mobile_app/MobileAppStepsTests.story
+++ b/vividus-tests/src/main/resources/story/system/mobile_app/MobileAppStepsTests.story
@@ -227,6 +227,13 @@ Then number of elements found by `accessibilityId()`
When I swipe RIGHT to element located `accessibilityId()` with duration PT1S
Then number of elements found by `accessibilityId()` is = `1`
Then number of elements found by `accessibilityId()` is = `0`
+When I change context to element located `xpath()`
+When I swipe LEFT to element located `accessibilityId()` with duration PT1S
+Then number of elements found by `accessibilityId()` is = `0`
+Then number of elements found by `accessibilityId()` is = `1`
+When I swipe RIGHT to element located `accessibilityId()` with duration PT1S
+Then number of elements found by `accessibilityId()` is = `1`
+Then number of elements found by `accessibilityId()` is = `0`
Examples:
|firstItemAccessibilityId|secondItemAccessibilityId|