JS Sketchbooksee JavaScript think ✏️
← back to phase 7

7.9 — Checkpoint: todo app, inspected

Eight lessons, one small app. A todo list is deliberately simple — and secretly uses every single piece of Phase 7 machinery you now own, end to end. Walk through building it here, then put the tester hat back on: it's about to become your own personal practice range.

No new concepts today. Just proof that you can read, write, listen for, validate, save, and inspect a real interactive page — the whole job, in miniature.

watch it happen
// <input data-test="new-todo">
// <form> ... </form>
// <ul id="todos"></ul>

form.addEventListener("submit", (event) => {
  event.preventDefault();
  const li = document.createElement("li");
  li.textContent = input.value;
  li.className = "todo";
  list.append(li);
  saveTodos();
});

list.addEventListener("click", (event) => {
  if (event.target.matches(".todo")) {
    event.target.classList.toggle("done");
    saveTodos();
  }
});

function saveTodos() {
  localStorage.setItem("todos", JSON.stringify(readTodos()));
}

The checkpoint project: a todo app. Every concept from this phase — tree, selectors, mutation, events, delegation, forms, storage, rendering — lands somewhere in these twenty lines.

the checkpoint: a todo app7.1 tree · 7.2 selectors · 7.3 mutation7.4 events · 7.5 delegation7.6 forms · 7.7 storage · 7.8 renderingevery Phase 7 concept lands in one small, real thing
under the hood

The deeper story, with the real names for things — this part is what turns “I saw it” into “I can explain it.”

Why a todo app specifically: it's small enough to hold entirely in your head, yet it genuinely exercises reading (7.2), writing (7.3), listening (7.4/7.5), forms (7.6), persistence (7.7), and timing (7.8) — a "real" production app adds more of the same shapes, not new DOM concepts.

This is also, literally, real QA work in miniature: most of an automation tester's career is spent writing selectors against apps someone else built, using exactly the querySelector skills from 7.2, and reasoning about what a click actually triggers using exactly the delegation and event patterns from 7.4/7.5.

Where the curriculum goes next: Phase 8 teaches the modern tooling (modules, npm, a taste of TypeScript) that real todo apps — React, Vue, and friends — are actually built with. Phase 9 is Node.js — JS with the browser walls removed. Phase 10 teaches the testing MINDSET. Phase 11 is Playwright itself, automating exactly this kind of app for real.

your turn

⌨️ part 1 — the todo core, without mutation

Build the app’s core logic in miniature: add and toggle, both as pure functions that return a NEW array — the same shape a delegated listener would call.

requirements:

  • An array todos, starting empty.
  • addTodo(todos, text): return a NEW array with { text, done: false } appended (spread, 4.9 — never push onto the original).
  • toggleTodo(todos, index): return a NEW array where ONLY the item at index has its done flipped (map, 4.9).
  • Add "milk", then add "eggs", then toggle index 0. Print each todo as "text (done)" or "text (not done)", joined by ", ".

when you press RUN, the console must show exactly:

milk (done), eggs (not done)

⌨️ part 2 — surviving a reload

Model what runs on every page load: parse a saved JSON string back into real todo objects and summarize them.

requirements:

  • A string saved = '[{"text":"milk","done":true},{"text":"eggs","done":false}]' — as if it just came from localStorage.getItem("todos").
  • Parse it into a real array with JSON.parse (7.7).
  • Print the TOTAL number of todos, then how many are done (filter’s length, 4.9).

when you press RUN, the console must show exactly:

2
1

✏️ Quick check 1

A todo’s delete button is clicked. Per 7.5, does the app need a listener wired to that SPECIFIC button? Type yes or no.

✏️ Quick check 2

The submit handler calls event.preventDefault() first. Per 7.6, what would happen WITHOUT that line? Type it in a few words.

✏️ Quick check 3

Todos are saved with JSON.stringify. Type the function (7.7) used to read them back into real objects:

teach it back

🗣️ Now teach it back

Walk a friend through everything that happens from typing a todo and pressing Enter, to it surviving a page reload — naming every Phase 7 concept it rides on.

Write it as if your friend is sitting next to you. Saved to your journal — future-you will use these notes to teach others.

a few sentences, minimum — you’ve got this
to remember
One small todo app exercises all of Phase 7: tree (7.1) → selectors (7.2) → mutation (7.3) → events (7.4) → bubbling/delegation (7.5) → forms (7.6) → storage (7.7) → rendering (7.8).
Build it, then inspect it: writing selectors against your own app IS the daily rhythm of automation testing, just compressed into one lesson.
Phase 7 complete. Next: Phase 8’s modern tooling — the modules, npm, and TypeScript taste that real apps like this one are actually built with.