diff --git a/packages/rpa-core/src/capabilities/desktop-uia.test.ts b/packages/rpa-core/src/capabilities/desktop-uia.test.ts index a605328..341901f 100644 --- a/packages/rpa-core/src/capabilities/desktop-uia.test.ts +++ b/packages/rpa-core/src/capabilities/desktop-uia.test.ts @@ -120,6 +120,24 @@ describe("desktop UIA selector compatibility", () => { expect(script).toContain("Find-RpaWindow"); }); + it("元素定位到但 clicked=false 时必须抛错,不允许静默成功(用户 NVIDIA 覆盖层踩坑场景)", async () => { + powershellMock.mockImplementation(async () => '{"clicked":false,"method":"invoke_pattern","name":"","x":0,"y":0,"w":1919,"h":1080}'); + let error: any = null; + try { + await getHandler("Element_ClickGround")!( + context, + node, + { selector: "window=NVIDIA GeForce Overlay DT;type=Document;id=RootWebArea" }, + {} as any + ); + } catch (e) { + error = e; + } + expect(error?.code).toBe("desktop_error"); + // recommendation 必须给出可执行建议 + expect(String(error?.recommendation ?? "")).toContain("桌面拾取"); + }); + it("dispatches screen setValue to coordinate paste", async () => { await getHandler("Element_SetValueGround")!(context, node, { selector: "screen=10,20,30,40", diff --git a/packages/rpa-core/src/capabilities/desktop-uia.ts b/packages/rpa-core/src/capabilities/desktop-uia.ts index d476cc6..201ec5c 100644 --- a/packages/rpa-core/src/capabilities/desktop-uia.ts +++ b/packages/rpa-core/src/capabilities/desktop-uia.ts @@ -690,8 +690,25 @@ function requireFound(result: Record | null, t: UiaTarget, acti const clickGround: CapabilityHandler = async (_ctx, node, args) => { const t = target(args, node); - if (t.selector.screen) return runScript(clickScreenScript(t), t); - return runWithImplicitWait(t, "click", clickScript(t), runScript, args); + const result = t.selector.screen + ? await runScript(clickScreenScript(t), t) + : await runWithImplicitWait(t, "click", clickScript(t), runScript, args); + // 元素定位到了但实际没点成(如拾取到全屏透明覆盖层:IsOffscreen=true 且无 Invoke/Toggle/Expand/Select 模式)。 + // 这种"假成功"会掩盖问题,必须按错误契约抛出,让运行记录如实标红。 + if (result && result.clicked === false) { + const s = t.selector; + throw new RuntimeError( + "desktop_error", + `元素点击未生效:已定位到目标(window=${s.window ?? ""}, name=${s.name ?? ""}, type=${s.type ?? ""}),但该元素不可见点击且不支持任何可调用模式`, + { + recommendation: "重新用「桌面拾取」选择真实可见的目标控件;若拾取结果落在全屏透明覆盖层上(如 NVIDIA 游戏内覆盖层、录屏悬浮条),先关闭覆盖层再拾取", + nodeId: node.id, + componentId: node.componentId, + detail: JSON.stringify(result) + } + ); + } + return result; }; const setValueGround: CapabilityHandler = async (_ctx, node, args) => {