test(hotkey): 补齐热键自动注入门禁#41
Merged
Merged
Conversation
feat(settings): 硅基流动 ASR/LLM 配置 + 关于页完善 + onAsrProviderChange bug 修复
Windows regression currently depends on a tester pressing a real modifier key, which cannot distinguish OS-hook delivery failures from coordinator state-machine failures. Add a debug/test-only injection path that drives handle_pressed and handle_released, logs the coordinator hotkey edge, and cancels the dry-run session automatically. Constraint: Must not rely on SendInput or a physical keyboard for the coordinator gate. Constraint: Keep physical hotkey testing as the OS hook coverage layer. Rejected: Fake log-only gate | would not exercise the coordinator hotkey path. Rejected: Production IPC command | unnecessary surface area for a test/dev-only gate. Confidence: high Scope-risk: narrow Tested: npm run check:hotkey-injection Tested: npm run build Tested: cargo check Tested: cargo check --release Tested: git diff --check Related: Open-Less#35
Reviewer's GuideAdds a dev/test-only hotkey injection gate that drives the real coordinator hotkey handlers, logs hotkey transitions, supports a dry-run mode via env var, wires it through a Tauri command and npm script, and provides a focused test and docs to validate that hotkey events reach the coordinator state machine without starting a real recording. Sequence diagram for the dev/test hotkey injection gate flowsequenceDiagram
actor Dev as DevEngineer
participant Npm as NpmScript_check_hotkey_injection
participant Node as Node_check_hotkey_injection_mjs
participant Cargo as Cargo_test
participant Test as RustTest_hotkey_injection_gate_logs_pressed_and_cancels
participant Coord as Coordinator
participant Inner as Inner
Dev->>Npm: npm run check:hotkey-injection
Npm->>Node: node scripts/check-hotkey-injection.mjs
Node->>Cargo: cargo test hotkey_injection_gate_logs_pressed_and_cancels
Cargo->>Test: Run async tokio test
Test->>Test: set OPENLESS_HOTKEY_INJECTION_DRY_RUN=1
Test->>Coord: Coordinator::new
Test->>Coord: inject_hotkey_click_for_dev()
activate Coord
Coord->>Coord: log "[coord] dev hotkey injection started"
Coord->>Inner: handle_pressed(&inner)
activate Inner
Inner->>Inner: log "[coord] hotkey pressed (mode, phase)"
Inner->>Inner: begin_session(&inner)
activate Inner
Inner->>Inner: hotkey_injection_dry_run_enabled()
Inner-->>Inner: true (env var is set)
Inner->>Inner: emit_capsule(Recording)
Inner->>Inner: state.phase = Listening
Inner->>Inner: log "[coord] session started (hotkey-injection dry-run)"
deactivate Inner
Inner-->>Coord: Ok(())
Inner->>Inner: handle_released(&inner)
activate Inner
Inner->>Inner: log "[coord] hotkey released (mode, phase)"
Inner-->>Inner: end_session skipped (dry-run already cancelled later)
deactivate Inner
Coord->>Inner: cancel_session(&inner)
Inner->>Inner: state.phase = Idle
deactivate Inner
Coord-->>Test: Ok(())
deactivate Coord
Test->>Test: assert state.phase == Idle
Test-->>Cargo: test passed
Cargo-->>Node: exit status 0, logs
Node->>Node: check output contains "[coord] hotkey pressed"
Node-->>Npm: success
Npm-->>Dev: Hotkey injection gate passed
Updated class diagram for Coordinator hotkey injection and dry-run gateclassDiagram
class Coordinator {
+new() Coordinator
+cancel_dictation()
+inject_hotkey_click_for_dev() Result
}
class Inner {
+prefs
+state
+vocab
+asr
}
class SessionPhase {
<<enum>>
Idle
Listening
Transcribing
Completed
Error
}
class HotkeyMode {
<<enum>>
Toggle
Hold
}
class CapsuleState {
<<enum>>
Idle
Recording
Error
}
class CoordinatorModuleHelpers {
+handle_pressed(inner)
+handle_released(inner)
+begin_session(inner) Result
+cancel_session(inner)
+hotkey_injection_dry_run_enabled() bool
+emit_capsule(inner,state,progress,elapsed,error,extra)
}
class CommandsModule {
+cancel_dictation(coord)
+inject_hotkey_click_for_dev(coord) Result
}
class HotkeyInjectionTests {
+hotkey_injection_gate_logs_pressed_and_cancels() async
}
Coordinator --> Inner : inner
CoordinatorModuleHelpers --> Inner : uses
CoordinatorModuleHelpers --> SessionPhase : updates_phase
CoordinatorModuleHelpers --> HotkeyMode : reads_mode
CoordinatorModuleHelpers --> CapsuleState : emits_state
CommandsModule --> Coordinator : delegates_methods
HotkeyInjectionTests --> Coordinator : constructs_and_calls
HotkeyInjectionTests --> SessionPhase : asserts_Idle_phase
CoordinatorModuleHelpers --> HotkeyInjectionTests : logged_by_test
Coordinator --> CoordinatorModuleHelpers : calls_helpers
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
appergb
pushed a commit
that referenced
this pull request
Apr 30, 2026
将 main 的 PR #41(coordinator hotkey 测试基础设施)合入 develop。 保留 develop 上的 i18n 变更与 main 的 hotkey 测试改动,无冲突。
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
摘要
Fixes #35。
本 PR 按最小改动补齐 dev/test 专用热键注入门禁,用于验证热键事件是否能进入 coordinator 状态机。
当前 Windows 真机回归中,物理全局热键仍需要人工按键验证,CI 很难稳定证明热键事件是否进入业务链路。本 PR 新增测试注入入口,让自动化脚本可以直接走
handle_pressed/handle_released路径,并通过 coordinator 日志断言热键按下事件已进入状态机。本 PR 不尝试替代真实 OS hook / 物理热键测试,只补齐非人工的 coordinator 热键链路门禁。
修复 / 新增 / 改进
新增 dev/test 专用热键注入入口。
注入路径走真实 coordinator 处理函数:
handle_pressedhandle_released为
handle_pressed/handle_released增加 coordinator 日志:[coord] hotkey presseddry-run 注入后会自动 cancel,避免测试流程触发长时间录音。
新增检查脚本:
npm run check:hotkey-injection检查脚本会断言日志中包含:
[coord] hotkey pressedREADME 补充 Hotkey Injection Gate 用法说明。
兼容
不包含:
对现有用户 / 本地环境 / 构建流程的影响:
npm run check:hotkey-injection验证 coordinator 热键链路。测试计划
命令:
npm run check:hotkey-injection结果:通过
证据路径:本地脚本输出,日志包含
[coord] hotkey pressed命令:
npm run build结果:通过
证据路径:本地构建输出
命令:
cargo check结果:通过
证据路径:本地检查输出
命令:
cargo check --release结果:通过
证据路径:本地 release 检查输出
命令:
git diff --check结果:通过
证据路径:本地命令输出
备注
本 PR 是针对 issue #35 的最小闭环修复:只补齐热键事件进入 coordinator 状态机的自动化门禁,不扩大到真实 Windows OS hook 行为验证。真实物理热键链路仍需要 Windows 真机测试覆盖。
Summary by Sourcery
Add a dev/test-only hotkey injection gate to validate that hotkey events reach the coordinator state machine without requiring physical hotkey input.
New Features:
npm run check:hotkey-injectionscript that runs a Rust test and asserts coordinator logs contain the hotkey pressed marker.Enhancements:
Documentation:
Tests: