|
- import fs from 'node:fs'
- import path from 'node:path'
- import assert from 'node:assert/strict'
- import { createRequire } from 'node:module'
- import { fileURLToPath } from 'node:url'
- import { login, call } from './role-permissions-live.mjs'
- const require = createRequire(new URL('../package.json', import.meta.url))
- const { chromium, expect } = require('@playwright/test')
- const report = fileURLToPath(new URL('../reports/narration-dialog-layout-20260909/', import.meta.url))
- fs.mkdirSync(report, { recursive: true })
- const session = await login('root')
- const project = (await call('tran/v1/content/projects?type=TRAINING&size=100', session.accessToken)).data.records.find(row => row.name.includes('APE2E-数字人讲解-狐狸'))
- assert.ok(project, 'Existing narration test project available')
- const browser = await chromium.launch({ channel: 'msedge', headless: true, args: ['--enable-unsafe-swiftshader'] })
- const checks = []
- let page
- try {
- const context = await browser.newContext({ viewport: { width: 1920, height: 911 } })
- await context.addInitScript(({ accessToken, refreshToken }) => {
- sessionStorage.setItem('unreal-tran:web:access-token:v1', accessToken)
- sessionStorage.setItem('unreal-tran:web:refresh-token:v1', refreshToken)
- }, session)
- page = await context.newPage()
- await page.goto(`http://127.0.0.1:6180/content/training-projects/${project.id}/legacy`)
- await page.locator('[data-action="set-tab"]').filter({ hasText: '讲解' }).click({ timeout: 60000 })
- await page.locator('[data-action="set-narration-source"][data-source="digital-library"]').click()
- await page.locator('[data-action="manage-digital-human"]').click()
- const dialog = page.locator('.digital-human-narration-dialog')
- console.log('Narration dialog opened')
- await expect(dialog.locator('.connection-state')).toContainText('已连接数字人服务', { timeout: 30000 })
- const preview = dialog.getByRole('button', { name: '预览', exact: true }).last()
- const previewResponse = page.waitForResponse(response => response.url().includes('/digital-human/videos/') && response.url().endsWith('/preview'), { timeout: 125000 })
- await preview.click({ timeout: 30000 })
- console.log('Authorized video preview requested')
- assert.equal((await previewResponse).status(), 200, 'Authorized video preview response')
- await page.waitForFunction(() => document.querySelector('.video-preview video')?.readyState >= 1, null, { timeout: 20000 })
- await dialog.locator('video').evaluate(video => { video.currentTime = 0.1 })
- async function verify(label, width, height, theme = 'light') {
- await page.setViewportSize({ width, height })
- await page.evaluate(async value => {
- const { usePreferencesStore } = await import('/src/stores/preferences.ts')
- usePreferencesStore().setThemeMode(value === 'dark' ? 'dark' : 'military')
- }, theme)
- await expect.poll(async () => dialog.evaluate(el => {
- const box = el.getBoundingClientRect(), footer = el.querySelector('.el-dialog__footer').getBoundingClientRect()
- const body = el.querySelector('.el-dialog__body')
- return box.top >= 0 && box.bottom <= innerHeight + 1 && box.left >= 0 && box.right <= innerWidth + 1 && footer.bottom <= innerHeight && body.scrollWidth <= body.clientWidth + 1
- })).toBe(true)
- await dialog.locator('.video-preview').scrollIntoViewIfNeeded()
- await expect(dialog.locator('.el-dialog__footer').getByRole('button', { name: '关闭', exact: true })).toBeVisible()
- const video = await dialog.locator('video').evaluate(el => ({ width: el.videoWidth, height: el.videoHeight, duration: el.duration }))
- assert.ok(video.width > 0 && video.duration > 0)
- await page.screenshot({ path: path.join(report, `${label}.png`), animations: 'disabled' })
- checks.push({ label, viewport: { width, height }, theme, result: 'PASS', video })
- }
- await verify('01-desktop-preview', 1920, 911)
- await verify('02-short-preview', 1366, 600)
- await verify('03-mobile-preview', 390, 844)
- await verify('04-dark-preview', 1366, 768, 'dark')
- await dialog.getByRole('tab', { name: '现场生成成片' }).click()
- await expect(dialog.getByRole('button', { name: '提交生成', exact: true })).toBeAttached()
- await dialog.getByRole('button', { name: '提交生成', exact: true }).scrollIntoViewIfNeeded()
- await page.screenshot({ path: path.join(report, '05-generation-form.png'), animations: 'disabled' })
- await dialog.getByRole('tab', { name: '生成任务', exact: true }).click()
- await dialog.locator('.el-dialog__footer').getByRole('button', { name: '关闭', exact: true }).click()
- await expect(dialog).toBeHidden()
- checks.push({ label: '生成表单、任务页签与底部关闭', result: 'PASS' })
- const lan = await context.request.get('http://192.168.31.168:6180/')
- assert.equal(lan.status(), 200)
- checks.push({ label: '局域网入口', result: 'PASS' })
- fs.writeFileSync(path.join(report, 'results.json'), JSON.stringify({ passed: true, projectId: project.id, accountType: '内部维护', checks, dataChanges: '使用已有测试工程和授权视频。打开数字人服务前编辑器按既有逻辑保存测试工程;未提交生成、导入绑定或发布。' }, null, 2))
- console.log('Narration dialog layout checks passed')
- } catch (error) {
- if (page) {
- await page.screenshot({ path: path.join(report, 'failure.png'), animations: 'disabled' }).catch(() => {})
- console.error(await page.locator('.el-message').allTextContents())
- }
- throw error
- } finally { await browser.close() }
|