Skip to content

feat(simdrive): a11y journeys + set_text for alert fields (1.0.0b10) - #165

Merged
mauricecarrier7 merged 2 commits into
mainfrom
simdrive-ax-journey-alert
Jun 22, 2026
Merged

feat(simdrive): a11y journeys + set_text for alert fields (1.0.0b10)#165
mauricecarrier7 merged 2 commits into
mainfrom
simdrive-ax-journey-alert

Conversation

@mauricecarrier7

Copy link
Copy Markdown
Contributor

Follow-on to #164. Two pieces, both validated end-to-end against a booted sim.

1. Accessibility journeys

The host-AX tools are now usable from the LLM journey runner:

  • perform_accessibility_action step — added to the runner's tool set, dispatch map, and system prompt, so a journey can invoke a VoiceOver custom action by name.
  • announcement_heard success criterion — the runner injects the announcements captured so far into the observation (simulator-only, best-effort) and a pure evaluator asserts the spoken text (case-insensitive substring).

A full VoiceOver flow is now expressible as a journey: drive to the reader → perform_accessibility_action "Where am I?" → succeed on announcement_heard.

2. set_text — text entry into fields HID can't reach

HID type_text (synthesized keystrokes) doesn't land in a UIAlertController prompt (e.g. a "Go to Page" dialog) — the field never receives the keys. set_text sets the field's AXValue directly via the host Accessibility API.

Verified the value propagates to the field's binding (the app actually reads it), against a real SwiftUI .alert text field — set_text "42" → tap Go → app shows "Went to page 42". Targets by identifier/label, or defaults to the first editable field in the window (the alert's field when a prompt is up). Simulator-only; TestKitApp FormTab gains a "Go to Page" alert fixture to exercise it.

This unblocks the PP-4529 Go-to-Page found/not-found branches that HID couldn't drive.

Packaging / tests

CI note

As on #164 and main, CodeQL and pip-audit fail pre-existing (dependency CVEs in requirements.lock; CodeQL config) — unrelated to this diff.

Scope / deferred

  • Scope: journey step + criterion, set_text + alert fixture, tests.
  • Deferred: label-scoping a field by its placeholder text (AXPlaceholderValue) — the first-editable-field default covers alerts; device-target (WDA) alert entry unchanged.

🤖 Generated with Claude Code

mauricecarrier7 and others added 2 commits June 22, 2026 11:35
…ents

Wires the host-AX tools into the LLM journey runner:

- New step tool `perform_accessibility_action` — added to StepDecision's tool
  set, the runner dispatch map, and the system prompt (so the agent can invoke
  a VoiceOver custom action by name during a journey).
- New success criterion `announcement_heard: "<text>"` — the runner injects the
  announcements captured so far into the observation (simulator-only, best-effort),
  and a pure evaluator checks the spoken text (case-insensitive substring).

This makes a full accessibility journey assertable end-to-end: drive to the
reader → perform "Where am I?" → succeed on announcement_heard.

Tests: tests/test_journey_ax.py (7); full non-live suite green (1580 passed).

**Scope:** journey step + criterion + prompt + tests.
**Deferred:** UIAlertController text entry (next).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
HID type_text can't land in a UIAlertController prompt (e.g. a "Go to Page"
dialog) — the field never receives synthesized keystrokes. Add a host-AX
set-value path that the app actually receives:

- ax.set_text() + tool `set_text`: set a field's AXValue directly. Verified the
  value propagates to the field's binding (the app reads it), against a real
  SwiftUI .alert text field. Targets by identifier/label, else the first
  editable field in the window (the alert's field when a prompt is up).
- Journey wiring: `set_text` added to the runner's tool set + dispatch + prompt
  (alongside the perform_accessibility_action step from the previous commit).
- TestKitApp FormTab gains a "Go to Page" alert fixture to exercise it.

Tool count 35 → 36; bumps 1.0.0b9 → b10. Tests: ax set_text field-find + tool
registration + journey dispatch. Full non-live suite green (1583 passed).

**Scope:** set_text + alert fixture + journey wiring + tests.
**Deferred:** label-scoping by placeholder text (AXPlaceholderValue) — first-field
default covers alerts; device-target alert entry (WDA) unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mauricecarrier7
mauricecarrier7 merged commit bff8bc8 into main Jun 22, 2026
5 of 7 checks passed
@mauricecarrier7
mauricecarrier7 deleted the simdrive-ax-journey-alert branch June 22, 2026 15:49
mauricecarrier7 added a commit that referenced this pull request Jun 23, 2026
…165)

* feat(simdrive): journey support for accessibility actions + announcements

Wires the host-AX tools into the LLM journey runner:

- New step tool `perform_accessibility_action` — added to StepDecision's tool
  set, the runner dispatch map, and the system prompt (so the agent can invoke
  a VoiceOver custom action by name during a journey).
- New success criterion `announcement_heard: "<text>"` — the runner injects the
  announcements captured so far into the observation (simulator-only, best-effort),
  and a pure evaluator checks the spoken text (case-insensitive substring).

This makes a full accessibility journey assertable end-to-end: drive to the
reader → perform "Read summary" → succeed on announcement_heard.

Tests: tests/test_journey_ax.py (7); full non-live suite green (1580 passed).

**Scope:** journey step + criterion + prompt + tests.
**Deferred:** UIAlertController text entry (next).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* feat(simdrive): set_text for alert fields via host-AX (1.0.0b10)

HID type_text can't land in a UIAlertController prompt (e.g. a "Go to Page"
dialog) — the field never receives synthesized keystrokes. Add a host-AX
set-value path that the app actually receives:

- ax.set_text() + tool `set_text`: set a field's AXValue directly. Verified the
  value propagates to the field's binding (the app reads it), against a real
  SwiftUI .alert text field. Targets by identifier/label, else the first
  editable field in the window (the alert's field when a prompt is up).
- Journey wiring: `set_text` added to the runner's tool set + dispatch + prompt
  (alongside the perform_accessibility_action step from the previous commit).
- TestKitApp FormTab gains a "Go to Page" alert fixture to exercise it.

Tool count 35 → 36; bumps 1.0.0b9 → b10. Tests: ax set_text field-find + tool
registration + journey dispatch. Full non-live suite green (1583 passed).

**Scope:** set_text + alert fixture + journey wiring + tests.
**Deferred:** label-scoping by placeholder text (AXPlaceholderValue) — first-field
default covers alerts; device-target alert entry (WDA) unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant