Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package com.testsigma.addons.mobileweb;

import com.testsigma.sdk.annotation.Action;
import com.testsigma.sdk.ApplicationType;

import com.testsigma.sdk.annotation.Element;
import com.testsigma.sdk.annotation.TestData;
import com.testsigma.sdk.WebAction;
import lombok.Data;

import java.util.WeakHashMap;

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebElement;

import com.testsigma.sdk.Result;

@Data
@lombok.EqualsAndHashCode(callSuper = false)
@Action(actionText = "Verify if element element-locator is element-state with scrollable boolean-value",
description = "verifies if the element is in the given state",
applicationType = ApplicationType.MOBILE_WEB,
useCustomScreenshot = false)
public class VerifyElementPresenceWithScroll extends WebAction {

@Element(reference = "element-locator")
private com.testsigma.sdk.Element element;

@TestData(reference = "element-state", allowedValues = {"CHECKED", "UNCHECKED", "PRESENT", "NOT PRESENT", "ENABLED", "DISABLED", "DISPLAYED", "NOT DISPLAYED"})
private com.testsigma.sdk.TestData elementState;
@TestData(reference = "boolean-value", allowedValues = {"TRUE", "FALSE"})
private com.testsigma.sdk.TestData scrollable;

@Override
public Result execute() throws NoSuchElementException {
Result result = Result.SUCCESS;
logger.info("Initiating execution");
logger.debug("Element locator: " + this.element.getValue() + " by: " + this.element.getBy());
try {
WebElement webElement = element.getElement();
logger.info("element found");
String scrollableValue = scrollable.getValue().toString().toLowerCase();
if ("true".equalsIgnoreCase(scrollableValue)) {
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", webElement);
}
String elementStateValue = elementState.getValue().toString().toLowerCase();
logger.info("element state value: " + elementStateValue);
switch (elementStateValue) {
case "checked":
if (webElement.isSelected()) {
logger.info("Element is checked");
result = Result.SUCCESS;
} else {
logger.info("Element is not checked");
result = Result.FAILED;
}
break;
case "unchecked":
if (webElement.isSelected()) {
logger.info("Element is checked");
result = Result.FAILED;
} else {
logger.info("Element is not checked");
result = Result.SUCCESS;
}
break;
case "present":
if (webElement.isDisplayed()) {
logger.info("Element is displayed");
result = Result.SUCCESS;
} else {
logger.info("Element is not displayed");
result = Result.FAILED;
}
break;
case "not present":
if (webElement.isDisplayed()) {
logger.info("Element is displayed");
result = Result.FAILED;
} else {
logger.info("Element is not displayed");
result = Result.SUCCESS;
}
break;
Comment on lines +68 to +85
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

"NOT PRESENT" can never return SUCCESS — logic bug.

If the element is truly absent from the DOM, element.getElement() on line 41 throws NoSuchElementException, which is caught at line 128 and unconditionally returns FAILED. The switch case for "not present" is only reached when the element does exist, so it actually checks "not displayed" — not "not present."

Similarly, the "present" case uses isDisplayed(), which can return false for an element that is present in the DOM but hidden. It should return SUCCESS simply because the element was found.

The NoSuchElementException catch block needs to account for the requested state — if the user asked for "NOT PRESENT" and the element wasn't found, that's a success.

Proposed fix sketch
         } catch (NoSuchElementException e) {
-            result = Result.FAILED;
-            logger.warn("Element not found with locator: " + this.element.getBy() + "::" + this.element.getValue());
-            setErrorMessage(String.format("Element not found with locator %s::%s", this.element.getBy(), this.element.getValue()));
+            String stateValue = elementState.getValue().toString().toLowerCase();
+            if ("not present".equals(stateValue)) {
+                logger.info("Element is not present as expected");
+                result = Result.SUCCESS;
+            } else {
+                result = Result.FAILED;
+                logger.warn("Element not found with locator: " + this.element.getBy() + "::" + this.element.getValue());
+                setErrorMessage(String.format("Element not found with locator %s::%s", this.element.getBy(), this.element.getValue()));
+            }
         }

And for the "present" case, since reaching the switch already proves the element exists in the DOM:

             case "present":
-                if (webElement.isDisplayed()) {
-                    logger.info("Element is displayed");
-                    result = Result.SUCCESS;
-                } else {
-                    logger.info("Element is not displayed");
-                    result = Result.FAILED;
-                }
+                logger.info("Element is present in the DOM");
+                result = Result.SUCCESS;
                 break;

Also applies to: 128-131

🤖 Prompt for AI Agents
In
`@element_validation_actions/src/main/java/com/testsigma/addons/mobileweb/VerifyElementPresenceWithScroll.java`
around lines 68 - 85, The current switch in VerifyElementPresenceWithScroll
incorrectly treats visibility as presence and the NoSuchElementException catch
always returns FAILED; update logic so that finding the element (i.e., reaching
the switch after element.getElement() succeeds) means "present" returns
Result.SUCCESS regardless of webElement.isDisplayed(), and the "not present"
case returns Result.FAILED because the element exists; then modify the
NoSuchElementException catch (the catch that currently always sets FAILED) to
inspect the requested state ("present" vs "not present") and return
Result.SUCCESS when the exception occurred and the requested state was "not
present", otherwise return Result.FAILED. Use the existing symbols webElement,
element.getElement(), the "present"/"not present" switch cases, the catch for
NoSuchElementException, and the Result enum to implement these changes.

case "enabled":
if (webElement.isEnabled()) {
logger.info("Element is enabled");
result = Result.SUCCESS;
} else {
logger.info("Element is not enabled");
result = Result.FAILED;
}
break;
case "disabled":
if (webElement.isEnabled()) {
logger.info("Element is enabled");
result = Result.FAILED;
} else {
logger.info("Element is not enabled");
result = Result.SUCCESS;
}
break;
case "displayed":
if (webElement.isDisplayed()) {
logger.info("Element is displayed");
result = Result.SUCCESS;
} else {
logger.info("Element is not displayed");
result = Result.FAILED;
}
break;
case "not displayed":
if (webElement.isDisplayed()) {
logger.info("Element is displayed");
result = Result.FAILED;
} else {
logger.info("Element is not displayed");
result = Result.SUCCESS;
}
break;
Comment on lines +49 to +121
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

"PRESENT" and "DISPLAYED" cases are identical — consider differentiating semantics.

Both "present" (lines 68–75) and "displayed" (lines 104–111) call isDisplayed() with identical logic. The same applies to "not present" vs "not displayed". Typically, "present" means the element exists in the DOM (regardless of visibility), while "displayed" means it is visible. Since allowedValues explicitly offers both options, users will expect different behavior.

  • PRESENT / NOT PRESENT: should check DOM existence (element found vs. NoSuchElementException).
  • DISPLAYED / NOT DISPLAYED: should check visibility via isDisplayed().
🤖 Prompt for AI Agents
In
`@element_validation_actions/src/main/java/com/testsigma/addons/mobileweb/VerifyElementPresenceWithScroll.java`
around lines 49 - 121, The "present"/"not present" branches currently duplicate
the "displayed"/"not displayed" logic by calling webElement.isDisplayed();
change "present"/"not present" to test DOM existence instead of visibility: use
a presence check such as driver.findElements(By...).isEmpty() or your existing
findElements/search helper to determine if the element exists in the DOM
(catching NoSuchElementException if your code locates elements differently), and
leave "displayed"/"not displayed" using webElement.isDisplayed(); update the
switch cases in VerifyElementPresenceWithScroll (the cases using
elementStateValue and webElement) to use the presence check for "present"/"not
present" and visibility for "displayed"/"not displayed".

default:
result = Result.FAILED;
logger.warn("Invalid element state: " + elementStateValue);
setErrorMessage(String.format("Invalid element state: %s", elementStateValue));
break;
}
Comment on lines +49 to +127
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

No error message set when non-default cases return FAILED.

When any of the switch branches (e.g., "checked", "enabled", "displayed") evaluates to Result.FAILED, setErrorMessage(...) is never called. Only the default and catch blocks set it. This means users will see a failure with no explanation of what went wrong.

Example fix for one branch (apply pattern to all)
             case "checked":
                 if (webElement.isSelected()) {
                     logger.info("Element is checked");
                     result = Result.SUCCESS;
                 } else {
                     logger.info("Element is not checked");
                     result = Result.FAILED;
+                    setErrorMessage("Element was expected to be CHECKED but it is not selected");
                 }
                 break;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
switch (elementStateValue) {
case "checked":
if (webElement.isSelected()) {
logger.info("Element is checked");
result = Result.SUCCESS;
} else {
logger.info("Element is not checked");
result = Result.FAILED;
}
break;
case "unchecked":
if (webElement.isSelected()) {
logger.info("Element is checked");
result = Result.FAILED;
} else {
logger.info("Element is not checked");
result = Result.SUCCESS;
}
break;
case "present":
if (webElement.isDisplayed()) {
logger.info("Element is displayed");
result = Result.SUCCESS;
} else {
logger.info("Element is not displayed");
result = Result.FAILED;
}
break;
case "not present":
if (webElement.isDisplayed()) {
logger.info("Element is displayed");
result = Result.FAILED;
} else {
logger.info("Element is not displayed");
result = Result.SUCCESS;
}
break;
case "enabled":
if (webElement.isEnabled()) {
logger.info("Element is enabled");
result = Result.SUCCESS;
} else {
logger.info("Element is not enabled");
result = Result.FAILED;
}
break;
case "disabled":
if (webElement.isEnabled()) {
logger.info("Element is enabled");
result = Result.FAILED;
} else {
logger.info("Element is not enabled");
result = Result.SUCCESS;
}
break;
case "displayed":
if (webElement.isDisplayed()) {
logger.info("Element is displayed");
result = Result.SUCCESS;
} else {
logger.info("Element is not displayed");
result = Result.FAILED;
}
break;
case "not displayed":
if (webElement.isDisplayed()) {
logger.info("Element is displayed");
result = Result.FAILED;
} else {
logger.info("Element is not displayed");
result = Result.SUCCESS;
}
break;
default:
result = Result.FAILED;
logger.warn("Invalid element state: " + elementStateValue);
setErrorMessage(String.format("Invalid element state: %s", elementStateValue));
break;
}
switch (elementStateValue) {
case "checked":
if (webElement.isSelected()) {
logger.info("Element is checked");
result = Result.SUCCESS;
} else {
logger.info("Element is not checked");
result = Result.FAILED;
setErrorMessage("Element was expected to be CHECKED but it is not selected");
}
break;
case "unchecked":
if (webElement.isSelected()) {
logger.info("Element is checked");
result = Result.FAILED;
} else {
logger.info("Element is not checked");
result = Result.SUCCESS;
}
break;
case "present":
if (webElement.isDisplayed()) {
logger.info("Element is displayed");
result = Result.SUCCESS;
} else {
logger.info("Element is not displayed");
result = Result.FAILED;
}
break;
case "not present":
if (webElement.isDisplayed()) {
logger.info("Element is displayed");
result = Result.FAILED;
} else {
logger.info("Element is not displayed");
result = Result.SUCCESS;
}
break;
case "enabled":
if (webElement.isEnabled()) {
logger.info("Element is enabled");
result = Result.SUCCESS;
} else {
logger.info("Element is not enabled");
result = Result.FAILED;
}
break;
case "disabled":
if (webElement.isEnabled()) {
logger.info("Element is enabled");
result = Result.FAILED;
} else {
logger.info("Element is not enabled");
result = Result.SUCCESS;
}
break;
case "displayed":
if (webElement.isDisplayed()) {
logger.info("Element is displayed");
result = Result.SUCCESS;
} else {
logger.info("Element is not displayed");
result = Result.FAILED;
}
break;
case "not displayed":
if (webElement.isDisplayed()) {
logger.info("Element is displayed");
result = Result.FAILED;
} else {
logger.info("Element is not displayed");
result = Result.SUCCESS;
}
break;
default:
result = Result.FAILED;
logger.warn("Invalid element state: " + elementStateValue);
setErrorMessage(String.format("Invalid element state: %s", elementStateValue));
break;
}
🤖 Prompt for AI Agents
In
`@element_validation_actions/src/main/java/com/testsigma/addons/mobileweb/VerifyElementPresenceWithScroll.java`
around lines 49 - 127, In VerifyElementPresenceWithScroll inside the switch on
elementStateValue, ensure every branch that sets result = Result.FAILED also
calls setErrorMessage(...) with a clear message (use the same descriptive text
logged, e.g. "Element is not displayed", "Element is not enabled", "Element is
not checked", etc.) so failures outside default/catch provide diagnostic detail;
update each case (checked, unchecked, present, not present, enabled, disabled,
displayed, not displayed) to set an appropriate error message whenever result is
set to FAILED, keeping existing logger.info/logger.warn lines.

} catch (NoSuchElementException e) {
result = Result.FAILED;
logger.warn("Element not found with locator: " + this.element.getBy() + "::" + this.element.getValue());
setErrorMessage(String.format("Element not found with locator %s::%s", this.element.getBy(), this.element.getValue()));
} catch (Exception e) {
result = Result.FAILED;
logger.warn("Error verifying element state: " + e.getMessage());
setErrorMessage(String.format("Error verifying element state: %s", e.getMessage()));
}
return result;
}
}