Files
Agent-System/web/e2e/controlled-document-reload.spec.ts
T
weichenandCursor 7f8ad76d12 test(docgov): add two-pool races and ledger-first live spec
Occupy the integration slot for M1 live sign-off, cover two pgx pools plus four sessions, and add a Playwright spec that treats projection consistency as 200 rather than 404.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-14 14:24:46 +00:00

115 lines
4.9 KiB
TypeScript

import { test, expect, type Page } from '@playwright/test';
import * as fs from 'fs';
import * as path from 'path';
import { fileURLToPath } from 'url';
/**
* M1 live: ledger-first GET. Projection missing must not become 404/409.
* Project 143 is read-only. Do not terminate or PUT workflow-plan.
*/
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const runAcceptance = process.env.RUN_UI_ACCEPTANCE === '1';
const ASSETS = process.env.UI_ACCEPTANCE_ASSETS_DIR
? path.resolve(process.env.UI_ACCEPTANCE_ASSETS_DIR)
: path.resolve(
__dirname,
'../../.doc/test-reports/assets/2026-09-14-document-reliability-pilot-live',
);
const SCREENSHOTS = path.join(ASSETS, 'screenshots');
fs.mkdirSync(SCREENSHOTS, { recursive: true });
const ADMIN_USER = process.env.ADMIN_USERNAME?.trim() || '';
const ADMIN_PASS = process.env.ADMIN_PASSWORD?.trim() || '';
const BASE = process.env.BASE_URL || 'http://127.0.0.1:8080';
const TARGET_DOC = 'doc_proj143_intake';
test.skip(!runAcceptance, 'set RUN_UI_ACCEPTANCE=1 against the rebuilt dev stack');
async function login(page: Page, username: string, password: string) {
await page.goto('/');
await page.fill('input[placeholder*="系统用户名"]', username);
await page.fill('input[placeholder*="登录密码"]', password);
await page.click('button:has-text("进入医疗协同工作台")');
await expect(page.getByText('新建立项会话')).toBeVisible({ timeout: 30_000 });
}
test.describe.serial('controlled document reload M1 live', () => {
test('project 143 content is 200 with consistency; anonymous is 401; unknown is 404', async ({
browser,
}) => {
if (!ADMIN_USER || !ADMIN_PASS) {
throw new Error('ADMIN_USERNAME and ADMIN_PASSWORD are required');
}
const page = await browser.newPage();
const contentHits: { status: number; consistency?: string; error?: string }[] = [];
page.on('response', async (res) => {
const u = res.url();
if (!u.includes(`/docgov/documents/${TARGET_DOC}/content`)) return;
let consistency: string | undefined;
let error: string | undefined;
try {
const json = (await res.json()) as { consistency?: string; error_code?: string };
consistency = json.consistency;
error = json.error_code;
} catch {
/* ignore non-json */
}
contentHits.push({ status: res.status(), consistency, error });
});
await login(page, ADMIN_USER, ADMIN_PASS);
await page.getByRole('complementary').getByTitle('对话协同会话', { exact: true }).click({ force: true });
await expect(page.getByRole('banner')).toContainText('对话协同会话', { timeout: 20_000 });
await page.screenshot({ path: path.join(SCREENSHOTS, '01-project-143.png'), fullPage: true });
const token = await page.evaluate(() => {
try {
const raw = window.localStorage.getItem('smdf_auth_session');
if (!raw) return '';
const session = JSON.parse(raw) as { token?: string };
return session.token || '';
} catch {
return '';
}
});
if (!token) {
throw new Error('login did not persist smdf_auth_session.token');
}
const authed = await page.request.get(`${BASE}/api/v1/docgov/documents/${TARGET_DOC}/content`, {
headers: token ? { Authorization: `Bearer ${token}` } : {},
});
const authedBody = await authed.json();
expect(authed.status(), `content ${JSON.stringify(authedBody)}`).toBe(200);
expect(authedBody.markdown, 'ledger markdown required').toBeTruthy();
expect(['aligned', 'missing', 'drift', 'empty', 'ledger_missing']).toContain(authedBody.consistency);
expect(authedBody.error_code ?? '').not.toMatch(/PROJECTION/);
await page.reload();
await expect(page.getByRole('banner')).toContainText('对话协同会话', { timeout: 20_000 });
const afterReload = await page.request.get(`${BASE}/api/v1/docgov/documents/${TARGET_DOC}/content`, {
headers: token ? { Authorization: `Bearer ${token}` } : {},
});
expect(afterReload.status()).toBe(200);
const reloadBody = await afterReload.json();
expect(reloadBody.markdown).toBeTruthy();
await page.screenshot({ path: path.join(SCREENSHOTS, '02-after-reload.png'), fullPage: true });
const anon = await page.request.get(`${BASE}/api/v1/docgov/documents/${TARGET_DOC}/content`);
expect(anon.status()).toBe(401);
const missing = await page.request.get(`${BASE}/api/v1/docgov/documents/doc_does_not_exist_m1/content`, {
headers: token ? { Authorization: `Bearer ${token}` } : {},
});
expect(missing.status()).toBe(404);
const missingBody = await missing.json();
expect(missingBody.error_code).toBe('DOCUMENT_NOT_FOUND');
const projection409 = contentHits.filter(
(h) => h.status === 409 || String(h.error || '').includes('PROJECTION'),
);
expect(projection409, JSON.stringify(contentHits)).toHaveLength(0);
});
});