Files
shanxia2.0/web-admin/scripts/test-vehicle-fuel-card.mjs
T

175 lines
7.7 KiB
JavaScript

import assert from 'node:assert/strict'
import { chromium } from 'playwright'
const origin = process.env.FUEL_CARD_TEST_ORIGIN || 'http://localhost:3006'
const screenshotPath = process.env.FUEL_CARD_SCREENSHOT || '/tmp/shanxia-vehicle-fuel-card.png'
const browser = await chromium.launch({ headless: true, channel: 'chrome' })
const context = await browser.newContext({ viewport: { width: 1440, height: 1000 } })
const page = await context.newPage()
page.setDefaultTimeout(20000)
const errors = []
page.on('pageerror', (error) => errors.push(error.message))
page.on('console', (message) => {
if (message.type() === 'error') console.error('Browser console:', message.text())
})
page.on('requestfailed', (request) =>
console.error('Request failed:', request.url(), request.failure())
)
const longCard = '000100001234567890123456789012345'
const base = '/transport/vehicle-fuel-card'
const calls = []
let rows = [
{
id: 'fixture-1',
licensePlate: '鄂A12345',
cardNo: longCard,
remark: '初始备注',
createTime: '2026-10-25 10:00:00',
updateTime: null
}
]
await context.addInitScript(() => {
localStorage.setItem(
'sys-v3.0.2-user',
JSON.stringify({
isLogin: true,
accessToken: 'fuel-card-fixture',
info: {
id: 'fixture-user',
userId: 'fixture-user',
userName: '回归测试用户',
role: 'admin',
roles: ['admin']
}
})
)
localStorage.setItem('sys-version', '3.0.2')
})
await context.route('**/api/**', async (route) => {
const request = route.request()
const url = new URL(request.url())
if (!url.pathname.startsWith('/api/')) return route.continue()
const path = url.pathname.replace(/^\/api/, '')
const method = request.method()
let body = {}
try {
body = request.postDataJSON() || {}
} catch {
/* GET 无请求体 */
}
let data = {}
if (path.startsWith(base)) {
calls.push({ path, method, body, params: Object.fromEntries(url.searchParams) })
if (path === base && method === 'GET') {
const q = url.searchParams.get('q') || ''
const filtered = rows.filter(
(row) =>
row.licensePlate.includes(q) || row.cardNo.includes(q) || (row.remark || '').includes(q)
)
const current = Number(url.searchParams.get('page') || 1)
const size = Number(url.searchParams.get('pageSize') || 20)
data = { list: filtered.slice((current - 1) * size, current * size), total: filtered.length }
} else if (path === base && method === 'POST') {
assert.deepEqual(Object.keys(body).sort(), ['cardNo', 'licensePlate', 'remark'])
data = { ...body, id: 'fixture-2', createTime: '2026-10-25 11:00:00', updateTime: null }
rows.push(data)
} else if (path === `${base}/batch-delete`) {
const previous = rows.length
rows = rows.filter((row) => !body.ids.includes(row.id))
data = { deleted: previous - rows.length }
} else if (method === 'PUT') {
assert.deepEqual(Object.keys(body).sort(), ['cardNo', 'licensePlate', 'remark'])
const id = path.split('/').pop()
const index = rows.findIndex((row) => row.id === id)
data = rows[index] = { ...rows[index], ...body, updateTime: '2026-10-25 12:00:00' }
} else if (method === 'GET') {
data = rows.find((row) => row.id === path.split('/').pop())
} else {
throw new Error(`Unexpected fixture request: ${method} ${path}`)
}
return route.fulfill({ json: data })
}
if (path === '/web/auth/current-user') {
data = {
id: 'fixture-user',
userId: 'fixture-user',
userName: '回归测试用户',
role: 'admin',
roles: ['admin']
}
} else if (path === '/web/auth/menu-codes') {
data = {
all: false,
menuCodes: ['pl:vehicle-fuel-card:list', 'pl:vehicle-recharge-workflow:list']
}
} else if (path.includes('favorites')) {
data = []
} else if (path.includes('dict-data')) {
data = {}
} else if (path.includes('upgrade-logs')) {
data = []
}
await route.fulfill({ json: { code: path.startsWith('/transport/') ? 0 : 200, msg: 'ok', data } })
})
try {
await page.goto(`${origin}/#/vehicle-mgmt/etc-recharge/vehicle-fuel-card`)
await page.getByText('车油卡信息', { exact: true }).first().click()
const panel = page
.locator('.panel')
.filter({ has: page.locator('h2.title-bar-heading', { hasText: '车油卡信息' }) })
await panel.locator('.el-link').filter({ hasText: '鄂A12345' }).waitFor()
assert.equal(await panel.locator('thead').getByText('操作', { exact: true }).count(), 0)
await panel.locator('.el-link').filter({ hasText: '鄂A12345' }).click()
const view = page.getByRole('dialog').filter({ has: page.locator('.view-hero') })
await view.getByText(longCard, { exact: true }).waitFor()
await view.getByRole('button', { name: '编辑', exact: true }).click()
const edit = page.getByRole('dialog').filter({ hasText: '编辑车油卡信息' })
await edit.getByPlaceholder('请输入油卡卡号').waitFor()
assert.equal(await edit.getByPlaceholder('请输入油卡卡号').inputValue(), longCard)
assert.equal(await edit.getByPlaceholder('请输入备注(选填)').inputValue(), '初始备注')
await edit.getByPlaceholder('请输入备注(选填)').fill('')
await edit.getByRole('button', { name: '确定', exact: true }).click()
await edit.waitFor({ state: 'hidden' })
assert.equal(calls.find((call) => call.method === 'PUT').body.cardNo, longCard)
assert.equal(calls.find((call) => call.method === 'PUT').body.remark, null)
await panel.getByRole('button', { name: '新增', exact: true }).click()
const add = page.getByRole('dialog').filter({ hasText: '新增车油卡信息' })
await add.getByPlaceholder('请输入车牌号').fill('鄂B23456')
await add.getByPlaceholder('请输入油卡卡号').fill('00012345678901234567890')
await add.getByPlaceholder('请输入备注(选填)').fill('新增备注')
await add.getByRole('button', { name: '确定', exact: true }).click()
await add.waitFor({ state: 'hidden' })
await panel.locator('.el-link').filter({ hasText: '鄂B23456' }).waitFor()
await page.locator('.el-message').first().waitFor({ state: 'hidden' })
await page.screenshot({ path: screenshotPath, fullPage: true })
await panel.getByPlaceholder('车牌号/油卡卡号/备注').fill('鄂B')
await panel.getByPlaceholder('车牌号/油卡卡号/备注').press('Enter')
await panel.locator('.el-link').filter({ hasText: '鄂A12345' }).waitFor({ state: 'hidden' })
assert.equal(
calls.filter((call) => call.path === base && call.method === 'GET').at(-1).params.q,
'鄂B'
)
await panel.getByPlaceholder('车牌号/油卡卡号/备注').hover()
await panel.locator('.quick-search-input .el-input__clear').click()
await panel.locator('.el-link').filter({ hasText: '鄂A12345' }).waitFor()
await panel.locator('thead .el-checkbox').first().click()
await panel.getByRole('button', { name: '删除', exact: true }).click()
await page.locator('.el-message-box').getByRole('button', { name: '删除', exact: true }).click()
await panel.locator('.el-link').filter({ hasText: '鄂A12345' }).waitFor({ state: 'hidden' })
assert.equal(rows.length, 0)
assert.deepEqual(calls.find((call) => call.path.endsWith('batch-delete')).body.ids.sort(), [
'fixture-1',
'fixture-2'
])
assert.deepEqual(errors, [])
console.log(
`PASS: 真实路由、列表、查看、编辑、长卡号、清空备注、新增、搜索、批量删除;截图 ${screenshotPath}`
)
} catch (error) {
console.error('Browser state:', page.url(), await page.locator('body').innerText(), errors, calls)
await page.screenshot({ path: '/tmp/shanxia-fuel-card-failure.png', fullPage: true })
throw error
} finally {
await browser.close()
}