From f9d8ad6279aae5876d9815378a106b2628c7713e Mon Sep 17 00:00:00 2001 From: Lana Begunova <70295997+lana-20@users.noreply.github.com> Date: Wed, 21 Oct 2026 08:42:55 -0700 Subject: [PATCH] An example for app_assistant, so the site builds again The generator requires an example for every tool, and app_assistant (mobiumdev/mobium#252) had none: the 2026-10-21 scheduled build failed with KeyError 'app_assistant', and the live site stayed at the 2026-10-20 build. Two scenarios, from the command's own help, in all five clients: "Open Clock" naming the app expected to come forward, and reading reached; and a question, reading the answer it showed. The first is captured on the Android 15 emulator, with Clock in front after. The second is not recorded: a signed-out emulator's Google Assistant answers a question with a web search sheet, read in one run of five, so its output would be third-party search results that change between runs. check_examples: 113 scenarios, 0 problems in every client, .NET included. --- data/runs.json | 9 +++++++++ examples/canonical.json | 18 ++++++++++++++++++ examples/dotnet.json | 8 ++++++++ examples/go.json | 8 ++++++++ examples/java.json | 8 ++++++++ examples/javascript.json | 8 ++++++++ examples/python.json | 8 ++++++++ scripts/capture.py | 4 ++++ static/img/shots/app_assistant-0-after.jpg | Bin 0 -> 23155 bytes 9 files changed, 71 insertions(+) create mode 100644 static/img/shots/app_assistant-0-after.jpg diff --git a/data/runs.json b/data/runs.json index 9c76a00..47f0eb9 100644 --- a/data/runs.json +++ b/data/runs.json @@ -768,5 +768,14 @@ "exit": 0, "output": "pressed \"DON'T SAVE\" on the dialog \"Save this draft?\\nYou can come back to it later.\"", "after": "/img/shots/app_alert-2-after.jpg" + }, + "app_assistant[0]": { + "tool": "app_assistant", + "index": 0, + "command": "mobium assistant \"Open Clock\" --app com.google.android.deskclock", + "verbatim": true, + "exit": 0, + "output": "asked Google Assistant (typed, not spoken): \"Open Clock\"\nit showed no text a screen read can see\nin front: com.google.android.deskclock\ncom.google.android.deskclock came forward", + "after": "/img/shots/app_assistant-0-after.jpg" } } diff --git a/examples/canonical.json b/examples/canonical.json index cbc4a66..37364c6 100644 --- a/examples/canonical.json +++ b/examples/canonical.json @@ -899,6 +899,24 @@ "args": {} } ], + "app_assistant": [ + { + "title": "Ask the assistant to open an app, and check that it came forward", + "cli": "mobium assistant \"Open Clock\" --app com.google.android.deskclock", + "args": { + "request": "Open Clock", + "app": "com.google.android.deskclock" + } + }, + { + "title": "Ask a question, and read the answer it showed", + "cli": "mobium assistant \"What is 15 times 3\" --timeout 20", + "args": { + "request": "What is 15 times 3", + "timeout": 20 + } + } + ], "app_hit_test": [ { "title": "Ask where a tap on an element would really land", diff --git a/examples/dotnet.json b/examples/dotnet.json index 479a8af..1981263 100644 --- a/examples/dotnet.json +++ b/examples/dotnet.json @@ -451,6 +451,14 @@ "code": "var found = device.Audit();\nConsole.WriteLine(found[\"findings\"]);" } ], + "app_assistant": [ + { + "code": "var got = device.Assistant(\"Open Clock\", app: \"com.google.android.deskclock\");\nif (!(got[\"reached\"] is bool reached && reached)) throw new Exception($\"in front: {got[\"front\"]}\");" + }, + { + "code": "var got = device.Assistant(\"What is 15 times 3\", timeoutSeconds: 20);\nConsole.WriteLine(got[\"answer\"]);" + } + ], "app_hit_test": [ { "code": "var hit = device.HitTest(\"testid=submit\");\nConsole.WriteLine(hit[\"reaches\"]);" diff --git a/examples/go.json b/examples/go.json index 346ee9f..b67ddb0 100644 --- a/examples/go.json +++ b/examples/go.json @@ -451,6 +451,14 @@ "code": "found, err := dev.Audit(ctx)\nif err != nil {\n\treturn err\n}\nfor _, f := range found.Findings {\n\tfmt.Println(f.Type, f.Summary)\n}" } ], + "app_assistant": [ + { + "code": "got, err := dev.Assistant(ctx, \"Open Clock\", mobium.AssistantOptions{App: \"com.google.android.deskclock\"})\nif err != nil {\n\treturn err\n}\nif got.Reached == nil || !*got.Reached {\n\treturn fmt.Errorf(\"Clock did not come forward: %s is in front\", got.Front)\n}" + }, + { + "code": "got, err := dev.Assistant(ctx, \"What is 15 times 3\", mobium.AssistantOptions{Timeout: 20 * time.Second})\nif err != nil {\n\treturn err\n}\nfmt.Println(got.Answer)" + } + ], "app_hit_test": [ { "code": "hit, err := dev.HitTest(ctx, \"testid=submit\")\nif err != nil {\n\treturn err\n}\nfmt.Println(hit.Reaches)" diff --git a/examples/java.json b/examples/java.json index b13ac9e..7a5474a 100644 --- a/examples/java.json +++ b/examples/java.json @@ -451,6 +451,14 @@ "code": "Map found = device.audit();\nSystem.out.println(found.get(\"findings\"));" } ], + "app_assistant": [ + { + "code": "Map got = device.assistant(\"Open Clock\", \"com.google.android.deskclock\", 0);\nif (!Boolean.TRUE.equals(got.get(\"reached\"))) throw new AssertionError(\"in front: \" + got.get(\"front\"));" + }, + { + "code": "Map got = device.assistant(\"What is 15 times 3\", null, 20);\nSystem.out.println(got.get(\"answer\"));" + } + ], "app_hit_test": [ { "code": "Map hit = device.hitTest(\"testid=submit\");\nSystem.out.println(hit.get(\"reaches\"));" diff --git a/examples/javascript.json b/examples/javascript.json index 8276f36..5b55590 100644 --- a/examples/javascript.json +++ b/examples/javascript.json @@ -451,6 +451,14 @@ "code": "const found = await device.audit()\nconsole.log(found.findings)" } ], + "app_assistant": [ + { + "code": "const got = await device.assistant('Open Clock', { app: 'com.google.android.deskclock' })\nif (!got.reached) throw new Error(`in front: ${got.front}`)" + }, + { + "code": "const got = await device.assistant('What is 15 times 3', { timeout: 20 })\nconsole.log(got.answer)" + } + ], "app_hit_test": [ { "code": "const hit = await device.hitTest('testid=submit')\nconsole.log(hit.reaches)" diff --git a/examples/python.json b/examples/python.json index 65586ad..891a8f7 100644 --- a/examples/python.json +++ b/examples/python.json @@ -451,6 +451,14 @@ "code": "found = device.audit()\nfor f in found[\"findings\"]:\n print(f[\"type\"], f[\"summary\"])" } ], + "app_assistant": [ + { + "code": "got = device.assistant(\"Open Clock\", app=\"com.google.android.deskclock\")\nassert got[\"reached\"], got[\"front\"]" + }, + { + "code": "got = device.assistant(\"What is 15 times 3\", timeout=20)\nprint(got[\"answer\"])" + } + ], "app_hit_test": [ { "code": "hit = device.hit_test(\"testid=submit\")\nprint(hit[\"reaches\"])" diff --git a/scripts/capture.py b/scripts/capture.py index da0d041..abc3d23 100644 --- a/scripts/capture.py +++ b/scripts/capture.py @@ -153,6 +153,10 @@ def app_screen(name): # played for two seconds, so the stop's expect has what it asks for. dict(tool="app_audio", i=0, setup=app_screen("Audio Demo") + ["wait testid=audioState"]), dict(tool="app_audio", i=1, setup=["tap testid=audioTone", "$sleep 3"]), + # The assistant, asked in typed text from the home screen: Clock is + # terminated first, so the picture shows the assistant bringing it forward. + dict(tool="app_assistant", i=0, setup=["terminate com.google.android.deskclock", "press home"], after=True, + pause=2.0, restore=["terminate com.google.android.deskclock", "press home"]), dict(tool="app_list_apps", i=0), dict(tool="app_contexts", i=0, setup=app_screen("WebViews") + ["tap 'text=Plain page'", "wait text=Back"], after=True), diff --git a/static/img/shots/app_assistant-0-after.jpg b/static/img/shots/app_assistant-0-after.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cc22327ca61a2b58622f423791643bc656b8f3f6 GIT binary patch literal 23155 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