Sparround

Working with strings and dates

Working with text is daily business in test code: normalising a string read from the UI, pulling an ID out of it, building unique test data.

Strings are immutable — every method returns a NEW string and leaves the original alone:

  • trim() — strips surrounding whitespace; almost always needed before asserting on UI text
  • split(separator) and join(separator) — convert between string and array: 'a,b,c'.split(',')
  • slice(from, to) — extracts a part; a negative index counts from the end: 'ORD123'.slice(-3)'123'
  • replace(a, b) — replaces only the FIRST match; for all of them use replaceAll(a, b) or a global regex
  • includes / startsWith / endsWith — boolean checks; more readable than indexOf(...) !== -1
  • toLowerCase() — for case-insensitive comparison

A template literal (backticks) is always more readable than string concatenation: Order ${id} — ${status}.

ExpressionResultNote
' Paid '.trim()'Paid'only outer whitespace is removed, inner stays
'a-b-c'.replace('-', '+')'a+b-c'only the FIRST match — a commonly missed detail
'a-b-c'.replaceAll('-', '+')'a+b+c'replaces all of them
'ORD-1042'.split('-')[1]'1042'simple parsing without regex
['a','b'].join(', ')'a, b'for assembling expected text
'12.50'.trim() === 12.50falsestring vs number comparison — convert with Number()

Date work is built on the Date object:

  • new Date() — the current moment; Date.now() — that moment as a millisecond timestamp (a plain number)
  • new Date('2026-03-14T22:30:00Z') — building a date from an ISO 8601 string (the most reliable way)
  • toISOString() — a standard string ALWAYS in UTC: '2026-03-14T22:30:00.000Z'
  • toLocaleDateString(locale, options) — a human format; the result depends on the machine's locale and timezone settings
  • Date arithmetic goes through milliseconds: new Date(Date.now() + 24 * 60 * 60 * 1000) — tomorrow

Assertion rule: check the machine-readable form (toISOString(), a timestamp, the date part via slice(0, 10)). Only assert on formatted text when locale and timeZone are stated explicitly (Intl.DateTimeFormat).

Timezones are the classic way to break tests: the developer sits in Baku (UTC+4) while the CI runner runs in UTC — late in the day toLocaleDateString() is a day off and the test fails only in the evenings. The fix: pin timeZone with Intl.DateTimeFormat, or set use: { timezoneId: 'Asia/Baku', locale: 'az-AZ' } in the Playwright config. In an interview this "fails only at night" story lands very well.

For unique test data Date.now() is simple and reliable: qa_${Date.now()}@test.local — it stops parallel tests from colliding on the same user.

📚 Sources and documentation