appium-mcp 1.76.0 → 1.78.0

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.
Files changed (63) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +169 -70
  3. package/dist/cli/index.d.ts +2 -0
  4. package/dist/cli/index.d.ts.map +1 -0
  5. package/dist/cli/index.js +49 -0
  6. package/dist/cli/index.js.map +1 -0
  7. package/dist/command.js +1 -1
  8. package/dist/command.js.map +1 -1
  9. package/dist/core.d.ts +12 -0
  10. package/dist/core.d.ts.map +1 -0
  11. package/dist/core.js +10 -0
  12. package/dist/core.js.map +1 -0
  13. package/dist/create-server.d.ts +50 -0
  14. package/dist/create-server.d.ts.map +1 -0
  15. package/dist/create-server.js +180 -0
  16. package/dist/create-server.js.map +1 -0
  17. package/dist/index.js +2 -36
  18. package/dist/index.js.map +1 -1
  19. package/dist/plugin.d.ts +209 -0
  20. package/dist/plugin.d.ts.map +1 -0
  21. package/dist/plugin.js +367 -0
  22. package/dist/plugin.js.map +1 -0
  23. package/dist/server.d.ts +1 -2
  24. package/dist/server.d.ts.map +1 -1
  25. package/dist/server.js +2 -67
  26. package/dist/server.js.map +1 -1
  27. package/dist/session-store.d.ts +8 -8
  28. package/dist/session-store.d.ts.map +1 -1
  29. package/dist/session-store.js +3 -2
  30. package/dist/session-store.js.map +1 -1
  31. package/dist/tests/__mocks__/@appium/support.d.ts +54 -61
  32. package/dist/tests/__mocks__/@appium/support.d.ts.map +1 -1
  33. package/dist/tests/__mocks__/@appium/support.js +42 -70
  34. package/dist/tests/__mocks__/@appium/support.js.map +1 -1
  35. package/dist/tests/create-server.test.d.ts +2 -0
  36. package/dist/tests/create-server.test.d.ts.map +1 -0
  37. package/dist/tests/create-server.test.js +253 -0
  38. package/dist/tests/create-server.test.js.map +1 -0
  39. package/dist/tests/plugin.test.d.ts +2 -0
  40. package/dist/tests/plugin.test.d.ts.map +1 -0
  41. package/dist/tests/plugin.test.js +340 -0
  42. package/dist/tests/plugin.test.js.map +1 -0
  43. package/dist/tests/tools/llm-wording.test.js +4 -1
  44. package/dist/tests/tools/llm-wording.test.js.map +1 -1
  45. package/dist/tests/verify.test.d.ts +2 -0
  46. package/dist/tests/verify.test.d.ts.map +1 -0
  47. package/dist/tests/verify.test.js +133 -0
  48. package/dist/tests/verify.test.js.map +1 -0
  49. package/dist/tests/vision-finder.test.d.ts +1 -1
  50. package/dist/tests/vision-finder.test.js +24 -6
  51. package/dist/tests/vision-finder.test.js.map +1 -1
  52. package/package.json +13 -1
  53. package/scripts/verify-names.mjs +12 -0
  54. package/server.json +2 -2
  55. package/src/cli/index.ts +58 -0
  56. package/src/command.ts +1 -1
  57. package/src/core.ts +28 -0
  58. package/src/create-server.ts +252 -0
  59. package/src/index.ts +2 -42
  60. package/src/plugin.ts +557 -0
  61. package/src/resources/submodules.zip +0 -0
  62. package/src/server.ts +2 -87
  63. package/src/session-store.ts +12 -11
