JavaScript String Practice Programs with Solutions (32 Programs)

Practise JavaScript strings 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 Strings lesson first.

JavaScript Beginner Programs

1. String lengthBeginner

Print the length of 'Playwright Testing'.

Show solution
const title = 'Playwright Testing';
console.log(title.length);

Output

18

Explanation: length counts every character, including spaces.

2. Upper and lower caseBeginner

Convert 'Login Page' to upper case and lower case.

Show solution
const text = 'Login Page';
console.log(text.toUpperCase());
console.log(text.toLowerCase());

Output

LOGIN PAGE
login page

Explanation: case methods return new strings. The original string is unchanged.

3. First and last characterBeginner

Print the first and last character of 'automation'.

Show solution
const word = 'automation';
console.log(word[0]);
console.log(word.at(-1));

Output

a
n

Explanation: index 0 is the first character, and at(-1) reads from the end.

4. Trim whitespaceBeginner

Remove spaces around ' qa@example.com '.

Show solution
const raw = '   qa@example.com  ';
console.log(`[${raw.trim()}]`);
console.log(`[${raw.trimStart()}]`);

Output

[qa@example.com]
[qa@example.com  ]

Explanation: trim removes whitespace from both ends. trimStart and trimEnd remove one side only.

5. Check if a string contains textBeginner

Check whether 'Order placed successfully' contains 'success' and 'failed'.

Show solution
const message = 'Order placed successfully';
console.log(message.includes('success'));
console.log(message.includes('failed'));

Output

true
false

Explanation: includes returns true or false. It is case-sensitive.

6. startsWith and endsWithBeginner

Check whether a URL starts with https:// and ends with /login.

Show solution
const url = 'https://qa.shop.test/login';
console.log(url.startsWith('https://'));
console.log(url.endsWith('/login'));

Output

true
true

Explanation: these methods check the beginning or end of a string without regular expressions.

7. Extract part of a stringBeginner

Extract 'Play' and 'wright' from 'Playwright' with slice.

Show solution
const tool = 'Playwright';
console.log(tool.slice(0, 4));
console.log(tool.slice(4));
console.log(tool.slice(-6));

Output

Play
wright
wright

Explanation: slice(start, end) stops before end. Negative numbers count from the end.

8. Replace textBeginner

Replace 'staging' with 'qa' in a URL, then replace every space with a dash in a title.

Show solution
const url = 'https://staging.shop.test/staging/home';
console.log(url.replace('staging', 'qa'));
console.log(url.replaceAll('staging', 'qa'));
console.log('My First Test'.replaceAll(' ', '-'));

Output

https://qa.shop.test/staging/home
https://qa.shop.test/qa/home
My-First-Test

Explanation: replace changes only the first match. replaceAll changes every match.

9. Split a sentence into wordsBeginner

Split 'run tests in parallel' into words and count them.

Show solution
const sentence = 'run tests in parallel';
const words = sentence.split(' ');
console.log(words);
console.log('Word count:', words.length);

Output

[ 'run', 'tests', 'in', 'parallel' ]
Word count: 4

Explanation: split turns a string into an array using a separator.

10. Repeat and padBeginner

Print a divider of 20 dashes and pad test IDs to 4 digits.

Show solution
console.log('-'.repeat(20));
for (const id of [7, 42, 315]) console.log('TC-' + String(id).padStart(4, '0'));

Output

--------------------
TC-0007
TC-0042
TC-0315

Explanation: repeat duplicates a string, and padStart fills it to a fixed length.

JavaScript Intermediate Programs

11. Reverse a stringIntermediate

Reverse 'Playwright'.

Show solution
const reversed = 'Playwright'.split('').reverse().join('');
console.log(reversed);

Output

thgirwyalP

Explanation: strings have no reverse, so split into characters, reverse the array and join it again.

12. Palindrome check ignoring case and spacesIntermediate

Check whether 'Never odd or even' is a palindrome.

Show solution
const text = 'Never odd or even';
const clean = text.toLowerCase().replace(/[^a-z0-9]/g, '');
const isPalindrome = clean === [...clean].reverse().join('');
console.log(clean, isPalindrome);

Output

neveroddoreven true

Explanation: normalise the text first (lower case, letters only), then compare it with its reverse.

13. Count occurrences of a characterIntermediate

