pediatric-ai-scribe-v3/e2e/tests/peguide-react.spec.js
Daniel aafe7981dc feat(client): port full PE_DATA checklist + Generate Exam Report flow
Biggest data port of the migration so far. PE_DATA is the 1000+ line
age-group × system × component × step hierarchy driving the pediatric
physical-exam checklist; every entry, pearl, significance note, and
abnormal-hint array is now available in the React tree.

client/src/data/pe-data.ts — verbatim port
  Extracted lines 316-1334 of public/js/peGuide.js with awk/sed, then
  wrapped in TS types. Every byte of the data body is byte-identical
  to the vanilla source. Added interfaces:
    PeStep { label, method, normal }
    PeComponent { name, steps[], abnormalHints[], pearl?, significance? }
    PeSystem { overview, components[] }
    PeAgeGroup { label, msk, neuro, resp, cv }
  …plus AGE_GROUP_ORDER / SYSTEM_ORDER / SYSTEM_LABELS canonical
  orderings for the UI.

client/src/data/pe-data.test.ts — parity lock
  Vitest suite that asserts every count captured from the vanilla
  source so any accidental drop surfaces as a red test:
    • 6 age groups × 4 systems
    • 103 components total
    • 27 pearl entries
    • 23 significance entries
    • per-cell component counts (e.g. toddler.neuro = 7, adolescent.cv = 5)
  Counts captured 2026-04-24 against peGuide.js commit 313ba7f.

client/src/pages/PeGuide.tsx — full viewer (replaces legacy-link stub)
  • Age-group pills (6) + system pills (4) drive the visible section
  • Overview banner per combination
  • CV system shows APTM legend + cardiac sounds library + innocent
    murmurs reference (unchanged clinical content from the earlier
    commit that added the scales/sounds file)
  • Resp system shows the respiratory sounds library
  • Collapsible grading-scales reference pulls from SYSTEM_SCALES
  • Component checklist: per-step Normal / Abnormal toggle, abnormal-
    hint list, pearl + significance callouts
  • Mark-all-normal + Reset shortcuts
  • Generate Exam Report posts the full step payload to
    /api/generate-pe-narrative, renders the returned narrative inline
  • No more "Open checklist in legacy viewer" amber banner — the
    React port now does the whole thing

e2e/tests/peguide-react.spec.js
  Age-group pills, system pills, overview rewrite on age change,
  CV/resp system-specific reference panels, mark-all-normal + summary,
  and a mocked /api/generate-pe-narrative round-trip.

Client tsc -b + vite build clean. Bundle 580.30 kB / 166.08 kB gz
(up ~100 kB from the shell-only port — the 1000-line PE_DATA is the
bulk; acceptable for the clinical reference data it surfaces).
2026-04-24 01:21:44 +02:00

84 lines
3.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ============================================================
// PE GUIDE (React port) — smoke tests for the full checklist.
// Covers age-group + system pills, overview, scales, sound
// libraries, component checklist with status toggles, and the
// Generate Exam Report path (mocked via page.route).
// ============================================================
const { test, expect, E2E_BASE } = require('../fixtures');
async function openPeGuide(page) {
await page.goto(E2E_BASE + '/app/peguide');
await page.waitForSelector('[data-testid="pe-age-group-pills"]', { timeout: 15000 });
}
test.describe('React PE Guide — age-group × system navigation', () => {
test('all 6 age-group pills render', async ({ authedPage: _, page }) => {
await openPeGuide(page);
for (const age of ['newborn', 'infant', 'toddler', 'preschool', 'school', 'adolescent']) {
await expect(page.locator('[data-testid="pe-age-' + age + '"]')).toBeVisible();
}
});
test('all 4 system pills render', async ({ authedPage: _, page }) => {
await openPeGuide(page);
for (const sys of ['msk', 'neuro', 'resp', 'cv']) {
await expect(page.locator('[data-testid="pe-system-' + sys + '"]')).toBeVisible();
}
});
test('switching age group rewrites the overview banner', async ({ authedPage: _, page }) => {
await openPeGuide(page);
await page.click('[data-testid="pe-age-newborn"]');
await expect(page.locator('[data-testid="pe-overview"]')).toContainText('Newborn');
await page.click('[data-testid="pe-age-adolescent"]');
await expect(page.locator('[data-testid="pe-overview"]')).toContainText('Adolescent');
});
test('CV system shows APTM + cardiac sounds + innocent murmurs', async ({ authedPage: _, page }) => {
await openPeGuide(page);
await page.click('[data-testid="pe-system-cv"]');
await expect(page.locator('[data-testid="pe-cv-aptm"]')).toBeVisible();
await expect(page.locator('[data-testid="sound-normal"]').first()).toBeVisible();
});
test('Resp system shows respiratory sound library', async ({ authedPage: _, page }) => {
await openPeGuide(page);
await page.click('[data-testid="pe-system-resp"]');
await expect(page.locator('[data-testid="pe-resp-sounds"]')).toBeVisible();
});
});
test.describe('React PE Guide — checklist + generation', () => {
test('mark-all-normal sets summary counts and enables Generate', async ({ authedPage: _, page }) => {
await openPeGuide(page);
await page.click('[data-testid="pe-age-toddler"]');
await page.click('[data-testid="pe-system-msk"]');
await page.click('[data-testid="btn-pe-all-normal"]');
await expect(page.locator('[data-testid="pe-checklist"]')).toContainText('0 not assessed');
await expect(page.locator('[data-testid="btn-pe-generate"]')).toBeEnabled();
});
test('Generate Exam Report calls /api/generate-pe-narrative', async ({ authedPage: _, page }) => {
await page.route('**/api/generate-pe-narrative', (route) =>
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
success: true,
model: 'mock-model',
narrative: 'MOCK PE narrative from the React port.',
summary: { normal: 5, abnormal: 0, notAssessed: 0 },
}),
}),
);
await openPeGuide(page);
await page.click('[data-testid="pe-age-toddler"]');
await page.click('[data-testid="pe-system-msk"]');
await page.click('[data-testid="btn-pe-all-normal"]');
await page.click('[data-testid="btn-pe-generate"]');
await expect(page.locator('[data-testid="pe-narrative"]')).toContainText('MOCK PE narrative');
});
});