Skip to content

Conversation

@ManojTestsigma
Copy link
Contributor

@ManojTestsigma ManojTestsigma commented Oct 27, 2025

please review these addons and publish as PUBLIC

Addon name : List data structure actions
Addon name : Checkbox actions
Addon accont: https://jarvis.testsigma.com/ui/tenants/3072/addons
Jira: https://testsigma.atlassian.net/browse/CUS-8162

fix

  1. Added addon to iterate through the list data structure using the separator
  2. Addon for checking and unchecking all the checkboxes.

Summary by CodeRabbit

Release Notes

  • New Features
    • Added checkbox automation actions: check all, uncheck all, and retrieve checkbox labels across Android, iOS, and Web platforms
    • Added while loop iteration action to process separator-delimited data and store current iteration values to runtime variables across Web, Mobile Web, Windows Advanced, Android, and iOS environments

@coderabbitai
Copy link

coderabbitai bot commented Oct 27, 2025

Walkthrough

Introduces two new addon modules: checkbox_actions provides cross-platform actions for checking/unchecking all checkboxes and fetching checkbox labels (Android, iOS, Web); list_data_structure_actions provides while-loop actions for iterating over separator-delimited data across multiple platforms (Android, iOS, Web, Mobile Web, Windows Advanced).

Changes

Cohort / File(s) Summary
checkbox_actions Module Configuration
checkbox_actions/pom.xml
New Maven project (com.testsigma.addons:checkbox_actions:1.0.0) with dependencies on testsigma-java-sdk, TestNG, Selenium, Appium, and Jackson; configures maven-shade-plugin and maven-source-plugin.
checkbox_actions - Android Actions
checkbox_actions/src/main/java/com/testsigma/addons/android/CheckAllCheckboxes.java, UnCheckAllCheckboxes.java, FetchCheckboxLabelAndStore.java
Three Android action classes: CheckAllCheckboxes and UnCheckAllCheckboxes toggle all enabled checkboxes; FetchCheckboxLabelAndStore retrieves labels and stores them as a runtime variable.
checkbox_actions - iOS Actions
checkbox_actions/src/main/java/com/testsigma/addons/ios/CheckAllCheckboxes.java, UnCheckAllCheckboxes.java, FetchCheckboxLabelAndStore.java
Three iOS action classes mirroring Android: CheckAllCheckboxes and UnCheckAllCheckboxes toggle checkboxes; FetchCheckboxLabelAndStore retrieves and stores labels as a runtime variable.
checkbox_actions - Web Actions
checkbox_actions/src/main/java/com/testsigma/addons/web/CheckAllCheckboxes.java, UnCheckAllCheckboxes.java, FetchCheckboxLabelAndStore.java
Three Web action classes: CheckAllCheckboxes and UnCheckAllCheckboxes toggle all enabled checkboxes; FetchCheckboxLabelAndStore fetches labels and stores them as a comma-separated runtime variable.
checkbox_actions - Utilities
checkbox_actions/src/main/java/com/testsigma/addons/utils/CheckboxActions.java, CheckBoxLabelFetcher.java
CheckboxActions utility provides platform-agnostic toggle logic for checking/unchecking checkboxes; CheckBoxLabelFetcher extracts checkbox labels via platform-specific strategies (Android, iOS, Web).
list_data_structure_actions Module Configuration
list_data_structure_actions/pom.xml
New Maven project (com.testsigma.addons:list_data_structure_actions:1.0.0) with identical dependency and plugin configuration as checkbox_actions.
list_data_structure_actions - While Loop Actions
list_data_structure_actions/src/main/java/com/testsigma/addons/android/WhileLoopStringBySeparator.java, ios/WhileLoopStringBySeparator.java, web/WhileLoopStringBySeparator.java, mobileweb/WhileLoopStringBySeparator.java, windowsAdvanced/WhileLoopStringBySeparator.java
Five platform-specific while-loop actions that iterate over SEPARATOR-delimited TEST-DATA, storing current iteration values and maintaining an index via runtime variables.

Sequence Diagram(s)

sequenceDiagram
    participant Action as CheckAllCheckboxes<br/>(Android/iOS/Web)
    participant CheckboxActions as CheckboxActions<br/>(Utility)
    participant Driver as WebDriver<br/>(Platform-specific)
    participant Element as WebElement<br/>(Checkbox)
    
    Action->>CheckboxActions: checkAllEnabledCheckboxes(driver, logger)
    CheckboxActions->>CheckboxActions: getPlatformType(driver)
    CheckboxActions->>CheckboxActions: findCheckboxes(driver, platform-xpath)
    
    loop For each checkbox element
        CheckboxActions->>Element: isEnabled()?
        alt Not Enabled
            CheckboxActions->>CheckboxActions: Log: Skip disabled
        else Enabled
            CheckboxActions->>CheckboxActions: getCheckboxInfo(element)
            CheckboxActions->>Element: isSelected()?
            alt Not Selected (need to check)
                CheckboxActions->>Element: click()
                CheckboxActions->>CheckboxActions: Log: Checked
            end
        end
    end
    
    CheckboxActions->>CheckboxActions: Log: Summary (processed, skipped)
    CheckboxActions->>Action: Return success
    Action->>Action: setSuccessMessage()
    Action->>Action: Return Result.SUCCESS
Loading
sequenceDiagram
    participant Action as FetchCheckboxLabelAndStore<br/>(Android/iOS/Web)
    participant Fetcher as CheckBoxLabelFetcher<br/>(Utility)
    participant Driver as WebDriver<br/>(Platform-specific)
    participant Element as WebElement<br/>(Checkbox)
    
    Action->>Fetcher: getAllCheckboxLabels(driver, logger)
    Fetcher->>Fetcher: getPlatformType(driver)
    Fetcher->>Fetcher: findCheckboxes(driver, platform-xpath)
    
    loop For each checkbox element
        Fetcher->>Fetcher: extractLabel(element, platform)
        alt Platform: Android
            Fetcher->>Element: getAttribute("text")?
            alt text exists
                Fetcher->>Fetcher: Add to labels
            else try content-desc
                Fetcher->>Element: getAttribute("content-desc")
            end
        else Platform: iOS
            Fetcher->>Element: getAttribute("label") / getAttribute("name")
        else Platform: Web
            Fetcher->>Element: Find ancestor label or label-for
        end
    end
    
    Fetcher->>Fetcher: Join labels: comma-separated string
    Fetcher->>Action: Return labels
    Action->>Action: Create RunTimeData(variable_name, labels)
    Action->>Action: setSuccessMessage()
    Action->>Action: Return Result.SUCCESS
Loading
sequenceDiagram
    participant Action as WhileLoopStringBySeparator<br/>(Any Platform)
    participant Provider as RunTimeDataProvider
    participant RTData as RunTimeData
    
    Action->>Action: Read SEPARATOR, TEST-DATA, RUNTIME-VARIABLE
    Action->>Action: Build index_key = RUNTIME-VARIABLE + "_TSIndex"
    Action->>Provider: Get current index from index_key
    
    alt Index not found
        Action->>Action: Set current_index = 0
    else Index found
        Action->>Action: Set current_index = retrieved_index
    end
    
    Action->>Action: Split TEST-DATA by SEPARATOR
    Action->>Action: Check: current_index < split_values.length?
    
    alt Index out of bounds
        Action->>Action: Log: No more values
        Action->>Action: setErrorMessage("End of data")
        Action->>Action: Return Result.FAILED
    else Index valid
        Action->>Action: current_value = split_values[current_index].trim()
        Action->>RTData: Store(RUNTIME-VARIABLE, current_value)
        Action->>Action: next_index = current_index + 1
        Action->>RTData: Store(index_key, next_index)
        Action->>Action: setSuccessMessage()
        Action->>Action: Return Result.SUCCESS
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

  • Multiple new Java action classes across five platforms (Android, iOS, Web, Mobile Web, Windows Advanced) with consistent patterns but requiring individual verification
  • Two utility classes (CheckboxActions, CheckBoxLabelFetcher) contain non-trivial platform detection and element handling logic with error recovery
  • Cross-platform XPath and attribute strategies need careful review for correctness
  • While-loop state management (index persistence, boundary conditions) across implementations requires thorough verification
  • Two POM configurations with consistent structure but dependency versions should be validated
  • Areas requiring extra attention:
    • Platform-specific checkbox locators and label extraction logic in CheckboxActions and CheckBoxLabelFetcher (potential locator brittleness)
    • Index boundary condition handling in all WhileLoopStringBySeparator implementations
    • Error handling consistency across all platform variants
    • Runtime variable and runtime data wiring patterns (@testdata, @RunTimeData, @RunTimeDataProvider annotations)

Suggested reviewers

  • vigneshtestsigma
  • Ganesh-Testsigma

Poem

🐰 A rabbit hops through checkboxes with glee,
Checking and unchecking across each degree,
While loops now dance with data split clean,
The finest addon module ever seen!
Labels are fetched with platform-aware grace,
TestSigma adds-on finds their perfect place.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "[Cus-8162] Addon for iterating list and bulk check box actions" clearly references the two major features being added: list iteration functionality (WhileLoopStringBySeparator across multiple platforms) and checkbox bulk operations (CheckAllCheckboxes, UnCheckAllCheckboxes, FetchCheckboxLabelAndStore across web, Android, and iOS). The title is concise, specific, and directly summarizes the main additions without using vague terminology. A developer scanning the history would immediately understand that this PR adds two new addons for list iteration and checkbox management.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch CUS-8162

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 14

🧹 Nitpick comments (24)
list_data_structure_actions/pom.xml (3)

74-86: Minimize shaded jar to reduce bloat and conflicts

Enable minimizeJar and keep dependency-reduced-pom disabled (common for add-ons).

             <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>
+                  <configuration>
+                    <createDependencyReducedPom>false</createDependencyReducedPom>
+                    <minimizeJar>true</minimizeJar>
+                  </configuration>
                 </execution>
               </executions>
             </plugin>

18-18: Remove unused property or wire in the plugin

testsigma.addon.maven.plugin is defined but unused. Either remove to avoid drift or use it.

-        <testsigma.addon.maven.plugin>1.0.0</testsigma.addon.maven.plugin>

47-58: ---

Versions verified as compatible; consider promoting to properties for consistency

Confirmed: org.seleniumhq.selenium:selenium-java 4.33.0 is published on Maven Central and compatible with io.appium:java-client 9.4.0 (Appium supports 4.26.0–4.33.0). Note: 4.37.0 is the latest stable 4.x, but your version is stable and within the compatibility range. Refactor to use Maven properties for easier version management and consistency across dependencies.

checkbox_actions/src/main/java/com/testsigma/addons/web/UnCheckAllCheckboxes.java (2)

14-16: Clarify action to “enabled checkboxes” and use error-level logging on failures

Keep user expectations aligned with behavior, and log failures at error level.

-@Action(actionText = "Uncheck all the checkboxes in the current page",
-        description = "Uncheck all the checkboxes in the current page",
+@Action(actionText = "Uncheck all enabled checkboxes on the current page",
+        description = "Unchecks every enabled checkbox on the current page; disabled checkboxes are skipped",
         applicationType = ApplicationType.WEB)
@@
-        } catch (Exception e) {
-            setErrorMessage("An error occurred while unchecking all the checkboxes in the current page: " + e.getMessage());
-            logger.info("An error occurred while unchecking all the checkboxes in the current page: " + ExceptionUtils.getStackTrace(e));
+        } catch (Exception e) {
+            setErrorMessage("An error occurred while unchecking all the checkboxes in the current page: " + e.getMessage());
+            logger.error("An error occurred while unchecking all the checkboxes in the current page: " + ExceptionUtils.getStackTrace(e));
             return Result.FAILED;
         }

Also applies to: 26-29, 22-25


17-17: Naming consistency: prefer “UncheckAllCheckboxes”

Class name uses “UnCheck…”. Consider renaming to “UncheckAllCheckboxes” to match action text and other classes.

Please confirm if other modules use “Uncheck” vs “UnCheck”; we can submit a follow-up rename PR across platforms if desired.

checkbox_actions/src/main/java/com/testsigma/addons/android/CheckAllCheckboxes.java (1)

14-16: Tighten logging, types, and wording

Use error level on failures, prefer generics, and clarify action scope.

