@crewhaus/tool-mouse-keyboard 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -14
- package/src/index.test.ts +92 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crewhaus/tool-mouse-keyboard",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Click / Type / Key / Scroll tools — destructive: true (Section 25 BROW)",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -12,17 +12,17 @@
|
|
|
12
12
|
"test": "bun test src"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@crewhaus/computer-use-driver": "0.1.
|
|
16
|
-
"@crewhaus/errors": "0.1.
|
|
17
|
-
"@crewhaus/tool-builder": "0.1.
|
|
18
|
-
"@crewhaus/tool-catalog": "0.1.
|
|
15
|
+
"@crewhaus/computer-use-driver": "0.1.3",
|
|
16
|
+
"@crewhaus/errors": "0.1.3",
|
|
17
|
+
"@crewhaus/tool-builder": "0.1.3",
|
|
18
|
+
"@crewhaus/tool-catalog": "0.1.3",
|
|
19
19
|
"zod": "^3.23.8"
|
|
20
20
|
},
|
|
21
21
|
"license": "Apache-2.0",
|
|
22
22
|
"author": {
|
|
23
23
|
"name": "Max Meier",
|
|
24
|
-
"email": "max@
|
|
25
|
-
"url": "https://
|
|
24
|
+
"email": "max@crewhaus.ai",
|
|
25
|
+
"url": "https://crewhaus.ai"
|
|
26
26
|
},
|
|
27
27
|
"repository": {
|
|
28
28
|
"type": "git",
|
|
@@ -34,12 +34,7 @@
|
|
|
34
34
|
"url": "https://github.com/crewhaus/factory/issues"
|
|
35
35
|
},
|
|
36
36
|
"publishConfig": {
|
|
37
|
-
"access": "
|
|
37
|
+
"access": "public"
|
|
38
38
|
},
|
|
39
|
-
"files": [
|
|
40
|
-
"src",
|
|
41
|
-
"README.md",
|
|
42
|
-
"LICENSE",
|
|
43
|
-
"NOTICE"
|
|
44
|
-
]
|
|
39
|
+
"files": ["src", "README.md", "LICENSE", "NOTICE"]
|
|
45
40
|
}
|
package/src/index.test.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
import type { Driver } from "@crewhaus/computer-use-driver";
|
|
3
3
|
import {
|
|
4
|
+
MouseKeyboardError,
|
|
4
5
|
createAllMouseKeyboardTools,
|
|
5
6
|
createClickTool,
|
|
6
7
|
createKeyTool,
|
|
@@ -37,6 +38,33 @@ function recordingDriver(): { driver: Driver; calls: string[] } {
|
|
|
37
38
|
return { driver, calls };
|
|
38
39
|
}
|
|
39
40
|
|
|
41
|
+
// A driver whose single named method rejects; all others are inert no-ops.
|
|
42
|
+
// Lets each tool's error-catch branch be exercised in isolation.
|
|
43
|
+
function throwingDriver(method: "click" | "type" | "key" | "scroll", message: string): Driver {
|
|
44
|
+
const base: Driver = {
|
|
45
|
+
backend: "chromium",
|
|
46
|
+
async connect() {},
|
|
47
|
+
async goto() {},
|
|
48
|
+
async screenshot() {
|
|
49
|
+
return new Uint8Array();
|
|
50
|
+
},
|
|
51
|
+
async click() {},
|
|
52
|
+
async type() {},
|
|
53
|
+
async key() {},
|
|
54
|
+
async scroll() {},
|
|
55
|
+
async getViewport() {
|
|
56
|
+
return { width: 0, height: 0, devicePixelRatio: 1 };
|
|
57
|
+
},
|
|
58
|
+
async disconnect() {},
|
|
59
|
+
};
|
|
60
|
+
return {
|
|
61
|
+
...base,
|
|
62
|
+
[method]: async () => {
|
|
63
|
+
throw new Error(message);
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
40
68
|
describe("Mouse + keyboard tools (T1 wrapping)", () => {
|
|
41
69
|
test("Click forwards (x, y, button) to driver.click", async () => {
|
|
42
70
|
const { driver, calls } = recordingDriver();
|
|
@@ -115,4 +143,68 @@ describe("Mouse + keyboard tools (T1 wrapping)", () => {
|
|
|
115
143
|
const r = await tool.execute({ x: 1, y: 1 }, {});
|
|
116
144
|
expect(typeof r === "string" && r.includes("[Click error]")).toBe(true);
|
|
117
145
|
});
|
|
146
|
+
|
|
147
|
+
test("Type driver errors are surfaced as a [Type error] result string", async () => {
|
|
148
|
+
const driver = throwingDriver("type", "type blew up");
|
|
149
|
+
const tool = createTypeTool({ driver });
|
|
150
|
+
const r = await tool.execute({ text: "hi" }, {});
|
|
151
|
+
expect(typeof r === "string" && r.includes("[Type error] type blew up")).toBe(true);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
test("Key driver errors are surfaced as a [Key error] result string", async () => {
|
|
155
|
+
const driver = throwingDriver("key", "key blew up");
|
|
156
|
+
const tool = createKeyTool({ driver });
|
|
157
|
+
const r = await tool.execute({ combo: "Enter" }, {});
|
|
158
|
+
expect(typeof r === "string" && r.includes("[Key error] key blew up")).toBe(true);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test("Scroll driver errors are surfaced as a [Scroll error] result string", async () => {
|
|
162
|
+
const driver = throwingDriver("scroll", "scroll blew up");
|
|
163
|
+
const tool = createScrollTool({ driver });
|
|
164
|
+
const r = await tool.execute({ dx: 0, dy: 10 }, {});
|
|
165
|
+
expect(typeof r === "string" && r.includes("[Scroll error] scroll blew up")).toBe(true);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
test("non-Error throw still yields a result string (String(err) fallback)", async () => {
|
|
169
|
+
// err.message is undefined → falls through to String(err).
|
|
170
|
+
const driver: Driver = {
|
|
171
|
+
backend: "chromium",
|
|
172
|
+
async connect() {},
|
|
173
|
+
async goto() {},
|
|
174
|
+
async screenshot() {
|
|
175
|
+
return new Uint8Array();
|
|
176
|
+
},
|
|
177
|
+
async click() {
|
|
178
|
+
throw "raw string failure";
|
|
179
|
+
},
|
|
180
|
+
async type() {},
|
|
181
|
+
async key() {},
|
|
182
|
+
async scroll() {},
|
|
183
|
+
async getViewport() {
|
|
184
|
+
return { width: 0, height: 0, devicePixelRatio: 1 };
|
|
185
|
+
},
|
|
186
|
+
async disconnect() {},
|
|
187
|
+
};
|
|
188
|
+
const tool = createClickTool({ driver });
|
|
189
|
+
const r = await tool.execute({ x: 1, y: 1 }, {});
|
|
190
|
+
expect(typeof r === "string" && r.includes("[Click error] raw string failure")).toBe(true);
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
describe("MouseKeyboardError", () => {
|
|
195
|
+
test("constructs with the 'tool' error code and a stable name", () => {
|
|
196
|
+
const err = new MouseKeyboardError("input device unavailable");
|
|
197
|
+
expect(err).toBeInstanceOf(Error);
|
|
198
|
+
expect(err.name).toBe("MouseKeyboardError");
|
|
199
|
+
expect(err.message).toBe("input device unavailable");
|
|
200
|
+
expect(err.code).toBe("tool");
|
|
201
|
+
expect(err.cause).toBeUndefined();
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test("threads an underlying cause through to the base error", () => {
|
|
205
|
+
const root = new Error("driver socket closed");
|
|
206
|
+
const err = new MouseKeyboardError("scroll failed", root);
|
|
207
|
+
expect(err.cause).toBe(root);
|
|
208
|
+
expect(err.code).toBe("tool");
|
|
209
|
+
});
|
|
118
210
|
});
|