diff --git a/docs/development/ui-testids-CN.md b/docs/development/ui-testids-CN.md new file mode 100644 index 0000000000..ab6058e286 --- /dev/null +++ b/docs/development/ui-testids-CN.md @@ -0,0 +1,429 @@ +[English](ui-testids.md) | **中文** + +# UI Test IDs + +本文档记录 BitFun UI 自动化使用的稳定 `data-testid` 值。 +测试 ID 按产品区域分组,只应在自动化流程确实需要稳定定位点时添加。 + +规则: + +- `data-testid` 只能作为测试定位器使用。不要让产品逻辑依赖它。 +- 优先标记真实可交互元素:`button`、`input`、可编辑区域或对话框根节点。 +- `data-testid` 必须保持稳定、小写,并使用连字符分隔。 +- 对重复项使用一个共享 `data-testid`,再配合稳定的 `data-*` 属性区分。 +- 不要把可见文案、CSS class、坐标、截图或 XPath 路径作为主定位方式。 +- 优先在配套 `data-*` 属性中使用稳定产品标识,例如 `data-workspace-id`、`data-session-id`、`data-agent-id`、`data-skill-key` 或 `data-settings-tab`。 + +## 覆盖规划 + +### 必须补 + +这些区域是 UI 自动化的高价值入口。在新增或扩展跨平台 pytest 用例前, +应优先提供稳定 ID。 + +| 区域 | 范围 | 原因 | +|---|---|---| +| App shell | App 根节点、主内容区、场景视口 | App 加载和路由就绪锚点。 | +| Navigation | 顶部动作、底部菜单、工作区菜单、工作区行、会话行 | 打开设置、会话、项目、Agents、Skills 和工作区级动作的主路径。 | +| Welcome scene | 场景根节点、打开/新建项目按钮、最近工作区列表 | OH 当前默认启动后会落在这里。 | +| Notifications | 通知按钮、通知中心根节点、关闭按钮、活动区块 | 当前 smoke 覆盖和异步任务可见性。 | +| Settings | 场景根节点、导航 tab、活动内容 | 当前 smoke 覆盖和后续配置测试。 | +| Session and Flow Chat | Session 场景、聊天/辅助面板、消息列表、输入区 | 会话创建稳定后的核心产品路径。 | +| Agents and Skills | 场景根节点、区域/tab、过滤器、卡片、关键动作 | Agent 设置和技能市场流程的高价值入口。 | + +### 可选补 + +这些区域等到有具体测试需要时再补。 + +| 区域 | 范围 | 原因 | +|---|---|---| +| Deep Review / BTW 详情面板 | Review 操作栏、评审成员详情、报告导出动作 | 对深入行为测试有价值,但不是 app smoke 必需。 | +| Tool cards | 特定 approve/retry/open-detail 控件 | 按具体工具流程添加,不要给每个渲染字段都打点。 | +| File、Git、Terminal、Browser 面板 | 面板根节点、主工具栏动作、选中列表行 | 等面板专项 pytest 覆盖出现后再补。 | +| Settings 表单控件 | 具体模型/Provider 字段、保存/重置按钮 | 配置测试需要时添加;避免标记每个展示型 label。 | +| Mini apps | Gallery 根节点、app 卡片、runner 根节点 | 等 Mini App 流程进入自动化计划后再补。 | + +### 不建议补 + +除非有明确自动化流程,否则避免给这些对象添加 ID。 + +| 范围 | 原因 | +|---|---| +| 装饰图标、徽章、计数器、阴影、动画 | 不是有意义的交互或状态锚点。 | +| 每个文本节点、段落和静态 label | 增加维护成本,并且重复绑定 i18n 可见文案。 | +| 生成的 markdown/code 内容和模型输出 span | 输出是动态的,应通过更高层状态断言。 | +| 坐标、canvas 像素、仅截图可见标记或原生窗口控件 | 跨平台 WebView 自动化应保持基于 DOM 和 `data-testid`。 | +| 把本地化文案复制到 `data-testid` 或作为主定位方式 | 文案或语言切换会导致定位失效。 | + +## 命名 + +- 使用区域前缀:`app-*`、`scene-*`、`nav-*`、`welcome-*`、`settings-*`、`notification-*`、`session-*`、`chat-*`、`flowchat-*`、`agents-*`、`skills-*`。 +- 按动作给按钮加后缀:`*-btn`、`*-toggle`、`*-open`、`*-close`、`*-submit`、`*-cancel`、`*-delete`。 +- 按结构给容器加后缀:`*-scene`、`*-panel`、`*-list`、`*-grid`、`*-menu`、`*-content`、`*-zone`。 +- 对重复行/卡片,复用一个 `data-testid` 并搭配稳定属性,例如: + - `nav-workspace-item` + `data-workspace-id` + - `nav-session-item` + `data-session-id` + - `settings-nav-tab` + `data-settings-tab` + - `agent-list-item` + `data-agent-id` / `data-agent-name` + - `skill-list-item` + `data-skill-id` / `data-skill-name` + - `skills-market-card` + `data-skill-install-id` + +## App Shell + +| 元素名称 | data-testid | 说明 | +|---|---|---| +| App 布局根节点 | `app-layout` | App 加载完成锚点。 | +| 主内容区 | `app-main-content` | 主场景内容容器。 | +| 导航面板 | `nav-panel` | 左侧导航容器。 | +| 场景视口根节点 | `scene-viewport` | 场景宿主根节点。 | +| 场景视口裁剪区 | `scene-viewport-clip` | 已挂载场景的裁剪区域。 | +| 空场景视口 | `scene-viewport-empty` | 没有打开 tab 时渲染。 | +| 已挂载场景 wrapper | `scene-viewport-scene` | 重复项。配合 `data-scene-id` 和 `data-scene-active` 使用。 | + +## Welcome + +| 元素名称 | data-testid | 说明 | +|---|---|---| +| Welcome 场景根节点 | `welcome-scene` | 默认启动场景锚点。 | +| 打开项目按钮 | `welcome-open-project-btn` | 打开文件/文件夹选择器。 | +| 新建项目按钮 | `welcome-new-project-btn` | 打开新建项目流程。 | +| 最近工作区列表 | `welcome-recent-workspace-list` | 有最近工作区时存在。 | +| 最近工作区行 | `welcome-recent-workspace-row` | 重复项。配合 `data-workspace-id` 使用。 | +| 最近工作区打开按钮 | `welcome-recent-workspace-open` | 重复项。配合 `data-workspace-id` 使用。 | +| 最近工作区移除按钮 | `welcome-recent-workspace-remove` | 重复项。配合 `data-workspace-id` 使用。 | +| 最近工作区空状态 | `welcome-recent-workspace-empty` | 没有最近工作区时存在。 | + +## Navigation + +| 元素名称 | data-testid | 说明 | +|---|---|---| +| 导航搜索触发按钮 | `nav-search-trigger` | 打开导航搜索。 | +| 新建 Code 会话按钮 | `nav-new-code-session-btn` | 为活动项目工作区创建或打开 code 会话。 | +| 新建 Cowork 会话按钮 | `nav-new-cowork-session-btn` | 为活动项目工作区创建或打开 cowork 会话。 | +| Assistant 按钮 | `nav-assistant-btn` | 打开 assistant/persona 场景。 | +| Agent/Skill 入口 | `agent-skill-entry` | 展开 Agents/Skills 导航入口组。 | +| Agent/Skill 面板 | `agent-skill-panel` | Agents/Skills 入口组或当前发现页根节点。 | +| Agent/Skill tabs | `agent-skill-tabs` | Agent 和 Skill 入口 tab 容器。 | +| Agent tab | `agent-tab` | 打开 Agents 发现页。 | +| Skill tab | `skill-tab` | 打开 Skills 发现页。 | +| 导航 sections 容器 | `nav-sections` | 工作区/会话 section 容器。 | +| 导航底部栏 | `nav-bottom-bar` | Mini App/footer 区域容器。 | +| 底部更多按钮 | `nav-footer-more-btn` | 打开底部溢出菜单。 | +| 底部菜单 | `nav-footer-menu` | 由底部更多按钮打开的溢出菜单。 | +| 底部设置菜单项 | `nav-footer-settings-item` | 从底部菜单打开 Settings 场景。 | +| 底部 Shell 按钮 | `shell-panel-entry` | 打开或关闭 shell 场景导航。 | +| 底部 Browser 按钮 | `browser-panel-entry` | 根据当前上下文打开 browser 场景或 browser 面板。 | + +## Navigation Workspaces + +| 元素名称 | data-testid | 说明 | +|---|---|---| +| 工作区添加按钮 | `nav-workspace-add-btn` | 打开工作区添加/最近工作区菜单。 | +| 工作区添加菜单 | `nav-workspace-menu` | 从添加按钮打开的 portal 菜单。 | +| 工作区菜单打开项目 | `nav-workspace-menu-open-project` | 打开项目选择器。 | +| 工作区菜单新建项目 | `nav-workspace-menu-new-project` | 打开新建项目流程。 | +| 工作区菜单远程 SSH | `nav-workspace-menu-remote-ssh` | 打开 SSH 远程连接流程。 | +| 工作区菜单最近工作区 | `nav-workspace-menu-recent-workspace` | 重复项。配合 `data-workspace-id` 使用。 | +| 工作区列表 | `nav-workspace-list` | 按列表类型重复。配合 `data-workspace-list` 使用。 | +| 工作区列表空状态 | `nav-workspace-list-empty` | 配合 `data-workspace-list` 使用。 | +| 工作区拖拽目标 | `nav-workspace-drop-target` | 重复拖拽目标。配合 `data-workspace-id` 使用。 | +| 工作区行 | `nav-workspace-item` | 重复项。配合 `data-workspace-id`、`data-workspace-kind` 和 `data-workspace-active` 使用。 | +| 工作区卡片 | `nav-workspace-card` | 可点击行主体。配合 `data-workspace-id` 使用。 | +| 工作区会话展开按钮 | `nav-workspace-sessions-toggle` | 展开/折叠会话行。配合 `data-workspace-id` 使用。 | +| 工作区名称按钮 | `nav-workspace-name-btn` | 激活工作区或切换会话展开状态。配合 `data-workspace-id` 使用。 | +| 工作区文件按钮 | `nav-workspace-files-btn` | 打开该工作区的文件查看器。配合 `data-workspace-id` 使用。 | +| 工作区搜索索引按钮 | `nav-workspace-search-index-btn` | 存在时打开搜索索引状态弹窗。配合 `data-workspace-id` 使用。 | +| 工作区行菜单按钮 | `nav-workspace-menu-btn` | 打开行操作菜单。配合 `data-workspace-id` 使用。 | +| 工作区行菜单 | `nav-workspace-item-menu` | 单个工作区的 portal 菜单。配合 `data-workspace-id` 使用。 | +| 工作区创建会话 | `nav-workspace-menu-create-session` | Assistant 工作区会话动作。 | +| 工作区创建 Code 会话 | `nav-workspace-menu-create-code-session` | 普通工作区 code 会话动作。 | +| 工作区创建 Cowork 会话 | `nav-workspace-menu-create-cowork-session` | 普通工作区 cowork 会话动作。 | +| 工作区创建 ACP 会话 | `nav-workspace-menu-create-acp-session` | 重复项。配合 `data-acp-client-id` 使用。 | +| 工作区创建 Init 会话 | `nav-workspace-menu-create-init-session` | 启动 AGENTS.md/init 会话。 | +| 工作区相关路径 | `nav-workspace-menu-related-paths` | 打开相关路径对话框。 | +| 工作区新建 worktree | `nav-workspace-menu-new-worktree` | 打开 worktree 创建对话框。 | +| 工作区删除 worktree | `nav-workspace-menu-delete-worktree` | 删除关联 worktree 工作区。 | +| 工作区复制路径 | `nav-workspace-menu-copy-path` | 复制工作区路径。 | +| 工作区 reveal | `nav-workspace-menu-reveal` | 在文件管理器中显示工作区。 | +| 工作区关闭 | `nav-workspace-menu-close` | 关闭工作区。 | +| 工作区重置 assistant | `nav-workspace-menu-reset-assistant` | 重置默认 assistant 工作区。 | +| 工作区删除 assistant | `nav-workspace-menu-delete-assistant` | 删除具名 assistant 工作区。 | +| 工作区会话区域 | `nav-workspace-session-region` | 包含单个工作区的会话。配合 `data-workspace-id` 使用。 | + +## Navigation Sessions + +| 元素名称 | data-testid | 说明 | +|---|---|---| +| 会话列表 | `nav-session-list` | 工作区维度的列表。配合 `data-workspace-id` 使用。 | +| 会话行 | `nav-session-item` | 重复项。配合 `data-session-id`、`data-session-kind`、`data-session-level` 和 `data-session-active` 使用。 | +| 会话菜单按钮 | `nav-session-menu-btn` | 打开行操作菜单。配合 `data-session-id` 使用。 | +| 会话菜单 | `nav-session-menu` | 单个会话的 portal 菜单。配合 `data-session-id` 使用。 | +| 会话重命名项 | `nav-session-menu-rename` | 开始重命名会话。 | +| 会话删除项 | `nav-session-menu-delete` | 删除会话。 | +| 会话列表展开按钮 | `nav-session-list-toggle` | 展开/折叠长会话列表。 | + +## Session And Chat + +| 元素名称 | data-testid | 说明 | +|---|---|---| +| Session 场景根节点 | `session-scene` | Session 场景锚点。 | +| Session 聊天面板 | `session-chat-pane` | Session 场景中的左侧聊天面板。 | +| Session 右侧面板 resizer | `session-right-pane-resizer` | 聊天和辅助面板之间的分隔条。 | +| Session 辅助面板 | `session-aux-pane` | 右侧 content canvas 面板。包含 `data-mode`。 | +| Chat pane 根节点 | `chat-pane` | FlowChat 宿主面板。 | +| FlowChat 容器 | `flowchat-container` | FlowChat 根节点。包含 `data-session-id`。 | +| FlowChat 消息区域 | `flowchat-messages` | 消息列表/welcome panel 宿主。 | +| FlowChat 消息列表 | `flowchat-message-list` | 有消息时的虚拟消息列表根节点。 | +| FlowChat 空消息列表 | `flowchat-message-list-empty` | 空虚拟列表状态。 | +| FlowChat 消息项 | `flowchat-message-item` | 重复的虚拟消息项。配合 `data-turn-id`、`data-item-type` 和 `data-item-index` 使用。 | +| Chat 输入容器 | `chat-input-container` | composer 根容器。 | +| Chat 输入可编辑区域 | `chat-input-textarea` | 富文本可编辑区域。 | +| Chat 发送按钮 | `chat-input-send-btn` | 输入有效时的发送动作。 | +| Chat 取消按钮 | `chat-input-cancel-btn` | 存在时用于取消进行中的发送/生成。 | +| Chat 输入工作区条 | `chat-input-workspace-strip` | composer 上方的活动工作区条。 | +| Chat 输入目标切换器 | `chat-input-target-switcher` | 目标/模式切换器。 | +| Chat 输入图片条 | `chat-input-image-strip` | 已附加图片条。 | +| Chat 输入启动 BTW 按钮 | `chat-input-boost-start-btw` | 存在时启动 BTW 流程。 | +| Pending queue 面板 | `pending-queue-panel` | 待处理后台任务队列。 | + +| Chat 模型选择按钮 | `chat-model-selector-btn` | 打开当前会话的模型选择器。 | +| Chat 模型选择菜单 | `chat-model-selector-menu` | 模型选择下拉菜单根节点。 | +| Chat 模型选择项 | `chat-model-selector-option` | 重复项。配合 `data-model-id`、`data-model-name` 和 `data-selected` 使用。 | +| Chat 用户消息 | `chat-user-message` | 重复的用户消息。配合 `data-turn-id`、`data-status` 和 `data-failed` 使用。 | +| Chat 用户消息内容 | `chat-user-message-content` | 用户消息文本内容。配合 `data-turn-id` 使用。 | +| Chat assistant 消息 | `chat-assistant-message` | 重复的模型轮次容器。配合 `data-turn-id`、`data-round-id`、`data-status`、`data-model-id`、`data-model-alias` 和 `data-streaming` 使用。 | +| Chat assistant 消息内容 | `chat-assistant-message-content` | assistant 文本块。配合 `data-turn-id`、`data-flow-item-id`、`data-status` 和 `data-streaming` 使用。 | +| Chat explore group | `chat-explore-group` | ExploreGroup 根节点,用于包裹折叠/合并后的工具轮次。包含 `data-group-kind`、`data-expanded`、`data-read-count`、`data-search-count` 和 `data-command-count`。 | +| Chat explore group toggle | `chat-explore-group-toggle` | ExploreGroup 真实展开/收起点击目标。包含 `data-group-kind` 和 `data-expanded`。 | +| Chat explore group content | `chat-explore-group-content` | ExploreGroup 内层内容容器。包含 `data-group-kind` 和 `data-expanded`。 | +| Chat thinking 面板 | `chat-thinking-panel` | thinking/reasoning 面板根节点。包含 `data-status`、`data-streaming` 和 `data-expanded`。 | +| Chat thinking 展开按钮 | `chat-thinking-toggle` | 可点击的 thinking 展开/收起 header。 | +| Chat thinking 内容 | `chat-thinking-content` | thinking/reasoning 文本内容。包含 `data-status` 和 `data-streaming`。 | +| Chat shell 命令卡片 | `chat-shell-command-card` | Shell 命令工具卡根节点。包含 `data-status`、`data-expanded` 和 `data-terminal-session-id`。 | +| Chat shell 命令展开按钮 | `chat-shell-command-toggle` | Shell 命令卡片的展开/收起点击目标。 | +| Chat shell 命令文本 | `chat-shell-command-text` | Shell 命令文本节点。 | +| Chat shell 命令输出 | `chat-shell-command-output` | Shell 命令 stdout/stderr 或实时输出区域。 | +| Chat shell 命令退出码 | `chat-shell-command-exit-code` | 退出码节点。包含 `data-exit-code` 和 `data-status`。 | +| Chat shell 工具卡片 | `chat-shell-tool-card` | Bash 的外层 FlowToolCard wrapper。包含 `data-tool-name` 和 `data-tool-card-id`。 | +| Chat shell 工具打开面板按钮 | `chat-shell-tool-open-panel` | 存在 terminal session 时,从 Bash ToolCard 打开关联终端面板。 | +| Chat browser 工具卡片 | `chat-browser-tool-card` | WebFetch 的外层 FlowToolCard wrapper。包含 `data-tool-name` 和 `data-tool-card-id`。 | +| Chat 文件变更卡片 | `chat-file-change-card` | 文件操作卡片根节点。包含 `data-status`、`data-action`、`data-path` 和 `data-expanded`。 | +| Chat 文件变更展开按钮 | `chat-file-change-toggle` | 文件操作卡片的展开/收起点击目标。 | +| Chat 文件变更路径 | `chat-file-change-path` | 文件路径/名称节点。包含 `data-path`。 | +| Chat 文件变更动作 | `chat-file-change-action` | 文件操作动作节点。包含 `data-action`。 | +| Chat 文件变更预览 | `chat-file-change-preview` | 文件操作卡片的代码/diff 预览区域。 | +| Chat MiniApp 卡片 | `chat-miniapp-card` | MiniApp 结果卡片根节点。包含 `data-status`、`data-app-id` 和 `data-expanded`。 | +| Chat MiniApp 标题 | `chat-miniapp-title` | MiniApp 标题/名称节点。包含 `data-app-id`。 | +| Chat MiniApp 文件列表 | `chat-miniapp-file-list` | MiniApp 结果文件列表容器。 | +| Chat MiniApp 文件行 | `chat-miniapp-file-row` | MiniApp 结果文件行。包含 `data-path`。 | +| Chat MiniApp 打开按钮 | `chat-miniapp-open-btn` | 打开 MiniApp 场景。包含 `data-app-id`。 | + +## Settings + +| 元素名称 | data-testid | 说明 | +|---|---|---| +| Settings 场景根节点 | `settings-scene` | Settings 场景的根内容区。包含 `data-settings-tab`。 | +| Settings 场景内容 | `settings-scene-content` | 当前活动 settings tab 的内容 wrapper。 | +| Settings 导航根节点 | `settings-nav` | 左侧 settings 导航。 | +| Settings 导航 tab | `settings-nav-tab` | 重复项。配合 `data-settings-tab` 使用。 | + +## Settings Models + +| 元素名称 | data-testid | 说明 | +|---|---|---| +| 模型列表 | `settings-model-list` | 已配置模型行的容器。 | +| 创建第一个模型配置按钮 | `settings-model-create-first-config-btn` | 从空状态启动第一个模型提供商配置流程。 | +| 自定义模型配置按钮 | `settings-model-custom-config-btn` | 启动自定义提供商配置。包含 `data-provider-id="custom"`。 | +| 模型提供商选项 | `settings-model-provider-option` | 重复的提供商卡片。配合 `data-provider-id` 使用,例如 `openbitfun`。 | +| 模型提供商名称输入框 | `settings-model-provider-name-input` | 提供商/配置展示名称字段,例如 mock LLM 提供商名称。 | +| 模型 API key 输入框 | `settings-model-api-key-input` | 模型配置表单里的 API key 字段。测试中不要硬编码真实 key,应从 local config 读取。 | +| 模型 Base URL 输入框 | `settings-model-base-url-input` | 自定义/OpenAI-compatible 提供商的 API base URL 字段。 | +| 模型请求格式选择器 | `settings-model-request-format-select` | 请求格式选择器,例如 OpenAI-compatible 或 Anthropic。 | +| 模型选择按钮 | `settings-model-select-btn` | 打开模型选择下拉框。 | +| 模型选择菜单 | `settings-model-select-menu` | 模型选择下拉框根节点。 | +| 模型选择项 | `settings-model-option` | 重复的下拉项。配合 `data-model-id`、`data-model-name` 和 `data-selected` 使用。 | +| 手动模型名称输入框 | `settings-model-manual-name-input` | 手动/自定义模型名称输入字段。 | +| 添加自定义模型按钮 | `settings-model-add-custom-btn` | 将手动模型名称加入已选模型列表。 | +| 已选模型列表 | `settings-model-selected-list` | 已选模型草稿列表。包含 `data-selected-count`。 | +| 已选模型空状态 | `settings-model-selected-list-empty` | 已选模型草稿为空时的状态。包含 `data-selected-count="0"`。 | +| 已选模型行 | `settings-model-selected-row` | 重复的已选模型草稿。配合 `data-model-id`、`data-model-name`、`data-selected` 和 `data-expanded` 使用。 | +| 已选模型移除按钮 | `settings-model-selected-remove-btn` | 移除已选模型草稿。配合 `data-model-id` 和 `data-model-name` 使用。 | +| 模型保存按钮 | `settings-model-save-btn` | 保存模型提供商/模型配置表单。 | +| 模型行 | `settings-model-row` | 重复的已保存模型行。配合 `data-model-id`、`data-model-name` 和 `data-config-id` 使用。 | +| 模型测试状态 | `settings-model-test-status` | 重复的已保存模型测试状态。配合 `data-model-id`、`data-model-name`、`data-config-id` 和 `data-status` 使用,`data-status` 可为 `success` 或 `error`。 | + +## Settings Appearance + +| 元素名称 | data-testid | 说明 | +|---|---|---| +| Appearance 页面根节点 | `appearance-config` | Settings 场景中 Appearance 页面内容根节点。 | +| Appearance 主题区域 | `appearance-theme-section` | 语言和主题配置区域根节点。 | +| Appearance 字体区域 | `appearance-font-section` | 字体偏好配置区域根节点。 | +| Appearance 语言选择器 | `appearance-language-select` | Appearance 中 language Select 的真实触发节点。 | +| Appearance 语言选项 | `appearance-language-option` | 重复的语言下拉选项。包含 `data-locale-id`,并带有 Select 组件提供的 `data-selected`。 | +| Appearance 主题选择器 | `appearance-theme-select` | Appearance 中 theme Select 的真实触发节点。 | +| Appearance 主题选项 | `appearance-theme-option` | 重复的主题下拉选项。包含 `data-theme-id`,并带有 Select 组件提供的 `data-selected`。 | +| Appearance UI 字号分组 | `appearance-ui-font-level-group` | UI font size 预置级别按钮组根节点。 | +| Appearance UI 字号按钮 | `appearance-ui-font-level-btn` | 重复的 UI font size 预置级别按钮。包含 `data-font-level` 和 `data-selected`。 | +| Appearance UI 自定义字号控制区 | `appearance-ui-font-custom-controls` | custom UI 字号控制区根节点,仅在 custom 激活时渲染。 | +| Appearance UI 自定义字号输入框 | `appearance-ui-font-custom-input` | custom UI 字号 px 输入框。包含 `data-font-level="custom"`。 | +| Appearance UI 自定义字号减一按钮 | `appearance-ui-font-custom-step-minus` | custom UI 字号减一按钮。 | +| Appearance UI 自定义字号加一按钮 | `appearance-ui-font-custom-step-plus` | custom UI 字号加一按钮。 | +| Appearance UI 字号预览区 | `appearance-ui-font-preview` | UI 字号预览区域。 | +| Appearance Flow Chat 字号开关 | `appearance-flowchat-font-toggle` | Flow Chat 独立字号开关的真实 input 节点。 | +| Appearance Flow Chat 字号选择器 | `appearance-flowchat-font-select` | Flow Chat 字号 Select 的真实触发节点。 | +| Appearance Flow Chat 字号选项 | `appearance-flowchat-font-option` | 重复的 Flow Chat 字号下拉选项。包含 `data-font-px`,并带有 Select 组件提供的 `data-selected`。 | +| Appearance 字体重置按钮 | `appearance-font-reset-btn` | 重置字体偏好到默认值。 | + +## Shell Panel + +| 元素名称 | data-testid | 说明 | +|---|---|---| +| Shell 面板入口 | `shell-panel-entry` | 打开 Shell 场景/导航的底部入口。 | +| Shell 面板 | `shell-panel` | Shell 场景、Shell 导航或 Terminal 场景根节点。 | +| Shell 面板标题 | `shell-panel-title` | Shell 导航标题或当前终端 toolbar 标题。 | +| Shell 命令列表 | `shell-command-list` | Shell 导航终端列表或当前终端容器。 | +| Shell 命令项 | `shell-command-item` | Shell 导航行或当前 xterm 根节点。包含 `data-command-id`,可用时包含 `data-command-status`。 | +| Shell 命令文本 | `shell-command-text` | Shell 导航中的终端/session 标签。 | +| Shell 命令输出 | `shell-command-output` | 当前终端的真实 xterm 输出容器。 | +| Shell 命令退出码 | `shell-command-exit-code` | session 退出后终端状态栏中的退出码。包含 `data-exit-code` 和 `data-status`。 | +| Shell 命令状态 | `shell-command-status` | Shell 导航状态点、终端加载/错误状态或终端状态栏。包含 `data-command-status`。 | +| Shell 命令重新运行 | `shell-command-rerun` | 终端错误状态下的重试按钮,或活动终端 toolbar 上的 Ctrl+C 动作。 | +| Shell 面板关闭 | `shell-panel-close` | 当前终端关闭按钮。 | + +说明: + +- 独立 xterm 终端没有结构化的逐命令历史 DOM。测试应使用 `shell-command-output` 断言终端渲染输出,使用 `chat-shell-command-*` 断言结构化 Bash ToolCard。 +- `shell-command-copy` 当前未暴露,因为活动终端复制能力基于选择/右键上下文菜单,并不是稳定可见按钮。 + +## Browser Panel + +| 元素名称 | data-testid | 说明 | +|---|---|---| +| Browser 面板入口 | `browser-panel-entry` | 根据当前上下文打开 Browser 场景或 Browser 面板的底部入口。 | +| Browser 面板 | `browser-panel` | Browser 场景或右侧 Browser 面板根节点。 | +| Browser 面板标题 | `browser-panel-title` | Browser toolbar/form 区域。 | +| Browser URL 输入框 | `browser-url-input` | 真实 URL 输入框。按 Enter 打开输入的 URL。 | +| Browser 页面容器 | `browser-page-frame` | iframe/webview host 内容区域。 | +| Browser 加载状态 | `browser-loading-indicator` | URL 加载中时的刷新/加载图标。 | +| Browser 错误信息 | `browser-error-message` | URL 校验、连通性或 webview 加载失败信息。 | +| Browser 当前 URL | `browser-current-url` | webview placeholder 中展示的当前 URL。 | +| Browser 刷新按钮 | `browser-refresh-button` | 刷新当前 Browser 页面。 | +| Browser 后退按钮 | `browser-back-button` | Browser 历史后退。 | +| Browser 前进按钮 | `browser-forward-button` | Browser 历史前进。 | + +说明: + +- `browser-open-button` 当前未暴露,因为 URL 导航通过现有地址栏表单按 Enter 提交;当前没有独立可见的打开按钮。 +- `browser-panel-close` 属于外层 scene/canvas tab chrome,不在 Browser 组件自身内部。 + +## Notifications + +| 元素名称 | data-testid | 说明 | +|---|---|---| +| 通知按钮 | `notification-button` | 打开或切换通知中心。 | +| 通知中心对话框 | `notification-center` | 通知中心弹窗根节点。 | +| 通知中心关闭按钮 | `notification-center-close-btn` | 关闭通知中心。 | +| 通知中心活动区块 | `notification-center-active-section` | 仅在存在活动任务通知时出现。 | + +## Flow Chat Header + +| 元素名称 | data-testid | 说明 | +|---|---|---| +| 后台 subagents 按钮 | `flowchat-header-background-subagents` | 打开后台 subagent 活动状态。 | +| Pull requests 按钮 | `flowchat-header-pull-requests` | 打开 pull request 相关 UI。 | +| Turn 列表 | `flowchat-header-turn-list` | Turn 导航列表。 | +| 上一个 turn 按钮 | `flowchat-header-turn-prev` | 切换到上一个可见 turn。 | +| 下一个 turn 按钮 | `flowchat-header-turn-next` | 切换到下一个可见 turn。 | + +## Agents + +| 元素名称 | data-testid | 说明 | +|---|---|---| +| Agent/Skill 面板 | `agent-skill-panel` | Agents 发现页激活时的场景根节点。 | +| Agent 列表 | `agent-list` | 所有 agent 区域和卡片的容器。 | +| Agent 列表项 | `agent-list-item` | 重复卡片。包含 `data-agent-id`、`data-agent-name` 和 `data-agent-kind`。 | +| Agent 列表项标题 | `agent-list-item-title` | Agent 卡片标题。 | +| Agent 列表项描述 | `agent-list-item-description` | Agent 卡片描述。 | +| Agent 列表空状态 | `agent-list-empty` | Agent 列表区块为空时的状态。 | +| Agent 详情面板 | `agent-detail-panel` | Agent 详情弹窗根节点。 | +| Agent 详情标题 | `agent-detail-title` | Agent 详情弹窗标题。 | +| Agent 详情描述 | `agent-detail-description` | Agent 详情描述。 | +| Agent 详情工具区域 | `agent-detail-tools-section` | Agent 能力/工具区域。 | +| Agent 详情工具项 | `agent-detail-tool-item` | 重复的已启用工具项。包含 `data-tool-name`。 | +| Agent 详情关闭按钮 | `agent-detail-close` | 详情弹窗关闭按钮。 | +| Core 锚点按钮 | `agents-anchor-core` | 滚动到 core agents 区域。 | +| Teams 锚点按钮 | `agents-anchor-teams` | 滚动到 teams 区域。 | +| Custom agents 锚点按钮 | `agents-anchor-custom` | 滚动到 custom agents 区域。 | +| Agents 搜索按钮 | `agents-search-btn` | 搜索后缀按钮。 | +| Core agents 区域 | `agents-core-zone` | Core agents section。 | +| Teams 区域 | `agents-teams-zone` | Agent teams section。 | +| Custom agents 区域 | `agents-custom-zone` | Custom/subagent section。 | +| Review team 配置按钮 | `agents-review-team-configure-btn` | 打开 review team 配置。 | +| Agent source 过滤器 | `agents-source-filter` | 重复项。配合 `data-agent-source` 使用。 | +| Agent kind 过滤器 | `agents-kind-filter` | 重复项。配合 `data-agent-kind` 使用。 | +| 创建 agent 按钮 | `agents-create-agent-btn` | 打开 custom agent 创建页。 | +| Agent team 卡片 | `agents-team-card` | 重复项。配合 `data-team-id` 使用。 | +| BTW 停止 review 按钮 | `btw-session-panel-stop-review` | 从 BTW 面板停止 review session。 | +| BTW origin 按钮 | `btw-session-panel-origin-button` | 从 BTW 面板打开 origin session。 | + +## Skills + +| 元素名称 | data-testid | 说明 | +|---|---|---| +| Agent/Skill 面板 | `agent-skill-panel` | Skills 发现页激活时的场景根节点。 | +| Skill 列表 | `skill-list` | 默认安装技能列表网格,也用于 marketplace 搜索结果。 | +| Skill 列表项 | `skill-list-item` | 重复的已安装 skill 卡片。包含 `data-skill-id`、`data-skill-name`、`data-skill-key`、`data-skill-level` 和 `data-skill-builtin`。 | +| Skill 列表项标题 | `skill-list-item-title` | Skill 卡片标题。 | +| Skill 列表项描述 | `skill-list-item-description` | 存在时为 Skill 卡片描述。 | +| Skill 列表空状态 | `skill-list-empty` | 已安装或 marketplace skill 列表为空时的状态。 | +| Skill 详情面板 | `skill-detail-panel` | Skill 详情弹窗根节点。 | +| Skill 详情标题 | `skill-detail-title` | Skill 详情弹窗标题。 | +| Skill 详情描述 | `skill-detail-description` | Skill 详情描述。 | +| Skill 详情能力区域 | `skill-detail-capabilities-section` | 已安装或 marketplace skill 的详情元数据/能力说明区域。 | +| Skill 详情关闭按钮 | `skill-detail-close` | 详情弹窗关闭按钮。 | +| Skills tabs 根节点 | `skills-tabs` | Installed/discover tabs 容器。 | +| Installed tab | `skills-tab-installed` | 包含 `data-skills-tab-active`。 | +| Discover tab | `skills-tab-discover` | 包含 `data-skills-tab-active`。 | +| Installed 面板 | `skills-installed-panel` | 已安装 skills 视图根节点。 | +| Installed 侧边栏 | `skills-installed-sidebar` | 已安装 category 侧边栏。 | +| Installed category | `skills-installed-category` | 重复项。配合 `data-skill-category` 使用。 | +| Installed 内容区 | `skills-installed-content` | 已安装 skills 主内容。 | +| Installed 搜索 | `skills-installed-search` | 已安装 skills 搜索根节点。 | +| 隐藏重复项按钮 | `skills-hide-duplicates-btn` | 包含 `data-active`。 | +| 添加本地 skill 按钮 | `skills-add-local-btn` | 打开添加 skill 表单。 | +| Installed 加载状态 | `skills-installed-loading` | 加载骨架屏容器。 | +| Installed 错误状态 | `skills-installed-error` | 错误状态容器。 | +| Installed 空状态 | `skills-installed-empty` | 空状态容器。 | +| Installed grid | `skills-installed-grid` | 已安装 skill 卡片网格。 | +| Installed skill 卡片 | `skills-installed-card` | 重复项。配合 `data-skill-key`、`data-skill-level` 和 `data-skill-builtin` 使用。 | +| Installed 卡片路径按钮 | `skills-installed-card-path` | 重复项。配合 `data-skill-key` 使用。 | +| Installed 卡片删除按钮 | `skills-installed-card-delete` | 重复项。配合 `data-skill-key` 使用。 | +| Installed 分页 | `skills-installed-pagination` | 已安装列表分页根节点。 | +| Installed 上一页 | `skills-installed-page-prev` | 上一页按钮。 | +| Installed 下一页 | `skills-installed-page-next` | 下一页按钮。 | +| Discover 面板 | `skills-discover-panel` | Marketplace 视图根节点。 | +| Discover 搜索 | `skills-discover-search` | Marketplace 搜索根节点。 | +| Discover 内容区 | `skills-discover-content` | Marketplace 内容区域。 | +| Discover 加载状态 | `skills-discover-loading` | 初始加载骨架屏容器。 | +| Discover 分页加载状态 | `skills-discover-page-loading` | 翻页时的加载状态。 | +| Discover 错误状态 | `skills-discover-error` | 错误状态容器。 | +| Discover 空状态 | `skills-discover-empty` | 空状态容器。 | +| Discover grid | `skills-discover-grid` | Marketplace 卡片网格。 | +| Market skill 卡片 | `skills-market-card` | 重复项。配合 `data-skill-install-id` 和 `data-skill-installed` 使用。 | +| Skill 卡片动作 | `skills-card-action` | 重复卡片动作。配合 `data-skill-action` 使用。 | +| Discover 分页 | `skills-discover-pagination` | Marketplace 分页根节点。 | +| Discover 上一页 | `skills-discover-page-prev` | 上一页按钮。 | +| Discover 下一页 | `skills-discover-page-next` | 下一页按钮。 | +| 详情删除按钮 | `skills-detail-delete-btn` | 删除选中的已安装 skill。 | +| 详情已安装按钮 | `skills-detail-installed-btn` | Marketplace 详情中的 disabled installed 标记。 | +| 详情项目级下载按钮 | `skills-detail-download-project-btn` | 将 market skill 下载到 project scope。 | +| 详情用户级下载按钮 | `skills-detail-download-user-btn` | 将 market skill 下载到 user scope。 | +| 详情路径按钮 | `skills-detail-path-btn` | 显示已安装 skill 路径。 | +| 详情外部链接 | `skills-detail-external-link` | 打开 marketplace 链接。 | +| 添加表单 | `skills-add-form` | 添加本地 skill 弹窗内容。 | +| 添加路径输入框 | `skills-add-path-input` | 本地 skill 路径输入框。 | +| 添加浏览按钮 | `skills-add-browse-btn` | 打开路径选择器。 | +| 添加校验结果 | `skills-add-validation` | 包含 `data-validation-valid`。 | +| 添加取消按钮 | `skills-add-cancel-btn` | 关闭添加表单。 | +| 添加提交按钮 | `skills-add-submit-btn` | 添加已校验的本地 skill。 | diff --git a/docs/development/ui-testids.md b/docs/development/ui-testids.md new file mode 100644 index 0000000000..5adc253b02 --- /dev/null +++ b/docs/development/ui-testids.md @@ -0,0 +1,429 @@ +[中文](ui-testids-CN.md) | **English** + +# UI Test IDs + +This document records stable `data-testid` values used by BitFun UI automation. +Test IDs are grouped by product area and should be added only when an automated +workflow needs a stable locator. + +Rules: + +- Use `data-testid` only as a test locator. Do not branch product logic on it. +- Prefer the real interactive element: `button`, `input`, editable region, or dialog root. +- Keep `data-testid` values stable, lowercase, and hyphen-separated. +- For repeated items, use one shared `data-testid` plus a stable data attribute. +- Do not use visible text, CSS classes, coordinates, screenshots, or XPath paths as primary locators. +- Prefer stable product identifiers in companion `data-*` attributes, such as `data-workspace-id`, `data-session-id`, `data-agent-id`, `data-skill-key`, or `data-settings-tab`. + +## Coverage Planning + +### Must Add + +These areas are high-value UI automation entry points and should have stable IDs +before adding or expanding cross-platform pytest cases. + +| Area | Scope | Rationale | +|---|---|---| +| App shell | App root, main content, scene viewport | App load and routing readiness anchors. | +| Navigation | Top actions, footer menu, workspace menu, workspace rows, session rows | Main path for opening settings, sessions, projects, agents, skills, and workspace-scoped actions. | +| Welcome scene | Scene root, open/new project buttons, recent workspace list | Default startup path currently lands here on OH. | +| Notifications | Notification button, center root, close button, active section | Current smoke coverage and async task visibility. | +| Settings | Scene root, nav tabs, active content | Current smoke coverage and future configuration tests. | +| Session and Flow Chat | Session scene, chat/aux panes, message list, composer | Main product workflow once session creation is stable. | +| Agents and Skills | Scene roots, zones/tabs, filters, cards, key actions | High-value navigation and marketplace/agent setup flows. | + +### Optional Add + +Add these when a concrete test needs them. + +| Area | Scope | Rationale | +|---|---|---| +| Deep Review / BTW detail panels | Review action bars, reviewer/member details, report export actions | Valuable for deeper behavior tests, but not needed for app smoke. | +| Tool cards | Specific approve/retry/open-detail controls | Add per tool workflow instead of tagging every rendered result field. | +| File, Git, Terminal, Browser panels | Panel roots, primary toolbar actions, selected list rows | Useful once panel-specific pytest coverage exists. | +| Settings form controls | Specific model/provider fields and save/reset buttons | Add with configuration tests; avoid tagging every display-only label. | +| Mini apps | Gallery root, app cards, runner root | Add when Mini App flows enter the automation plan. | + +### Not Recommended + +Avoid adding IDs to these surfaces unless there is a clear automated workflow. + +| Scope | Reason | +|---|---| +| Decorative icons, badges, counters, shadows, animations | Not meaningful interaction or state anchors. | +| Every text node, paragraph, and static label | Creates maintenance cost and duplicates i18n-visible content. | +| Generated markdown/code content and model output spans | Output is dynamic and should be asserted through higher-level state. | +| Coordinates, canvas pixels, screenshot-only markers, or native window controls | Cross-platform WebView automation should stay DOM and `data-testid` based. | +| Localized text copied into `data-testid` or required as the primary locator | Breaks when locales or copy change. | + +## Naming + +- Use area prefixes: `app-*`, `scene-*`, `nav-*`, `welcome-*`, `settings-*`, `notification-*`, `session-*`, `chat-*`, `flowchat-*`, `agents-*`, `skills-*`. +- Use action suffixes for buttons: `*-btn`, `*-toggle`, `*-open`, `*-close`, `*-submit`, `*-cancel`, `*-delete`. +- Use structure suffixes for containers: `*-scene`, `*-panel`, `*-list`, `*-grid`, `*-menu`, `*-content`, `*-zone`. +- For repeated rows/cards, reuse one `data-testid` and pair it with a stable attribute, for example: + - `nav-workspace-item` + `data-workspace-id` + - `nav-session-item` + `data-session-id` + - `settings-nav-tab` + `data-settings-tab` + - `agent-list-item` + `data-agent-id` / `data-agent-name` + - `skill-list-item` + `data-skill-id` / `data-skill-name` + - `skills-market-card` + `data-skill-install-id` + +## App Shell + +| Element name | data-testid | Notes | +|---|---|---| +| App layout root | `app-layout` | App load-ready anchor. | +| Main content area | `app-main-content` | Primary scene content container. | +| Navigation panel | `nav-panel` | Left navigation container. | +| Scene viewport root | `scene-viewport` | Scene host root. | +| Scene viewport clip | `scene-viewport-clip` | Mounted scene clip area. | +| Empty scene viewport | `scene-viewport-empty` | Rendered when no tabs are open. | +| Mounted scene wrapper | `scene-viewport-scene` | Repeated item. Pair with `data-scene-id` and `data-scene-active`. | + +## Welcome + +| Element name | data-testid | Notes | +|---|---|---| +| Welcome scene root | `welcome-scene` | Default startup scene anchor. | +| Open project button | `welcome-open-project-btn` | Opens the file/folder picker. | +| New project button | `welcome-new-project-btn` | Opens the new project flow. | +| Recent workspace list | `welcome-recent-workspace-list` | Present when recent workspaces exist. | +| Recent workspace row | `welcome-recent-workspace-row` | Repeated item. Pair with `data-workspace-id`. | +| Recent workspace open button | `welcome-recent-workspace-open` | Repeated item. Pair with `data-workspace-id`. | +| Recent workspace remove button | `welcome-recent-workspace-remove` | Repeated item. Pair with `data-workspace-id`. | +| Recent workspace empty state | `welcome-recent-workspace-empty` | Present when no recent workspace is available. | + +## Navigation + +| Element name | data-testid | Notes | +|---|---|---| +| Nav search trigger | `nav-search-trigger` | Opens navigation search. | +| New code session button | `nav-new-code-session-btn` | Creates or opens a code session for the active project workspace. | +| New cowork session button | `nav-new-cowork-session-btn` | Creates or opens a cowork session for the active project workspace. | +| Assistant button | `nav-assistant-btn` | Opens assistant/persona scene. | +| Agent/Skill entry | `agent-skill-entry` | Expands the Agents/Skills navigation entry group. | +| Agent/Skill panel | `agent-skill-panel` | Agents/Skills entry group or active discovery scene root. | +| Agent/Skill tabs | `agent-skill-tabs` | Navigation tab container for Agent and Skill entries. | +| Agent tab | `agent-tab` | Opens the Agents discovery scene. | +| Skill tab | `skill-tab` | Opens the Skills discovery scene. | +| Navigation sections | `nav-sections` | Container for workspace/session sections. | +| Navigation bottom bar | `nav-bottom-bar` | Container for Mini App/footer region. | +| Footer more button | `nav-footer-more-btn` | Opens the footer overflow menu. | +| Footer menu | `nav-footer-menu` | Overflow menu opened from the footer more button. | +| Footer settings item | `nav-footer-settings-item` | Opens the Settings scene from the footer menu. | +| Footer shell button | `shell-panel-entry` | Opens or closes the shell scene nav. | +| Footer browser button | `browser-panel-entry` | Opens browser scene or browser panel depending on active context. | + +## Navigation Workspaces + +| Element name | data-testid | Notes | +|---|---|---| +| Workspace add button | `nav-workspace-add-btn` | Opens workspace add/recent menu. | +| Workspace add menu | `nav-workspace-menu` | Portal menu opened from add button. | +| Workspace menu open project | `nav-workspace-menu-open-project` | Opens project picker. | +| Workspace menu new project | `nav-workspace-menu-new-project` | Opens new project flow. | +| Workspace menu remote SSH | `nav-workspace-menu-remote-ssh` | Opens SSH remote connect flow. | +| Workspace menu recent workspace | `nav-workspace-menu-recent-workspace` | Repeated item. Pair with `data-workspace-id`. | +| Workspace list | `nav-workspace-list` | Repeated by list type. Pair with `data-workspace-list`. | +| Workspace list empty state | `nav-workspace-list-empty` | Pair with `data-workspace-list`. | +| Workspace drop target | `nav-workspace-drop-target` | Repeated drag target. Pair with `data-workspace-id`. | +| Workspace row | `nav-workspace-item` | Repeated item. Pair with `data-workspace-id`, `data-workspace-kind`, and `data-workspace-active`. | +| Workspace card | `nav-workspace-card` | Clickable row body. Pair with `data-workspace-id`. | +| Workspace sessions toggle | `nav-workspace-sessions-toggle` | Expands/collapses session rows. Pair with `data-workspace-id`. | +| Workspace name button | `nav-workspace-name-btn` | Activates workspace or toggles sessions. Pair with `data-workspace-id`. | +| Workspace files button | `nav-workspace-files-btn` | Opens file viewer for workspace. Pair with `data-workspace-id`. | +| Workspace search index button | `nav-workspace-search-index-btn` | Opens search index status modal when present. Pair with `data-workspace-id`. | +| Workspace row menu button | `nav-workspace-menu-btn` | Opens row action menu. Pair with `data-workspace-id`. | +| Workspace row menu | `nav-workspace-item-menu` | Portal menu for one workspace. Pair with `data-workspace-id`. | +| Workspace create session | `nav-workspace-menu-create-session` | Assistant workspace session action. | +| Workspace create code session | `nav-workspace-menu-create-code-session` | Normal workspace code session action. | +| Workspace create cowork session | `nav-workspace-menu-create-cowork-session` | Normal workspace cowork session action. | +| Workspace create ACP session | `nav-workspace-menu-create-acp-session` | Repeated item. Pair with `data-acp-client-id`. | +| Workspace create init session | `nav-workspace-menu-create-init-session` | Starts AGENTS.md/init session. | +| Workspace related paths | `nav-workspace-menu-related-paths` | Opens related paths dialog. | +| Workspace new worktree | `nav-workspace-menu-new-worktree` | Opens worktree creation dialog. | +| Workspace delete worktree | `nav-workspace-menu-delete-worktree` | Deletes linked worktree workspace. | +| Workspace copy path | `nav-workspace-menu-copy-path` | Copies workspace path. | +| Workspace reveal | `nav-workspace-menu-reveal` | Reveals workspace in file explorer. | +| Workspace close | `nav-workspace-menu-close` | Closes workspace. | +| Workspace reset assistant | `nav-workspace-menu-reset-assistant` | Resets default assistant workspace. | +| Workspace delete assistant | `nav-workspace-menu-delete-assistant` | Deletes named assistant workspace. | +| Workspace session region | `nav-workspace-session-region` | Contains sessions for one workspace. Pair with `data-workspace-id`. | + +## Navigation Sessions + +| Element name | data-testid | Notes | +|---|---|---| +| Session list | `nav-session-list` | Workspace-scoped list. Pair with `data-workspace-id`. | +| Session row | `nav-session-item` | Repeated item. Pair with `data-session-id`, `data-session-kind`, `data-session-level`, and `data-session-active`. | +| Session menu button | `nav-session-menu-btn` | Opens row action menu. Pair with `data-session-id`. | +| Session menu | `nav-session-menu` | Portal menu for one session. Pair with `data-session-id`. | +| Session rename item | `nav-session-menu-rename` | Starts session rename. | +| Session delete item | `nav-session-menu-delete` | Deletes session. | +| Session list toggle | `nav-session-list-toggle` | Expands/collapses long session lists. | + +## Session And Chat + +| Element name | data-testid | Notes | +|---|---|---| +| Session scene root | `session-scene` | Session scene anchor. | +| Session chat pane | `session-chat-pane` | Left chat pane within session scene. | +| Session right pane resizer | `session-right-pane-resizer` | Splitter between chat and aux pane. | +| Session aux pane | `session-aux-pane` | Right content canvas pane. Includes `data-mode`. | +| Chat pane root | `chat-pane` | FlowChat host pane. | +| FlowChat container | `flowchat-container` | FlowChat root. Includes `data-session-id`. | +| FlowChat messages region | `flowchat-messages` | Message list/welcome panel host. | +| FlowChat message list | `flowchat-message-list` | Virtual message list root when messages exist. | +| FlowChat empty message list | `flowchat-message-list-empty` | Empty virtual list state. | +| FlowChat message item | `flowchat-message-item` | Repeated virtual item. Pair with `data-turn-id`, `data-item-type`, and `data-item-index`. | +| Chat input container | `chat-input-container` | Root container for the composer. | +| Chat input editable region | `chat-input-textarea` | Rich text editable region. | +| Chat send button | `chat-input-send-btn` | Send action when input is valid. | +| Chat cancel button | `chat-input-cancel-btn` | Cancels in-progress send/generation when present. | +| Chat input workspace strip | `chat-input-workspace-strip` | Active workspace strip above composer. | +| Chat input target switcher | `chat-input-target-switcher` | Target/mode switcher. | +| Chat input image strip | `chat-input-image-strip` | Attached image strip. | +| Chat input start BTW button | `chat-input-boost-start-btw` | Starts the BTW flow when present. | +| Chat model selector button | `chat-model-selector-btn` | Opens the session model selector. | +| Chat model selector menu | `chat-model-selector-menu` | Model selector dropdown root. | +| Chat model selector option | `chat-model-selector-option` | Repeated item. Pair with `data-model-id`, `data-model-name`, and `data-selected`. | +| Chat user message | `chat-user-message` | Repeated user message. Pair with `data-turn-id`, `data-status`, and `data-failed`. | +| Chat user message content | `chat-user-message-content` | User message text content. Pair with `data-turn-id`. | +| Chat assistant message | `chat-assistant-message` | Repeated model round container. Pair with `data-turn-id`, `data-round-id`, `data-status`, `data-model-id`, `data-model-alias`, and `data-streaming`. | +| Chat assistant message content | `chat-assistant-message-content` | Assistant text block. Pair with `data-turn-id`, `data-flow-item-id`, `data-status`, and `data-streaming`. | +| Chat explore group | `chat-explore-group` | Explore-group root that wraps collapsed/merged tool rounds. Includes `data-group-kind`, `data-expanded`, `data-read-count`, `data-search-count`, and `data-command-count`. | +| Chat explore group toggle | `chat-explore-group-toggle` | Real click target that expands/collapses an explore group. Includes `data-group-kind` and `data-expanded`. | +| Chat explore group content | `chat-explore-group-content` | Inner content container for explore-group items. Includes `data-group-kind` and `data-expanded`. | +| Chat thinking panel | `chat-thinking-panel` | Thinking/reasoning panel root. Includes `data-status`, `data-streaming`, and `data-expanded`. | +| Chat thinking toggle | `chat-thinking-toggle` | Clickable thinking expand/collapse header. | +| Chat thinking content | `chat-thinking-content` | Thinking/reasoning text content. Includes `data-status` and `data-streaming`. | +| Chat shell command card | `chat-shell-command-card` | Shell command tool card root. Includes `data-status`, `data-expanded`, and `data-terminal-session-id`. | +| Chat shell command toggle | `chat-shell-command-toggle` | Click target for expanding/collapsing a shell command card. | +| Chat shell command text | `chat-shell-command-text` | Shell command text node. | +| Chat shell command output | `chat-shell-command-output` | Shell command stdout/stderr or live output area. | +| Chat shell command exit code | `chat-shell-command-exit-code` | Exit code node. Includes `data-exit-code` and `data-status`. | +| Chat shell tool card | `chat-shell-tool-card` | Outer FlowToolCard wrapper for Bash. Includes `data-tool-name` and `data-tool-card-id`. | +| Chat shell tool open panel | `chat-shell-tool-open-panel` | Opens the associated terminal panel when a terminal session is available. | +| Chat browser tool card | `chat-browser-tool-card` | Outer FlowToolCard wrapper for WebFetch. Includes `data-tool-name` and `data-tool-card-id`. | +| Chat file change card | `chat-file-change-card` | File operation card root. Includes `data-status`, `data-action`, `data-path`, and `data-expanded`. | +| Chat file change toggle | `chat-file-change-toggle` | Click target for expanding/collapsing a file operation card. | +| Chat file change path | `chat-file-change-path` | File path/name node. Includes `data-path`. | +| Chat file change action | `chat-file-change-action` | File operation action node. Includes `data-action`. | +| Chat file change preview | `chat-file-change-preview` | Code/diff preview area for file operation cards. | +| Chat MiniApp card | `chat-miniapp-card` | MiniApp result card root. Includes `data-status`, `data-app-id`, and `data-expanded`. | +| Chat MiniApp title | `chat-miniapp-title` | MiniApp title/name node. Includes `data-app-id`. | +| Chat MiniApp file list | `chat-miniapp-file-list` | MiniApp result file list container. | +| Chat MiniApp file row | `chat-miniapp-file-row` | MiniApp result file row. Includes `data-path`. | +| Chat MiniApp open button | `chat-miniapp-open-btn` | Opens the MiniApp scene. Includes `data-app-id`. | +| Pending queue panel | `pending-queue-panel` | Pending background task queue. | + +## Settings + +| Element name | data-testid | Notes | +|---|---|---| +| Settings scene root | `settings-scene` | Root content area for the Settings scene. Includes `data-settings-tab`. | +| Settings scene content | `settings-scene-content` | Active settings tab content wrapper. | +| Settings navigation root | `settings-nav` | Left-side settings navigation. | +| Settings navigation tab | `settings-nav-tab` | Repeated item. Pair with `data-settings-tab`. | + +## Settings Models + +| Element name | data-testid | Notes | +|---|---|---| +| Model list | `settings-model-list` | Container for configured model rows. | +| Create first model config button | `settings-model-create-first-config-btn` | Starts the first model provider setup from the empty state. | +| Custom model config button | `settings-model-custom-config-btn` | Starts custom provider configuration. Includes `data-provider-id="custom"`. | +| Model provider option | `settings-model-provider-option` | Repeated provider card. Pair with `data-provider-id`, for example `openbitfun`. | +| Model provider name input | `settings-model-provider-name-input` | Provider/config display name field, such as a mock LLM provider name. | +| Model API key input | `settings-model-api-key-input` | API key field in the model configuration form. Do not hardcode real keys in tests; load them from local config. | +| Model base URL input | `settings-model-base-url-input` | API base URL field for custom/OpenAI-compatible providers. | +| Model request format select | `settings-model-request-format-select` | Request format selector, for example OpenAI-compatible vs Anthropic. | +| Model select button | `settings-model-select-btn` | Opens the model selection dropdown. | +| Model selection menu | `settings-model-select-menu` | Model selection dropdown root. | +| Model selection option | `settings-model-option` | Repeated dropdown item. Pair with `data-model-id`, `data-model-name`, and `data-selected`. | +| Manual model name input | `settings-model-manual-name-input` | Manual/custom model name entry field. | +| Add custom model button | `settings-model-add-custom-btn` | Adds the manual model name into the selected model list. | +| Selected model list | `settings-model-selected-list` | Selected model draft list. Includes `data-selected-count`. | +| Selected model empty state | `settings-model-selected-list-empty` | Empty selected model draft state. Includes `data-selected-count="0"`. | +| Selected model row | `settings-model-selected-row` | Repeated selected model draft. Pair with `data-model-id`, `data-model-name`, `data-selected`, and `data-expanded`. | +| Selected model remove button | `settings-model-selected-remove-btn` | Removes a selected model draft. Pair with `data-model-id` and `data-model-name`. | +| Model save button | `settings-model-save-btn` | Saves the model provider/configuration form. | +| Model row | `settings-model-row` | Repeated saved model row. Pair with `data-model-id`, `data-model-name`, and `data-config-id`. | +| Model test status | `settings-model-test-status` | Repeated saved model test status. Pair with `data-model-id`, `data-model-name`, `data-config-id`, and `data-status` (`success` or `error`). | + +## Settings Appearance + +| Element name | data-testid | Notes | +|---|---|---| +| Appearance config root | `appearance-config` | Appearance page content root inside the settings scene. | +| Appearance theme section | `appearance-theme-section` | Language and theme settings section root. | +| Appearance font section | `appearance-font-section` | Font preference section root. | +| Appearance language select | `appearance-language-select` | Language select trigger in Appearance settings. | +| Appearance language option | `appearance-language-option` | Repeated language dropdown option. Includes `data-locale-id` and Select-provided `data-selected`. | +| Appearance theme select | `appearance-theme-select` | Theme select trigger in Appearance settings. | +| Appearance theme option | `appearance-theme-option` | Repeated theme dropdown option. Includes `data-theme-id` and Select-provided `data-selected`. | +| Appearance UI font level group | `appearance-ui-font-level-group` | UI font preset button group root. | +| Appearance UI font level button | `appearance-ui-font-level-btn` | Repeated preset button. Includes `data-font-level` and `data-selected`. | +| Appearance UI font custom controls | `appearance-ui-font-custom-controls` | Custom UI font px controls root, rendered when custom is active. | +| Appearance UI font custom input | `appearance-ui-font-custom-input` | Custom UI font px number input. Includes `data-font-level="custom"`. | +| Appearance UI font custom step minus | `appearance-ui-font-custom-step-minus` | Custom UI font px decrement button. | +| Appearance UI font custom step plus | `appearance-ui-font-custom-step-plus` | Custom UI font px increment button. | +| Appearance UI font preview | `appearance-ui-font-preview` | UI font preview area. | +| Appearance Flow Chat font toggle | `appearance-flowchat-font-toggle` | Flow Chat independent font size toggle input. | +| Appearance Flow Chat font select | `appearance-flowchat-font-select` | Flow Chat font size select trigger. | +| Appearance Flow Chat font option | `appearance-flowchat-font-option` | Repeated Flow Chat font size option. Includes `data-font-px` and Select-provided `data-selected`. | +| Appearance font reset button | `appearance-font-reset-btn` | Resets font preferences to defaults. | + +## Shell Panel + +| Element name | data-testid | Notes | +|---|---|---| +| Shell panel entry | `shell-panel-entry` | Footer entry that opens the Shell scene/nav. | +| Shell panel | `shell-panel` | Shell scene, shell nav, or terminal scene root. | +| Shell panel title | `shell-panel-title` | Shell nav title or active terminal toolbar title. | +| Shell command list | `shell-command-list` | Shell nav terminal list or active terminal container. | +| Shell command item | `shell-command-item` | Shell nav row or active xterm root. Includes `data-command-id` and, when available, `data-command-status`. | +| Shell command text | `shell-command-text` | Shell nav terminal/session label. | +| Shell command output | `shell-command-output` | Real xterm output container for the active terminal. | +| Shell command exit code | `shell-command-exit-code` | Terminal status bar exit code when the session has exited. Includes `data-exit-code` and `data-status`. | +| Shell command status | `shell-command-status` | Shell nav status dot, terminal loading/error state, or terminal status bar. Includes `data-command-status`. | +| Shell command rerun | `shell-command-rerun` | Retry button in terminal error state or Ctrl+C toolbar action on active terminal. | +| Shell panel close | `shell-panel-close` | Active terminal close button. | + +Notes: + +- The standalone xterm terminal does not expose a structured per-command history DOM. Tests should use `shell-command-output` for rendered terminal output and `chat-shell-command-*` for structured Bash ToolCard assertions. +- `shell-command-copy` is not currently exposed because the active terminal copy action is context-menu/selection driven rather than a stable visible button. + +## Browser Panel + +| Element name | data-testid | Notes | +|---|---|---| +| Browser panel entry | `browser-panel-entry` | Footer entry that opens the Browser scene or Browser panel, depending on active context. | +| Browser panel | `browser-panel` | Browser scene or right-side Browser panel root. | +| Browser panel title | `browser-panel-title` | Browser toolbar/form region. | +| Browser URL input | `browser-url-input` | Real URL input field. Press Enter to open the typed URL. | +| Browser page frame | `browser-page-frame` | iframe/webview host content area. | +| Browser loading indicator | `browser-loading-indicator` | Refresh/loading icon while a URL is loading. | +| Browser error message | `browser-error-message` | URL validation/connectivity/webview load failure message. | +| Browser current URL | `browser-current-url` | Current URL display in the webview placeholder. | +| Browser refresh button | `browser-refresh-button` | Refreshes the current browser page. | +| Browser back button | `browser-back-button` | Navigates browser history back. | +| Browser forward button | `browser-forward-button` | Navigates browser history forward. | + +Notes: + +- `browser-open-button` is not currently exposed because URL navigation is submitted by the existing address form via Enter; no dedicated visible open button exists. +- `browser-panel-close` depends on the surrounding scene/canvas tab chrome rather than the Browser component itself. + +## Notifications + +| Element name | data-testid | Notes | +|---|---|---| +| Notification button | `notification-button` | Opens or toggles the notification center. | +| Notification center dialog | `notification-center` | Notification center modal root. | +| Notification center close button | `notification-center-close-btn` | Closes the notification center. | +| Notification center active section | `notification-center-active-section` | Present only when active task notifications exist. | + +## Flow Chat Header + +| Element name | data-testid | Notes | +|---|---|---| +| Background subagents button | `flowchat-header-background-subagents` | Opens background subagent activity state. | +| Pull requests button | `flowchat-header-pull-requests` | Opens pull request related UI. | +| Turn list | `flowchat-header-turn-list` | Turn navigation list. | +| Previous turn button | `flowchat-header-turn-prev` | Moves to previous visible turn. | +| Next turn button | `flowchat-header-turn-next` | Moves to next visible turn. | + +## Agents + +| Element name | data-testid | Notes | +|---|---|---| +| Agent/Skill panel | `agent-skill-panel` | Agents scene root when the Agents discovery page is active. | +| Agent list | `agent-list` | Container for all agent zones and cards. | +| Agent list item | `agent-list-item` | Repeated card. Includes `data-agent-id`, `data-agent-name`, and `data-agent-kind`. | +| Agent list item title | `agent-list-item-title` | Agent card title. | +| Agent list item description | `agent-list-item-description` | Agent card description. | +| Agent list empty | `agent-list-empty` | Empty state for an agent list section. | +| Agent detail panel | `agent-detail-panel` | Agent detail modal root. | +| Agent detail title | `agent-detail-title` | Agent detail modal title. | +| Agent detail description | `agent-detail-description` | Agent detail description. | +| Agent detail tools section | `agent-detail-tools-section` | Agent capability/tools section. | +| Agent detail tool item | `agent-detail-tool-item` | Repeated enabled tool item. Includes `data-tool-name`. | +| Agent detail close | `agent-detail-close` | Modal close button. | +| Core anchor button | `agents-anchor-core` | Scrolls to core agents zone. | +| Teams anchor button | `agents-anchor-teams` | Scrolls to teams zone. | +| Custom agents anchor button | `agents-anchor-custom` | Scrolls to custom agents zone. | +| Agents search button | `agents-search-btn` | Search suffix button. | +| Core agents zone | `agents-core-zone` | Core agents section. | +| Teams zone | `agents-teams-zone` | Agent teams section. | +| Custom agents zone | `agents-custom-zone` | Custom/subagent section. | +| Review team configure button | `agents-review-team-configure-btn` | Opens review team configuration. | +| Agent source filter | `agents-source-filter` | Repeated item. Pair with `data-agent-source`. | +| Agent kind filter | `agents-kind-filter` | Repeated item. Pair with `data-agent-kind`. | +| Create agent button | `agents-create-agent-btn` | Opens custom agent creation page. | +| Agent team card | `agents-team-card` | Repeated item. Pair with `data-team-id`. | +| BTW stop review button | `btw-session-panel-stop-review` | Stops review session from BTW panel. | +| BTW origin button | `btw-session-panel-origin-button` | Opens origin session from BTW panel. | + +## Skills + +| Element name | data-testid | Notes | +|---|---|---| +| Agent/Skill panel | `agent-skill-panel` | Skills scene root when the Skills discovery page is active. | +| Skill list | `skill-list` | Installed skill list grid by default. Also used for marketplace results. | +| Skill list item | `skill-list-item` | Repeated installed skill card. Includes `data-skill-id`, `data-skill-name`, `data-skill-key`, `data-skill-level`, and `data-skill-builtin`. | +| Skill list item title | `skill-list-item-title` | Skill card title. | +| Skill list item description | `skill-list-item-description` | Skill card description when present. | +| Skill list empty | `skill-list-empty` | Empty state for installed or marketplace skill list. | +| Skill detail panel | `skill-detail-panel` | Skill detail modal root. | +| Skill detail title | `skill-detail-title` | Skill detail modal title. | +| Skill detail description | `skill-detail-description` | Skill detail description. | +| Skill detail capabilities section | `skill-detail-capabilities-section` | Detail metadata/capability rows for installed or marketplace skill. | +| Skill detail close | `skill-detail-close` | Modal close button. | +| Skills tabs root | `skills-tabs` | Installed/discover tabs container. | +| Installed tab | `skills-tab-installed` | Includes `data-skills-tab-active`. | +| Discover tab | `skills-tab-discover` | Includes `data-skills-tab-active`. | +| Installed panel | `skills-installed-panel` | Installed skills view root. | +| Installed sidebar | `skills-installed-sidebar` | Installed category sidebar. | +| Installed category | `skills-installed-category` | Repeated item. Pair with `data-skill-category`. | +| Installed content | `skills-installed-content` | Main installed skills content. | +| Installed search | `skills-installed-search` | Installed skills search root. | +| Hide duplicates button | `skills-hide-duplicates-btn` | Includes `data-active`. | +| Add local skill button | `skills-add-local-btn` | Opens add skill form. | +| Installed loading state | `skills-installed-loading` | Loading skeleton container. | +| Installed error state | `skills-installed-error` | Error state container. | +| Installed empty state | `skills-installed-empty` | Empty state container. | +| Installed grid | `skills-installed-grid` | Installed skills card grid. | +| Installed skill card | `skills-installed-card` | Repeated item. Pair with `data-skill-key`, `data-skill-level`, and `data-skill-builtin`. | +| Installed card path button | `skills-installed-card-path` | Repeated item. Pair with `data-skill-key`. | +| Installed card delete button | `skills-installed-card-delete` | Repeated item. Pair with `data-skill-key`. | +| Installed pagination | `skills-installed-pagination` | Installed list pagination root. | +| Installed previous page | `skills-installed-page-prev` | Previous page button. | +| Installed next page | `skills-installed-page-next` | Next page button. | +| Discover panel | `skills-discover-panel` | Marketplace view root. | +| Discover search | `skills-discover-search` | Marketplace search root. | +| Discover content | `skills-discover-content` | Marketplace content area. | +| Discover loading state | `skills-discover-loading` | Initial loading skeleton container. | +| Discover page loading state | `skills-discover-page-loading` | Loading state for page changes. | +| Discover error state | `skills-discover-error` | Error state container. | +| Discover empty state | `skills-discover-empty` | Empty state container. | +| Discover grid | `skills-discover-grid` | Marketplace card grid. | +| Market skill card | `skills-market-card` | Repeated item. Pair with `data-skill-install-id` and `data-skill-installed`. | +| Skill card action | `skills-card-action` | Repeated card action. Pair with `data-skill-action`. | +| Discover pagination | `skills-discover-pagination` | Marketplace pagination root. | +| Discover previous page | `skills-discover-page-prev` | Previous page button. | +| Discover next page | `skills-discover-page-next` | Next page button. | +| Detail delete button | `skills-detail-delete-btn` | Deletes selected installed skill. | +| Detail installed button | `skills-detail-installed-btn` | Disabled installed marker for marketplace detail. | +| Detail project download button | `skills-detail-download-project-btn` | Downloads market skill to project scope. | +| Detail user download button | `skills-detail-download-user-btn` | Downloads market skill to user scope. | +| Detail path button | `skills-detail-path-btn` | Reveals installed skill path. | +| Detail external link | `skills-detail-external-link` | Opens marketplace link. | +| Add form | `skills-add-form` | Add local skill modal content. | +| Add path input | `skills-add-path-input` | Local skill path input. | +| Add browse button | `skills-add-browse-btn` | Opens path picker. | +| Add validation result | `skills-add-validation` | Includes `data-validation-valid`. | +| Add cancel button | `skills-add-cancel-btn` | Closes add form. | +| Add submit button | `skills-add-submit-btn` | Adds validated local skill. | diff --git a/src/crates/services/services-integrations/src/mcp/protocol/transport_remote.rs b/src/crates/services/services-integrations/src/mcp/protocol/transport_remote.rs index 5a5facde65..77e984a27e 100644 --- a/src/crates/services/services-integrations/src/mcp/protocol/transport_remote.rs +++ b/src/crates/services/services-integrations/src/mcp/protocol/transport_remote.rs @@ -512,7 +512,7 @@ impl RemoteMCPTransport { let info = service.peer().peer_info().ok_or_else(|| { MCPRuntimeError::mcp("Handshake succeeded but server info missing".to_string()) })?; - Ok(map_rmcp_initialize_result(info)) + Ok(map_rmcp_initialize_result(&info)) } ClientState::Connecting { transport } => { let Some(transport) = transport.take() else { @@ -546,7 +546,7 @@ impl RemoteMCPTransport { service: Arc::clone(&service), }; - Ok(map_rmcp_initialize_result(info)) + Ok(map_rmcp_initialize_result(&info)) } } } diff --git a/src/web-ui/src/app/components/GalleryLayout/GalleryDetailModal.tsx b/src/web-ui/src/app/components/GalleryLayout/GalleryDetailModal.tsx index 567dd80464..28e539aa95 100644 --- a/src/web-ui/src/app/components/GalleryLayout/GalleryDetailModal.tsx +++ b/src/web-ui/src/app/components/GalleryLayout/GalleryDetailModal.tsx @@ -13,6 +13,10 @@ interface GalleryDetailModalProps { meta?: React.ReactNode; actions?: React.ReactNode; children?: React.ReactNode; + testId?: string; + titleTestId?: string; + descriptionTestId?: string; + closeButtonTestId?: string; } const GalleryDetailModal: React.FC = ({ @@ -26,8 +30,21 @@ const GalleryDetailModal: React.FC = ({ meta, actions, children, + testId, + titleTestId, + descriptionTestId, + closeButtonTestId, }) => ( - +
{icon ? ( @@ -41,7 +58,7 @@ const GalleryDetailModal: React.FC = ({
{badges ?
{badges}
: null} {description?.trim() ? ( -

{description.trim()}

+

{description.trim()}

) : null} {meta ?
{meta}
: null}
diff --git a/src/web-ui/src/app/components/GalleryLayout/GalleryEmpty.tsx b/src/web-ui/src/app/components/GalleryLayout/GalleryEmpty.tsx index d0778922a6..5040f8386a 100644 --- a/src/web-ui/src/app/components/GalleryLayout/GalleryEmpty.tsx +++ b/src/web-ui/src/app/components/GalleryLayout/GalleryEmpty.tsx @@ -6,6 +6,7 @@ interface GalleryEmptyProps { isError?: boolean; action?: React.ReactNode; className?: string; + testId?: string; } const GalleryEmpty: React.FC = ({ @@ -14,8 +15,9 @@ const GalleryEmpty: React.FC = ({ isError = false, action, className, + testId, }) => ( -
+
{icon} {message} {action} diff --git a/src/web-ui/src/app/components/GalleryLayout/GalleryGrid.tsx b/src/web-ui/src/app/components/GalleryLayout/GalleryGrid.tsx index 43716dfb6b..8d7dd5cd1f 100644 --- a/src/web-ui/src/app/components/GalleryLayout/GalleryGrid.tsx +++ b/src/web-ui/src/app/components/GalleryLayout/GalleryGrid.tsx @@ -1,6 +1,6 @@ import React from 'react'; -interface GalleryGridProps { +interface GalleryGridProps extends React.HTMLAttributes { children: React.ReactNode; minCardWidth?: number; className?: string; @@ -10,10 +10,16 @@ const GalleryGrid: React.FC = ({ children, minCardWidth = 320, className, + style, + ...gridProps }) => (
{children}
diff --git a/src/web-ui/src/app/components/GalleryLayout/GalleryLayout.tsx b/src/web-ui/src/app/components/GalleryLayout/GalleryLayout.tsx index b106399ef1..54d732687e 100644 --- a/src/web-ui/src/app/components/GalleryLayout/GalleryLayout.tsx +++ b/src/web-ui/src/app/components/GalleryLayout/GalleryLayout.tsx @@ -1,13 +1,13 @@ import React from 'react'; import './GalleryLayout.scss'; -interface GalleryLayoutProps { +interface GalleryLayoutProps extends React.HTMLAttributes { children: React.ReactNode; className?: string; } -const GalleryLayout: React.FC = ({ children, className }) => ( -
+const GalleryLayout: React.FC = ({ children, className, ...rootProps }) => ( +
{children} diff --git a/src/web-ui/src/app/components/GalleryLayout/GalleryZone.tsx b/src/web-ui/src/app/components/GalleryLayout/GalleryZone.tsx index d022ec2bbd..83da738e93 100644 --- a/src/web-ui/src/app/components/GalleryLayout/GalleryZone.tsx +++ b/src/web-ui/src/app/components/GalleryLayout/GalleryZone.tsx @@ -1,6 +1,6 @@ import React from 'react'; -interface GalleryZoneProps { +interface GalleryZoneProps extends Omit, 'title'> { id?: string; title: string; subtitle?: React.ReactNode; @@ -16,8 +16,9 @@ const GalleryZone: React.FC = ({ tools, children, className, + ...sectionProps }) => ( -
+
{title} diff --git a/src/web-ui/src/app/components/NavPanel/MainNav.tsx b/src/web-ui/src/app/components/NavPanel/MainNav.tsx index b9e027444d..feed2417ad 100644 --- a/src/web-ui/src/app/components/NavPanel/MainNav.tsx +++ b/src/web-ui/src/app/components/NavPanel/MainNav.tsx @@ -422,6 +422,8 @@ const MainNav: React.FC = ({ role="menuitem" title={tooltip} onClick={() => { void handleSwitchWorkspace(workspace.id); }} + data-testid="nav-workspace-menu-recent-workspace" + data-workspace-id={workspace.id} >