From 9d3e2134516f3e26f09ceb95e6df861d073f7556 Mon Sep 17 00:00:00 2001 From: Sunil Gembali Date: Wed, 10 Jul 2024 11:21:41 +0530 Subject: [PATCH] feat [TE-1007] : Need an addon to map parking spots in camera stream - OBS Application --- 2d_drawing/pom.xml | 102 ++++++++++++++++++ .../addons/web/DrawLineOnElement.java | 68 ++++++++++++ .../addons/web/DrawPolygonOnElement.java | 71 ++++++++++++ .../addons/web/DrawRectangleOnElement.java | 70 ++++++++++++ .../testsigma/addons/web/DrawingAction.java | 59 ++++++++++ 5 files changed, 370 insertions(+) create mode 100644 2d_drawing/pom.xml create mode 100644 2d_drawing/src/main/java/com/testsigma/addons/web/DrawLineOnElement.java create mode 100644 2d_drawing/src/main/java/com/testsigma/addons/web/DrawPolygonOnElement.java create mode 100644 2d_drawing/src/main/java/com/testsigma/addons/web/DrawRectangleOnElement.java create mode 100644 2d_drawing/src/main/java/com/testsigma/addons/web/DrawingAction.java diff --git a/2d_drawing/pom.xml b/2d_drawing/pom.xml new file mode 100644 index 00000000..a68f077e --- /dev/null +++ b/2d_drawing/pom.xml @@ -0,0 +1,102 @@ + + + 4.0.0 + com.testsigma.addons + 2d_drawing + 1.0.0 + jar + + + UTF-8 + 11 + 11 + 1.2.12_cloud + 5.8.0-M1 + 1.0.0 + 3.2.1 + 1.18.20 + + + + + + com.testsigma + testsigma-java-sdk + ${testsigma.sdk.version} + + + org.projectlombok + lombok + ${lombok.version} + true + + + org.junit.jupiter + junit-jupiter-api + ${junit.jupiter.version} + test + + + org.testng + testng + 6.14.3 + + + + org.seleniumhq.selenium + selenium-java + 4.14.1 + + + + io.appium + java-client + 9.0.0 + + + com.fasterxml.jackson.core + jackson-annotations + 2.13.0 + + + org.apache.commons + commons-lang3 + 3.14.0 + + + + + 2d_drawing + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + + + + org.apache.maven.plugins + maven-source-plugin + ${maven.source.plugin.version} + + + attach-sources + + jar + + + + + + + diff --git a/2d_drawing/src/main/java/com/testsigma/addons/web/DrawLineOnElement.java b/2d_drawing/src/main/java/com/testsigma/addons/web/DrawLineOnElement.java new file mode 100644 index 00000000..5875f5f0 --- /dev/null +++ b/2d_drawing/src/main/java/com/testsigma/addons/web/DrawLineOnElement.java @@ -0,0 +1,68 @@ +package com.testsigma.addons.web; + +import com.testsigma.sdk.ApplicationType; +import com.testsigma.sdk.Result; +import com.testsigma.sdk.annotation.Action; +import com.testsigma.sdk.annotation.Element; +import com.testsigma.sdk.annotation.TestData; +import lombok.Data; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.interactions.MoveTargetOutOfBoundsException; + +import java.awt.*; + +@Data +@Action(actionText = "Drawing: Draw a line on the element element-locator using start position (x1, y1) " + + "and end position (x2, y2) (Position Format: Percentage of element width,Percentage of element height," + + " Ex: 40,60)", + description = "Drawing a line in the given element with given relative start and end positions", + applicationType = ApplicationType.WEB) +public class DrawLineOnElement extends DrawingAction { + + @Element(reference = "element-locator") + private com.testsigma.sdk.Element camera; + @TestData(reference = "x1") + private com.testsigma.sdk.TestData x1; + @TestData(reference = "y1") + private com.testsigma.sdk.TestData y1; + @TestData(reference = "x2") + private com.testsigma.sdk.TestData x2; + @TestData(reference = "y2") + private com.testsigma.sdk.TestData y2; + + + @Override + public Result execute() throws NoSuchElementException { + Result result = Result.SUCCESS; + try { + elementRect = getCamera().getElement().getRect(); + logger.info(String.format("Element dimensions x: %s, y:%s, width:%s, height:%s", + elementRect.x, elementRect.y, elementRect.width, elementRect.height)); + + Point start = getPointFromString(x1.getValue().toString(), y1.getValue().toString()); + logger.info("Start point: " + start.toString()); + Point end = getPointFromString(x2.getValue().toString(), y2.getValue().toString()); + logger.info("End point: " + end.toString()); + Actions actions = new Actions(driver); + actions.moveToLocation(start.x, start.y).click().moveToLocation(end.x, end.y).click().build().perform(); + + setSuccessMessage("Successfully drawn the line on the element"); + } catch (MoveTargetOutOfBoundsException e) { + logger.info("Invalid locations raised :" + ExceptionUtils.getStackTrace(e)); + setErrorMessage("The positions are not with in the element"); + result = Result.FAILED; + } catch (RuntimeException e) { + logger.info("Exception occurred: " + ExceptionUtils.getStackTrace(e)); + setErrorMessage(runtimeErrorMessage); + result = Result.FAILED; + } catch (Exception e) { + logger.info("Exception raised :" + ExceptionUtils.getStackTrace(e)); + setErrorMessage("Unable to draw the line"); + result = Result.FAILED; + } + return result; + + } +} \ No newline at end of file diff --git a/2d_drawing/src/main/java/com/testsigma/addons/web/DrawPolygonOnElement.java b/2d_drawing/src/main/java/com/testsigma/addons/web/DrawPolygonOnElement.java new file mode 100644 index 00000000..dcf2f3cc --- /dev/null +++ b/2d_drawing/src/main/java/com/testsigma/addons/web/DrawPolygonOnElement.java @@ -0,0 +1,71 @@ +package com.testsigma.addons.web; + +import com.testsigma.sdk.ApplicationType; +import com.testsigma.sdk.Result; +import com.testsigma.sdk.annotation.Action; +import com.testsigma.sdk.annotation.Element; +import com.testsigma.sdk.annotation.TestData; +import lombok.Data; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.interactions.MoveTargetOutOfBoundsException; + +import java.awt.*; +import java.util.List; +import java.util.NoSuchElementException; + +@Data +@Action(actionText = "Drawing: Draw a polygon on element element-locator using the list of relative positions data-points (Percentage of " + + "element width, Percentage of element height. Ex: 5,10:15,20:20,25)", + description = "Drawing polygon on element using the list of relative positions which are based on the element height and width", + applicationType = ApplicationType.WEB) +public class DrawPolygonOnElement extends DrawingAction { + + @Element(reference = "element-locator") + private com.testsigma.sdk.Element camera; + @TestData(reference = "data-points") + private com.testsigma.sdk.TestData points_; + + + + @Override + public Result execute() throws NoSuchElementException { + Result result = Result.SUCCESS; + String pointString = points_.getValue().toString(); + String[] pointStringList = pointString.split(":"); + try{ + elementRect = getCamera().getElement().getRect(); + logger.info(String.format("Element dimensions x: %s, y:%s, width:%s, height:%s", + elementRect.x, elementRect.y, elementRect.width, elementRect.height)); + List xyPairs = retrieveRelativePoints(pointStringList); + if (xyPairs.size() < 2) { + setRuntimeErrorMessage(String.format("Provided positions are %s, minimum 3 positions are" + + " required to draw polygon", xyPairs.size())); + throw new RuntimeException("Invalid no of positions"); + } + logger.info("Adding first point again to the last to complete the polygon drawing"); + xyPairs.add(xyPairs.get(0)); + Actions actions = new Actions(driver); + for (Point point: xyPairs) { + actions.moveToLocation(point.x, point.y).click().build().perform(); + } + setSuccessMessage("Successfully drawn the polygon using the given positions on the element"); + } catch (MoveTargetOutOfBoundsException e) { + logger.info("Invalid locations raised :" + ExceptionUtils.getStackTrace(e)); + setErrorMessage("The positions are not with in the element"); + result = Result.FAILED; + } catch (RuntimeException e) { + logger.info("Exception occurred: " + ExceptionUtils.getStackTrace(e)); + setErrorMessage(runtimeErrorMessage); + result = Result.FAILED; + } catch (Exception e) { + logger.info("Exception raised :" + ExceptionUtils.getStackTrace(e)); + setErrorMessage("Unable to generate the polygon"); + result = Result.FAILED; + } + return result; + + } + + +} \ No newline at end of file diff --git a/2d_drawing/src/main/java/com/testsigma/addons/web/DrawRectangleOnElement.java b/2d_drawing/src/main/java/com/testsigma/addons/web/DrawRectangleOnElement.java new file mode 100644 index 00000000..f54407f6 --- /dev/null +++ b/2d_drawing/src/main/java/com/testsigma/addons/web/DrawRectangleOnElement.java @@ -0,0 +1,70 @@ +package com.testsigma.addons.web; + +import com.testsigma.sdk.ApplicationType; +import com.testsigma.sdk.Result; +import com.testsigma.sdk.WebAction; +import com.testsigma.sdk.annotation.Action; +import com.testsigma.sdk.annotation.Element; +import com.testsigma.sdk.annotation.TestData; +import lombok.Data; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.Rectangle; +import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.interactions.MoveTargetOutOfBoundsException; + +@Data +@Action(actionText = "Drawing: Draw a Rectangle on the element element-locator with dimensions Length: Test-Data1 ," + + " Breadth: Test-Data2 and start position (x1, y1) (Position Format: Percentage of element width,Percentage" + + " of element height, Ex: 40,60)", + description = "Drawing a rectangle in the given element based on the given dimensions and position", + applicationType = ApplicationType.WEB) +public class DrawRectangleOnElement extends WebAction { + + @Element(reference = "element-locator") + private com.testsigma.sdk.Element camera; + @TestData(reference = "x1") + private com.testsigma.sdk.TestData xPercentage; + @TestData(reference = "y1") + private com.testsigma.sdk.TestData yPercentage; + @TestData(reference = "Test-Data1") + private com.testsigma.sdk.TestData width; + @TestData(reference = "Test-Data2") + private com.testsigma.sdk.TestData height; + + + @Override + public Result execute() throws NoSuchElementException { + Result result = Result.SUCCESS; + try{ + Rectangle rectangle = getCamera().getElement().getRect(); + logger.info(String.format("Element dimensions x: %s, y:%s, width:%s, height:%s", + rectangle.x, rectangle.y, rectangle.width, rectangle.height)); + double x = Double.parseDouble(xPercentage.getValue().toString()); + double y = Double.parseDouble(yPercentage.getValue().toString()); + int boxWidth = Integer.parseInt(width.getValue().toString()); + int boxHeight = Integer.parseInt(height.getValue().toString()); + int startX = (int) ((x * rectangle.getWidth() / 100) + rectangle.getX()); + int startY = (int) ((y * rectangle.getHeight() / 100) + rectangle.getY()); + int endX = startX + boxWidth; + int endY = startY + boxHeight; + logger.info("Start locations relative to the given element startX - " + startX + ", startY - " + startY); + + Actions actions = new Actions(driver); + actions.moveToLocation(startX, startY).clickAndHold().moveToLocation(endX, endY).release().build().perform(); + + setSuccessMessage(String.format("Successfully created the rectangle on the given location, started from" + + " x: %s, y:%s", startX, startY)); + } catch (MoveTargetOutOfBoundsException e) { + logger.info("Invalid locations raised :" + ExceptionUtils.getStackTrace(e)); + setErrorMessage("The positions are not with in the element"); + result = Result.FAILED; + } catch (Exception e) { + logger.info("Exception raised :" + ExceptionUtils.getStackTrace(e)); + setErrorMessage("Unable to generate the rectangle"); + result = Result.FAILED; + } + return result; + + } +} \ No newline at end of file diff --git a/2d_drawing/src/main/java/com/testsigma/addons/web/DrawingAction.java b/2d_drawing/src/main/java/com/testsigma/addons/web/DrawingAction.java new file mode 100644 index 00000000..05f2011b --- /dev/null +++ b/2d_drawing/src/main/java/com/testsigma/addons/web/DrawingAction.java @@ -0,0 +1,59 @@ +package com.testsigma.addons.web; + +import com.testsigma.sdk.Result; +import com.testsigma.sdk.WebAction; +import lombok.Data; +import org.openqa.selenium.By; +import org.openqa.selenium.NoSuchElementException; +import org.openqa.selenium.StaleElementReferenceException; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.interactions.Actions; + +import java.awt.*; +import java.util.ArrayList; +import java.util.List; + +@Data +public class DrawingAction extends WebAction { + + protected org.openqa.selenium.Rectangle elementRect; + protected String runtimeErrorMessage = "Unable to perform the operation, run time error occurred"; + + @Override + protected Result execute() throws NoSuchElementException { + return null; + } + + + protected List retrieveRelativePoints(String[] pointsString) { + List xyPairs = new ArrayList<>(); + for (String xy : pointsString) { + logger.info("Converting to point: " + xy); + String[] pointValues = xy.split(","); + if (pointValues.length != 2) { + setRuntimeErrorMessage("Invalid input positions given, it should be (Ex: x1,y1:x2,y2:x3,y3)."); + throw new RuntimeException("Invalid input"); + } + Point point = getPointFromString(pointValues[0], pointValues[1]); + logger.info(String.format("Point string %s, point : %s", xy, point.toString())); + xyPairs.add(point); + } + return xyPairs; + } + + protected Point getPointFromString(String xStr, String yStr) { + try { + logger.info("Retrieving relative x and y"); + double x = Double.parseDouble(xStr); + double y = Double.parseDouble(yStr); + int relativeX = (int) ((x * elementRect.getWidth() / 100) + elementRect.getX()); + int relativeY = (int) ((y * elementRect.getHeight() / 100) + elementRect.getY()); + logger.info("Retrieved.."); + return new Point(relativeX, relativeY); + } catch (NumberFormatException e) { + setRuntimeErrorMessage("Invalid input positions given, input should contain numbers in the format " + + "(Ex: x1,y1:x2,y2:x3,y3)"); + throw new RuntimeException("Invalid input, number conversion!!"); + } + } +}