Sparround

Working with JSON and data

JSON is the language of API tests. Two functions are enough:

  • JSON.parse(text) — turns a JSON string into a JavaScript object
  • JSON.stringify(object) — turns an object into a JSON string; the second and third arguments give readable output: JSON.stringify(obj, null, 2)

In practice Playwright's response.json() parses for you — you rarely call JSON.parse by hand. You need it when working with raw text (a fixture read from a file, config in process.env).

CAREFUL: JSON.parse throws on invalid text. Trying to parse an empty body or an HTML error page drops the test with the cryptic Unexpected token < in JSON message — which actually means the server returned HTML, not JSON.

Input valueAfter JSON.stringifyConsequence
an undefined fieldthe field disappears entirelythe difference between "absent" and "empty" is erased
a Date objectan ISO stringparsing back gives a string, not a Date
a function / methoddroppeda class instance degrades to a plain object
NaN, Infinitynulla calculation error gets hidden
Map, Setan empty object {}the data is silently lost
a circular referencethrows a TypeErrorhit when logging an object

Reading deep data safely. When an API response is nested, use ?. and ?? instead of checking each level:

const city = body.items?.[0]?.shipping?.address?.city ?? 'unknown';

If a field is missing the test fails with a clear assertion message rather than Cannot read properties of undefined.

Checking the shape of a response (contract testing). Assert on structure and types, not exact values — such a test survives data changes but fails when the contract breaks:

  • is it an array: Array.isArray(body.items)
  • type: typeof body.total === 'number'
  • key present: 'status' in order
  • Playwright/Jest matchers: expect.objectContaining, expect.any(String), expect.arrayContaining

For deep copies, JSON.parse(JSON.stringify(obj)) is the old-school trick and causes every loss listed above. The modern answer is structuredClone(obj): it copies Date, Map, Set and nested arrays correctly (but not functions — it throws on those).

Prepare a short interview answer: "A JSON round-trip is not a deep copy, it is a lossy simplification: undefined and functions vanish, Date becomes a string, NaN becomes null. So I copy test data with `structuredClone` or a factory function."

📚 Sources and documentation

  • JSONofficialdeveloper.mozilla.org