JavaScript Loop Practice Programs with Solutions (32 Programs)

Practise JavaScript loops with 32 programs, each with a full solution, the exact output and a short explanation. The programs start with the basics, move to intermediate problems and finish with real-world scenarios from test automation, such as test data, prices, form inputs and test results. They are written for testers learning JavaScript for Playwright.

Advertisement

How to practise: read the task, write your own solution first, then open Show solution to compare. Run any program with node program.js.

New to this topic? Read the JavaScript Loops lesson first.

JavaScript Beginner Programs

1. Print 1 to 5 with a for loopBeginner

Print the numbers 1 to 5 on one line.

Show solution
let line = '';
for (let i = 1; i <= 5; i++) {
  line += i + ' ';
}
console.log(line.trim());

Output

1 2 3 4 5

Explanation: a for loop has a start (let i = 1), a condition (i &lt;= 5) and an update (i++).

2. Countdown with a while loopBeginner

Print a countdown from 5 to 1 followed by 'Go!'.

Show solution
let n = 5;
while (n > 0) {
  console.log(n);
  n--;
}
console.log('Go!');

Output

5
4
3
2
1
Go!

Explanation: while repeats as long as its condition is true. Update the variable inside, or the loop never ends.

3. Sum of 1 to 100Beginner

Add up all numbers from 1 to 100.

Show solution
let sum = 0;
for (let i = 1; i <= 100; i++) {
  sum += i;
}
console.log('Sum:', sum);

Output

Sum: 5050

Explanation: an accumulator variable collects the running total on each iteration.

4. Multiplication tableBeginner

Print the multiplication table of 7 from 1 to 10.

Show solution
for (let i = 1; i <= 10; i++) {
  console.log(`7 x ${i} = ${7 * i}`);
}

Output

7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35
7 x 6 = 42
7 x 7 = 49
7 x 8 = 56
7 x 9 = 63
7 x 10 = 70

Explanation: the loop counter supplies the multiplier on each pass.

5. Even numbers up to 20Beginner

Print all even numbers from 2 to 20 by stepping 2 at a time.

Show solution
const evens = [];
for (let i = 2; i <= 20; i += 2) {
  evens.push(i);
}
console.log(evens.join(', '));

Output

2, 4, 6, 8, 10, 12, 14, 16, 18, 20

Explanation: the update step can be any expression, such as i += 2.

6. Loop over an array with for…ofBeginner

Print each browser name from an array.

Show solution
const browsers = ['chromium', 'firefox', 'webkit'];
for (const browser of browsers) {
  console.log('Running on', browser);
}

Output

Running on chromium
Running on firefox
Running on webkit

Explanation: for...of gives each value directly, which is the cleanest way to read an array.

7. Index and value with entries()Beginner

Print each test name with its position, starting at 1.

Show solution
const tests = ['login', 'search', 'checkout'];
for (const [index, name] of tests.entries()) {
  console.log(`${index + 1}. ${name}`);
}

Output

1. login
2. search
3. checkout

Explanation: entries() yields [index, value] pairs that you can destructure.

8. Loop over object keys with for…inBeginner

Print every key and value of a config object.

Show solution
const config = { browser: 'chromium', retries: 2, headless: true };
for (const key in config) {
  console.log(`${key} = ${config[key]}`);
}

Output

browser = chromium
retries = 2
headless = true

Explanation: for...in iterates over an object’s keys. Use bracket notation to read each value.

9. Characters of a stringBeginner

Print each character of 'QA' and count the letters in 'Playwright'.

Show solution
for (const ch of 'QA') console.log(ch);
let count = 0;
for (const ch of 'Playwright') count++;
console.log('Letters:', count);

Output

Q
A
Letters: 10

Explanation: strings are iterable, so for...of visits each character.

10. do…while runs at least onceBeginner

Show that do...while runs its body once even when the condition is false.

Show solution
let attempts = 10;
do {
  console.log('Attempt', attempts);
  attempts++;
} while (attempts < 3);
console.log('Finished');

Output

Attempt 10
Finished

Explanation: do...while checks the condition after the body, so the body always runs at least once.

JavaScript Intermediate Programs

11. FactorialIntermediate

Calculate 5! and 10! with a loop.

Show solution
function factorial(n) {
  let result = 1;
  for (let i = 2; i <= n; i++) result *= i;
  return result;
}
console.log(factorial(5));
console.log(factorial(10));

Output

120
3628800

Explanation: multiply an accumulator by each number from 2 to n.

12. Fibonacci seriesIntermediate

Print the first 10 Fibonacci numbers.

Show solution
const fib = [0, 1];
for (let i = 2; i < 10; i++) {
  fib.push(fib[i - 1] + fib[i - 2]);
}
console.log(fib.join(' '));

Output

0 1 1 2 3 5 8 13 21 34

Explanation: each new term is the sum of the previous two.

13. Reverse a numberIntermediate

