|
- 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/advanced-drag-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)
- const browser = await chromium.launch({ channel: 'msedge', headless: true, args: ['--enable-unsafe-swiftshader'] })
- let page
- const checks = []
- 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)
- localStorage.setItem('unreal-tran:web:preferences:v1', JSON.stringify({ themeMode: 'military' }))
- }, session)
- page = await context.newPage()
- await page.goto(`http://127.0.0.1:6180/content/training-projects/${project.id}/legacy`)
- await page.getByRole('radio', { name: '高级编排', exact: true }).click({ timeout: 60000 })
- const canvas = page.locator('[data-role="flow-canvas"]')
- const node = page.locator('[data-flow-node="flow-start"]')
- const head = node.locator('.tfa-node-head')
- await head.scrollIntoViewIfNeeded()
- const initial = await node.evaluate(el => ({ x: parseFloat(el.style.left), y: parseFloat(el.style.top) }))
- const box = await head.boundingBox(), area = await canvas.boundingBox()
- await page.mouse.move(box.x + 45, box.y + 22)
- await page.mouse.down()
- const pointerY = area.y + area.height - 100
- await page.mouse.move(box.x + 45, pointerY, { steps: 12 })
- const before = await node.evaluate(el => parseFloat(el.style.top))
- const scrollDelta = await canvas.evaluate(el => { const old = el.scrollTop; el.scrollTop += 180; return el.scrollTop - old })
- assert.ok(scrollDelta > 80)
- await page.mouse.move(box.x + 45, pointerY + 5, { steps: 2 })
- const after = await node.evaluate(el => parseFloat(el.style.top))
- assert.ok(Math.abs(after - before - scrollDelta - 5) < 3, 'Node follows pointer in scrolled coordinates')
- const oldLimit = await canvas.evaluate(el => el.clientHeight - 110)
- assert.ok(after > oldLimit + 80, 'Node reaches grid below the former viewport limit')
- await page.mouse.up()
- checks.push({ name: '拖入下方网格,拖动中滚动不跳位', result: 'PASS', before, after, scrollDelta, formerLimit: oldLimit })
- const scrollBefore = await canvas.evaluate(el => el.scrollTop)
- await head.click()
- await expect.poll(() => canvas.evaluate(el => el.scrollTop)).toBe(scrollBefore)
- await expect.poll(() => node.evaluate(el => parseFloat(el.style.top))).toBe(after)
- await page.screenshot({ path: path.join(report, '01-lower-grid.png'), animations: 'disabled' })
- checks.push({ name: '选择节点后保留画布滚动位置', result: 'PASS' })
- await page.setViewportSize({ width: 1366, height: 768 })
- const last = page.locator('.tfa-node').last(), lastHead = last.locator('.tfa-node-head')
- await lastHead.scrollIntoViewIfNeeded()
- const previous = await last.evaluate(el => ({ x: parseFloat(el.style.left), y: parseFloat(el.style.top) }))
- const lastBox = await lastHead.boundingBox()
- await page.mouse.move(lastBox.x + 45, lastBox.y + 22)
- await page.mouse.down()
- await page.mouse.move(lastBox.x + 55, lastBox.y + 32, { steps: 4 })
- await page.mouse.up()
- const next = await last.evaluate(el => ({ x: parseFloat(el.style.left), y: parseFloat(el.style.top) }))
- assert.ok(Math.abs(next.x - previous.x - 10) < 2 && Math.abs(next.y - previous.y - 10) < 2, 'Small drag after horizontal scroll must not jump to viewport limit')
- await page.screenshot({ path: path.join(report, '02-horizontal-scroll.png'), animations: 'disabled' })
- checks.push({ name: '窄窗口横向滚动后拖动不跳位', result: 'PASS', previous, next })
- await page.getByRole('radio', { name: '基础编排', exact: true }).click()
- await page.getByRole('radio', { name: '高级编排', exact: true }).click()
- assert.equal(await node.evaluate(el => parseFloat(el.style.top)), after)
- checks.push({ name: '切换编排模式保留节点坐标', result: 'PASS' })
- fs.writeFileSync(path.join(report, 'results.json'), JSON.stringify({ passed: true, projectId: project.id, accountType: '内部维护', initial, checks, dataChanges: '仅调整已有测试工程的浏览器草稿,未点击保存或发布。' }, null, 2))
- console.log('Advanced drag layout checks passed')
- } catch (error) {
- if (page) await page.screenshot({ path: path.join(report, 'failure.png'), animations: 'disabled' }).catch(() => {})
- throw error
- } finally { await browser.close() }
|