VibeView supports tvOS (Apple TV), Android TV and Roku (see Roku) on the Devices page, for recording and replay, and for AI-driven test runs. These platforms use a focus-based interaction model rather than touch: navigation happens with a d-pad, and actions operate on whichever UI element currently holds focus. Recording, replay, and the AI tool set all account for this.
Supported device groups
The device list on the Devices page lists TV devices under up to three headings, one per TV platform available to your organization:
- Apple TV — tvOS simulator entries (e.g. Apple TV 4K running tvOS).
- Android TV — Android TV emulator entries.
- Roku — physical Roku devices.
The exact models and OS versions depend on what the device fleet has available at the time; the list shows what is online rather than a fixed catalog.
Launching a TV session
- Open Devices.
- In the device list on the left, scroll to the Apple TV or Android TV heading and pick a device.
- Click Start session.
The session boots the same way as a phone or tablet session, and the video stream appears once the device is ready. You can install an app from your organization’s library into a TV session the same way you would on a phone.
Navigating with the d-pad
TV sessions have no touch interaction — tapping the stream does nothing. Instead, the page forwards keyboard events while a TV session is active. Navigation keys become d-pad presses:
| Keyboard | D-pad action |
|---|---|
| Arrow Up | DPAD_UP |
| Arrow Down | DPAD_DOWN |
| Arrow Left | DPAD_LEFT |
| Arrow Right | DPAD_RIGHT |
| Enter | DPAD_CENTER (select) |
| Escape | BACK |
Every other key is forwarded the same way it is on a phone session: printable characters (letters, digits, space, symbols) are typed into the focused field on the device, and Backspace deletes. That means apps with their own key handling (a search box, a debug shortcut, a game) receive the keys you press. Modifier chords such as Cmd+R or Ctrl+C are never forwarded, so browser shortcuts keep working, and a held key types once rather than repeating.
The status line at the bottom of the page reads D-pad: arrow keys, Enter to select · type to send while a TV session is live.
Keyboard forwarding is suppressed when focus is in an input, textarea, or select control on the page, so you can still type into the page’s own controls without firing keys at the device.
Focus model
TV apps draw a focus cursor that moves between interactive elements. A d-pad direction press moves that focus; DPAD_CENTER activates whatever is focused. VibeView surfaces focus in two places:
- UI tree — focused elements are marked
[focused]in the formatted tree the AI agent sees. On Android TV and Roku, elements that can take focus are also markedfocusable, both in that tree and in theui-treean agent reads through agent control, so an agent walking focus knows which elements a d-pad press can land on. The Apple TV tree does not carry thefocusablemark; use[focused]and the element types (buttons, cells) instead. On Apple TV the tree comes from the native automation layer. On Android TV thefocusedattribute from the device’s accessibility tree is preserved on each element. When focus sits on an unlabelled container, such as the frame around a tile or a tab, the tree marks the first labelled element inside it as[focused](the tile’s poster or the tab’s text). - Recordings — d-pad events captured during a recording are enriched with the focused element at the time of the press, so replay can confirm the intended target instead of only replaying key codes.
AI tools on TV sessions
When a test runs against a TV session, the agent’s tool list is adjusted to match the platform:
- Touch-only tools (
tap,tap_and_type,tap_coordinates,swipe,scroll_until_visible,gesture_preset,alert,long_press,select_picker_value,drag,keys) are removed. press_buttonis used for d-pad and back:dpad_up,dpad_down,dpad_left,dpad_right,dpad_center,back.homeis also accepted on Apple TV and Android TV, but the agent is explicitly warned that it exits the app and should only be used when a step requires leaving the app. On Roku the agent also hasplay,rewind,forward,replay,infoandbackspace, has nohome(the session stays in your channel), and has noclear_textoropen_url.type_text,clear_text,wait,locate,assert_visible,assert_not_visible,assert_value,find_element,step_complete, andstep_failedwork the same as on mobile.
On every TV platform the agent gets two additional focus tools:
tap_focused_tv(ref)— move focus to the element identified byrefand press SELECT in one call. Use this instead of chaining severalpress_button(dpad_*)calls followed bydpad_center.focus_element_tv(ref)— move focus to the element identified byrefwithout pressing SELECT. Use when you want to verify state or position focus before a subsequent action.
The two tools work on every platform, tuned to each:
- On Apple TV they use the platform’s built-in focus navigation to reach the element, then select it. The tools resolve
refagainst the current UI tree. - On Android TV VibeView navigates focus to the target element automatically and verifies focus actually arrived. If the element can’t be reached, the tool stops and reports it instead of pressing keys indefinitely.
- On Roku they move focus to the element, reaching list tiles by their title, and report when the channel’s focus can’t be observed.
Android TV focus-walk requires the app to expose focus to the device’s accessibility layer (react-native-tvos / Leanback native-focus apps). Apps that track focus only in their own JS never surface it, so focus-walk can’t see or verify it — see Limitations.
Recording TV interactions
Enhanced recording captures d-pad presses on TV sessions. Each press is automatically enriched with the element that held focus at the time, so replay can verify the intended target instead of only re-sending key codes. This happens in the background and never slows down your recording.
Focus-verified replay
When a recorded TV d-pad step carries a focused element, replay does not blindly re-send the recorded keycode. Instead it navigates to that element and verifies focus actually landed there before continuing. This makes replay survive layout drift: if a row or tile is added or removed since recording, replay still targets the intended element instead of silently mis-firing the old keycode at whatever now sits in that position.
If the element can’t be reached — it’s gone from the screen, or the app’s focus isn’t observable to the device’s accessibility layer — replay falls back to the recorded d-pad keycode and marks the step unverified, recording the reason. The behavior is identical on every TV platform.
For a complete worked example — a coding agent building a react-native-tvos app, running seven focus assertions on a cloud Apple TV and Android TV with these commands, and submitting it to both stores — read AI agent ships an Apple TV and Android TV app in 46 minutes, or clone the Marquee sample app.
Apple TV specifics
- A fresh Apple TV device has Settings only. Apple’s tvOS simulator has no App Store, browser, or TV app, so the way to use it is to upload your own tvOS build and start the session from it (see Preparing Your App Build: tvOS).
- The AI agent’s UI tree and focus actions on Apple TV are served by the native automation layer, which exposes the full element tree and focus state for the running app.
- On tvOS 18 and later you can hear the app’s audio: turn it on from the Audio section of the Device tab (see Device audio).
- When VibeView opens a link into your app (an AI step or
open-url), tvOS first asks “Open in “App”?”; VibeView answers Open when the prompt names your app, and leaves a prompt for any other app on screen. - tvOS prompts (a deep link’s “Open in …?” confirmation, permission alerts) show up in the UI tree as an
Alertwith their buttons, andalert get/alert accept --button <label>read and answer them from the CLI or MCP. Afterpress home, the next tree describes the tvOS home screen rather than coming back empty. Focus actions (focus,tap-focused) and typing act on whatever is on screen too: an icon on the home screen, or a field in Settings, works the same way as one in your app. A session started without an app has a UI tree too: it describes the home screen, or Settings once you open it.
Android TV specifics
- The device has internet access, but the Google apps that come bundled with the Android TV image (YouTube, YouTube Music, Play Games) only work on Play-certified hardware and are hidden from the home screen. Your own app connects normally.
- Android TV devices are a mix of 32-bit x86 and x86_64: a TV APK with native code should include both slices (see Preparing Your App Build: Android TV). Uploads warn when one is missing.
- The UI tree comes from the device’s accessibility tree. The
focusedandselectedattributes are preserved on every element, so the agent can see which row or tile holds focus. - Focus navigation is automatic: VibeView moves focus to the target element and verifies it arrived, or reports that the target can’t be reached. This is what backs
tap_focused_tv/focus_element_tvand focus-verified replay on Android TV. typeworks on a text field you have only focused: when its on-screen keyboard is closed, VibeView opens it first, so there’s no need to pressdpad_centerbefore typing.
Roku
Roku devices appear under a third heading in the device list, and a Roku session streams a real physical Roku device live to your browser.
Remote control works with the same keyboard model as the other TV platforms: arrow keys move the d-pad, Enter is OK/select, and Escape is back. Text entry is supported too — when a Roku on-screen keyboard is focused, printable keys you type are sent straight to it (Backspace deletes), with no separate typing mode.
The UI Tree Inspector works on Roku sessions. Element coordinates in the tree are best-effort, so treat highlighted positions as approximate.
You can hear the channel’s audio (turn it on from the Audio section — see Device audio).
Roku sessions are confined to the app under test: system and home navigation is blocked, and if the device leaves the app for any reason, VibeView brings the app back automatically. That includes a Back press on your channel’s first screen: a Roku exits the channel on an unhandled Back, so you will see the channel restart on its first screen a couple of seconds later. That is the confinement relaunching it, not a crash, and anything the channel wrote to the registry is still there.
Every Roku session starts from an app
Unlike iOS and Android, you cannot open a Roku device on its own — pick the app you want to test and start the session from there. Starting a Roku session without an app is rejected, because a Roku session has nowhere to go without one: home and system navigation are blocked by the confinement described above.
Upload your channel as a .zip on the Apps page like any other app, then start a session from it. Your channel is put on the device at the start of each session, so it takes a few seconds to appear after the stream comes up.
The stream and the remote are live during those few seconds, but nothing starts driving the session until your channel is actually up: a test you opened with Replay (or from a group) waits for it rather than running against the screen that happens to be showing. If the channel can’t be put on the device — a rejected package, say — the session tells you so instead of starting the replay.
Each session starts clean
Your channel is removed from the Roku when the session ends, and a fresh copy is put on for the next one. Anything the channel stored on the device — signed-in accounts, saved preferences, cached data — is gone with it, so every session begins from a first-launch state.
Sign-in state does not carry over between sessions. If your channel needs an account, sign in during each session or supply credentials with launch parameters.
Sharing and embedding
Roku channels can be shared with a public link and embedded on your own site, the same as apps on the other platforms. Each visitor gets a fresh copy of your channel, and their player shows Opening app… until it is installed and open. Visitors stay inside your channel: Home and system navigation are blocked for them just as they are in your own sessions.
Recording and test runs
Recording, replay and AI test runs work on Roku sessions the same way they do on the other TV platforms. Each remote press you record remembers the element that had focus, and replay moves focus to that element before continuing, so a recording keeps working when a row gains or loses an item.
Some channels draw their own focus highlight without telling the device which item is selected. On those screens VibeView cannot see which item is focused: replay presses the recorded keys in order, and the step is marked as replayed by key presses. Smart runs still check the screen after each step and hand over to AI if it does not match.
To fix that, build your channel with the VibeView Roku plugin. It lets VibeView see your channel’s own highlight and gives each item a stable id, so steps name the item you pressed and replay finds it even when the layout changes.
The start state applies on Roku too. Restart the app restarts your channel and keeps what it stored. Clean app data and Fresh install both remove the channel and install it again, which takes a few seconds: a Roku keeps a channel’s saved data (a signed-in account, saved settings) for as long as the channel is installed, so reinstalling is the only way to start from a clean state.
Link your Apple TV, Android TV and Roku apps as one product on the app page (see Same app on other platforms) so their tests are listed together on the Tests page. Roku channels rarely share a bundle id with your other apps, so VibeView suggests a Roku channel only when its name matches; otherwise link it by hand from the app page. TV tests and phone tests stay separate: a TV test never runs on a phone or tablet app.
Channel logs
The Logs tab of the Devices tools panel, vibeview logs and the agent logs tool show your
channel’s console output on Roku: everything it prints, the compile and run
markers around each install, the reason it exited, and — when it hits a
runtime error — the error and its backtrace. Output that belongs to a
previous session is not shown.
If the connection to the device drops mid-session, the log says so
(log reconnected -- channel output printed while the connection was down was not captured) and picks up from there. Anything the channel printed during
that gap is not recovered, so the log never shows output twice or presents
old output as new.
If the device’s console buffer has moved on too far for VibeView to tell
your session’s output apart from an earlier one, the log says that instead
of guessing (channel output is not being captured). Start a new session to
resume logging — reinstalling or restarting the channel on its own does not
restore it. The same message appears when the device cannot be reached at
all.
A channel that stops on a runtime error is closed and started again, the same way a crashing app is relaunched on the other platforms, so the stream never sits on a frozen screen; the error and backtrace stay in the log.
Reloading a channel while you develop
If you’re actively working on a channel, vibeview dev --platform roku opens
a live Roku session in your browser and lets you re-package, upload, and
reload the running channel from your terminal as you make changes — see
Roku under the dev command in the CLI
reference for the full workflow, including the auto-reload
--watch option.
Limitations
tap_focused_tvandfocus_element_tvwork on every TV platform. On Android TV they require focus to be observable to the device’s accessibility layer (react-native-tvos / Leanback native-focus apps). Apps that track focus only in their own JS never surface it: focus-walk can’t see or verify focus, so the agent and replay fall back to plainpress_button(dpad_*)navigation and steps are marked unverified. This is an app-architecture limitation, not a bug.- On Roku,
focus_element_tv/tap_focused_tvreach list tiles by their title. On screens where the channel draws its own highlight without moving the device’s focus, they cannot see which item is selected and report that instead. - Touch input into the video canvas is disabled on TV sessions. Navigate via keyboard.
- Exact device models depend on what the device fleet has available; VibeView does not ship a fixed catalog of TV devices.
Running TV tests from the CLI
The CLI run commands pick a TV device on their own for a test or group whose app is an Apple TV or Android TV app. --device-category tv asks for one explicitly (CLI 0.28.0 and earlier sent phone when you left it out, so pass it with those versions). The platform (tvOS vs Android TV) is still derived from the test case’s app — --device-category only selects the form factor.
vibeview run-test test-789 --device-category tv
vibeview run-suite suite-abc --device-category tv
vibeview run-suites --tag smoke --device-category tv
If no TV-category device is available, the run queues until one becomes available (same behavior as phone / tablet).
When multiple TV devices are registered, use vibeview list-devices --category tv
to find a specific device_id, then pin your run to it:
vibeview run-test test-789 --device atv-01
The --device flag overrides --device-category (the two cannot be combined).
Cross-TV replay (record on one TV platform, replay on the other)
A TV test recorded on one TV platform can be replayed on the other TV platform. Both Apple TV and Android TV are the same form factor (--device-category tv), so a recording made on one replays on the other — the same way iOS and Android mobile recordings replay cross-platform.
There is no special flag for this. Replay targets whichever TV platform the run is pointed at, and the platform comes from what you replay against: the test’s app, or the live session, determines the platform — exactly as described in Running TV tests from the CLI, where --device-category tv selects the form factor and the platform is derived from the app. To replay on the other platform, point the same recorded test at that platform’s app (or run it in a session on that platform): the device choice in the Run dialog, and --platform on vibeview run-test / run-suite and the platform field of the CI run API, find your app on the other TV platform by its bundle id / package name.
Whether a step replays verified or unverified depends on shared identifiers:
- When the app exposes shared, stable identifiers across platforms, replay reaches the recorded element by selector and focus-verifies it. react-native-tvos apps that set a JS
testIDget it mapped to the iOSaccessibilityIdentifierand the Androidresource-id, and replay matches the recorded identifier against whichever of those fields the live platform exposes it in — giving focus-verified cross-TV replay. - Without shared identifiers, the selector can’t match on the other platform, so replay falls back to portable d-pad keycodes (the
DPAD_*map is identical across both platforms) and the step is marked unverified.
So shared testIDs are what unlock verified cross-TV replay. The custom-JS-focus limitation applies here too: if an Android TV app’s focus isn’t observable to the device’s accessibility layer, focus can’t be verified on that side regardless of identifiers, and those steps fall back to unverified d-pad navigation.
See also
- AI testing — general AI-driven test behavior, tool list, and AI use.
- Devices — session basics and device selection.
- CLI — full CLI reference including
--device-category.