Scoring & state
<qti-outcome-processing>
Declared inside <qti-assessment-test> (per the QTI spec), this element is invisible (display: none) and does nothing until outcomeProcessing() is called on the enclosing <qti-test>. That method finds the <qti-outcome-processing> element and calls process() on it, which in turn runs process() on each of its child rule elements in document order — the same rule-execution model used by item-level response processing.
qti-test-variables
A test-level expression, used inside <qti-outcome-processing> rules to aggregate a variable across multiple items — e.g. summing every item’s SCORE.
| Attribute | Notes |
|---|---|
variable-identifier | The item-level variable to aggregate (e.g. SCORE). |
include-category / exclude-category | Space-separated category lists to filter which item refs contribute. An item ref qualifies when it carries one of the included categories and none of the excluded ones; its own category is a space-separated list too, and matching any entry is enough. |
weight-identifier | Optional per-item weight, read from each qti-assessment-item-ref’s weights map — its <qti-weight> children, keyed by identifier. An item ref that declares no such weight counts as 1. |
getResult() walks every qti-assessment-item-ref in the enclosing <qti-assessment-test>, filters by category, applies weights, and sums the named variable’s value across the matching items’ current testContext. An item whose value is not a number contributes nothing rather than turning the total into NaN.
qti-number-selected
A test-level expression returning how many item references the test selected — the count of the
same set qti-test-variables aggregates over, and right before any item has been attempted.
| Attribute | Notes |
|---|---|
section-identifier | Only count item refs inside the <qti-assessment-section> with this identifier; every section when absent. |
include-category / exclude-category | The same space-separated category filters qti-test-variables uses, with the same any-match / both-must-hold semantics. |
section-identifier works on qti-test-variables too — both elements select their item refs the
same way.
qti-number-presented
A test-level expression returning how many of those item references have been presented to the
candidate. It takes the same section-identifier, include-category and exclude-category
attributes as qti-number-selected.
An item counts as presented once its completionStatus has left not_attempted: presenting an item
starts its first attempt. Items a linear test part passed over (a false qti-pre-condition, a
qti-branch-rule that jumped past them) and items the candidate has not reached are not counted.
Use it for totals over the candidate’s own route — for example a maximum score of one point per
presented item, so branched-over items do not count against the candidate:
<qti-set-outcome-value identifier="MAXSCORE"> <qti-number-presented exclude-category="unscored" /></qti-set-outcome-value>Totals over items that were not presented
Items load when the candidate reaches them. Until then the test context holds no outcome values for
them, so a sum such as MAXSCORE over qti-test-variables only covers the items seen so far. QTI
gives an item that was not presented its declared defaults, but nothing at test level carries those
defaults: qti-weight only multiplies, qti-variable-mapping only renames, and qti-outcome-maximum
reads the item too. Fetching every item at results time just to read its declarations is a request per
item; prefer, in this order:
-
Put the total in the content. Declare it as the test outcome’s default, which outcome processing resets to before every run:
<qti-outcome-declaration identifier="MAXSCORE" base-type="float" cardinality="single"><qti-default-value><qti-value>20</qti-value></qti-default-value></qti-outcome-declaration>When every item is worth the same, count instead of sum:
qti-number-selectedfor the whole test, orqti-number-presentedfor the candidate’s own route through a test with branch rules. -
Prepare it with the package. Read the item declarations once when the package is built or served, and hand them to the test before the first item loads: as
variablesof the items in astateyou assign toqtiTest.state, or withqtiTest.updateItemVariables(itemRefId, values)oncito-test-loaded. Outcome processing then reads them like any other value. (initContextontest-navigationcannot carry them: it only feeds the computed context.)
qti-test-feedback
Test-level feedback, declared in <qti-assessment-test>. It renders nothing where it is declared: where
and when to show it is the host’s decision. After outcomeProcessing(), qtiTest.getTestFeedback(access)
returns the ones that apply — access is atEnd (the default) or during, and leaving it out returns
both:
qtiTest.outcomeProcessing();const atEnd = qtiTest.getTestFeedback('atEnd').map(feedback => feedback.innerHTML);A feedback applies when its outcome-identifier holds its identifier (show-hide="show"), or does not
(show-hide="hide"); feedback.matches(value) answers that for any value.
<test-check-item>
A “submit this attempt” button. On click it:
- Dispatches
test-end-attempt(bubbles) — picked up by<test-navigation>, which callsprocessResponse(true, ...)on the active item. - Dispatches
test-show-correct-responsewithdetail: true— reveals the item’s correct response. - Toggles
.showon every[view]-tagged element inside the current<test-container>, making scorer-only content visible immediately.
test-scoring-buttons
Renders a human-scoring UI for the active item, driven by a <template> child (via Heximal templates) so the markup is fully up to you — the component only supplies the data: { scores, score, disabled }, where scores is [0..MAXSCORE] and disabled is true unless the item’s SCORE outcome has externalScored === 'human'.
Clicking an <input> inside the template dispatches test-update-outcome-variable with { assessmentItemRefId, outcomeVariableId: 'SCORE', value }, which <test-navigation> applies to the active item.
<test-scoring-buttons> <template> <!-- receives { scores, score, disabled } --> </template></test-scoring-buttons>test-scoring-feedback
Renders feedback text for the active item based on completion status, SCORE, and externalScored. The actual copy is supplied via data-* attributes on the element itself — data-text-no-response, data-text-correct, data-text-incorrect, data-score-unknown, data-in-progress — so wording is fully caller-controlled; the component only picks which one applies.
test-show-correct-response — deprecated
Marked @deprecated in source. It toggled correct-response visibility via a shown state and test-show-correct-response event, but the codebase is moving toward the <template>-driven pattern used by test-scoring-buttons/test-view-toggle. Check with the team before reaching for it in new work.