/** @fileoverview COD-358 vertical session rail orientation policy and wiring. */ import { readFileSync } from 'node:fs'; import { resolve } from 'node:path'; import vm from 'node:vm'; import { describe, expect, it } from 'vitest'; const read = (path: string) => readFileSync(resolve(import.meta.dirname, '..', path), 'utf8'); const indexHtml = read('src/web/public/index.html'); const stylesCss = read('src/web/public/styles.css'); const settingsJs = read('src/web/public/settings-ui.js'); const appJs = read('src/web/public/app.js'); const schemasTs = read('src/web/schemas.ts'); function loadPolicy() { const context = vm.createContext({ window: {}, globalThis: {} }); vm.runInContext(read('src/web/public/constants.js'), context, { filename: 'constants.js' }); return ( context.window as { CodemanTabOverflow: { resolveTabOrientation: (input: unknown) => string }; } ).CodemanTabOverflow; } describe('vertical tab orientation policy', () => { it('honors vertical on desktop and tablet but forces phones horizontal', () => { const policy = loadPolicy(); expect(policy.resolveTabOrientation({ deviceType: 'desktop', setting: 'vertical' })).toBe('vertical'); expect(policy.resolveTabOrientation({ deviceType: 'tablet', setting: 'vertical' })).toBe('vertical'); expect(policy.resolveTabOrientation({ deviceType: 'mobile', setting: 'vertical' })).toBe('horizontal'); }); it('fails closed to horizontal for absent and unknown values', () => { const policy = loadPolicy(); expect(policy.resolveTabOrientation(undefined)).toBe('horizontal'); expect(policy.resolveTabOrientation({})).toBe('horizontal'); expect(policy.resolveTabOrientation({ deviceType: 'desktop', setting: 'sideways' })).toBe('horizontal'); }); }); describe('vertical tab rail wiring', () => { it('ships one rail before the terminal and one orientation control', () => { expect(indexHtml).toContain('id="tabRail"'); expect(indexHtml.indexOf('id="tabRail"')).toBeLessThan(indexHtml.indexOf('id="terminalContainer"')); expect(indexHtml).toContain('id="appSettingsTabOrientation"'); expect(indexHtml).toContain('