Reverse the digits of 12345 using a while loop and %.

Show solution
let num = 12345;
let reversed = 0;
while (num > 0) {
  reversed = reversed * 10 + (num % 10);
  num = Math.floor(num / 10);
}
console.log(reversed);

Output

54321

Explanation: % 10 takes the last digit and Math.floor(num / 10) removes it.

14. Prime check with breakIntermediate

Check whether 29 and 33 are prime, stopping as soon as a divisor is found.

Show solution
for (const n of [29, 33]) {
  let isPrime = n > 1;
  for (let d = 2; d * d <= n; d++) {
    if (n % d === 0) {
      isPrime = false;
      break;
    }
  }
  console.log(n, isPrime ? 'is prime' : 'is not prime');
}

Output

29 is prime
33 is not prime

Explanation: break exits the loop early. Checking divisors up to √n is enough.

15. Skip values with continueIntermediate

Print numbers 1 to 10, skipping multiples of 3.

Show solution
const result = [];
for (let i = 1; i <= 10; i++) {
  if (i % 3 === 0) continue;
  result.push(i);
}
console.log(result.join(' '));

Output

1 2 4 5 7 8 10

Explanation: continue skips the rest of the current iteration and moves to the next one.

16. Nested loops: star patternIntermediate

Print a right-angled triangle of stars with 4 rows.

Show solution
for (let row = 1; row <= 4; row++) {
  let line = '';
  for (let col = 1; col <= row; col++) line += '*';
  console.log(line);
}

Output

*
**
***
****

Explanation: the inner loop runs once per row and its length depends on the outer counter.

17. Count vowelsIntermediate

Count the vowels in 'Automation Testing'.

Show solution
const text = 'Automation Testing';
let vowels = 0;
for (const ch of text.toLowerCase()) {
  if ('aeiou'.includes(ch)) vowels++;
}
console.log('Vowels:', vowels);

Output

Vowels: 8

Explanation: loop over each character and count the ones that match a condition.

18. Find the maximum without Math.maxIntermediate

Find the largest value in [34, 78, 12, 99, 45] with a loop.

Show solution
const values = [34, 78, 12, 99, 45];
let max = values[0];
for (const v of values) {
  if (v > max) max = v;
}
console.log('Max:', max);

Output

Max: 99

Explanation: keep the best value seen so far and replace it whenever a larger one appears.

19. Labeled break out of nested loopsIntermediate

Search a grid for the value 7 and stop both loops when it is found.

Show solution
const grid = [[1, 2, 3], [4, 7, 6], [7, 8, 9]];
outer: for (let r = 0; r < grid.length; r++) {
  for (let c = 0; c < grid[r].length; c++) {
    if (grid[r][c] === 7) {
      console.log(`Found 7 at row ${r}, col ${c}`);
      break outer;
    }
  }
}

Output

Found 7 at row 1, col 1

Explanation: a label lets break exit the outer loop, not just the inner one.

20. Palindrome checkIntermediate

Check whether 'level' and 'test' are palindromes using two pointers.

Show solution
for (const word of ['level', 'test']) {
  let isPalindrome = true;
  for (let i = 0, j = word.length - 1; i < j; i++, j--) {
    if (word[i] !== word[j]) {
      isPalindrome = false;
      break;
    }
  }
  console.log(word, isPalindrome);
}

Output

level true
test false

Explanation: compare characters from both ends moving inwards. A for loop can update two variables at once.

JavaScript Real-World QA Scenario Programs

21. Run tests in every browserReal-world

Simulate running three tests in three browsers and print each combination.

Show solution
const browsers = ['chromium', 'firefox', 'webkit'];
const tests = ['login', 'search', 'checkout'];
let runs = 0;
for (const browser of browsers) {
  for (const test of tests) {
    runs++;
  }
}
console.log(`${tests.length} tests x ${browsers.length} browsers = ${runs} runs`);

Output

3 tests x 3 browsers = 9 runs

Explanation: nested loops visit every combination, just like Playwright projects multiply test runs.

22. Retry until successReal-world

Retry a flaky action up to 3 times, where it succeeds on the 3rd attempt.

Show solution
const MAX = 3;
let attempt = 0;
let success = false;
while (attempt < MAX && !success) {
  attempt++;
  success = attempt === 3;
  console.log(`Attempt ${attempt}: ${success ? 'passed' : 'failed'}`);
}
console.log(success ? 'Action succeeded' : 'Gave up');

Output

Attempt 1: failed
Attempt 2: failed
Attempt 3: passed
Action succeeded

Explanation: the loop stops when it succeeds or runs out of attempts, whichever comes first.

23. Poll for a status changeReal-world

Poll a job status list until it reports 'done', with a maximum of 5 polls.

Show solution
const statuses = ['queued', 'running', 'running', 'done', 'done'];
let polls = 0;
let status;
do {
  status = statuses[polls];
  polls++;
  console.log(`Poll ${polls}: ${status}`);
} while (status !== 'done' && polls < 5);