Count how many times 't' appears in 'test automation tutorial'.

Show solution
const text = 'test automation tutorial';
let count = 0;
for (const ch of text) if (ch === 't') count++;
console.log(count);
console.log(text.split('t').length - 1);

Output

6
6

Explanation: you can loop over characters, or split on the character and count the pieces minus one.

14. Capitalise each wordIntermediate

Convert 'checkout with saved card' to title case.

Show solution
const title = 'checkout with saved card'
  .split(' ')
  .map(word => word[0].toUpperCase() + word.slice(1))
  .join(' ');
console.log(title);

Output

Checkout With Saved Card

Explanation: split into words, capitalise the first letter of each, and join them back.

15. Character frequency mapIntermediate

Count each character in 'banana'.

Show solution
const freq = {};
for (const ch of 'banana') freq[ch] = (freq[ch] || 0) + 1;
console.log(freq);

Output

{ b: 1, a: 3, n: 2 }

Explanation: an object works as a counter, with each character as a key.

16. Anagram checkIntermediate

Check whether 'listen' and 'silent' are anagrams.

Show solution
const normalise = s => [...s.toLowerCase()].sort().join('');
console.log(normalise('listen') === normalise('silent'));
console.log(normalise('test') === normalise('sets'));

Output

true
false

Explanation: anagrams contain the same letters, so their sorted characters match.

17. camelCase to kebab-caseIntermediate

Convert 'loginButtonText' to 'login-button-text'.

Show solution
const camel = 'loginButtonText';
const kebab = camel.replace(/([A-Z])/g, '-$1').toLowerCase();
console.log(kebab);

Output

login-button-text

Explanation: a regular expression inserts a dash before each capital letter, and lower-casing finishes the job.

18. Longest wordIntermediate

Find the longest word in 'Playwright makes cross browser testing reliable'.

Show solution
const words = 'Playwright makes cross browser testing reliable'.split(' ');
let longest = '';
for (const w of words) if (w.length > longest.length) longest = w;
console.log(longest, longest.length);

Output

Playwright 10

Explanation: track the best word while looping, replacing it only when a longer one appears.

19. Truncate long textIntermediate

Write truncate(text, max) that adds ... when text is longer than max.

Show solution
const truncate = (text, max) => (text.length > max ? text.slice(0, max - 3) + '...' : text);
console.log(truncate('Short title', 20));
console.log(truncate('A very long product name that overflows', 20));

Output

Short title
A very long produ...

Explanation: UI tests often check that long names are cut off, so knowing the exact rule helps.

20. Compare strings ignoring caseIntermediate

Compare 'Submit' and 'SUBMIT' case-insensitively in two ways.

Show solution
const a = 'Submit', b = 'SUBMIT';
console.log(a === b);
console.log(a.toLowerCase() === b.toLowerCase());
console.log(a.localeCompare(b, undefined, { sensitivity: 'accent' }) === 0);

Output

false
true
true

Explanation: normalising case, or localeCompare with a sensitivity option, ignores letter case.

JavaScript Real-World QA Scenario Programs

21. Validate an email formatReal-world

Check a list of emails against a simple pattern.

Show solution
const pattern = /^[^\s@]+@[^\s@]+\.[a-z]{2,}$/i;
for (const email of ['qa@example.com', 'qa@example', 'qa example@test.com', 'QA@Shop.IN']) {
  console.log(email.padEnd(20), pattern.test(email) ? 'valid' : 'invalid');
}

Output

qa@example.com       valid
qa@example           invalid
qa example@test.com  invalid
QA@Shop.IN           valid

Explanation: a regular expression describes the allowed format. padEnd aligns the output in columns.

22. Extract the order numberReal-world

Extract ORD-58213 from the confirmation text.

Show solution
const confirmation = 'Thank you! Your order ORD-58213 has been placed.';
const match = confirmation.match(/ORD-\d+/);
console.log(match ? match[0] : 'Not found');

Output

ORD-58213

Explanation: match returns the matched text, so tests can reuse dynamic values shown in the UI.

23. Mask a card numberReal-world

Show only the last 4 digits of '4111 1111 1111 1234'.

Show solution
const card = '4111 1111 1111 1234';
const digits = card.replace(/\s/g, '');
const masked = '**** **** **** ' + digits.slice(-4);
console.log(masked);

