4.14 — Checkpoint: test-results dashboard
Checkpoint. No new syntax today — instead, a look at your actual future. When a Playwright suite finishes, it hands you exactly one thing: an array of objects, one per test — name, passed or failed, how long it took. Someone has to turn that raw pile into answers: how many failed? which ones? how slow are we?
That someone is about to be you. Everything Phase 4 built — objects (4.4), references (4.6), the trio (4.9), sorting (4.10), destructuring (4.11) — chains together here into a working test-results dashboard. This is the phase's promise kept: not toy data, your job, four phases early.
const runs = [
{ name: "login", passed: true, ms: 320 },
{ name: "search", passed: false, ms: 810 },
{ name: "cart", passed: true, ms: 150 },
{ name: "pay", passed: false, ms: 990 },
];
const failed = runs.filter(r => !r.passed);
console.log(failed.length);
const names = failed.map(r => r.name);
console.log(names);
const totalMs = runs.reduce((s, r) => s + r.ms, 0);
console.log(totalMs);Memorize this shape — you will see it weekly for the rest of your career: an ARRAY (the suite) of OBJECTS (one per test), each with a name, a boolean verdict, and a duration. Everything a dashboard shows is computed from a pile shaped exactly like this.
The deeper story, with the real names for things — this part is what turns “I saw it” into “I can explain it.”
The pattern you've just used has a name in data work: select → project → aggregate. filter selects the rows you care about, map projects each row down to the field you need, reduce aggregates many values into one. Every dashboard, every report, every analytics query in existence is some arrangement of those three verbs. SQL calls them WHERE, SELECT and SUM; spreadsheets call them filters and pivot tables.
One reference-rules reminder while chaining (4.6 never sleeps): filter and map build new arrays, but the objects inside are the same ones — arrows. Mutating failed[0].name would change the original run in runs. Chains make new containers, never new contents.
And a promise for later: in lesson 10.5, Vitest will print its own version of this exact dashboard after every run — red and green, counts and timings. You'll read it like an author, because you've now written one.
⌨️ part 1 — the pass rate
The number every manager asks for first. Given a run of results, compute what percentage passed — computed from the data, so tomorrow’s 400-test run needs zero edits.
requirements:
- Start with
results: objects for"signup"(passed true),"logout"(false),"search"(true),"upload"(true) — each shaped{ test: "…", passed: … }. - Count the passing runs (a filter and a length), divide by the TOTAL count, scale to 100.
- Print the rate with a percent sign glued on:
75%.
when you press RUN, the console must show exactly:
⌨️ part 2 — the slowest failure
Triage time: of all the FAILED runs, which took longest? (Slow failures usually hide timeouts — every QA engineer hunts these.) One chain: keep the failures, order them, take the top.
requirements:
- Start with
runs:"a11y"failed in420ms,"api"passed in90ms,"e2e"failed in1400ms — each shaped{ name, passed, ms }. - Build ONE chain: keep only failures, then sort them slowest-first (mind 4.10's comparator).
- Take the first element of the chained result using array destructuring (4.11), and print its
name.
when you press RUN, the console must show exactly:
✏️ Quick check 1
Type exactly what this prints:
const rs = [
{ ok: true, ms: 10 },
{ ok: false, ms: 30 },
{ ok: false, ms: 20 },
];
console.log(rs.filter(r => !r.ok).length);✏️ Quick check 2
Type exactly what this prints:
const rs = [
{ ms: 10 },
{ ms: 30 },
];
console.log(rs.reduce((s, r) => s + r.ms, 5));✏️ Quick check 3
After this chain, what does top.name hold? Type it:
const rs = [
{ name: "a", ms: 50 },
{ name: "b", ms: 90 },
];
const [top] = rs.sort((x, y) => y.ms - x.ms);🗣️ Now teach it back
A project manager hands you an array of test-run objects and asks for “failure count, failing test names, and total runtime.” Explain — in plain words, method by method — how you’d compute all three without writing a single loop.
Write it as if your friend is sitting next to you. Saved to your journal — future-you will use these notes to teach others.