New: the SCORM Central WordPress plugin. Put a course on any WordPress page and see who finished. Get the plugin →

Start free →

SCORM demo course: what it should prove

A SCORM demo is a diagnostic, not a showcase. What a good demo must read, write and commit, how to check the LMS record, and which demos prove nothing.

What a SCORM demo is for

A SCORM demo course is a small package whose only job is to exercise the runtime so you can see what an LMS actually records. It is a diagnostic, not a showcase. A good demo reads the learner's name, writes a bookmark, suspend data, a score and a status, commits, terminates, and lets you check each value in the LMS.

Most packages labelled "demo" or "sample" are built to look like a course rather than to test one. They show a few slides, set completed on the last page, and stop. All that proves is that the LMS can unzip a file and serve HTML. It says nothing about whether a score arrives, whether a learner can resume, or whether completion survives a closed tab — the things that go wrong in production.

Think of the demo as a probe. The LMS sits behind a JavaScript API and never tells you what it does with the values it receives. The probe sends known values in a known order, and you look at what came out the other end. A minimal SCORM package example shows the file structure; the rest of this article is about what the probe should do once it launches.

What should a demo course exercise?

Every element of the data model your real courses depend on. That is a short list, and a single-page SCO can cover it in a few dozen lines of JavaScript. Build the sequence below in this order, because order is part of the test.

  1. Find the API and call Initialize once. The SCO searches up the window hierarchy for API (SCORM 1.2) or API_1484_11 (SCORM 2004) and calls LMSInitialize("") or Initialize(""). Exactly once; a second call is an error on strict platforms.
  2. Read the learner and the entry state. cmi.core.learner_name and cmi.core.entry in 1.2; cmi.learner_name and cmi.entry in 2004. Display both on the page.
  3. Read the current status. cmi.core.lesson_status in 1.2; cmi.completion_status in 2004. A first launch should show not attempted or unknown; anything else means the LMS is carrying state from an earlier attempt.
  4. Write a bookmark. cmi.core.lesson_location in 1.2 or cmi.location in 2004, with a value you will recognise later, such as page-3.
  5. Write suspend data. A known string into cmi.suspend_data. Keep it under 4,096 characters in SCORM 1.2, because that is the cap and many platforms truncate silently rather than rejecting the write.
  6. Set a score. In 1.2, write cmi.core.score.min, cmi.core.score.max, then cmi.core.score.raw. In 2004, write cmi.score.scaled as a value between 0 and 1. The LMS uses scaled for rollup in 2004, so a demo that only writes raw is not testing what the platform reads.
  7. Set status, after the score. In 1.2, one write to cmi.core.lesson_status, typically passed. In 2004, two separate writes: cmi.success_status to passed and cmi.completion_status to completed. They are independent fields; set both so you can confirm the LMS stores both.
  8. Commit. LMSCommit("") or Commit(""). Then wait a moment.
  9. Terminate. LMSFinish("") in 1.2 or Terminate("") in 2004, from a button on the page rather than the browser's unload event, so you know exactly when it happened.

Log every call and return value to a visible panel on the page, so whoever runs the demo can read the conversation without developer tools. SetValue returning "false" is the most useful signal a demo gives, and it is invisible unless printed.

Order is a test in itself. Some platforms lock the attempt record the first time they see a terminal status and ignore later writes. Write score before status and commit once after both; then swap the order in a second run and compare what the LMS kept.

Reading the result in the LMS

The launch is half the test. The other half is finding the attempt record in the LMS and checking each value you sent against what was stored. Where that record lives varies — a SCORM report, a learner transcript, an administrator's attempt detail page — but every LMS that supports SCORM keeps one, because it needs it to resume the learner.

What you wroteSCORM 1.2 elementSCORM 2004 elementWhat to look for
Bookmarkcmi.core.lesson_locationcmi.locationYour exact string, unchanged
Statecmi.suspend_datacmi.suspend_dataFull length; compare character count, not just the start
Scorecmi.core.score.raw (with min/max)cmi.score.scaledThe number, and whether the LMS converted it to a percentage
Statuscmi.core.lesson_statuscmi.completion_status + cmi.success_statusIn 2004, both fields present and independent
Session timecmi.core.session_timecmi.session_timeAccumulated into total time across launches

Pay particular attention to status. Many LMS reports collapse the two 2004 fields into one word such as "Passed" or "Complete". That is a reporting choice, not a storage fault, but you need to know which field drives the word, because a course that sets completed and failed will display differently on different platforms. The mechanics are covered in how SCORM tracks completion.

