58 lines
4.2 KiB
TypeScript
58 lines
4.2 KiB
TypeScript
import { expect, test, type Page, type BrowserContext } from '@playwright/test'
|
||
|
||
async function setup(page: Page, context: BrowserContext, mode = 'success') {
|
||
await page.setViewportSize({ width: 1920, height: 1080 })
|
||
await context.addCookies([{ name: 'Admin-Token', value: 'isolated-test-token', domain: 'localhost', path: '/' }])
|
||
const previews: number[][] = []; const writes: number[][] = []
|
||
await page.route('**/api/**', async route => {
|
||
const url = new URL(route.request().url()); const pathname = url.pathname
|
||
if (pathname.startsWith('/src/api/')) return route.continue()
|
||
const reply = (data: unknown) => route.fulfill({ json: { code: 200, data } })
|
||
if (pathname.endsWith('/api/v1/menurole')) return reply([{ path: '/workbench', component: 'Layout', menuName: 'Workbench', title: '工作台', visible: '0', children: [{ path: '/syb-inner-codes', component: '/goauto/syb-inner-codes/index', menuName: 'GoAutoSybInnerCodes', title: '档口入库码', visible: '0' }] }])
|
||
if (pathname.endsWith('/api/v1/getinfo')) return reply({ roles: ['purchaser'], name: '模拟采购员', avatar: '', permissions: [] })
|
||
if (pathname.endsWith('/syb-inner-codes') && route.request().method() === 'GET') return reply({ items: ['updated', 'ready', 'failed', 'ready'].map((status, i) => ({ id: i + 1, businessDate: '2026-09-29', orderNumber: `MOCK-${i + 1}`, status, items: [{ code: `MOCK-CODE-${i}`, ordinal: 1 }], specRaw: '模拟规格' })), total: 4 })
|
||
if (pathname.endsWith('/apply-preview')) {
|
||
const ids = route.request().postDataJSON().ids; previews.push(ids)
|
||
if (mode === 'preview-error') return route.fulfill({ status: 500, json: { code: 'INTERNAL', message: '模拟预览失败' } })
|
||
return reply({ records: ids.length, inboundCodes: ids.length === 1 ? 3 : 2, blocked: mode === 'changed' && ids.length === 2 ? [{ id: 4, status: 'updated' }] : [] })
|
||
}
|
||
if (pathname.endsWith('/apply')) {
|
||
writes.push(route.request().postDataJSON().ids)
|
||
return reply({ batchId: 'mock-batch', queued: writes.at(-1)!.length })
|
||
}
|
||
if (pathname.includes('/apply-batches/')) return reply({ batch: { id: 'mock-batch', status: 'running', requested: writes.at(-1)!.length, processed: 0 } })
|
||
return reply({ items: [], total: 0 })
|
||
})
|
||
await page.goto('/#/syb-inner-codes')
|
||
await expect(page.getByRole('cell', { name: 'MOCK-1', exact: true })).toBeVisible()
|
||
await page.locator('.el-table__header-wrapper .el-checkbox').first().click()
|
||
await page.getByRole('button', { name: '回写(2)', exact: true }).click()
|
||
return { previews, writes, dialog: page.getByRole('dialog') }
|
||
}
|
||
|
||
test('mixed selection reports skipped items and submits only ready records', async ({ page, context }) => {
|
||
const { previews, writes, dialog } = await setup(page, context)
|
||
await expect(dialog.getByText('选中 4 条,可回写 2 条,跳过 2 条;只提交本次确认的可回写记录。')).toBeVisible()
|
||
await expect(dialog.getByRole('button', { name: '回写 2 条', exact: true })).toBeEnabled()
|
||
expect(previews).toEqual([[2, 4]]); expect(writes).toEqual([])
|
||
await dialog.getByRole('button', { name: '回写 2 条', exact: true }).click()
|
||
await expect.poll(() => writes.length).toBe(1); expect(writes[0]).toEqual([2, 4])
|
||
await expect(dialog).not.toBeVisible()
|
||
})
|
||
|
||
test('preview status changes update count and only submit remaining candidate', async ({ page, context }) => {
|
||
const { previews, writes, dialog } = await setup(page, context, 'changed')
|
||
await expect(dialog.getByText('选中 4 条,可回写 1 条,跳过 3 条;只提交本次确认的可回写记录。')).toBeVisible()
|
||
await expect(dialog.getByRole('button', { name: '回写 1 条', exact: true })).toBeEnabled()
|
||
expect(previews).toEqual([[2, 4], [2]])
|
||
await dialog.getByRole('button', { name: '回写 1 条', exact: true }).click()
|
||
await expect.poll(() => writes.length).toBe(1); expect(writes[0]).toEqual([2])
|
||
})
|
||
|
||
test('preview failure is visible and cannot submit', async ({ page, context }) => {
|
||
const { writes, dialog } = await setup(page, context, 'preview-error')
|
||
await expect(dialog.locator('.el-alert--error')).toBeVisible()
|
||
await expect(dialog.getByRole('button', { name: '回写 2 条', exact: true })).toBeDisabled()
|
||
expect(writes).toEqual([])
|
||
})
|