diff --git a/tests/radar-reports.test.mjs b/tests/radar-reports.test.mjs
new file mode 100644
index 00000000..df38d458
--- /dev/null
+++ b/tests/radar-reports.test.mjs
@@ -0,0 +1,162 @@
+// src/components/RadarReports/index.js renders the whole /reports page from
+// the mirrored data/radar-reports.json corpus, and no test loaded it — it did
+// not appear in the `node --test --experimental-test-coverage` report at all.
+//
+// scripts/validate-radar-reports.mjs guards the shape of the JSON, but nothing
+// guarded the rendering: the provenance line, the one-
-per-report mapping,
+// the optional publishedAt row and — most importantly — the
+// `target="_blank"`/`rel="noreferrer"` pairing on every outbound cncf.io link
+// could all regress silently. These assertions cover the rendered output.
+
+import assert from 'node:assert/strict';
+import { readFileSync } from 'node:fs';
+import { fileURLToPath } from 'node:url';
+import test from 'node:test';
+
+import { importSource } from './helpers-jsx.mjs';
+import {
+ findAllByType,
+ findByType,
+ textOf,
+ walkElements,
+} from './tools/react-element-tree.mjs';
+
+const { default: RadarReports } = await importSource(
+ 'src/components/RadarReports/index.js',
+);
+
+// The component imports the corpus through the `@site` alias at module scope,
+// so the test has to assert against the same checked-in file rather than an
+// injected fixture.
+const data = JSON.parse(
+ readFileSync(
+ fileURLToPath(new URL('../data/radar-reports.json', import.meta.url)),
+ 'utf8',
+ ),
+);
+const reports = data.radarReports || [];
+
+const LONG_DATE = { year: 'numeric', month: 'long', day: 'numeric' };
+
+/**
+ * `` is a nested component element, so the walker yields it
+ * without descending into its output. Invoking it renders that subtree.
+ */
+function renderSyncStatus(tree) {
+ const element = [...walkElements(tree)].find(
+ (node) =>
+ typeof node.type === 'function' && node.type.name === 'SyncStatus',
+ );
+ assert.ok(element, 'expected the component to render a ');
+ return element.type(element.props);
+}
+
+test('the report list is a labelled landmark region', () => {
+ const tree = RadarReports();
+ assert.equal(tree.type, 'section');
+ assert.equal(tree.props['aria-label'], 'CNCF Technology Radar reports');
+});
+
+test('one list item is rendered per mirrored report', () => {
+ const items = findAllByType(RadarReports(), 'li');
+ assert.equal(items.length, reports.length);
+ assert.ok(
+ reports.length > 0,
+ 'expected the corpus to hold at least one report',
+ );
+});
+
+test('every list item carries a unique React key', () => {
+ const keys = findAllByType(RadarReports(), 'li').map((item) => item.key);
+ assert.ok(
+ keys.every((key) => key !== null && key !== undefined),
+ 'a keyless list item would make React re-mount rows on every re-render',
+ );
+ assert.equal(new Set(keys).size, keys.length, `duplicate keys: ${keys}`);
+});
+
+test('each report title links to its own cncf.io page', () => {
+ const items = findAllByType(RadarReports(), 'li');
+ items.forEach((item, index) => {
+ const report = reports[index];
+ const heading = findByType(item, 'h3');
+ assert.ok(heading, `report ${report.id} rendered no heading`);
+ const anchor = findByType(heading, 'a');
+ assert.ok(anchor, `report ${report.id} rendered no title link`);
+ assert.equal(anchor.props.href, report.url);
+ assert.equal(textOf(anchor), report.title);
+ });
+});
+
+test('each report summary is rendered as text', () => {
+ const items = findAllByType(RadarReports(), 'li');
+ items.forEach((item, index) => {
+ assert.ok(
+ textOf(item).includes(reports[index].summary),
+ `report ${reports[index].id} did not render its summary`,
+ );
+ });
+});
+
+test('a publication date is shown as a long en-US date', () => {
+ const items = findAllByType(RadarReports(), 'li');
+ const dated = reports.filter((report) => report.publishedAt);
+ assert.ok(
+ dated.length > 0,
+ 'expected at least one report with publishedAt to exercise the dated branch',
+ );
+ items.forEach((item, index) => {
+ const report = reports[index];
+ if (!report.publishedAt) return;
+ const expected = new Date(report.publishedAt).toLocaleDateString(
+ 'en-US',
+ LONG_DATE,
+ );
+ assert.ok(
+ textOf(item).includes(expected),
+ `report ${report.id} did not render "${expected}"`,
+ );
+ });
+});
+
+test('the provenance line credits the upstream source and mirror date', () => {
+ const status = renderSyncStatus(RadarReports());
+ assert.ok(status, 'expected a provenance line for a corpus with generatedAt');
+ const anchor = findByType(status, 'a');
+ assert.ok(anchor, 'expected the provenance line to link to the source');
+ assert.equal(anchor.props.href, data.sourceUrl);
+ const expectedDate = new Date(data.generatedAt).toLocaleDateString(
+ 'en-US',
+ LONG_DATE,
+ );
+ const text = textOf(status);
+ assert.match(text, /Mirrored from/);
+ assert.ok(
+ text.includes(expectedDate),
+ `provenance line did not render "${expectedDate}": ${text}`,
+ );
+});
+
+test('every outbound link opens in a new tab without leaking window.opener', () => {
+ const tree = RadarReports();
+ const anchors = [
+ ...findAllByType(tree, 'a'),
+ ...findAllByType(renderSyncStatus(tree), 'a'),
+ ];
+ assert.ok(
+ anchors.length > reports.length,
+ 'expected the source link plus one link per report',
+ );
+ for (const anchor of anchors) {
+ assert.equal(
+ anchor.props.target,
+ '_blank',
+ `${anchor.props.href} is not _blank`,
+ );
+ assert.match(
+ anchor.props.rel ?? '',
+ /\bnoreferrer\b/,
+ `${anchor.props.href} can reach back through window.opener`,
+ );
+ }
+});