Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions design-qa.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,96 @@

final result: passed

---

# Workspace Document Tabs Follow-up Review

Comment thread
qdaxb marked this conversation as resolved.
Outdated
## Source visual truth

- Reference: `/Users/axb-mac/.wegent-executor/workspace/attachments/draft/1785512913569/image.model-input.png`
Comment thread
qdaxb marked this conversation as resolved.
Outdated

## Implementation evidence

- Task tab active: `wework/test-results/ai-verify/final-workspace-tabs-review/01-task-active.png`
- New-tab menu: `wework/test-results/ai-verify/final-workspace-tabs-review/02-new-tab-menu.png`
- Project spaces active: `wework/test-results/ai-verify/final-workspace-tabs-review/03-project-spaces-active.png`
- Concrete project title active: `wework/test-results/ai-verify/final-workspace-tabs-review/04-project-name-active.png`
- Switch back to task: `wework/test-results/ai-verify/final-workspace-tabs-review/05-switch-back-to-task.png`
- Close project tab: `wework/test-results/ai-verify/final-workspace-tabs-review/06-close-project-tab.png`
- Restore closed project tab: `wework/test-results/ai-verify/final-workspace-tabs-review/07-restore-closed-project-tab.png`
- Tab context menu: `wework/test-results/ai-verify/final-workspace-tabs-review/08-tab-context-menu.png`
- Independent project window: `wework/test-results/ai-verify/final-workspace-tabs-review/09-project-new-window.png`
- Side-by-side comparison: `wework/test-results/ai-verify/final-workspace-tabs-review/10-reference-vs-implementation.png`

## Review findings

- The active document tab uses the content surface color, stronger text, and connected corner
shapes; inactive tabs remain on the muted titlebar. The selected and unselected states are
visibly distinct at a glance.
- Horizontal tab padding and a hidden-scrollbar overflow region preserve both active-tab corner
shapes at the first and last positions while allowing future multi-tab growth.
- The reference hierarchy is preserved: native traffic lights, document tabs, a quiet titlebar,
sidebar/content separation, and the active tab visually joining the page below.
- Top-level navigation consistently uses “项目空间”; an opened project uses its concrete name
(“产品规划”) in both the main window and the independent window.
- Add-tab and context menus remain compact, aligned to their trigger, and clamped to the viewport.
- The real Tauri independent-window capture confirms that the reduced workspace-window capability
still supports the complete project-space experience.

## Interaction and accessibility verification

- Open, select, close, restore, reorder, keyboard context-menu, and open-in-new-window flows were
exercised.
- Tabs expose semantic `tablist`/`tab` roles without nesting another button inside the tab.
- Close labels and auxiliary route titles are localized in Chinese and English.
- No actionable P0, P1, or P2 visual mismatch remains.

final result: passed
Comment thread
qdaxb marked this conversation as resolved.
Outdated

---

# Wework 工作区标签设计 QA

## 目标

- 参考图:`/Users/axb-mac/.wegent-executor/workspace/attachments/draft/1785512913569/image.png`
- 实现范围:Wework 顶层任务 / 项目空间文档标签、项目名标题、关闭与恢复、新窗口。
- 验证环境:macOS 真实 Tauri 隔离实例,主窗口 1280×720;独立项目窗口 1280×800。

## 对照结果

- 对照图:`wework/test-results/ai-verify/final-workspace-tabs/10-reference-vs-implementation.png`
- 标题栏高度、文档标签宽度、圆角连接、关闭按钮、加号位置与参考方向一致。
- 标题栏使用稳定浅灰底色,选中标签使用内容表面色;未选中标签留在标题栏层,状态差异清晰。
- 顶层产品名统一为“项目空间”;具体项目打开后标签标题显示项目名,例如“产品规划”。
- 主窗口与独立项目窗口均无裁切、重叠、错误边框或圆角断裂。

## 核心流程截图

1. `01-task-active.png`:任务标签初始选中。
2. `02-new-tab-menu.png`:新建标签菜单。
3. `03-project-spaces-active.png`:项目空间顶层标签选中。
4. `04-project-name-active.png`:具体项目标题显示“产品规划”。
5. `05-switch-back-to-task.png`:切回任务,选中态同步。
6. `06-close-project-tab.png`:关闭项目标签后回退到任务。
7. `07-restore-closed-project-tab.png`:快捷键恢复已关闭项目标签。
8. `08-tab-context-menu.png`:标签上下文菜单。
9. `09-project-new-window.png`:项目在独立窗口中打开。

截图目录:`wework/test-results/ai-verify/final-workspace-tabs/`

## 缺陷审查

- P0:选中与未选中标签底色过于接近。已拆分标题栏和活动标签表面色,并重新截图验证。
- P0:新建项目后标签仍显示“项目空间”。已改为直接使用创建结果更新活动标签,真实流程与单测均通过。
- P1:右键菜单只能依赖鼠标。已增加 Shift+F10 / Context Menu 键入口。
- P1:动态项目窗口无法纳入隔离截图链。已增加工作区窗口 WebView 截图命令并验证。
- P2:未发现。