Output

Poll 1: queued
Poll 2: running
Poll 3: running
Poll 4: done

Explanation: polling loops need both a success condition and a limit, so tests never hang forever.

24. Summarise test resultsReal-world

Count passed, failed and skipped results in one loop.

Show solution
const results = ['passed', 'failed', 'passed', 'skipped', 'passed', 'failed'];
const summary = { passed: 0, failed: 0, skipped: 0 };
for (const r of results) summary[r]++;
console.log(summary);

Output

{ passed: 3, failed: 2, skipped: 1 }

Explanation: use each status as a key in a counter object and increment it inside the loop.

25. Find the first failed testReal-world

Stop at the first failed test and print its name and position.

Show solution
const runs = [
  { name: 'login', status: 'passed' },
  { name: 'search', status: 'failed' },
  { name: 'checkout', status: 'failed' }
];
for (let i = 0; i < runs.length; i++) {
  if (runs[i].status === 'failed') {
    console.log(`First failure: ${runs[i].name} (#${i + 1})`);
    break;
  }
}

Output

First failure: search (#2)

Explanation: break stops as soon as the first match is found, so later items are not checked.

26. Total a shopping cartReal-world

Loop over cart items and calculate the total price.

Show solution
const cart = [
  { item: 'Keyboard', price: 1499, qty: 1 },
  { item: 'Mouse', price: 599, qty: 2 },
  { item: 'Cable', price: 199, qty: 3 }
];
let total = 0;
for (const { price, qty } of cart) total += price * qty;
console.log('Cart total:', total);

Output

Cart total: 3294

Explanation: destructuring in the for...of header reads just the fields the calculation needs.

27. Generate test usersReal-world

Generate 3 test users with numbered usernames and emails.

Show solution
const users = [];
for (let i = 1; i <= 3; i++) {
  users.push({ username: `qa_user${i}`, email: `qa_user${i}@example.com` });
}
for (const u of users) console.log(u.username, u.email);

Output

qa_user1 qa_user1@example.com
qa_user2 qa_user2@example.com
qa_user3 qa_user3@example.com

Explanation: a counter loop is a simple way to build numbered test data.

28. Validate every emailReal-world

Check each email in a list and print the invalid ones.

Show solution
const emails = ['a@test.com', 'bad-email', 'qa@shop.in', 'no@domain'];
const pattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
for (const email of emails) {
  if (!pattern.test(email)) console.log('Invalid:', email);
}
console.log('Checked', emails.length, 'emails');

Output

Invalid: bad-email
Invalid: no@domain
Checked 4 emails

Explanation: a loop applies the same validation to every item and reports only the failures.

29. Paginate through resultsReal-world

Read pages of results until a page is empty, counting the total items.

Show solution
const pages = [[1, 2, 3], [4, 5, 6], [7], []];
let page = 0;
let total = 0;
while (pages[page].length > 0) {
  total += pages[page].length;
  page++;
}
console.log(`Read ${page} pages, ${total} items`);

Output

Read 3 pages, 7 items

Explanation: pagination loops continue until the server returns an empty page.

30. Compare two listsReal-world

Find expected menu items missing from the actual menu.

Show solution
const expected = ['Home', 'Products', 'About', 'Contact'];
const actual = ['Home', 'About', 'Blog'];
const missing = [];
for (const item of expected) {
  if (!actual.includes(item)) missing.push(item);
}
console.log('Missing:', missing.join(', '));

Output

Missing: Products, Contact

Explanation: loop over one list and check membership in the other to find differences.

31. Table rows to objectsReal-world

Convert table rows (arrays) into objects using a header row.

Show solution
const header = ['id', 'name', 'status'];
const rows = [['1', 'login', 'pass'], ['2', 'search', 'fail']];
for (const row of rows) {
  const record = {};
  for (let i = 0; i < header.length; i++) record[header[i]] = row[i];
  console.log(record);
}

Output

{ id: '1', name: 'login', status: 'pass' }
{ id: '2', name: 'search', status: 'fail' }

Explanation: the inner loop pairs each header with the value at the same position, which is how web tables are usually read.

32. Wait with async delays in a loopReal-world

Simulate three steps that each wait 20 ms, running one after another with for...of and await.

Show solution
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const steps = ['open page', 'fill form', 'submit'];
for (const step of steps) {
  await sleep(20);
  console.log('Done:', step);
}
console.log('All steps finished in order');

Output

Done: open page
Done: fill form
Done: submit
All steps finished in order

Explanation: for...of with await runs async steps sequentially, which is how Playwright actions run. forEach would not wait. (Top-level await works in ES modules, such as .mjs files or "type": "module".)

Keep Practising

1 thought on “JavaScript Loop Practice Programs with Solutions (32 Programs)”

Leave a Comment