Output

**** **** **** 1234

Explanation: remove spaces first so the last four characters are always digits.

24. Build a slug from a titleReal-world

Turn ' Playwright: Getting Started (2026)! ' into 'playwright-getting-started-2026'.

Show solution
const title = '  Playwright: Getting Started (2026)!  ';
const slug = title.trim().toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
console.log(slug);

Output

playwright-getting-started-2026

Explanation: replace every run of non-alphanumeric characters with one dash, then trim dashes from the ends.

25. Parse a key=value cookie stringReal-world

Turn 'session=abc123; theme=dark; lang=en' into an object.

Show solution
const cookieText = 'session=abc123; theme=dark; lang=en';
const cookies = {};
for (const part of cookieText.split('; ')) {
  const [key, value] = part.split('=');
  cookies[key] = value;
}
console.log(cookies);

Output

{ session: 'abc123', theme: 'dark', lang: 'en' }

Explanation: split into pairs, then split each pair at =.

26. Normalise whitespace in UI textReal-world

Collapse extra spaces and line breaks in ' Total:\n ₹1,299 '.

Show solution
const uiText = '  Total:\n   ₹1,299  ';
const normalised = uiText.replace(/\s+/g, ' ').trim();
console.log(normalised);

Output

Total: ₹1,299

Explanation: page text often contains line breaks and indentation. Playwright’s toHaveText normalises whitespace the same way.

27. Check the URL path and queryReal-world

Read the path and the q parameter from a search URL.

Show solution
const url = new URL('https://shop.test/search?q=wireless%20mouse&page=2');
console.log(url.pathname);
console.log(url.searchParams.get('q'));
console.log(url.searchParams.get('page'));

Output

/search
wireless mouse
2

Explanation: the URL class parses URLs and decodes values such as %20, which is safer than slicing strings.

28. Template literal reportReal-world

Build a multi-line test report with a template literal.

Show solution
const name = 'Checkout';
const passed = 18, failed = 2;
const report = `Suite: ${name}
Passed: ${passed}
Failed: ${failed}
Status: ${failed === 0 ? 'GREEN' : 'RED'}`;
console.log(report);

Output

Suite: Checkout
Passed: 18
Failed: 2
Status: RED

Explanation: template literals keep line breaks and can include expressions such as ternaries.

29. Compare expected and actual textReal-world

Report the first position where two strings differ.

Show solution
function firstDiff(a, b) {
  const len = Math.max(a.length, b.length);
  for (let i = 0; i < len; i++) if (a[i] !== b[i]) return i;
  return -1;
}
const expected = 'Welcome back, Asha';
const actual = 'Welcome back, Asha!';
const i = firstDiff(expected, actual);
console.log(i === -1 ? 'Texts match' : `Differs at index ${i}: '${expected[i] ?? ''}' vs '${actual[i] ?? ''}'`);

Output

Differs at index 18: '' vs '!'

Explanation: pinpointing the first difference makes text-assertion failures much quicker to debug.

30. Extract all hashtagsReal-world

Find all hashtags in a social post.

Show solution
const post = 'Learning #Playwright with #TypeScript for #QA automation';
const tags = post.match(/#\w+/g) || [];
console.log(tags.join(', '));
console.log(tags.length);

Output

#Playwright, #TypeScript, #QA
3

Explanation: the g flag returns every match. || [] avoids errors when nothing matches.

31. Format a name for displayReal-world

Convert ' ASHA sharma ' into 'Asha Sharma'.

Show solution
const raw = '  ASHA   sharma ';
const display = raw
  .trim()
  .split(/\s+/)
  .map(part => part[0].toUpperCase() + part.slice(1).toLowerCase())
  .join(' ');
console.log(display);

Output

Asha Sharma

Explanation: splitting on \s+ handles any number of spaces between words.

32. Count words in a reviewReal-world

Count the words in a review, ignoring extra spaces, and check a 10-word minimum.

Show solution
const review = '  Great product,   fast delivery and   very good packaging  ';
const wordCount = review.trim().split(/\s+/).length;
console.log('Words:', wordCount);
console.log(wordCount >= 10 ? 'Accepted' : 'Too short');

Output

Words: 8
Too short

Explanation: trimming first avoids empty strings at the ends being counted as words.

Keep Practising

Leave a Comment