From 816dbac49329e35cdb408c7cb5f9bd3ce2eea270 Mon Sep 17 00:00:00 2001 From: Lana Begunova <70295997+lana-20@users.noreply.github.com> Date: Wed, 21 Oct 2026 10:11:58 -0700 Subject: [PATCH] An example for app_speech, so the site builds again The generator requires an example for every tool, and app_speech (mobiumdev/mobium#254) has none, so the next scheduled build would fail as it did for app_assistant. Three scenarios on MobiumApp's Form Demo, in all five clients: what the screen reader says where its cursor is, a walk of the screen in its order, and the cursor put on Pro. All three are captured on the Android 15 emulator with TalkBack on, and the picture shows TalkBack's green cursor on Pro, unselected. The capture needs TalkBack's log output level at VERBOSE, its own setting: it was set there by hand before and back to ERROR after, and TalkBack is off again. check_examples: 116 scenarios, 0 problems in every client, .NET included. --- data/runs.json | 25 ++++++++++++++++++++++++ examples/canonical.json | 22 +++++++++++++++++++++ examples/dotnet.json | 11 +++++++++++ examples/go.json | 11 +++++++++++ examples/java.json | 11 +++++++++++ examples/javascript.json | 11 +++++++++++ examples/python.json | 11 +++++++++++ scripts/capture.py | 9 +++++++++ static/img/shots/app_speech-2-after.jpg | Bin 0 -> 26845 bytes 9 files changed, 111 insertions(+) create mode 100644 static/img/shots/app_speech-2-after.jpg diff --git a/data/runs.json b/data/runs.json index 47f0eb9..7f146dc 100644 --- a/data/runs.json +++ b/data/runs.json @@ -777,5 +777,30 @@ "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" + }, + "app_speech[2]": { + "tool": "app_speech", + "index": 2, + "command": "mobium speech label=Pro", + "verbatim": true, + "exit": 0, + "output": "TalkBack says: \"not checked. Pro. Radio button\" — Pro (radio)", + "after": "/img/shots/app_speech-2-after.jpg" + }, + "app_speech[0]": { + "tool": "app_speech", + "index": 0, + "command": "mobium speech", + "verbatim": true, + "exit": 0, + "output": "TalkBack says: \"not checked. Pro. Radio button\" — Pro (radio)" + }, + "app_speech[1]": { + "tool": "app_speech", + "index": 1, + "command": "mobium speech --walk --limit 20", + "verbatim": true, + "exit": 0, + "output": "TalkBack says:\n 1. \"not checked. Team. Radio button\" — Team (radio)\n 2. \"OFF. Dark mode. Switch\" — Dark mode (switch)\n 3. \"Dark mode, for the whole app\" — Dark mode, for the whole app, not in map\n 4. \"Read-only\" — Read-only, not in map\n 5. \"This field cannot be edited. Edit box. disabled\"\n 6. \"notify=false terms=false plan=free theme=light\" — notify=false terms=false plan=free theme=light, not in map\n 7. (nothing)\n 8. \"Back. Button\" — Back (button)\n 9. \"Form\" — Form, not in map\n 10. \"not checked. Email me. Check box\" — Email me (checkbox)\n 11. \"not checked. Accept terms. Check box\" — Accept terms (checkbox)\n 12. \"checked. Free. Radio button\" — Free (radio)\n 13. \"not checked. Pro. Radio button\" — Pro (radio)\nended: the cursor came back round to the first element" } } diff --git a/examples/canonical.json b/examples/canonical.json index 37364c6..72ff483 100644 --- a/examples/canonical.json +++ b/examples/canonical.json @@ -917,6 +917,28 @@ } } ], + "app_speech": [ + { + "title": "Say what the screen reader says about the element its cursor is on", + "cli": "mobium speech", + "args": {} + }, + { + "title": "Walk the screen in the screen reader's order, each sentence beside its element", + "cli": "mobium speech --walk --limit 20", + "args": { + "walk": true, + "limit": 20 + } + }, + { + "title": "Put the screen reader's cursor on an element, and hear what it says", + "cli": "mobium speech label=Pro", + "args": { + "target": "label=Pro" + } + } + ], "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 1981263..1a7bc3a 100644 --- a/examples/dotnet.json +++ b/examples/dotnet.json @@ -459,6 +459,17 @@ "code": "var got = device.Assistant(\"What is 15 times 3\", timeoutSeconds: 20);\nConsole.WriteLine(got[\"answer\"]);" } ], + "app_speech": [ + { + "code": "var said = device.Speech();\nConsole.WriteLine(said[\"steps\"]);" + }, + { + "code": "var walk = device.Speech(walk: true, limit: 20);\nConsole.WriteLine($\"{walk[\"steps\"]} ended {walk[\"ended\"]}\");" + }, + { + "code": "var said = device.Speech(\"label=Pro\");\nConsole.WriteLine(said[\"steps\"]);" + } + ], "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 b67ddb0..be6527d 100644 --- a/examples/go.json +++ b/examples/go.json @@ -459,6 +459,17 @@ "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_speech": [ + { + "code": "said, err := dev.Speech(ctx, mobium.SpeechOptions{})\nif err != nil {\n\treturn err\n}\nfmt.Println(said.Steps[0].Said)" + }, + { + "code": "walk, err := dev.Speech(ctx, mobium.SpeechOptions{Walk: true, Limit: 20})\nif err != nil {\n\treturn err\n}\nfor _, step := range walk.Steps {\n\tfmt.Println(step.Said)\n}\nfmt.Println(\"ended:\", walk.Ended)" + }, + { + "code": "said, err := dev.Speech(ctx, mobium.SpeechOptions{Target: \"label=Pro\"})\nif err != nil {\n\treturn err\n}\nfmt.Println(said.Steps[0].Said)" + } + ], "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 7a5474a..0952461 100644 --- a/examples/java.json +++ b/examples/java.json @@ -459,6 +459,17 @@ "code": "Map got = device.assistant(\"What is 15 times 3\", null, 20);\nSystem.out.println(got.get(\"answer\"));" } ], + "app_speech": [ + { + "code": "Map said = device.speech(null, false, 0);\nSystem.out.println(said.get(\"steps\"));" + }, + { + "code": "Map walk = device.speech(null, true, 20);\nSystem.out.println(walk.get(\"steps\") + \" ended \" + walk.get(\"ended\"));" + }, + { + "code": "Map said = device.speech(\"label=Pro\", false, 0);\nSystem.out.println(said.get(\"steps\"));" + } + ], "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 5b55590..5ac165f 100644 --- a/examples/javascript.json +++ b/examples/javascript.json @@ -459,6 +459,17 @@ "code": "const got = await device.assistant('What is 15 times 3', { timeout: 20 })\nconsole.log(got.answer)" } ], + "app_speech": [ + { + "code": "const said = await device.speech()\nconsole.log(said.steps)" + }, + { + "code": "const walk = await device.speech({ walk: true, limit: 20 })\nconsole.log(walk.steps, walk.ended)" + }, + { + "code": "const said = await device.speech({ target: 'label=Pro' })\nconsole.log(said.steps)" + } + ], "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 891a8f7..64c42df 100644 --- a/examples/python.json +++ b/examples/python.json @@ -459,6 +459,17 @@ "code": "got = device.assistant(\"What is 15 times 3\", timeout=20)\nprint(got[\"answer\"])" } ], + "app_speech": [ + { + "code": "said = device.speech()\nprint(said[\"steps\"][0][\"said\"])" + }, + { + "code": "walk = device.speech(walk=True, limit=20)\nfor step in walk[\"steps\"]:\n print(step[\"said\"], step.get(\"element\", {}).get(\"label\"))" + }, + { + "code": "said = device.speech(\"label=Pro\")\nprint(said[\"steps\"])" + } + ], "app_hit_test": [ { "code": "hit = device.hit_test(\"testid=submit\")\nprint(hit[\"reaches\"])" diff --git a/scripts/capture.py b/scripts/capture.py index abc3d23..129f437 100644 --- a/scripts/capture.py +++ b/scripts/capture.py @@ -157,6 +157,15 @@ def app_screen(name): # 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"]), + # The screen reader on the Form Demo, TalkBack turned on after the screen + # is up. The cursor is put on Pro first, so the picture shows TalkBack's + # green rectangle there and the plain read after it says Pro; the walk + # goes last, and TalkBack goes off. Needs TalkBack's log output level at + # VERBOSE, which is TalkBack's own setting: set it there before, and back. + dict(tool="app_speech", i=2, setup=app_screen("Form Demo") + ["wait label=Pro", "accessibility screen_reader on", + "$sleep 3"], after=True, pause=1.0), + dict(tool="app_speech", i=0), + dict(tool="app_speech", i=1, restore=["accessibility screen_reader off"]), 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_speech-2-after.jpg b/static/img/shots/app_speech-2-after.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d8639f3927a72dac29f91f7eba4679f6f55f5802 GIT binary patch literal 26845 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