Loops let you repeat actions — whether it’s iterating through test data, checking multiple elements, or retrying flaky operations. This guide covers every loop type in TypeScript with real Playwright examples you’ll use daily in test automation.
📖 What You’ll Learn: for loop, while loop, do…while, for…of, for…in, forEach, break/continue, and looping through Playwright elements.
🔁 for Loop
The classic loop — you control the start, end, and step.
// Basic for loop
for (let i: number = 0; i < 5; i++) {
console.log('Iteration:', i);
}
// Output: 0, 1, 2, 3, 4
// Counting backwards
for (let i: number = 10; i > 0; i -= 2) {
console.log(i);
}
// Output: 10, 8, 6, 4, 2
// Looping through an array by index
let browsers: string[] = ['chromium', 'firefox', 'webkit'];
for (let i = 0; i < browsers.length; i++) {
console.log(`Browser ${i + 1}: ${browsers[i]}`);
}
🔄 while and do...while Loops
// while — checks condition BEFORE each iteration
let attempts: number = 0;
while (attempts < 3) {
console.log(`Attempt ${attempts + 1}`);
attempts++;
}
// do...while — runs at least ONCE, then checks condition
let input: string = '';
do {
input = 'valid'; // simulating user input
console.log('Processing input:', input);
} while (input === '');
// Retry pattern (common in test automation)
let retryCount: number = 0;
let success: boolean = false;
while (!success && retryCount < 3) {
try {
// attempt some operation
success = true;
console.log('Operation succeeded!');
} catch {
retryCount++;
console.log(`Retry ${retryCount}/3`);
}
}
⚠️ Always include a way to exit while loops (increment a counter, set a flag). An infinite loop will crash your tests!
🎯 for...of and for...in Loops
// for...of — iterate over VALUES (arrays, strings, maps)
let testCases: string[] = ['login', 'signup', 'checkout'];
for (const tc of testCases) {
console.log('Running test:', tc);
}
// for...in — iterate over KEYS/INDICES (objects)
let config = { baseURL: 'https://sqatools.in', timeout: 30000, retries: 2 };
for (const key in config) {
console.log(`${key}: ${config[key as keyof typeof config]}`);
}
// Iterating over a Map
let testData = new Map();
testData.set('user1', 'admin@test.com');
testData.set('user2', 'user@test.com');
for (const [key, value] of testData) {
console.log(`${key} -> ${value}`);
}
💡 Quick Rule: Use for...of for arrays and iterable values. Use for...in for object keys. Never use for...in on arrays — it iterates over indices as strings, which causes bugs.
📋 forEach and Array Methods
let scores: number[] = [85, 92, 78, 95, 88];
// forEach — run a function for each element
scores.forEach((score, index) => {
console.log(`Student ${index + 1}: ${score}`);
});
// map — transform each element into a new array
let grades = scores.map(s => s >= 90 ? 'A' : s >= 80 ? 'B' : 'C');
console.log(grades); // ['B', 'A', 'C', 'A', 'B']
// filter — keep only elements that match
let topScores = scores.filter(s => s >= 90);
console.log(topScores); // [92, 95]
// find — get the first match
let firstTop = scores.find(s => s >= 90);
console.log(firstTop); // 92
// every/some — check all or any
let allPassed = scores.every(s => s >= 60); // true
let anyPerfect = scores.some(s => s === 100); // false
⏹️ break and continue
// break — exit the loop entirely
for (let i = 0; i < 10; i++) {
if (i === 5) break;
console.log(i);
}
// Output: 0, 1, 2, 3, 4
// continue — skip current iteration, go to next
for (let i = 0; i < 10; i++) {
if (i % 2 === 0) continue; // skip even numbers
console.log(i);
}
// Output: 1, 3, 5, 7, 9
🎭 Loops in Playwright — Real Examples
import { test, expect } from '@playwright/test';
test('iterate through page elements', async ({ page }) => {
await page.goto('https://sqatools.in');
// Get all navigation links and verify each one
const navLinks = page.locator('nav a');
const count = await navLinks.count();
for (let i = 0; i < count; i++) {
const text = await navLinks.nth(i).textContent();
const href = await navLinks.nth(i).getAttribute('href');
console.log(`Link ${i + 1}: ${text} -> ${href}`);
expect(href).not.toBeNull();
}
});
// Data-driven test with for...of
const testUsers = [
{ email: 'admin@test.com', role: 'admin' },
{ email: 'user@test.com', role: 'user' },
{ email: 'guest@test.com', role: 'guest' },
];
for (const user of testUsers) {
test(`login as ${user.role}`, async ({ page }) => {
await page.goto('/login');
await page.fill('#email', user.email);
await page.fill('#password', 'test123');
await page.click('#login-btn');
await expect(page.locator('.role-badge')).toHaveText(user.role);
});
}
❓ FAQ
🤔 What is the difference between for...of and for...in?
for...of iterates over values (arrays, strings). for...in iterates over keys/indices (objects). Use for...of for arrays and for...in for object properties.
🤔 How do I loop through Playwright locators?
Use locator.count() to get the number of matches, then use a for loop with locator.nth(i) to access each element individually.
🎯 Next Steps
- 📘 TypeScript Operators
- 📘 TypeScript Conditions
- 📘 TypeScript Functions — Write reusable code
- 🎬 SqaToolsByDY on YouTube
🎬 Watch the full TypeScript tutorial series on YouTube!
Subscribe to SqaToolsByDY • Practice on sqatools.in