all
This commit is contained in:
223
tests/e2e/layer-operations.spec.ts
Normal file
223
tests/e2e/layer-operations.spec.ts
Normal 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('基础矩形图层')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user