// Mac App Store screenshots (APP_DESKTOP, 16:10), the landscape layout's sizes, the safe-margin rule and the contact // sheet timeout. The page-level render of the landscape layout and the margins: tests/browser/landscape.browser.ts. import { describe, expect, test } from 'bun:test'; import { checkImage, IMAGE_SPECS, imageInfo, macNote } from '../cli/shots/spec'; import { defaultSizes, marginViolations, renderDims, SAFE_MARGIN_MIN, sheetLayout, sheetTimeoutMs, SIZES } from '../cli/shots/lib'; import { marginIssues, requiredSets } from '../cli/shots/report'; import { displaySets, MAC_DISPLAY } from '../cli/apple/screenshots'; import { chromebookSkip } from '../cli/play/images'; import { APPLE_SHOT_DIR } from '../cli/lib/art-pull'; import { validateConfig } from '../cli/lib/config'; import { loadFactor } from '../cli/shots/render'; import { png } from './fixtures'; describe('Mac sizes', () => { test('the four 16:10 sizes Apple lists, landscape only, APP_DESKTOP', () => { expect(IMAGE_SPECS.mac!.sizes).toEqual([[2880, 1800], [2560, 1600], [1440, 900], [1280, 800]]); expect(IMAGE_SPECS.mac!.type).toBe('APP_DESKTOP'); expect(SIZES.mac).toMatchObject({ w: 2880, h: 1800, device: 'landscape' }); for (const [w, h] of IMAGE_SPECS.mac!.sizes) expect(checkImage(imageInfo(png(w, h)), 'mac')).toEqual([]); expect(checkImage(imageInfo(png(1800, 2880)), 'mac').map(i => i.code)).toEqual(['size']); expect(checkImage(imageInfo(png(1920, 1080)), 'mac').map(i => i.code)).toEqual(['size']); expect(checkImage(imageInfo(png(2880, 1800, { colorType: 6 })), 'mac').map(i => i.code)).toEqual(['alpha']); }); test('opt-in with apple.mac; required then', () => { expect(defaultSizes({ apple: { bundleId: 'x' } } as never)).not.toContain('mac'); expect(defaultSizes({ apple: { bundleId: 'x', mac: true } } as never)).toContain('mac'); expect(requiredSets({ apple: { mac: true } }).mac).toBe(true); expect(requiredSets({ apple: {} }).mac).toBeUndefined(); }); test('uploads: the Mac set only to a macOS version', () => { expect(MAC_DISPLAY).toEqual({ mac: 'APP_DESKTOP' }); expect(displaySets({ mac: true }, 'MAC_OS')).toEqual({ mac: 'APP_DESKTOP' }); expect(displaySets({ mac: true }, 'IOS')).not.toHaveProperty('mac'); expect(displaySets({}, 'MAC_OS')).toEqual({}); expect(APPLE_SHOT_DIR.APP_DESKTOP).toBe('mac'); }); test('validate note: a macOS version without Mac screenshots', () => { expect(macNote({ macVersion: true, mac: false })).toContain('apple.mac: true'); expect(macNote({ macVersion: true, mac: true })).toBeNull(); expect(macNote({ macVersion: false, mac: false })).toBeNull(); }); }); describe('landscape layout sizes', () => { test('mac: window frame by default; chromebook and Play tablets: bare', () => { expect(renderDims('mac', undefined)).toEqual({ w: 2880, h: 1800, landscape: true, frame: 'window' }); expect(renderDims('chromebook', undefined)).toEqual({ w: 1920, h: 1080, landscape: true, frame: 'none' }); expect(renderDims('tab10', undefined)).toMatchObject({ w: 1440, h: 2560, landscape: false }); expect(renderDims('tab10', { landscape: { playTablets: true } })).toMatchObject({ w: 2560, h: 1440, landscape: true, frame: 'none' }); expect(renderDims('mac', { landscape: { frame: 'none' } }).frame).toBe('none'); for (const k of ['tab7', 'tab10']) { const d = renderDims(k, { landscape: { playTablets: true } }); expect(checkImage(imageInfo(png(d.w, d.h)), k)).toEqual([]); } }); test('chromebook: opt-in with play.chromebook, a check, and a console note instead of an upload', () => { expect(defaultSizes({ play: { packageName: 'x' } } as never)).not.toContain('chromebook'); expect(defaultSizes({ play: { packageName: 'x', chromebook: true } } as never)).toContain('chromebook'); expect(checkImage(imageInfo(png(1920, 1080)), 'chromebook')).toEqual([]); expect(chromebookSkip(true)).toContain('Main store listing'); expect(chromebookSkip(false)).toBeNull(); }); test('config: frame and side are validated', () => { const errs = (landscape: unknown) => validateConfig({ app: { name: 'X', profile: 'game' }, languages: [{ id: 'en' }], shots: { copy: 'c.json', frames: 'f', out: 'o', scenes: [{ id: 'a', frames: [{ src: 'a.png' }] }], landscape } } as never).filter(e => e.startsWith('shots.landscape')); expect(errs({ frame: 'window', side: 'right', playTablets: true })).toEqual([]); expect(errs({ frame: 'macbook' })).toEqual(["shots.landscape.frame: 'window' | 'none'"]); }); }); describe('safe margins', () => { const W = 1320, H = 2868; test('boxes inside the margins pass; text at the edge fails', () => { expect(marginViolations([{ el: 'title', x: W * .07, y: H * .05, w: W * .86, h: 200 }], W, H)).toEqual([]); const v = marginViolations([{ el: 'title', x: 12, y: 300, w: 1290, h: 200 }, { el: 'logo', x: 200, y: 20, w: 900, h: 300 }], W, H); expect(v).toHaveLength(2); expect(v[0]).toContain('title is too close to the edge (left 12 px, right 18 px'); expect(v[1]).toContain('logo is too close to the edge (top 20 px'); expect(Math.round(W * SAFE_MARGIN_MIN.x)).toBe(79); }); test('shots check: an error per box, none without layout data', () => { const e = marginIssues({ overflow: [], boxes: [{ el: 'subtitle', x: 0, y: 900, w: 500, h: 60 }] }, W, H); expect(e.map(i => [i.level, i.code])).toEqual([['error', 'margin']]); expect(marginIssues({ overflow: [] }, W, H)).toEqual([]); expect(marginIssues(undefined, W, H)).toEqual([]); }); }); describe('contact sheet timeout', () => { test('scales with images, sizes and load; never a flat 30 s', () => { const nine = sheetTimeoutMs(9 * 5, 9); expect(nine).toBeGreaterThan(30_000 * 3); expect(sheetTimeoutMs(90, 9)).toBeGreaterThan(nine); expect(sheetTimeoutMs(45, 9, 3)).toBe(nine * 3); expect(sheetTimeoutMs(45, 9, 50)).toBe(nine * 5); expect(sheetTimeoutMs(1, 1, 0.2)).toBe(sheetTimeoutMs(1, 1)); }); test('load factor: forced by env, clamped 1..5', () => { expect(loadFactor({ STOREBOUND_LOAD_FACTOR: '3' })).toBe(3); expect(loadFactor({}, [40, 20, 0], 10)).toBe(4); expect(loadFactor({}, [0, 0, 0], 10)).toBe(1); expect(loadFactor({}, [500, 0, 0], 10)).toBe(5); }); test('landscape tiles take half height on the sheet', () => { const l = sheetLayout([{ size: 'mac', files: ['a'], dims: { w: 2880, h: 1800 } }]); expect(l.tiles[0]).toMatchObject({ h: 450, w: 720 }); }); });