--- name: showcase-qa description: On-device regression sweep of every UI Kitten component using agent-device against the Expo showcase app (src/showcases). Use when asked to test the library on a simulator/emulator, hunt visual or interaction regressions, verify a component fix on device, or record/replay .ad scripts. --- # Showcase QA with agent-device Goal: drive the showcase app on a simulator, exercise every component section in all four theme/mapping combinations, and report regressions with evidence. Facts about the app (bundle id, test IDs, scripts) are in the repo `AGENTS.md`; read it first. ## 0. Preconditions (do once) ```bash agent-device --version # must exist; never npx -y agent-device@latest yarn showcases:start # Metro on :8081, background it (debug builds only) yarn showcases:ios # prebuild + pod install + build + install ``` If `expo run:ios` fails with `Unable to boot device because we cannot determine the runtime bundle`, pick a simulator whose runtime is installed: `xcrun simctl list devices available`, boot it by UDID with `xcrun simctl boot `, then pass `--device `. Do not run `agent-device doctor` as routine prep. Run it only when `open` fails. ## 1. Open ```bash agent-device open com.uikitten.showcases --platform ios --relaunch --session qa ``` `open` returns the initial interactive snapshot. If it shows a LogBox/RedBox overlay, that is finding #1: `screenshot --overlay-refs`, `react-devtools errors`, then `agent-device react-native dismiss-overlay` and continue. ## 2. Sweep loop The app is one `ScrollView` (`id="showcase-scroll"`). Sections in order: Layout, Button, ButtonGroup, Input, CheckBox, Toggle, Radio, RadioGroup, Card, Avatar, Spinner, ProgressBar, CircularProgressBar, Divider, Icon, List, ListItem, Menu, MenuItem, Select, SelectItem, Popover, Tooltip, OverflowMenu, Modal, TopNavigation, TopNavigationAction, BottomNavigation, BottomNavigationTab, Tab, TabBar, TabView, Drawer, DrawerItem, Calendar, RangeCalendar, Datepicker, RangeDatepicker, Autocomplete, ViewPager. For each section: 1. `agent-device scroll down --settle` until `id="section--title"` is in the diff (or `agent-device wait 'id="section--title"'` after a scroll). 2. `agent-device screenshot .agent-device/qa/-/.png`. 3. Interact with what the section exposes, always with `--settle`, and verify from the diff: - Button/ButtonGroup: press each visible button; nothing should throw. - Input/Autocomplete: `fill` text, check the value echoes; `keyboard dismiss`. - CheckBox/Toggle/Radio/RadioGroup: press, verify `selected` flips (`is selected `). - Select/Datepicker/RangeDatepicker/Popover/Tooltip/OverflowMenu/Modal: press the trigger, verify the overlay content appears in the diff, pick an item, verify the overlay closes and the trigger reflects the choice. **Overlay not appearing, appearing at 0,0, or not closing is a regression.** - Calendar/RangeCalendar: press a day, verify selection; page next/prev month. - Tab/TabBar/TabView/BottomNavigation/ViewPager: press each tab, verify the selected indicator moves; swipe the ViewPager. - Menu/Drawer/List: press items, verify selection changes. 4. If a section looks wrong in the screenshot but the snapshot is fine, keep the screenshot as evidence and note it as "visual". ## 3. Theme / mapping matrix Repeat the sweep for each of: Eva/Light (default), Eva/Dark, Material/Light, Material/Dark. Switch with `press 'id="toggle-theme"' --settle` and `press 'id="toggle-mapping"' --settle`; confirm via `get text 'id="theme-label"'`. Compare the screenshot of each section across the four combinations; a section that renders identically in light and dark, or that loses borders/contrast, is a theming regression. ## 4. Render health (optional, per suspect component) ```bash agent-device react-devtools status agent-device react-devtools wait --connected agent-device react-devtools profile start # interact with the suspect section a few times agent-device react-devtools profile stop agent-device react-devtools profile rerenders --limit 10 agent-device react-devtools profile slow --limit 5 ``` Report render offenders separately from visual/interaction findings. ## 5. Save replays for the regression suite For a flow worth guarding, re-run it with recording armed and durable selectors (ids/labels, not `@refs`), then commit the script under `src/showcases/e2e/`: ```bash agent-device open com.uikitten.showcases --platform ios --relaunch --session rec \ --save-script src/showcases/e2e/.ad # ... steps using id="..." selectors and --settle ... agent-device close --session rec ``` Every script must start with `context platform=ios` (add `context timeout=` if needed) so `agent-device test` can discover it. Run the suite: `yarn e2e:ios`. ## Selector gotchas (verified on iOS simulator) - Nodes exposed as `[other]` (CheckBox, Radio, MenuItem, SelectItem, calendar days, Datepicker input) do **not** match `label="..."` or `text="..."` selectors. Use the `@eN` ref from the latest `snapshot -i`, or `find "" press --first|--last`. - `press` has no `--first/--last`; `find` and `gesture` have no `--settle`. After `find ... press`, run `wait stable`. - A text field's placeholder is not its label. Focus it by ref, then `type ""`. - `scroll ` lands by scroll physics, not exact offset. Loop `is visible 'id="section--title"'` / `scroll down 0.5 --settle` instead of counting. - `keyboard dismiss` fails on iOS (no dismiss key). Tap a neutral area, never the header buttons (`toggle-theme` / `toggle-mapping` sit at the top right and are easy to hit by accident). - Never start Metro with `CI=1`: Expo disables watch mode ("reloads are disabled") and every edit after startup is silently ignored. Verify an edit landed by fetching the bundle: `curl -s 'http://127.0.0.1:8081/src/showcases/index.ts.bundle?platform=ios&dev=true' | grep -c `. - Set `AGENT_DEVICE_SESSION=qa` in the shell rather than passing `--session` from a zsh variable; unquoted `$VAR` is not word-split in zsh. - The iOS backend never exposes the `selected` trait: `is selected` errors on every element, even the active BottomNavigation tab, and `get attrs` lists only type/label/value/rect. Verify selection through visible state (label, value, diff) instead. Do not report "selected state missing" from agent-device output alone. - Roles without a native iOS trait (checkbox, radio, menuitem) show as `[other]`. Check `snapshot --raw`: React Native folds role + state into `value`, e.g. `"value":"checkbox, checked"`, which is what VoiceOver announces. That is RN's design, not a library bug. Switch/button/text-field have native traits and show their own type. - A `Card` exposes its children as one grouped `[other]` node ("Welcome…, SHOW TOOLTIP, DISMISS"). `find "DISMISS" press --first` then taps the group's centre, not the button. Read the button's position from a screenshot and `press --settle`. - Overlay content covers the header, so `press 'id="toggle-theme"'` while a Popover is open only closes the Popover. Flip the theme first, then open the overlay and inspect its colours. - When two calendars are on screen (Calendar showcase + an open Datepicker), `label="16"` is ambiguous; the error lists candidates with `@eN~sM` refs, and the later one is the picker's. A bare `@eN` from an older snapshot may silently do nothing: prefer the `~s` form it printed. - Closing a Tooltip by tapping "outside" must avoid the bubble itself; tap well below the anchor. - A `TextInput` focused inside a `Modal` makes the first tap on a nested `Select` option only blur the input (Select's own list has no `keyboardShouldPersistTaps`). Tap twice or blur first. - Android emulator: if the app shows "Unable to load script" and logcat says `Failed to connect to /10.0.2.2:8081`, the emulator's host NAT is down (no `default` route). Cold-boot it (`emulator -avd Pixel_7_API_34 -no-snapshot-load`), run `adb reverse tcp:8081 tcp:8081` again (a fresh boot drops it), then `agent-device open com.uikitten.showcases --platform android --relaunch --metro-host localhost --metro-port 8081`; that flag is what sets `debug_http_host` (editing the pref by hand gets overwritten). Reloading from the RedBox can leave a blank surface: force-stop and open again instead. A Release build is no way out: agent-device refuses non-debuggable Android apps (`run-as: package not debuggable`). - `expo run:android --device` wants an AVD *name* (`Pixel_7_API_34`), not `emulator-5554`; with a single running emulator, omit it. ## 6. Close and report `agent-device close --session qa`. Report format (one bullet per finding, no praise): - ` · / · `: what was expected, what happened, evidence path(s). Include the RN overlay text verbatim if one appeared. - End with a table: component × combination, ✓ / ✗ / not exercised.