Files
crawler-plugin/admin-frontend-vue/e2e/dup-console.spec.ts
T
huangzd1997 fd614004b0 fix(撞款e2e): 台账分页断言限定到台账表格紧邻分页器
台账 tab 下页面同时有「店铺上架分布」分页器(设计要求常显)与台账分页器,
全页 .old-pagination 命中 2 个元素触发 strict mode;断言改为 .table-wrap + .old-pagination,
用例意图不变(台账分页可见)。撞款 4 用例全绿,全量 e2e 44 通过(通知面板 1 例失败系并行会话在改 NotificationBell.vue,与本改动无关)。
2026-09-14 00:25:19 +08:00

98 lines
5.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { existsSync } from 'node:fs'
import { pathToFileURL } from 'node:url'
import { expect, test } from '@playwright/test'
// 撞款控制台(DuplicateCheckPage)像素级复刻 reference asin-store-console 的真浏览器验收:
// mock 后端跑真实数据渲染,无 pageerror;并截图本页与 reference 离线页供人工比对。
const REFERENCE = 'D:\\todesk\\副业\\数富AI\\crawler-plugin\\reference\\asin-store-console\\asin-store-console\\index.html'
test('test_dup_console_render_dup_tab_normal_primary_path', async ({ page }) => {
const errors: string[] = []
page.on('pageerror', (error) => errors.push(error.message))
await page.goto('/admin-vue/shop-center/duplicate-check')
await expect(page.locator('.dup-head h2')).toHaveText('店铺数据撞款监控')
// KPI + 矩阵行 + 撞款卡片都渲染出真实 mock 数据
await expect(page.locator('.kpi')).toHaveCount(7)
await expect(page.locator('table.matrix tbody tr').first()).toBeVisible({ timeout: 15000 })
await expect(page.locator('.dup-card').first()).toBeVisible()
// 分组撞款:切到「分组撞款」出现分组 chips
await page.getByRole('button', { name: /分组撞款/ }).click()
await expect(page.locator('.g-chip').first()).toBeVisible()
expect(errors).toEqual([])
await page.screenshot({ path: 'test-results/dup-console-admin-dup.jpg' })
})
test('test_dup_console_render_ledger_tab_normal_variant_input', async ({ page }) => {
const errors: string[] = []
page.on('pageerror', (error) => errors.push(error.message))
await page.goto('/admin-vue/shop-center/duplicate-check')
await expect(page.locator('.dup-head h2')).toHaveText('店铺数据撞款监控')
await page.getByRole('button', { name: /全部ASIN台账/ }).click()
await expect(page.locator('table.ledger tbody tr').first()).toBeVisible({ timeout: 15000 })
// 台账 tab 下页面同时有「店铺上架分布」分页器(常显,见 tests/align-dup-console.test.ts)与台账分页器,
// 全页 .old-pagination 会命中 2 个元素触发 strict mode;限定到台账表格(.table-wrap)紧邻的分页器。
await expect(page.locator('.table-wrap + .old-pagination')).toBeVisible()
expect(errors).toEqual([])
await page.locator('.table-wrap').screenshot({ path: 'test-results/dup-console-admin-ledger.jpg' })
})
test('test_dup_console_palette_matches_reference_tokens', async ({ page }) => {
// reference 设计令牌在页面落定:主蓝 #2E5BE6、红 #D63A4A、弱红底、单元底色等(按钮蓝白统一为 #4f78a5)。
await page.goto('/admin-vue/shop-center/duplicate-check')
await expect(page.locator('.kpi')).toHaveCount(7)
const got = await page.evaluate(() => {
const cs = (sel, prop) => {
const el = document.querySelector(sel)
return el ? getComputedStyle(el)[prop] : null
}
return {
btnPrimary: cs('.btn-primary', 'backgroundColor'),
btnPrimaryColor: cs('.btn-primary', 'color'),
kpiDanger: cs('.kpi.danger .k-value', 'color'),
kpiPrimary: cs('.kpi.primary .k-value', 'color'),
mCell: cs('.m-cell', 'backgroundColor'),
mCellText: cs('.m-cell', 'color'),
badgeDup: cs('.badge.dup', 'backgroundColor'),
badgeSingle: cs('.badge.single', 'backgroundColor'),
kSub: cs('.kpi .k-sub', 'color'),
selectBorder: cs('.f-group select', 'borderColor'),
kDotDanger: cs('.kpi.danger .k-dot', 'backgroundColor'),
}
})
expect(got.btnPrimary).toBe('rgb(79, 120, 165)') // 全站按钮主色统一 #4f78a5d385d999 起)
expect(got.btnPrimaryColor).toBe('rgb(255, 255, 255)')
expect(got.kpiDanger).toBe('rgb(214, 58, 74)')
expect(got.kpiPrimary).toBe('rgb(46, 91, 230)')
expect(got.mCell).toBe('rgb(234, 240, 255)')
expect(got.mCellText).toBe('rgb(46, 91, 230)')
expect(got.badgeDup).toBe('rgb(253, 235, 237)')
expect(got.badgeSingle).toBe('rgb(231, 247, 239)')
expect(got.kSub).toBe('rgb(152, 161, 177)')
expect(got.selectBorder).toBe('rgb(213, 219, 230)')
expect(got.kDotDanger).toBe('rgb(214, 58, 74)')
})
test('test_dup_console_structure_matches_reference', async ({ page }) => {
// 结构对齐:矩阵列=可见店铺数、台账列=reference 10 列、分组说明抽屉内 4 列。
await page.goto('/admin-vue/shop-center/duplicate-check')
await expect(page.locator('.kpi')).toHaveCount(7)
await expect(page.locator('table.matrix tbody tr').first()).toBeVisible({ timeout: 15000 })
const matrixHeaders = await page.locator('table.matrix thead th').count()
expect(matrixHeaders).toBe(8) // ASIN + 品牌 + 6 家店
await page.getByRole('button', { name: /全部ASIN台账/ }).click()
await expect(page.locator('table.ledger tbody tr').first()).toBeVisible({ timeout: 15000 })
const ledgerHeaders = await page.locator('table.ledger thead th').count()
expect(ledgerHeaders).toBe(10)
})
test('test_dup_console_reference_screenshot', async ({ page }) => {
// reference 离线原型截图:仅供人工像素比对(不接入应用路由)。
test.skip(!existsSync(REFERENCE), 'reference 原型不在本机,跳过比对')
await page.goto(pathToFileURL(REFERENCE).href)
await expect(page.locator('.kpi').first()).toBeVisible({ timeout: 15000 })
await page.screenshot({ path: 'test-results/dup-console-reference.jpg' })
})