@@ -0,0 +1,340 @@
1
+ import { describe, test, expect, jest } from '@jest/globals';
2
+ await jest.unstable_mockModule('appium-uiautomator2-driver', () => ({
3
+ AndroidUiautomator2Driver: class MockAndroidUiautomator2Driver {
4
+ },
5
+ }));
6
+ await jest.unstable_mockModule('appium-xcuitest-driver', () => ({
7
+ XCUITestDriver: class MockXCUITestDriver {
8
+ },
9
+ }));
10
+ await jest.unstable_mockModule('../logger', () => ({
11
+ default: {
12
+ debug: jest.fn(),
13
+ info: jest.fn(),
14
+ warn: jest.fn(),
15
+ error: jest.fn(),
16
+ },
17
+ }));
18
+ await jest.unstable_mockModule('../tools/index', () => ({
19
+ default: jest.fn(),
20
+ }));
21
+ const { AppiumMcpCore, PluginManager, McpRegistry } = await import('../plugin.js');
22
+ const log = (await import('../logger.js')).default;
23
+ const { setSession, safeDeleteAllSessions } = await import('../session-store.js');
24
+ function makeMockServer() {
25
+ const registeredTools = [];
26
+ const registeredPrompts = [];
27
+ const registeredResources = [];
28
+ const registeredResourceTemplates = [];
29
+ const server = {
30
+ addTool(toolDef) {
31
+ registeredTools.push(toolDef);
32
+ },
33
+ addPrompt(promptDef) {
34
+ registeredPrompts.push(promptDef);
35
+ },
36
+ addResource(resourceDef) {
37
+ registeredResources.push(resourceDef);
38
+ },
39
+ addResourceTemplate(resourceTemplateDef) {
40
+ registeredResourceTemplates.push(resourceTemplateDef);
41
+ },
42
+ _tools: registeredTools,
43
+ _prompts: registeredPrompts,
44
+ _resources: registeredResources,
45
+ _resourceTemplates: registeredResourceTemplates,
46
+ };
47
+ server.addTool = server.addTool.bind(server);
48
+ server.addPrompt = server.addPrompt.bind(server);
49
+ server.addResource = server.addResource.bind(server);
50
+ server.addResourceTemplate = server.addResourceTemplate.bind(server);
51
+ return server;
52
+ }
53
+ // ---------------------------------------------------------------------------
54
+ // McpRegistry
55
+ // ---------------------------------------------------------------------------
56
+ describe('McpRegistry', () => {
57
+ test('delegates tool registration to server.addTool', () => {
58
+ const mockServer = makeMockServer();
59
+ const registry = new McpRegistry(mockServer);
60
+ registry.addTool('my_tool', 'A test tool', {}, async () => ({
61
+ content: [{ type: 'text', text: 'ok' }],
62
+ }));
63
+ expect(mockServer._tools).toHaveLength(1);
64
+ expect(mockServer._tools[0].name).toBe('my_tool');
65
+ });
66
+ test('delegates prompt and resource registration to server methods', () => {
67
+ const mockServer = makeMockServer();
68
+ const registry = new McpRegistry(mockServer);
69
+ registry.addPrompt({
70
+ name: 'my_prompt',
71
+ load: async () => 'Prompt text',
72
+ });
73
+ registry.addResource({
74
+ uri: 'example://resource',
75
+ name: 'Example Resource',
76
+ load: async () => ({ text: 'Resource text' }),
77
+ });
78
+ registry.addResourceTemplate({
79
+ uriTemplate: 'example://resource/{name}',
80
+ name: 'Example Resource Template',
81
+ arguments: [{ name: 'name', required: true }],
82
+ load: async ({ name }) => ({ text: `Resource ${name}` }),
83
+ });
84
+ expect(mockServer._prompts).toHaveLength(1);
85
+ expect(mockServer._resources).toHaveLength(1);
86
+ expect(mockServer._resourceTemplates).toHaveLength(1);
87
+ });
88
+ });
89
+ // ---------------------------------------------------------------------------
90
+ // AppiumMcpCore
91
+ // ---------------------------------------------------------------------------
92
+ describe('AppiumMcpCore', () => {
93
+ test('exposes session identity and ownership state', async () => {
94
+ const core = new AppiumMcpCore();
95
+ const driver = { deleteSession: async () => { } };
96
+ await safeDeleteAllSessions();
97
+ expect(core.getSessionId()).toBeNull();
98
+ expect(core.getSessionInfo()).toBeNull();
99
+ setSession(driver, 'session-1', { platformName: 'Android' }, 'owned');
100
+ expect(core.getSessionId()).toBe('session-1');
101
+ expect(core.getSessionInfo('session-1')).not.toBeNull();
102
+ await safeDeleteAllSessions();
103
+ });
104
+ });
105
+ // ---------------------------------------------------------------------------
106
+ // PluginManager – registration
107
+ // ---------------------------------------------------------------------------
108
+ describe('PluginManager.register', () => {
109
+ test('registers plugins and logs them', () => {
110
+ const server = makeMockServer();
111
+ const manager = new PluginManager(server);
112
+ const plugin = { name: 'test-plugin', version: '0.1.0' };
113
+ manager.register([plugin]);
114
+ // No errors thrown means registration succeeded.
115
+ });
116
+ test('skips duplicate plugin names', () => {
117
+ const server = makeMockServer();
118
+ const manager = new PluginManager(server);
119
+ const plugin = { name: 'dup', version: '1.0.0' };
120
+ manager.register([plugin, plugin]);
121
+ // Should not throw.
122
+ });
123
+ test('installs the tool interceptor only once', async () => {
124
+ const server = makeMockServer();
125
+ const manager = new PluginManager(server);
126
+ let beforeCallCount = 0;
127
+ const pluginA = {
128
+ name: 'plugin-a',
129
+ version: '1.0.0',
130
+ async beforeCall() {
131
+ beforeCallCount += 1;
132
+ },
133
+ };
134
+ const pluginB = {
135
+ name: 'plugin-b',
136
+ version: '1.0.0',
137
+ };
138
+ manager.register([pluginA]);
139
+ manager.register([pluginB]);
140
+ server.addTool({
141
+ name: 'target_tool',
142
+ description: 'test',
143
+ parameters: {},
144
+ execute: async () => ({
145
+ content: [{ type: 'text', text: 'original' }],
146
+ }),
147
+ });
148
+ const wrappedTool = server._tools[0];
149
+ await wrappedTool.execute({}, {});
150
+ expect(beforeCallCount).toBe(1);
151
+ });
152
+ });
153
+ // ---------------------------------------------------------------------------
154
+ // PluginManager – beforeCall short-circuit
155
+ // ---------------------------------------------------------------------------
156
+ describe('PluginManager beforeCall hook', () => {
157
+ test('allows before-hook to short-circuit tool execution', async () => {
158
+ const server = makeMockServer();
159
+ const manager = new PluginManager(server);
160
+ let originalExecuteCalled = false;
161
+ const plugin = {
162
+ name: 'short-circuit-plugin',
163
+ version: '1.0.0',
164
+ async beforeCall(_ctx) {
165
+ return {
166
+ isError: false,
167
+ content: [{ type: 'text', text: 'intercepted' }],
168
+ };
169
+ },
170
+ };
171
+ manager.register([plugin]);
172
+ // Register a tool whose execute we can spy on.
173
+ server.addTool({
174
+ name: 'target_tool',
175
+ description: 'test',
176
+ parameters: {},
177
+ execute: async () => {
178
+ originalExecuteCalled = true;
179
+ return { content: [{ type: 'text', text: 'original' }] };
180
+ },
181
+ });
182
+ // Find the wrapped tool and call it.
183
+ const wrappedTool = server._tools[0];
184
+ const result = await wrappedTool.execute({}, {});
185
+ expect(originalExecuteCalled).toBe(false);
186
+ expect(result.content[0].text).toBe('intercepted');
187
+ });
188
+ });
189
+ // ---------------------------------------------------------------------------
190
+ // PluginManager – afterCall result modification
191
+ // ---------------------------------------------------------------------------
192
+ describe('PluginManager afterCall hook', () => {
193
+ test('allows after-hook to modify the result', async () => {
194
+ const server = makeMockServer();
195
+ const manager = new PluginManager(server);
196
+ const plugin = {
197
+ name: 'result-modifier',
198
+ version: '1.0.0',
199
+ async afterCall(_ctx, result) {
200
+ return {
201
+ ...result,
202
+ content: [
203
+ {
204
+ type: 'text',
205
+ text: 'modified: ' + result.content[0].text,
206
+ },
207
+ ],
208
+ };
209
+ },
210
+ };
211
+ manager.register([plugin]);
212
+ server.addTool({
213
+ name: 'tool_to_modify',
214
+ description: 'test',
215
+ parameters: {},
216
+ execute: async () => ({
217
+ content: [{ type: 'text', text: 'original result' }],
218
+ }),
219
+ });
220
+ const wrappedTool = server._tools[0];
221
+ const result = await wrappedTool.execute({}, {});
222
+ expect(result.content[0].text).toBe('modified: original result');
223
+ });
224
+ test('passes through the result when after-hook returns nothing', async () => {
225
+ const server = makeMockServer();
226
+ const manager = new PluginManager(server);
227
+ let afterHookCalled = false;
228
+ const plugin = {
229
+ name: 'pass-through',
230
+ version: '1.0.0',
231
+ async afterCall() {
232
+ afterHookCalled = true;
233
+ },
234
+ };
235
+ manager.register([plugin]);
236
+ server.addTool({
237
+ name: 'tool_to_pass_through',
238
+ description: 'test',
239
+ parameters: {},
240
+ execute: async () => ({
241
+ content: [{ type: 'text', text: 'original result' }],
242
+ }),
243
+ });
244
+ const wrappedTool = server._tools[0];
245
+ const result = await wrappedTool.execute({}, {});
246
+ expect(afterHookCalled).toBe(true);
247
+ expect(result.content[0].text).toBe('original result');
248
+ });
249
+ });
250
+ // ---------------------------------------------------------------------------
251
+ // PluginManager – initialize / destroy lifecycle
252
+ // ---------------------------------------------------------------------------
253
+ describe('PluginManager lifecycle', () => {
254
+ test('calls initialize on plugins that implement it', async () => {
255
+ const server = makeMockServer();
256
+ const manager = new PluginManager(server);
257
+ let initialized = false;
258
+ const plugin = {
259
+ name: 'lifecycle-plugin',
260
+ version: '1.0.0',
261
+ async initialize() {
262
+ initialized = true;
263
+ },
264
+ };
265
+ manager.register([plugin]);
266
+ await manager.initialize();
267
+ expect(initialized).toBe(true);
268
+ });
269
+ test('calls destroy on plugins in reverse order', async () => {
270
+ const server = makeMockServer();
271
+ const manager = new PluginManager(server);
272
+ const order = [];
273
+ const pluginA = {
274
+ name: 'plugin-a',
275
+ version: '1.0.0',
276
+ async destroy() {
277
+ order.push('a');
278
+ },
279
+ };
280
+ const pluginB = {
281
+ name: 'plugin-b',
282
+ version: '1.0.0',
283
+ async destroy() {
284
+ order.push('b');
285
+ },
286
+ };
287
+ manager.register([pluginA, pluginB]);
288
+ await manager.destroy();
289
+ expect(order).toEqual(['b', 'a']);
290
+ });
291
+ });
292
+ // ---------------------------------------------------------------------------
293
+ // PluginManager – register delegation
294
+ // ---------------------------------------------------------------------------
295
+ describe('PluginManager.registerPluginCapabilities', () => {
296
+ test('calls register on plugins that implement it', () => {
297
+ const server = makeMockServer();
298
+ const manager = new PluginManager(server);
299
+ let called = false;
300
+ const plugin = {
301
+ name: 'tool-registrar',
302
+ version: '1.0.0',
303
+ register(registry) {
304
+ called = true;
305
+ registry.addTool('custom_tool', 'A custom tool', {}, async () => ({
306
+ content: [{ type: 'text', text: 'custom' }],
307
+ }));
308
+ },
309
+ };
310
+ manager.register([plugin]);
311
+ manager.registerPluginCapabilities();
312
+ expect(called).toBe(true);
313
+ // The interceptor wraps addTool, so our custom_tool is in server._tools
314
+ const names = server._tools.map((t) => t.name);
315
+ expect(names).toContain('custom_tool');
316
+ });
317
+ test('skips duplicate capability registration by plugin name', () => {
318
+ const server = makeMockServer();
319
+ const manager = new PluginManager(server);
320
+ let registerCount = 0;
321
+ const plugin = {
322
+ name: 'repeat-registrar',
323
+ version: '1.0.0',
324
+ register(registry) {
325
+ registerCount += 1;
326
+ registry.addTool('repeat_tool', 'A repeat tool', {}, async () => ({
327
+ content: [{ type: 'text', text: 'repeat' }],
328
+ }));
329
+ },
330
+ };
331
+ log.warn.mockClear();
332
+ manager.register([plugin]);
333
+ manager.registerPluginCapabilities();
334
+ manager.registerPluginCapabilities();
335
+ expect(registerCount).toBe(1);
336
+ expect(server._tools).toHaveLength(1);
337
+ expect(log.warn).toHaveBeenCalledWith('[PluginManager] Duplicate plugin name "repeat-registrar" – skipping.');
338
+ });
339
+ });
340
+ //# sourceMappingURL=plugin.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.test.js","sourceRoot":"","sources":["../../src/tests/plugin.test.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,7 @@
1
1
  import { describe, expect, jest, test } from '@jest/globals';
