align(重复检测): DuplicateCheckPage 像素级复刻 reference asin-store-console
撞款控制台整页复刻 reference 观感:引入页面独立 reference 令牌(#2E5BE6 主蓝/#D63A4A 红/#F2F4F8 底)落到 KPI 色点/矩阵单元格/撞款卡/台账 chips;撞款覆盖矩阵与全部ASIN台账改原生表格(台账20条/页+共N条/上一页/下一页/跳至N页分页条,列头服务端排序▲/▼);筛选改原生 input/select/date;明细抽屉+底部 toast 复刻 reference(原生 mask/drawer/d-table 汇总徽章);分组说明只读(归属来自店铺管理)。 数据源保持自家 /api/admin/shop-data-crawl/duplicate-check-console|-ledger|-export 不变。 验收:mock-admin-server 补 console/ledger 夹具;新增 e2e dup-console.spec(渲染/台账切换/令牌色值/矩阵台账结构断言+截图);align-dup-console/align-column-width 断言随原生表格调整;前端 1552 测试全绿 + vue-tsc/build 通过。
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
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 })
|
||||
await expect(page.locator('.pager')).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、弱红底、单元底色等。
|
||||
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(46, 91, 230)')
|
||||
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' })
|
||||
})
|
||||
Reference in New Issue
Block a user