Files
ycode/scripts/library-ui-regression.tsx
T

165 lines
6.2 KiB
TypeScript

import assert from 'node:assert/strict'
import { promises as fs } from 'node:fs'
import { resolve } from 'node:path'
import { renderToStaticMarkup } from 'react-dom/server'
import type { LibrarySnapshot } from '../src/shared/library'
import type { LibraryArtifactEntry } from '../src/shared/library'
import LibraryPage, {
LibraryHomeContent,
LocalArtifactsView,
relativeTimeLabel
} from '../src/renderer/src/library/LibraryPageParity'
import { groupLibraryEntries } from '../src/renderer/src/library/catalog'
const now = Date.UTC(2026, 9, 17, 12, 0, 0)
const entry: LibraryArtifactEntry = {
id: 'artifact:session-a:report',
sessionId: 'session-a',
workspaceId: 'workspace-a',
workspaceName: 'YCode',
workspaceRoot: 'C:\\workspace',
sourceSessionTitle: '查看当前项目',
messageId: 'message-a',
sourceKind: 'write',
name: 'project-report.md',
path: 'C:\\workspace\\project-report.md',
kind: 'document',
availability: 'available',
size: 11_264,
createdAt: now - 4_000,
updatedAt: now - 60_000,
recentAt: now - 120_000,
favorite: true
}
const snapshot: LibrarySnapshot = {
artifacts: [entry],
generatedAt: now
}
const api = {
async getSnapshot(): Promise<LibrarySnapshot> {
return snapshot
},
async setFavorite() {
return { version: 1 as const, favoriteArtifactIds: [entry.id], recent: [] }
},
async recordRecent() {
return { version: 1 as const, favoriteArtifactIds: [entry.id], recent: [] }
}
}
async function main(): Promise<void> {
const homePage = renderToStaticMarkup(
<LibraryPage api={api} onOpenArtifact={() => undefined} />
)
assert.match(homePage, /class="library-page library-page--home"/)
assert.match(homePage, /class="library-sidebar knowledge-sidebar-pc"/)
assert.match(homePage, /最近访问/)
assert.match(homePage, /我分享的/)
assert.match(homePage, /与我共享/)
assert.match(homePage, /个人资料尚未接入/)
assert.match(homePage, /团队资料尚未接入/)
assert.doesNotMatch(homePage, /library-local-panel/)
const homeContent = renderToStaticMarkup(
<LibraryHomeContent
entries={[entry]}
kind="all"
loading={false}
sidebarCollapsed={false}
onToggleSidebar={() => undefined}
onKindChange={() => undefined}
onOpen={() => undefined}
/>
)
assert.match(homeContent, /class="library-home-main main-layout-content-pc"/)
assert.match(homeContent, />名称</)
assert.match(homeContent, />所有者</)
assert.match(homeContent, />位置</)
assert.match(homeContent, />最近访问</)
assert.match(homeContent, /project-report\.md/)
assert.match(homeContent, /了解资料库/)
assert.equal(
(homeContent.match(/class="wb-home-guide-card-illustration-pc library-guide__illustration"/g) ?? []).length,
2
)
assert.doesNotMatch(homeContent, /library-robot-shell/)
const groups = groupLibraryEntries([entry])
const local = renderToStaticMarkup(
<LocalArtifactsView
entries={[entry]}
groups={groups}
kind="all"
query=""
sort={{ key: 'updatedAt', direction: 'desc' }}
favoritesOnly={false}
favoriteCount={1}
loading={false}
searchInputRef={{ current: null }}
collapsedWorkspaces={new Set()}
collapsedTasks={new Set()}
onBack={() => undefined}
onKindChange={() => undefined}
onQueryChange={() => undefined}
onFavoritesOnlyChange={() => undefined}
onSort={() => undefined}
onToggleWorkspace={() => undefined}
onToggleTask={() => undefined}
onOpen={() => undefined}
onFavorite={() => undefined}
/>
)
assert.match(local, /class="library-local-panel my-files-panel"/)
assert.match(local, /aria-label="返回资料库"/)
assert.match(local, /搜索文件、任务或工作空间/)
assert.match(local, />类型</)
assert.match(local, />更新人</)
assert.match(local, />更新时间</)
assert.match(local, />大小</)
assert.match(local, /role="table" aria-label="本地产物列表"/)
assert.match(local, /role="rowgroup"/)
assert.match(local, /role="row"/)
assert.match(local, /role="columnheader"/)
assert.match(local, /role="cell"/)
assert.match(local, /aria-label="更新人,未知">—</)
assert.doesNotMatch(local, /<th\b/)
assert.match(local, /class="library-file-row /)
assert.match(local, /class="library-file-button /)
assert.equal((local.match(/class="my-files-list-action-btn"/g) ?? []).length, 2)
assert.equal((local.match(/class="my-files-list-action-wrapper"/g) ?? []).length, 2)
assert.doesNotMatch(local, /class="library-favorite |class="library-open-action/)
assert.equal((local.match(/class="my-files-flat-sort-icon"/g) ?? []).length, 1)
assert.match(local, /class="my-files-flat-sort-icon desc"/)
assert.doesNotMatch(local, /knowledge-sidebar-pc/)
assert.equal(relativeTimeLabel(now - 30_000, now), '刚刚')
assert.equal(relativeTimeLabel(now - 2 * 60_000, now), '2分钟前')
assert.equal(relativeTimeLabel(now - 3 * 60 * 60_000, now), '3小时前')
assert.equal(relativeTimeLabel(now - 2 * 24 * 60 * 60_000, now), '2天前')
const css = await fs.readFile(resolve('src/renderer/src/library/library.css'), 'utf8')
assert.match(
css,
/--library-font-family: "PingFang SC", -apple-system, BlinkMacSystemFont, sans-serif;/
)
assert.match(css, /\.library-page--home\.is-sidebar-collapsed,\s*\.library-page--local \{\s*grid-template-columns: minmax\(0, 1fr\);/)
assert.match(css, /grid-template-columns: var\(--library-sidebar-width\) minmax\(0, 1fr\);/)
assert.match(css, /\.library-local-column \{\s*width: 100px;/)
assert.match(css, /\.library-file-row \{\s*height: 46px;/)
assert.match(css, /\.library-sidebar-nav \{\s*[\s\S]*?padding: 2px 12px 10px;/)
assert.match(css, /\.library-page \.library-nav-item \{\s*box-sizing: border-box;\s*padding: 4px 12px;/)
assert.match(css, /\.library-page \.library-type-button \{\s*box-sizing: border-box;[\s\S]*?border: 1px solid var\(--library-border\);/)
assert.match(css, /\.my-files-flat-sort-icon\.asc,[\s\S]*?opacity: 1;/)
assert.match(css, /\.library-page \.my-files-list-action-btn \{[\s\S]*?width: 28px;\s*height: 28px;/)
console.log('library-ui-regression: ok')
}
main().catch((error) => {
console.error(error)
process.exitCode = 1
})