## 最终结论

final result: passed

## Dropdown alignment follow-up

- Source visual truth: `/Users/axb-mac/.wegent-executor/workspace/attachments/draft/1785311314363/image.png`
Expand Down
45 changes: 45 additions & 0 deletions wework/e2e/desktop/task-flow.e2e.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2911,6 +2911,48 @@ async function captureVerificationScreenshot(control, name, selector = 'body') {
return screenshotPath
}

async function verifyWorkspaceDocumentTabs(control) {
await control.command('waitFor', '[data-testid="workspace-tab-strip"]', {
timeoutMs: DEFAULT_STEP_TIMEOUT_MS,
})
await control.command('waitFor', '[data-tab-kind="task"][aria-selected="true"]', {
text: '任务',
timeoutMs: DEFAULT_STEP_TIMEOUT_MS,
})

await control.command('click', '[data-testid="workspace-tab-add"]')
await control.command('waitFor', '[data-testid="workspace-tab-add-menu"]', {
timeoutMs: DEFAULT_STEP_TIMEOUT_MS,
})
await control.command('click', '[data-testid="workspace-tab-add-board"]')
await control.command('waitFor', '[data-tab-kind="board"][aria-selected="true"]', {
timeoutMs: DEFAULT_STEP_TIMEOUT_MS,
})
await control.command('waitFor', '[data-testid="cloud-todo-workspace"]', {
timeoutMs: DEFAULT_STEP_TIMEOUT_MS,
})
await captureVerificationScreenshot(control, 'workspace-tabs-01-project-spaces-active.png')

await control.command(
'click',
'[data-testid^="workspace-tab-select-task-"]'
)
await control.command('waitFor', '[data-tab-kind="task"][aria-selected="true"]', {
text: '任务',
timeoutMs: DEFAULT_STEP_TIMEOUT_MS,
})
await control.command(
'click',
'[data-testid^="workspace-tab-close-board-"]'
)
await waitForSnapshot(
control,
snapshot => !snapshot.testIds.some(testId => testId.startsWith('workspace-tab-board-')),
'Closing the project-space document tab did not remove it from the titlebar'
)
await captureVerificationScreenshot(control, 'workspace-tabs-02-task-restored.png')
}

