Skip to content

feat(progress): show learners what completion requires; honest quiz ticks; header progress bar - #10

Merged
RichardoC merged 1 commit into
mainfrom
claude/festive-noether-o06qq7
Sep 14, 2026
Merged

RichardoC merged 1 commit into
mainfrom
claude/festive-noether-o06qq7

Conversation

@RichardoC

Copy link
Copy Markdown
Owner

Problem

Learners cannot tell how far through the course they are, or whether they have done what completion requires:

  • The contents-page tick only means a page has been opened. x_pageLoaded() sets x_pageInfo[i].viewed the moment a page loads, and tickViewed() draws from that flag alone. A quiz ticks before a single question is answered.
  • The LMS shows 0% until the very end. SCORM 1.2 has no progress field. getSuccessStatus() reports incomplete until every one of the 43 tracked pages has been left, then passed/failed. Moodle's default "Learning objects" grading method counts SCOs with status completed/passed; this package is one SCO, so the grade is 0 then 1.
  • Nothing in the course said which required pages were still owed. A learner who skipped References saw a fully ticked menu and a "Course complete" page saying their result was recorded, while Moodle held incomplete forever.

The LMS side is structural (see the README for why SCORM 2004 and multi-SCO do not help with Moodle), so this PR makes the course itself honest. All changes are content-level: no engine patch.

Changes

Status panel (source/scorm_progress.js, part 5). Every .xtStatusPanel element is filled with: required pages completed out of 43, the names of the pages still to visit (capped at 6), each quiz's result or "not yet submitted", the weighted score against the pass mark, and the exact status the LMS currently holds, in plain language. Two placeholders: the root menuText (text column of the contents page) and a <div> at the top of the Course complete page. Refreshed from x_pageLoaded, XENITH.PAGEMENU.tickViewed, XTExitPage, XTExitInteraction and XTSetPageScore. Outside an LMS it says tracking is not active.

Quiz ticks mean "submitted". XTSetPageScore (only called by the quiz results screen) now sets the page interaction's unused complete field. It is persisted as a sixth element of each xtPages row and restored on resume; records from older builds infer it from a non-zero score. After tickViewed, an opened-but-unsubmitted quiz gets a half-filled circle (fa-adjust, class xtPending, label "Opened, quiz not yet submitted") instead of a tick.

Header progress bar (Xerte's own, editor-supported): progressBarType="header2", progressSub="milestones", a milestone="true" on each of the 8 quiz pages, label {x}% of pages viewed. Note header1 ("above titles") inserts after the header logo icon; this course has no logo, so it silently built nothing.

Content: the Welcome page explains the three indicators and that every page from Welcome to the final quiz must be visited and every quiz submitted. The Course complete page opens with the panel and no longer claims the result "has been recorded" unconditionally.

Docs: README section "Progress and completion: what learners and the LMS see" with the Moodle SCORM activity settings that matter (Grading method, Completion tracking, Display attempt status) and why SCORM 2004 / multi-SCO were rejected. PROJECT_CONTEXT section on the mechanism.

Deliberately not changed

  • Which pages are required. All 43 tracked pages still count, including About, Mapping, Glossary and References. Exempting a page needs care: because of the off-by-one documented under "SCORM completion bug fix", unmarkForCompletion on page N actually exempts page N-1. The clean route is for the root script to rebuild state.toCompletePages from the live page list before XTInitialise. Happy to do that as a follow-up if reference pages should not block completion.
  • The pass check. The engine uses strictly greater than, so exactly 80% reports failed while the Welcome page says the pass mark is 80%. Moodle applies no mastery override (the Xerte manifest has no adlcp:masteryscore). Flagging rather than changing scoring semantics in this PR.

Tests

Four new tests in tests/test_scorm_tracking.py plus panel assertions at the end of the full walkthrough:

  • test_status_panel_tells_the_learner_what_is_left
  • test_quiz_tick_means_submitted_not_opened (including across a resume, and the persisted flag)
  • test_older_records_infer_submission_from_the_score
  • test_header_progress_bar_counts_viewed_pages

Run locally against the v0.0.7 release package with the new data.xml as template.xml (the export copies data.xml verbatim apart from the build version, and the release's engine files are identical to the current docker-container branch): 22/22 pass. The CI workflow builds through a real XOT container and is the authoritative run.

Screenshots

Contents page: header bar with quiz milestones, half-filled circle on the opened-but-unsubmitted Theme 1 Quiz, status panel in the text column. Course complete page: panel showing 3 of 43 required pages, one quiz at 100%, LMS status incomplete.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MfWFRfRw3sR98Vq48EKEYa


Generated by Claude Code

…icks; header progress bar

Learners could not tell how far through the course they were or whether
they had done what the LMS needs. The contents-page tick only meant a page
had been opened, and SCORM 1.2 gives the LMS nothing but
incomplete/passed/failed, so Moodle's "Learning objects" grade sits at 0%
until the very end.

The LMS side is structural, so make the course itself honest:

- Status panel: the root script fills every `.xtStatusPanel` element (one
  in the menu text of the contents page, one at the top of the Course
  complete page) with required pages done out of 43, the pages still to
  visit, each quiz result or "not yet submitted", the weighted score against
  the pass mark, and the exact status the LMS currently holds, in plain
  language. Refreshed on page load, menu tick updates, page exits and quiz
  submission.
- Quiz ticks mean "submitted": XTSetPageScore (the quiz results screen) now
  marks the page interaction complete; the flag is persisted as a sixth
  element of each xtPages row and restored on resume (older records infer
  it from a non-zero score). An opened-but-unsubmitted quiz shows a
  half-filled circle with an explanatory label instead of a tick.
- Header progress bar (Xerte's own): progressBarType="header2" with a
  milestone marker on each quiz page and the label "{x}% of pages viewed".
  header1 inserts after the header logo, which this course lacks, so it
  built nothing.
- Welcome page explains the indicators; Course complete no longer claims
  the result "has been recorded" unconditionally.

Docs: README section on what learners and the LMS see, with the Moodle
SCORM activity settings that matter (grading method, completion tracking,
attempt status display) and why SCORM 2004 / multi-SCO do not help;
PROJECT_CONTEXT section on the mechanism and what was deliberately left
unchanged (which pages are required; the strict > pass check).

Tests: four new tracking tests plus panel assertions in the full
walkthrough; 22/22 pass against the released package with the new
template.xml.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MfWFRfRw3sR98Vq48EKEYa
@github-actions

Copy link
Copy Markdown

📖 Course content preview

Download the course-preview artifact from the workflow run and open index.html to read the full course (pages + quizzes, correct answers marked ✓):

This preview is generated from source/data.xml by tools/render_preview.py. It is for review only — the playable SCORM package is built by the release workflow.

@RichardoC
RichardoC merged commit f2c37ac into main Sep 14, 2026
2 checks passed
@RichardoC
RichardoC deleted the claude/festive-noether-o06qq7 branch September 14, 2026 14:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants