48 lines
3.9 KiB
TypeScript
48 lines
3.9 KiB
TypeScript
import { expect, test, type APIRequestContext } from '@playwright/test';
|
|
import path from 'node:path';
|
|
|
|
const api = 'http://localhost:5302/api';
|
|
const password = 'E2ePassword123!';
|
|
async function login(client: APIRequestContext, email: string) {
|
|
expect((await client.post(`${api}/auth/login`, { data: { email, password } })).status()).toBe(200);
|
|
const me = await (await client.get(`${api}/auth/me`)).json();
|
|
return { id: me.id as string, headers: { 'X-CSRF-TOKEN': (await client.storageState()).cookies.find(cookie => cookie.name === 'XSRF-TOKEN')!.value, 'X-Session-Context': me.sessionContext as string } };
|
|
}
|
|
|
|
test('real Docling produces owner-scoped administrator history without exposing source text', async ({ page, playwright }, info) => {
|
|
await page.context().route('**/*', route => ['localhost', '127.0.0.1'].includes(new URL(route.request().url()).hostname) ? route.continue() : route.abort());
|
|
const admin = await playwright.request.newContext();
|
|
try {
|
|
const administrator = await login(admin, 'e2e@example.test');
|
|
const email = `processing-docling-${Date.now()}@example.test`;
|
|
expect((await admin.post(`${api}/users`, { headers: administrator.headers, data: { email, password, roles: ['Premium'] } })).status()).toBe(200);
|
|
const owner = await login(page.request, email);
|
|
await page.goto('/career?section=import');
|
|
await page.locator('input[type=file][accept*=".pdf"]').setInputFiles(path.resolve(process.env.CV_IMPORT_FIXTURE_ROOT || '../.artifacts/cv-import/corpus-02', 'dev-en-simple.pdf'));
|
|
await expect.poll(async () => (await (await page.request.get(`${api}/profile-cv/runs`)).json())[0]?.operation?.status, { timeout: 90000 }).toBe('succeeded');
|
|
const run = (await (await page.request.get(`${api}/profile-cv/runs`)).json())[0];
|
|
const id = run.operation.id;
|
|
expect(run.status).toBe('pending_review');
|
|
expect((await admin.get(`${api}/profile-cv/runs/${run.id}/source`)).status()).toBe(404);
|
|
const history = await (await admin.get(`${api}/admin/processing/${id}/events`)).json();
|
|
expect(history.items.map((item: { kind: string }) => item.kind)).toEqual(['Created', 'Claimed', ...Array(7).fill('StageChanged'), 'Completed']);
|
|
expect(history.items.filter((item: { kind: string }) => item.kind === 'StageChanged').map((item: { stage: string }) => item.stage)).toEqual(['cv_validating_file', 'cv_extracting', 'cv_identifying_sections', 'cv_analysing', 'cv_validating_details', 'cv_preparing_review', 'cv_review_ready']);
|
|
const detail = await (await admin.get(`${api}/admin/processing/${id}`)).json();
|
|
expect(detail.owner.id).toBe(owner.id);
|
|
expect(detail.document.name).toBe('dev-en-simple.pdf');
|
|
expect(detail.document.pages).toBeGreaterThan(0);
|
|
expect(detail.worker).toBe('document');
|
|
expect(detail.workerEnabled).toBe(true);
|
|
for (const field of ['rawExtractedText', 'documentJson', 'structuredProfileJson', 'leaseToken', 'failureMessage', 'resultReference']) expect(detail).not.toHaveProperty(field);
|
|
await login(page.request, 'e2e@example.test');
|
|
await page.goto('/admin/processing');
|
|
await page.getByLabel('Owner ID', { exact: true }).fill(owner.id);
|
|
await page.getByRole('button', { name: 'Apply filters', exact: true }).click();
|
|
await page.getByRole('button', { name: `View processing details ${id}`, exact: true }).click();
|
|
await expect(page.getByText(/^Processing completed/)).toBeVisible();
|
|
await expect(page.getByLabel('Correlation ID', { exact: true })).toHaveValue(id);
|
|
await page.screenshot({ path: info.outputPath('real-docling-processing-history.png'), fullPage: true });
|
|
await info.attach('real-parser-evidence-limit', { body: 'Actual pinned Docling conversion and deterministic interpretation; no generative model inference or model accuracy acceptance. Administrator source-download access remains denied by the ordinary ownership API.', contentType: 'text/plain' });
|
|
} finally { await admin.dispose(); }
|
|
});
|