mobile-debug-mcp 0.20.1 → 0.21.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.
- package/dist/interact/index.js +154 -118
- package/dist/scripts/capture_ui_after_tap.mjs +43 -0
- package/dist/scripts/check_play_observe.mjs +18 -0
- package/dist/scripts/check_play_substring.mjs +38 -0
- package/dist/scripts/dump_ui_tree.mjs +20 -0
- package/dist/scripts/observe-test.mjs +32 -0
- package/dist/scripts/press_and_observe.mjs +90 -0
- package/dist/scripts/press_and_wait_ui.mjs +85 -0
- package/dist/scripts/test_generate_and_wait.mjs +123 -0
- package/dist/server.js +18 -0
- package/dist/system/gradle.js +4 -4
- package/dist/utils/android/utils.js +2 -2
- package/docs/CHANGELOG.md +3 -0
- package/package.json +1 -1
- package/src/interact/index.ts +96 -68
- package/src/server.ts +20 -0
- package/src/system/gradle.ts +4 -4
- package/src/utils/android/utils.ts +2 -2
- package/test/observe/unit/observe_until_edge_cases.test.ts +41 -0
- package/test/observe/unit/observe_until_stability.test.ts +30 -0
- package/test/interact/device/observe_until_device.ts +0 -24
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ToolsInteract } from '../../../../src/interact/index.js'
|
|
2
|
+
import * as Observe from '../../../../src/observe/index.js'
|
|
3
|
+
|
|
4
|
+
async function run() {
|
|
5
|
+
console.log('Unit: observe_until edge cases')
|
|
6
|
+
|
|
7
|
+
const origFind = (ToolsInteract as any).findElementHandler
|
|
8
|
+
const origFp = (Observe as any).ToolsObserve.getScreenFingerprintHandler
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
// 1) Immediate absence should pass for match='absent'
|
|
12
|
+
(ToolsInteract as any).findElementHandler = async () => ({ found: false })
|
|
13
|
+
const r1 = await (ToolsInteract as any).observeUntilHandler({ type: 'ui', query: 'Nothing', timeoutMs: 2000, pollIntervalMs: 100, stability_ms: 200, match: 'absent', platform: 'android' })
|
|
14
|
+
console.log('Immediate absent test:', r1 && (r1 as any).success ? 'PASS' : 'FAIL', JSON.stringify({ poll_count: (r1 as any).poll_count, duration_ms: (r1 as any).duration_ms, stable_duration_ms: (r1 as any).stable_duration_ms, matchSource: (r1 as any).matchSource }, null, 2))
|
|
15
|
+
|
|
16
|
+
// 2) Boundary stability: condition becomes true and stays exactly long enough
|
|
17
|
+
// Use pollInterval 100ms and stability 300ms -> need ~3 consecutive trues
|
|
18
|
+
let seq2 = [false, true, true, true]
|
|
19
|
+
(ToolsInteract as any).findElementHandler = async () => ({ found: seq2.shift() ?? true })
|
|
20
|
+
const r2 = await (ToolsInteract as any).observeUntilHandler({ type: 'ui', query: 'Boundary', timeoutMs: 2000, pollIntervalMs: 100, stability_ms: 300, match: 'present', platform: 'android' })
|
|
21
|
+
console.log('Boundary stability test:', r2 && (r2 as any).success ? 'PASS' : 'FAIL', JSON.stringify({ poll_count: (r2 as any).poll_count, duration_ms: (r2 as any).duration_ms, stable_duration_ms: (r2 as any).stable_duration_ms, matchSource: (r2 as any).matchSource }, null, 2))
|
|
22
|
+
|
|
23
|
+
// 3) Long flicker that never stabilizes should timeout/fail
|
|
24
|
+
// Sequence toggles true/false repeatedly
|
|
25
|
+
let seq3 = [false, true, false, true, false, true, false]
|
|
26
|
+
(ToolsInteract as any).findElementHandler = async () => ({ found: seq3.shift() ?? false })
|
|
27
|
+
const r3 = await (ToolsInteract as any).observeUntilHandler({ type: 'ui', query: 'Flicker', timeoutMs: 1200, pollIntervalMs: 150, stability_ms: 400, match: 'present', platform: 'android' })
|
|
28
|
+
console.log('Long flicker timeout test:', !(r3 && (r3 as any).success) ? 'PASS' : 'FAIL', JSON.stringify({ poll_count: (r3 as any).poll_count, duration_ms: (r3 as any).duration_ms, stable_duration_ms: (r3 as any).stable_duration_ms, matchSource: (r3 as any).matchSource }, null, 2))
|
|
29
|
+
|
|
30
|
+
// 4) Very short stability requirement should pass quickly
|
|
31
|
+
(ToolsInteract as any).findElementHandler = async () => ({ found: true })
|
|
32
|
+
const r4 = await (ToolsInteract as any).observeUntilHandler({ type: 'ui', query: 'ShortStable', timeoutMs: 2000, pollIntervalMs: 200, stability_ms: 50, match: 'present', platform: 'android' })
|
|
33
|
+
console.log('Short stability test:', r4 && (r4 as any).success ? 'PASS' : 'FAIL', JSON.stringify({ poll_count: (r4 as any).poll_count, duration_ms: (r4 as any).duration_ms, stable_duration_ms: (r4 as any).stable_duration_ms, matchSource: (r4 as any).matchSource }, null, 2))
|
|
34
|
+
|
|
35
|
+
} finally {
|
|
36
|
+
(ToolsInteract as any).findElementHandler = origFind
|
|
37
|
+
(Observe as any).ToolsObserve.getScreenFingerprintHandler = origFp
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
run().catch(e=>{ console.error(e); process.exit(1) })
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ToolsInteract } from '../../../../src/interact/index.js'
|
|
2
|
+
import * as Observe from '../../../../src/observe/index.js'
|
|
3
|
+
|
|
4
|
+
async function run() {
|
|
5
|
+
console.log('Unit: observe_until stability behavior')
|
|
6
|
+
|
|
7
|
+
const origFind = (ToolsInteract as any).findElementHandler
|
|
8
|
+
const origFp = (Observe as any).ToolsObserve.getScreenFingerprintHandler
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
// Simulate UI flicker: present, absent, present, then stable
|
|
12
|
+
const seq = [false, true, false, true, true, true]
|
|
13
|
+
(ToolsInteract as any).findElementHandler = async () => ({ found: seq.shift() ?? true })
|
|
14
|
+
|
|
15
|
+
const res = await (ToolsInteract as any).observeUntilHandler({ type: 'ui', query: 'X', timeoutMs: 5000, pollIntervalMs: 100, stability_ms: 500, platform: 'android' })
|
|
16
|
+
const ok = res && (res as any).success
|
|
17
|
+
console.log('Flicker stability test:', ok ? 'PASS' : 'FAIL', JSON.stringify((res as any).telemetry || {}, null, 2))
|
|
18
|
+
|
|
19
|
+
// Simulate immediate stable presence
|
|
20
|
+
(ToolsInteract as any).findElementHandler = async () => ({ found: true })
|
|
21
|
+
const res2 = await (ToolsInteract as any).observeUntilHandler({ type: 'ui', query: 'Y', timeoutMs: 2000, pollIntervalMs: 100, stability_ms: 300, platform: 'android' })
|
|
22
|
+
console.log('Immediate stable test:', res2 && (res2 as any).success ? 'PASS' : 'FAIL', JSON.stringify((res2 as any).telemetry || {}, null, 2))
|
|
23
|
+
|
|
24
|
+
} finally {
|
|
25
|
+
(ToolsInteract as any).findElementHandler = origFind
|
|
26
|
+
(Observe as any).ToolsObserve.getScreenFingerprintHandler = origFp
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
run().catch(e=>{ console.error(e); process.exit(1) })
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
(async function main(){
|
|
2
|
-
try{
|
|
3
|
-
const inter = await import('../../src/interact/index.ts')
|
|
4
|
-
const manage = await import('../../src/manage/index.ts')
|
|
5
|
-
const ToolsInteract = (inter as any).ToolsInteract
|
|
6
|
-
const ToolsManage = (manage as any).ToolsManage
|
|
7
|
-
|
|
8
|
-
const ANDROID_ID = process.env.ANDROID_DEVICE || 'emulator-5554'
|
|
9
|
-
const IOS_UDID = process.env.IOS_DEVICE || '2EFFD8FD-5D09-47CC-95F8-28BBE30AF7ED'
|
|
10
|
-
console.log('Device test starting. Android:', ANDROID_ID, 'iOS:', IOS_UDID)
|
|
11
|
-
|
|
12
|
-
// Start modul8 on both platforms if present
|
|
13
|
-
try { await ToolsManage.startAppHandler({ platform: 'android', appId: 'com.ideamechanics.modul8', deviceId: ANDROID_ID }); console.log('Started android app (if installed)') } catch(e){ console.error('Android start skipped:', e.message || e) }
|
|
14
|
-
try { await ToolsManage.startAppHandler({ platform: 'ios', appId: 'com.ideamechanics.modul8.Modul8', deviceId: IOS_UDID }); console.log('Started ios app (if installed)') } catch(e){ console.error('iOS start skipped:', e.message || e) }
|
|
15
|
-
|
|
16
|
-
// Observe UI for Generate Session on both devices (will timeout if not present)
|
|
17
|
-
const aRes = await ToolsInteract.observeUntilHandler({ type: 'ui', query: 'Generate Session', timeoutMs: 20000, pollIntervalMs: 500, platform: 'android', deviceId: ANDROID_ID })
|
|
18
|
-
console.log('Android observe result:', JSON.stringify(aRes, null, 2))
|
|
19
|
-
|
|
20
|
-
const iRes = await ToolsInteract.observeUntilHandler({ type: 'ui', query: 'Generate Session', timeoutMs: 20000, pollIntervalMs: 500, platform: 'ios', deviceId: IOS_UDID })
|
|
21
|
-
console.log('iOS observe result:', JSON.stringify(iRes, null, 2))
|
|
22
|
-
|
|
23
|
-
} catch (e) { console.error('ERR', e); process.exit(1) }
|
|
24
|
-
})()
|