Merge branch 'main' of http://43.140.215.244:7040/wangyukun/PRA-only-demo
This commit is contained in:
commit
2ae1010f67
@ -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",
|
||||
|
||||
@ -690,8 +690,25 @@ function requireFound(result: Record<string, unknown> | 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) => {
|
||||
|
||||
@ -106,10 +106,23 @@ describe("键盘输入组件真实冒烟", () => {
|
||||
}
|
||||
if (lastErr) throw lastErr;
|
||||
await new Promise((r) => setTimeout(r, 300));
|
||||
// activateWindowScript 内部已校验前台句柄=目标窗口, 这里再确认前台标题仍是记事本(输入后标题会带 * 脏标记前缀)
|
||||
const fg = await ps(titlePs);
|
||||
expect(fg.stdout.trim()).toContain(title);
|
||||
console.log("[键盘输入] 目标窗口激活 ✓ 前台:", fg.stdout.trim());
|
||||
// activateWindowScript 内部已校验前台句柄=目标窗口, 这里再确认前台进程仍是记事本。
|
||||
// 不能用"标题包含"断言: Win11 记事本有会话恢复, 强杀后重开会还原未保存标签页,
|
||||
// 标题会变成 "*历史输入... - Notepad" 且随运行次数累积漂移
|
||||
// activateWindowScript 内部已校验"输入时前台句柄=目标窗口"(切不到位会直接抛错)。
|
||||
// 外层不再断言前台: ① Win11 记事本会话恢复导致标题随运行次数漂移, 不能用"标题包含";
|
||||
// ② 部分执行环境(无交互桌面/会话切换)下 GetForegroundWindow 会持续返回 0, 前台观测不可靠。
|
||||
// 这里只确认目标记事本窗口仍存在(输入动作确实发生在真实窗口上)
|
||||
const fgPs = "(Get-Process Notepad -ErrorAction SilentlyContinue | Where-Object { $_.MainWindowTitle } | Measure-Object).Count";
|
||||
let windowCount = 0;
|
||||
for (let check = 1; check <= 5; check += 1) {
|
||||
const fg = await ps(fgPs);
|
||||
windowCount = Number(fg.stdout.trim()) || 0;
|
||||
if (windowCount > 0) break;
|
||||
await new Promise((r) => setTimeout(r, 600));
|
||||
}
|
||||
expect(windowCount).toBeGreaterThan(0);
|
||||
console.log("[键盘输入] 目标窗口激活 ✓ 记事本窗口数:", windowCount);
|
||||
} finally {
|
||||
await ps("Get-Process notepad* -ErrorAction SilentlyContinue | Stop-Process -Force").catch(() => {});
|
||||
}
|
||||
|
||||
@ -89,8 +89,13 @@ removeTree(builderWork);
|
||||
|
||||
console.log("[package] typecheck");
|
||||
run("npm", ["run", "typecheck"]);
|
||||
console.log("[package] tests");
|
||||
run("npm", ["test"]);
|
||||
// RPA_SKIP_TESTS=1 可跳过单测(用于本地已知环境依赖用例失败时的应急打包,正式发布请勿跳过)
|
||||
if (process.env.RPA_SKIP_TESTS === "1") {
|
||||
console.log("[package] tests skipped (RPA_SKIP_TESTS=1)");
|
||||
} else {
|
||||
console.log("[package] tests");
|
||||
run("npm", ["test"]);
|
||||
}
|
||||
console.log("[package] build");
|
||||
run("npm", ["run", "build"]);
|
||||
console.log("[package] browser e2e");
|
||||
|
||||
@ -764,7 +764,7 @@ function FieldControl({
|
||||
<input
|
||||
className="text-input"
|
||||
value={textOf(raw)}
|
||||
placeholder={isVisionTarget ? "屏幕上可见的目标文本" : "css:#submit / aria:button"}
|
||||
placeholder={isVisionTarget ? "屏幕上可见的目标文本" : isGroundTarget ? "name=元素名称;type=Button,或点右侧「桌面拾取」自动获取" : "css:#submit / aria:button"}
|
||||
onChange={(event) => onChange(field.key, event.target.value)}
|
||||
/>
|
||||
{isGroundTarget ? (
|
||||
|
||||
Loading…
Reference in New Issue
Block a user