import { captureScreenshot, expect, test } from './fixtures' import { TeachingContractMock } from './teaching-contract-mock' test.describe('教员只读预览工作台', () => { test('按原型呈现完整工作台且所有演练保持浏览器本地只读', async ({ page }, testInfo) => { await page.setViewportSize({ width: 1920, height: 1080 }) const contract = new TeachingContractMock('admin') await contract.install(page) await page.goto('/teaching/virtual-training/preview/assignment-virtual-preview') const workbench = page.locator('.teaching-preview-workbench') await expect(workbench).toBeVisible() await expect(workbench).toContainText('教员预览 · 不计成绩') await expect(workbench.locator('.preview-step-panel > header')).toContainText('1 / 8') await expect(workbench.locator('.preview-step-panel li')).toHaveCount(8) await expect(workbench.locator('.preview-step-panel')).toContainText('卸压确认与故障基线采集') await expect(workbench.locator('.preview-step-panel')).toContainText('密封复验与中修闭环') await expect(workbench.locator('.preview-runtime-viewport canvas')).toBeVisible() await expect(workbench.locator('.preview-digital-teacher')).toContainText('装备维修虚拟教员') await expect(workbench.locator('.preview-digital-teacher')).toContainText('数字车间知识库') await expect(workbench.locator('.preview-digital-teacher')).toContainText('确认压力表回零,记录故障压力和泄漏现象。') await expect(workbench.locator('.preview-digital-teacher img')).toHaveJSProperty('complete', true) await expect(workbench.locator('iframe')).toHaveCount(0) await captureScreenshot(page, testInfo, 'teaching-teacher-preview-initial') const writesBefore = contract.requests.filter((request) => ['POST', 'PUT', 'DELETE'].includes(request.method)).length await workbench.getByRole('button', { name: '打开在线答疑', exact: true }).click() const onlineDrawer = page.locator('.el-drawer:visible').filter({ hasText: '装备维修虚拟教员 · 数字车间知识库' }).last() const digitalInstructor = onlineDrawer.getByTestId('digital-instructor-embed') await expect(digitalInstructor).toBeVisible() const instructorFrame = digitalInstructor.locator('iframe') await expect(instructorFrame).toHaveAttribute('src', /\/embed\/demo-equipment-instructor\?open=1&knowledgeSource=workshop$/) await expect(instructorFrame).toHaveAttribute('allow', 'autoplay; microphone') await expect(digitalInstructor.locator('.digital-instructor-embed__status')).toHaveText('页面已加载') await expect(page.frameLocator('[data-testid="digital-instructor-embed"] iframe').getByTestId('mock-ai-person')).toHaveText('虚拟教员在线答疑') await expect.poll(() => contract.digitalInstructorFrameLoads).toBe(1) expect(contract.requests.filter((request) => ['POST', 'PUT', 'DELETE'].includes(request.method))).toHaveLength(writesBefore) await page.keyboard.press('Escape') await expect(onlineDrawer).toBeHidden() await expect(page.locator('[data-testid="digital-instructor-embed"] iframe')).toHaveCount(0) await workbench.getByRole('button', { name: '判定详情', exact: true }).click() await expect(workbench.locator('.preview-rule-drawer')).toContainText('RELEASE_PRESSURE_BASELINE') await expect(workbench.locator('.preview-rule-drawer')).toContainText('这里只展示发布快照中的公开字段') await workbench.getByRole('button', { name: '规则演示', exact: true }).click() await workbench.getByRole('button', { name: '步骤演示', exact: true }).click() await workbench.getByRole('button', { name: '引导完成', exact: true }).click() await expect(workbench.getByRole('button', { name: /下一步/ })).toBeEnabled() await workbench.getByRole('button', { name: /下一步/ }).click() await expect(workbench.getByRole('heading', { name: /第 2 步:油管与接头外泄检查/ })).toBeVisible() await expect(workbench.locator('.preview-step-panel > header')).toContainText('2 / 8') await workbench.getByRole('button', { name: /过程记录/ }).click() const drawer = page.locator('.el-drawer:visible').last() await expect(drawer).toContainText('不会提交到教学事件接口') await expect(drawer).toContainText('本地试走步骤') await expect(drawer).toContainText('规则演示') await expect(drawer).toContainText('步骤演示') const writesAfter = contract.requests.filter((request) => ['POST', 'PUT', 'DELETE'].includes(request.method)).length expect(writesAfter).toBe(writesBefore) await page.keyboard.press('Escape') await expect(drawer).toBeHidden() await captureScreenshot(page, testInfo, 'teaching-teacher-preview-workbench') await workbench.getByRole('button', { name: '返回任务列表', exact: true }).click() await expect(page).toHaveURL(/\/teaching\/virtual-training$/) }) })