import { screen, fireEvent, waitFor } from '@testing-library/react'; import '@testing-library/jest-dom'; import { setupReady } from './testHelpers'; describe('screen controls', () => { let originalRequestFullscreen; let originalExitFullscreen; let originalFullscreenElement; let originalVisibilityState; let originalWakeLock; beforeEach(() => { localStorage.clear(); originalRequestFullscreen = document.documentElement.requestFullscreen; originalExitFullscreen = document.exitFullscreen; originalFullscreenElement = Object.getOwnPropertyDescriptor(document, 'fullscreenElement'); originalVisibilityState = Object.getOwnPropertyDescriptor(document, 'visibilityState'); originalWakeLock = Object.getOwnPropertyDescriptor(navigator, 'wakeLock'); }); afterEach(() => { document.documentElement.requestFullscreen = originalRequestFullscreen; document.exitFullscreen = originalExitFullscreen; if (originalFullscreenElement) Object.defineProperty(document, 'fullscreenElement', originalFullscreenElement); else Object.defineProperty(document, 'fullscreenElement', { configurable: true, value: null }); if (originalVisibilityState) Object.defineProperty(document, 'visibilityState', originalVisibilityState); if (originalWakeLock) Object.defineProperty(navigator, 'wakeLock', originalWakeLock); else Object.defineProperty(navigator, 'wakeLock', { configurable: true, value: undefined }); localStorage.clear(); }); test('encounter header exposes prevent-sleep, browser-fullscreen, and popout controls', async () => { await setupReady('ScreenCamp', 'ScreenEnc'); expect(screen.getAllByRole('button', { name: 'Prevent sleep' }).length).toBeGreaterThanOrEqual(2); expect(screen.getAllByRole('button', { name: 'Enter browser fullscreen' })).toHaveLength(1); expect(screen.getByRole('button', { name: 'Expand encounter to full page' })).toBeInTheDocument(); }); test('re-acquires wake lock when tablet becomes visible after browser release', async () => { let releaseListener; const sentinel = { released: false, release: jest.fn().mockResolvedValue(undefined), addEventListener: jest.fn((event, callback) => { if (event === 'release') releaseListener = callback; }), }; const request = jest.fn().mockResolvedValue(sentinel); Object.defineProperty(navigator, 'wakeLock', { configurable: true, value: { request } }); let visibility = 'visible'; Object.defineProperty(document, 'visibilityState', { configurable: true, get: () => visibility }); await setupReady('WakeCamp', 'WakeEnc'); fireEvent.click(screen.getAllByRole('button', { name: 'Prevent sleep' })[0]); await waitFor(() => expect(request).toHaveBeenCalledTimes(1)); visibility = 'hidden'; releaseListener(); visibility = 'visible'; document.dispatchEvent(new Event('visibilitychange')); await waitFor(() => expect(request).toHaveBeenCalledTimes(2)); }); test('character editor has labeled tablet-sized save button', async () => { await setupReady('SaveCamp', 'SaveEnc'); fireEvent.change(screen.getByLabelText('Name', { selector: '#characterName' }), { target: { value: 'Tablet Hero' } }); fireEvent.click(screen.getByRole('button', { name: 'Add Character' })); await screen.findByText('Tablet Hero'); fireEvent.click(screen.getByRole('button', { name: 'Edit character' })); const save = screen.getByRole('button', { name: 'Save character' }); expect(save).toHaveTextContent('Save'); expect(save).toHaveClass('min-h-[40px]'); }); test('attempts to restore fullscreen when tablet becomes visible after lock', async () => { const requestFullscreen = jest.fn().mockResolvedValue(undefined); document.documentElement.requestFullscreen = requestFullscreen; document.exitFullscreen = jest.fn().mockResolvedValue(undefined); Object.defineProperty(document, 'fullscreenElement', { configurable: true, get: () => null }); let visibility = 'visible'; Object.defineProperty(document, 'visibilityState', { configurable: true, get: () => visibility }); await setupReady('RestoreCamp', 'RestoreEnc'); fireEvent.click(screen.getByRole('button', { name: 'Enter browser fullscreen' })); await waitFor(() => expect(requestFullscreen).toHaveBeenCalledTimes(1)); visibility = 'hidden'; document.dispatchEvent(new Event('fullscreenchange')); visibility = 'visible'; document.dispatchEvent(new Event('visibilitychange')); await waitFor(() => expect(requestFullscreen).toHaveBeenCalledTimes(2)); }); });