import { expect, test } from "@playwright/test"; import type { OperationalTask } from "../../src/features/workbench/api/operational-task-client"; const now = "2026-09-23T09:00:00Z"; const sources = ["peripheral_test_data", "scada_devices", "workbench_runtime", "scada_readings", "work_orders", "other_saved_data"]; const sourceRef = (source: string) => `${source}:sha256:${"7d5852b69d8e3d4e127800882683c3319e58".repeat(2)}`; const snapshotKey = "query_scope_with_a_long_unbroken_field_name"; const task: OperationalTask = { project_id: "11111111-1111-4111-8111-111111111111", task_id: "22222222-2222-4222-8222-222222222222", task_type: "event_investigation", workflow: "water_quality_complaint", lifecycle_status: "completed", active_run: null, status: "completed", priority: "normal", revision: 1, execution_generation: 1, execution_request_id: null, title: "水质投诉调查", summary: "居民反映异味", source: { kind: "operator", external_id: null, external_revision: null, event_kind: "water_quality_complaint" }, trigger: { kind: "manual", occurred_at: now, detail: "演示小区" }, scheduled_for: null, agent_session_id: null, agent_lease_expires_at: null, current_plan_revision: null, current_report_revision: 1, created_at: now, updated_at: now, latest_plan: null, latest_report: { revision: 1, execution_generation: 1, source_session_id: "evidence-layout-session", published_at: now, published_by: "agent", report: { title: "调查报告", current_conclusion: "需现场核查用户端。", conclusion_boundary: "仅覆盖已有记录。", evidence_refs: sources.slice(0, 5), recommendations: [], pending_items: [], stage: "final", outcome: "concluded", stop_reason: null, data_gaps: [] } }, evidence: sources.map((source) => ({ evidence_id: source, kind: "system_data", summary: `${source} 数据快照`, source_label: source, source_ref: sourceRef(source), observed_at: now, recorded_at: now, recorded_by: "agent", has_snapshot: true })), actions: [], access_requests: [], work_order_snapshot: null, permissions: { can_publish_artifacts: false, can_propose_actions: false, can_sync_external_feedback: false, can_decide_work_orders: false, can_execute_work_orders: false, can_decide_commands: false, can_execute_commands: false, can_decide_access: false } }; test("调查证据与数据快照的长引用在桌面和窄屏完整换行", async ({ page }, testInfo) => { await page.route("http://127.0.0.1:8787/api/v1/**", (route) => route.fulfill({ json: { items: [] } })); await page.goto("/", { waitUntil: "domcontentloaded" }); await page.setContent('
'); await page.evaluate(async ({ task, snapshotKey }) => { const reactModule = await import("/node_modules/.vite/deps/react.js"); const React = reactModule.default ?? reactModule; const clientModule = await import("/node_modules/.vite/deps/react-dom_client.js"); const { createRoot } = clientModule.default ?? clientModule; const { AgentExecutionPlanPanel } = await import("/src/features/workbench/components/agent-execution-plan-panel.tsx"); const noop = async () => undefined; createRoot(document.getElementById("report")).render(React.createElement(AgentExecutionPlanPanel, { task, onContinue: noop, onDecision: noop, onExecute: noop, onReconcile: noop, onRefresh: noop, onLoadEvidenceSnapshot: async (evidenceId: string) => ({ source: "workbench_runtime", origin: "system_data", source_ref: task.evidence.find((item) => item.evidence_id === evidenceId)!.source_ref, queried_at: task.updated_at, truncated: false, data: { [snapshotKey]: "long_snapshot_value_".repeat(8) } }) })); }, { task, snapshotKey }); const evidence = page.getByRole("region", { name: "主要依据", exact: true }); await expect(evidence).toBeVisible(); for (const name of ["更多引用依据 · 2 条", "其他已保存资料"]) { const summary = evidence.locator("summary").filter({ hasText: name }); await summary.focus(); await page.keyboard.press("Enter"); await expect(summary.locator("..")).toHaveAttribute("open", ""); } for (const source of sources) { const card = evidence.locator("details").filter({ has: page.locator("summary", { hasText: `${source} 数据快照` }) }).last(); await card.locator("summary").first().click(); await expect(card.locator("dd.font-mono")).toHaveText(sourceRef(source)); await card.getByRole("button", { name: "查看数据快照", exact: true }).click(); await expect(card.getByRole("region", { name: "数据快照" })).toContainText(snapshotKey); } for (const width of [1440, 705, 375, 320]) { await page.setViewportSize({ width, height: 900 }); const overflow = await evidence.evaluate((section) => { return [...section.querySelectorAll("dd, dt, [aria-label='数据快照'] p")].flatMap((element) => { const rect = element.getBoundingClientRect(); const card = element.closest("details")!.getBoundingClientRect(); return element.scrollWidth > element.clientWidth + 1 || rect.right > card.right + 1 || rect.left < card.left - 1 ? [{ text: element.textContent, width: element.clientWidth, scrollWidth: element.scrollWidth, right: rect.right, cardRight: card.right }] : []; }); }); expect(overflow, `证据字段在 ${width}px 下不应撑出卡片`).toEqual([]); await evidence.screenshot({ path: testInfo.outputPath(`evidence-${width}.png`) }); } });