EdTech QA
Learning platforms: course progression, assessments, certifications, and accessibility.
// OVERVIEW
Learning state is the product. The failures that matter most are invisible: progress silently not saved, a certificate issued for an incomplete course, a quiz timer that resets on page refresh. None of these surface as errors — they surface as learner frustration or platform trust loss.
// What makes EdTech QA different
- Learning state is the primary data: progress percentage, last-viewed lesson, quiz score, and quiz timer must all be saved atomically — a partial save leaves the learner in an inconsistent state with no visible error
- Cross-device sync requires persistent state readable in a fresh session on a different device — not just a session handoff, but a server-authoritative progress record that survives browser close and device switch
- Quiz timer is server-enforced: page refresh or navigation away must not reset the clock to its starting value; remaining time must be derived from the server-recorded start time, not a client-side countdown
- Certificate eligibility must be validated server-side at issuance time: a client-side completion flag is not sufficient — a direct API call must not bypass the completion gate
- Teacher publish/unpublish must not break enrolled students' in-progress state: unpublishing a lesson mid-course must not reset any student's progress percentage to zero
// Core user journeys
| Journey | What to cover |
|---|---|
| Enrol and resume | Learner enrols in a course, completes a lesson, closes the browser, and returns in a new session; assert progress is at the start of the next lesson, not reset |
| Course completion and certificate | Learner completes all required modules; assert certificate is issued only after the last required module is marked complete, not before |
| Quiz from start to score | Learner starts a timed quiz, answers all questions, and submits; assert the timer persists through any page refresh and the score is recorded correctly |
| Teacher content management | Teacher publishes a lesson, updates it, and unpublishes it; assert enrolled students' progress is not disrupted at any step |
| Cross-device progress sync | Learner completes 40% on desktop, opens the same course on mobile immediately after; assert progress is 40% on mobile, not zero |
// RISKS & TEST AREAS
// Main risk areas
| Risk | Why it matters |
|---|---|
| Silent progress reset | The PATCH to the progress API returns HTTP 200 but the write is not committed to the database; the learner sees success in the UI but returns in a new session to find progress back at zero |
| Premature certificate issuance | The completion gate is enforced in the UI only; a learner who calls the certificate endpoint directly with a session that has not completed all required modules receives a valid certificate |
| Quiz timer reset on page refresh | The timer state is stored in client memory; a page refresh reinitialises it to the full duration, giving the learner an unlimited number of full-length attempts |
| Teacher unpublish breaks enrolled student progress | Course progress is calculated as completed-lessons / total-lessons; unpublishing a lesson changes the denominator without adjusting the numerator, resetting all enrolled students to 0% |
| Cross-device progress stale cache | Progress saved on mobile is not reflected on desktop within the expected sync window due to a CDN or application cache serving a stale progress response from before the update |
// Functional areas to test
- Course and lesson navigation: enrolment, lesson sequencing, completion marking, and resume-from-last-position
- Progress tracking and state persistence: lesson-complete, module-complete, and course-complete events with server-authoritative storage
- Quiz engine: timer start and server-side enforcement, question rendering, answer submission, and score calculation
- Certificate eligibility and generation: server-side completion check, certificate creation, and download
- Content management: teacher publish, update, and unpublish with immediate enrolled-student state propagation
// API & integration areas
- Progress persistence API: assert lesson-complete and module-complete events are written durably before the next lesson loads, not fire-and-forget
- Certificate issuance endpoint: assert the endpoint checks all required module completions server-side before issuing and returns HTTP 403 for incomplete courses regardless of client-submitted data
- Quiz state API: assert timer start time is recorded server-side on first question load and remaining time is calculated from that server timestamp on every subsequent request
- Content sync API: assert a lesson unpublished by the teacher is reflected in enrolled students' course view within the defined propagation SLA
- Cross-device session sync: assert progress written in one authenticated session is readable in a new authenticated session on a different device within the defined consistency window
// Data testing
- Seed courses with a known completion state matrix: fully complete, one module missing, all modules complete but certificate not yet issued — one course per state for targeted certificate-gate tests
- Seed quiz attempts with known server-side start times to test timer-persistence scenarios without waiting for real time to pass
- Seed enrolled students at various progress points (0%, 40%, 80%, 99%) to test teacher-unpublish impact across a range of starting states
- Never use real student performance data, quiz answers, or personal progress history in test environments
// CROSS-CUTTING CONCERNS
// Security & privacy
- Certificate issuance endpoint must enforce completion server-side and must not trust a client-submitted completion status or completion flag in the request body
- Quiz timer expiry must be validated server-side: assert that a submission received after the server-recorded expiry time is rejected, regardless of the client-side timer state
- Student progress data must be scoped to the authenticated student: one student must not be able to read another student's quiz scores, completion percentage, or certificate status
- Unpublished course content must not be returned to enrolled students: assert that lesson content marked as draft or unpublished is excluded from all student-facing API responses
// Accessibility
- WCAG AA contrast and keyboard navigation on all quiz interfaces: countdown timers, multiple-choice inputs, free-text answer fields, and submit buttons
- Screen reader on progress updates and module-completion announcements: assert completion state changes are announced via an ARIA live region, not silently reflected in the progress bar
- Full keyboard navigation through the lesson content and quiz flow: previous/next lesson, question navigation, and quiz submission without requiring mouse or touch
// Performance
- Concurrent quiz submission at end of class: simulate N students submitting the final question simultaneously; assert all scores are recorded correctly and no submissions are lost
- Video and media content load on constrained connections: assert video player renders and buffers correctly at low bandwidth and that a failed media load does not block lesson completion
- Progress API write latency: assert the lesson-complete event is persisted before the next-lesson navigation request resolves, so a page reload immediately after completion does not revert progress
// Mobile & responsive
- Cross-device progress sync at 375 px: progress completed on desktop must appear within the defined SLA when the same course is opened on a mobile browser
- Quiz timer and form usability at 375 px: countdown timer must be visible without scrolling, multiple-choice inputs must meet WCAG tap-target size, and text-answer fields must not be obscured by the soft keyboard
// BUGS & SCENARIOS
// Common bugs
| Bug | Scenario / repro |
|---|---|
| Silent progress reset | Learner completes lesson 3 of 5; the UI shows 60% progress; learner closes the browser and returns an hour later to find progress at 0% — the PATCH to the progress endpoint returned HTTP 200 but the write was never committed |
| Premature certificate | Learner completes modules 1–4 of a 5-module course; the certificate button is disabled in the UI but the learner calls the certificate endpoint directly; the server issues a valid certificate without checking module 5 completion |
| Quiz timer reset on refresh | Quiz has a 20-minute timer; learner refreshes the page at the 15-minute mark; a new 20-minute timer starts in the browser; the server does not detect the duplicate attempt and accepts the second session as a fresh start |
| Unpublish breaks enrolled student progress | Course has 5 lessons; enrolled student has completed lessons 1–3 (60%); teacher unpublishes lesson 2; the progress calculation now counts 2 completions out of 4 published lessons but the display shows 0% due to a denominator mismatch bug |
| Cross-device stale cache | Learner completes 60% of a course on mobile; opens the same course on desktop 10 seconds later; desktop shows 0% because the CDN serves a cached progress response from before the mobile update |
// Example test scenarios
- 01Start a course; complete the first lesson; close the browser; reopen the course in a new session — assert progress is at the start of lesson 2, not back at lesson 1
- 02Complete 4 of 5 required modules in a course; call the certificate issuance endpoint directly without completing the 5th — assert the response is HTTP 403 or 422, not a certificate PDF
- 03Start a quiz with a 20-minute timer; refresh the page at the 5-minute mark; assert the timer shows approximately 15 minutes remaining, derived from the server-recorded start time, not the full 20 minutes
- 04Enrol a student in a 5-lesson course; mark lessons 1–3 complete; teacher unpublishes lesson 2 — assert the student's progress percentage reflects 2 completions out of the remaining structure and does not reset to 0%
- 05Complete 40% of a course on device A; immediately open the same course on device B — assert progress is 40% on device B within the defined consistency window
// Edge cases
- Learner submits the last quiz question at the exact millisecond the server-side timer expires: assert the submission is accepted if it arrived before expiry and rejected if it arrived after, with deterministic behaviour at the boundary
- Course updated while learner is mid-lesson: teacher adds a new mandatory module; assert the learner's progress percentage recalculates correctly and the new module appears at the correct position in the course outline
- Certificate issued, then teacher adds a new mandatory module: assert the system has a defined policy for whether the existing certificate remains valid or is revoked, and that the policy is enforced consistently
- Concurrent progress writes from two browser tabs on the same lesson: both tabs send a lesson-complete event; assert the server applies exactly one credit and does not double-count the completion
- Quiz answer autosave on connection drop: learner's answers are autosaved mid-quiz; connection drops and is restored; assert autosaved answers are restored on reconnect and the timer continues from the correct remaining time
// AUTOMATION & TOOLS
// What to automate
- Progress persistence suite: complete each lesson type (video, reading, interactive) and assert progress is retrievable in a fresh authenticated session with no shared in-memory state between test runs
- Certificate gate parametrised: for each value of N from 1 to (required modules − 1), complete exactly N modules and assert the certificate endpoint returns HTTP 403; complete all required modules and assert it returns the certificate
- Timer integrity test: record the server-side quiz start time; refresh the page; assert the remaining time shown equals (quiz duration − elapsed server time), not the full quiz duration
- Unpublish impact matrix: for each lesson in a course, unpublish it after students have completed it; assert enrolled students' progress percentage is recalculated correctly and navigation to adjacent lessons is not broken
// Useful tools
PlaywrightE2E learning flows, progress persistence across fresh sessions, and cross-device simulation via multiple browser contextsAccessibility checkerValidate quiz interfaces, progress bars, and completion announcements against WCAG AA automaticallyAPI testing checklistProgress persistence API, certificate issuance endpoint, and quiz state API coverageHow to test: formsQuiz input validation, free-text answer fields, and multi-step assessment form scenariosBoundary value generatorQuiz timer boundary values: exactly at expiry, 1 second before, and 1 second after for deterministic timer-cutoff testsk6 performance testingConcurrent quiz submission load test and progress API write-latency measurement under end-of-class traffic
// SHIP & LEARN
// Release readiness checklist
- Progress persistence verified: lesson completion survives a fresh authenticated browser session with no shared in-memory state — no silent reset
- Certificate gate enforced server-side: direct API call with an incomplete course returns HTTP 403 in all paths regardless of client-submitted completion data
- Quiz timer persists through page refresh: remaining time is derived from the server-recorded start time, not reset to the full duration on page load
- Teacher unpublish does not reset enrolled student progress: progress percentage recalculates correctly and navigation to adjacent lessons is not broken
- Cross-device sync verified: progress written on one device is readable within the defined consistency SLA on a second authenticated device
- Certificate endpoint scoped to authenticated student's own enrolled courses: assert a student cannot request a certificate for another student's course or for an un-enrolled course
- Accessibility audit passed: quiz timer display, progress bar, and module-completion state all meet WCAG AA under automated and manual review