-@Action(actionText = "Check all the checkboxes in the current page",
-        description = "Check all the checkboxes in the current page",
+@Action(actionText = "Check all enabled checkboxes on the current page",
+        description = "Checks every enabled checkbox on the current page; disabled checkboxes are skipped",
         applicationType = ApplicationType.ANDROID)
@@
-            AndroidDriver androidDriver = (AndroidDriver) this.driver;
+            AndroidDriver<?> androidDriver = (AndroidDriver<?>) this.driver;
             new CheckboxActions().checkAllEnabledCheckboxes(androidDriver, logger);
@@
-            logger.info("Error in CheckAllCheckboxes Android action: " + ExceptionUtils.getStackTrace(e));
+            logger.error("Error in CheckAllCheckboxes Android action: " + ExceptionUtils.getStackTrace(e));
             return Result.FAILED;

Also applies to: 28-33, 23-25

checkbox_actions/src/main/java/com/testsigma/addons/ios/UnCheckAllCheckboxes.java (2)

14-16: Clarify wording and improve logging and typing

Align text with behavior, use error-level logging, and adopt generics.

-@Action(actionText = "Uncheck all the checkboxes in the current page",
-        description = "Uncheck all the checkboxes in the current page",
+@Action(actionText = "Uncheck all enabled checkboxes on the current page",
+        description = "Unchecks every enabled checkbox on the current page; disabled checkboxes are skipped",
         applicationType = ApplicationType.IOS)
@@
-            IOSDriver iosDriver = (IOSDriver) this.driver;
+            IOSDriver<?> iosDriver = (IOSDriver<?>) this.driver;
             new CheckboxActions().unCheckAllEnabledCheckboxes(iosDriver, logger);
@@
-            logger.info("Error in UnCheckAllCheckboxes iOS action: " + ExceptionUtils.getStackTrace(e));
+            logger.error("Error in UnCheckAllCheckboxes iOS action: " + ExceptionUtils.getStackTrace(e));
             return Result.FAILED;

Also applies to: 28-33, 23-26


17-17: Naming consistency: prefer “UncheckAllCheckboxes”

Consider renaming class to “UncheckAllCheckboxes” for consistency.

checkbox_actions/src/main/java/com/testsigma/addons/web/CheckAllCheckboxes.java (1)

14-16: Clarify action scope and log failures at error level

Match behavior (enabled only) and improve failure visibility.

-@Action(actionText = "Check all the checkboxes in the current page",
-        description = "Check all the checkboxes in the current page",
+@Action(actionText = "Check all enabled checkboxes on the current page",
+        description = "Checks every enabled checkbox on the current page; disabled checkboxes are skipped",
         applicationType = ApplicationType.WEB)
@@
-            logger.info("Error in CheckAllCheckboxes Web action: " + ExceptionUtils.getStackTrace(e));
+            logger.error("Error in CheckAllCheckboxes Web action: " + ExceptionUtils.getStackTrace(e));
             return Result.FAILED;

Also applies to: 26-31

checkbox_actions/src/main/java/com/testsigma/addons/android/UnCheckAllCheckboxes.java (2)

13-18: Avoid Lombok @DaTa here and consider consistent naming.

This action has no own fields; @DaTa adds noisy toString/equals/hashCode. Also, consider renaming class to UncheckAllCheckboxes (lowercase “c”) to match the action text and typical naming.


21-33: Drop the AndroidDriver cast; pass WebDriver directly and improve error log level.

CheckboxActions works with WebDriver and detects platform. Casting is redundant and can fail in mixed contexts. Also prefer error-level logging if Logger supports it.

-            AndroidDriver androidDriver = (AndroidDriver) this.driver;
-            new CheckboxActions().unCheckAllEnabledCheckboxes(androidDriver, logger);
+            new CheckboxActions().unCheckAllEnabledCheckboxes(driver, logger);
-            logger.info("Error in UnCheckAllCheckboxes Android action: " + ExceptionUtils.getStackTrace(e));
+            logger.info("Error in UnCheckAllCheckboxes Android action: " + ExceptionUtils.getStackTrace(e)); // consider logger.error
checkbox_actions/src/main/java/com/testsigma/addons/ios/CheckAllCheckboxes.java (2)

13-18: Remove Lombok @DaTa; it’s unnecessary here.

No fields on this class; @DaTa generates unused methods and noisy toString.


21-33: Avoid IOSDriver cast; delegate with WebDriver.

Let CheckboxActions detect platform; also consider error-level logging for failures.

-            IOSDriver iosDriver = (IOSDriver) this.driver;
-            new CheckboxActions().checkAllEnabledCheckboxes(iosDriver, logger);
+            new CheckboxActions().checkAllEnabledCheckboxes(driver, logger);
-            logger.info("Error in CheckAllCheckboxes iOS action: " + ExceptionUtils.getStackTrace(e));
+            logger.info("Error in CheckAllCheckboxes iOS action: " + ExceptionUtils.getStackTrace(e)); // consider logger.error
checkbox_actions/src/main/java/com/testsigma/addons/utils/CheckBoxLabelFetcher.java (3)

10-12: Deduplicate labels while preserving order.

Prevent repeated labels by using a LinkedHashSet, then join once.

-import java.util.List;
-import java.util.StringJoiner;
+import java.util.List;
+import java.util.LinkedHashSet;
+import java.util.Set;
@@
-            StringJoiner labels = new StringJoiner(", ");
-            int processedCount = 0;
+            Set<String> labels = new LinkedHashSet<>();
+            int processedCount = 0;
@@
-            String result = labels.toString();
+            String result = String.join(", ", labels);

Also applies to: 28-31, 49-51


143-164: Add web aria fallbacks for unlabeled inputs.

Handle accessible naming when no association exists.

         // Fallback to <label for="id"> association if ancestor label not found
         if (labelText.isEmpty()) {
             String id = checkbox.getAttribute("id");
             if (id != null && !id.isEmpty()) {
                 try {
                     WebElement label = driver.findElement(By.xpath("//label[@for='" + id + "']"));
                     labelText = label.getText().trim();
                 } catch (Exception ignored) { }
             }
         }
+
+        // aria-label fallback
+        if (labelText.isEmpty()) {
+            String aria = checkbox.getAttribute("aria-label");
+            if (aria != null && !aria.trim().isEmpty()) {
+                labelText = aria.trim();
+            }
+        }
+
+        // aria-labelledby fallback (first id)
+        if (labelText.isEmpty()) {
+            String labelledBy = checkbox.getAttribute("aria-labelledby");
+            if (labelledBy != null && !labelledBy.trim().isEmpty()) {
+                String firstId = labelledBy.trim().split("\\s+")[0];
+                try {
+                    WebElement lbl = driver.findElement(By.id(firstId));
+                    labelText = lbl.getText().trim();
+                } catch (Exception ignored) { }
+            }
+        }

69-81: Tighten iOS locators and avoid unlikely @type filter.

The filter [@type='XCUIElementTypeButton'] is unusual; prefer class-based axes.

-                return driver.findElements(By.xpath("//XCUIElementTypeSwitch | //XCUIElementTypeButton[@type='XCUIElementTypeButton'] | //input[@type='checkbox']"));
+                return driver.findElements(By.xpath("//XCUIElementTypeSwitch | //XCUIElementTypeButton | //input[@type='checkbox']"));

Also consider that iOS “value” typically represents checked state (1/0) rather than a label; using it as a label is a last resort only.

Also applies to: 121-141

checkbox_actions/src/main/java/com/testsigma/addons/android/FetchCheckboxLabelAndStore.java (2)

16-18: Fix typo in user-facing text: “comma separated”.

-@Action(actionText = "Fetch all checkboxes on the page and store the label in runtime variable runtime-variable in comma seperated format",
-        description = "Fetch all checkboxes on the page and store the label in runtime variable runtime-variable in comma seperated format",
+@Action(actionText = "Fetch all checkboxes on the page and store the label in runtime variable runtime-variable in comma separated format",
+        description = "Fetch all checkboxes on the page and store the label in runtime variable runtime-variable in comma separated format",
         applicationType = ApplicationType.ANDROID)

33-35: Remove AndroidDriver cast; pass WebDriver.

Fetcher accepts WebDriver and detects platform.

-            AndroidDriver androidDriver = (AndroidDriver) this.driver;
-            String labels = new CheckBoxLabelFetcher().getAllCheckboxLabels(androidDriver, logger);
+            String labels = new CheckBoxLabelFetcher().getAllCheckboxLabels(driver, logger);
checkbox_actions/src/main/java/com/testsigma/addons/web/FetchCheckboxLabelAndStore.java (1)

15-17: Correct “comma separated” typo in action text/description.

-@Action(actionText = "Fetch all checkboxes on the page and store the label in runtime variable runtime-variable in comma seperated format",
-        description = "Fetch all checkboxes on the page and store the label in runtime variable runtime-variable in comma seperated format",
+@Action(actionText = "Fetch all checkboxes on the page and store the label in runtime variable runtime-variable in comma separated format",
+        description = "Fetch all checkboxes on the page and store the label in runtime variable runtime-variable in comma separated format",
         applicationType = ApplicationType.WEB)
checkbox_actions/src/main/java/com/testsigma/addons/ios/FetchCheckboxLabelAndStore.java (2)

16-18: Fix “comma separated” spelling.

-@Action(actionText = "Fetch all checkboxes on the page and store the label in runtime variable runtime-variable in comma seperated format",
-        description = "Fetch all checkboxes on the page and store the label in runtime variable runtime-variable in comma seperated format",
+@Action(actionText = "Fetch all checkboxes on the page and store the label in runtime variable runtime-variable in comma separated format",
+        description = "Fetch all checkboxes on the page and store the label in runtime variable runtime-variable in comma separated format",
         applicationType = ApplicationType.IOS)

33-35: Remove IOSDriver cast; use WebDriver.

-            IOSDriver iosDriver = (IOSDriver) this.driver;
-            String labels = new CheckBoxLabelFetcher().getAllCheckboxLabels(iosDriver, logger);
+            String labels = new CheckBoxLabelFetcher().getAllCheckboxLabels(driver, logger);
checkbox_actions/src/main/java/com/testsigma/addons/utils/CheckboxActions.java (1)

89-92: Simplify iOS checkbox locator; drop unlikely @type filter.

-                return driver.findElements(By.xpath("//XCUIElementTypeSwitch | //XCUIElementTypeButton[@type='XCUIElementTypeButton'] | //input[@type='checkbox']"));
+                return driver.findElements(By.xpath("//XCUIElementTypeSwitch | //XCUIElementTypeButton | //input[@type='checkbox']"));
checkbox_actions/pom.xml (2)

59-63: Update jackson-annotations to a recent stable version.

jackson-annotations 2.13.0 is from 2021 and outdated. Consider updating to 2.17.x or 2.18.x to include security patches and improvements.

         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-annotations</artifactId>
-            <version>2.13.0</version>
+            <version>2.17.0</version>
         </dependency>

74-86: Consider configuring shade plugin to exclude or relocate common transitive dependencies.

The maven-shade-plugin is configured without exclusions or relocation rules. This may cause classpath conflicts if consumers already have dependencies like commons-lang3, jackson, or lombok. Consider adding <configuration> with <transformers> and/or <filters> to prevent shadowing critical transitive deps, or use relocation to avoid conflicts.

For example:

             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-shade-plugin</artifactId>
                 <version>3.2.4</version>
+                <configuration>
+                    <filters>
+                        <filter>
+                            <artifact>*:*</artifact>
+                            <excludes>
+                                <exclude>META-INF/**</exclude>
+                            </excludes>
+                        </filter>
+                    </filters>
+                    <transformers>
+                        <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
+                    </transformers>
+                </configuration>
                 <executions>
                     <execution>
                         <phase>package</phase>
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1716e8b and 007d8f8.

📒 Files selected for processing (18)
  • checkbox_actions/pom.xml (1 hunks)
  • checkbox_actions/src/main/java/com/testsigma/addons/android/CheckAllCheckboxes.java (1 hunks)
  • checkbox_actions/src/main/java/com/testsigma/addons/android/FetchCheckboxLabelAndStore.java (1 hunks)
  • checkbox_actions/src/main/java/com/testsigma/addons/android/UnCheckAllCheckboxes.java (1 hunks)
  • checkbox_actions/src/main/java/com/testsigma/addons/ios/CheckAllCheckboxes.java (1 hunks)
  • checkbox_actions/src/main/java/com/testsigma/addons/ios/FetchCheckboxLabelAndStore.java (1 hunks)
  • checkbox_actions/src/main/java/com/testsigma/addons/ios/UnCheckAllCheckboxes.java (1 hunks)
  • checkbox_actions/src/main/java/com/testsigma/addons/utils/CheckBoxLabelFetcher.java (1 hunks)
  • checkbox_actions/src/main/java/com/testsigma/addons/utils/CheckboxActions.java (1 hunks)
  • checkbox_actions/src/main/java/com/testsigma/addons/web/CheckAllCheckboxes.java (1 hunks)
  • checkbox_actions/src/main/java/com/testsigma/addons/web/FetchCheckboxLabelAndStore.java (1 hunks)
  • checkbox_actions/src/main/java/com/testsigma/addons/web/UnCheckAllCheckboxes.java (1 hunks)
  • list_data_structure_actions/pom.xml (1 hunks)
  • list_data_structure_actions/src/main/java/com/testsigma/addons/android/WhileLoopStringBySeparator.java (1 hunks)
  • list_data_structure_actions/src/main/java/com/testsigma/addons/ios/WhileLoopStringBySeparator.java (1 hunks)
  • list_data_structure_actions/src/main/java/com/testsigma/addons/mobileweb/WhileLoopStringBySeparator.java (1 hunks)
  • list_data_structure_actions/src/main/java/com/testsigma/addons/web/WhileLoopStringBySeparator.java (1 hunks)
  • list_data_structure_actions/src/main/java/com/testsigma/addons/windowsAdvanced/WhileLoopStringBySeparator.java (1 hunks)
🔇 Additional comments (3)
list_data_structure_actions/pom.xml (1)

16-18: Avoid milestone JUnit; pin a stable Jupiter version

5.8.0-M1 is a pre-release. Prefer a stable 5.x. Align with the rest of the repo to reduce surprises.

list_data_structure_actions/src/main/java/com/testsigma/addons/android/WhileLoopStringBySeparator.java (1)

15-22: Android action registered as WEB and extends WebAction.

This will register/run under Web, not Android. Adjust ApplicationType and base class (confirm exact class name in your SDK).

-@Action(actionText = "store the current iteration value using SEPARATOR separated values in TEST-DATA " +
-        "into a runtime variable RUNTIME-VARIABLE",
-        description = "Iterate SEPARATOR separated values in TEST-DATA and store current iteration value in RUNTIME-VARIABLE",
-        applicationType = ApplicationType.WEB,
-        actionType = StepActionType.WHILE_LOOP)
-public class WhileLoopStringBySeparator extends WebAction {
+@Action(actionText = "store the current iteration value using SEPARATOR separated values in TEST-DATA " +
+        "into a runtime variable RUNTIME-VARIABLE",
+        description = "Iterate SEPARATOR separated values in TEST-DATA and store current iteration value in RUNTIME-VARIABLE",
+        applicationType = ApplicationType.ANDROID,
+        actionType = StepActionType.WHILE_LOOP)
+public class WhileLoopStringBySeparator extends AndroidAction {

Add/adjust imports:

-import com.testsigma.sdk.WebAction;
+import com.testsigma.sdk.AndroidAction;

Please confirm the correct Android base class name in your SDK (e.g., AndroidAction vs AndroidMobileAction).

list_data_structure_actions/src/main/java/com/testsigma/addons/ios/WhileLoopStringBySeparator.java (1)

15-22: iOS action registered as WEB and extends WebAction.

This will register/run under Web, not iOS. Adjust ApplicationType and base class (confirm exact class name).

-@Action(actionText = "store the current iteration value using SEPARATOR separated values in TEST-DATA " +
-        "into a runtime variable RUNTIME-VARIABLE",
-        description = "Iterate SEPARATOR separated values in TEST-DATA and store current iteration value " +
-                "in RUNTIME-VARIABLE",
-        applicationType = ApplicationType.WEB,
-        actionType = StepActionType.WHILE_LOOP)
-public class WhileLoopStringBySeparator extends WebAction {
+@Action(actionText = "store the current iteration value using SEPARATOR separated values in TEST-DATA " +
+        "into a runtime variable RUNTIME-VARIABLE",
+        description = "Iterate SEPARATOR separated values in TEST-DATA and store current iteration value " +
+                "in RUNTIME-VARIABLE",
+        applicationType = ApplicationType.IOS,
+        actionType = StepActionType.WHILE_LOOP)
+public class WhileLoopStringBySeparator extends IOSAction {

Imports:

-import com.testsigma.sdk.WebAction;
+import com.testsigma.sdk.IOSAction;

Please confirm the correct iOS base class name in your SDK.

Comment on lines +36 to +41
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Replace pre-release JUnit version with a stable release.

junit-jupiter-api 5.8.0-M1 is a milestone release (marked -M1), not recommended for production. Use a stable final release like 5.8.0 or later.

         <dependency>
             <groupId>org.junit.jupiter</groupId>
             <artifactId>junit-jupiter-api</artifactId>
-            <version>${junit.jupiter.version}</version>
+            <version>5.11.0</version>
         </dependency>

Also update the property:

-        <junit.jupiter.version>5.8.0-M1</junit.jupiter.version>
+        <junit.jupiter.version>5.11.0</junit.jupiter.version>
📝 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
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.11.0</version>
<scope>test</scope>
</dependency>
🤖 Prompt for AI Agents
In checkbox_actions/pom.xml around lines 36 to 41, the pom currently references
a pre-release JUnit (5.8.0-M1); update the junit-jupiter version to a stable
release by changing the junit.jupiter.version property to a final release (e.g.,
5.8.0 or later such as 5.8.2/5.9.x) and ensure the dependency uses that
property; remove the -M1 suffix from the property value so the dependency
resolves to the stable release.

Comment on lines +42 to +46
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
</dependency>
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Update TestNG to a supported version; 6.14.3 is from 2018 and likely contains unpatched vulnerabilities.

TestNG 6.14.3 is severely outdated and may have known security issues. Upgrade to TestNG 7.x or later (e.g., 7.10.2).

         <dependency>
             <groupId>org.testng</groupId>
             <artifactId>testng</artifactId>
-            <version>6.14.3</version>
+            <version>7.10.2</version>
         </dependency>
📝 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
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.10.2</version>
</dependency>
🤖 Prompt for AI Agents
In checkbox_actions/pom.xml around lines 42 to 46, the project depends on TestNG
6.14.3 which is outdated and may have security issues; update the dependency to
a supported 7.x release (for example 7.10.2) in the <dependency> section, run a
full build and test (mvn clean test) to catch any breaking changes, and if tests
fail adjust any TestNG API usages or test annotations to be compatible with
TestNG 7.x (and update Maven Surefire/Failsafe plugin versions if necessary).

Comment on lines +29 to +33
try {
String variableName = runtimeVariable.getValue().toString();
logger.info("Starting to fetch checkbox labels on Android platform and store in variable: " + variableName);

AndroidDriver androidDriver = (AndroidDriver) this.driver;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Null/empty runtime-variable guard to avoid NPE.

runtimeVariable.getValue() can be null. Fail fast with a clear message.

-            String variableName = runtimeVariable.getValue().toString();
+            if (runtimeVariable == null || runtimeVariable.getValue() == null ||
+                runtimeVariable.getValue().toString().trim().isEmpty()) {
+                setErrorMessage("Runtime variable name (runtime-variable) is required.");
+                return Result.FAILED;
+            }
+            String variableName = runtimeVariable.getValue().toString().trim();
🤖 Prompt for AI Agents
In
checkbox_actions/src/main/java/com/testsigma/addons/android/FetchCheckboxLabelAndStore.java
around lines 29 to 33, guard against runtimeVariable or
runtimeVariable.getValue() being null before calling toString(); if either is
null (or the value's toString() is empty) log a clear error and fail fast by
throwing an exception or returning an appropriate failure result so you don't
get an NPE. Add an explicit null/empty check, craft a descriptive message
including the variable name/key, and ensure the method exits cleanly after
logging so downstream code (like casting driver) is not executed when the
runtime variable is invalid.

Comment on lines +29 to +31
try {
String variableName = runtimeVariable.getValue().toString();
logger.info("Starting to fetch checkbox labels on iOS platform and store in variable: " + variableName);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Add runtime-variable null/empty check.

-            String variableName = runtimeVariable.getValue().toString();
+            if (runtimeVariable == null || runtimeVariable.getValue() == null ||
+                runtimeVariable.getValue().toString().trim().isEmpty()) {
+                setErrorMessage("Runtime variable name (runtime-variable) is required.");
+                return Result.FAILED;
+            }
+            String variableName = runtimeVariable.getValue().toString().trim();
🤖 Prompt for AI Agents
In
checkbox_actions/src/main/java/com/testsigma/addons/ios/FetchCheckboxLabelAndStore.java
around lines 29 to 31, the code uses runtimeVariable.getValue() without checking
for null or empty, which can cause NullPointerException or store invalid data;
add a guard that verifies runtimeVariable is not null and
runtimeVariable.getValue() is not null and not an empty string before calling
toString() or using the value, and if the check fails log an error (or set an
appropriate failure status/exception) and return/throw early to avoid proceeding
with an invalid variable name.

Comment on lines +51 to +59
// Click only if current state does not match desired state
if (checkbox.isSelected() != check) {
checkbox.click();
logger.info((check ? "Checked" : "Unchecked") + " checkbox: " + checkboxInfo);
processedCount++;
} else {
logger.info("Checkbox already in desired state: " + checkboxInfo);
skippedCount++;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Platform-specific checked-state detection is required (isSelected is wrong on mobile).

On Android/iOS, isSelected() often does not reflect “checked”. Use platform attributes instead to avoid flipping already-correct checkboxes.

-                    // Click only if current state does not match desired state
-                    if (checkbox.isSelected() != check) {
+                    // Click only if current state does not match desired state
+                    boolean current = isChecked(checkbox, platform);
+                    if (current != check) {
                         checkbox.click();
                         logger.info((check ? "Checked" : "Unchecked") + " checkbox: " + checkboxInfo);
                         processedCount++;
                     } else {
                         logger.info("Checkbox already in desired state: " + checkboxInfo);
                         skippedCount++;
                     }

Add helper:

@@
     }
 
+    private boolean isChecked(WebElement checkbox, String platform) {
+        try {
+            switch (platform) {
+                case "Android":
+                    String checked = checkbox.getAttribute("checked");
+                    return "true".equalsIgnoreCase(checked);
+                case "iOS":
+                    String value = checkbox.getAttribute("value");
+                    return "1".equals(value) || "true".equalsIgnoreCase(value);
+                default:
+                    return checkbox.isSelected();
+            }
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
     private String getPlatformType(WebDriver driver) {

Also applies to: 84-96

Comment on lines +51 to +54
String separatorValue = this.separator.getValue().toString();
String inputValue = this.inputData.getValue().toString();
String[] inputValues = inputValue.split(separatorValue);

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Same literal split + validation + parse hardening as other platforms.

Apply the same fix set (Pattern.quote, non-empty SEPARATOR, null checks, robust index parse).

@@
+import java.util.regex.Pattern;
@@
-            String separatorValue = this.separator.getValue().toString();
-            String inputValue = this.inputData.getValue().toString();
-            String[] inputValues = inputValue.split(separatorValue);
+            if (separator == null || separator.getValue() == null) {
+                setErrorMessage("SEPARATOR is required");
+                return Result.FAILED;
+            }
+            if (inputData == null || inputData.getValue() == null) {
+                setErrorMessage("TEST-DATA is required");
+                return Result.FAILED;
+            }
+            String separatorValue = String.valueOf(this.separator.getValue());
+            if (separatorValue.isEmpty()) {
+                setErrorMessage("SEPARATOR cannot be empty");
+                return Result.FAILED;
+            }
+            String inputValue = String.valueOf(this.inputData.getValue());
+            String[] inputValues = inputValue.split(Pattern.quote(separatorValue), -1);
@@
-            int currentIterationIndexValue;
-            if (currentIterationIndexData != null) {
-                currentIterationIndexValue = Integer.parseInt(currentIterationIndexData.toString());
-            } else {
-                logger.info("Current iteration index is null");
-                currentIterationIndexValue = 0;
-            }
+            int currentIterationIndexValue = 0;
+            if (currentIterationIndexData != null) {
+                try {
+                    currentIterationIndexValue = Integer.parseInt(currentIterationIndexData.toString().trim());
+                } catch (NumberFormatException nfe) {
+                    logger.warn("Invalid currentIterationIndexData '{}', defaulting to 0", currentIterationIndexData);
+                }
+            } else {
+                logger.info("Current iteration index is null; starting at 0");
+            }
+            if (currentIterationIndexValue < 0) {
+                logger.warn("Negative iteration index {}; clamping to 0", currentIterationIndexValue);
+                currentIterationIndexValue = 0;
+            }
@@
-            logger.info("Stored next index" + indexedRuntimeVariableName + " = " + currentIterationIndexValue);
+            logger.info("Stored next index " + indexedRuntimeVariableName + " = " + currentIterationIndexValue);

Also applies to: 63-71

🤖 Prompt for AI Agents
In
list_data_structure_actions/src/main/java/com/testsigma/addons/ios/WhileLoopStringBySeparator.java
around lines 51-54 (and also apply same changes to 63-71): the code currently
calls toString() on separator and inputData and uses String.split with the raw
separator, without null/empty checks or robust index parsing. Add null checks
for this.separator and this.inputData before calling getValue()/toString();
ensure separator is not empty (throw or handle invalid separator); use
java.util.regex.Pattern.quote(separator) when splitting to avoid regex
meta-characters; guard against empty input and zero-length split results; and
parse any numeric index values with Integer.parseInt inside a try/catch,
validating bounds before use. Ensure all of these validations are applied in
both the first block (lines ~51-54) and the other block (~63-71).

Comment on lines +51 to +54
String separatorValue = this.separator.getValue().toString();
String inputValue = this.inputData.getValue().toString();
String[] inputValues = inputValue.split(separatorValue);

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Literal split and input/index hardening.

Same corrective changes as Web.

@@
+import java.util.regex.Pattern;
@@
-            String separatorValue = this.separator.getValue().toString();
-            String inputValue = this.inputData.getValue().toString();
-            String[] inputValues = inputValue.split(separatorValue);
+            if (separator == null || separator.getValue() == null) {
+                setErrorMessage("SEPARATOR is required");
+                return Result.FAILED;
+            }
+            if (inputData == null || inputData.getValue() == null) {
+                setErrorMessage("TEST-DATA is required");
+                return Result.FAILED;
+            }
+            String separatorValue = String.valueOf(this.separator.getValue());
+            if (separatorValue.isEmpty()) {
+                setErrorMessage("SEPARATOR cannot be empty");
+                return Result.FAILED;
+            }
+            String inputValue = String.valueOf(this.inputData.getValue());
+            String[] inputValues = inputValue.split(Pattern.quote(separatorValue), -1);
@@
-            int currentIterationIndexValue;
-            if (currentIterationIndexData != null) {
-                currentIterationIndexValue = Integer.parseInt(currentIterationIndexData.toString());
-            } else {
-                logger.info("Current iteration index is null");
-                currentIterationIndexValue = 0;
-            }
+            int currentIterationIndexValue = 0;
+            if (currentIterationIndexData != null) {
+                try {
+                    currentIterationIndexValue = Integer.parseInt(currentIterationIndexData.toString().trim());
+                } catch (NumberFormatException nfe) {
+                    logger.warn("Invalid currentIterationIndexData '{}', defaulting to 0", currentIterationIndexData);
+                }
+            } else {
+                logger.info("Current iteration index is null; starting at 0");
+            }
+            if (currentIterationIndexValue < 0) {
+                logger.warn("Negative iteration index {}; clamping to 0", currentIterationIndexValue);
+                currentIterationIndexValue = 0;
+            }
@@
-            logger.info("Stored next index" + indexedRuntimeVariableName + " = " + currentIterationIndexValue);
+            logger.info("Stored next index " + indexedRuntimeVariableName + " = " + currentIterationIndexValue);

Also applies to: 63-71

🤖 Prompt for AI Agents
In
list_data_structure_actions/src/main/java/com/testsigma/addons/mobileweb/WhileLoopStringBySeparator.java
around lines 51-54 (and also apply the same fixes to lines 63-71): harden input
and separator handling to avoid NPEs and incorrect splitting — replace direct
this.separator.getValue().toString() and this.inputData.getValue().toString()
with safe conversions (e.g., Objects.toString(value, "") or explicit null
checks), use Pattern.quote(separator) when calling split to treat the separator
as a literal, handle empty separators appropriately (avoid infinite split), use
split(..., -1) if trailing empty tokens must be preserved, and add bounds checks
before indexing into the resulting array (validate array length and the loop
index) so you never assume a non-null array or valid index.

Comment on lines +51 to +54
String separatorValue = this.separator.getValue().toString();
String inputValue = this.inputData.getValue().toString();
String[] inputValues = inputValue.split(separatorValue);

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Make splitting literal-safe, validate inputs, and parse index robustly.

split(...) treats SEPARATOR as regex and will mis-split on chars like ".", "|", "+". Also add guards for empty/null inputs and safe index parsing with a negative-index clamp.

Apply:

@@
+import java.util.regex.Pattern;
@@
-            String runtimeVariableName = runtimeVariable.getValue().toString();
+            // Validate inputs
+            if (runtimeVariable == null || runtimeVariable.getValue() == null ||
+                String.valueOf(runtimeVariable.getValue()).trim().isEmpty()) {
+                setErrorMessage("RUNTIME-VARIABLE is required and cannot be empty");
+                return Result.FAILED;
+            }
+            if (separator == null || separator.getValue() == null) {
+                setErrorMessage("SEPARATOR is required");
+                return Result.FAILED;
+            }
+            if (inputData == null || inputData.getValue() == null) {
+                setErrorMessage("TEST-DATA is required");
+                return Result.FAILED;
+            }
+
+            String runtimeVariableName = String.valueOf(runtimeVariable.getValue());
             String indexedRuntimeVariableName = runtimeVariableName + "_TSIndex"; // variable to hold index value
 
-            String separatorValue = this.separator.getValue().toString();
-            String inputValue = this.inputData.getValue().toString();
-            String[] inputValues = inputValue.split(separatorValue);
+            String separatorValue = String.valueOf(this.separator.getValue());
+            if (separatorValue.isEmpty()) {
+                setErrorMessage("SEPARATOR cannot be empty");
+                return Result.FAILED;
+            }
+            String inputValue = String.valueOf(this.inputData.getValue());
+            // Use literal split and preserve trailing empties to iterate consistently
+            String[] inputValues = inputValue.split(Pattern.quote(separatorValue), -1);
@@
-            int currentIterationIndexValue;
-            if (currentIterationIndexData != null) {
-                currentIterationIndexValue = Integer.parseInt(currentIterationIndexData.toString());
-            } else {
-                logger.info("Current iteration index is null");
-                currentIterationIndexValue = 0;
-            }
+            int currentIterationIndexValue = 0;
+            if (currentIterationIndexData != null) {
+                try {
+                    currentIterationIndexValue = Integer.parseInt(currentIterationIndexData.toString().trim());
+                } catch (NumberFormatException nfe) {
+                    logger.warn("Invalid currentIterationIndexData '{}', defaulting to 0", currentIterationIndexData);
+                    currentIterationIndexValue = 0;
+                }
+            } else {
+                logger.info("Current iteration index is null; starting at 0");
+            }
+            if (currentIterationIndexValue < 0) {
+                logger.warn("Negative iteration index {}; clamping to 0", currentIterationIndexValue);
+                currentIterationIndexValue = 0;
+            }
@@
-            logger.info("Stored next index" + indexedRuntimeVariableName + " = " + currentIterationIndexValue);
+            logger.info("Stored next index " + indexedRuntimeVariableName + " = " + currentIterationIndexValue);

Also applies to: 63-71

Comment on lines +13 to +17
@Action(actionText = "Iterate SEPARATOR separated values in TEST-DATA and store current iteration value in RUNTIME-VARIABLE",
description = "Iterate SEPARATOR separated values in TEST-DATA and store current iteration value in RUNTIME-VARIABLE",
displayName = "Store the current iteration value from string with separator SEPARATOR STRING-WITH-SEPARATOR RUNTIME-VARIABLE",
applicationType = ApplicationType.WINDOWS_ADVANCED,
actionType = StepActionType.WHILE_LOOP)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Unify TEST-DATA reference and clarify display name.

The field uses reference "STRING-WITH-SEPARATOR" but action text mentions "TEST-DATA". This inconsistency will confuse users and breaks cross-platform parity.

@@
-@Action(actionText = "Iterate SEPARATOR separated values in TEST-DATA and store current iteration value in RUNTIME-VARIABLE",
-        description = "Iterate SEPARATOR separated values in TEST-DATA and store current iteration value in RUNTIME-VARIABLE",
-        displayName = "Store the current iteration value from string with separator SEPARATOR STRING-WITH-SEPARATOR RUNTIME-VARIABLE",
+@Action(actionText = "Iterate SEPARATOR-separated values in TEST-DATA and store current iteration value in RUNTIME-VARIABLE",
+        description = "Iterate SEPARATOR-separated values in TEST-DATA and store current iteration value in RUNTIME-VARIABLE",
+        displayName = "Store current iteration from SEPARATOR-separated TEST-DATA into RUNTIME-VARIABLE",
         applicationType = ApplicationType.WINDOWS_ADVANCED,
         actionType = StepActionType.WHILE_LOOP)
@@
-    @TestData(reference = "STRING-WITH-SEPARATOR")
+    @TestData(reference = "TEST-DATA")
     private com.testsigma.sdk.TestData inputData;

Also applies to: 23-25

🤖 Prompt for AI Agents
In
list_data_structure_actions/src/main/java/com/testsigma/addons/windowsAdvanced/WhileLoopStringBySeparator.java
around lines 13-17 and 23-25, the annotation and displayName use inconsistent
parameter names ("TEST-DATA" in actionText/description vs
"STRING-WITH-SEPARATOR" in the field), which is confusing and breaks parity;
update the actionText, description, and displayName to consistently reference
the same parameter name (choose either TEST-DATA or STRING-WITH-SEPARATOR) and
update any UI-facing displayName to clearly describe inputs as "SEPARATOR" and
the chosen data parameter (e.g., "Store the current iteration value from
TEST-DATA using separator SEPARATOR into RUNTIME-VARIABLE"), ensuring all
occurrences on the listed lines are changed to the unified name.

Comment on lines +47 to +55
String separatorValue = this.separator.getValue().toString();
String inputValue = this.inputData.getValue().toString();
String[] inputValues = inputValue.split(separatorValue);

// Get the current iteration index
Object currentIterationIndexData = null;
try {
currentIterationIndexData = currentIterationIndexProvider.getRuntimeData(indexedRuntimeVariableName);
} catch (Exception ex) {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Use literal split, validate inputs, and harden index parsing.

Same issues as Web: regex split, empty/null inputs, unsafe parse.

@@
+import java.util.regex.Pattern;
@@
-            String runtimeVariableName = runtimeVariable.getValue().toString();
+            if (runtimeVariable == null || runtimeVariable.getValue() == null ||
+                String.valueOf(runtimeVariable.getValue()).trim().isEmpty()) {
+                setErrorMessage("RUNTIME-VARIABLE is required and cannot be empty");
+                return Result.FAILED;
+            }
+            if (separator == null || separator.getValue() == null) {
+                setErrorMessage("SEPARATOR is required");
+                return Result.FAILED;
+            }
+            if (inputData == null || inputData.getValue() == null) {
+                setErrorMessage("TEST-DATA is required");
+                return Result.FAILED;
+            }
+            String runtimeVariableName = String.valueOf(runtimeVariable.getValue());
             String indexedRuntimeVariableName = runtimeVariableName + "_TSIndex"; // variable to hold index value
 
-            String separatorValue = this.separator.getValue().toString();
-            String inputValue = this.inputData.getValue().toString();
-            String[] inputValues = inputValue.split(separatorValue);
+            String separatorValue = String.valueOf(this.separator.getValue());
+            if (separatorValue.isEmpty()) {
+                setErrorMessage("SEPARATOR cannot be empty");
+                return Result.FAILED;
+            }
+            String inputValue = String.valueOf(this.inputData.getValue());
+            String[] inputValues = inputValue.split(Pattern.quote(separatorValue), -1);
@@
-            int currentIterationIndexValue;
-            if (currentIterationIndexData != null) {
-                currentIterationIndexValue = Integer.parseInt(currentIterationIndexData.toString());
-            } else {
-                logger.info("Current iteration index is null");
-                currentIterationIndexValue = 0;
-            }
+            int currentIterationIndexValue = 0;
+            if (currentIterationIndexData != null) {
+                try {
+                    currentIterationIndexValue = Integer.parseInt(currentIterationIndexData.toString().trim());
+                } catch (NumberFormatException nfe) {
+                    logger.warn("Invalid currentIterationIndexData '{}', defaulting to 0", currentIterationIndexData);
+                    currentIterationIndexValue = 0;
+                }
+            } else {
+                logger.info("Current iteration index is null; starting at 0");
+            }
+            if (currentIterationIndexValue < 0) {
+                logger.warn("Negative iteration index {}; clamping to 0", currentIterationIndexValue);
+                currentIterationIndexValue = 0;
+            }
@@
-            logger.info("Stored next index" + indexedRuntimeVariableName + " = " + currentIterationIndexValue);
+            logger.info("Stored next index " + indexedRuntimeVariableName + " = " + currentIterationIndexValue);

Also applies to: 59-67

@ManojTestsigma ManojTestsigma merged commit d332e93 into dev Nov 12, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants