Files
goauto/web/tests/e2e/syb-network-retry.spec.ts
T

122 lines
8.9 KiB
TypeScript

import { expect, test } from '@playwright/test'
const sybProductRoute = [{ path: '/goauto-order-workbench', component: 'Layout', menuName: 'GoAutoOrderWorkbench', title: '订单工作台', visible: '0', children: [{ path: '/syb-products', component: '/goauto/syb-products/index', menuName: 'GoAutoSybProducts', title: 'SYB 商品', visible: '0' }] }]
test('SYB 商品首次网络失败时静默重试一次并恢复列表', async({ page, context }) => {
await context.addCookies([{ name: 'Admin-Token', value: 'prototype-test-token', domain: 'localhost', path: '/' }])
let listCalls = 0
await page.route('**/api/**', async route => {
const url = new URL(route.request().url())
if (url.pathname.startsWith('/src/api/')) return route.continue()
if (url.pathname.endsWith('/api/v1/getinfo')) return route.fulfill({ json: { code: 200, data: { roles: ['admin'], name: '管理员', avatar: '', introduction: '', permissions: [] }}})
if (url.pathname.endsWith('/api/v1/menurole')) return route.fulfill({ json: { code: 200, data: sybProductRoute }})
if (url.pathname.endsWith('/api/admin/v1/syb-products')) {
listCalls += 1
if (listCalls === 1) return route.abort('connectionrefused')
return route.fulfill({ json: { code: 200, data: { items: [{ id: 72, orderCode: 'RETRY-72', shopeeItemId: '10072', productTitle: '网络恢复后的商品', quantity: 1, parseStatus: 'success' }], total: 1, page: 1, pageSize: 20 }}})
}
if (url.pathname.endsWith('/api/admin/v1/purchase-tasks/batch-preview')) return route.fulfill({ json: { code: 200, data: { items: [{ sybProductId: 72, eligible: false, reason: '测试数据未关联商品', processStage: 'manual_action', processStageLabel: '待人工处理', processStageReason: '测试数据未关联商品' }], eligibleCount: 0, skippedCount: 1 }}})
return route.fulfill({ json: { code: 200, data: [] }})
})
await page.goto('/#/syb-products')
await expect(page.getByText('网络恢复后的商品')).toBeVisible()
expect(listCalls).toBe(2)
await expect(page.getByText('服务器连接异常,请检查服务器!')).toHaveCount(0)
})
test('SYB 商品业务错误不重试', async({ page, context }) => {
await context.addCookies([{ name: 'Admin-Token', value: 'prototype-test-token', domain: 'localhost', path: '/' }])
let listCalls = 0
await page.route('**/api/**', async route => {
const url = new URL(route.request().url())
if (url.pathname.startsWith('/src/api/')) return route.continue()
if (url.pathname.endsWith('/api/v1/getinfo')) return route.fulfill({ json: { code: 200, data: { roles: ['admin'], name: '管理员', avatar: '', introduction: '', permissions: [] }}})
if (url.pathname.endsWith('/api/v1/menurole')) return route.fulfill({ json: { code: 200, data: sybProductRoute }})
if (url.pathname.endsWith('/api/admin/v1/syb-products')) {
listCalls += 1
return route.fulfill({ json: { code: 500, msg: '测试业务错误' }})
}
return route.fulfill({ json: { code: 200, data: [] }})
})
await page.goto('/#/syb-products')
await expect(page.getByText('测试业务错误')).toBeVisible()
expect(listCalls).toBe(1)
})
test('SYB 列表先展示,采购准备在独立请求完成后更新', async({ page, context }) => {
await context.addCookies([{ name: 'Admin-Token', value: 'prototype-test-token', domain: 'localhost', path: '/' }])
await page.route('**/api/**', async route => {
const url = new URL(route.request().url())
if (url.pathname.startsWith('/src/api/')) return route.continue()
if (url.pathname.endsWith('/api/v1/getinfo')) return route.fulfill({ json: { code: 200, data: { roles: ['admin'], name: '管理员', avatar: '', introduction: '', permissions: [] }}})
if (url.pathname.endsWith('/api/v1/menurole')) return route.fulfill({ json: { code: 200, data: sybProductRoute }})
if (url.pathname.endsWith('/api/admin/v1/syb-products')) return route.fulfill({ json: { code: 200, data: { items: [{ id: 73, orderCode: 'FAST-73', shopeeItemId: '10073', productTitle: '先显示的商品', quantity: 1, parseStatus: 'success' }], total: 1, page: 1, pageSize: 20 }}})
if (url.pathname.endsWith('/api/admin/v1/purchase-tasks/batch-preview')) {
await new Promise(resolve => setTimeout(resolve, 3000))
return route.fulfill({ json: { code: 200, data: { items: [{ sybProductId: 73, pddProductId: 173, eligible: true, minUnitPriceCent: 100, maxUnitPriceCent: 300, processStage: 'purchase_ready', processStageLabel: '可创建采购', processStageReason: '当前条件可以创建采购任务' }], eligibleCount: 1, skippedCount: 0 }}})
}
return route.fulfill({ json: { code: 200, data: [] }})
})
await page.goto('/#/syb-products')
await expect(page.getByText('先显示的商品')).toBeVisible({ timeout: 2000 })
await expect(page.getByText('正在检查')).toBeVisible()
await expect(page.getByText('可以创建')).toBeVisible({ timeout: 5000 })
})
test('采购准备失败不清空 SYB 列表且不弹全局错误', async({ page, context }) => {
await context.addCookies([{ name: 'Admin-Token', value: 'prototype-test-token', domain: 'localhost', path: '/' }])
await page.route('**/api/**', async route => {
const url = new URL(route.request().url())
if (url.pathname.startsWith('/src/api/')) return route.continue()
if (url.pathname.endsWith('/api/v1/getinfo')) return route.fulfill({ json: { code: 200, data: { roles: ['admin'], name: '管理员', avatar: '', introduction: '', permissions: [] }}})
if (url.pathname.endsWith('/api/admin/v1/syb-products')) return route.fulfill({ json: { code: 200, data: { items: [{ id: 74, orderCode: 'FAIL-74', shopeeItemId: '10074', productTitle: '仍然可见的商品', quantity: 1, parseStatus: 'success' }], total: 1, page: 1, pageSize: 20 }}})
if (url.pathname.endsWith('/api/v1/menurole')) return route.fulfill({ json: { code: 200, data: sybProductRoute }})
if (url.pathname.endsWith('/api/admin/v1/purchase-tasks/batch-preview')) return route.fulfill({ status: 500, json: { code: 500, msg: '预检测试失败' }})
return route.fulfill({ json: { code: 200, data: [] }})
})
await page.goto('/#/syb-products')
await expect(page.getByText('仍然可见的商品')).toBeVisible()
await expect(page.getByText('采购准备检查失败,请点击刷新重试')).toBeVisible()
await expect(page.getByText('预检测试失败')).toHaveCount(0)
})
test('新的查询结果不会被旧采购预检覆盖', async({ page, context }) => {
await context.addCookies([{ name: 'Admin-Token', value: 'prototype-test-token', domain: 'localhost', path: '/' }])
await page.route('**/api/**', async route => {
const url = new URL(route.request().url())
if (url.pathname.startsWith('/src/api/')) return route.continue()
if (url.pathname.endsWith('/api/v1/getinfo')) return route.fulfill({ json: { code: 200, data: { roles: ['admin'], name: '管理员', avatar: '', introduction: '', permissions: [] }}})
if (url.pathname.endsWith('/api/v1/menurole')) return route.fulfill({ json: { code: 200, data: sybProductRoute }})
if (url.pathname.endsWith('/api/admin/v1/syb-products')) {
const searched = url.searchParams.get('orderCodes') === 'NEW-76'
const item = searched
? { id: 76, orderCode: 'NEW-76', shopeeItemId: '10076', productTitle: '新商品', quantity: 1, parseStatus: 'success' }
: { id: 75, orderCode: 'OLD-75', shopeeItemId: '10075', productTitle: '旧商品', quantity: 1, parseStatus: 'success' }
return route.fulfill({ json: { code: 200, data: { items: [item], total: 1, page: 1, pageSize: 20 }}})
}
if (url.pathname.endsWith('/api/admin/v1/purchase-tasks/batch-preview')) {
const [id] = route.request().postDataJSON().sybProductIds
if (id === 75) {
await new Promise(resolve => setTimeout(resolve, 1200))
return route.fulfill({ json: { code: 200, data: { items: [{ sybProductId: 75, pddProductId: 175, eligible: true, processStage: 'purchase_ready', processStageLabel: '可创建采购', processStageReason: '当前条件可以创建采购任务' }], eligibleCount: 1, skippedCount: 0 }}})
}
return route.fulfill({ json: { code: 200, data: { items: [{ sybProductId: 76, eligible: false, reason: '新商品暂不可创建', processStage: 'manual_action', processStageLabel: '待人工处理', processStageReason: '新商品暂不可创建' }], eligibleCount: 0, skippedCount: 1 }}})
}
return route.fulfill({ json: { code: 200, data: [] }})
})
await page.goto('/#/syb-products')
await expect(page.getByText('旧商品')).toBeVisible()
await page.getByPlaceholder('每行一个订单号,最多 100 个').fill('NEW-76')
await page.getByRole('button', { name: '查询' }).click()
await expect(page.getByText('新商品', { exact: true })).toBeVisible()
await expect(page.getByText('新商品暂不可创建')).toBeVisible()
await page.waitForTimeout(1500)
await expect(page.getByText('新商品暂不可创建')).toBeVisible()
await expect(page.getByText('可以创建', { exact: true })).toHaveCount(0)
})