输入、审批与交互操作
本页从 Web 端到会话结果,说明输入框提交、待审批面板接管以及批准后的恢复行为。依据为浏览器端到端测试;未读取客户端组件和服务端实现,因此将测试可验证的外部契约与内部实现严格区分。
Purpose and Scope
范围限于输入、审批与交互操作的用户可见路径:输入长提示、切换访问模式、等待审批、通过按钮或键盘批准、观察会话事件和输入框恢复。审批规则、权限判定引擎、会话事件持久化、Web 构建与部署不属于本页;这些内部实现细节在已读取的源码中未找到。对于会话存储及权限策略,应参阅相应专题,而不是把测试观察当作实现保证。审批端到端测试。
Overview
测试先用 launchWebScaffold 建立可认证工作区,借助浏览器定位 [data-composer-input],设置 Read Only 模式并按 Enter 发送提示;待 [data-approval-key] 出现后,在审批面板中允许一次操作。测试既检查较长命令的滚动区域与按钮可达性,也核对 approval/decided 事件、工作区文件、回复以及审批面板消失后的输入框重新可用。准备过程、提交和等待、结论断言。
Architecture
下面仅表示测试代码实际连接或观测到的组件、事件和 DOM 元素,不代表未经读取的内部模块调用关系。
Source: approval-composer.e2e.ts
Scaffold 暴露 ctx 的 session/event 订阅;测试将事件累积起来,与页面操作后的结果进行交叉检查。这一结构避免仅凭按钮点击就认为命令已执行;文件内容和最终工作区快照提供另一层可观测证据。事件订阅、结果检查。
实际交互流程
1. 环境与事件观察
测试根据 webSnapshotMode() 选择录制或重放:录制时只测试按钮路径;非录制模式同时测试按钮与键盘路径。重放时以 replayFixture、paceMs: 15 和 compareReplaySession: true 初始化 scaffold。测试在浏览器导航前订阅 session/event,因此后续可检验批准结果。模式选择与准备。
2. 提交输入并进入审批
测试先填写 40 行探针文本,从运行中的 [data-input-scroll] 读取 composer 的 clientHeight,清空后选择 Read Only。它先创建 whenTurnSettled 等待,再填入 PROMPT、按 Enter,等待 [data-approval-key] 出现,并确认 [data-approval-scroll] 内出现长命令的一部分。这里的 PROMPT 要求写入 notes.txt 并回复 DONE;测试生成 220 个不同 token,使待审批命令足够长,以验证溢出布局。测试输入生成、输入提交。
1const input = page.locator('[data-composer-input]').first()
2await input.waitFor({ timeout: 10_000 })
3
4// Derive the expected cap from the live composer instead of duplicating its pixel value.
5await input.fill(CAP_PROBE)
6const composerCap = await input.evaluate(el => el.closest('[data-input-scroll]')?.clientHeight ?? 0)
7expect(composerCap).toBeGreaterThan(0)
8await input.fill('')Source: approval-composer.e2e.ts
3. 审批、收束和恢复
面板提供 Allow once 按钮;替代路径为聚焦审批滚动区域后按 Enter。测试等待回合收束,再断言最近一次 approval/decided 含 allowed-once,工作区文件包含提示中的 token,页面出现 DONE,审批面板被移除,composer 首个输入框重新可用。录制路径则记录 fixture 并校验最终工作区快照,提前返回。批准和断言。
Source: approval-composer.e2e.ts
序列图中的两个批准分支来自同一测试用例的 method 条件;它们不会在一次执行中同时触发。分支和结果。
Usage Examples
切换访问模式并发送提示
以下是测试实际使用的浏览器操作;PROMPT 在同一文件中定义为包含大量 token 的写文件请求。先等待模式标签变化,再提交输入,可以让测试在预期的 Read Only 状态下触发审批路径。提示定义。
1await page.locator('[aria-label^="Access mode"]').click()
2await page.getByRole('menuitem', { name: 'Read Only' }).click()
3await expect.poll(
4 () => page.locator('[aria-label="Access mode, current: Read Only"]').count(),
5 { timeout: 15_000 },
6).toBe(1)
7
8const settled = scaffold.whenTurnSettled(MODE === 'record' ? 240_000 : 60_000)
9await input.fill(PROMPT)
10await input.press('Enter')Source: approval-composer.e2e.ts
两种批准方式
1if (method === 'button') await panel.getByRole('button', { name: 'Allow once' }).click()
2else {
3 await scroll.focus()
4 await page.keyboard.press('Enter')
5}Source: approval-composer.e2e.ts
布局边界与失败检测
长命令测试分别把视口改为 900×1000 和 900×700;它要求审批文本确实可以滚动、审批区域的可见高度与实时测得的 composer 上限相差小于 1 像素,且两个操作按钮既在视口内,也在卡片底部以内。这里使用运行时尺寸而非复制 CSS 数值,可检测共享高度约束退化;小于 1 像素的容差用于处理亚像素布局差异。几何检查。
1expect(geometry.buttons).toBe(2)
2expect(geometry.scrolls).toBe(true)
3// The panel and composer share one cap; allow sub-pixel layout variance.
4expect(Math.abs(geometry.capped - composerCap)).toBeLessThan(1)
5expect(geometry.actionsTop).toBeGreaterThan(0)
6expect(geometry.actionsBottom).toBeLessThanOrEqual(geometry.viewport)
7expect(geometry.actionsBottom).toBeLessThanOrEqual(geometry.cardBottom)Source: approval-composer.e2e.ts
测试失败时保存截图;非录制路径验证 console 的 pageErrors 和 warnings 都为空,并以轮询等待 DONE 和输入框恢复。显式超时覆盖初始输入、模式切换、审批面板和回合收束等异步边界。测试使用 sessionEvents.filter(...).at(-1) 检查最近的批准事件,但未由此证明生产代码的并发仲裁或事件持久性;实现细节在已读取源码中未找到。失败截图与等待、收尾检查。
测试配置与运行边界
| 项目 | 类型 | 测试中的值 | 作用 |
|---|---|---|---|
MODE | webSnapshotMode() 的结果 | record 或其他模式 | record 时仅运行按钮场景,其他模式运行按钮和键盘场景。 |
replayFixture | 文件路径 | FIXTURE | 非录制模式重放 session.v3.jsonl。 |
paceMs | 数字 | 15 | 非录制模式传入 launchWebScaffold 的重放参数。 |
compareReplaySession | 布尔值 | true | 非录制模式传入 scaffold。 |
whenTurnSettled 超时 | 毫秒 | 录制 240_000;否则 60_000 | 等待回合结束。 |
以上为测试参数,不能推断是产品配置默认值。模式与 scaffold 参数、回合超时。
API 与扩展边界
可确认的只是测试调用接口:launchWebScaffold(...) 返回供测试使用的 scaffold;scaffold.ctx.on('session/event', ...) 接收事件;scaffold.whenTurnSettled(...) 被等待以取得 sessionId。其完整类型签名、异常语义与内部实现未在已读取源码中找到,故不将其描述为对外稳定 API。调用点、等待及返回值、使用会话 ID。扩展这类交互回归测试时,可沿用两种输入途径、事件和文件结果交叉断言,以及从实际 DOM 测量几何上限的方式;不要假设未检查的产品内部挂钩。
Related Links
- 审批面板端到端场景:本页行为证据与操作断言。
- Web TypeScript 测试清单:指向相关问题输入与审批测试;这些其他测试的实现不在本页证据范围内。