With loops, you can repeat a sequence of test steps a set number of times within a single test run. Loops are useful when your test needs to perform the same action for each item in a list, such as selecting every option in a dropdown, adding multiple items to a cart, or checking each row in a table. This article explains how create and work with loops in your tests, including how to:
- Create a loop
- Loop through items on a page
- Loop through items in an array
- Use the loop index variable
- Exit a loop early
- Replay loops in the Trainer
- Review loop output in test runs
Limitation
Looping isn’t supported for flows in API tests.
Create a loop
In the mabl Trainer, take the following steps to create a loop:
-
Click on + (Add step) > Loops.
-
Loops are saved as flows in mabl. Give the flow a name.
-
Click on the Looping tab.
-
Select a looping option:
- Loop using a fixed number: Repeat the steps a set number of times. The value must be a valid number between 2 and 500.
- Loop using a variable: Set the number of iterations dynamically from a number variable (also 2 to 500).
- Loop using elements: Loop through all the elements that match a CSS query. Supported for browser tests only.
- Loop using a variable array: Loop once for each item in an array-type variable. Supported for both browser and mobile tests.
You cannot set a flow to loop using a flow parameter.
-
Click OK.
-
With the Trainer cursor inside the Start flow and End flow steps, record the test steps that you would like to repeat in the loop.
Alternatively, you may convert an existing set of test steps into a loop. Create a loop, then drag and drop the Start flow and End flow steps so that they wrap around the test steps you want to repeat in the loop.
When you configure a looping value for a flow, the settings are not applied to other instances of the flow. We recommend using a naming convention in your workspace to identify flows that are intended to function as a loop.
Loop settings
Loop through items on the page
A common use case for loops is repeating steps for each item in a dynamic list on the page, such as dropdown options, table rows, or menu items.
The simplest way to do this is to select Loop using elements when you create the loop. mabl loops through every element that matches a CSS query, and a runtime variable called {{@run.loop_locator}} targets the matching element for the current iteration:
- Create a loop and select Loop using elements.
- Write a CSS query to identify the elements you want to loop through.
- Optional: If the loop includes steps that navigate away from the page or trigger a reload, check Prefetch elements.
- Inside the loop, use
{{@run.loop_locator}}in a custom find step to interact with the current item: click it, assert on its text, or create a variable from its properties.
Prefetch elements
By default, mabl marks elements directly in the DOM to keep track of what has been processed. If the loop navigates away from the page or triggers a reload, this context gets lost. When Prefetch elements is selected, mabl maintains that context, counting the matching elements before the loop starts and iterating strictly by position (index). Because Prefetch elements relies on element positions rather than DOM marks, it assumes that the list re-renders in the exact same order every time you return to the page.
Loop using elements is supported for browser tests only.
Loop using an index variable
If you need a custom XPath selector, or you want to reuse the element count elsewhere in the test, you can loop using an index variable instead:
- Count the items. Use Find Elements to locate the elements you want to loop through. Create a variable from the element count.
- Create a loop using the count variable. Follow the steps above to create a loop and select Loop using a variable, choosing the count variable you just created.
-
Create a zero-based index variable. Inside the loop, create a variable called
indexwith the value{{@run.loop_index-1}}. This is necessary becauserun.loop_indexstarts at 1, but element lists are zero-indexed. See the section on using the loop index for more detail. -
Target each item using the index. Use Find Elements with an XPath or CSS selector that incorporates
{{@index}}to target the current item. For example,(//li[@role="option"])[{{@index}}]. - Perform your action. Click the element, assert on its text, create a variable from its properties, or record any other steps you need to repeat for each item.
If you need to extract text or properties from elements into a list, you can use the snippet generator to write a JavaScript snippet that collects the values you need.
Loop through items in an array
If you’ve collected a list of data from an earlier shared variable or test step, you can loop through it once for each item using Loop using a variable array. This option is great for testing scenarios that require looping through output from an API response or JavaScript snippet. When you create the loop, a runtime variable called {{@run.loop_item}} resolves to the array value at the current iteration.
- Extract an array of data and store it in a variable. For example, you might make an API request to get all the users in an account and store the result in a variable called
account_users. - Create a loop and select Loop using a variable array, choosing the array variable.
- Inside the loop, access the current item with
{{@run.loop_item}}. Use it to search for, interact with, or validate each item in the list.
If the array contains objects, use dot notation inside the curly brackets to access a property. For example, if each item in account_users has an email property, you can assert the email address for every user with {{@run.loop_item.email}}.
Loop using a variable array is supported for both browser and mobile tests.
Use the loop index variable
Within a loop, mabl adds a special, read-only variable called run.loop_index, which starts at 1. To access the loop index, use mabl variable syntax: {{@run.loop_index}}.
Zero-based indexing
Because run.loop_index starts at 1, you’ll need to adjust it when accessing zero-indexed data like arrays or element lists. Create a variable inside the loop with the value {{@run.loop_index-1}} and use that variable in your selectors or data access expressions.
Access loop index in snippets
In snippets, you can access the loop index in one of the following ways:
- Add
{{@run.loop_index}}as a snippet parameter. - Access the loop index from the
mablInputsobject:mablInputs.variables.web.runtime.flow_run_ordinal_index
Exit a loop early
To create a de facto while loop that exits when a specific condition is met, follow these steps:
- Create a variable and assign it a number as a value.
- Create a flow that loops using the variable you just created.
- In the flow, add an IF step that asserts the conditions in which the loop should exit.
- In the IF step, add a variable step that creates a new variable with the same name as the looping variable, and set the value to 0.
- Add an ELSE step.
- In the ELSE step, record the steps that the loop should do if the break conditions are not met.
In the example below, the variable total is initialized to 500. In the loop, as soon as the number of checked checkboxes reaches five, the value of total changes to 0. Updating the value of the looping variable causes the loop to exit early.
Exiting a loop early
This pattern is also useful for polling scenarios, such as refreshing a page until an expected value appears. Set the loop count to a maximum number of retries, then add a condition that exits the loop when the expected element or value is present.
Replay loops in the Trainer
When replaying loops in the mabl Trainer, mabl tries to resume playing the loop at the current index, even if you stopped the loop partway through. Click on the loop dropdown to set the loop to a specific iteration for Trainer playback.
Review loop output in test runs
When you run a test with a loop in the cloud, the test output shows the following tag for each iteration: Loop: {current index}/{total loop count}.
The {total loop count} indicates how many times the loop ran during the test run. This number is not necessarily the same as the configured loop count for the test. For example, if you configured a loop to run 5 times, but the test failed during the third iteration of the loop, the total loop count for the test run will be 3, not 5: Loop: {current index}/3.
Loops vs. DataTables
Loops and DataTable scenarios serve different purposes:
- Loops repeat a subset of steps within a single test run.
- DataTable scenarios run the entire test once per row of data.