import { expect, test } from '@playwright/test'; const pddProductRoute = [{ path: '/goauto-order-workbench', component: 'Layout', menuName: 'GoAutoOrderWorkbench', title: '订单工作台', visible: '0', children: [{ path: '/pdd-products', component: '/goauto/pdd-products/index', menuName: 'GoAutoPddProducts', title: 'PDD 商品', visible: '0' }] }]; const product = { id: 1, goodsId: '972800403573', url: 'https://mobile.yangkeduo.com/goods.html?goods_id=972800403573', title: '夏季防晒冰丝袖套', shopName: '清凉优选店', salesCount: 1200, reviewCount: 36, status: 'active', collectionSelectable: true, specs: [ { name: '颜色分类', role: 'color', values: [{ name: '黑色', selectable: true, priceCent: 2590 }] }, { name: '尺码', role: 'size', values: [{ name: 'XL', selectable: true }] }, ], updatedAt: '2026-08-17T08:00:00Z', colorImages: [{ color: '黑色', imagePath: '/static/uploadfile/goauto-color/test.jpg' }], }; test('PDD 商品列表、详情和编辑流程符合已确认原型', async ({ page, context }) => { let updatePayload: any; await context.addCookies([{ name: 'Admin-Token', value: 'prototype-test-token', domain: 'localhost', path: '/' }]); await page.route('**/static/**', route => route.fulfill({ status: 200, contentType: 'image/png', body: Buffer.from('iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=', 'base64') })); await page.route('**/api/**', async route => { const url = new URL(route.request().url()); if (url.pathname.endsWith('/api/v1/menurole')) return route.fulfill({ json: { code: 200, data: pddProductRoute } }); if (url.pathname.startsWith('/src/api/')) { await route.continue(); return; } if (url.pathname.endsWith('/api/v1/getinfo')) { await route.fulfill({ json: { code: 200, data: { roles: ['admin'], name: '管理员', avatar: '', introduction: '', permissions: [] } } }); return; } if (url.pathname.endsWith('/api/admin/v1/pdd-products/1') && route.request().method() === 'PATCH') { updatePayload = route.request().postDataJSON(); await route.fulfill({ json: { code: 200, data: { product: { ...product, ...updatePayload } } } }); return; } if (url.pathname.endsWith('/api/admin/v1/pdd-products/1')) { await route.fulfill({ json: { code: 200, data: { product } } }); return; } if (url.pathname.endsWith('/api/admin/v1/pdd-products')) { await route.fulfill({ json: { code: 200, data: { items: [product, { ...product, id: 2, goodsId: '719834019024', title: '无图商品', colorImages: undefined }], total: 2, page: 1, pageSize: 20 } } }); return; } await route.fulfill({ json: { code: 200, data: [] } }); }); await page.goto('/#/pdd-products'); await expect(page.getByRole('button', { name: '添加', exact: true })).toBeVisible(); await expect(page.getByText('夏季防晒冰丝袖套')).toBeVisible(); await expect(page.getByText('¥25.90').first()).toBeVisible(); const listImage = page.getByRole('img', { name: '黑色颜色图,单击或双击查看大图' }).first() await listImage.click(); await expect(page.locator('.el-image-viewer__wrapper')).toBeVisible(); await page.locator('.el-image-viewer__close').click(); await listImage.dblclick(); await expect(page.locator('.el-image-viewer__wrapper')).toBeVisible(); await page.locator('.el-image-viewer__close').click(); await expect(page.getByRole('columnheader', { name: '颜色图' })).toBeVisible(); await expect(page.getByRole('columnheader', { name: '销量 / 评价' })).toHaveCount(0); await expect(page.getByText('暂无图片', { exact: true })).toBeVisible(); await page.getByRole('button', { name: '查看' }).first().click(); await expect(page.getByText('PDD 商品详情')).toBeVisible(); await expect(page.locator('.spec-title').filter({ hasText: '颜色分类' })).toBeVisible(); await expect(page.getByText('XL')).toBeVisible(); await expect(page.getByLabel('PDD 商品详情').getByText('1,200', { exact: true })).toBeVisible(); await expect(page.getByLabel('PDD 商品详情').getByText('36', { exact: true })).toBeVisible(); await page.getByRole('button', { name: '编辑商品' }).click(); await expect(page.getByText('编辑 PDD 商品')).toBeVisible(); await page.getByLabel('商品标题').fill('夏季防晒袖套(人工确认)'); await page.getByLabel('销量').fill('1300'); await page.getByLabel('评价数量').fill('40'); await page.getByRole('button', { name: '保存修改' }).click(); await expect.poll(() => updatePayload?.title).toBe('夏季防晒袖套(人工确认)'); expect(updatePayload.specs[0].values[0].priceCent).toBe(2590); expect(updatePayload.salesCount).toBe(1300); expect(updatePayload.reviewCount).toBe(40); }); test('带 productId 的 PDD 商品路由进入单商品定位并可通过查询退出', async ({ page, context }) => { let requestedProductId = ''; let listCalls = 0; const second = { ...product, id: 2, goodsId: '719834019024', title: '第二件商品' }; 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.endsWith('/api/v1/menurole')) return route.fulfill({ json: { code: 200, data: pddProductRoute } }); 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/pdd-products/1')) { requestedProductId = '1'; return route.fulfill({ json: { code: 200, data: { product } } }); } if (url.pathname.endsWith('/api/admin/v1/pdd-products')) { listCalls += 1; return route.fulfill({ json: { code: 200, data: { items: [product, second], total: 2, page: 1, pageSize: 20 } } }); } return route.fulfill({ json: { code: 200, data: [] } }); }); await page.goto('/#/pdd-products?productId=1'); await expect(page.getByText('PDD 商品详情')).toBeVisible(); await expect(page.locator('.el-drawer').getByText('夏季防晒冰丝袖套', { exact: true })).toBeVisible(); await expect(page.getByText('当前定位:PDD-1 / goods_id 972800403573', { exact: true })).toBeVisible(); await expect(page.getByText('第二件商品', { exact: true })).toHaveCount(0); await expect(page.getByText('共 1 条', { exact: true })).toBeVisible(); await expect(page.getByRole('button', { name: '查看全部 PDD 商品' })).toHaveCount(0); expect(requestedProductId).toBe('1'); expect(listCalls).toBe(0); await page.getByLabel('PDD 商品详情').getByLabel('关闭此对话框').click(); await expect(page.getByLabel('PDD 商品详情')).toBeHidden(); const locatedRow = page.locator('.el-table__body-wrapper tbody tr'); await expect(locatedRow.getByRole('checkbox')).toBeEnabled(); await locatedRow.locator('.el-checkbox').click(); await expect(page.getByText('已选择 1 条')).toBeVisible(); await expect(page.getByRole('button', { name: '创建采集 (1)', exact: true })).toBeEnabled(); await page.getByRole('button', { name: '查询', exact: true }).click(); await expect.poll(() => listCalls).toBe(1); await expect(page).toHaveURL(/#\/pdd-products$/); await expect(page.getByText('第二件商品', { exact: true })).toBeVisible(); await expect(page.getByText('共 2 条', { exact: true })).toBeVisible(); await expect(page.getByText('当前定位:PDD-1 / goods_id 972800403573', { exact: true })).toHaveCount(0); }); test('单商品定位的重置和无效编号不会误显示其他商品', async ({ page, context }) => { let listURL: URL | undefined; const second = { ...product, id: 2, goodsId: '719834019024', title: '第二件商品' }; 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.endsWith('/api/v1/menurole')) return route.fulfill({ json: { code: 200, data: pddProductRoute } }); 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/pdd-products/1')) return route.fulfill({ json: { code: 200, data: { product } } }); if (url.pathname.endsWith('/api/admin/v1/pdd-products')) { listURL = url; return route.fulfill({ json: { code: 200, data: { items: [product, second], total: 2, page: 1, pageSize: 20 } } }); } return route.fulfill({ json: { code: 200, data: [] } }); }); await page.goto('/#/pdd-products?productId=invalid'); await expect(page.getByText('PDD 商品编号无效', { exact: true })).toBeVisible(); await expect(page.getByText('972800403573', { exact: true })).toHaveCount(0); expect(listURL).toBeUndefined(); await page.getByRole('button', { name: '查询', exact: true }).click(); await expect.poll(() => listURL?.pathname).toBe('/api/admin/v1/pdd-products'); await expect(page.getByText('第二件商品', { exact: true })).toBeVisible(); listURL = undefined; await page.goto('/#/pdd-products?productId=1'); await page.reload(); await page.getByLabel('PDD 商品详情').getByLabel('关闭此对话框').click(); await expect(page.getByLabel('PDD 商品详情')).toBeHidden(); await page.getByPlaceholder('goods_id、标题或店铺').fill('不会保留'); await page.locator('.el-form-item').filter({ hasText: '状态' }).locator('.el-select').click(); await page.getByRole('option', { name: '正常' }).click(); await page.getByRole('button', { name: '重置', exact: true }).click(); await expect.poll(() => listURL?.searchParams.get('keyword')).toBe(''); expect(listURL?.searchParams.get('status')).toBe(''); await expect(page).toHaveURL(/#\/pdd-products$/); }); test('单商品定位对不可采集商品禁用勾选并显示原因', async ({ page, context }) => { const disabled = { ...product, status: 'disabled', collectionSelectable: false, collectionDisabledReason: '商品已停用' }; 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/menurole')) return route.fulfill({ json: { code: 200, data: pddProductRoute } }); 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/pdd-products/1')) return route.fulfill({ json: { code: 200, data: { product: disabled } } }); return route.fulfill({ json: { code: 200, data: [] } }); }); await page.goto('/#/pdd-products?productId=1'); await page.getByLabel('PDD 商品详情').getByLabel('关闭此对话框').click(); await expect(page.getByLabel('PDD 商品详情')).toBeHidden(); await expect(page.locator('.el-table__body-wrapper tbody tr').getByRole('checkbox')).toBeDisabled(); await expect(page.getByText('商品已停用', { exact: true })).toBeVisible(); await expect(page.getByRole('button', { name: '创建采集', exact: true })).toBeDisabled(); }); test('PDD 商品当前页多选并批量创建独立采集任务', async ({ page, context }) => { const second = { ...product, id: 2, goodsId: '719834019024', title: '第二件商品' }; const disabled = { ...product, id: 3, goodsId: '731370706977', title: '已停用商品', status: 'disabled', collectionSelectable: false, collectionDisabledReason: '商品已停用' }; let batchPayload: any; 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/menurole')) return route.fulfill({ json: { code: 200, data: pddProductRoute } }); 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/pdd-products')) return route.fulfill({ json: { code: 200, data: { items: [product, second, disabled], total: 3, page: 1, pageSize: 20 } } }); if (url.pathname.endsWith('/api/admin/v1/collection-rules')) return route.fulfill({ json: { code: 200, data: { items: [{ id: 9, name: 'PDD 商品详情采集' }], total: 1 } } }); if (url.pathname.endsWith('/api/admin/v1/devices')) return route.fulfill({ json: { code: 200, data: { items: [{ id: 4, name: 'samsung-SM-G9700', selectable: true }], total: 1 } } }); if (url.pathname.endsWith('/api/admin/v1/collection-tasks/batch')) { batchPayload = route.request().postDataJSON(); return route.fulfill({ json: { code: 200, data: { successCount: 1, failureCount: 1, items: [{ pddProductId: 1, success: true, taskId: 101 }, { pddProductId: 2, success: false, code: 'PDD_PRODUCT_TASK_ACTIVE', message: '该商品已有待执行或执行中的任务' }] } } }); } return route.fulfill({ json: { code: 200, data: [] } }); }); await page.goto('/#/pdd-products'); const rows = page.locator('.el-table__body-wrapper tbody tr'); await rows.nth(0).locator('.el-checkbox').click(); await rows.nth(1).locator('.el-checkbox').click(); await expect(rows.nth(2).getByRole('checkbox')).toBeDisabled(); await expect(page.getByText('已选择 2 条')).toBeVisible(); await page.getByRole('button', { name: '创建采集 (2)', exact: true }).click(); await page.getByLabel('采集规则').click(); await page.getByRole('option', { name: 'PDD 商品详情采集' }).click(); await page.getByRole('button', { name: '创建 2 个采集任务' }).click(); await expect.poll(() => batchPayload?.pddProductIds).toEqual([1, 2]); expect(batchPayload.ruleId).toBe(9); expect(batchPayload.deviceId).toBeNull(); await expect(page.getByText('创建完成:成功 1 个,失败 1 个')).toBeVisible(); await expect(page.getByText('采集任务 #101')).toBeVisible(); await expect(page.getByText('该商品已有待执行或执行中的任务')).toBeVisible(); });