| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- 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()
- }
|