Files
ObsiGate/tests/e2e/image-viewer.spec.js
T
bruno eccbf7474e
CI / lint (push) Successful in 1m57s
CI / security (push) Successful in 1m22s
CI / test (push) Successful in 4m32s
CI / build (push) Failing after 1m16s
CI / e2e (push) Skipped
feat: support complet des images — arborescence, visionneuse, indexation #108
2026-09-23 07:47:04 -04:00

99 lines
3.8 KiB
JavaScript

/**
* E2E tests for the ObsiGate image viewer (roadmap #108).
*
* Fixtures : `test_vault/sample-image.png` (96x64) + `test_vault/sample-vector.svg`.
*
* Run (local):
* BASE_URL=http://localhost:2029 npx playwright test tests/e2e/image-viewer.spec.js
* BASE_URL=http://localhost:2029 npx playwright test tests/e2e/image-viewer.spec.js --headed
*/
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('Image viewer — zoom / pan / navigation (#108)', () => {
test('affiche l\'image dans la visionneuse dédiée (URL /api/image)', async ({ page }) => {
// #108-B1 — l'image isolée doit pointer vers /api/image (octets), pas /raw (JSON).
const imageResponsePromise = page.waitForResponse(
(r) => r.url().includes('/api/image/') && r.status() === 200,
{ timeout: 15000 },
);
await login(page);
await openFile(page, 'TestVault', 'sample-image.png');
const main = page.locator('#content-area .image-viewer-container img.image-main');
await expect(main).toBeVisible({ timeout: 10000 });
await expect(main).toHaveAttribute('src', /\/api\/image\/TestVault\?path=/);
const resp = await imageResponsePromise;
expect(resp.headers()['content-type']).toContain('image/png');
// Le badge de zoom démarre à 100 %.
await expect(page.locator('#content-area .image-zoom-badge')).toHaveText('100%');
});
test('le zoom molette et le reset modifient la transform', async ({ page }) => {
await login(page);
await openFile(page, 'TestVault', 'sample-image.png');
await expect(page.locator('#content-area .image-stage')).toBeVisible({ timeout: 10000 });
const badge = page.locator('#content-area .image-zoom-badge');
await expect(badge).toHaveText('100%');
await page.locator('#content-area .image-stage').hover();
await page.mouse.wheel(0, -240);
await expect(badge).not.toHaveText('100%', { timeout: 5000 });
const transform = await page.locator('#content-area img.image-main').evaluate(
(el) => getComputedStyle(el).transform,
);
expect(transform).not.toBe('none');
// Double-clic = réinitialisation.
await page.locator('#content-area .image-stage').dblclick();
await expect(badge).toHaveText('100%');
});
test('navigue entre les images du dossier via la pellicule', async ({ page }) => {
await login(page);
await openFile(page, 'TestVault', 'sample-image.png');
const strip = page.locator('#content-area .image-nav-strip');
await expect(strip).toBeVisible({ timeout: 10000 });
// sample-image.png et sample-vector.svg partagent le dossier racine.
await expect(strip.locator('img.image-thumb')).toHaveCount(2);
await page.locator('#content-area .image-nav-strip img.image-thumb').first().click();
await expect(page.locator('#content-area .image-title')).toBeVisible();
});
});