This commit is contained in:
2026-04-08 21:26:18 +08:00
commit 8fdc7ac0c3
401 changed files with 53093 additions and 0 deletions

View File

@@ -0,0 +1,223 @@
import { expect, test } from '@playwright/test'
/**
* DCS 编辑器 - 图层操作测试
*
* 测试图层的添加、选择、删除等操作。
* 部分测试(如拖拽添加组件)因 Playwright 对 HTML5 drag-and-drop 的限制
* 而标记为 skip仅验证可测试的交互路径。
*/
/** 辅助函数:创建画布并进入编辑器 */
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 })
}
/** 辅助函数:获取图层面板中的图层行数量 */
async function getLayerRowCount(page: import('@playwright/test').Page): Promise<number> {
return page.locator('.layer-list .layer-row').count()
}
test.describe('图层管理', () => {
test.skip('通过拖拽添加组件到画布', async ({ page }) => {
// 跳过HTML5 drag-and-drop 在 Playwright 中较难模拟,
// 且应用在 Tauri 环境还使用了 pointer 方案替代。
await enterEditor(page, '拖拽添加测试')
// 切换到组件面板
await page.locator('.sidebar-tab-item').filter({ hasText: '组件' }).click()
await expect(page.locator('.components-tab')).toBeVisible()
// 获取矩形组件卡片和画布舞台区域
const rectCard = page.locator('.component-card').first()
const canvas = page.locator('.canvas-wrapper')
// 尝试拖拽(此操作可能不可靠)
await rectCard.dragTo(canvas, {
targetPosition: { x: 300, y: 300 },
})
// 验证图层面板中出现新图层
await page.locator('.sidebar-tab-item').filter({ hasText: '图层' }).click()
const layerCount = await getLayerRowCount(page)
expect(layerCount).toBeGreaterThan(0)
})
test('初始状态下图层面板为空', async ({ page }) => {
await enterEditor(page, '空图层面板测试')
// 确认图层面板可见
await expect(page.locator('.layers-tab')).toBeVisible()
// 新画布应该没有图层
const layerCount = await getLayerRowCount(page)
expect(layerCount).toBe(0)
})
test('属性面板初始显示空状态或底图信息', async ({ page }) => {
await enterEditor(page, '属性面板初始测试')
// 属性面板头部应该可见且显示"属性"标题
const propertyTitle = page.locator('.property-panel .title')
await expect(propertyTitle).toContainText('属性')
// 没有选中图层时,应显示提示文字
const summaryOrEmpty = page.locator('.property-panel .selection-summary, .property-panel .property-empty')
await expect(summaryOrEmpty.first()).toBeVisible()
})
test('属性面板有停靠/浮动切换按钮', async ({ page }) => {
await enterEditor(page, '停靠切换测试')
// 停靠/浮动切换按钮应存在
const dockBtn = page.locator('.dock-toggle-btn')
await expect(dockBtn).toBeVisible()
// 点击切换到浮动模式
await dockBtn.click()
await expect(page.locator('.property-panel-shell--floating')).toBeVisible()
// 再次点击切换回停靠模式
await page.locator('.dock-toggle-btn').click()
await expect(page.locator('.property-panel-shell:not(.property-panel-shell--floating)')).toBeVisible()
})
test('图层面板显示页面列表', async ({ page }) => {
await enterEditor(page, '页面列表验证测试')
// 页面树区域应显示至少一个页面
const pageRows = page.locator('.page-tree .page-row')
await expect(pageRows.first()).toBeVisible()
// 第一个页面应处于激活状态
await expect(page.locator('.page-row.active')).toBeVisible()
})
test('图层面板有添加页面按钮', async ({ page }) => {
await enterEditor(page, '添加页面按钮测试')
// 页面头部的添加按钮应存在fa-plus 图标)
const addPageBtn = page.locator('.page-header').locator('button').filter({
has: page.locator('.fa-plus'),
})
await expect(addPageBtn).toBeVisible()
})
test('图层面板有搜索框', async ({ page }) => {
await enterEditor(page, '图层搜索测试')
// 搜索行应包含输入框
const searchInput = page.locator('.layer-search-row input')
await expect(searchInput).toBeVisible()
})
test('状态栏无选中时不显示选中计数', async ({ page }) => {
await enterEditor(page, '状态栏选中计数测试')
// 没有选中图层时,状态栏右侧不应显示"已选中"
await expect(page.locator('.editor-status-bar .status-right')).not.toContainText('已选中')
})
test('缩放信息显示在状态栏中', async ({ page }) => {
await enterEditor(page, '状态栏缩放测试')
// 状态栏应显示缩放百分比(如"100%"
const statusItems = page.locator('.editor-status-bar .status-item')
let foundZoom = false
const count = await statusItems.count()
for (let i = 0; i < count; i++) {
const text = await statusItems.nth(i).textContent()
if (text && text.includes('%')) {
foundZoom = true
break
}
}
expect(foundZoom).toBe(true)
})
test('画布舞台有标尺', async ({ page }) => {
await enterEditor(page, '标尺测试')
// 水平标尺
await expect(page.locator('.ruler-top')).toBeVisible()
// 垂直标尺
await expect(page.locator('.ruler-left')).toBeVisible()
// 标尺角落
await expect(page.locator('.ruler-corner')).toBeVisible()
})
test.skip('选中图层后属性面板显示属性', async ({ page }) => {
// 跳过:需要先有图层才能选中,添加图层依赖拖拽操作
await enterEditor(page, '选中属性测试')
// 预期:选中图层后,属性面板标题下方应显示图层信息
const propertyBody = page.locator('.property-panel .property-body')
await expect(propertyBody).toBeVisible()
})
test.skip('可以删除选中的图层', async ({ page }) => {
// 跳过:需要先有可选中的图层(添加图层依赖拖拽操作)
await enterEditor(page, '删除图层测试')
// 预期:选中图层后按 Delete/Backspace 可删除
// 或通过右键菜单删除
})
test.skip('删除图层后可撤销', async ({ page }) => {
// 跳过:依赖先添加并删除图层
await enterEditor(page, '撤销删除测试')
// 预期:删除图层后,撤销按钮变为可用,点击撤销可恢复图层
})
test('图层面板页面列表可以折叠和展开', async ({ page }) => {
await enterEditor(page, '页面折叠测试')
// 页面树应该初始可见
await expect(page.locator('.page-tree')).toBeVisible()
// 点击折叠/展开按钮page-header 中的角标按钮)
const toggleBtn = page.locator('.page-header .header-actions button').filter({
has: page.locator('.fa-angle-up, .fa-angle-down'),
})
await toggleBtn.click()
// 页面树应该被隐藏v-show 控制,元素仍在 DOM 中但不可见)
await expect(page.locator('.page-tree')).toBeHidden()
// 再次点击展开
await toggleBtn.click()
await expect(page.locator('.page-tree')).toBeVisible()
})
test('画布舞台 overlay 层存在', async ({ page }) => {
await enterEditor(page, 'Overlay 测试')
// overlay 是放置图层选择框等交互元素的层
await expect(page.locator('.canvas-wrapper .overlay')).toBeAttached()
})
test('组件面板中的组件卡片显示描述信息', async ({ page }) => {
await enterEditor(page, '组件描述测试')
// 切换到组件面板
await page.locator('.sidebar-tab-item').filter({ hasText: '组件' }).click()
await expect(page.locator('.components-tab')).toBeVisible()
// 每个组件卡片应该有标题和描述
const firstCard = page.locator('.component-card').first()
await expect(firstCard.locator('.card-title')).toBeVisible()
await expect(firstCard.locator('.card-desc')).toBeVisible()
// 验证具体描述内容(矩形:基础矩形图层)
const rectDesc = page.locator('.component-card').filter({ hasText: '矩形' }).locator('.card-desc')
await expect(rectDesc).toContainText('基础矩形图层')
})
})