Files
test/tests/e2e/canvas-editor.spec.ts
2026-04-08 21:26:18 +08:00

182 lines
7.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { expect, test } from '@playwright/test'
/**
* DCS 编辑器 - 画布编辑器核心功能测试
*
* 测试画布页面管理、侧边栏标签切换、组件面板等核心交互。
* 每个测试独立运行,通过创建画布进入编辑器。
*/
/** 辅助函数:创建画布并进入编辑器 */
async function enterEditor(page: import('@playwright/test').Page, canvasName = '测试画布') {
await page.goto('/')
await page.waitForLoadState('networkidle')
await page.locator('.add-card').click()
const dialog = page.locator('.el-dialog')
await expect(dialog).toBeVisible({ timeout: 5000 })
await dialog.locator('input').first().fill(canvasName)
await dialog.locator('button').filter({ hasText: '创建' }).click()
await expect(page.locator('.dcs-editor')).toBeVisible({ timeout: 10000 })
}
test.describe('画布编辑器核心功能', () => {
test('编辑器加载后显示画布舞台', async ({ page }) => {
await enterEditor(page, '画布加载测试')
// 画布舞台wrapper应该可见
await expect(page.locator('.canvas-wrapper')).toBeVisible()
// 画布内 canvas 元素应存在
await expect(page.locator('.canvas-wrapper canvas')).toBeVisible()
// 标尺应该可见
await expect(page.locator('.ruler-top')).toBeVisible()
await expect(page.locator('.ruler-left')).toBeVisible()
})
test('侧边栏标签 - 默认显示图层面板', async ({ page }) => {
await enterEditor(page, '侧边栏标签测试')
// 默认激活的标签应该是"图层"
const activeTab = page.locator('.sidebar-tab-item.active')
await expect(activeTab).toContainText('图层')
// 图层面板区域应该可见
await expect(page.locator('.layers-tab')).toBeVisible()
})
test('侧边栏标签 - 切换到组件面板', async ({ page }) => {
await enterEditor(page, '组件面板测试')
// 点击"组件"标签
await page.locator('.sidebar-tab-item').filter({ hasText: '组件' }).click()
// 组件标签应变为激活状态
const activeTab = page.locator('.sidebar-tab-item.active')
await expect(activeTab).toContainText('组件')
// 组件面板应该可见,且包含提示文字
await expect(page.locator('.components-tab')).toBeVisible()
await expect(page.locator('.components-hint')).toContainText('拖拽添加到画布')
})
test('侧边栏标签 - 切换到模板面板', async ({ page }) => {
await enterEditor(page, '模板面板测试')
// 点击"模板"标签
await page.locator('.sidebar-tab-item').filter({ hasText: '模板' }).click()
// 模板标签应变为激活状态
const activeTab = page.locator('.sidebar-tab-item.active')
await expect(activeTab).toContainText('模板')
})
test('侧边栏标签 - 可以依次切换回图层面板', async ({ page }) => {
await enterEditor(page, '标签回切测试')
// 先切到组件
await page.locator('.sidebar-tab-item').filter({ hasText: '组件' }).click()
await expect(page.locator('.sidebar-tab-item.active')).toContainText('组件')
// 再切回图层
await page.locator('.sidebar-tab-item').filter({ hasText: '图层' }).click()
await expect(page.locator('.sidebar-tab-item.active')).toContainText('图层')
await expect(page.locator('.layers-tab')).toBeVisible()
})
test('组件面板显示所有可用组件', async ({ page }) => {
await enterEditor(page, '组件列表测试')
// 切换到组件面板
await page.locator('.sidebar-tab-item').filter({ hasText: '组件' }).click()
await expect(page.locator('.components-tab')).toBeVisible()
// 验证组件卡片数量constants.ts 定义了 5 个:矩形、数值、文本、棒图、按钮)
const cards = page.locator('.component-card')
await expect(cards).toHaveCount(5)
// 验证各组件名称
await expect(page.locator('.card-title').filter({ hasText: '矩形' })).toBeVisible()
await expect(page.locator('.card-title').filter({ hasText: '数值' })).toBeVisible()
await expect(page.locator('.card-title').filter({ hasText: '文本' })).toBeVisible()
await expect(page.locator('.card-title').filter({ hasText: '棒图' })).toBeVisible()
await expect(page.locator('.card-title').filter({ hasText: '按钮' })).toBeVisible()
})
test('图层面板显示页面列表和画布页数', async ({ page }) => {
await enterEditor(page, '页面列表测试')
// 图层面板应可见
await expect(page.locator('.layers-tab')).toBeVisible()
// 页面头部应显示页数
await expect(page.locator('.page-header')).toContainText('页数')
// 页面列表应至少有一个活动页面
const activePage = page.locator('.page-row.active')
await expect(activePage).toBeVisible()
})
test('点击画布背景可以取消图层选中', async ({ page }) => {
await enterEditor(page, '取消选中测试')
// 点击画布背景区域
await page.locator('.canvas-wrapper').click({ position: { x: 50, y: 50 } })
// 状态栏不应显示选中信息(没有选中任何图层时不会显示"已选中"
await expect(page.locator('.editor-status-bar .status-right')).not.toContainText('已选中')
})
test('撤销按钮初始状态为禁用', async ({ page }) => {
await enterEditor(page, '撤销状态测试')
// 撤销按钮初始应该是禁用的(没有操作历史)
const undoBtn = page.locator('.editor-header .icon-btn').filter({ has: page.locator('.fa-rotate-left') })
await expect(undoBtn).toBeDisabled()
// 重做按钮初始也应该是禁用的
const redoBtn = page.locator('.editor-header .icon-btn').filter({ has: page.locator('.fa-rotate-right') })
await expect(redoBtn).toBeDisabled()
})
test('头部包含分享和运行按钮', async ({ page }) => {
await enterEditor(page, '头部按钮测试')
// 分享按钮
await expect(page.locator('.share-btn')).toBeVisible()
await expect(page.locator('.share-btn')).toContainText('分享')
// 运行组合按钮
await expect(page.locator('.run-combo-btn')).toBeVisible()
await expect(page.locator('.run-main-btn')).toBeVisible()
})
test('工具栏显示工具按钮', async ({ page }) => {
await enterEditor(page, '工具栏测试')
// 工具栏应可见
await expect(page.locator('.tool-rail')).toBeVisible()
// 工具按钮应存在(至少有移动工具、文本工具、矩形工具 + 底部折叠按钮)
const toolButtons = page.locator('.tool-rail .tool-btn')
const count = await toolButtons.count()
expect(count).toBeGreaterThanOrEqual(3)
})
test('侧边栏可以折叠和展开', async ({ page }) => {
await enterEditor(page, '折叠展开测试')
// 确认侧边栏面板初始可见
await expect(page.locator('.editor-sidebar-panel')).toBeVisible()
// 点击折叠按钮(工具栏底部的按钮,有 fa-angles-left 图标)
const collapseBtn = page.locator('.tool-bottom .tool-btn')
await collapseBtn.click()
// 侧边栏应添加 is-collapsed 类
await expect(page.locator('.editor-sidebar-shell.is-collapsed')).toBeVisible()
// 再次点击展开
await collapseBtn.click()
await expect(page.locator('.editor-sidebar-shell:not(.is-collapsed)')).toBeVisible()
})
})