Files
goauto/web/tests/e2e/syb-shop-module.spec.ts
T

82 lines
5.4 KiB
TypeScript

import { expect, test } from '@playwright/test';
const shops = [
{ id: 1, displayName: '晨曦优选店', normalizedName: '晨曦优选店', enabled: true, lastSeenAt: '2026-08-20T02:00:00Z', lastSeenOrderCount: 126, updatedAt: '2026-08-20T02:00:00Z' },
{ id: 2, displayName: 'ABC服饰', normalizedName: 'abc服饰', enabled: false, lastSeenAt: null, lastSeenOrderCount: null, updatedAt: '2026-08-19T02:00:00Z' },
];
async function mockPage(page: any, context: any, roles: string[]) {
const calls: { creates: any[]; enabled: any[] } = { creates: [], enabled: [] };
await context.addCookies([{ name: 'Admin-Token', value: 'prototype-test-token', domain: 'localhost', path: '/' }]);
await page.route('**/api/**', async (route: any) => {
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, name: roles.includes('admin') ? '管理员' : '采购员', avatar: '', introduction: '', permissions: [] } } });
if (url.pathname.endsWith('/api/admin/v1/syb-shops/discover')) return route.fulfill({ json: { code: 200, data: { items: [{ displayName: '新发现店铺', orderCount: 38, status: 'new' }, { displayName: '晨曦优选店', orderCount: 126, status: 'enabled' }] } } });
if (url.pathname.endsWith('/api/admin/v1/syb-shops') && route.request().method() === 'POST') {
calls.creates.push(route.request().postDataJSON());
return route.fulfill({ json: { code: 200, data: { id: 3, ...route.request().postDataJSON() } } });
}
if (url.pathname.endsWith('/api/admin/v1/syb-shops/2/enabled')) {
calls.enabled.push(route.request().postDataJSON());
return route.fulfill({ json: { code: 200, data: { ...shops[1], ...route.request().postDataJSON() } } });
}
if (url.pathname.endsWith('/api/admin/v1/syb-shops')) return route.fulfill({ json: { code: 200, data: { items: shops, total: 2, enabledCount: 1, page: 1, pageSize: 20 } } });
return route.fulfill({ json: { code: 200, data: [] } });
});
return calls;
}
test('管理员可以发现、添加并启用 SYB 店铺', async ({ page, context }) => {
const calls = await mockPage(page, context, ['admin']);
await page.goto('http://localhost:9527/#/syb-shops/index');
await expect(page.getByText('晨曦优选店').first()).toBeVisible();
await expect(page.getByText('已启用 1 个')).toBeVisible();
await page.getByRole('button', { name: '从 SYB 发现店铺', exact: true }).click();
await page.getByRole('button', { name: '开始发现' }).click();
const dialog = page.getByRole('dialog', { name: '从 SYB 发现店铺' });
const rows = dialog.locator('.el-table__body-wrapper tbody tr');
await rows.nth(0).locator('.el-checkbox').click();
await expect(rows.nth(1).getByRole('checkbox')).toBeDisabled();
await dialog.getByRole('button', { name: '添加选中的 1 家店铺' }).click();
await expect.poll(() => calls.creates).toEqual([{ displayName: '新发现店铺', enabled: true }]);
await dialog.getByRole('button', { name: '关闭此对话框' }).click();
await page.locator('.el-table__body-wrapper tbody tr').filter({ hasText: 'ABC服饰' }).locator('.el-switch').click();
await expect.poll(() => calls.enabled).toEqual([{ enabled: true }]);
});
test('采购员查看店铺时配置控件保持只读', async ({ page, context }) => {
await mockPage(page, context, ['purchaser']);
await page.goto('http://localhost:9527/#/syb-shops/index');
await expect(page.getByText('当前账号只有查看权限')).toBeVisible();
await expect(page.getByRole('button', { name: '从 SYB 发现店铺', exact: true })).toBeDisabled();
await expect(page.getByRole('button', { name: '新增店铺' })).toBeDisabled();
await expect(page.locator('.el-table').getByRole('switch')).toHaveCount(0);
await expect(page.getByText('已启用', { exact: true }).first()).toBeVisible();
await expect(page.getByText('只读').first()).toBeVisible();
});
test('没有启用店铺时从 SYB 导入在前端预检阶段停止', async ({ page, context }) => {
let importCalled = false;
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-shops')) return route.fulfill({ json: { code: 200, data: { items: [], total: 0, enabledCount: 0, page: 1, pageSize: 1 } } });
if (url.pathname.endsWith('/api/admin/v1/syb-products/import')) {
importCalled = true;
return route.fulfill({ json: { code: 500, message: '不应调用' } });
}
if (url.pathname.endsWith('/api/admin/v1/syb-products')) 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/#/syb-products/index');
await page.getByRole('button', { name: '从 SYB 导入' }).click();
await expect(page.getByRole('dialog', { name: '无法导入' })).toContainText('还没有启用任何店铺');
expect(importCalled).toBe(false);
});