-
Notifications
You must be signed in to change notification settings - Fork 15
[CUS-12449] add-on for swiping in the given direction with pause. #386
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ManojTestsigma
wants to merge
1
commit into
dev
Choose a base branch
from
CUS-12449
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+668
−0
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <project | ||
| xmlns="http://maven.apache.org/POM/4.0.0" | ||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> | ||
| <groupId>com.testsigma.addons</groupId> | ||
| <artifactId>swipe_actions</artifactId> | ||
| <version>1.0.1</version> | ||
| <packaging>jar</packaging> | ||
|
|
||
| <properties> | ||
| <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
| <maven.compiler.source>11</maven.compiler.source> | ||
| <maven.compiler.target>11</maven.compiler.target> | ||
| <testsigma.sdk.version>1.2.24_cloud</testsigma.sdk.version> | ||
| <junit.jupiter.version>5.8.0-M1</junit.jupiter.version> | ||
| <testsigma.addon.maven.plugin>1.0.0</testsigma.addon.maven.plugin> | ||
| <maven.source.plugin.version>3.2.1</maven.source.plugin.version> | ||
| <lombok.version>1.18.30</lombok.version> | ||
|
|
||
| </properties> | ||
|
|
||
| <dependencies> | ||
| <dependency> | ||
| <groupId>com.testsigma</groupId> | ||
| <artifactId>testsigma-java-sdk</artifactId> | ||
| <version>${testsigma.sdk.version}</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.projectlombok</groupId> | ||
| <artifactId>lombok</artifactId> | ||
| <version>${lombok.version}</version> | ||
| <optional>true</optional> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.junit.jupiter</groupId> | ||
| <artifactId>junit-jupiter-api</artifactId> | ||
| <version>${junit.jupiter.version}</version> | ||
| <scope>test</scope> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.testng</groupId> | ||
| <artifactId>testng</artifactId> | ||
| <version>6.14.3</version> | ||
| </dependency> | ||
| <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java --> | ||
| <dependency> | ||
| <groupId>org.seleniumhq.selenium</groupId> | ||
| <artifactId>selenium-java</artifactId> | ||
| <version>4.33.0</version> | ||
| </dependency> | ||
| <!-- https://mvnrepository.com/artifact/io.appium/java-client --> | ||
| <dependency> | ||
| <groupId>io.appium</groupId> | ||
| <artifactId>java-client</artifactId> | ||
| <version>9.4.0</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>com.fasterxml.jackson.core</groupId> | ||
| <artifactId>jackson-annotations</artifactId> | ||
| <version>2.13.0</version> | ||
| </dependency> | ||
|
|
||
| </dependencies> | ||
| <build> | ||
| <finalName>swipe_actions</finalName> | ||
| <plugins> | ||
| <plugin> | ||
| <groupId>org.apache.maven.plugins</groupId> | ||
| <artifactId>maven-shade-plugin</artifactId> | ||
| <version>3.2.4</version> | ||
| <executions> | ||
| <execution> | ||
| <phase>package</phase> | ||
| <goals> | ||
| <goal>shade</goal> | ||
| </goals> | ||
| </execution> | ||
| </executions> | ||
| </plugin> | ||
| <plugin> | ||
| <groupId>org.apache.maven.plugins</groupId> | ||
| <artifactId>maven-source-plugin</artifactId> | ||
| <version>${maven.source.plugin.version}</version> | ||
| <executions> | ||
| <execution> | ||
| <id>attach-sources</id> | ||
| <goals> | ||
| <goal>jar</goal> | ||
| </goals> | ||
| </execution> | ||
| </executions> | ||
| </plugin> | ||
| </plugins> | ||
| </build> | ||
| </project> | ||
145 changes: 145 additions & 0 deletions
145
...e_actions/src/main/java/com/testsigma/addons/android/ScrollInsideElementWithDuration.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,145 @@ | ||
| package com.testsigma.addons.android; | ||
|
|
||
| import com.testsigma.sdk.AndroidAction; | ||
| import com.testsigma.sdk.ApplicationType; | ||
| import com.testsigma.sdk.Element; | ||
| import com.testsigma.sdk.Result; | ||
| import com.testsigma.sdk.annotation.Action; | ||
| import com.testsigma.sdk.annotation.TestData; | ||
| import io.appium.java_client.AppiumDriver; | ||
| import lombok.Data; | ||
| import org.openqa.selenium.NoSuchElementException; | ||
| import org.openqa.selenium.Rectangle; | ||
| import org.openqa.selenium.interactions.PointerInput; | ||
| import org.openqa.selenium.interactions.Sequence; | ||
|
|
||
| import java.time.Duration; | ||
| import java.util.Collections; | ||
|
|
||
| import static org.openqa.selenium.interactions.PointerInput.Kind.TOUCH; | ||
| import static org.openqa.selenium.interactions.PointerInput.MouseButton.LEFT; | ||
| import static org.openqa.selenium.interactions.PointerInput.Origin.viewport; | ||
|
|
||
| @Data | ||
| @Action(actionText = "Swipe inside the element element-name in direction direction for duration seconds", | ||
| description = "Scrolls inside the given element in the specified direction. The swipe gesture takes the" + | ||
| " given number of seconds to complete. Use longer durations for slower, more deliberate scrolls.", | ||
| applicationType = ApplicationType.ANDROID, | ||
| displayName = "Scroll inside element with direction and duration", | ||
| useCustomScreenshot = false) | ||
| public class ScrollInsideElementWithDuration extends AndroidAction { | ||
|
|
||
| @com.testsigma.sdk.annotation.Element(reference = "element-name") | ||
| private Element elementName; | ||
|
|
||
| @TestData(reference = "direction", | ||
| allowedValues = { | ||
| "LEFT TO RIGHT", | ||
| "RIGHT TO LEFT", | ||
| "MIDDLE TO LEFT", | ||
| "MIDDLE TO RIGHT", | ||
| "LEFT TO MIDDLE", | ||
| "RIGHT TO MIDDLE", | ||
| "TOP TO BOTTOM", | ||
| "BOTTOM TO TOP", | ||
| "TOP TO MIDDLE", | ||
| "MIDDLE TO TOP", | ||
| "BOTTOM TO MIDDLE", | ||
| "MIDDLE TO BOTTOM" | ||
| }) | ||
| private com.testsigma.sdk.TestData direction; | ||
|
|
||
| @TestData(reference = "duration") | ||
| private com.testsigma.sdk.TestData duration; | ||
|
|
||
| @Override | ||
| protected Result execute() throws NoSuchElementException { | ||
| logger.info("Starting scroll inside element with direction and duration"); | ||
|
|
||
| int durationSeconds; | ||
| try { | ||
| durationSeconds = Integer.parseInt(duration.getValue().toString().trim()); | ||
| } catch (NumberFormatException e) { | ||
| setErrorMessage("Invalid duration: '" + duration.getValue() + "'. Please provide a whole number of seconds."); | ||
| return Result.FAILED; | ||
| } | ||
|
|
||
| if (durationSeconds <= 0) { | ||
| setErrorMessage("Duration must be greater than 0, but got: " + durationSeconds); | ||
| return Result.FAILED; | ||
| } | ||
|
|
||
| String swipeDirection = direction.getValue().toString().trim().toUpperCase(); | ||
|
|
||
| try { | ||
| org.openqa.selenium.WebElement webElement = elementName.getElement(); | ||
| Rectangle rect = webElement.getRect(); | ||
|
|
||
| int centerX = rect.x + rect.width / 2; | ||
| int centerY = rect.y + rect.height / 2; | ||
| int left = rect.x; | ||
| int right = rect.x + rect.width; | ||
| int top = rect.y; | ||
| int bottom = rect.y + rect.height; | ||
|
|
||
| logger.info(String.format("Element rect: x=%d y=%d w=%d h=%d", rect.x, rect.y, rect.width, rect.height)); | ||
|
|
||
| int[] coords = resolveCoordinates(swipeDirection, left, right, top, bottom, centerX, centerY); | ||
| if (coords == null) { | ||
| setErrorMessage("Unsupported direction: " + swipeDirection); | ||
| return Result.FAILED; | ||
| } | ||
|
|
||
| int startX = coords[0]; | ||
| int startY = coords[1]; | ||
| int endX = coords[2]; | ||
| int endY = coords[3]; | ||
|
|
||
| logger.info(String.format("Swipe [%s]: (%d,%d) -> (%d,%d) over %ds", | ||
| swipeDirection, startX, startY, endX, endY, durationSeconds)); | ||
|
|
||
| AppiumDriver appiumDriver = (AppiumDriver) this.driver; | ||
| PointerInput finger = new PointerInput(TOUCH, "finger"); | ||
| Sequence swipe = new Sequence(finger, 1) | ||
| .addAction(finger.createPointerMove(Duration.ofMillis(0), viewport(), startX, startY)) | ||
| .addAction(finger.createPointerDown(LEFT.asArg())) | ||
| .addAction(finger.createPointerMove(Duration.ofSeconds(durationSeconds), viewport(), endX, endY)) | ||
| .addAction(finger.createPointerUp(LEFT.asArg())); | ||
|
|
||
| appiumDriver.perform(Collections.singletonList(swipe)); | ||
|
|
||
| setSuccessMessage(String.format( | ||
| "Successfully scrolled inside the element [%s] over %d second(s)", swipeDirection, durationSeconds)); | ||
| return Result.SUCCESS; | ||
|
|
||
| } catch (NoSuchElementException e) { | ||
| logger.debug("Element not found: " + e.getMessage()); | ||
| setErrorMessage("Element not found: " + e.getMessage()); | ||
| return Result.FAILED; | ||
| } catch (Exception e) { | ||
| logger.debug("Scroll failed: " + e.getMessage()); | ||
| setErrorMessage("Scroll failed: " + e.getMessage()); | ||
| return Result.FAILED; | ||
| } | ||
| } | ||
|
|
||
| private int[] resolveCoordinates(String dir, int left, int right, int top, int bottom, int cx, int cy) { | ||
| switch (dir) { | ||
| // ── Horizontal ────────────────────────────────────────────────────────── | ||
| case "LEFT TO RIGHT": return new int[]{left, cy, right, cy}; | ||
| case "RIGHT TO LEFT": return new int[]{right, cy, left, cy}; | ||
| case "MIDDLE TO LEFT": return new int[]{cx, cy, left, cy}; | ||
| case "MIDDLE TO RIGHT": return new int[]{cx, cy, right, cy}; | ||
| case "LEFT TO MIDDLE": return new int[]{left, cy, cx, cy}; | ||
| case "RIGHT TO MIDDLE": return new int[]{right, cy, cx, cy}; | ||
| // ── Vertical ──────────────────────────────────────────────────────────── | ||
| case "TOP TO BOTTOM": return new int[]{cx, top, cx, bottom}; | ||
| case "BOTTOM TO TOP": return new int[]{cx, bottom, cx, top}; | ||
| case "TOP TO MIDDLE": return new int[]{cx, top, cx, cy}; | ||
| case "MIDDLE TO TOP": return new int[]{cx, cy, cx, top}; | ||
| case "BOTTOM TO MIDDLE":return new int[]{cx, bottom, cx, cy}; | ||
| case "MIDDLE TO BOTTOM":return new int[]{cx, cy, cx, bottom}; | ||
| default: return null; | ||
| } | ||
| } | ||
| } |
73 changes: 73 additions & 0 deletions
73
...actions/src/main/java/com/testsigma/addons/ios/ScrollInsideElementFromMiddleToBottom.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| package com.testsigma.addons.ios; | ||
|
|
||
| import com.testsigma.sdk.ApplicationType; | ||
| import com.testsigma.sdk.Element; | ||
| import com.testsigma.sdk.IOSAction; | ||
| import com.testsigma.sdk.Result; | ||
| import com.testsigma.sdk.annotation.Action; | ||
| import io.appium.java_client.AppiumDriver; | ||
| import lombok.Data; | ||
| import org.openqa.selenium.NoSuchElementException; | ||
| import org.openqa.selenium.Rectangle; | ||
| import org.openqa.selenium.interactions.PointerInput; | ||
| import org.openqa.selenium.interactions.Sequence; | ||
|
|
||
| import java.time.Duration; | ||
| import java.util.Collections; | ||
|
|
||
| import static org.openqa.selenium.interactions.PointerInput.Kind.TOUCH; | ||
| import static org.openqa.selenium.interactions.PointerInput.MouseButton.LEFT; | ||
| import static org.openqa.selenium.interactions.PointerInput.Origin.viewport; | ||
|
|
||
| @Data | ||
| @Action(actionText = "Swipe inside the element element-name from middle to bottom", | ||
| description = "Scrolls inside the given element starting from its vertical midpoint down to its bottom edge." + | ||
| " Useful for revealing content below the centre of the element.", | ||
| applicationType = ApplicationType.IOS, | ||
| displayName = "Scroll inside element from middle to bottom", | ||
| useCustomScreenshot = false) | ||
| public class ScrollInsideElementFromMiddleToBottom extends IOSAction { | ||
|
|
||
| @com.testsigma.sdk.annotation.Element(reference = "element-name") | ||
| private Element elementName; | ||
|
|
||
| @Override | ||
| protected Result execute() throws NoSuchElementException { | ||
| logger.info("Starting scroll inside element from middle to bottom"); | ||
|
|
||
| try { | ||
| org.openqa.selenium.WebElement webElement = elementName.getElement(); | ||
| Rectangle rect = webElement.getRect(); | ||
|
|
||
| int startX = rect.x + rect.width / 2; | ||
| int startY = rect.y + rect.height / 2; | ||
| int endX = startX; | ||
| int endY = rect.y + rect.height; | ||
|
|
||
| logger.info(String.format("Element rect: x=%d y=%d w=%d h=%d", rect.x, rect.y, rect.width, rect.height)); | ||
| logger.info(String.format("Swipe: (%d,%d) -> (%d,%d)", startX, startY, endX, endY)); | ||
|
|
||
| AppiumDriver appiumDriver = (AppiumDriver) this.driver; | ||
| PointerInput finger = new PointerInput(TOUCH, "finger"); | ||
| Sequence swipe = new Sequence(finger, 1) | ||
| .addAction(finger.createPointerMove(Duration.ofMillis(0), viewport(), startX, startY)) | ||
| .addAction(finger.createPointerDown(LEFT.asArg())) | ||
| .addAction(finger.createPointerMove(Duration.ofSeconds(2), viewport(), endX, endY)) | ||
| .addAction(finger.createPointerUp(LEFT.asArg())); | ||
|
|
||
| appiumDriver.perform(Collections.singletonList(swipe)); | ||
|
|
||
| setSuccessMessage("Successfully scrolled inside the element from middle to bottom"); | ||
| return Result.SUCCESS; | ||
|
|
||
| } catch (NoSuchElementException e) { | ||
| logger.debug("Element not found: " + e.getMessage()); | ||
| setErrorMessage("Element not found: " + e.getMessage()); | ||
| return Result.FAILED; | ||
| } catch (Exception e) { | ||
| logger.debug("Failed to scroll inside element from middle to bottom: " + e.getMessage()); | ||
| setErrorMessage("Failed to scroll: " + e.getMessage()); | ||
| return Result.FAILED; | ||
| } | ||
| } | ||
| } |
73 changes: 73 additions & 0 deletions
73
swipe_actions/src/main/java/com/testsigma/addons/ios/ScrollInsideElementFromMiddleToTop.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| package com.testsigma.addons.ios; | ||
|
|
||
| import com.testsigma.sdk.ApplicationType; | ||
| import com.testsigma.sdk.Element; | ||
| import com.testsigma.sdk.IOSAction; | ||
| import com.testsigma.sdk.Result; | ||
| import com.testsigma.sdk.annotation.Action; | ||
| import io.appium.java_client.AppiumDriver; | ||
| import lombok.Data; | ||
| import org.openqa.selenium.NoSuchElementException; | ||
| import org.openqa.selenium.Rectangle; | ||
| import org.openqa.selenium.interactions.PointerInput; | ||
| import org.openqa.selenium.interactions.Sequence; | ||
|
|
||
| import java.time.Duration; | ||
| import java.util.Collections; | ||
|
|
||
| import static org.openqa.selenium.interactions.PointerInput.Kind.TOUCH; | ||
| import static org.openqa.selenium.interactions.PointerInput.MouseButton.LEFT; | ||
| import static org.openqa.selenium.interactions.PointerInput.Origin.viewport; | ||
|
|
||
| @Data | ||
| @Action(actionText = "Swipe inside the element element-name from middle to top", | ||
| description = "Scrolls inside the given element starting from its vertical midpoint up to its top edge." + | ||
| " Useful for revealing content above the centre of the element.", | ||
| applicationType = ApplicationType.IOS, | ||
| displayName = "Scroll inside element from middle to top", | ||
| useCustomScreenshot = false) | ||
| public class ScrollInsideElementFromMiddleToTop extends IOSAction { | ||
|
|
||
| @com.testsigma.sdk.annotation.Element(reference = "element-name") | ||
| private Element elementName; | ||
|
|
||
| @Override | ||
| protected Result execute() throws NoSuchElementException { | ||
| logger.info("Starting scroll inside element from middle to top"); | ||
|
|
||
| try { | ||
| org.openqa.selenium.WebElement webElement = elementName.getElement(); | ||
| Rectangle rect = webElement.getRect(); | ||
|
|
||
| int startX = rect.x + rect.width / 2; | ||
| int startY = rect.y + rect.height / 2; | ||
| int endX = startX; | ||
| int endY = rect.y; | ||
|
|
||
| logger.info(String.format("Element rect: x=%d y=%d w=%d h=%d", rect.x, rect.y, rect.width, rect.height)); | ||
| logger.info(String.format("Swipe: (%d,%d) -> (%d,%d)", startX, startY, endX, endY)); | ||
|
|
||
| AppiumDriver appiumDriver = (AppiumDriver) this.driver; | ||
| PointerInput finger = new PointerInput(TOUCH, "finger"); | ||
| Sequence swipe = new Sequence(finger, 1) | ||
| .addAction(finger.createPointerMove(Duration.ofMillis(0), viewport(), startX, startY)) | ||
| .addAction(finger.createPointerDown(LEFT.asArg())) | ||
| .addAction(finger.createPointerMove(Duration.ofSeconds(2), viewport(), endX, endY)) | ||
| .addAction(finger.createPointerUp(LEFT.asArg())); | ||
|
|
||
| appiumDriver.perform(Collections.singletonList(swipe)); | ||
|
|
||
| setSuccessMessage("Successfully scrolled inside the element from middle to top"); | ||
| return Result.SUCCESS; | ||
|
|
||
| } catch (NoSuchElementException e) { | ||
| logger.debug("Element not found: " + e.getMessage()); | ||
| setErrorMessage("Element not found: " + e.getMessage()); | ||
| return Result.FAILED; | ||
| } catch (Exception e) { | ||
| logger.debug("Failed to scroll inside element from middle to top: " + e.getMessage()); | ||
| setErrorMessage("Failed to scroll: " + e.getMessage()); | ||
| return Result.FAILED; | ||
| } | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
latest Selenium Java version April 2026💡 Result:
The latest version of Selenium Java as of April 30, 2026, is 4.43.0, released on April 10, 2026. This is confirmed by the official Selenium downloads page listing it as the stable version and the GitHub release page providing the selenium-java-4.43.0.zip asset with significant downloads.
Citations:
🌐 Web query:
Appium java-client latest version 9.4.0 April 2026💡 Result:
As of 2026-04-30, the latest released version of the Appium Java client (artifact io.appium:java-client) is 10.1.1 (with 10.1.0 released 2026-03-11).
Citations:
Update to latest Selenium and Appium versions in use.
Selenium 4.33.0 is outdated; the latest stable version as of April 2026 is 4.43.0 (released April 10, 2026). Similarly, Appium java-client 9.4.0 is significantly behind the latest version 10.1.1 (released March 11, 2026). Update both dependencies to their latest versions and verify compatibility with the Testsigma SDK.
🤖 Prompt for AI Agents