The behaviour specs ran headless, against mocks. That catches logic errors and misses everything that only shows up on a real device: the keyboard, the soft input, the rendering, the navigation.

This adds an on-device Android layer driven by Maestro. The same behaviour specs now run against a handset, with glue that drives the app the way a person does.

Two things took longer than expected. The first is text input: a Chinese pinyin keyboard holds injected Latin keystrokes in its composition buffer and never commits them, so an input that works headless silently does nothing on device. The second is that text selectors in Maestro are full-match regular expressions, so “Continue” never matches “Continue as Mara”.

Both are the kind of thing you only learn by running against the real thing, which is the point of the layer.