diff --git a/tests/awards-timeline.test.mjs b/tests/awards-timeline.test.mjs index df7b30af..b5705e0c 100644 --- a/tests/awards-timeline.test.mjs +++ b/tests/awards-timeline.test.mjs @@ -13,7 +13,7 @@ // calling the unexported WinnerCard with a synthetic entry. import assert from 'node:assert/strict'; -import test from 'node:test'; +import test, { before } from 'node:test'; import { importSource } from './helpers-jsx.mjs'; import { @@ -27,7 +27,18 @@ const { default: AwardsTimeline } = await importSource( ); const { default: awardsData } = await importSource('data/awards.json'); -const timeline = AwardsTimeline(); +// Rendering at module scope would let a change that breaks the render throw +// before node:test starts, so the process dies with an uncaught exception +// instead of a failing test. A root `before` hook runs the same code inside +// the runner, so the failure is reported as a test failure and is attributed +// to whatever caused it. +let timeline; +let WinnerCard; + +before(() => { + timeline = AwardsTimeline(); + WinnerCard = componentNamed(timeline, 'WinnerCard'); +}); /** @returns {any[]} every element in the tree, in document order */ function elements(tree) { @@ -50,8 +61,6 @@ function componentNamed(tree, name) { return element.type; } -const WinnerCard = componentNamed(timeline, 'WinnerCard'); - function cardElements(tree = timeline) { return elements(tree).filter((element) => element.type === WinnerCard); } diff --git a/tests/community-people.test.mjs b/tests/community-people.test.mjs index 799fe98a..74769c4c 100644 --- a/tests/community-people.test.mjs +++ b/tests/community-people.test.mjs @@ -13,7 +13,7 @@ // That hook's effect is already covered at 100% by tests/use-focus-trap.test.mjs. import assert from 'node:assert/strict'; -import test from 'node:test'; +import test, { before } from 'node:test'; import React from 'react'; @@ -118,10 +118,16 @@ function findByClass(tree, className) { // `PersonCard` and `PersonDialog` are private, so they are taken from the tree // the exported component produces rather than imported. +// +// Rendering at module scope would let a change that breaks the render throw +// before node:test starts, so the process dies with an uncaught exception +// instead of a failing test. A root `before` hook runs the same code inside +// the runner, so the failure is reported as a test failure and is attributed +// to whatever caused it. const SECTIONS = Object.keys(peopleData.people); const SAMPLE_SECTION = SECTIONS[0]; -const PersonCard = CommunityPeople({ section: SAMPLE_SECTION }).props - .children[0].type; +let PersonCard; +let PersonDialog; const FULL_PERSON = { name: 'Ada Lovelace', @@ -143,8 +149,11 @@ function openDialog(person) { return { card, dialogElement }; } -const { dialogElement: SAMPLE_DIALOG } = openDialog(FULL_PERSON); -const PersonDialog = SAMPLE_DIALOG.type; +before(() => { + PersonCard = CommunityPeople({ section: SAMPLE_SECTION }).props.children[0] + .type; + PersonDialog = openDialog(FULL_PERSON).dialogElement.type; +}); function renderDialog(person, onClose = () => {}) { return render(PersonDialog, { diff --git a/tests/metrics-dashboard.test.mjs b/tests/metrics-dashboard.test.mjs index 0dc63323..b3a37a45 100644 --- a/tests/metrics-dashboard.test.mjs +++ b/tests/metrics-dashboard.test.mjs @@ -11,7 +11,7 @@ // than as snapshots of today's numbers. import assert from 'node:assert/strict'; -import test from 'node:test'; +import test, { before } from 'node:test'; import { formatDate } from '../src/components/shared/formatDate.js'; import { importWithData } from './helpers-component-data.mjs'; @@ -29,7 +29,20 @@ const { default: MetricsDashboard } = await importSource( ); const { default: metricsData } = await importSource('data/metrics.json'); -const dashboard = MetricsDashboard(); +// Rendering at module scope would let a change that breaks the render throw +// before node:test starts, so the process dies with an uncaught exception +// instead of a failing test. A root `before` hook runs the same code inside +// the runner, so the failure is reported as a test failure and is attributed +// to whatever caused it. +let dashboard; +let lifecycle; +let Sparkline; + +before(() => { + dashboard = MetricsDashboard(); + lifecycle = renderNested(dashboard, 'LifecycleSection'); + Sparkline = componentNamed(lifecycle, 'Sparkline'); +}); /** @returns {any[]} every element in the tree, in document order */ function elements(tree) { @@ -75,9 +88,6 @@ function parsePoints(value) { }); } -const lifecycle = renderNested(dashboard, 'LifecycleSection'); -const Sparkline = componentNamed(lifecycle, 'Sparkline'); - test('the freshness line states when the data was collected', () => { const meta = elements(dashboard).find((element) => textOf(element).startsWith('Last updated'),