async function verifyCloudWorkPage(control) {
await control.command('navigate', 'body', { value: '/cloud-work' })
await control.command('waitFor', '[data-testid="cloud-work-page"]', {
Expand Down Expand Up @@ -10544,6 +10586,9 @@ last_updated = "2026-07-30T00:00:00Z"`

if (shouldRunDesktopCheckpoint('core-task-flow')) {
if (!GUIDANCE_SCROLL_ONLY) {
phase = 'workspace-document-tabs'
await verifyWorkspaceDocumentTabs(control)

phase = 'automation-lifecycle'
await verifyAutomationLifecycle(control, workspacePath)

Expand Down
6 changes: 4 additions & 2 deletions wework/scripts/ai-verify.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const corsHeaders = {
function usage() {
console.error(`Usage:
pnpm --filter wework ai:verify start
pnpm --filter wework ai:verify <capture|capture-popout|snapshot|debug|click|click-at|click-then-macrotask|seed-local-project|reload|close-to-tray|request-close|dismiss-popout|drag|drop-file|drop-paths|fill|hover|metrics|navigate|paste-paths|pointer-move|press|scroll-into-view|select-text|show-popout|system-drag-drop|wait-for|window-focus-snapshot|text|status|stop> --session PATH [options]
pnpm --filter wework ai:verify <capture|capture-popout|capture-workspace|snapshot|debug|click|click-at|click-then-macrotask|seed-local-project|reload|close-to-tray|request-close|dismiss-popout|drag|drop-file|drop-paths|fill|hover|metrics|navigate|paste-paths|pointer-move|press|scroll-into-view|select-text|show-popout|system-drag-drop|wait-for|window-focus-snapshot|text|status|stop> --session PATH [options]

Options:
--codex-home-initialization true
Expand Down Expand Up @@ -401,6 +401,7 @@ async function main() {
const action = {
capture: 'capture',
'capture-popout': 'capturePopoutWindow',
'capture-workspace': 'captureWorkspaceWindow',
snapshot: 'snapshot',
debug: 'getWorkbenchDebugSnapshot',
click: 'click',
Expand Down Expand Up @@ -438,6 +439,7 @@ async function main() {
options.selector ??
(command === 'capture' ||
command === 'capture-popout' ||
command === 'capture-workspace' ||
command === 'snapshot' ||
command === 'debug' ||
command === 'click-at' ||
Expand Down Expand Up @@ -490,7 +492,7 @@ async function main() {
effectiveTimeoutMs
)
}
if (command === 'capture' || command === 'capture-popout') {
if (command === 'capture' || command === 'capture-popout' || command === 'capture-workspace') {
if (!options.output) throw new Error('--output is required')
const prefix = 'data:image/png;base64,'
if (!value.value?.startsWith(prefix)) throw new Error('Invalid screenshot payload')
Expand Down
22 changes: 22 additions & 0 deletions wework/src-tauri/capabilities/workspace-window.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "workspace-window",
"description": "Allows project-space document windows to manage only their own window chrome.",
"windows": ["workspace-*"],
"permissions": [
"core:default",
"core:window:allow-close",
"core:window:allow-destroy",
"core:window:allow-set-focus",
"core:window:allow-show",
"core:window:allow-start-dragging",
"core:window:allow-unminimize",
"core:window:allow-minimize",
"core:window:allow-maximize",
"core:window:allow-unmaximize",
"core:window:allow-toggle-maximize",
"core:window:allow-is-maximized",
"core:window:allow-is-fullscreen",
"log:default"
Comment thread
qdaxb marked this conversation as resolved.
Outdated
]
}
30 changes: 30 additions & 0 deletions wework/src-tauri/src/desktop_capture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,36 @@ pub async fn capture_popout_webview(app: tauri::AppHandle) -> Result<String, Str
capture_webview_impl(app, "popout-window", false).await
}

#[tauri::command]
pub async fn capture_workspace_webview(app: tauri::AppHandle) -> Result<String, String> {
use tauri::Manager;

let label = app
.webview_windows()
.into_iter()
.find_map(|(label, window)| {
(label.starts_with("workspace-") && window.is_focused().unwrap_or(false))
.then_some(label)
})
.or_else(|| {
app.webview_windows()
.into_keys()
.filter(|label| label.starts_with("workspace-"))
.max_by_key(|label| {
(
label
.rsplit('-')
.next()
.and_then(|timestamp| timestamp.parse::<u128>().ok())
.unwrap_or_default(),
label.clone(),
)
})
})
.ok_or_else(|| "No workspace window is available".to_string())?;
capture_webview_impl(app, &label, false).await
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

#[cfg(target_os = "macos")]
pub(crate) async fn capture_embedded_webview_png(
webview: tauri::Webview<tauri::Wry>,
Expand Down
1 change: 1 addition & 0 deletions wework/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4527,6 +4527,7 @@ pub fn run() {
cloud_authorization_window::position_cloud_authorization_window,
desktop_capture::capture_main_webview,
desktop_capture::capture_popout_webview,
desktop_capture::capture_workspace_webview,
acknowledge_frontend_resume_probe,
register_frontend_recovery_bridge,
#[cfg(desktop)]
Expand Down
16 changes: 7 additions & 9 deletions wework/src/App.apps.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -202,22 +202,22 @@ describe('App center route', () => {
})
}

test('renders the app center with fixed titlebar tabs on the app route', async () => {
test('renders the app center in an Apps document tab', async () => {
window.history.pushState({}, '', '/apps')

render(<App />)

await waitForStartupScreenToClose()

await waitFor(() => expect(window.location.pathname).toBe('/apps'))
expect(screen.getByTestId('desktop-app-switcher')).toHaveTextContent('任务')
expect(screen.getByTestId('workspace-tab-strip')).toHaveTextContent('应用')
expect(screen.getByRole('tab', { name: /应用/ })).toHaveAttribute('aria-selected', 'true')
expect(screen.getByTestId('desktop-auxiliary-surface')).toHaveClass(
'app-view-surface',
'rounded-xl',
'border'
)
expect(screen.queryByTestId('chrome-tab-todo')).not.toBeInTheDocument()
expect(screen.queryByTestId('chrome-tab-apps')).not.toBeInTheDocument()
expect(screen.getByTestId('workspace-tab-add')).toBeInTheDocument()
expect(screen.getByTestId('apps-page')).toBeInTheDocument()
expect(screen.getByRole('heading', { name: '管理你的办公与编码应用' })).toBeInTheDocument()
expect(await screen.findByText('Executor 状态')).toBeInTheDocument()
Expand Down Expand Up @@ -339,18 +339,16 @@ describe('App center route', () => {
expect(sectionTabs).not.toHaveClass('xl:hidden')
})

test('uses the fixed global view switcher on the app center route', async () => {
test('uses the document tab strip on the app center route', async () => {
window.history.pushState({}, '', '/apps')

render(<App />)

await waitForStartupScreenToClose()
expect(await screen.findByText('Executor 状态')).toBeInTheDocument()

const weworkTab = screen.getByTestId('chrome-tab-wework')
expect(screen.queryByTestId('chrome-tab-todo')).not.toBeInTheDocument()
expect(screen.queryByTestId('chrome-tab-apps')).not.toBeInTheDocument()
expect(weworkTab).toBeInTheDocument()
expect(screen.getByRole('tab', { name: /应用/ })).toHaveAttribute('aria-selected', 'true')
expect(screen.getByTestId('workspace-tab-add')).toBeInTheDocument()

expect(screen.getByTestId('apps-sidebar-nav')).toBeInTheDocument()
})
Expand Down
Loading
Loading