---
source_url: "https://support.functionize.com/hc/en-us/articles/32997125931543-Creating-Loops-in-Test-Cases"
title: Creating Loops in Test Cases – Functionize
mirrored_at: 2026-08-04T03:33:47.998Z
host: support.functionize.com
cited_in_42a: true
mirror_canonical: "https://index.42a.ai/support.functionize.com/hc/en-us/articles/32997125931543-Creating-Loops-in-Test-Cases"
---

> **Original source:** https://support.functionize.com/hc/en-us/articles/32997125931543-Creating-Loops-in-Test-Cases

Thorough testing often requires repeating the same task multiple times to validate consistency, accuracy, and functionality. In Functionize, you can achieve this in two main ways:

-   **Page Objects** → Store reusable flows (e.g., login, search, navigation).
-   **Loops** → Repeat an action sequence in a test a fixed number of times or until a condition is met.

Loops provide more precision and flexibility than Page Objects. They allow you to test tasks comprehensively, uncover edge cases, and validate against conditions that may only appear after multiple iterations.

## **Shared Concepts**

**Viewing Completed Loops**

-   By default, the **Browser Results tab** and **Slider View** show only the final iteration.
-   Click **Show All Iterations** to expand and view each iteration with pass/fail results.
-   Each iteration is labeled (L1, L2, L3, etc.) in the first Action of its sequence.

**Visual Indicators in Results**

-   The looped actions are highlighted in a blue wrapper.
-   A **vertical line** appears to the left of all looped Actions.
-   A **dot** marks the first Action in the Loop sequence.
-   A **greater-than (>) icon** in the Action footer highlights all steps in the Loop. Clicking the icon keeps the highlighting visible.
-   Nested loops display additional vertical lines and icons (e.g., L2, L3).

## **Use Cases**

**Shopping Cart Validation**

-   Bug: cart item count did not always match the number of items added.
-   Solution: record a test that loops through adding multiple items, verifying that the display count increases each time.
-   Advanced check: include a Custom JS Action to validate that the **cart total** matches (iteration count × item price).

**Dropdown Category Validation**

-   Goal: ensure each category link in a dynamic menu navigates correctly.
-   Approach: create Variables capturing all category texts and hrefs, then iterate through them with a Custom JS Loop.

## **Adding Loops with Architect**

1.  Record a new test up to the Loop insertion point.
2.  Record the Actions you want repeated.
3.  Open the **Actions Sidebar Panel** → select **Loops**.
4.  Choose:
    -   **X Times** → repeat a fixed number of iterations.
    -   **Custom JS** → define a condition (while logic).
    -   Example: X Times = 10 iterations.
5.  Select the Actions to include (via white dot selectors or range selection).
6.  Click **Add** → Architect groups the Actions under a Loop container.

**Dynamic Verification Example**

-   Edit the Verify Action inside the Loop.
-   Replace a fixed text value (e.g., 1) with a dynamic expression: `{{parseInt(fze.iteration) + 1}}` 
-   This validates against the current iteration number.
-   **Note**: +1 is needed since iterations start at 0.

## **Adding Loops to an Existing Test**

1.  Open the **Test Detail Page**.
2.  From the **Insert Menu** above the first Action in the sequence, click **Loop**.
3.  Choose **X Times** or **Custom JS** and enter values.
4.  Select the Loop End Action → Insert.
5.  Loops are visually denoted in the same way as in Architect (vertical line, dot, L1 icon, > icon).

## **Nested Loops**

Functionize supports nested Loops:

-   Record Parent Loop Actions in Architect.
-   Add Child Loop in the **Test Detail Page**.
-   Visual indicators:
    -   Second vertical line.
    -   L2 notation.
    -   Double greater-than icons in Action footer.

## **Editing Loops**

-   **Edit Actions** → Expand Action within Loop and update.
-   **Insert Actions** → Use standard Insert process when Loop is collapsed.
-   **Delete Actions** → Use normal Delete inside Loop.
-   **Delete Entire Loop** → Removes the Loop wrapper but retains the Actions inside.

## **Advanced Use: Custom JS + Variables**

**Example: Category Menu Validation**

```
Setup Variables

// Capture category link texts

let listElements = Array.from(document.getElementsByClassName("product-categories")[0].childNodes);

fze.local.categorylisttexts = [];

for (let i = 0; i < listElements.length; i++) {

  if (listElements[i].firstChild && listElements[i].firstChild.textContent) { 

fze.local.categorylisttexts.push(listElements[i].firstChild.textContent.trim());

  }

}

// Capture category link hrefs

fze.local.categorylisthrefs = [];

for (let i = 0; i < listElements.length; i++) {

  if (listElements[i].firstChild && listElements[i].firstChild.hasAttribute('href')) {

    fze.local.categorylisthrefs.push(listElements[i].firstChild.getAttribute('href'));

  }

}
```

This creates two arrays:

-   `fze.local.categorylisttexts` → menu labels.
-   `fze.local.categorylisthrefs` → menu URLs.

### Define the Loop Condition

`return fze.iteration < fze.local.categorylisttexts.length;`

### Use Dynamic Expressions

Click link by text:  
`{{fze.local.categorylisttexts[fze.iteration]}}`

Verify correct URL opens:  
`{{fze.local.categorylisthrefs[fze.iteration]}}`

_**Result**:_ The test iterates through each menu option, clicks it, and verifies the correct page loads.

## Loop using timeout and iteration limit

**Code:**

// Initialize startTime globally (persists during the test)

if (!window.startTime) {

window.startTime = Date.now();

}

// Continue loop while both conditions are true

return fze.iteration < 10 && (Date.now() - window.startTime) < 10000;

**Explanation:**

-   `fze.iteration < 10` → stops after 10 iterations.
    
-   `(Date.now() - window.startTime) < 10000` → stops if 10 seconds have passed.
    
-   `window.startTime` is global, persisting across iterations.
    

**Purpose:**

-   Adds a **timeout safeguard** to avoid infinite or long-running loops.
    
-   Ensures loop stops after **max iterations or time limit**, whichever comes first.
    

**Use Case:**

-   Loops where **time or iteration limits** are needed to prevent hanging.
    

## **Best Practices**

-   Use **X Times Loops** for predictable iteration counts.
    -   Variables can be used as iteration counts with SetVariable or TDM test actions.
-   Use **Custom JS Loops** for data-driven or condition-based workflows.
-   Always add **verifications inside Loops** to catch issues mid-iteration.
-   Use **dynamic expressions (e.g.,** `**fze.iteration**`**)** instead of hardcoding values.
-   Nest Loops only when necessary → they can make debugging harder.
-   Keep Loops short and well-scoped.
-   Loops repeat Actions, while Page Objects store reusable flows. Combining both improves maintainability and reusability.
-   Incorporate conditional checks or try/catch logic within Custom JS Loops to handle intermittent failures gracefully.
-   Iteration-specific screenshots help identify exactly which iteration failed.

## **Additional Considerations**

-   Be aware that Loops will increase execution time.
-   Use waits or conditional waits for elements that load slowly or dynamically to mitigate test flakiness.
-   Test action limits still apply to test cases with loops and are cumulative.