/** * E2E tests for the ObsiGate audio/video viewers (roadmap #109). * * Fixtures : `test_vault/sample-audio.mp3` (1 s sine, ~5 ko) + * `test_vault/sample-video.webm` (64x64 VP8, ~1 ko). * * Run (local): * BASE_URL=http://localhost:2029 npx playwright test tests/e2e/media-viewer.spec.js */ import { test, expect } from '@playwright/test'; const BASE = process.env.BASE_URL || 'http://localhost:2029'; const CREDS = { username: process.env.OBSIGATE_USER || 'admin', password: process.env.OBSIGATE_PASS || 'test123', }; async function login(page) { await page.goto(BASE); const loginForm = page.locator('#login-screen'); await expect(loginForm).toBeVisible({ timeout: 5000 }).catch(() => {}); if (await loginForm.isVisible()) { await page.fill('#login-username', CREDS.username); await page.fill('#login-password', CREDS.password); await page.click('#login-btn'); } await page.waitForFunction(() => window.__OBSIGATE_BOOTED === true, { timeout: 20000 }); } async function openFile(page, vault, filePath) { const treeItem = page.locator(`.tree-item[data-vault="${vault}"][data-path="${filePath}"]`); if (!(await treeItem.count())) { await page.locator(`.tree-item.vault-item[data-vault="${vault}"]`).first().click(); await treeItem.waitFor({ state: 'attached', timeout: 8000 }); } await treeItem.dblclick({ timeout: 5000 }); } test.describe('Media viewers — HTML5 audio/video (#109)', () => { test('rend un lecteur audio natif branché sur /api/media', async ({ page }) => { await login(page); await openFile(page, 'TestVault', 'sample-audio.mp3'); const audio = page.locator('#content-area .audio-viewer-container audio.audio-player'); await expect(audio).toBeVisible({ timeout: 10000 }); await expect(audio).toHaveAttribute('src', /\/api\/media\/TestVault\?path=/); await expect(audio).toHaveAttribute('controls', ''); // La durée est lue côté client via loadedmetadata. await expect(page.locator('#content-area .media-duration-badge')).not.toHaveText('--:--', { timeout: 10000 }); }); test('rend un lecteur vidéo natif branché sur /api/media', async ({ page }) => { await login(page); await openFile(page, 'TestVault', 'sample-video.webm'); const video = page.locator('#content-area .video-viewer-container video.video-player'); await expect(video).toBeVisible({ timeout: 10000 }); await expect(video).toHaveAttribute('src', /\/api\/media\/TestVault\?path=/); await expect(video).toHaveAttribute('playsinline', ''); }); test('le streaming média honore les requêtes Range (206)', async ({ page }) => { await login(page); const resp = await page.request.get( `${BASE}/api/media/TestVault?path=${encodeURIComponent('sample-video.webm')}`, { headers: { Range: 'bytes=0-99' } }, ); expect(resp.status()).toBe(206); expect(resp.headers()['content-range']).toMatch(/^bytes 0-99\/\d+$/); expect(resp.headers()['accept-ranges']).toBe('bytes'); }); });