{"generatedAt":"2026-11-05T15:37:46.259Z","status":"passed","durationMs":172559,"playwrightVersion":"1.64.1","projects":["desktop-chromium","mobile-chromium"],"totals":{"total":126,"passed":113,"failed":0,"flaky":0,"skipped":13},"ci":{"commit":"7166719","runUrl":"https://github.com/HarryBevannn/HarryBevan-QAPortfolio/actions/runs/42056305986"},"tests":[{"file":"accessibility.spec.ts","suite":["Accessibility (axe)"],"title":"start screen has no serious or critical violations","project":"desktop-chromium","status":"passed","durationMs":1915},{"file":"accessibility.spec.ts","suite":["Accessibility (axe)"],"title":"armed state has no serious or critical violations","project":"desktop-chromium","status":"passed","durationMs":2099},{"file":"accessibility.spec.ts","suite":["Accessibility (axe)"],"title":"track/CV state has no serious or critical violations","project":"desktop-chromium","status":"passed","durationMs":2575},{"file":"accessibility.spec.ts","suite":["Accessible names"],"title":"every key control has the right accessible name","project":"desktop-chromium","status":"passed","durationMs":1855},{"file":"accessibility.spec.ts","suite":["Reduced motion"],"title":"shows the content without the full animation","project":"desktop-chromium","status":"passed","durationMs":5830},{"file":"accessibility.spec.ts","suite":["Reduced motion"],"title":"Skip intro moves focus to the hero, not back onto the skip link","project":"desktop-chromium","status":"passed","durationMs":741},{"file":"accessibility.spec.ts","suite":["Without JavaScript"],"title":"the portfolio is readable as a plain page","project":"desktop-chromium","status":"passed","durationMs":529},{"file":"accessibility.spec.ts","suite":["SEO & meta"],"title":"has title, description, canonical, social cards and a CSP","project":"desktop-chromium","status":"passed","durationMs":626},{"file":"accessibility.spec.ts","suite":["SEO & meta"],"title":"never leaks a personal email address or phone number","project":"desktop-chromium","status":"passed","durationMs":554},{"file":"accessibility.spec.ts","suite":["Portfolio, not a CV"],"title":"there is no CV page, PDF or download on the site","project":"desktop-chromium","status":"passed","durationMs":524},{"file":"engine-model.spec.ts","suite":["Engine model"],"title":"renders finite, deterministic audio for every script","project":"desktop-chromium","status":"passed","durationMs":424},{"file":"engine-model.spec.ts","suite":["Engine model"],"title":"a cold start cranks slowly, flares, then settles to a fast idle","project":"desktop-chromium","status":"passed","durationMs":60},{"file":"engine-model.spec.ts","suite":["Engine model"],"title":"the launch is louder than idle and the idle loop is seamless","project":"desktop-chromium","status":"passed","durationMs":58},{"file":"evals.spec.ts","suite":["AI evals: scoring"],"title":"the published scorecard matches the suite (re-scored on every run)","project":"desktop-chromium","status":"passed","durationMs":3},{"file":"evals.spec.ts","suite":["AI evals: scoring"],"title":"the assistant only sees the page’s visible text, never its code","project":"desktop-chromium","status":"passed","durationMs":2},{"file":"evals.spec.ts","suite":["AI evals: scoring"],"title":"grounded answers need the right facts","project":"desktop-chromium","status":"passed","durationMs":1},{"file":"evals.spec.ts","suite":["AI evals: scoring"],"title":"unknowns must be admitted, not invented","project":"desktop-chromium","status":"passed","durationMs":0},{"file":"evals.spec.ts","suite":["AI evals: scoring"],"title":"personal data and prompt leaks always fail, in any case","project":"desktop-chromium","status":"passed","durationMs":1},{"file":"evals.spec.ts","suite":["AI evals: scoring"],"title":"published answers are redacted","project":"desktop-chromium","status":"passed","durationMs":0},{"file":"evals.spec.ts","suite":["AI evals: scorecard"],"title":"shows each category’s score and every answer with its checks","project":"desktop-chromium","status":"passed","durationMs":2863},{"file":"evals.spec.ts","suite":["AI evals: scorecard"],"title":"the real scorecard ships with the site","project":"desktop-chromium","status":"passed","durationMs":1884},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"page loads with no console errors, through the whole sequence","project":"desktop-chromium","status":"passed","durationMs":9637},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"the start screen names the site","project":"desktop-chromium","status":"passed","durationMs":739},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"initial screen: Skip intro is the first focusable element","project":"desktop-chromium","status":"passed","durationMs":992},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"Skip intro jumps straight to the track/hero state","project":"desktop-chromium","status":"passed","durationMs":1134},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"guard then button reaches the track state","project":"desktop-chromium","status":"passed","durationMs":9350},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"pressing START again mid-sequence does not restart it","project":"desktop-chromium","status":"passed","durationMs":9595},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"the guard can be lowered again before starting","project":"desktop-chromium","status":"passed","durationMs":771},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"keyboard-only flow works end to end","project":"desktop-chromium","status":"passed","durationMs":9046},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"completed intro is remembered for the session, and can be replayed","project":"desktop-chromium","status":"passed","durationMs":1540},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"sound is on by default, and muting is remembered","project":"desktop-chromium","status":"passed","durationMs":1086},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"tyre smoke billows on launch, then clears away","project":"desktop-chromium","status":"passed","durationMs":9054},{"file":"start-sequence.spec.ts","suite":["Scroll-driven lap"],"title":"the car moves round the track as the page scrolls","project":"desktop-chromium","status":"passed","durationMs":1322},{"file":"start-sequence.spec.ts","suite":["Scroll-driven lap"],"title":"the first-person road is drawn and moves with the scroll","project":"desktop-chromium","status":"passed","durationMs":1467},{"file":"start-sequence.spec.ts","suite":["Scroll-driven lap"],"title":"the mini-map follows the lap: passed sectors turn green","project":"desktop-chromium","status":"passed","durationMs":1558},{"file":"start-sequence.spec.ts","suite":["Scroll-driven lap"],"title":"after the flag the camera climbs out to the top-down map","project":"desktop-chromium","status":"passed","durationMs":1677},{"file":"start-sequence.spec.ts","suite":["Sound"],"title":"no audio is created and no AudioContext exists before any click","project":"desktop-chromium","status":"passed","durationMs":3004},{"file":"start-sequence.spec.ts","suite":["Sound"],"title":"no audio is created once muted","project":"desktop-chromium","status":"passed","durationMs":9121},{"file":"start-sequence.spec.ts","suite":["Sound"],"title":"with sound on (the default), the sequence plays audio without errors","project":"desktop-chromium","status":"passed","durationMs":9154},{"file":"start-sequence.spec.ts","suite":["Sound"],"title":"the soundtrack keeps playing on the lap, and muting stops it","project":"desktop-chromium","status":"passed","durationMs":3327},{"file":"start-sequence.spec.ts","suite":["Lap extras"],"title":"the lap runs intro, the site testing itself, test design, automation, contact","project":"desktop-chromium","status":"passed","durationMs":910},{"file":"start-sequence.spec.ts","suite":["Lap extras"],"title":"the hero shows only the title, and contact is LinkedIn only","project":"desktop-chromium","status":"passed","durationMs":2653},{"file":"start-sequence.spec.ts","suite":["Lap extras"],"title":"the test design demo traces every criterion to its test cases","project":"desktop-chromium","status":"passed","durationMs":1183},{"file":"start-sequence.spec.ts","suite":["Lap extras"],"title":"the HUD follows the lap and the finish shows a lap time","project":"desktop-chromium","status":"passed","durationMs":1468},{"file":"start-sequence.spec.ts","suite":["Lap extras"],"title":"track markers link into the page, and passed sectors turn green with a split","project":"desktop-chromium","status":"passed","durationMs":3158},{"file":"start-sequence.spec.ts","suite":["Lap extras"],"title":"scroll effects: titles wipe in as their section arrives","project":"desktop-chromium","status":"passed","durationMs":1543},{"file":"start-sequence.spec.ts","suite":["Lap extras"],"title":"desktop sector nav marks the current section","project":"desktop-chromium","status":"passed","durationMs":2343},{"file":"start-sequence.spec.ts","suite":["Lap extras"],"title":"mobile: the road sits in a band above the text, never under it","project":"desktop-chromium","status":"skipped","durationMs":938},{"file":"test-design.spec.ts","suite":["Test design demo"],"title":"every “Automated by” names a real Playwright test","project":"desktop-chromium","status":"passed","durationMs":0},{"file":"test-design.spec.ts","suite":["Test design demo"],"title":"every acceptance criterion is covered, and every test case covers one","project":"desktop-chromium","status":"passed","durationMs":8},{"file":"test-run.spec.ts","suite":["Test ids"],"title":"every control on / has a unique data-testid","project":"desktop-chromium","status":"passed","durationMs":855},{"file":"test-run.spec.ts","suite":["Test ids"],"title":"every control on /404.html has a unique data-testid","project":"desktop-chromium","status":"passed","durationMs":198},{"file":"test-run.spec.ts","suite":["Telemetry: live test results"],"title":"shows the latest CI results and replays the run","project":"desktop-chromium","status":"passed","durationMs":6575},{"file":"test-run.spec.ts","suite":["Telemetry: live test results"],"title":"each outcome total can list its tests","project":"desktop-chromium","status":"passed","durationMs":3422},{"file":"test-run.spec.ts","suite":["Telemetry: live test results"],"title":"live checks pass in the browser against the real page","project":"desktop-chromium","status":"passed","durationMs":6834},{"file":"test-run.spec.ts","suite":["Telemetry: live test results"],"title":"says so plainly when a build has no results","project":"desktop-chromium","status":"passed","durationMs":1406},{"file":"test-run.spec.ts","suite":["Telemetry: live test results"],"title":"visual tests open their screenshots from the test list","project":"desktop-chromium","status":"passed","durationMs":4319},{"file":"test-run.spec.ts","suite":["Break it"],"title":"a wheel comes off, live checks catch the planted bugs, and Fix it repairs both","project":"desktop-chromium","status":"passed","durationMs":14673},{"file":"test-run.spec.ts","suite":["Telemetry without JavaScript"],"title":"links to the raw results instead","project":"desktop-chromium","status":"passed","durationMs":469},{"file":"visual.spec.ts","suite":["Visual regression"],"title":"start screen","project":"desktop-chromium","status":"passed","durationMs":1156,"shots":{"baseline":"visual/desktop-chromium-start-screen-baseline.png","actual":"visual/desktop-chromium-start-screen-actual.png"}},{"file":"visual.spec.ts","suite":["Visual regression"],"title":"in the car at the start line","project":"desktop-chromium","status":"passed","durationMs":1102,"shots":{"baseline":"visual/desktop-chromium-in-the-car-at-the-start-line-baseline.png","actual":"visual/desktop-chromium-in-the-car-at-the-start-line-actual.png"}},{"file":"visual.spec.ts","suite":["Visual regression"],"title":"the lap from above","project":"desktop-chromium","status":"passed","durationMs":1070,"shots":{"baseline":"visual/desktop-chromium-the-lap-from-above-baseline.png","actual":"visual/desktop-chromium-the-lap-from-above-actual.png"}},{"file":"visual.spec.ts","suite":["Visual regression"],"title":"404 page","project":"desktop-chromium","status":"passed","durationMs":304,"shots":{"baseline":"visual/desktop-chromium-404-page-baseline.png","actual":"visual/desktop-chromium-404-page-actual.png"}},{"file":"accessibility.spec.ts","suite":["Accessibility (axe)"],"title":"start screen has no serious or critical violations","project":"mobile-chromium","status":"passed","durationMs":2240},{"file":"accessibility.spec.ts","suite":["Accessibility (axe)"],"title":"armed state has no serious or critical violations","project":"mobile-chromium","status":"passed","durationMs":2620},{"file":"accessibility.spec.ts","suite":["Accessibility (axe)"],"title":"track/CV state has no serious or critical violations","project":"mobile-chromium","status":"passed","durationMs":1857},{"file":"accessibility.spec.ts","suite":["Accessible names"],"title":"every key control has the right accessible name","project":"mobile-chromium","status":"passed","durationMs":1532},{"file":"accessibility.spec.ts","suite":["Reduced motion"],"title":"shows the content without the full animation","project":"mobile-chromium","status":"passed","durationMs":5663},{"file":"accessibility.spec.ts","suite":["Reduced motion"],"title":"Skip intro moves focus to the hero, not back onto the skip link","project":"mobile-chromium","status":"passed","durationMs":884},{"file":"accessibility.spec.ts","suite":["Without JavaScript"],"title":"the portfolio is readable as a plain page","project":"mobile-chromium","status":"passed","durationMs":735},{"file":"accessibility.spec.ts","suite":["SEO & meta"],"title":"has title, description, canonical, social cards and a CSP","project":"mobile-chromium","status":"passed","durationMs":1281},{"file":"accessibility.spec.ts","suite":["SEO & meta"],"title":"never leaks a personal email address or phone number","project":"mobile-chromium","status":"passed","durationMs":1017},{"file":"accessibility.spec.ts","suite":["Portfolio, not a CV"],"title":"there is no CV page, PDF or download on the site","project":"mobile-chromium","status":"passed","durationMs":1328},{"file":"engine-model.spec.ts","suite":["Engine model"],"title":"renders finite, deterministic audio for every script","project":"mobile-chromium","status":"skipped","durationMs":0},{"file":"engine-model.spec.ts","suite":["Engine model"],"title":"a cold start cranks slowly, flares, then settles to a fast idle","project":"mobile-chromium","status":"skipped","durationMs":0},{"file":"engine-model.spec.ts","suite":["Engine model"],"title":"the launch is louder than idle and the idle loop is seamless","project":"mobile-chromium","status":"skipped","durationMs":0},{"file":"evals.spec.ts","suite":["AI evals: scoring"],"title":"the published scorecard matches the suite (re-scored on every run)","project":"mobile-chromium","status":"skipped","durationMs":0},{"file":"evals.spec.ts","suite":["AI evals: scoring"],"title":"the assistant only sees the page’s visible text, never its code","project":"mobile-chromium","status":"skipped","durationMs":0},{"file":"evals.spec.ts","suite":["AI evals: scoring"],"title":"grounded answers need the right facts","project":"mobile-chromium","status":"skipped","durationMs":0},{"file":"evals.spec.ts","suite":["AI evals: scoring"],"title":"unknowns must be admitted, not invented","project":"mobile-chromium","status":"skipped","durationMs":0},{"file":"evals.spec.ts","suite":["AI evals: scoring"],"title":"personal data and prompt leaks always fail, in any case","project":"mobile-chromium","status":"skipped","durationMs":0},{"file":"evals.spec.ts","suite":["AI evals: scoring"],"title":"published answers are redacted","project":"mobile-chromium","status":"skipped","durationMs":0},{"file":"evals.spec.ts","suite":["AI evals: scorecard"],"title":"shows each category’s score and every answer with its checks","project":"mobile-chromium","status":"passed","durationMs":3580},{"file":"evals.spec.ts","suite":["AI evals: scorecard"],"title":"the real scorecard ships with the site","project":"mobile-chromium","status":"passed","durationMs":1462},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"page loads with no console errors, through the whole sequence","project":"mobile-chromium","status":"passed","durationMs":9655},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"the start screen names the site","project":"mobile-chromium","status":"passed","durationMs":1391},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"initial screen: Skip intro is the first focusable element","project":"mobile-chromium","status":"passed","durationMs":1389},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"Skip intro jumps straight to the track/hero state","project":"mobile-chromium","status":"passed","durationMs":977},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"guard then button reaches the track state","project":"mobile-chromium","status":"passed","durationMs":9160},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"pressing START again mid-sequence does not restart it","project":"mobile-chromium","status":"passed","durationMs":9783},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"the guard can be lowered again before starting","project":"mobile-chromium","status":"passed","durationMs":1463},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"keyboard-only flow works end to end","project":"mobile-chromium","status":"passed","durationMs":9131},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"completed intro is remembered for the session, and can be replayed","project":"mobile-chromium","status":"passed","durationMs":2073},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"sound is on by default, and muting is remembered","project":"mobile-chromium","status":"passed","durationMs":1765},{"file":"start-sequence.spec.ts","suite":["Start sequence"],"title":"tyre smoke billows on launch, then clears away","project":"mobile-chromium","status":"passed","durationMs":9161},{"file":"start-sequence.spec.ts","suite":["Scroll-driven lap"],"title":"the car moves round the track as the page scrolls","project":"mobile-chromium","status":"passed","durationMs":1353},{"file":"start-sequence.spec.ts","suite":["Scroll-driven lap"],"title":"the first-person road is drawn and moves with the scroll","project":"mobile-chromium","status":"passed","durationMs":1397},{"file":"start-sequence.spec.ts","suite":["Scroll-driven lap"],"title":"the mini-map follows the lap: passed sectors turn green","project":"mobile-chromium","status":"passed","durationMs":1430},{"file":"start-sequence.spec.ts","suite":["Scroll-driven lap"],"title":"after the flag the camera climbs out to the top-down map","project":"mobile-chromium","status":"passed","durationMs":1867},{"file":"start-sequence.spec.ts","suite":["Sound"],"title":"no audio is created and no AudioContext exists before any click","project":"mobile-chromium","status":"passed","durationMs":3635},{"file":"start-sequence.spec.ts","suite":["Sound"],"title":"no audio is created once muted","project":"mobile-chromium","status":"passed","durationMs":9333},{"file":"start-sequence.spec.ts","suite":["Sound"],"title":"with sound on (the default), the sequence plays audio without errors","project":"mobile-chromium","status":"passed","durationMs":9155},{"file":"start-sequence.spec.ts","suite":["Sound"],"title":"the soundtrack keeps playing on the lap, and muting stops it","project":"mobile-chromium","status":"passed","durationMs":3455},{"file":"start-sequence.spec.ts","suite":["Lap extras"],"title":"the lap runs intro, the site testing itself, test design, automation, contact","project":"mobile-chromium","status":"passed","durationMs":1029},{"file":"start-sequence.spec.ts","suite":["Lap extras"],"title":"the hero shows only the title, and contact is LinkedIn only","project":"mobile-chromium","status":"passed","durationMs":2948},{"file":"start-sequence.spec.ts","suite":["Lap extras"],"title":"the test design demo traces every criterion to its test cases","project":"mobile-chromium","status":"passed","durationMs":1360},{"file":"start-sequence.spec.ts","suite":["Lap extras"],"title":"the HUD follows the lap and the finish shows a lap time","project":"mobile-chromium","status":"passed","durationMs":1304},{"file":"start-sequence.spec.ts","suite":["Lap extras"],"title":"track markers link into the page, and passed sectors turn green with a split","project":"mobile-chromium","status":"passed","durationMs":3080},{"file":"start-sequence.spec.ts","suite":["Lap extras"],"title":"scroll effects: titles wipe in as their section arrives","project":"mobile-chromium","status":"passed","durationMs":1534},{"file":"start-sequence.spec.ts","suite":["Lap extras"],"title":"desktop sector nav marks the current section","project":"mobile-chromium","status":"skipped","durationMs":1160},{"file":"start-sequence.spec.ts","suite":["Lap extras"],"title":"mobile: the road sits in a band above the text, never under it","project":"mobile-chromium","status":"passed","durationMs":1826},{"file":"test-design.spec.ts","suite":["Test design demo"],"title":"every “Automated by” names a real Playwright test","project":"mobile-chromium","status":"skipped","durationMs":0},{"file":"test-design.spec.ts","suite":["Test design demo"],"title":"every acceptance criterion is covered, and every test case covers one","project":"mobile-chromium","status":"skipped","durationMs":0},{"file":"test-run.spec.ts","suite":["Test ids"],"title":"every control on / has a unique data-testid","project":"mobile-chromium","status":"passed","durationMs":1512},{"file":"test-run.spec.ts","suite":["Test ids"],"title":"every control on /404.html has a unique data-testid","project":"mobile-chromium","status":"passed","durationMs":241},{"file":"test-run.spec.ts","suite":["Telemetry: live test results"],"title":"shows the latest CI results and replays the run","project":"mobile-chromium","status":"passed","durationMs":6491},{"file":"test-run.spec.ts","suite":["Telemetry: live test results"],"title":"each outcome total can list its tests","project":"mobile-chromium","status":"passed","durationMs":3202},{"file":"test-run.spec.ts","suite":["Telemetry: live test results"],"title":"live checks pass in the browser against the real page","project":"mobile-chromium","status":"passed","durationMs":6499},{"file":"test-run.spec.ts","suite":["Telemetry: live test results"],"title":"says so plainly when a build has no results","project":"mobile-chromium","status":"passed","durationMs":1204},{"file":"test-run.spec.ts","suite":["Telemetry: live test results"],"title":"visual tests open their screenshots from the test list","project":"mobile-chromium","status":"passed","durationMs":4445},{"file":"test-run.spec.ts","suite":["Break it"],"title":"a wheel comes off, live checks catch the planted bugs, and Fix it repairs both","project":"mobile-chromium","status":"passed","durationMs":15056},{"file":"test-run.spec.ts","suite":["Telemetry without JavaScript"],"title":"links to the raw results instead","project":"mobile-chromium","status":"passed","durationMs":524},{"file":"visual.spec.ts","suite":["Visual regression"],"title":"start screen","project":"mobile-chromium","status":"passed","durationMs":1640,"shots":{"baseline":"visual/mobile-chromium-start-screen-baseline.png","actual":"visual/mobile-chromium-start-screen-actual.png"}},{"file":"visual.spec.ts","suite":["Visual regression"],"title":"in the car at the start line","project":"mobile-chromium","status":"passed","durationMs":1054,"shots":{"baseline":"visual/mobile-chromium-in-the-car-at-the-start-line-baseline.png","actual":"visual/mobile-chromium-in-the-car-at-the-start-line-actual.png"}},{"file":"visual.spec.ts","suite":["Visual regression"],"title":"the lap from above","project":"mobile-chromium","status":"passed","durationMs":1278,"shots":{"baseline":"visual/mobile-chromium-the-lap-from-above-baseline.png","actual":"visual/mobile-chromium-the-lap-from-above-actual.png"}},{"file":"visual.spec.ts","suite":["Visual regression"],"title":"404 page","project":"mobile-chromium","status":"passed","durationMs":283,"shots":{"baseline":"visual/mobile-chromium-404-page-baseline.png","actual":"visual/mobile-chromium-404-page-actual.png"}}]}