feat: complete WorkBuddy parity and Windows release workflow

This commit is contained in:
xiaohan.yuan committed 2026-10-18 12:45:21 +08:00
1 parent 143516b3a8
commit d5512df549
434 files changed
+54977 -1854

No files matched your search

+29 -17
View File
@@ -197,12 +197,12 @@ if (!process.versions.electron) {
check('menu items keep the recovered 2px gap', light.itemsGap, '2px')
check('settings row shows the Ctrl+, shortcut', light.items[0].value, 'Ctrl+,')
check('appearance row reports the current light theme', light.items[1].value, '浅色')
check('unwired rows stay honest about their state', [light.items[2].value, light.items[3].value], ['待拆解', '未接入'])
check('memory is wired while the update row stays honest', [light.items[2].value, light.items[3].value], [null, '未接入'])
check('footer keeps margin-top 6 + padding-top 8 + 1px rule', [light.footer.marginTop, light.footer.paddingTop, light.footer.ruleHeight], ['6px', '8px', '1px'])
check('logout row keeps the 32px row inside the footer', [Math.round(light.logout.box[3]), light.logout.font], [32, '14px/400/22px'])
check('logout entry is present and honest', /退出登录.*未接入/.test(light.logout.text), true)
check('menu content matches the requested scope', light.text,
'Xxiaohan.yuan账号为 mock 数据,尚未接入登录套餐未接入升级套餐余额未接入购买积分设置Ctrl+,外观浅色记忆与进化待拆解检查更新未接入退出登录未接入')
'Xxiaohan.yuan账号为 mock 数据,尚未接入登录套餐未接入升级套餐余额未接入购买积分设置Ctrl+,外观浅色记忆与进化检查更新未接入退出登录未接入')
check('menu shows no fabricated 套餐/余额/积分 numbers', light.digits, false)
await shot('account-menu-light')
@@ -260,9 +260,9 @@ if (!process.versions.electron) {
await step('menu-settings-navigation')
assert.equal(await read(clickRow('设置')), true)
await wait('!document.querySelector(".ycode-account-menu")', 'menu closed after settings click')
await wait('!!document.querySelector(".models-settings-panel")', 'models panel in the reused settings window', settings)
await wait('!!document.querySelector(".general-settings-panel")&&!document.querySelector(".appearance-panel")', 'general panel in the reused settings window', settings)
check('设置 row reuses the native settings window', BrowserWindow.getAllWindows().filter(win => win !== main).length, 1)
check('设置 row lands on the models panel', await read(`!!document.querySelector('.models-settings-panel')&&!document.querySelector('.appearance-panel')`, settings), true)
check('设置 row lands on the general panel', await read(`!!document.querySelector('.general-settings-panel')&&!document.querySelector('.appearance-panel')`, settings), true)
await step('menu-light-restore')
await read(`document.querySelector('[data-settings-tab="appearance"]').click()`, settings)
@@ -272,22 +272,34 @@ if (!process.versions.electron) {
check('light theme is restored through the same settings window', await read(`[document.documentElement.dataset.theme,localStorage.getItem('ycode:theme')]`), ['light', 'light'])
const settingsId = settings.id
await read(`document.querySelector('.settings-window-close').click()`, settings)
for (let index = 0; index < 200 && !settings.isDestroyed(); index++) await pause(20)
check('settings window closes normally', settings.isDestroyed(), true)
check('closed settings window is gone from the app windows', BrowserWindow.getAllWindows().filter(win => win.id === settingsId).length, 0)
for (let index = 0; index < 200 && settings.isVisible(); index++) await pause(20)
check('settings window hides normally', !settings.isDestroyed() && !settings.isVisible(), true)
check('closed settings window stays cached', BrowserWindow.getAllWindows().filter(win => win.id === settingsId).length, 1)
await step('menu-memory-navigation')
await read(openMenu)
await wait('!!document.querySelector(".ycode-account-menu")', 'menu open for memory')
assert.equal(await read(clickRow('记忆与进化')), true)
await wait('!document.querySelector(".ycode-account-menu")', 'menu closed after memory click')
for (let index = 0; index < 200; index++) {
settings = BrowserWindow.getAllWindows().find(win => win !== main)
if (settings && !settings.webContents.isLoading()) break
await pause(25)
}
assert.ok(settings, 'memory settings window')
observe(settings)
await wait('!!document.querySelector(".memory-settings-panel")', 'memory settings panel', settings)
check('记忆与进化 row opens the real memory settings panel', await read(`!!document.querySelector('.memory-settings-panel')&&!document.querySelector('.appearance-panel')`, settings), true)
check('memory row reuses one native settings window', BrowserWindow.getAllWindows().filter(win => win !== main).length, 1)
const memorySettingsId = settings.id
await read(`document.querySelector('.settings-window-close').click()`, settings)
for (let index = 0; index < 200 && settings.isVisible(); index++) await pause(20)
check('memory settings window hides normally', !settings.isVisible() && BrowserWindow.getAllWindows().some(win => win.id === memorySettingsId), true)
await step('menu-unwired-rows')
await read(openMenu)
await wait('!!document.querySelector(".ycode-account-menu")', 'menu open for unwired rows')
snapshots.unwiredRows = await read(rowSource)
assert.equal(await read(clickRow('记忆与进化')), true)
await wait('!document.querySelector(".ycode-account-menu")', 'menu closed after unwired row click')
const hint = await wait(`(()=>{const node=document.querySelector('.sidebar__hint');return node?node.textContent:null})()`, 'sidebar hint for the unwired row')
check('记忆与进化 reports a pending state instead of fake success', /待拆解|尚未接入/.test(hint), true)
check('unwired row does not open an extra window', BrowserWindow.getAllWindows().filter(win => win !== main).length, 0)
await wait('!document.querySelector(".sidebar__hint")', 'hint auto-dismissed')
await read(openMenu)
await wait('!!document.querySelector(".ycode-account-menu")', 'menu reopened for remaining rows')
assert.equal(await read(clickRow('检查更新')), true)
await wait('!document.querySelector(".ycode-account-menu")', 'menu closed after 检查更新')
check('检查更新 reports an unwired state', /尚未接入/.test(await wait(`(()=>{const node=document.querySelector('.sidebar__hint');return node?node.textContent:null})()`, 'hint for 检查更新')), true)
@@ -295,8 +307,8 @@ if (!process.versions.electron) {
await read(openMenu)
await wait('!!document.querySelector(".ycode-account-menu")', 'menu open for logout')
await shot('account-menu-final')
// 记忆与进化 / 检查更新 / 退出登录 三行都要对辅助技术保持 disabled,不假装可用。
check('unwired rows stay disabled for assistive tech', snapshots.unwiredRows.slice(2).map(row => row.ariaDisabled), ['true', 'true', 'true'])
// 已接入的记忆行保持可操作;检查更新与退出登录仍要对辅助技术保持 disabled。
check('only the still-unwired rows are disabled for assistive tech', snapshots.unwiredRows.slice(2).map(row => row.ariaDisabled), [null, 'true', 'true'])
check('no renderer error logs', rendererErrors, [])
const report = { result: checks.every(item => item.pass) ? 'PASS' : 'FAIL',