release: bump version to 0.73.0
Some checks failed
ci / backend (push) Has been cancelled
ci / frontend (push) Has been cancelled
ci / delivery (push) Has been cancelled
release / images (push) Has been cancelled

This commit is contained in:
linkong
2026-06-29 17:04:05 +08:00
parent 19d5ac0fee
commit fbecf30513
41 changed files with 2306 additions and 311 deletions

View File

@@ -182,7 +182,7 @@ function loadAdminManifestNavigationEntries() {
}
const entries = []
const routePattern = /\{\s*path:\s*'([^']+)',\s*label:\s*'([^']+)',\s*group:\s*'([^']+)'/g
const routePattern = /\{\s*path:\s*'([^']+)',\s*label:\s*'([^']+)'.*?\bgroup:\s*'([^']+)'/gs
for (const match of routesBlock.matchAll(routePattern)) {
const groupLabel = groupLabels.get(match[3])
if (!groupLabel) {
@@ -487,6 +487,82 @@ async function checkNoGlobalHorizontalOverflow(page, route) {
}
}
async function checkAdminShellOneScreen(page, route, options = {}) {
const { expectAccountVisible = false, expectPreferencesVisible = false } = options
const layout = await page.evaluate(() => {
const rectFor = (selector) => {
const element = document.querySelector(selector)
if (!element) return null
const rect = element.getBoundingClientRect()
return {
top: rect.top,
bottom: rect.bottom,
height: rect.height,
clientHeight: element.clientHeight,
scrollHeight: element.scrollHeight,
}
}
const root = rectFor('#root')
const admin = rectFor('.admin')
const account = rectFor('.admin__account')
const preferences = rectFor('.admin__preferences-panel')
return {
viewportHeight: window.innerHeight,
documentOverflowY: document.documentElement.scrollHeight - document.documentElement.clientHeight,
bodyOverflowY: document.body.scrollHeight - document.body.clientHeight,
rootOverflowY: root ? root.scrollHeight - root.clientHeight : 0,
root,
admin,
account,
preferences,
}
})
if (!layout.admin) return
const tolerance = 2
const failures = []
const adminHeightDelta = Math.abs(layout.admin.height - layout.viewportHeight)
if (adminHeightDelta > tolerance) {
failures.push(
`.admin height ${layout.admin.height.toFixed(2)}px does not match viewport ${layout.viewportHeight}px`,
)
}
if (layout.admin.bottom > layout.viewportHeight + tolerance || layout.admin.top < -tolerance) {
failures.push(
`.admin escapes viewport (top=${layout.admin.top.toFixed(2)}, bottom=${layout.admin.bottom.toFixed(2)})`,
)
}
if (layout.rootOverflowY > tolerance) {
failures.push(`#root vertical overflow ${layout.rootOverflowY}px`)
}
if (layout.documentOverflowY > tolerance || layout.bodyOverflowY > tolerance) {
failures.push(
`document/body vertical overflow document=${layout.documentOverflowY}px body=${layout.bodyOverflowY}px`,
)
}
if (expectAccountVisible && layout.account) {
if (layout.account.top < -tolerance || layout.account.bottom > layout.viewportHeight + tolerance) {
failures.push(
`.admin__account is not fully in the first viewport ` +
`(top=${layout.account.top.toFixed(2)}, bottom=${layout.account.bottom.toFixed(2)})`,
)
}
}
if (expectPreferencesVisible && layout.preferences) {
if (layout.preferences.top < -tolerance || layout.preferences.bottom > layout.viewportHeight + tolerance) {
failures.push(
`.admin__preferences-panel is not fully in the first viewport ` +
`(top=${layout.preferences.top.toFixed(2)}, bottom=${layout.preferences.bottom.toFixed(2)})`,
)
}
}
if (failures.length) {
throw new Error(`${route}: admin shell one-screen check failed: ${failures.join('; ')}`)
}
}
const now = '2026-06-26T00:00:00Z'
const smokeAuthUser = {
id: 1,
@@ -823,9 +899,12 @@ async function runAuthenticatedAdminChecks(browser, failures, consoleErrors, opt
}
await expectVisibleText(page, route.text, routeLabel)
if (expectAccount) {
await expectVisibleText(page, 'Hi, smoke-admin', routeLabel)
await expectVisibleText(page, '您好,smoke-admin', routeLabel)
}
await checkNoFrameworkOverlay(page, routeLabel)
if (!zoom) {
await checkAdminShellOneScreen(page, routeLabel, { expectAccountVisible: expectAccount })
}
if (checkHorizontalOverflow) {
await checkNoGlobalHorizontalOverflow(page, routeLabel)
}
@@ -884,6 +963,34 @@ async function runAdminInteractionChecks(browser, failures, consoleErrors) {
))
await expectVisibleText(page, 'SMTP 邮件', 'global search smtp')
await page.goto(urlFor('/admin'), { waitUntil: 'domcontentloaded' })
await clickFirstVisible(page.getByRole('button', { name: '展开偏好设置' }), 'admin preferences drawer open')
await page.waitForTimeout(350)
await checkAdminShellOneScreen(page, 'admin preferences drawer open', {
expectAccountVisible: true,
expectPreferencesVisible: true,
})
await clickFirstVisible(
page.getByRole('group', { name: '控制台语言' }).getByRole('button', { name: 'EN' }),
'admin language switch english',
)
await expectVisibleText(page, 'Dashboard', 'admin language switch english')
await page.getByLabel('Search features, settings, and text').fill('SMTP')
await clickFirstVisible(page.getByRole('option', { name: /SMTP/i }), 'admin english global search smtp option')
await expectUrl(page, 'admin english global search smtp', (location) => (
location.pathname === '/settings' && location.search.includes('section=smtp')
))
await expectVisibleText(page, 'SMTP Email', 'admin english global search smtp')
const reopenEnglishPreferences = await firstVisibleOrNull(page.getByRole('button', { name: 'Expand preferences' }), 500)
if (reopenEnglishPreferences) {
await reopenEnglishPreferences.click()
}
await clickFirstVisible(
page.getByRole('group', { name: 'Console language' }).getByRole('button', { name: '中文' }),
'admin language switch chinese',
)
await expectVisibleText(page, 'SMTP 邮件', 'admin language switch chinese')
await page.goto(urlFor('/ai'), { waitUntil: 'domcontentloaded' })
await clickFirstVisible(page.locator('a[aria-label="设置"][href="/settings"]'), 'ai settings shortcut')
await expectUrl(page, 'ai settings shortcut', (location) => location.pathname === '/settings')
@@ -1079,7 +1186,7 @@ async function runAuthInteractionChecks(browser, failures, consoleErrors) {
await page.getByRole('button', { name: '验证并登录' }).click()
await expectUrl(page, 'register verify login', (location) => location.pathname === '/admin')
await expectVisibleText(page, '仪表盘', 'register verify login')
await expectVisibleText(page, 'Hi, smoke-auth', 'register verify login')
await expectVisibleText(page, '您好,smoke-auth', 'register verify login')
})
await withAuthPage('forgot password reset', async (page) => {
@@ -1106,7 +1213,7 @@ async function runAuthInteractionChecks(browser, failures, consoleErrors) {
await page.getByRole('button', { name: '验证并登录' }).click()
await expectUrl(page, 'standalone verify email', (location) => location.pathname === '/admin')
await expectVisibleText(page, '仪表盘', 'standalone verify email')
await expectVisibleText(page, 'Hi, smoke-auth', 'standalone verify email')
await expectVisibleText(page, '您好,smoke-auth', 'standalone verify email')
})
}