键盘输入组件修复: 接入 words 字段与三种输入方式
This commit is contained in:
parent
6b05a65664
commit
46348413c1
@ -99,10 +99,22 @@ export function psString(value: unknown): string {
|
||||
}
|
||||
|
||||
const keyboardSend: CapabilityHandler = async (_ctx, node, args) => {
|
||||
const keys = text(args, ["keys", "key", "text", "value"]);
|
||||
// 字段: words=输入内容(键盘输入), keys/key=按键组合(按键系列), interval=输入间隔(V1毫秒/基础版秒), fuctype=输入方式(0后台接口/1人工模拟/2剪贴板粘贴)
|
||||
const keys = text(args, ["words", "keys", "key", "text", "value"]);
|
||||
if (!keys) throw new RuntimeError("validation_error", "键盘输入为空", { nodeId: node.id, componentId: node.componentId });
|
||||
await manualDelay();
|
||||
await powershell(`Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.SendKeys]::SendWait(${psString(keys)})`);
|
||||
const rawInterval = number(args, ["interval"], 0);
|
||||
const intervalMs = node.componentId === "Keyboard_Send" ? Math.max(0, Math.round(rawInterval * 1000)) : Math.max(0, Math.round(rawInterval));
|
||||
const mode = text(args, ["fuctype"], "0");
|
||||
const isTextSend = node.componentId === "Keyboard_Send" || node.componentId === "Keyboard_Send_V1";
|
||||
// 文本输入需转义 SendKeys 特殊字符(+^%~(){}[])按字面输入;按键组合组件(Keyboard_Press)与粘贴模式保留原文
|
||||
const escape = isTextSend && mode !== "2" ? `$t = $t -replace '[+^%~(){}[\\]]','{$0}'; ` : "";
|
||||
const send = mode === "2"
|
||||
? `Set-Clipboard -Value $t; Start-Sleep -Milliseconds 120; [System.Windows.Forms.SendKeys]::SendWait('^v')`
|
||||
: mode === "1"
|
||||
? `foreach ($ch in $t.ToCharArray()) { $c = [string]$ch; if ('+^%~(){}[]'.Contains($c)) { $c = '{' + $c + '}' }; [System.Windows.Forms.SendKeys]::SendWait($c); Start-Sleep -Milliseconds ${intervalMs} }`
|
||||
: `[System.Windows.Forms.SendKeys]::SendWait($t)`;
|
||||
await powershell(`Add-Type -AssemblyName System.Windows.Forms; $t = ${psString(keys)}; ${escape}${send}`);
|
||||
await manualDelay();
|
||||
return keys;
|
||||
};
|
||||
|
||||
48
src/main/capabilities/keyboard-send-smoke.test.ts
Normal file
48
src/main/capabilities/keyboard-send-smoke.test.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { CatalogComponent, FlowNode } from "../../shared/types";
|
||||
import { getHandler } from "../engine/registry";
|
||||
import type { RunContext } from "../engine/types";
|
||||
import "./desktop";
|
||||
|
||||
const component = {} as CatalogComponent;
|
||||
const node = (id: string): FlowNode => ({ id: "smoke-kb", componentId: id, position: { x: 0, y: 0 }, values: {}, options: {} });
|
||||
|
||||
const ctx = {
|
||||
runId: "kb-smoke", flowId: "kb-smoke-flow", flow: {} as RunContext["flow"],
|
||||
vars: {}, secrets: {}, signal: new AbortController().signal, evidenceDir: "D:/office-test2",
|
||||
emit: () => {}, log: () => {}, componentOf: () => undefined
|
||||
} as unknown as RunContext;
|
||||
|
||||
async function invoke(componentId: string, args: Record<string, unknown>): Promise<unknown> {
|
||||
const handler = getHandler(componentId);
|
||||
expect(handler).toBeTypeOf("function");
|
||||
return handler!(ctx, node(componentId), args, component);
|
||||
}
|
||||
|
||||
describe("键盘输入组件真实冒烟", () => {
|
||||
it("words 字段取值(此前读不到报「键盘输入为空」), 后台接口模式整段发送特殊字符不抛错", async () => {
|
||||
const out = await invoke("Keyboard_Send_V1", { words: "哈哈哈(测试)100%^2", interval: "10", fuctype: "0" });
|
||||
expect(out).toBe("哈哈哈(测试)100%^2");
|
||||
console.log("[键盘输入] 后台接口模式整段发送 ✓:", out);
|
||||
}, 60000);
|
||||
|
||||
it("人工模拟模式逐字符+间隔毫秒真实发送", async () => {
|
||||
const out = await invoke("Keyboard_Send_V1", { words: "逐字输入ABC", interval: "5", fuctype: "1" });
|
||||
expect(out).toBe("逐字输入ABC");
|
||||
console.log("[键盘输入] 人工模拟逐字符 ✓:", out);
|
||||
}, 60000);
|
||||
|
||||
it("剪切板粘贴模式: 原文进入剪贴板并发送 Ctrl+V", async () => {
|
||||
const content = `粘贴${Date.now()}`;
|
||||
const out = await invoke("Keyboard_Send_V1", { words: content, fuctype: "2" });
|
||||
expect(out).toBe(content);
|
||||
const clip = await invoke("Clipboard_GetText", {}) as string;
|
||||
expect(clip).toBe(content);
|
||||
console.log("[键盘输入] 剪贴板粘贴模式 ✓ 剪贴板内容一致:", clip);
|
||||
}, 60000);
|
||||
|
||||
it("空输入仍报「键盘输入为空」", async () => {
|
||||
await expect(invoke("Keyboard_Send_V1", { words: "", interval: "10" })).rejects.toThrow("键盘输入为空");
|
||||
console.log("[键盘输入] 空输入校验 ✓");
|
||||
}, 60000);
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user