175 lines
7.7 KiB
JavaScript
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()
|
|
}
|