shots capture: signed-in web apps (shots.capture.auth request with ${cred:}/${env:} references or storageState), shots login saves a demo sign-in to .storebound/auth.json (0600), expired-session warning, secrets and cookies masked

This commit is contained in:
CRTkafa 2026-10-20 12:41:43 +07:00
parent 3949ff1531
commit e1e4e05237
15 changed files with 545 additions and 9 deletions

View file

@ -7,6 +7,7 @@
// exec-out screencap. Emulator or a USB device.
// folder bring your own frames: <frames>/<lang>/<phone|tablet>/<name>.png, checked for size.
import type { ShotsCapture, ShotSpec, VideoRecord } from '../lib/config';
import { validateAuth } from './auth';
export type Source = 'web' | 'ios-sim' | 'android-emu' | 'folder';
export const SOURCES: Source[] = ['web', 'ios-sim', 'android-emu', 'folder'];
@ -29,6 +30,7 @@ export function validateCapture(c: ShotsCapture | undefined): string[] {
}
if (c.ios?.warmupMs !== undefined && !(Number.isInteger(c.ios.warmupMs) && c.ios.warmupMs >= 0)) e.push('shots.capture.ios.warmupMs: milliseconds (integer >= 0)');
if (c.concurrency !== undefined && !(Number.isInteger(c.concurrency) && c.concurrency >= 1 && c.concurrency <= 32)) e.push('shots.capture.concurrency: integer 1-32');
if (c.auth) e.push(...validateAuth(c.auth));
if (c.session !== undefined && !['per-shot', 'per-language'].includes(c.session)) e.push('shots.capture.session: per-shot | per-language');
if (c.reuseTimeoutMs !== undefined && !(Number.isInteger(c.reuseTimeoutMs) && c.reuseTimeoutMs > 0)) e.push('shots.capture.reuseTimeoutMs: milliseconds (integer > 0)');
if (src === 'android-emu' && !c.android?.package) e.push('shots.capture.android.package: application id (source android-emu)');