Hepatic Safety Explorer: test evidence

Requirement-traced qualification evidence for the safety.viz hep-explorer module.

Scope
26 coverage rows36 distinct requirement IDs
Tests executed
172 automated checks24 browser · 148 unit
Result
pass all passing7 evidence screenshots
Generated
2026-07-12 05:50 UTC
Environment
linux 6.17.0-1018-azure · node v22.23.1 · playwright 1.61.1 · chromium 149.0.7827.55

Scope & approach

Traceability for the hep-explorer module (a Chart.js reimplementation of the SafetyGraphics/hep-explorer eDISH hepatotoxicity explorer matching its core behavior, under #43), per the convention in CONTRIBUTING.md. Requirement IDs use the module's condensed **HEP-*** scheme cited in the source and test names — HEP-CHART-* (scatter/axes), HEP-QUAD-* (quadrants/cutpoints), HEP-CTRL-* (controls), HEP-DISPLAY-* (eDISH/mDISH standardization), HEP-SELECT-* (participant detail/visit path), HEP-DATA-* (data contract/cleaning), and HEP-API-* (lifecycle/events). A reviewed source requirement matrix (hep-explorer.md in the requirements repo) is not yet published, so the source-matrix column is pending; each row lists the module IDs its test covers.

Each table row traces one requirement to the automated test(s) that evidence it: the requirement ID and its source-matrix rows link back to the reviewed specification, the issue column links the implementing work, and the result column shows the recorded outcome of every matching test from the committed evidence.json with its captured screenshots. Browser evidence is captured at fixed conditions (1280×800, device scale 1) on the canonical Linux CI environment.

Browser evidence (Playwright — tests/e2e/hep-explorer.spec.js)

15 requirement rows · 15 tests

RequirementSource matrix rowsIssueTests & evidence
HEP-CTRL-001/002/006/007/008/009/010/011/012#43
  • pass HEP-CTRL-001/HEP-CTRL-002/HEP-QUAD-001/HEP-DISPLAY-001/HEP-CTRL-006/HEP-CTRL-007/HEP-CTRL-008/HEP-CTRL-009/HEP-CTRL-010/HEP-CTRL-011/HEP-CTRL-012: renders the full control panel (#43)
Evidence screenshot HEP-CTRL-001-control-panel.pngEvidence screenshot HEP-CTRL-006-log-axes.pngEvidence screenshot HEP-CTRL-009-color-by-group.pngEvidence screenshot HEP-DISPLAY-001-mdish-display.png
HEP-DATA-001, HEP-CTRL-011#43
  • pass HEP-DATA-001/HEP-CTRL-011: participant note reports N and % and updates on filter (#43)
HEP-DATA-003#43
  • pass HEP-DATA-003: missing and non-numeric results are dropped with a reported count and note (#43)
Evidence screenshot HEP-DATA-003-invalid-data-note.png
HEP-QUAD-002/003/004/005#43
  • pass HEP-QUAD-002/HEP-QUAD-003/HEP-QUAD-004/HEP-QUAD-005: quadrant cut-lines classify one participant per quadrant and drive the summary table (#43)
Evidence screenshot HEP-QUAD-002-quadrant-summary.png
HEP-QUAD-001/004#43
  • pass HEP-QUAD-001/HEP-QUAD-004: changing the x-axis reference line reclassifies the quadrants (#43)
HEP-DISPLAY-001/002, HEP-CHART-002#43
  • pass HEP-DISPLAY-001/HEP-DISPLAY-002/HEP-CHART-002: the display toggle switches eDISH and mDISH axis titles and cutpoints (#43)
Evidence screenshot HEP-DISPLAY-001-mdish-display.png
HEP-SELECT-001/002/003/005/006#43
  • pass HEP-SELECT-001/HEP-SELECT-002/HEP-SELECT-003/HEP-SELECT-005/HEP-SELECT-006: clicking a point draws the visit path, detail panels, and linked listing (#43)
Evidence screenshot HEP-SELECT-001-participant-detail.png
HEP-SELECT-002#43
  • pass HEP-SELECT-002: selecting a second participant without a background click destroys the prior detail chart (no Chart.js leak) (#43)
HEP-SELECT-007#43
  • pass HEP-SELECT-007: clicking the background clears the selection, detail panels, and listing (#43)
HEP-SELECT-006#43
  • pass HEP-SELECT-006: changing Display Type while a participant is selected re-renders the coordinated panels in the new units (#43)
HEP-CTRL-009#43
  • pass HEP-CTRL-009: grouping colors the points and renders a legend (#43)
Evidence screenshot HEP-CTRL-009-color-by-group.png
HEP-CTRL-006, HEP-CHART-003#43
  • pass HEP-CTRL-006/HEP-CHART-003: the axis-type toggle switches both axes between linear and log (#43)
Evidence screenshot HEP-CTRL-006-log-axes.png
HEP-CHART-004#43
  • pass HEP-CHART-004: point tooltips list participant, R Ratio, peaks with days, and the day difference (#43)
HEP-API-003#43
  • pass HEP-API-003: participantsSelected fires on select and clear (#43)
HEP-API-001#43
  • pass HEP-API-001: lifecycle API supports init, setData, setSettings, render, resize, and destroy (#43)

Unit evidence (Vitest — tests/unit/hep-explorer/)

11 requirement rows · 55 tests

RequirementSource matrix rowsIssueTests & evidence
HEP-CTRL-001/002/006/007/008/009/010/011 (defaults, control specs)#43

configure.test.js

  • pass hep-explorer configure HEP-CTRL-001/002: measure-option lists coerce a single string to an array (port)
  • pass hep-explorer configure HEP-CTRL-008: the timing window defaults to 30 days (port)
  • pass hep-explorer configure HEP-CTRL-009: groups always offer a leading None option and honor group_by (port)
  • pass hep-explorer configure HEP-CTRL-010: r_ratio normalizes to a [min, max] pair with a data-resolved null max by default (port)
  • pass hep-explorer configure HEP-CTRL-011: filter specs normalize strings and objects and preserve a start value (port)
  • pass hep-explorer configure HEP-DATA-002/HEP-CTRL-001/002: measure_values map the short keys to full TEST strings and x/y defaults are ALT vs TB (port)
  • pass hep-explorer configure HEP-DISPLAY-001/HEP-CTRL-006/007: display, axis-type, point-size, and measure constants match the original renderer (port)
  • pass hep-explorer getPlugins HEP-CTRL-009: groupColorScale maps distinct group values to palette colors and cycles (port)
  • pass hep-explorer getScales HEP-CHART-003/HEP-CTRL-006: a log domain runs from the smallest positive value to the max, padded, including the cut (port)
  • pass hep-explorer getScales HEP-CTRL-006: the log axis type switches both scales to logarithmic and drops a non-positive min (port)
  • pass hep-explorer structureData HEP-CTRL-008: buildPoints flags points outside the timing window as hollow (port)
  • pass hep-explorer structureData HEP-CTRL-009: buildPoints tags each point with its participant-level group value when grouping (port)
  • pass hep-explorer structureData HEP-CTRL-010: maxRRatio is the largest finite participant R-Ratio, 0 when none is finite (port)
  • pass hep-explorer structureData HEP-CTRL-011: applyFilters keeps points matching every active filter; unset filters match everything (port)
Evidence screenshot HEP-CTRL-001-control-panel.pngEvidence screenshot HEP-CTRL-009-color-by-group.pngEvidence screenshot HEP-CTRL-006-log-axes.pngEvidence screenshot HEP-DISPLAY-001-mdish-display.png
HEP-QUAD-001, HEP-DATA-001/002, HEP-DISPLAY-001, HEP-SELECT-006 (cuts back-fill, mappings)#43

configure.test.js

  • pass hep-explorer configure HEP-DATA-001..004: default settings map the standard id, measure, value, unit, normal-range, and timing columns (port)
  • pass hep-explorer configure HEP-DATA-002: a partial measure_values override back-fills the other measures from the defaults (port)
  • pass hep-explorer configure HEP-DATA-002/HEP-CTRL-001/002: measure_values map the short keys to full TEST strings and x/y defaults are ALT vs TB (port)
  • pass hep-explorer configure HEP-DISPLAY-001/HEP-CTRL-006/007: display, axis-type, point-size, and measure constants match the original renderer (port)
  • pass hep-explorer configure HEP-QUAD-001: a partial cuts override deep-merges onto the defaults so untouched measures keep their cuts (port)
  • pass hep-explorer configure HEP-QUAD-001: cutFor back-fills unlisted measures and missing display modes from the defaults entry (port)
  • pass hep-explorer configure HEP-QUAD-001: default cuts give the classic eDISH view — ALT >= 3xULN via the defaults entry, TB >= 2xULN (port)
  • pass hep-explorer configure HEP-SELECT-006: details normalize to spec arrays and default to an empty list for the derived columns (port)
  • pass hep-explorer getScales HEP-DISPLAY-001/HEP-CHART-002: axis suffix and label reflect the active display mode and use the full measure label (port)
  • pass hep-explorer structureData HEP-DATA-002: resolveMeasureRows matches rows via the measure_values TEST strings (port)
  • pass hep-explorer structureData HEP-DISPLAY-001: buildPoints in mDISH uses the xBaseline peaks (port)
  • pass hep-explorer structureData HEP-DISPLAY-001: deriveBaseline uses the day-0 record, else the earliest day, as the xBaseline denominator (port)
Evidence screenshot HEP-CTRL-001-control-panel.pngEvidence screenshot HEP-CTRL-006-log-axes.pngEvidence screenshot HEP-DISPLAY-001-mdish-display.png
HEP-DATA-005 (schema required columns)#43

checkInputs.test.js

  • pass hep-explorer checkInputs HEP-DATA-005: missing required columns throw a single error naming every missing variable (port)
  • pass hep-explorer checkInputs HEP-DATA-005: non-array or empty data reports every required column as missing (port)
  • pass hep-explorer checkInputs HEP-DATA-005: remapped column settings are validated against the remapped names (port)
  • pass hep-explorer checkInputs HEP-DATA-005: valid long-format data with the required columns passes (port)
HEP-DATA-002/003/004 (measure resolution, cleaning)#43

structureData.test.js

  • pass hep-explorer configure HEP-DATA-002: a partial measure_values override back-fills the other measures from the defaults (port)
  • pass hep-explorer configure HEP-DATA-002/HEP-CTRL-001/002: measure_values map the short keys to full TEST strings and x/y defaults are ALT vs TB (port)
  • pass hep-explorer structureData HEP-DATA-002: resolveMeasureRows matches rows via the measure_values TEST strings (port)
  • pass hep-explorer structureData HEP-DATA-003: cleanData drops blank/non-numeric values and non-positive ULNs with a count (port)
  • pass hep-explorer structureData HEP-DATA-004: a non-numeric study-day value is treated as absent (NaN), not coerced (port)
  • pass hep-explorer structureData HEP-DATA-004: without a study-day column __hep_day is NaN and timing falls back to filled points (port)
  • pass hep-explorer structureData HEP-DATA-004/HEP-DISPLAY-002: cleanData tags rows with numeric value, ULN, day, and the xULN derivation (port)
  • pass hep-explorer structureData HEP-SELECT-004/HEP-DATA-004: with no study day, assignSequence orders and pairs by per-measure input order (port)
Evidence screenshot HEP-CTRL-001-control-panel.pngEvidence screenshot HEP-DATA-003-invalid-data-note.png
HEP-DISPLAY-001/002/003/004/006 (×ULN, ×Baseline, peaks, R-Ratio)#43

structureData.test.js

  • pass hep-explorer configure HEP-DISPLAY-001/HEP-CTRL-006/007: display, axis-type, point-size, and measure constants match the original renderer (port)
  • pass hep-explorer getScales HEP-DISPLAY-001/HEP-CHART-002: axis suffix and label reflect the active display mode and use the full measure label (port)
  • pass hep-explorer structureData HEP-CHART-001/HEP-DISPLAY-003: buildPoints reduces to one peak-vs-peak point per participant with timing and rRatio (port)
  • pass hep-explorer structureData HEP-DATA-004/HEP-DISPLAY-002: cleanData tags rows with numeric value, ULN, day, and the xULN derivation (port)
  • pass hep-explorer structureData HEP-DISPLAY-001: buildPoints in mDISH uses the xBaseline peaks (port)
  • pass hep-explorer structureData HEP-DISPLAY-001: deriveBaseline uses the day-0 record, else the earliest day, as the xBaseline denominator (port)
  • pass hep-explorer structureData HEP-DISPLAY-003: participantPeak picks the record with the max active-display value, per display mode (port)
  • pass hep-explorer structureData HEP-DISPLAY-004: a zero baseline leaves xBaseline NaN so mDISH drops the participant (port)
  • pass hep-explorer structureData HEP-DISPLAY-004: buildPoints in mDISH drops participants without a usable baseline (port)
  • pass hep-explorer structureData HEP-DISPLAY-006: computeRRatio is peak ALT xULN over peak ALP xULN, NaN without ALP (port)
Evidence screenshot HEP-CTRL-006-log-axes.pngEvidence screenshot HEP-DISPLAY-001-mdish-display.png
HEP-CHART-001, HEP-CTRL-008/009/011 (points, timing, group, filters)#43

structureData.test.js

  • pass hep-explorer configure HEP-CTRL-008: the timing window defaults to 30 days (port)
  • pass hep-explorer configure HEP-CTRL-009: groups always offer a leading None option and honor group_by (port)
  • pass hep-explorer configure HEP-CTRL-011: filter specs normalize strings and objects and preserve a start value (port)
  • pass hep-explorer getPlugins HEP-CTRL-009: groupColorScale maps distinct group values to palette colors and cycles (port)
  • pass hep-explorer structureData HEP-CHART-001/HEP-DISPLAY-003: buildPoints reduces to one peak-vs-peak point per participant with timing and rRatio (port)
  • pass hep-explorer structureData HEP-CTRL-008: buildPoints flags points outside the timing window as hollow (port)
  • pass hep-explorer structureData HEP-CTRL-009: buildPoints tags each point with its participant-level group value when grouping (port)
  • pass hep-explorer structureData HEP-CTRL-011: applyFilters keeps points matching every active filter; unset filters match everything (port)
Evidence screenshot HEP-CTRL-009-color-by-group.png
HEP-QUAD-004 (quadrant classification counts/percents)#43

structureData.test.js

  • pass hep-explorer structureData HEP-QUAD-004: a point exactly on a cutpoint classifies as High, and empty data yields zero percents (port)
  • pass hep-explorer structureData HEP-QUAD-004: classifyQuadrants buckets one point per quadrant with counts and percents (port)
HEP-SELECT-002/003/005 (drill-down series)#43

structureData.test.js

  • pass hep-explorer structureData HEP-SELECT-002: participantMeasureSeries returns one day-ordered series per present measure in display units (port)
  • pass hep-explorer structureData HEP-SELECT-003: visitPathSeries pairs the X/Y values by visit in chronological order (port)
  • pass hep-explorer structureData HEP-SELECT-003: visitPathSeries respects the active display mode (port)
  • pass hep-explorer structureData HEP-SELECT-003: without a visit column the path pairs by study day and labels the days (port)
  • pass hep-explorer structureData HEP-SELECT-005: measureSummary reports n/min/median/max of the raw values per present measure (port)
HEP-CHART-002/003/004, HEP-CTRL-006, HEP-DISPLAY-001 (domains, log, labels)#43

getScales.test.js

  • pass hep-explorer configure HEP-DISPLAY-001/HEP-CTRL-006/007: display, axis-type, point-size, and measure constants match the original renderer (port)
  • pass hep-explorer getPlugins HEP-CHART-004: pointTooltip lists participant, R Ratio, both peaks with days, and the day gap (port)
  • pass hep-explorer getPlugins HEP-CHART-004: pointTooltip names each measure with its full label from measure_values (port)
  • pass hep-explorer getPlugins HEP-CHART-004: pointTooltip shows NA for a missing R Ratio or day and omits an unknown day gap (port)
  • pass hep-explorer getScales HEP-CHART-002: buildScales titles both axes with the full measure labels in the active display units (port)
  • pass hep-explorer getScales HEP-CHART-003: a linear eDISH domain starts at 0 and always keeps the cutpoint in view (port)
  • pass hep-explorer getScales HEP-CHART-003: degenerate linear domains fall back sanely (port)
  • pass hep-explorer getScales HEP-CHART-003/HEP-CTRL-006: a log domain runs from the smallest positive value to the max, padded, including the cut (port)
  • pass hep-explorer getScales HEP-CHART-004: formatNumber trims trailing zeros at the requested precision and blanks non-finite values (port)
  • pass hep-explorer getScales HEP-CTRL-006: the log axis type switches both scales to logarithmic and drops a non-positive min (port)
  • pass hep-explorer getScales HEP-DISPLAY-001/HEP-CHART-002: axis suffix and label reflect the active display mode and use the full measure label (port)
  • pass hep-explorer structureData HEP-DISPLAY-001: buildPoints in mDISH uses the xBaseline peaks (port)
  • pass hep-explorer structureData HEP-DISPLAY-001: deriveBaseline uses the day-0 record, else the earliest day, as the xBaseline denominator (port)
Evidence screenshot HEP-CTRL-006-log-axes.pngEvidence screenshot HEP-DISPLAY-001-mdish-display.png
HEP-CHART-004, HEP-CTRL-009, HEP-QUAD-002, HEP-SELECT-001 (tooltip, palette, plugin)#43

getPlugins.test.js

  • pass hep-explorer configure HEP-CTRL-009: groups always offer a leading None option and honor group_by (port)
  • pass hep-explorer getPlugins HEP-CHART-004: pointTooltip lists participant, R Ratio, both peaks with days, and the day gap (port)
  • pass hep-explorer getPlugins HEP-CHART-004: pointTooltip names each measure with its full label from measure_values (port)
  • pass hep-explorer getPlugins HEP-CHART-004: pointTooltip shows NA for a missing R Ratio or day and omits an unknown day gap (port)
  • pass hep-explorer getPlugins HEP-CTRL-009: groupColorScale maps distinct group values to palette colors and cycles (port)
  • pass hep-explorer getPlugins HEP-QUAD-002: QUADRANT_LABELS pin the four Hy's-Law quadrants to their corner and High/Normal combination (port)
  • pass hep-explorer getPlugins HEP-SELECT-001: the selection highlight color is a hex color distinct from the group palette (port)
  • pass hep-explorer getScales HEP-CHART-004: formatNumber trims trailing zeros at the requested precision and blanks non-finite values (port)
  • pass hep-explorer structureData HEP-CTRL-009: buildPoints tags each point with its participant-level group value when grouping (port)
Evidence screenshot HEP-CTRL-009-color-by-group.pngEvidence screenshot HEP-QUAD-002-quadrant-summary.pngEvidence screenshot HEP-SELECT-001-participant-detail.png
HEP-API-001 (module export)#43

export.test.js

  • pass hep-explorer module export HEP-API-001: the public collection exposes the hepExplorer factory (port)

Visual evidence

Every screenshot below is a committed baseline: the same PNG is the visual-regression baseline the browser suite asserts against and the evidence artifact shown here. Click any capture for the full-resolution image.

Source-matrix routing status

No reviewed source requirement matrix exists yet for this module (the config's hep-explorer.md matrix link resolves once it is published in the requirements repo), so routing is against the port spec's scope rather than matrix rows.

Reproducing this report

The evidence set is regenerated from a full test run and committed with the code it qualifies; CI fails when they drift. To verify or rebuild it:

npm ci
npm run evidence:check   # compare a fresh run against the committed evidence
npm run evidence         # regenerate docs/evidence/hep-explorer/evidence.json

Screenshot baselines are canonical to the Linux CI runner; the repository's Update evidence baselines workflow is the authoritative way to refresh them. See CONTRIBUTING.md for the traceability convention.