Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

Assessment Demo

A static, single-page web app that delivers a multi-challenge assessment loaded from JSON — five question types, free navigation, partial-credit scoring, progress persistence, and a results view, styled to DeepLearning.AI's brand.

See SPEC.md for the full specification and PLAN.md for the milestone plan. This repo is being built milestone by milestone.

Status

M0 — Scaffold, data layer & infra: complete. App shell + screen router, seeded PRNG/shuffle utilities, and the assessment data layer (load → validate → normalize → flatten, with stable item ids and a content fingerprint).

M1 — Instructions screen: complete. Full instructions screen (summary, data-derived type legend, how-it-works), session-seed ownership (mint-or-restore, fingerprint-scoped), a safe localStorage wrapper with in-memory fallback, and a GitHub Pages deploy workflow.

M2 — Quiz shell & navigation: complete. Keyed state-mutation API (currentIndex/answers/resolvedOrderings, patched in place — no full re-render), question panel (scenario banner, challenge/point meta, prompt), Back/Next + a compact full-width horizontal navigator (grouped by challenge, roving tabindex, status icons, jump-to), and a progress indicator. M3 — Question types: core complete. Per-type module registry (src/questions/*) with a uniform render/statusOf/score interface, mounted through a lazy mount-once-and-cache widget lifecycle in the quiz screen (answers rehydrate from app.answers on revisit). All five types are interactive: single/multi-select (radios/checkboxes); grouping (group bins + an "unplaced" chip pool, click-to-place); matching (two columns — items vs options — click-to-match, one-to-one, auto-matches the final pair); and ordering (move up/down). All click-to-select-then-place — no native drag, so it's keyboard- and touch-operable. Per-type status (not-answered / in-progress / answered) and partial-credit scoring are implemented and unit tested.

M4 — Scoring & results: complete. Submit appears on the last question and opens a confirmation modal (warns about incomplete questions; focus-trapped, Escape/backdrop to cancel). On confirm, scoring.js grades every question (delegating to the per-type score), rolls up totals, percentage, and per-challenge subtotals, and the results screen shows a score summary plus a per-question review (your answer, the canonical correct answer, and outcome as shape+label — ✓ correct / ◐ partial / ✕ incorrect / ○ not answered). Retake clears state and returns to the start.

M5 — Persistence: complete. In-quiz state (answers, resolved orderings, current index, submitted) auto-saves to localStorage on every change, in a blob namespaced by the content fingerprint (seed in its own key). On load, a session with real progress restores and the instructions screen offers Resume / Start over; a submitted session reloads straight to results. Retake / Start over clear storage. Falls back to in-memory with a notice when localStorage is unavailable; stale blobs are discarded on fingerprint/schemaVersion mismatch.

M6 — Polish, a11y, CI, deploy: complete. CI (.github/workflows/ci.yml) runs the test suite on every push/PR. Accessibility pass: status/outcome signals use shape + text label (not color alone), with in-progress now amber vs the teal answered dot so they differ by color too; the submit modal uses a focus trap + inert background; roving-tabindex navigator; two aria-live regions; lang, skip link, visible focus, and prefers-reduced-motion all in place; 44px primary touch targets; contrast verified AA (point chip, status, outcome colors). The error screen has a Try again retry (§10). CTA semantics hold (one coral primary per screen).

The header shows the official DeepLearning.AI logo (dlai-logo.webp) at 28px tall, with alt="DeepLearning.AI".

Live: https://roberto-dlai.github.io/assessment-demo/ (auto-deploys from main via .github/workflows/deploy-pages.yml; tests gated by CI).

Choosing an assessment

data/assessments.json is a manifest listing the selectable assessments ({ id, title, description, file }). On load:

  • with multiple assessments and no selection, a picker screen lists them;
  • ?a=<id> deep-links straight to one (and the URL updates when you pick);
  • a single manifest entry (or no manifest) skips the picker and loads the default.

Each assessment keeps its own progress — the saved session is namespaced by id + content-fingerprint, so distinct assessments never collide (even with identical content) and a content change still invalidates stale saves. Add an assessment by dropping its JSON in data/ and adding a manifest entry.

Running locally

ES modules and fetch() are blocked under file://, so you must use a local static server — don't open index.html directly.

# option A (Node)
npm run serve            # runs `npx serve .`

# option B (Python)
python3 -m http.server 8000

Then visit the printed URL (e.g. http://localhost:8000). The app boots to the instructions screen; load failures surface on an error screen (and the console).

Tests

Pure modules (PRNG, shuffle, data normalization) are covered by Node's built-in test runner — no dependencies:

npm test                 # node --test

Scoring, persistence, and per-type question behavior are all covered.

Project structure

index.html                 # entry; loads fonts, theme.css, styles, src/main.js
theme.css                  # DeepLearning.AI brand tokens
styles/app.css             # app layout/styles
data/
  assessments.json                          # manifest of selectable assessments
  spec-driven-development-assessment.json    # example assessment(s)
src/
  main.js                  # bootstrap + screen router
  state.js                 # app state + in-quiz answer state (status via registry)
  session.js               # per-assessment seed + session blob (fingerprint-scoped)
  scoring.js               # grade(app): totals + per-challenge subtotals + outcomes
  data/loadAssessment.js   # load, validate, normalize, flatten, fingerprint
  util/prng.js             # mulberry32 seeded PRNG + helpers
  util/shuffle.js          # deterministic shuffles
  util/storage.js          # safe localStorage wrapper (in-memory fallback)
  util/a11y.js             # announce / focusHeading / createFocusTrap
  questions/               # per-type modules: render / statusOf / score
    registry.js            #   type -> module
    single.js  multi.js  grouping.js  matching.js  ordering.js
  screens/
    dom.js                 # shared el()/mountScreen()/heading() helpers
    picker.js  modal.js  instructions.js  quiz.js  results.js  error.js
test/
  util.test.js  state.test.js  persistence.test.js  persist-session.test.js
  questions.test.js  scoring.test.js   (53 tests)

All asset paths are relative so the app works from a GitHub Pages project subpath (/<repo>/).

Deployment

Static site — no backend. Published to GitHub Pages via GitHub Actions (.github/workflows/deploy-pages.yml, serving the repo root); ci.yml runs the test suite on every push/PR.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages