test(e2e): prove the independent row against a state row's gap (review)
PR Checks / Frontend Typecheck + Tests (pull_request) Successful in 1m14s
PR Checks / Backend Smoke (pull_request) Successful in 10s
PR Checks / Build Backend (no push) (pull_request) Successful in 33s
PR Checks / Build Frontend (no push) (pull_request) Successful in 1m26s
PR Checks / Build Pipeline (no push) (pull_request) Successful in 1m16s
PR Checks / AI Code Review (Claude) (pull_request) Successful in 21s

The journey passed whenever the LA map was empty or not yet rendered. It now
waits for a state school in the same LA to show its gap, and both LA journeys
fail rather than skip on an empty map.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
TudorandClaude Opus 5.5 committed 2026-10-06 12:51:18 +01:00
1 parent c6ff77f05b
commit 870af949ee
1 file changed
+30 -15
+30 -15
View File
@@ -417,6 +417,9 @@ test('a secondary search row compares its Attainment 8 with the LA average', asy
// guards the comparison itself; the unit test pins the cache mode.
const la = await (await page.request.get('/api/la-averages')).json();
const averages: Record<string, number> = la.secondary?.attainment_8_by_la ?? {};
// DfE publishes about 152 LA averages. An empty map (a missing mart, or a
// year the LA data set has not reached) hides every comparison: fail, not skip.
expect(Object.keys(averages).length).toBeGreaterThan(100);
const res = await page.request.get('/api/schools?search=school&phase=secondary&page_size=50');
expect(res.ok()).toBeTruthy();
const school = ((await res.json()).schools ?? []).find(
@@ -435,23 +438,35 @@ test('a secondary search row compares its Attainment 8 with the LA average', asy
test('an independent secondary shows its Attainment 8 without an LA comparison', async ({ page }) => {
// DfE's LA averages cover state-funded schools, and an independent school's
// Attainment 8 leaves out IGCSEs, so a gap would mislead (audit H2).
const res = await page.request.get('/api/schools?school_type=independent&phase=secondary&page_size=50');
expect(res.ok()).toBeTruthy();
const school = ((await res.json()).schools ?? []).find(
(s: { attainment_8_score?: number | null; school_type?: string }) =>
s.attainment_8_score != null && !/special/i.test(s.school_type ?? ''));
test.skip(!school, 'no independent secondary with an Attainment 8 here');
// Attainment 8 leaves out IGCSEs, so a gap would mislead (audit H2). A state
// school on the same page must show its gap first, so the absence is real.
const la = await (await page.request.get('/api/la-averages')).json();
const averages: Record<string, number> = la.secondary?.attainment_8_by_la ?? {};
expect(Object.keys(averages).length).toBeGreaterThan(100);
const averagesLoaded = page.waitForResponse(r => r.url().includes('/la-averages'));
await searchByName(page, school.school_name);
await averagesLoaded;
const link = page.locator(`a[href^="/school/${school.urn}-"]`).first();
await expect(link).toBeVisible({ timeout: 15_000 });
const stats = link.locator('xpath=ancestor::div[contains(@class, "__rowContent")][1]')
type Row = { urn: number; school_type?: string; local_authority?: string; attainment_8_score?: number | null };
const compared = (s: Row) => s.attainment_8_score != null && s.local_authority != null
&& averages[s.local_authority] != null
&& !/special|pupil referral|alternative provision/i.test(s.school_type ?? '');
let found: { la: string; state: Row; independent: Row } | null = null;
for (const name of ['Kensington and Chelsea', 'Westminster', 'Camden', 'Hammersmith and Fulham', 'Barnet']) {
// The search page asks for the same first 50 schools.
const res = await page.request.get(`/api/schools?search=${encodeURIComponent(name)}&phase=secondary&page_size=50`);
const schools: Row[] = ((await res.json()).schools ?? []).filter(compared);
const independent = schools.find(s => /independent/i.test(s.school_type ?? ''));
const state = schools.find(s => !/independent/i.test(s.school_type ?? ''));
if (independent && state) { found = { la: name, state, independent }; break; }
}
test.skip(!found, 'no LA here lists a state and an independent secondary on one page');
await page.goto(`/?search=${encodeURIComponent(found!.la)}&phase=secondary`);
const stats = (urn: number) => page.locator(`a[href^="/school/${urn}-"]`).first()
.locator('xpath=ancestor::div[contains(@class, "__rowContent")][1]')
.locator('[class*="__line3"]');
await expect(stats.getByText(school.attainment_8_score.toFixed(1))).toBeVisible();
await expect(stats.getByText(/vs LA avg/)).toHaveCount(0);
await expect(stats(found!.state.urn).getByText(/vs LA avg/)).toBeVisible({ timeout: 15_000 });
const independent = stats(found!.independent.urn);
await expect(independent.getByText(found!.independent.attainment_8_score!.toFixed(1))).toBeVisible();
await expect(independent.getByText(/vs LA avg/)).toHaveCount(0);
});
test('a secondary shows its 2023/24 GCSE results, the last year DfE published Progress 8', async ({ page }) => {