Files
goauto/web/tests/e2e/syb-sync-run.spec.ts
T

83 lines
6.7 KiB
TypeScript

import { expect, test } from '@playwright/test';
async function authenticate(context: any) {
await context.addCookies([{ name: 'Admin-Token', value: 'prototype-test-token', domain: 'localhost', path: '/' }]);
}
test('同步记录展示失败原因和按店铺统计', async ({ page, context }) => {
await authenticate(context);
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: ['purchaser'], name: '采购员', avatar: '', introduction: '', permissions: [] } } });
if (url.pathname.endsWith('/api/admin/v1/syb-products/sync-runs/51')) return route.fulfill({ json: { code: 200, data: { item: { id: 51, dateFrom: '2026-08-18', dateTo: '2026-08-20', status: 'failed', daysProcessed: 2, daysTotal: 3, progressPercent: 66, orderCount: 12, detailCount: 8, acceptedCount: 10, shopSkipped: 2, created: 5, updated: 3, operatorName: '系统定时同步', startedAt: '2026-08-20T01:00:00Z', finishedAt: '2026-08-20T01:05:00Z', errorMessage: '第 3 天读取失败,等待下个调度周期重试', shopFilterHash: 'abc123', shopBreakdown: [{ shopName: '大碼臻選', accepted: 10, skipped: 0 }, { shopName: '未知店铺', accepted: 0, skipped: 2 }] } } } });
if (url.pathname.endsWith('/api/admin/v1/syb-products/sync-runs')) return route.fulfill({ json: { code: 200, data: { items: [{ id: 51, dateFrom: '2026-08-18', dateTo: '2026-08-20', status: 'failed', daysProcessed: 2, daysTotal: 3, orderCount: 12, detailCount: 8, created: 5, updated: 3, operatorName: '系统定时同步', startedAt: '2026-08-20T01:00:00Z' }], total: 1, page: 1, pageSize: 20 } } });
return route.fulfill({ json: { code: 200, data: [] } });
});
await page.goto('http://localhost:9527/#/syb-sync-runs/index');
await expect(page.getByRole('heading', { name: 'SYB 同步记录' })).toBeVisible();
await expect(page.getByRole('button', { name: '立即同步' })).toHaveCount(0);
await expect(page.getByText('2026-08-18 至 2026-08-20')).toBeVisible();
await page.getByRole('button', { name: '详情' }).click();
await expect(page.getByText('第 3 天读取失败,等待下个调度周期重试')).toBeVisible();
await expect(page.getByText('大碼臻選')).toBeVisible();
await expect(page.getByText('未知店铺')).toBeVisible();
await expect(page.getByText('系统定时同步', { exact: true }).first()).toBeVisible();
});
test('管理员可立即同步今天和昨天,受理后按钮进入运行中状态', async ({ page, context }) => {
await authenticate(context);
let importBody: any = null;
let importAccepted = false;
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/import') && route.request().method() === 'POST') {
importBody = route.request().postDataJSON();
await new Promise(resolve => setTimeout(resolve, 200));
importAccepted = true;
return route.fulfill({ status: 202, json: { code: 200, data: { runId: 88, status: 'running' } } });
}
if (url.pathname.endsWith('/api/admin/v1/syb-products/sync-runs')) {
const items = importAccepted ? [{ id: 88, dateFrom: importBody.dateFrom, dateTo: importBody.dateTo, status: 'running', progressPercent: 0, daysProcessed: 0, daysTotal: 2, orderCount: 0, detailCount: 0, created: 0, updated: 0, operatorName: '管理员', startedAt: '2026-08-24T08:00:00Z' }] : [];
return route.fulfill({ json: { code: 200, data: { items, total: items.length, page: 1, pageSize: 20 } } });
}
return route.fulfill({ json: { code: 200, data: [] } });
});
await page.goto('http://localhost:9527/#/syb-sync-runs/index');
const button = page.getByRole('button', { name: '立即同步' });
await expect(button).toBeVisible();
await button.click();
await expect(button).toBeDisabled();
await expect(page.getByText('已开始同步今天和昨天')).toBeVisible();
await expect(page.getByRole('button', { name: '同步进行中' })).toBeDisabled();
const now = new Date();
const yesterday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1);
const formatDate = (value: Date) => `${value.getFullYear()}-${String(value.getMonth() + 1).padStart(2, '0')}-${String(value.getDate()).padStart(2, '0')}`;
expect(importBody).toEqual({ dateFrom: formatDate(yesterday), dateTo: formatDate(now) });
});
test('SYB 定时任务可进入执行记录,其他任务不显示该入口', async ({ page, context }) => {
await authenticate(context);
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: [{ path: '/schedule', component: 'Layout', visible: '0', menuName: 'Schedule', title: '定时任务', icon: 'time', children: [{ path: 'index', component: '/schedule/index', visible: '0', menuName: 'SysJobManage', title: '定时任务', icon: 'time' }] }] } });
if (url.pathname.endsWith('/api/v1/sysjob')) return route.fulfill({ json: { code: 200, data: { list: [{ jobId: 1, jobName: 'SYB 每小时自动同步', jobGroup: 'GoAuto', cronExpression: '0 5 * * * *', invokeTarget: 'GoAutoSYBHourlySync', status: 2, entry_id: 10 }, { jobId: 2, jobName: '其他任务', jobGroup: 'DEFAULT', cronExpression: '0 0 * * * *', invokeTarget: 'OtherJob', status: 2, entry_id: 11 }], count: 2 } } });
if (url.pathname.endsWith('/api/admin/v1/syb-products/sync-runs')) return route.fulfill({ json: { code: 200, data: { items: [], total: 0, page: 1, pageSize: 20 } } });
return route.fulfill({ json: { code: 200, data: [] } });
});
await page.goto('http://localhost:9527/#/schedule/index');
await expect(page.getByText('SYB 每小时自动同步', { exact: true })).toBeVisible();
await expect(page.getByRole('button', { name: '执行记录', exact: true })).toHaveCount(1);
await page.getByRole('button', { name: '执行记录', exact: true }).click();
await expect(page).toHaveURL(/#\/syb-sync-runs\/index$/);
await expect(page.getByRole('heading', { name: 'SYB 同步记录' })).toBeVisible();
});