// Guardrail from real use: the raw frames folder was git-ignored and never captured, `shots render` produced store // images with no app or game in them (only 404 lines in the log) and `shots check` still said 0 errors. Now render // refuses to start without every frame, and report.json `missing` entries are check errors. import { describe, expect, test } from 'bun:test'; import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { framesForRender } from '../cli/shots/lib'; import { allIssues, scanRenders } from '../cli/shots/report'; import { png } from './fixtures'; const scenes = [{ frames: [{ src: 'home.png' }, { src: 'back.png' }] }, { frames: [{ src: 'level.png' }] }]; describe('missing frames', () => { test('framesForRender lists every frame per language and device class', () => { expect(framesForRender(scenes, ['ios69', 'ipad13', 'feature'], ['en'], {})).toEqual([ 'en/phone/back.png', 'en/phone/home.png', 'en/phone/level.png', 'en/tablet/back.png', 'en/tablet/home.png', 'en/tablet/level.png']); expect(framesForRender(scenes, ['mac'], ['en', 'tr'], {})).toEqual(['en/landscape/home.png', 'en/landscape/level.png', 'tr/landscape/home.png', 'tr/landscape/level.png']); expect(framesForRender(scenes, ['feature'], ['en'], { feature: { frame: 'promo.png' } })).toEqual(['en/phone/promo.png']); }); test('a render recorded with failed loads is a shots check error', () => { const dir = mkdtempSync(join(tmpdir(), 'sb-missing-')); try { mkdirSync(join(dir, 'en', 'ios69'), { recursive: true }); writeFileSync(join(dir, 'en', 'ios69', '01.png'), png(1320, 2868)); writeFileSync(join(dir, 'en', 'ios69', '02.png'), png(1320, 2868)); writeFileSync(join(dir, 'report.json'), JSON.stringify({ 'en/ios69/01.png': { overflow: [], missing: ['404 http://127.0.0.1:8792/frames/en/phone/home.png'], fonts: { fallback: [], missing: [] } }, 'en/ios69/02.png': { overflow: [], missing: [], fonts: { fallback: [], missing: [] } }, })); const issues = allIssues(scanRenders(dir, { langs: ['en'], sizes: ['ios69'], probe: () => null })).filter(x => x.issue.code === 'frame-missing'); expect(issues.map(x => `${x.where} ${x.issue.level}`)).toEqual(['en/ios69/01.png error']); expect(issues[0]!.issue.msg).toContain('/frames/en/phone/home.png'); } finally { rmSync(dir, { recursive: true, force: true }); } }); });