archy/neode-ui/src/composables/__tests__/useControllerNav.test.ts

509 lines
19 KiB
TypeScript
Raw Normal View History

import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
// Mock vue-router
const mockRoute = { path: '/dashboard' }
const mockRouter = { push: vi.fn().mockResolvedValue(undefined) }
vi.mock('vue-router', () => ({
useRoute: () => mockRoute,
useRouter: () => mockRouter,
}))
// Mock stores
vi.mock('@/stores/controller', () => ({
useControllerStore: () => ({
setActive: vi.fn(),
setGamepadCount: vi.fn(),
isActive: false,
gamepadCount: 0,
}),
}))
vi.mock('@/stores/spotlight', () => ({
useSpotlightStore: () => ({
isOpen: false,
close: vi.fn(),
}),
}))
vi.mock('@/stores/cli', () => ({
useCLIStore: () => ({
isOpen: false,
close: vi.fn(),
}),
}))
vi.mock('@/stores/appLauncher', () => ({
useAppLauncherStore: () => ({
isOpen: false,
close: vi.fn(),
}),
}))
// Mock useNavSounds
vi.mock('@/composables/useNavSounds', () => ({
playNavSound: vi.fn(),
}))
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
// ─── Module Export Tests ────────────────────────────────────────
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
describe('useControllerNav - module', () => {
beforeEach(() => {
vi.clearAllMocks()
vi.useFakeTimers()
Object.defineProperty(navigator, 'getGamepads', {
value: vi.fn().mockReturnValue([null, null, null, null]),
configurable: true,
writable: true,
})
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
afterEach(() => { vi.useRealTimers() })
it('exports useControllerNav as a function', async () => {
const mod = await import('../useControllerNav')
expect(typeof mod.useControllerNav).toBe('function')
})
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
// ─── Nav Key Classification ─────────────────────────────────────
describe('useControllerNav - nav keys', () => {
const navKeys = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Enter', 'Escape']
it('classifies all arrow keys, Enter, and Escape as nav keys', () => {
for (const key of navKeys) {
expect(navKeys.includes(key)).toBe(true)
}
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
it('rejects non-nav keys', () => {
for (const key of ['a', 'Space', 'Tab', 'Shift', 'F1', 'Delete']) {
expect(navKeys.includes(key)).toBe(false)
}
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
// ─── Route Pattern Tests ────────────────────────────────────────
describe('useControllerNav - route patterns', () => {
it('recognizes detail page patterns for Escape-back behavior', () => {
const pattern = /\/apps\/[^/]+$|\/marketplace\/[^/]+$|\/cloud\/[^/]+$/
expect(pattern.test('/apps/bitcoin')).toBe(true)
expect(pattern.test('/marketplace/electrs')).toBe(true)
expect(pattern.test('/cloud/photos')).toBe(true)
expect(pattern.test('/dashboard')).toBe(false)
expect(pattern.test('/apps')).toBe(false)
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
it('recognizes all page type patterns for right-arrow targets', () => {
expect(/^\/dashboard(\/)?$/.test('/dashboard')).toBe(true)
expect(/^\/dashboard(\/)?$/.test('/dashboard/')).toBe(true)
expect(/^\/dashboard\/(apps|marketplace)(\/|$)/.test('/dashboard/apps')).toBe(true)
expect(/^\/dashboard\/(apps|marketplace)(\/|$)/.test('/dashboard/marketplace')).toBe(true)
expect(/^\/dashboard\/cloud(\/|$)/.test('/dashboard/cloud')).toBe(true)
expect(/^\/dashboard\/server(\/|$)/.test('/dashboard/server')).toBe(true)
expect(/^\/dashboard\/web5(\/|$)/.test('/dashboard/web5')).toBe(true)
expect(/^\/dashboard\/settings(\/|$)/.test('/dashboard/settings')).toBe(true)
})
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
// ─── Focusable Element Detection ────────────────────────────────
describe('useControllerNav - focusable elements', () => {
afterEach(() => { document.body.innerHTML = '' })
it('finds buttons, links, and inputs as focusable', () => {
document.body.innerHTML = `
<div>
<button>Click</button>
<a href="/test">Link</a>
<input type="text" />
<button disabled>Disabled</button>
</div>
`
const focusable = document.querySelectorAll(
'a[href], button:not([disabled]), input:not([disabled])'
)
expect(focusable.length).toBe(3)
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
it('finds elements with tabindex as focusable', () => {
document.body.innerHTML = `
<div tabindex="0">Container</div>
<div tabindex="-1">Hidden</div>
<div>Not focusable</div>
`
const focusable = document.querySelectorAll('[tabindex]:not([tabindex="-1"])')
expect(focusable.length).toBe(1)
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
it('finds data-controller-container as focusable', () => {
document.body.innerHTML = `
<div data-controller-container tabindex="0">Card 1</div>
<div data-controller-container tabindex="0">Card 2</div>
<div>Regular div</div>
`
const containers = document.querySelectorAll('[data-controller-container]')
expect(containers.length).toBe(2)
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
it('excludes data-controller-ignore elements', () => {
document.body.innerHTML = `
<button>Visible</button>
<button data-controller-ignore>Ignored</button>
<div data-controller-ignore><button>Also ignored</button></div>
`
const all = Array.from(document.querySelectorAll<HTMLElement>('button:not([disabled])')).filter(
el => !el.hasAttribute('data-controller-ignore') && !el.closest('[data-controller-ignore]')
)
expect(all.length).toBe(1)
expect(all[0]?.textContent).toBe('Visible')
})
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
// ─── Zone Detection ─────────────────────────────────────────────
describe('useControllerNav - zones', () => {
afterEach(() => { document.body.innerHTML = '' })
it('sidebar elements belong to sidebar zone', () => {
document.body.innerHTML = `
<div data-controller-zone="sidebar"><a href="/home">Home</a></div>
<div data-controller-zone="main"><button>Action</button></div>
`
const link = document.querySelector('a')!
const btn = document.querySelector('button')!
expect(link.closest('[data-controller-zone="sidebar"]')).toBeTruthy()
expect(btn.closest('[data-controller-zone="main"]')).toBeTruthy()
expect(link.closest('[data-controller-zone="main"]')).toBeNull()
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
it('main elements belong to main zone', () => {
document.body.innerHTML = `
<div data-controller-zone="sidebar"><a href="/">Nav</a></div>
<div data-controller-zone="main"><div data-controller-container tabindex="0"><button>Inner</button></div></div>
`
const inner = document.querySelector('button')!
expect(inner.closest('[data-controller-zone="main"]')).toBeTruthy()
})
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
// ─── Container Drill-in/Drill-out ───────────────────────────────
describe('useControllerNav - container behavior', () => {
afterEach(() => { document.body.innerHTML = '' })
it('container elements are identified via data-controller-container', () => {
document.body.innerHTML = `
<div data-controller-container tabindex="0">
<button>Stop</button>
<button>Launch</button>
</div>
`
const container = document.querySelector('[data-controller-container]')
expect(container).toBeTruthy()
expect(container?.getAttribute('tabindex')).toBe('0')
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
it('inner buttons are found within containers', () => {
document.body.innerHTML = `
<div data-controller-container tabindex="0">
<button>Stop</button>
<button data-controller-launch-btn>Launch</button>
</div>
`
const container = document.querySelector('[data-controller-container]')!
const inner = Array.from(container.querySelectorAll<HTMLElement>('button:not([disabled])')).filter(
el => el !== container
)
expect(inner.length).toBe(2)
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
it('isInsideContainer detects when element is nested in a container', () => {
document.body.innerHTML = `
<div data-controller-container tabindex="0">
<button id="inner">Action</button>
</div>
<button id="outer">Outside</button>
`
const inner = document.getElementById('inner')!
const outer = document.getElementById('outer')!
const innerContainer = inner.closest('[data-controller-container]')
expect(innerContainer).toBeTruthy()
expect(innerContainer !== inner).toBe(true)
expect(outer.closest('[data-controller-container]')).toBeNull()
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
it('data-controller-launch marks a card for Enter=launch behavior', () => {
document.body.innerHTML = `
<div data-controller-container data-controller-launch tabindex="0">
<button data-controller-launch-btn>Launch</button>
</div>
`
const container = document.querySelector('[data-controller-container]')!
expect(container.hasAttribute('data-controller-launch')).toBe(true)
const btn = container.querySelector('[data-controller-launch-btn]')
expect(btn).toBeTruthy()
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
it('data-controller-install marks a card for Enter=install behavior', () => {
document.body.innerHTML = `
<div data-controller-container data-controller-install tabindex="0">
<button data-controller-install-btn>Install</button>
</div>
`
const container = document.querySelector('[data-controller-container]')!
expect(container.hasAttribute('data-controller-install')).toBe(true)
const btn = container.querySelector('[data-controller-install-btn]')
expect(btn).toBeTruthy()
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
// ─── Spatial Navigation (findNearestInDirection) ────────────────
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
describe('useControllerNav - spatial navigation logic', () => {
afterEach(() => { document.body.innerHTML = '' })
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
it('direction filtering works correctly', () => {
// Simulate the direction check logic from findNearestInDirection
const fromRect = { left: 200, right: 350, top: 0, bottom: 150, width: 150, height: 150 }
const threshold = 50
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
// Element to the left
const leftRect = { left: 0, right: 150, top: 0, bottom: 150 }
expect(leftRect.right <= fromRect.left + threshold).toBe(true) // is to the left
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
// Element to the right
const rightRect = { left: 400, right: 550, top: 0, bottom: 150 }
expect(rightRect.left >= fromRect.right - threshold).toBe(true) // is to the right
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
// Element below
const belowRect = { left: 200, right: 350, top: 200, bottom: 350 }
expect(belowRect.top >= fromRect.bottom - threshold).toBe(true) // is below
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
// Element above (from below position)
expect(fromRect.bottom <= belowRect.top + threshold).toBe(true) // fromRect is above belowRect
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
it('overlap scoring prefers aligned elements', () => {
// Two elements to the right: one aligned, one offset
const fromRect = { left: 0, right: 150, top: 50, bottom: 200, width: 150, height: 150 }
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
// Aligned (same row, full overlap on Y axis)
const alignedRect = { left: 200, right: 350, top: 50, bottom: 200, width: 150, height: 150 }
const alignedOverlap = Math.max(0, Math.min(fromRect.bottom, alignedRect.bottom) - Math.max(fromRect.top, alignedRect.top))
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
// Offset (partially overlapping on Y axis)
const offsetRect = { left: 200, right: 350, top: 160, bottom: 310, width: 150, height: 150 }
const offsetOverlap = Math.max(0, Math.min(fromRect.bottom, offsetRect.bottom) - Math.max(fromRect.top, offsetRect.top))
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
expect(alignedOverlap).toBeGreaterThan(offsetOverlap) // aligned element wins
expect(alignedOverlap).toBe(150) // full overlap
expect(offsetOverlap).toBe(40) // partial overlap
})
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
// ─── Gamepad Detection ──────────────────────────────────────────
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
describe('useControllerNav - gamepad', () => {
it('counts connected gamepads', () => {
const gamepads = [
{ connected: true } as Gamepad,
null,
{ connected: true } as Gamepad,
null,
]
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
expect(gamepads.filter(g => g?.connected).length).toBe(2)
})
it('handles null gamepad list', () => {
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
const getCount = (gp: (Gamepad | null)[] | null): number =>
gp ? gp.filter(g => g?.connected).length : 0
expect(getCount(null)).toBe(0)
})
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
it('handles all-null gamepad list', () => {
const gamepads: (Gamepad | null)[] = [null, null, null, null]
fix: production onboarding, CI tests, container security, keyboard nav Install & Onboarding: - Remove DEV_MODE=true from production ISO service file (auto-created users, skipped password setup) - Auto-install no longer overwrites rootfs service file with bad template - Login.vue always checks auth.isSetup — shows password creation form on fresh install without requiring dev build flag - Deploy image-versions.sh to /opt/archipelago/scripts/ on installed nodes - First-boot-containers sources image-versions.sh, runs podman as archipelago user (rootless), enables linger + podman.socket - Correct volume ownership (100000:100000 for rootless UID mapping) Container Security: - FileBrowser: add --cap-add=DAC_OVERRIDE for rootless podman volume access - FileBrowser: add --read-only, /data volume for database, proper cmd args - First-boot script matches backend config (security hardening + health check) CI Pipeline: - Add vue-tsc type check + vitest run to build-iso.yml (runs every push) - Add post-install-tests.yml workflow (workflow_dispatch, SSH to target) - Build report: set +eo pipefail, fix rootfs path, add || true guards - Bundle run-post-install-tests.sh into ISO E2E Test Suite (scripts/run-post-install-tests.sh): - Phase 1: Install verification (files, services, podman, linger, DEV_MODE check) - Phase 2: Onboarding flow (auth.isSetup, auth.setup, login, DID, complete) - Phase 3: Container lifecycle (install 3 apps via package.install RPC, verify running, stop, verify stopped, restart, verify running, health) - Phase 4: Log verification (first-boot log, diagnostics, journal errors) - Correct package.install params: {"id", "dockerImage"} Frontend: - Fix backdrop-filter tab-switch bug (keep animations paused during rebuild) - Dashboard glitch animations paused during tab-hidden - Gamepad nav: auto-focus first container on route change - Tab roving: Left/Right on role="tab" cycles and activates sibling tabs - ContainerApps: data-controller-launch on running app cards - 515 tests passing (fixed 30 broken, added 19 new keyboard nav tests) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:16:57 +00:00
expect(Array.from(gamepads).filter(g => g?.connected).length).toBe(0)
})
})
// ─── Sidebar Navigation ─────────────────────────────────────────
describe('useControllerNav - sidebar behavior', () => {
afterEach(() => { document.body.innerHTML = '' })
it('sidebar has linear up/down navigation with wrap', () => {
document.body.innerHTML = `
<div data-controller-zone="sidebar">
<a href="/dashboard" class="nav-tab-active">Home</a>
<a href="/dashboard/apps">Apps</a>
<a href="/dashboard/cloud">Cloud</a>
<button>Logout</button>
</div>
`
const items = document.querySelectorAll('[data-controller-zone="sidebar"] a, [data-controller-zone="sidebar"] button')
expect(items.length).toBe(4)
// Wrap: last→first
const lastIdx = items.length - 1
const nextIdx = lastIdx >= items.length - 1 ? 0 : lastIdx + 1
expect(nextIdx).toBe(0) // wraps to Home
// Wrap: first→last
const firstIdx = 0
const prevIdx = firstIdx <= 0 ? items.length - 1 : firstIdx - 1
expect(prevIdx).toBe(3) // wraps to Logout
})
it('left arrow from main goes to active sidebar tab', () => {
document.body.innerHTML = `
<div data-controller-zone="sidebar">
<a href="/dashboard">Home</a>
<a href="/dashboard/apps" class="nav-tab-active">Apps</a>
</div>
<div data-controller-zone="main">
<button id="mainBtn">Action</button>
</div>
`
const activeTab = document.querySelector('.nav-tab-active')
expect(activeTab).toBeTruthy()
expect(activeTab?.textContent).toBe('Apps')
})
})
// ─── Auto-focus Behavior ─────────────────────────────────────────
describe('useControllerNav - auto-focus', () => {
afterEach(() => { document.body.innerHTML = '' })
it('first container in main zone is the auto-focus target', () => {
document.body.innerHTML = `
<div data-controller-zone="main">
<div data-controller-container tabindex="0" id="first">Card 1</div>
<div data-controller-container tabindex="0" id="second">Card 2</div>
</div>
`
const mainZone = document.querySelector('[data-controller-zone="main"]')
const firstContainer = mainZone?.querySelector<HTMLElement>('[data-controller-container]')
expect(firstContainer?.id).toBe('first')
})
it('does not auto-focus when input is active', () => {
document.body.innerHTML = `
<input id="search" type="text" />
<div data-controller-zone="main">
<div data-controller-container tabindex="0">Card</div>
</div>
`
const input = document.getElementById('search') as HTMLInputElement
input.focus()
// Auto-focus should skip when input is active
expect(document.activeElement?.tagName).toBe('INPUT')
})
})
// ─── Tab Roving Behavior ─────────────────────────────────────────
describe('useControllerNav - tab roving', () => {
afterEach(() => { document.body.innerHTML = '' })
it('role="tab" elements are found as siblings within tablist', () => {
document.body.innerHTML = `
<div role="tablist">
<button role="tab" id="tab1">Dashboard</button>
<button role="tab" id="tab2">Setup</button>
</div>
`
const tabs = document.querySelectorAll('[role="tab"]')
expect(tabs.length).toBe(2)
const tablist = tabs[0]?.closest('[role="tablist"]')
expect(tablist).toBeTruthy()
})
it('tab roving cycles right: first → second → first', () => {
const tabs = ['tab1', 'tab2']
// Right from index 0
expect((0 + 1) % tabs.length).toBe(1)
// Right from index 1 (wraps)
expect((1 + 1) % tabs.length).toBe(0)
})
it('tab roving cycles left: second → first → second', () => {
const tabs = ['tab1', 'tab2']
// Left from index 1
expect((1 - 1 + tabs.length) % tabs.length).toBe(0)
// Left from index 0 (wraps)
expect((0 - 1 + tabs.length) % tabs.length).toBe(1)
})
it('tab roving falls back to parent when no role="tablist" wrapper', () => {
document.body.innerHTML = `
<div class="mode-switcher">
<button role="tab" id="tab1">Dashboard</button>
<button role="tab" id="tab2">Setup</button>
</div>
`
const tab = document.getElementById('tab1')!
// No role="tablist" — falls back to parentElement
const tablist = tab.closest('[role="tablist"]') ?? tab.parentElement
expect(tablist).toBeTruthy()
const tabs = tablist!.querySelectorAll('[role="tab"]:not([disabled])')
expect(tabs.length).toBe(2)
})
})
// ─── Scroll Behavior ──────────────────────────────────────────────
describe('useControllerNav - scroll helpers', () => {
it('focused elements have scrollIntoView method', () => {
document.body.innerHTML = `
<div data-controller-zone="main">
<div data-controller-container tabindex="0">Card 1</div>
</div>
`
const card = document.querySelector('[data-controller-container]') as HTMLElement
// jsdom provides scrollIntoView as a no-op
expect(card).toBeTruthy()
expect(card.focus).toBeDefined()
})
})
// ─── Container Grid Navigation ────────────────────────────────────
describe('useControllerNav - grid navigation patterns', () => {
afterEach(() => { document.body.innerHTML = '' })
it('marketplace 3-column grid has correct spatial relationships', () => {
// Simulate a 3-column grid (like marketplace)
document.body.innerHTML = `
<div data-controller-zone="main">
<div data-controller-container tabindex="0" id="c1" style="position:absolute;left:0;top:0;width:200px;height:200px">App 1</div>
<div data-controller-container tabindex="0" id="c2" style="position:absolute;left:220px;top:0;width:200px;height:200px">App 2</div>
<div data-controller-container tabindex="0" id="c3" style="position:absolute;left:440px;top:0;width:200px;height:200px">App 3</div>
<div data-controller-container tabindex="0" id="c4" style="position:absolute;left:0;top:220px;width:200px;height:200px">App 4</div>
<div data-controller-container tabindex="0" id="c5" style="position:absolute;left:220px;top:220px;width:200px;height:200px">App 5</div>
<div data-controller-container tabindex="0" id="c6" style="position:absolute;left:440px;top:220px;width:200px;height:200px">App 6</div>
</div>
`
const containers = document.querySelectorAll('[data-controller-container]')
expect(containers.length).toBe(6)
// Row 1: c1, c2, c3; Row 2: c4, c5, c6
expect(containers[0]?.id).toBe('c1')
expect(containers[3]?.id).toBe('c4')
})
it('home 2-column grid has correct container count', () => {
document.body.innerHTML = `
<div data-controller-zone="main">
<div data-controller-container tabindex="0">My Apps</div>
<div data-controller-container tabindex="0">Wallet</div>
<div data-controller-container tabindex="0">System</div>
</div>
`
const containers = document.querySelectorAll('[data-controller-container]')
expect(containers.length).toBe(3)
})
})