storebound/tests/mac-landscape.test.ts

105 lines
6.4 KiB
TypeScript

// 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 });
});
});