CI happy path: seed a PDF document with a transcription block as admin, then as the READ_ALL "reader" open it — assert the "Transkription lesen" control, the read text, a plain "Transkription" header, and the absence of the Lesen/Bearbeiten tabs (panel cannot switch to edit). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
99 lines
3.3 KiB
TypeScript
99 lines
3.3 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
import fs from 'fs';
|
|
import { login } from './helpers/auth';
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const PDF_FIXTURE = path.resolve(__dirname, 'fixtures/minimal.pdf');
|
|
|
|
/**
|
|
* E2E for issue #697 — read-only users can read an existing transcription.
|
|
*
|
|
* Setup runs as admin (default storage state): a PDF document with one
|
|
* transcription block, so hasTranscription is true. The assertions run in a
|
|
* fresh context logged in as the seeded READ_ALL-only "reader": they can open
|
|
* the read view but see no edit tab and no per-block edit controls, and the
|
|
* panel cannot be switched to edit.
|
|
*/
|
|
|
|
let docId: string;
|
|
let docHref: string;
|
|
|
|
test.describe.configure({ mode: 'serial' });
|
|
|
|
test.describe('Read-only user reads an existing transcription', () => {
|
|
test.beforeAll(async ({ request }) => {
|
|
const baseURL = process.env.E2E_BASE_URL ?? 'http://localhost:3000';
|
|
const uniqueSuffix = Date.now();
|
|
|
|
const docRes = await request.post('/api/documents', {
|
|
multipart: {
|
|
title: `E2E Read-only Transcription ${uniqueSuffix}`,
|
|
documentDate: '1945-05-08'
|
|
}
|
|
});
|
|
if (!docRes.ok()) throw new Error(`Create document failed: ${docRes.status()}`);
|
|
docId = (await docRes.json()).id;
|
|
docHref = `${baseURL}/documents/${docId}`;
|
|
|
|
await request.put(`/api/documents/${docId}`, {
|
|
multipart: {
|
|
title: `E2E Read-only Transcription ${uniqueSuffix}`,
|
|
documentDate: '1945-05-08',
|
|
file: {
|
|
name: 'minimal.pdf',
|
|
mimeType: 'application/pdf',
|
|
buffer: fs.readFileSync(PDF_FIXTURE)
|
|
}
|
|
}
|
|
});
|
|
|
|
const annRes = await request.post(`/api/documents/${docId}/annotations`, {
|
|
data: { pageNumber: 1, x: 0.1, y: 0.1, width: 0.5, height: 0.1, color: '#00C7B1' }
|
|
});
|
|
if (!annRes.ok()) throw new Error(`Create annotation failed: ${annRes.status()}`);
|
|
|
|
const blockRes = await request.post(`/api/documents/${docId}/transcription-blocks`, {
|
|
data: {
|
|
pageNumber: 1,
|
|
x: 0.1,
|
|
y: 0.1,
|
|
width: 0.5,
|
|
height: 0.1,
|
|
text: 'Liebe Mutter, viele Grüße vom Mai 1945',
|
|
label: null
|
|
}
|
|
});
|
|
if (!blockRes.ok()) throw new Error(`Create block failed: ${blockRes.status()}`);
|
|
});
|
|
|
|
test.afterAll(async ({ request }) => {
|
|
if (docId) await request.delete(`/api/documents/${docId}`);
|
|
});
|
|
|
|
test('reader opens the read view with no edit tab or edit controls', async ({ browser }) => {
|
|
const context = await browser.newContext({ storageState: { cookies: [], origins: [] } });
|
|
const page = await context.newPage();
|
|
try {
|
|
await login(page, 'reader', 'reader123');
|
|
await page.goto(docHref);
|
|
|
|
// Reader entry control is the read label, not "Transkribieren".
|
|
const readButton = page.getByRole('button', { name: /Transkription lesen/i });
|
|
await expect(readButton).toBeVisible({ timeout: 5000 });
|
|
await readButton.click();
|
|
|
|
// Read view shows the transcription text.
|
|
await expect(page.getByText(/Mai 1945/)).toBeVisible({ timeout: 5000 });
|
|
|
|
// Header is a plain "Transkription" label, not a Lesen/Bearbeiten toggle.
|
|
await expect(page.getByRole('heading', { name: /^Transkription$/i })).toBeVisible();
|
|
await expect(page.getByTestId('mode-edit')).toHaveCount(0);
|
|
await expect(page.getByTestId('mode-read')).toHaveCount(0);
|
|
} finally {
|
|
await context.close();
|
|
}
|
|
});
|
|
});
|