Files
goauto/web/tests/e2e/collection-rule-editor.spec.ts
T

66 lines
5.5 KiB
TypeScript

import { test, expect } from '@playwright/test'
const template = {
schemaVersion: 2,
ruleType: 'pddProductDetail',
navigation: { steps: [
{ id: 'browser-open-pdd', page: 'browser', packageName: 'com.heytap.browser', action: 'click', selector: { text: '打开拼多多APP' }, timeoutMs: 15000, optional: true },
{ id: 'system-open', page: 'system-confirm', packageName: 'android', action: 'click', selector: { text: '打开' }, timeoutMs: 8000, optional: true },
] },
pageEvidence: { packageName: 'com.xunmeng.pinduoduo', activityName: 'com.xunmeng.pinduoduo.activity.NewPageActivity', selector: { resourceId: 'android:id/content', className: 'android.widget.FrameLayout' } },
navigationRecovery: { reopenBrowser: { enabled: true, maxAttempts: 1, settleMs: 1000 } },
pageRecovery: { transientSoldOut: { enabled: true, exactText: '商品已售罄', fallbackTopText: '相似商品', pullDownCount: 2, intervalMs: 1000, settleMs: 2000, maxAttempts: 1 } },
hooks: { afterSpecPanelOpen: [] },
collector: {
collectorId: 'pddProductDetailV1', specEntryStrategy: 'safeBottomSpecEntryV1', priceParser: 'pddRmbPriceV1', priceGranularity: 'color',
dimensionAliases: { color: ['颜色分类', '颜色'], size: ['尺码', '尺寸'] },
timeoutsMs: { page: 30000, specPanel: 10000, selection: 2000, price: 2000, overall: 180000 },
limits: { goodsPageVerticalSwipes: 3, specHorizontalSwipes: 12, specVerticalSwipes: 12, stableEdgeReads: 2, stablePriceReads: 2, maxSkuCount: 500 },
},
}
test('v2 rule uses safe form and read-only JSON preview', async ({ page, context }) => {
await context.addCookies([{ name: 'Admin-Token', value: 'test-token', domain: 'localhost', path: '/' }])
await page.route('**/api/v1/getinfo', route => route.fulfill({ json: { code: 200, data: { roles: ['admin'], name: 'admin', avatar: '', introduction: '', permissions: [] } } }))
await page.route('**/api/v1/menurole', route => route.fulfill({ json: { code: 200, data: [] } }))
await page.route('**/api/admin/v1/collection-rules/templates/pdd-product-detail-v1', route => route.fulfill({ json: { code: 200, data: { templateId: 'pdd-product-detail-v1', name: 'PDD 商品详情采集 v2', content: template } } }))
await page.route(/\/api\/admin\/v1\/collection-rules\?(?!.*templates).*/, route => route.fulfill({ json: { code: 200, data: { items: [], total: 0, page: 1, pageSize: 20 } } }))
await page.goto('/#/collection-rules/index')
await expect(page.getByRole('heading', { name: '采集规则' })).toBeVisible()
await page.getByRole('button', { name: '创建 PDD 采集规则' }).click()
await expect(page.getByRole('heading', { name: '页面识别' })).toBeVisible()
await expect(page.getByRole('heading', { name: '规格维度别名' })).toBeVisible()
await expect(page.getByRole('heading', { name: '超时设置' })).toBeVisible()
await expect(page.getByRole('heading', { name: '遍历上限' })).toBeVisible()
await expect(page.getByRole('heading', { name: '商品页假售罄恢复' })).toBeVisible()
await expect(page.getByRole('heading', { name: '商品详情进入恢复' })).toBeVisible()
await expect(page.getByText('固定能力 v1')).toBeVisible()
await expect(page.locator('.json-editor')).toHaveCount(0)
await page.getByText('查看只读 JSON 预览').click()
await expect(page.locator('.json-preview-block')).toContainText('pddProductDetailV1')
await expect(page.locator('.json-preview-block')).toContainText('商品已售罄')
await expect(page.locator('.json-preview-block')).toContainText('相似商品')
await expect(page.locator('.json-preview-block')).toContainText('reopenBrowser')
await expect(page.locator('.json-preview-block')).not.toContainText('提交订单')
await expect(page.getByRole('button', { name: '保存并立即生效' })).toBeEnabled()
})
test('task detail shows structured color prices and v2 snapshot', async ({ page, context }) => {
await context.addCookies([{ name: 'Admin-Token', value: 'test-token', domain: 'localhost', path: '/' }])
await page.route('**/api/v1/getinfo', route => route.fulfill({ json: { code: 200, data: { roles: ['admin'], name: 'admin', avatar: '', introduction: '', permissions: [] } } }))
await page.route('**/api/v1/menurole', route => route.fulfill({ json: { code: 200, data: [] } }))
const task = { id: 88, goodsIdSnapshot: '719834019024', ruleName: 'PDD 商品详情采集', deviceName: 'OPPO-PKG110', status: 'completed_partial', createdAt: '2026-08-15T00:00:00Z', title: '测试商品', shopName: '测试旗舰店', salesText: '已拼100件', reviewCount: 20, ruleSnapshot: JSON.stringify(template) }
await page.route(/\/api\/admin\/v1\/collection-tasks\?.*/, route => route.fulfill({ json: { code: 200, data: { items: [task], total: 1, page: 1, pageSize: 20 } } }))
await page.route('**/api/admin/v1/collection-tasks/88', route => route.fulfill({ json: { code: 200, data: { task, dimensions: [{ key: 'color', name: '颜色', values: ['红色'] }], colorPrices: [{ color: '红色', priceCent: 1099 }], skus: [{ specs: { color: '红色' }, priceCent: 1099, complete: false }], missing: ['size'] } } }))
await page.goto('/#/collection-tasks/index')
await expect(page.getByText('719834019024')).toBeVisible()
await page.getByRole('button', { name: '详情' }).click()
await expect(page.getByRole('heading', { name: '颜色价格' })).toBeVisible()
await expect(page.getByText('¥10.99').first()).toBeVisible()
await page.getByText('查看本任务规则快照').click()
await expect(page.locator('.snapshot-json')).toContainText('pddProductDetailV1')
})