2
+ function mockToolErrorMessage(err) {
3
+ return err instanceof Error ? err.message : String(err);
4
+ }
2
5
  jest.unstable_mockModule('../../tools/tool-response', () => ({
3
6
  errorResult: jest.fn((text) => ({
4
7
  content: [{ type: 'text', text }],
@@ -7,7 +10,7 @@ jest.unstable_mockModule('../../tools/tool-response', () => ({
7
10
  readWebElementId: jest.fn(),
8
11
  resolveDriver: jest.fn(),
9
12
  textResultWithPrimaryElementId: jest.fn(),
10
- toolErrorMessage: jest.fn((err) => err instanceof Error ? err.message : String(err)),
13
+ toolErrorMessage: jest.fn(mockToolErrorMessage),
11
14
  }));
12
15
  jest.unstable_mockModule('../../tools/session/attach-session', () => ({
13
16
  attachSessionAction: jest.fn(),
@@ -1 +1 @@
1
- {"version":3,"file":"llm-wording.test.js","sourceRoot":"","sources":["../../../src/tests/tools/llm-wording.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"llm-wording.test.js","sourceRoot":"","sources":["../../../src/tests/tools/llm-wording.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=verify.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.test.d.ts","sourceRoot":"","sources":["../../src/tests/verify.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,133 @@
1
+ import { describe, expect, jest, test } from '@jest/globals';
2
+ await jest.unstable_mockModule('appium-uiautomator2-driver', () => ({
3
+ AndroidUiautomator2Driver: class MockAndroidUiautomator2Driver {
4
+ },
5
+ }));
6
+ await jest.unstable_mockModule('appium-xcuitest-driver', () => ({
7
+ XCUITestDriver: class MockXCUITestDriver {
8
+ },
9
+ }));
10
+ await jest.unstable_mockModule('../tools/index', () => ({
11
+ default: (server) => {
12
+ server.addTool({ name: 'builtin_tool' });
13
+ server.addTool({ name: 'another_builtin_tool' });
14
+ },
15
+ }));
16
+ const { formatVerificationReport, verifyAppiumMcpNames } = await import('../plugin.js');
17
+ describe('verifyAppiumMcpNames', () => {
18
+ test('passes when plugin and tool names are unique', () => {
19
+ const plugin = {
20
+ name: 'unique-plugin',
21
+ version: '1.0.0',
22
+ register(registry) {
23
+ registry.addTool('plugin_tool', 'plugin tool', {}, async () => ({
24
+ content: [{ type: 'text', text: 'ok' }],
25
+ }));
26
+ },
27
+ };
28
+ const report = verifyAppiumMcpNames({ plugins: [plugin] });
29
+ expect(report.ok).toBe(true);
30
+ expect(report.duplicates).toEqual([]);
31
+ expect(report.pluginCount).toBe(1);
32
+ expect(report.toolCount).toBe(3);
33
+ expect(report.errors).toEqual([]);
34
+ });
35
+ test('reports duplicate plugin names', () => {
36
+ const plugins = [
37
+ { name: 'duplicate-plugin', version: '1.0.0' },
38
+ { name: 'duplicate-plugin', version: '2.0.0' },
39
+ ];
40
+ const report = verifyAppiumMcpNames({ plugins });
41
+ expect(report.ok).toBe(false);
42
+ expect(report.duplicates).toEqual([
43
+ {
44
+ kind: 'plugin',
45
+ name: 'duplicate-plugin',
46
+ entries: [
47
+ {
48
+ name: 'duplicate-plugin',
49
+ source: 'plugin:duplicate-plugin@1.0.0',
50
+ },
51
+ {
52
+ name: 'duplicate-plugin',
53
+ source: 'plugin:duplicate-plugin@2.0.0',
54
+ },
55
+ ],
56
+ },
57
+ ]);
58
+ expect(report.errors).toEqual([]);
59
+ });
60
+ test('reports duplicate tool names across plugins and built-ins', () => {
61
+ const plugin = {
62
+ name: 'conflicting-plugin',
63
+ version: '1.0.0',
64
+ register(registry) {
65
+ registry.addTool('builtin_tool', 'conflicting tool', {}, async () => ({
66
+ content: [{ type: 'text', text: 'ok' }],
67
+ }));
68
+ },
69
+ };
70
+ const report = verifyAppiumMcpNames({ plugins: [plugin] });
71
+ expect(report.ok).toBe(false);
72
+ expect(report.duplicates).toEqual([
73
+ {
74
+ kind: 'tool',
75
+ name: 'builtin_tool',
76
+ entries: [
77
+ { name: 'builtin_tool', source: 'plugin:conflicting-plugin' },
78
+ { name: 'builtin_tool', source: 'appium-mcp core' },
79
+ ],
80
+ },
81
+ ]);
82
+ expect(report.errors).toEqual([]);
83
+ });
84
+ test('collects plugin registration errors and continues checking tools', () => {
85
+ const plugins = [
86
+ {
87
+ name: 'broken-plugin',
88
+ version: '1.0.0',
89
+ register() {
90
+ throw new Error('plugin setup failed');
91
+ },
92
+ },
93
+ {
94
+ name: 'working-plugin',
95
+ version: '1.0.0',
96
+ register(registry) {
97
+ registry.addTool('working_plugin_tool', 'working tool', {}, async () => ({
98
+ content: [{ type: 'text', text: 'ok' }],
99
+ }));
100
+ },
101
+ },
102
+ ];
103
+ const report = verifyAppiumMcpNames({ plugins });
104
+ expect(report.ok).toBe(false);
105
+ expect(report.toolCount).toBe(3);
106
+ expect(report.duplicates).toEqual([]);
107
+ expect(report.errors).toEqual([
108
+ {
109
+ source: 'plugin:broken-plugin',
110
+ message: 'plugin setup failed',
111
+ },
112
+ ]);
113
+ });
114
+ });
115
+ describe('formatVerificationReport', () => {
116
+ test('formats passing reports', () => {
117
+ const report = verifyAppiumMcpNames();
118
+ expect(formatVerificationReport(report)).toBe('Checked 0 plugin name(s) and 2 tool name(s).\n' +
119
+ 'No duplicate plugin or tool names found.');
120
+ });
121
+ test('formats error reports', () => {
122
+ expect(formatVerificationReport({
123
+ ok: false,
124
+ pluginCount: 1,
125
+ toolCount: 2,
126
+ duplicates: [],
127
+ errors: [{ source: 'appium-mcp core', message: 'AI config missing' }],
128
+ })).toBe('Checked 1 plugin name(s) and 2 tool name(s).\n' +
129
+ 'Registration/load errors found:\n' +
130
+ ' appium-mcp core: AI config missing');
131
+ });
132
+ });
133
+ //# sourceMappingURL=verify.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.test.js","sourceRoot":"","sources":["../../src/tests/verify.test.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Mock strategy:
5
5
  * - global fetch: mocked to avoid real HTTP requests
6
- * - @appium/support imageUtil: mocked via __mocks__/@appium/support.ts
6
+ * - @appium/support imageUtil.requireSharp: spied locally to avoid sharp work
7
7
  * - Screenshot input: benchmark image.png read as base64
8
8
  */
9
9
  export {};
@@ -3,14 +3,14 @@
3
3
  *
4
4
  * Mock strategy:
5
5
  * - global fetch: mocked to avoid real HTTP requests
6
- * - @appium/support imageUtil: mocked via __mocks__/@appium/support.ts
6
+ * - @appium/support imageUtil.requireSharp: spied locally to avoid sharp work
7
7
  * - Screenshot input: benchmark image.png read as base64
8
8
  */
9
9
  import { describe, test, expect, beforeEach, afterEach, jest, } from '@jest/globals';
10
10
  import { readFileSync } from 'node:fs';
11
11
  import { join, dirname } from 'node:path';
12
12
  import { fileURLToPath } from 'node:url';
13
- import { mockSharpInstance } from './__mocks__/@appium/support.js';
13
+ import { imageUtil } from '@appium/support';
14
14
  // ─── Resolve paths ────────────────────────────────────────────────────────────
15
15
  const __filename = fileURLToPath(import.meta.url);
16
16
  const __dirname = dirname(__filename);
@@ -48,6 +48,24 @@ function mockModelResponse(content) {
48
48
  function jsonBBoxResponse(target, bbox) {
49
49
  return `action: **CLICK**\nParameters: {"target": "${target}", "bbox_2d": [${bbox.join(', ')}]}`;
50
50
  }
51
+ const mockSharpInstance = {
52
+ resizeCalls: [],
53
+ toBufferImpl: () => Promise.resolve(Buffer.from('mock-compressed-image')),
54
+ resize(w, h) {
55
+ this.resizeCalls.push([w, h]);
56
+ return this;
57
+ },
58
+ jpeg(_opts) {
59
+ return this;
60
+ },
61
+ toBuffer() {
62
+ return this.toBufferImpl();
63
+ },
64
+ reset() {
65
+ this.resizeCalls = [];
66
+ this.toBufferImpl = () => Promise.resolve(Buffer.from('mock-compressed-image'));
67
+ },
68
+ };
51
69
  function arrayBBoxResponse(bbox) {
52
70
  return `The element is located at [${bbox.join(', ')}]`;
53
71
  }
@@ -57,6 +75,10 @@ describe('AIVisionFinder', () => {
57
75
  const originalFetch = global.fetch;
58
76
  let fetchSpy;
59
77
  beforeEach(() => {
78
+ mockSharpInstance.reset();
79
+ jest
80
+ .spyOn(imageUtil, 'requireSharp')
81
+ .mockReturnValue(((_input) => mockSharpInstance));
60
82
  fetchSpy = jest.fn();
61
83
  global.fetch = fetchSpy;
62
84
  process.env.AI_VISION_API_BASE_URL = 'https://mock-api.example.com/v1';
@@ -296,10 +318,6 @@ describe('AIVisionFinder', () => {
296
318
  });
297
319
  // ── Image compression – resize actually called ──────────────────────────────
298
320
  describe('findElement – image compression (resize verification)', () => {
299
- beforeEach(() => {
300
- // Reset shared sharp mock state before each test in this group
301
- mockSharpInstance.reset();
302
- });
303
321
  test('should call sharp resize when image width exceeds imageMaxWidth', async () => {
304
322
  process.env.AI_VISION_IMAGE_MAX_WIDTH = '100';
305
323
  const normalizedBBox = [