feat(SPA): schema list and the sidebar Content group
This commit is contained in:
1 parent
73a75d5cb9
commit
3c67cd2314
34 files changed
+2181
-18
No files matched your search
+32
-6
@@ -418,6 +418,10 @@ const settleMs = 400
|
||||
const diffThreshold = 24
|
||||
const maxDiffPercent = 10
|
||||
|
||||
const shellApi: Record<string, ApiMock> = {
|
||||
'GET /v1/content-type': { status: 200, body: [] },
|
||||
}
|
||||
|
||||
function budgetFor(cap: DiffException['maxPercent'] | undefined, viewport: Viewport) {
|
||||
if (cap === undefined) {
|
||||
return maxDiffPercent
|
||||
@@ -595,6 +599,15 @@ function groupSectionRows(markdown: string, group: string) {
|
||||
return [...section.matchAll(/^\| \d+ \| ([^|]+?) \|/gm)].map((match) => match[1]!.trim())
|
||||
}
|
||||
|
||||
const boardGroupLabels: Record<string, Record<string, string>> = {
|
||||
schema: {
|
||||
'Schema list': '1 Schema list',
|
||||
'Schema builder': '2 Schema builder',
|
||||
'Review and delete': '3 Review and delete',
|
||||
'Field types': '4 Field types',
|
||||
},
|
||||
}
|
||||
|
||||
const referenceGroups: Record<string, string> = {
|
||||
'integration-api-keys': 'API keys',
|
||||
}
|
||||
@@ -614,7 +627,9 @@ async function readScreen(name: string): Promise<Screen> {
|
||||
if (!reference) {
|
||||
throw new Error(`docs/design/screens/${name}.md has no visual reference line`)
|
||||
}
|
||||
const referenceGroups = [...reference[2]!.matchAll(/"([^"]+)"/g)].map((match) => match[1]!)
|
||||
const referenceGroups = [...reference[2]!.matchAll(/"([^"]+)"/g)].map(
|
||||
(match) => boardGroupLabels[name]?.[match[1]!] ?? match[1]!,
|
||||
)
|
||||
const numberedRows = [...markdown.matchAll(/^\| \d+ \| ([^|]+?) \|/gm)].map((match) =>
|
||||
match[1]!.trim(),
|
||||
)
|
||||
@@ -813,7 +828,14 @@ async function captureDesign(
|
||||
const title = headers.find(
|
||||
(div) => div.querySelector('span')?.textContent?.trim() === state,
|
||||
)
|
||||
const block = title?.parentElement
|
||||
const wideBlock = section
|
||||
? [...section.querySelectorAll<HTMLElement>('div')].find(
|
||||
(div) =>
|
||||
div.style.width === '1037px' &&
|
||||
div.querySelector('span > .sc-interp')?.textContent?.trim() === state,
|
||||
)
|
||||
: undefined
|
||||
const block = title ? title.parentElement : wideBlock
|
||||
const target = block
|
||||
? [...block.querySelectorAll<HTMLElement>('div')].find(
|
||||
(div) => div.style.width === `${width}px`,
|
||||
@@ -890,6 +912,7 @@ async function captureApp(
|
||||
})
|
||||
await serveIconsLocally(context)
|
||||
const unmocked = new Set<string>()
|
||||
const fallback = new Set<string>()
|
||||
const calls = new Map<string, number>()
|
||||
await context.route('**/v1/**', async (route) => {
|
||||
const request = route.request()
|
||||
@@ -897,7 +920,10 @@ async function captureApp(
|
||||
const key = `${request.method()} ${url.pathname}`
|
||||
const call = (calls.get(key) ?? 0) + 1
|
||||
calls.set(key, call)
|
||||
const mock = setup.api?.[key]
|
||||
const mock = setup.api?.[key] ?? shellApi[key]
|
||||
if (mock && !setup.api?.[key]) {
|
||||
fallback.add(key)
|
||||
}
|
||||
if (!mock) {
|
||||
unmocked.add(key)
|
||||
await route.fulfill({ status: 404, body: '' })
|
||||
@@ -932,7 +958,7 @@ async function captureApp(
|
||||
await page.waitForTimeout(settleMs)
|
||||
await page.screenshot({ path, animations: 'disabled' })
|
||||
await context.close()
|
||||
return [...unmocked]
|
||||
return { unmocked: [...unmocked], fallback: [...fallback] }
|
||||
}
|
||||
|
||||
async function diff(browser: Browser, designPath: string, appPath: string, diffPath: string) {
|
||||
@@ -1053,7 +1079,7 @@ async function main() {
|
||||
|
||||
const appPath = join(directory, `app-${suffix}`)
|
||||
const diffPath = join(directory, `diff-${suffix}`)
|
||||
const unmocked = await captureApp(
|
||||
const { unmocked, fallback } = await captureApp(
|
||||
browser,
|
||||
app.origin,
|
||||
setup,
|
||||
@@ -1080,7 +1106,7 @@ async function main() {
|
||||
? ` [exception ${describeCap(setup.exception.maxPercent)} approved by ${setup.exception.approvedBy}: ${setup.exception.reason}]`
|
||||
: ''
|
||||
lines.push(
|
||||
`${problems.length ? 'FAIL' : 'PASS'} ${state} · ${viewport} · ${theme}: ${percent.toFixed(2)}% pixels differ → ${relative(repoRoot, directory)}${problems.length ? ` (${problems.join('; ')})` : ''}${exception}`,
|
||||
`${problems.length ? 'FAIL' : 'PASS'} ${state} · ${viewport} · ${theme}: ${percent.toFixed(2)}% pixels differ → ${relative(repoRoot, directory)}${problems.length ? ` (${problems.join('; ')})` : ''}${exception}${fallback.length ? ` [shellApi fallback: ${fallback.join(', ')}]` : ''}`,
|
||||
)
|
||||
}
|
||||
await board.context().close()
|
||||
|
||||
Reference in new issue
Block a user