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