272 lines
9.2 KiB
TypeScript
272 lines
9.2 KiB
TypeScript
import { test, expect, request } from '@playwright/test';
|
|
|
|
const timestamp = Date.now()
|
|
const testProjectId = '550e8400-e29b-41d4-a716-446655440001'
|
|
|
|
function uniqueCode() {
|
|
return `EQ-${timestamp}-${Math.random().toString(36).substr(2, 8)}`
|
|
}
|
|
|
|
async function getToken() {
|
|
const context = await request.newContext()
|
|
const loginResp = await context.post('http://127.0.0.1:8080/api/auth/login', {
|
|
headers: { 'Content-Type': 'application/json' },
|
|
data: { username: 'admin', password: 'Admin@123' }
|
|
})
|
|
const loginData = await loginResp.json()
|
|
const token = loginData.data?.token
|
|
await context.dispose()
|
|
return token
|
|
}
|
|
|
|
async function createEquipment(token: string, name: string) {
|
|
const context = await request.newContext()
|
|
const resp = await context.post('http://127.0.0.1:8080/api/v1/mdm/equipment', {
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': `Bearer ${token}`
|
|
},
|
|
data: {
|
|
projectId: testProjectId,
|
|
equipmentName: name,
|
|
equipmentCode: uniqueCode(),
|
|
equipmentType: 'ELEVATOR',
|
|
systemType: 'ELEVATOR',
|
|
ownershipType: 'PROJECT',
|
|
status: 'ACTIVE'
|
|
}
|
|
})
|
|
const data = await resp.json()
|
|
await context.dispose()
|
|
if (data.code !== 200 || !data.data) {
|
|
console.log(`创建设备失败: ${JSON.stringify(data)}`)
|
|
return null
|
|
}
|
|
return data.data
|
|
}
|
|
|
|
async function createTask(token: string, equipmentId: string, title: string) {
|
|
const context = await request.newContext()
|
|
const resp = await context.post('http://127.0.0.1:8080/api/mdm/maintenance-tasks', {
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': `Bearer ${token}`
|
|
},
|
|
data: {
|
|
equipmentId,
|
|
title,
|
|
description: `测试工单`,
|
|
taskType: 'CORRECTIVE',
|
|
triggerType: 'FAULT',
|
|
priority: 'MEDIUM'
|
|
}
|
|
})
|
|
const data = await resp.json()
|
|
await context.dispose()
|
|
if (data.code !== 200 || !data.data) {
|
|
console.log(`创建任务失败: ${JSON.stringify(data)}`)
|
|
return null
|
|
}
|
|
return data.data
|
|
}
|
|
|
|
async function deleteEquipment(token: string, id: string) {
|
|
if (!id) return
|
|
const context = await request.newContext()
|
|
await context.delete(`http://127.0.0.1:8080/api/v1/mdm/equipment/${id}`, {
|
|
headers: { 'Authorization': `Bearer ${token}` }
|
|
})
|
|
await context.dispose()
|
|
}
|
|
|
|
test.describe('业务流程E2E测试', () => {
|
|
|
|
test('1. 设备完整生命周期', async () => {
|
|
const token = await getToken()
|
|
expect(token).toBeTruthy()
|
|
|
|
const equipment = await createEquipment(token!, `设备生命周期_${timestamp}`)
|
|
expect(equipment?.id).toBeTruthy()
|
|
console.log(`✓ 创建设备: ${equipment?.id}`)
|
|
|
|
const context = await request.newContext()
|
|
const getResp = await context.get(`http://127.0.0.1:8080/api/v1/mdm/equipment/${equipment.id}`, {
|
|
headers: { 'Authorization': `Bearer ${token}` }
|
|
})
|
|
expect(getResp.status()).toBe(200)
|
|
const detailData = await getResp.json()
|
|
expect(detailData.data.equipmentName).toContain('设备生命周期')
|
|
console.log('✓ 查询设备详情成功')
|
|
await context.dispose()
|
|
|
|
await deleteEquipment(token!, equipment.id)
|
|
console.log('✓ 删除设备成功')
|
|
})
|
|
|
|
test('2. 维保工单状态流转', async () => {
|
|
const token = await getToken()
|
|
const equipment = await createEquipment(token!, `工单流转_${timestamp}`)
|
|
if (!equipment) {
|
|
console.log('设备创建失败,跳过测试')
|
|
return
|
|
}
|
|
|
|
const task = await createTask(token!, equipment.id, `工单流转测试_${timestamp}`)
|
|
if (!task) {
|
|
console.log('任务创建失败,跳过测试')
|
|
await deleteEquipment(token!, equipment.id)
|
|
return
|
|
}
|
|
console.log(`✓ 工单创建: ${task?.id}, 状态: ${task?.status}`)
|
|
|
|
const assignCtx = await request.newContext()
|
|
const assignResp = await assignCtx.post(`http://127.0.0.1:8080/api/mdm/maintenance-tasks/${task.id}/assign`, {
|
|
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
|
|
data: { assignedTo: '张三' }
|
|
})
|
|
expect(assignResp.status()).toBe(200)
|
|
console.log('✓ 派单成功')
|
|
await assignCtx.dispose()
|
|
|
|
const startCtx = await request.newContext()
|
|
const startResp = await startCtx.post(`http://127.0.0.1:8080/api/mdm/maintenance-tasks/${task.id}/start`, {
|
|
headers: { 'Authorization': `Bearer ${token}` }
|
|
})
|
|
expect(startResp.status()).toBe(200)
|
|
console.log('✓ 开始执行成功')
|
|
await startCtx.dispose()
|
|
|
|
const completeCtx = await request.newContext()
|
|
const completeResp = await completeCtx.post(`http://127.0.0.1:8080/api/mdm/maintenance-tasks/${task.id}/complete`, {
|
|
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
|
|
data: { result: '已完成', completedBy: '张三' }
|
|
})
|
|
expect(completeResp.status()).toBe(200)
|
|
console.log('✓ 完成工单成功')
|
|
await completeCtx.dispose()
|
|
|
|
const verifyCtx = await request.newContext()
|
|
const verifyResp = await verifyCtx.post(`http://127.0.0.1:8080/api/mdm/maintenance-tasks/${task.id}/verify`, {
|
|
headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
|
|
data: { verifiedBy: '李经理', rating: 5 }
|
|
})
|
|
expect(verifyResp.status()).toBe(200)
|
|
console.log('✓ 验收工单成功')
|
|
await verifyCtx.dispose()
|
|
|
|
await deleteEquipment(token!, equipment.id)
|
|
console.log('✓ 工单流转测试完成')
|
|
})
|
|
|
|
test('3. 设备列表页面正常加载', async ({ page }) => {
|
|
const token = await getToken()
|
|
await page.goto('http://127.0.0.1:5175/login')
|
|
await page.evaluate((t) => {
|
|
localStorage.setItem('token', t)
|
|
localStorage.setItem('userInfo', JSON.stringify({ username: 'admin' }))
|
|
}, token!)
|
|
await page.goto('http://127.0.0.1:5175/equipment/list')
|
|
await page.waitForLoadState('networkidle')
|
|
await page.waitForTimeout(1500)
|
|
const url = page.url()
|
|
expect(url).toContain('equipment')
|
|
console.log('✓ 设备列表页面加载正常')
|
|
})
|
|
|
|
})
|
|
|
|
test.describe('边际情况E2E测试', () => {
|
|
|
|
test('4. 取消工单功能', async () => {
|
|
const token = await getToken()
|
|
const equipment = await createEquipment(token!, `取消测试_${timestamp}`)
|
|
if (!equipment) {
|
|
console.log('设备创建失败,跳过测试')
|
|
return
|
|
}
|
|
const task = await createTask(token!, equipment.id, `取消测试_${timestamp}`)
|
|
if (!task) {
|
|
await deleteEquipment(token!, equipment.id)
|
|
console.log('任务创建失败,跳过测试')
|
|
return
|
|
}
|
|
|
|
const context = await request.newContext()
|
|
const cancelResp = await context.post(`http://127.0.0.1:8080/api/mdm/maintenance-tasks/${task.id}/cancel`, {
|
|
headers: { 'Authorization': `Bearer ${token}` }
|
|
})
|
|
expect(cancelResp.status()).toBe(200)
|
|
const cancelData = await cancelResp.json()
|
|
expect(cancelData.data?.status).toBe('CANCELLED')
|
|
console.log('✓ 取消工单成功')
|
|
await context.dispose()
|
|
await deleteEquipment(token!, equipment.id)
|
|
})
|
|
|
|
test('5. 获取不存在的设备返回404', async () => {
|
|
const token = await getToken()
|
|
const context = await request.newContext()
|
|
const resp = await context.get('http://127.0.0.1:8080/api/v1/mdm/equipment/00000000-0000-0000-0000-000000000000', {
|
|
headers: { 'Authorization': `Bearer ${token}` }
|
|
})
|
|
const status = resp.status()
|
|
console.log(`不存在设备响应状态: ${status}`)
|
|
expect(status).toBe(404)
|
|
console.log('✓ 不存在资源返回404')
|
|
await context.dispose()
|
|
})
|
|
|
|
test('6. 未登录访问返回401/403', async () => {
|
|
const context = await request.newContext()
|
|
const resp = await context.get('http://127.0.0.1:8080/api/mdm/maintenance-tasks')
|
|
expect([401, 403]).toContain(resp.status())
|
|
console.log('✓ 未授权访问被拒绝')
|
|
await context.dispose()
|
|
})
|
|
|
|
test('7. 重复设备名称应允许创建', async () => {
|
|
const token = await getToken()
|
|
const dupName = `重复名称_${timestamp}`
|
|
|
|
const eq1 = await createEquipment(token!, dupName)
|
|
if (!eq1) {
|
|
console.log('第一个设备创建失败')
|
|
return
|
|
}
|
|
const eq2 = await createEquipment(token!, dupName)
|
|
expect(eq2?.id).toBeTruthy()
|
|
console.log('✓ 系统允许重复设备名称')
|
|
|
|
await deleteEquipment(token!, eq1.id)
|
|
await deleteEquipment(token!, eq2.id)
|
|
})
|
|
|
|
})
|
|
|
|
test.describe('页面稳定性测试', () => {
|
|
test('8. 设备相关页面无严重错误', async ({ page }) => {
|
|
const errors: string[] = []
|
|
page.on('console', msg => {
|
|
if (msg.type() === 'error') errors.push(msg.text())
|
|
})
|
|
|
|
const token = await getToken()
|
|
await page.goto('http://127.0.0.1:5175/equipment/list')
|
|
await page.evaluate((t) => {
|
|
localStorage.setItem('token', t)
|
|
localStorage.setItem('userInfo', JSON.stringify({ username: 'admin' }))
|
|
}, token!)
|
|
await page.reload()
|
|
|
|
const pages = ['/equipment/list', '/equipment/maintenance-plan', '/equipment/maintenance-task']
|
|
for (const path of pages) {
|
|
await page.goto(`http://127.0.0.1:5175${path}`)
|
|
await page.waitForLoadState('networkidle')
|
|
await page.waitForTimeout(800)
|
|
}
|
|
|
|
console.log(`控制台错误数: ${errors.length}`)
|
|
expect(errors.length).toBeLessThan(5)
|
|
console.log('✓ 页面无严重错误')
|
|
})
|
|
}) |