If a value is missing, the demo's own log says where to look. SetValue returning "true" followed by an empty field in the LMS points at a commit that never persisted or a platform that discarded the element. SetValue returning "false" points at the content: a malformed value, a write to a read-only element, or a call made after Terminate.

The resume test

Close the demo, then launch it again from the same learner account. This is the test single-launch demos skip, and it catches the most expensive failures, because a learner who cannot resume a forty-minute module will simply not finish it. On the second launch the demo should read and display:

  • cmi.core.entry or cmi.entry — expected value resume. If it reads ab-initio or an empty string, the LMS either did not store the suspended state or started a fresh attempt.
  • The bookmark — exactly what you wrote on the first run.
  • The suspend data — exactly what you wrote, at the same length. A shorter string means truncation, the usual symptom of exceeding the 4,096-character cap in 1.2.
  • The status — whatever you set, unless the platform resets status on every launch, which is worth knowing before a real course depends on it.

Whether entry comes back as resume depends on what the first run wrote to cmi.core.exit (1.2) or cmi.exit (2004). Writing suspend before terminating asks the LMS to preserve the attempt; leaving it empty, or writing logout, may legitimately start a new attempt on some platforms. Run the demo both ways and see the difference rather than guess at it.

A clean resume — correct entry, correct bookmark, full suspend data — is the strongest single piece of evidence a demo can give you. A failed resume is almost always one of three things: suspend data over the cap, no Commit before the first session ended, or an exit value the platform read as "start over".

Demo courses that prove nothing

Because the word "demo" sets a low bar, a lot of packages pass it without telling you anything useful. The common gaps:

  • Status set, nothing committed. The page writes completed and closes. On platforms that persist on Terminate it works; on platforms that persist only on Commit it does not. The demo looks fine on the first and you ship a course that loses completions on the second.
  • Score written after status. The platform locks the record on passed and drops the score that follows. The LMS shows "Passed", which looks like success, and nobody notices the empty score column until a compliance report asks for it.
  • Suspend data over 4,096 characters in SCORM 1.2. The write returns "true", the LMS stores the first 4,096 characters, and the demo never relaunches to notice the rest is gone.
  • No resume test. One launch, one result. Everything in the previous section goes untested.
  • Return values not shown. A string of "false" responses produces exactly the same screen as a string of "true" responses.
  • Only one version exercised. A SCORM 1.2 demo says nothing about how the platform handles cmi.score.scaled or separate success and completion status in 2004. If your real courses are 2004, test 2004.

The fix for all of these is the same: treat the demo as a measurement, write down what you expect to see in the LMS before you launch, and compare. A demo that passes without a written expectation has not passed anything. The same discipline applies to a real course, which is the subject of how to test a SCORM package before upload.

Short checklist:

  1. Initialize called once, returned "true".
  2. Learner name and entry read and displayed.
  3. Bookmark, suspend data, score, status written in that order.
  4. Every SetValue return value visible on the page.
  5. Commit, then Terminate, from a button.
  6. Each value found in the LMS attempt record.
  7. Second launch: entry is resume, bookmark and suspend data intact.

Where SCORM Central fits

SCORM Central turns PowerPoint, PDF, and video files into SCORM 1.2 or SCORM 2004 4th Edition packages you can edit in its course builder, and its free tester shows the manifest checks and every runtime call a package makes before an LMS sees it. See how it works, or test a package free.

Keep reading — Testing & Troubleshooting

Testing & Troubleshooting5 min What does SCORM compliant content mean? SCORM compliant content meets two rules: a zip with a valid imsmanifest.xml, and a SCO that calls the LMS API. How to check a vendor compliance claim. Testing & Troubleshooting7 min imsmanifest.xml missing or not found: fixes An LMS says imsmanifest.xml is missing or not found. The file usually exists but is in the wrong place: six causes, a fix for each, and a 30-second check. Testing & Troubleshooting6 min SCORM integration and cross-domain problems SCORM integration fails when a course and the LMS sit on different domains. Why the browser blocks the API search, and the proxy and bridge fixes.
Testing & Troubleshooting

Test your SCORM package free.

Upload the zip and watch every runtime call it makes — Initialize, SetValue, Commit — plus manifest checks, before your LMS sees it. No account.

→ upload  course-scorm2004.zip
  manifest … valid (2004 4th Ed)
  Initialize("") → "true"
  SetValue cmi.score.scaled → "0.84"
  Commit("") → "true"
✓ 0 errors, 2 notes