mobile-debug-mcp 0.12.8 → 0.14.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.
@@ -0,0 +1,129 @@
1
+ import { ToolsInteract } from '../../../src/tools/interact.js'
2
+ import { ToolsObserve } from '../../../src/tools/observe.js'
3
+
4
+ const origGet = (ToolsObserve as any).getUITreeHandler
5
+ const origSwipe = (ToolsInteract as any).swipeHandler
6
+
7
+ async function runTests() {
8
+ // Use a stable logger to avoid test harness replacing console.log between calls
9
+ console.log = (...args: any[]) => { try { process.stdout.write(args.map(a => (typeof a === 'string' ? a : JSON.stringify(a))).join(' ') + '\n') } catch {} }
10
+ console.log('Starting tests for scroll_to_element...')
11
+
12
+ // Test 1: Element found immediately
13
+ console.log('\nTest 1: Element found immediately')
14
+ (ToolsObserve as any).getUITreeHandler = async () => ({
15
+ device: { platform: 'android', id: 'mock', osVersion: '12', model: 'Pixel', simulator: true },
16
+ screen: '',
17
+ resolution: { width: 1080, height: 1920 },
18
+ elements: [{
19
+ text: 'Target',
20
+ type: 'Button',
21
+ contentDescription: null,
22
+ clickable: true,
23
+ enabled: true,
24
+ visible: true,
25
+ bounds: [0, 0, 100, 100],
26
+ resourceId: null
27
+ }]
28
+ })
29
+
30
+ const res1 = await ToolsInteract.scrollToElementHandler({ platform: 'android', selector: { text: 'Target' }, direction: 'down', maxScrolls: 5, scrollAmount: 0.7 })
31
+ console.log('Result:', res1.success === true ? 'PASS' : 'FAIL')
32
+ console.log('scrollsPerformed:', (res1 as any).scrollsPerformed)
33
+
34
+ // Test 2: Element found after scrolling
35
+ console.log('\nTest 2: Element found after scrolling')
36
+ let calls = 0
37
+ (ToolsObserve as any).getUITreeHandler = async () => {
38
+ calls++
39
+ if (calls < 3) {
40
+ return {
41
+ device: { platform: 'android', id: 'mock', osVersion: '12', model: 'Pixel', simulator: true },
42
+ screen: '',
43
+ resolution: { width: 1080, height: 1920 },
44
+ elements: []
45
+ }
46
+ }
47
+ return {
48
+ device: { platform: 'android', id: 'mock', osVersion: '12', model: 'Pixel', simulator: true },
49
+ screen: '',
50
+ resolution: { width: 1080, height: 1920 },
51
+ elements: [{
52
+ text: 'Target',
53
+ type: 'Button',
54
+ contentDescription: null,
55
+ clickable: true,
56
+ enabled: true,
57
+ visible: true,
58
+ bounds: [0, 0, 100, 100],
59
+ resourceId: null
60
+ }]
61
+ }
62
+ }
63
+
64
+ // Stub swipe so it doesn't try to call adb/idb
65
+ (ToolsInteract as any).swipeHandler = async () => ({ success: true })
66
+
67
+ const res2 = await ToolsInteract.scrollToElementHandler({ platform: 'android', selector: { text: 'Target' }, direction: 'down', maxScrolls: 5, scrollAmount: 0.7 })
68
+ console.log('Result:', res2.success === true ? 'PASS' : 'FAIL')
69
+ console.log('calls:', calls, calls >= 3 ? 'PASS' : 'FAIL')
70
+
71
+ // Test 3: UI unchanged stops early
72
+ console.log('\nTest 3: UI unchanged stops early')
73
+ (ToolsObserve as any).getUITreeHandler = async () => ({
74
+ device: { platform: 'android', id: 'mock', osVersion: '12', model: 'Pixel', simulator: true },
75
+ screen: '',
76
+ resolution: { width: 1080, height: 1920 },
77
+ elements: []
78
+ })
79
+
80
+ (ToolsInteract as any).swipeHandler = async () => ({ success: true })
81
+
82
+ const res3 = await ToolsInteract.scrollToElementHandler({ platform: 'android', selector: { text: 'Missing' }, direction: 'down', maxScrolls: 5, scrollAmount: 0.7 })
83
+ console.log('Result:', res3.success === false && (res3 as any).attempts === 1 ? 'PASS' : 'FAIL')
84
+ console.log('Reason:', (res3 as any).reason || JSON.stringify(res3))
85
+
86
+ // Test 4: Offscreen element scrolls into view
87
+ console.log('\nTest 4: Offscreen element scrolls into view')
88
+ const ai = new (await import('../../../src/android/interact.js')).AndroidInteract()
89
+ const origObserveGet = ai['observe'].getUITree
90
+ const origAiSwipe = ai.swipe
91
+ let swiped = false
92
+ let swipeCalled = 0
93
+ ;(ai['observe'] as any).getUITree = async () => {
94
+ if (!swiped) {
95
+ return {
96
+ device: { platform: 'android', id: 'mock', osVersion: '12', model: 'Pixel', simulator: true },
97
+ screen: '',
98
+ resolution: { width: 1080, height: 1920 },
99
+ elements: [ { text: null, type: 'android.view.View', resourceId: null, contentDescription: null, bounds: [0,0,1080,200], visible: true } ]
100
+ }
101
+ }
102
+ return {
103
+ device: { platform: 'android', id: 'mock', osVersion: '12', model: 'Pixel', simulator: true },
104
+ screen: '',
105
+ resolution: { width: 1080, height: 1920 },
106
+ elements: [{ text: 'OffscreenTarget', type: 'android.widget.Button', contentDescription: null, clickable: true, enabled: true, visible: true, bounds: [100,400,300,460], resourceId: null }]
107
+ }
108
+ }
109
+ ;(ai as any).swipe = async () => { swipeCalled++; swiped = true; return { success: true } }
110
+
111
+ const r4 = await ai.scrollToElement({ text: 'OffscreenTarget' }, 'down', 3, 0.7, 'mock')
112
+ const ok4 = r4 && (r4 as any).success === true && (r4 as any).scrollsPerformed === 1 && swipeCalled === 1
113
+ console.log('Result:', ok4 ? 'PASS' : 'FAIL')
114
+ console.log(' success:', (r4 as any).success, 'scrollsPerformed:', (r4 as any).scrollsPerformed, 'swipeCalled:', swipeCalled)
115
+
116
+ ;(ai['observe'] as any).getUITree = origObserveGet
117
+ ;(ai as any).swipe = origAiSwipe
118
+
119
+ // Restore
120
+ (ToolsObserve as any).getUITreeHandler = origGet
121
+ ;(ToolsInteract as any).swipeHandler = origSwipe
122
+ }
123
+
124
+ // Ensure console.log is a function (some test runners replace it)
125
+ if (typeof console.log !== 'function') {
126
+ console.log = (...args: any[]) => { try { process.stdout.write(args.map(a => (typeof a === 'string' ? a : JSON.stringify(a))).join(' ') + '\n') } catch { /* swallow */ } }
127
+ }
128
+
129
+ runTests().catch(console.error)
@@ -95,7 +95,7 @@ async function runTests() {
95
95
  const elapsed4 = Date.now() - start4;
96
96
  console.log("Result:", result4.found === false && result4.error === "ADB Connection Failed" ? "PASS" : "FAIL");
97
97
  console.log("Error Message:", result4.error);
98
- console.log("Elapsed time (should be < 500ms):", elapsed4, elapsed4 < 500 ? "PASS" : "FAIL");
98
+ console.log("Elapsed time (should be < 1000ms):", elapsed4, elapsed4 < 1000 ? "PASS" : "FAIL");
99
99
 
100
100
  // Restore
101
101
  (AndroidObserve as any).prototype.getUITree = originalGetUITree;