import assert from 'node:assert/strict'; import {test} from 'node:test'; import {readFile} from 'node:fs/promises'; import {loadTypescript} from './support/load-typescript.mjs'; test('view controls are in settings and scene contains only a text tilt button',async()=>{ const html=await readFile(new URL('../index.html',import.meta.url),'utf8'); const settings=html.slice(html.indexOf(']*data-tool="view"/); assert.match(settings,/id="panel-view"[\s\S]*id="camera-offset"/); assert.doesNotMatch(html,/id="motion-tools"|◫/); const header=html.slice(html.indexOf('
')); assert.match(header,/id="scene-motion"/); assert.match(header,/id="gyro-label">기울기 연결/); }); test('mobile eligibility does not mistake a narrow or touch-enabled desktop for a phone',async()=>{ const {isMobileDevice}=await loadTypescript(new URL('../src/ui/MobileDevice.ts',import.meta.url)); for(const nav of [{userAgent:'Mozilla Android'},{userAgent:'Mozilla iPhone'},{userAgent:'Mozilla iPad'},{userAgent:'Macintosh',maxTouchPoints:5},{userAgent:'Unknown',userAgentData:{mobile:true}}])assert.equal(isMobileDevice(nav),true); for(const nav of [undefined,{}, {userAgent:'Windows',maxTouchPoints:10},{userAgent:'Macintosh',maxTouchPoints:0},{userAgent:'Linux x86_64',maxTouchPoints:1}])assert.equal(isMobileDevice(nav),false); }); test('tilt matches transparent underlined door styling and header rows use content height',async()=>{ const css=await readFile(new URL('../src/style.css',import.meta.url),'utf8'); assert.match(css,/#gyro,#gyro\[aria-pressed=true\],#gyro\[aria-busy=true\]\s*\{[^}]*background:transparent;[^}]*border:0;[^}]*text-decoration:underline/); assert.doesNotMatch(css,/#gyro[^}]*background:#315b43/); assert.match(css,/\.scene-toolbar\s*\{[^}]*display:grid/); assert.match(css,/\.scene-motion\s*\{[^}]*position:static/); }); test('in-flow unavailable notice clears old floating transform',async()=>{ const css=await readFile(new URL('../src/style.css',import.meta.url),'utf8'); assert.match(css,/#gyro-notice\s*\{[^}]*position:static;[^}]*transform:none/); }); test('actions remain right aligned when comparison hides the brand',async()=>{ const css=await readFile(new URL('../src/style.css',import.meta.url),'utf8'); assert.match(css,/\.scene-actions\s*\{[^}]*grid-column:2/); }); test('tilt keyboard focus retains the contrasting door-style halo in every state',async()=>{ const css=await readFile(new URL('../src/style.css',import.meta.url),'utf8'); assert.match(css,/#gyro:focus-visible\s*\{[^}]*box-shadow:0 0 0 5px #302b25/); });