181 lines
7.3 KiB
JavaScript
181 lines
7.3 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-recharge-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 = []
|
|
const calls = []
|
|
page.on('pageerror', (error) => errors.push(error.message))
|
|
const cardNo = '1000113400009309765'
|
|
const oldCardNo = '1000113400009253456'
|
|
const vehicles = ['皖LB1283', '皖H21522', '皖H09177'].map((licensePlate, index) => ({
|
|
id: `vehicle-${index}`,
|
|
licensePlate,
|
|
vehicleType: 'self',
|
|
vehicleStatus: 'available'
|
|
}))
|
|
const row = {
|
|
id: 'apply-fixture',
|
|
applyNo: 'CZ202610250001',
|
|
licensePlate: '皖LB1283',
|
|
rechargeType: 'fuel',
|
|
boundFuelCardNo: cardNo,
|
|
applicantId: 'fixture-user',
|
|
applicantName: '回归测试用户',
|
|
applyDate: '2026-10-25',
|
|
odometerKm: 12345,
|
|
status: 'disbursed',
|
|
record: { cardNo: oldCardNo, amount: 1000, rechargeDate: '2026-10-25' }
|
|
}
|
|
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/, '')
|
|
let data = {}
|
|
if (path.startsWith('/transport/')) {
|
|
calls.push({ path, method: request.method(), params: Object.fromEntries(url.searchParams) })
|
|
assert.equal(request.method(), 'GET', 'browser check must not submit business data')
|
|
if (path === '/transport/vehicle') data = { list: vehicles, total: vehicles.length }
|
|
else if (path === '/transport/vehicle-recharge-apply/') data = { items: [row], total: 1 }
|
|
else if (path.startsWith('/transport/vehicle-recharge-approval/'))
|
|
data = { items: [row], total: 1 }
|
|
else if (path === '/transport/vehicle-recharge-record/disburse-board')
|
|
data = {
|
|
items: [
|
|
{ ...row, applyId: row.id, applyStatus: row.status, recordId: 'r1', cardNo: oldCardNo }
|
|
],
|
|
total: 1
|
|
}
|
|
else if (path === '/transport/vehicle-recharge-apply/fuel-card') {
|
|
const licensePlate = url.searchParams.get('licensePlate')
|
|
if (licensePlate === '皖H09177')
|
|
return route.fulfill({ status: 503, json: { detail: '测试网络失败' } })
|
|
return route.fulfill({
|
|
json: { licensePlate, cardNo: licensePlate === '皖LB1283' ? cardNo : null }
|
|
})
|
|
} else if (path === '/transport/vehicle-recharge-apply/apply-fixture') data = row
|
|
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-recharge-apply:list',
|
|
'pl:vehicle-recharge-approval:list',
|
|
'pl:vehicle-recharge-record:list'
|
|
]
|
|
}
|
|
} else if (path === '/web/admin/users/options') {
|
|
data = [{ label: '回归测试用户', value: 'fixture-user' }]
|
|
} else if (path.includes('favorites') || path.includes('upgrade-logs')) data = []
|
|
await route.fulfill({ json: { code: 200, msg: 'ok', data } })
|
|
})
|
|
|
|
function field(dialog, label) {
|
|
return dialog.locator('.el-form-item').filter({
|
|
has: page.locator('.el-form-item__label').filter({ hasText: new RegExp(`^${label}$`) })
|
|
})
|
|
}
|
|
|
|
async function choose(dialog, label, text) {
|
|
await field(dialog, label).locator('.el-select').click()
|
|
await page.locator('.el-select-dropdown:visible').getByText(text, { exact: true }).click()
|
|
}
|
|
|
|
try {
|
|
for (const kind of ['apply', 'approval', 'record']) {
|
|
await page.goto(`${origin}/#/vehicle-mgmt/etc-recharge/vehicle-recharge-${kind}`)
|
|
const table = page.locator('.list-table')
|
|
await table.getByText('油卡卡号', { exact: true }).waitFor()
|
|
await table.getByText(cardNo, { exact: true }).first().waitFor()
|
|
assert.equal(await table.getByText(cardNo, { exact: true }).count(), 1)
|
|
}
|
|
await page.goto(`${origin}/#/vehicle-mgmt/etc-recharge/vehicle-recharge-apply`)
|
|
await page.getByRole('button', { name: '新增申请', exact: true }).waitFor()
|
|
await page.locator('.el-link').filter({ hasText: row.applyNo }).click()
|
|
const view = page.getByRole('dialog').filter({ has: page.locator('.view-hero') })
|
|
await view.getByText('绑定油卡卡号', { exact: true }).waitFor()
|
|
await view.getByText(cardNo, { exact: true }).waitFor()
|
|
await view.getByText(oldCardNo, { exact: true }).waitFor()
|
|
await view.locator('.el-dialog__headerbtn').click()
|
|
await view.waitFor({ state: 'hidden' })
|
|
await page.getByRole('button', { name: '新增申请', exact: true }).click()
|
|
const form = page.getByRole('dialog').filter({ hasText: '新增申请' })
|
|
await choose(form, '充值类型', '油卡')
|
|
const binding = field(form, '绑定油卡卡号').locator('input')
|
|
await binding.waitFor()
|
|
assert.equal(await binding.inputValue(), '请先选择车牌号')
|
|
await choose(form, '车牌号', '皖LB1283')
|
|
await page.waitForFunction(
|
|
(expected) =>
|
|
[...document.querySelectorAll('.el-dialog input')].some((input) => input.value === expected),
|
|
cardNo
|
|
)
|
|
assert.equal(await binding.inputValue(), cardNo)
|
|
assert.notEqual(await binding.getAttribute('readonly'), null)
|
|
await choose(form, '充值类型', '山峡')
|
|
await binding.waitFor({ state: 'hidden' })
|
|
await choose(form, '充值类型', '油卡')
|
|
await page.waitForFunction(
|
|
(expected) =>
|
|
[...document.querySelectorAll('.el-dialog input')].some((input) => input.value === expected),
|
|
cardNo
|
|
)
|
|
await form.locator('.el-dialog__header').click()
|
|
await page.locator('.el-select-dropdown:visible').waitFor({ state: 'hidden' })
|
|
await page.screenshot({ path: screenshotPath, fullPage: true })
|
|
await choose(form, '车牌号', '皖H21522')
|
|
await page.waitForFunction(() =>
|
|
[...document.querySelectorAll('.el-dialog input')].some((input) => input.value === '未绑定油卡')
|
|
)
|
|
assert.equal(await binding.inputValue(), '未绑定油卡')
|
|
await choose(form, '车牌号', '皖H09177')
|
|
await page.waitForFunction(() =>
|
|
[...document.querySelectorAll('.el-dialog input')].some(
|
|
(input) => input.value === '油卡信息加载失败'
|
|
)
|
|
)
|
|
assert.equal(await binding.inputValue(), '油卡信息加载失败')
|
|
assert.deepEqual(errors, [])
|
|
assert.ok(calls.some((call) => call.path.endsWith('/fuel-card')))
|
|
console.log(
|
|
`PASS: 真实申请页详情/填写、长卡号、历史卡号保留、fuel/山峡切换、未绑定及失败;未提交数据。截图 ${screenshotPath}`
|
|
)
|
|
} catch (error) {
|
|
console.error('Browser state:', page.url(), await page.locator('body').innerText(), errors, calls)
|
|
await page.screenshot({ path: '/tmp/shanxia-recharge-fuel-card-failure.png', fullPage: true })
|
|
throw error
|
|
} finally {
|
|
await browser.close()
|
|
}
|