chore: integrate main updates into workspace document preview

This commit is contained in:
程序员阿江(Relakkes)
2026-09-30 02:37:25 +08:00
91 changed files with 4772 additions and 642 deletions
+1
View File
@@ -156,6 +156,7 @@ const DESKTOP_SCOPE: CoverageScope = {
includePrefixes: ['desktop/src/'],
excludePrefixes: [
'desktop/src/types/',
'desktop/src/test/',
// Dev-only tooling, same category as mocks/. `dev/` holds the component
// gallery, which Vite never bundles (its build input is index.html alone)
// and which exists precisely to be looked at by a person — unit-testing a
@@ -5,6 +5,8 @@ import { tmpdir } from 'node:os'
import { join } from 'node:path'
import {
DESKTOP_UI_SMOKE_ALLOW_SELECTOR,
DESKTOP_UI_SMOKE_ATTENTION_PROBE,
DESKTOP_UI_SMOKE_ATTENTION_TAB,
DESKTOP_UI_SMOKE_LOCALE,
buildDesktopUiSmokeBootstrap,
buildDesktopUiSmokePrompt,
@@ -34,6 +36,24 @@ describe('deterministic desktop UI smoke setup', () => {
expect(DESKTOP_UI_SMOKE_ALLOW_SELECTOR).toBe('button[aria-label^="Allow: "]')
})
test('matches the waiting-tab marker the desktop actually renders', () => {
const tabBar = readFileSync('desktop/src/components/layout/TabBar.tsx', 'utf8')
const mark = readFileSync('desktop/src/components/layout/SessionAttentionMark.tsx', 'utf8')
const english = readFileSync('desktop/src/i18n/locales/en.ts', 'utf8')
// Same idea as the approval button above: the selectors are derived from the
// production markup, so a rename fails here before the lane times out waiting.
expect(tabBar).toContain('data-testid="tab-bar"')
expect(tabBar).toContain("data-attention={needsAttention ? 'true' : 'false'}")
expect(mark).toContain('role="img"')
expect(english).toContain("'tabs.sessionRunning': 'Session running'")
expect(DESKTOP_UI_SMOKE_ATTENTION_TAB).toBe('[data-testid="tab-bar"] [data-attention="true"]')
expect(DESKTOP_UI_SMOKE_ATTENTION_PROBE).toContain(DESKTOP_UI_SMOKE_ATTENTION_TAB)
expect(DESKTOP_UI_SMOKE_ATTENTION_PROBE).toContain('[role="img"]')
// The probe must also reject a tab that carries the running dot.
expect(DESKTOP_UI_SMOKE_ATTENTION_PROBE).toContain('!tab.querySelector(\'[aria-label="Session running"]\')')
})
test('asks the mock runtime to write inside the fixture copy only', () => {
const projectDir = '/tmp/fixture-copy'
const { target, prompt } = buildDesktopUiSmokePrompt(projectDir)
@@ -47,6 +47,22 @@ const SMOKE_MODEL_ID = 'desktop-ui-smoke-model'
export const DESKTOP_UI_SMOKE_LOCALE = 'en'
export const DESKTOP_UI_SMOKE_ALLOW_SELECTOR = 'button[aria-label^="Allow: "]'
/**
* The tab of a session stopped on a decision only the user can make.
* `data-attention` is set on the tab by TabBar; the strip is the only place it
* appears, so the selector is anchored there.
*/
export const DESKTOP_UI_SMOKE_ATTENTION_TAB = '[data-testid="tab-bar"] [data-attention="true"]'
/**
* True while that tab carries the warning mark and has *not* also been given the
* running dot. A session parked on a permission card is "running" by chatState
* too, and the running dot said the one thing that is not true of it.
*/
export const DESKTOP_UI_SMOKE_ATTENTION_PROBE =
`(() => { const tab = document.querySelector('${DESKTOP_UI_SMOKE_ATTENTION_TAB}'); ` +
`return !!tab && !!tab.querySelector('[role="img"]') && !tab.querySelector('[aria-label="Session running"]') })()`
export function buildDesktopUiSmokeBootstrap(sessionId: string) {
return [
`localStorage.setItem('cc-haha-locale', ${JSON.stringify(DESKTOP_UI_SMOKE_LOCALE)})`,
@@ -262,7 +278,13 @@ export async function executeDeterministicDesktopSmoke(
throw new Error('the tool wrote the fixture file before the permission dialog was answered')
}
await browserStep(['screenshot', join(artifactDir, 'permission-dialog.png')], { allowFailure: true })
// While the dialog is open the session's tab has to say the session is
// waiting on the person, not running, and has to stop saying it once the
// request is answered. A marker derived from anything but the open request
// gets one of those two wrong.
await browserStep(['wait', '--fn', DESKTOP_UI_SMOKE_ATTENTION_PROBE], { timeoutMs: 15_000 })
await browserStep(['click', DESKTOP_UI_SMOKE_ALLOW_SELECTOR], { timeoutMs: 20_000 })
await browserStep(['wait', '--fn', `!document.querySelector('${DESKTOP_UI_SMOKE_ATTENTION_TAB}')`], { timeoutMs: 20_000 })
await pollUntil(
async () => existsSync(target) && readFileSync(target, 'utf8') === TARGET_CONTENT,