Test evidence

Cross-tabulation

Every requirement of this module, the tests named for it, and what each test recorded the last time the evidence was rebuilt.

Summary

Requirements
31
Tests named for them
31 (10 unit, 21 browser)
Result
pass every test passing
Screenshots
9
Recorded
2026-10-04 19:02 UTC
Environment
linux 6.17.0-1022-azure · node v22.23.3 · playwright 1.61.1 · chromium 149.0.7827.55
Test run
Continuous-integration run 37226711557

The requirements are the rows of the module’s requirement matrix. A test is named for a requirement by starting its name with the requirement’s ID. The results are read from the committed evidence set; continuous integration reruns every test and fails when the committed set no longer matches.

Requirements and their tests

  1. CT-KIT-001 pass

    The chart is built from safety.viz's kit on the page and draws its bars with the kit's Chart.js, bundling neither; without safety.viz on the page it is refused with a message saying what is missing.

    • pass browser CT-KIT-001: the chart is built from safety.viz’s kit on the page and draws its bars with the kit’s Chart.js; without safety.viz it says what is missing (#44)
  2. CT-CFG-001 pass

    Every setting has a default; row_by and col_by are each a column or a cut variable; percent is row, col or none; test is chisq, fisher or none; a setting that is not known, or a value it cannot take, is refused with a sentence naming it.

    • pass unit cross-tabulation: settings CT-CFG-001: every setting has a default; the rows and the columns are each a column or a cut variable; the percentages, the test and the statistic are checked (#44)
  3. CT-DATA-001 pass

    The counts, the row and column totals and the grand total are desktop R's table() of the same participants, each in R's category, for every case; a value that is empty or only white space is missing, as R's recipe reads it.

    • pass unit cross-tabulation: the table CT-DATA-001: the counts, the row and column totals and the grand total are desktop R’s table() of the same participants, for every case (#44)
  4. CT-DATA-002 pass

    Each cell's row and column percentages are its count of its row's or its column's total, as desktop R works them out.

    • pass unit cross-tabulation: the table CT-DATA-002: the row and the column percentages are each count of its row’s or its column’s total, as desktop R works them out (#44)
  5. CT-DATA-003 pass

    A biomarker cut by the shared cut rule makes the rows or the columns, low to high, worked out on the participants the filters keep.

    • pass unit cross-tabulation: the table CT-DATA-003: a biomarker cut by the shared cut rule makes the rows or the columns, low to high, worked out on the participants the filters keep (#44)
  6. CT-DRAW-001 pass

    Arm by response on the synthetic study: every count, the totals and each row's percentages on the page are desktop R's, and the stacked bars are the same percentages, drawn to 100.

    • pass browser CT-DRAW-001: arm by response: every count, the totals and each row’s percentages are desktop R’s, and the stacked bars are the same percentages (#44)
    Screenshot captured by a test of CT-DRAW-001: arm by responseScreenshot captured by a test of CT-DRAW-001: as the gallery shows it
  7. CT-DRAW-002 pass

    With column percentages each cell's percentage is of its column's total and the bars stack each column by the rows; with none there are no percentages.

    • pass browser CT-DRAW-002: column percentages are each count of its column’s total, and the bars then stack each column by the rows; with none there are no percentages (#44)
  8. CT-DRAW-003 pass

    Response by CRP at Baseline cut at its median: the columns are the cut's groups, low to high, with desktop R's counts; the footnote states the cut; the Columns control offers the cut variables the settings name.

    • pass browser CT-DRAW-003: a biomarker cut by the shared cut rule makes the columns, low to high, with desktop R’s counts, and the footnote states the cut; the Columns control offers it (#44)
    Screenshot captured by a test of CT-DRAW-003: response by crp median
  9. CT-STAT-001 pass

    R is asked once per table, with one row per participant, the function, the arguments, the identity and the row count that desktop R's recipe writes; a column's categories are named by code point and a cut's low to high, the same in every browser language, whatever order the table shows them in.

    • pass unit cross-tabulation: what R is asked, and what the line says CT-STAT-001: R is asked once per table, with the function, the arguments, the identity and the row count desktop R’s recipe writes, and one row per participant (#44)
  10. CT-STAT-002 pass

    R's chi-square and Fisher results are printed with their method and counts, labelled exploratory and unadjusted, and Fisher's odds ratio with its interval.

    • pass unit cross-tabulation: what R is asked, and what the line says CT-STAT-002: R’s chi-square and Fisher results are printed with their method and counts, labelled exploratory and unadjusted, and Fisher’s odds ratio with its interval (#44)
  11. CT-STAT-003 pass

    The small-expected-count warning is R's: printed with the result as R worded it when R gives it, and not otherwise.

    • pass unit cross-tabulation: what R is asked, and what the line says CT-STAT-003: the small-expected warning is R’s, printed with the result when R gives it and not otherwise (#44)
  12. CT-STAT-004 pass

    Handed to a connection as stored results, each of desktop R's answers is found by the chart's request for its table.

    • pass unit cross-tabulation: what R is asked, and what the line says CT-STAT-004: handed to a connection as stored results, each of R’s answers is found by the chart’s request for its table (#44)
  13. CT-STAT-005 pass

    With R's answers stored in the page, the chi-square and the Fisher results print with their method and counts, Fisher's odds ratio with its interval, and what the chart asked is the key R wrote.

    • pass browser CT-STAT-005: with R’s answers stored in the page, the chi-square and Fisher results print with their method and counts, Fisher’s odds ratio with its interval, and the identity R wrote is the chart’s (#44)
    Screenshot captured by a test of CT-STAT-005: fisher with odds ratio
  14. CT-STAT-006 pass

    R's small-expected-count warning is printed with the result for a table with an expected count below 5 (response by CRP at Baseline cut at 8), and not for one without.

    • pass browser CT-STAT-006: R’s small-expected-count warning is printed with the result for a table with an expected count below 5, and not for one without (#44)
    Screenshot captured by a test of CT-STAT-006: small expected counts
  15. CT-STAT-007 pass

    With no R attached the line says statistics are unavailable, the table and the bars are still drawn, and nothing is fetched; with no test chosen R is asked nothing.

    • pass browser CT-STAT-007: with no R attached the line says statistics are unavailable, the table and the bars are still drawn, and nothing is fetched (#44)
  16. CT-STAT-008 pass

    The test is of the participants the filters keep, as desktop R gives it for the women alone, and the line says the filter.

    • pass browser CT-STAT-008: the test is of the participants the filters keep, as desktop R gives it for the women alone, and the line says the filter (#44)
  17. CT-STAT-009 pass

    Once the connection is replaced, a late answer from the old one changes neither the line nor what chart.statistics() reports.

    • pass browser CT-STAT-009: once the connection is replaced, a late answer from the old one changes neither the line nor what chart.statistics() reports (#44)
  18. CT-STAT-010 pass

    A table R withholds, a category below its minimum size, prints R's reason with the table's variables named where R names the columns the chart handed it, and no number.

    • pass unit cross-tabulation: what R is asked, and what the line says CT-STAT-010: a table R withholds, a category below its minimum size, prints R’s reason with the table’s variables named where R names the columns the chart gave it, and no number (#44, #58)
  19. CT-STAT-011 pass

    In the page, a withheld table's line reads R's reason with the variables named, and no p-value.

    • pass browser CT-STAT-011: a table R withholds prints R’s reason, with the table’s variables named in it, and no number (#44, #58)
  20. CT-STAT-012 pass

    After a filter changes, the answer to the table no longer on screen is dropped when it arrives, and the line and chart.statistics() hold the answer for the table drawn.

    • pass browser CT-STAT-012: after a filter changes, the answer to the table no longer on screen is dropped when it arrives; the line shows the answer for the table drawn (#44, #58)
  21. CT-STAT-013 pass

    Changing what the percentages are of redraws the table and the bars and asks R nothing: the line keeps R's answer for the table.

    • pass browser CT-STAT-013: changing what the percentages are of redraws the table and the bars and asks R nothing: the line keeps R’s answer (#44, #58)
  22. CT-LIST-001 pass

    Clicking a count lists that cell's participants, the ones desktop R puts in that cell, in the kit's listing, and a row of it opens safety.viz's participant profile of that participant.

    • pass browser CT-LIST-001: clicking a count lists that cell’s participants in the kit’s listing, and a row of it opens the participant’s profile (#44)
    Screenshot captured by a test of CT-LIST-001: participants of a cell
  23. CT-FAIL-001 pass

    When drawing fails the chart says so in its footnote, empties the listing and the rail, keeps its controls and leaves nothing half drawn, and draws again once it can.

    • pass browser CT-FAIL-001: when drawing fails the chart says so in its element and keeps its controls, leaving nothing half drawn, and draws again once it can (#44)
  24. CT-DROP-001 pass

    With a participant table, participants it does not have and rows with no participant id are counted by reason; a participant table without the id column is refused with a sentence; filters that let nobody through say so; the id column and the table change together.

    • pass browser CT-DROP-001: with a participant table, participants it does not have and rows with no participant id are counted by reason; a participant table without the id column is refused with a sentence; filters that let nobody through say so; the id column and the table change together (#44)
  25. CT-MOBILE-001 pass

    At 390 pixels the controls are folded away, the table fits or scrolls inside its own box, and the page does not scroll sideways.

    • pass browser CT-MOBILE-001: at 390px the controls are folded away, the table fits or scrolls inside its own box, and the page does not scroll sideways (#44)
    Screenshot captured by a test of CT-MOBILE-001: the table on a phone
  26. CT-SITE-001 pass

    The live demo holds at a 390-pixel-wide viewport with no horizontal scroll, with the controls open.

    • pass browser CT-SITE-001: the live demo holds at a 390px-wide viewport with no horizontal scroll, with the controls open (#44)
    Screenshot captured by a test of CT-SITE-001: demo on a phone
  27. CT-SITE-002 pass

    The gallery lists the chart with links to its live demo, its evidence page and its API reference; the demo opens on arm by response, draws the table where R cannot be reached and says so, and offers CRP at Baseline cut at its median.

    • pass browser CT-SITE-002: the gallery lists the chart with links to its live demo, its evidence page and its API reference, and the demo opens on arm by response (#44)
  28. CT-SITE-003 pass

    The API reference has a table row for every setting the chart has, with the default the code has; the site build fails when one is missing.

    • pass unit cross-tabulation: the API reference CT-SITE-003: the reference names every setting the chart has, with its default, and a setting it leaves out is a problem (#44)
  29. CT-LIVE-001 pass

    Against R started in the browser on the demo: arm by response, by chi-square and by Fisher's exact test, every count, statistic and p-value equals desktop R's within 1 part in 10^8.

    • pass browser CT-LIVE-001: arm by response, by chi-square and by Fisher’s exact test, with R started in this browser: every count, statistic and p-value is desktop R’s (#44)
    Screenshot captured by a test of CT-LIVE-001: r in the browser
  30. CT-LIVE-002 pass

    Against R in the browser: response by CRP at Baseline cut at its median, by both tests, and cut at 8, where R warns of small expected counts, equal desktop R's, warning included.

    • pass browser CT-LIVE-002: response by CRP at Baseline cut at its median, by both tests, and cut at 8, where R warns of small expected counts, are desktop R’s (#44)
  31. CT-LIVE-003 pass

    Against R in the browser: the women alone, by the filter, equals desktop R's.

    • pass browser CT-LIVE-003: the women alone, by the filter, is desktop R’s (#44)

Tests run with every module

92 tests of the site, the evidence pipeline and the repository’s own checks

These are recorded in every module’s evidence set. A requirement ID one of them carries belongs to another module’s page.

  • pass browser CORE-SITE-001: the home page names the library and its version, and shows the version its bundle reports (#1)
  • pass browser CORE-SITE-002: the home page holds at a 390px-wide viewport with no horizontal scroll (#1)
  • pass browser CORE-SITE-003: the gallery is reached from the home page and lists the published charts, or says that none is published yet (#7)
  • pass browser CORE-SITE-004: the gallery lists each shared part, and its two links lead to that module’s evidence page and API reference (#7)
  • pass browser CORE-SITE-006: every module has an evidence page that lists each requirement of its matrix (#7)
  • pass browser CORE-SITE-006: the connection to R’s evidence page lists every RCON- and PVAL- requirement with the tests that prove it (#7)
  • pass browser CORE-SITE-007: a screenshot a test captured is shown under its requirement on the evidence page (#7)
  • pass browser CORE-SITE-009: every module has an API reference page that documents each name it exports (#7)
  • pass browser CORE-SITE-009: the connection to R’s API reference documents createConnection and formatStatistic (#7)
  • pass browser CORE-SITE-012: the gallery holds at a 390px-wide viewport with no horizontal scroll (#7)
  • pass browser CORE-SITE-013: each module’s evidence page holds at a 390px-wide viewport with no horizontal scroll (#7)
  • pass browser CORE-SITE-014: each module’s API reference holds at a 390px-wide viewport, with its tables restacked (#7)
  • pass browser CORE-SITE-015: the site serves the synthetic study, and the gallery gives its row counts and the commit it was copied from (#7)
  • pass unit API reference page CORE-SITE-009: a link to another reference file goes to that module’s page, and the page names the file it was rendered from (#7)
  • pass unit API reference page CORE-SITE-009: the page is the reference file, rendered: its title, sections, tables and code (#7)
  • pass unit API reference page CORE-SITE-009: the sections are listed at the top, each linked to its place on the page (#7)
  • pass unit API reference: held to the code CORE-MAN-006: an export listed as data is documented as one, under one heading, and its fields are not held one by one (#32)
  • pass unit API reference: held to the code CORE-SITE-010: a constant whose value the reference does not give is a problem (#7)
  • pass unit API reference: held to the code CORE-SITE-010: a function the reference documents that the bundle does not export is a problem (#7)
  • pass unit API reference: held to the code CORE-SITE-010: a namespace in the surface stands for each of its members, and a constant carries its value (#7)
  • pass unit API reference: held to the code CORE-SITE-010: a parameter the source documents and the reference leaves out is a problem (#7)
  • pass unit API reference: held to the code CORE-SITE-010: a reference that documents every export, parameter and constant has no problems (#7)
  • pass unit API reference: held to the code CORE-SITE-010: an export no module claims, a surface the bundle lacks and an empty surface are each a problem (#7)
  • pass unit API reference: held to the code CORE-SITE-010: an export with no heading in the reference is a problem (#7)
  • pass unit API reference: held to the code CORE-SITE-010: the committed references document everything the committed bundle exports (#7)
  • pass unit API reference: held to the code CORE-SITE-010: the connection’s reference is held to the parameters its source documents (#7)
  • pass unit API reference: held to the code GC-SITE-004: a chart’s reference names every setting the chart has, and a setting it leaves out is a problem (#9)
  • pass unit evidence normalizer buildEvidenceSets splits records per module and duplicates shared scaffold records (#1)
  • pass unit evidence normalizer buildRun builds GitHub Actions run provenance from the environment (#1)
  • pass unit evidence normalizer compareEvidence flags status drift and test-set changes, ignoring screenshots (#1)
  • pass unit evidence normalizer compareEvidence ignores provenance so --check never drifts on generatedAt/environment/run (#1)
  • pass unit evidence normalizer CORE-SITE-011: a requirement row with no test named for it is reported (#7)
  • pass unit evidence normalizer CORE-SITE-011: a test that names a requirement in no matrix is reported with the test (#7)
  • pass unit evidence normalizer moduleForFile routes test files to modules by path (#1)
  • pass unit evidence normalizer normalizePlaywright walks nested suites into browser-suite records (#1)
  • pass unit evidence normalizer normalizeVitest maps assertion results to unit-suite records (#1)
  • pass unit evidence normalizer parseTestName extracts requirement IDs and issue refs (#1)
  • pass unit evidence normalizer parseTestName recognizes any requirement-ID prefix, not just SH (#1)
  • pass unit evidence normalizer provenance lives in dedicated top-level keys; the records array stays timestamp-free (#1)
  • pass unit evidence page CORE-SITE-006: a requirement with no test says so, and the summary counts it (#7)
  • pass unit evidence page CORE-SITE-006: each requirement shows the tests named for it, unit or browser, with the result each recorded (#7)
  • pass unit evidence page CORE-SITE-006: every requirement is listed in the matrix’s order with its text (#7)
  • pass unit evidence page CORE-SITE-006: tests that carry none of the module’s requirements are listed apart, as run with every module (#7)
  • pass unit evidence page CORE-SITE-006: with every requirement tested and passing the summary says every test is passing (#7)
  • pass unit evidence page CORE-SITE-007: a screenshot is shown under the requirement it was captured for, and only there (#7)
  • pass unit evidence page CORE-SITE-007: the build is told of a screenshot the evidence names that is not committed (#7)
  • pass unit evidence page CORE-SITE-008: results recorded on a developer’s machine say so, and absent provenance is not invented (#7)
  • pass unit evidence page CORE-SITE-008: the page says when and where the results were recorded and links the run (#7)
  • pass unit evidence page the page links the module’s requirement matrix and its committed evidence set (#7)
  • pass unit gallery CORE-SITE-003: a chart that is registered but not yet available is not listed as published (#7)
  • pass unit gallery CORE-SITE-003: a chart’s card shows its picture once that screenshot is committed, and no picture before (#9)
  • pass unit gallery CORE-SITE-003: a registered chart is listed under Charts with links to its evidence page and API reference (#7)
  • pass unit gallery CORE-SITE-003: with no chart registered the gallery says that no chart is published yet (#7)
  • pass unit gallery CORE-SITE-004: each shared part is listed with links to its evidence page and API reference (#7)
  • pass unit gallery CORE-SITE-004: the registry as committed lists the core and the connection to R as shared parts (#7)
  • pass unit gallery CORE-SITE-015: the gallery says what each table of the synthetic study holds, its rows, and the commit it was copied from (#7)
  • pass unit gallery the home page heads its callout for one chart and for several (#26)
  • pass unit gallery the home page links each module’s evidence page and API reference, and the gallery (#7)
  • pass unit gallery the home page says there are no charts yet only while none is published (#9)
  • pass unit markdown: blocks a relative link points at the repository, and a link to another reference file at its page (#7)
  • pass unit markdown: blocks CORE-SITE-009: a fenced block is code, escaped and left as written, and a # inside it is not a heading (#7)
  • pass unit markdown: blocks CORE-SITE-009: a table keeps each column heading on every cell, so it can restack on a narrow screen (#7)
  • pass unit markdown: blocks CORE-SITE-009: headings get the anchors GitHub gives them, repeated ones numbered (#7)
  • pass unit markdown: blocks CORE-SITE-009: paragraphs join their lines, and bullet and numbered lists keep theirs apart (#7)
  • pass unit markdown: inline keeps a code span inside a link label, and links a bare address in angle brackets (#7)
  • pass unit markdown: inline mdText strips the marks and keeps the words (#7)
  • pass unit markdown: inline reads nothing inside a code span as a link or as emphasis (#7)
  • pass unit markdown: inline renders code, links, bold and italic, and escapes everything else (#7)
  • pass unit module registry CORE-SITE-005: an entry that does not say whether it is a chart or a shared part is refused (#7)
  • pass unit module registry CORE-SITE-005: an entry without its matrix or its API reference is refused, as is a name registered twice (#7)
  • pass unit module registry CORE-SITE-005: the registry as committed is well formed (#7)
  • pass unit R check page RCON-PAGE-001: the page has a button that starts R, the stated tolerance and the versions desktop R used (#3)
  • pass unit R check page RCON-PAGE-002: the recorded megabytes, requests and seconds are shown for cold, reload and warm, with how they were measured (#3)
  • pass unit R check page RCON-PAGE-003: with no recorded measurement the page says so and prints no number in its place (#3)
  • pass unit repo hygiene no source or test file carries a machine-specific absolute path (#1)
  • pass unit requirements-lib: freshness guard flags added and removed requirement IDs (#1)
  • pass unit requirements-lib: freshness guard flags changed requirement text (#1)
  • pass unit requirements-lib: freshness guard reports fresh when the committed set matches a fresh extraction (#1)
  • pass unit requirements-lib: matrix parsing ignores the header, separator, and non-requirement content (#1)
  • pass unit requirements-lib: matrix parsing keeps an escaped pipe inside a requirement cell as a single row (#1)
  • pass unit requirements-lib: matrix parsing maps each requirement ID to its reviewed text (#1)
  • pass unit requirements-lib: requirement set wraps the parsed map with module + matrix provenance (#1)
  • pass unit requirements-lib: unregistered matrices passes when every matrix file is registered, ignoring the README and non-markdown files (#1)
  • pass unit requirements-lib: unregistered matrices reports a matrix file no module in site/config.json names (#1)
  • pass unit site pages CORE-SITE-001: the home page names the library and its version (#1)
  • pass unit site pages escapeHtml escapes the five HTML-significant characters (#1)
  • pass unit site pages renderShell fills title, description, version and root, and leaves no token behind (#1)
  • pass unit site pages summarizeModule counts requirement rows and passing test records (#1)
  • pass unit site pages the home page links to the R check page (#3)
  • pass unit site pages the home page lists each registered module with its counts and a link to its matrix (#1)
  • pass unit site validation: internal links flags internal links and asset references that do not resolve (#1)
  • pass unit site validation: internal links passes a site whose internal links all resolve, ignoring external and fragment links (#1)

Checking this page

npm ci
npm run evidence:check   # rerun every test and compare with the committed evidence set
npm run evidence         # rebuild docs/evidence/cross-tab/evidence.json