Devices, Browsers, and Input Methods
Hosanna selects a platform separately from a target kind. A test can therefore run a platform expression in an owned browser or, where the launcher implements it, on a simulator or physical device.
Select a target
HosannaTestConfig accepts platform, target, appConfig, and device. Environment variables override the first two when config does not set them:
HS_TEST_PLATFORM=browser HS_TEST_TARGET=web npm run test:ui
HS_TEST_PLATFORM=tizen HS_TEST_TARGET=web HS_TEST_DEVICE=tizen npm run test:ui
HS_TEST_PLATFORM=webos HS_TEST_TARGET=web HS_TEST_DEVICE=webos npm run test:ui
HS_TEST_PLATFORM=roku HS_TEST_TARGET=device npm run test:ui
Target kinds are web, sim, and device. Use the package scripts in the application repository for supported combinations rather than assuming every platform/target pair has a complete transport.
Select target-specific tests in TypeScript:
import { createHosannaTestTarget } from '@tantawowa/hosanna-tools/testing';
import config from '../hosanna-test.config';
const target = createHosannaTestTarget(config);
test.runIf(target.matches({ platform: 'roku', target: 'device' }))(
'captures a Roku screenshot',
async ({ hs }) => {
await hs.screenshot.capture('roku-home');
},
);
{ target: 'web' } means a desktop Web DOM test transport. Use platform
browser, tizen, or webos to select the compile target; the device preset
only shapes an already-selected bundle.
Current capability matrix
The runtime descriptor reports the first seven capabilities below. Full-run video is separate launcher configuration because it records the surrounding test run rather than an in-app command. The current shared launcher supports:
| Capability | Owned browser | Physical Roku | Apple/Android native simulator | Physical Tizen/webOS |
|---|---|---|---|---|
| Remote-style keys | Yes | Yes, through ECP | Yes, through the command plane | App/MCP command plane plus direct real-remote validation |
| Touch | Web/iOS/Android platform expressions | No | No | No |
| Text entry | Yes | No | No | No |
| Deep link | Yes | Yes | Yes, through relaunch arguments | Bounded same-file MCP query reload for test-rig navigation; not a vendor launch deep link |
| Screenshot | Yes | Yes | Yes, through simctl or ADB | No shared/vendor screenshot transport |
| Registry | Yes | Yes | Yes | Shared command plane |
| Logs | Yes | Yes | Yes | App/MCP logs; vendor log streaming is optional |
| Full-run video | Playwright WebM | Capture-card/window capture when configured | Apple simulator recording; explicit macOS capture for Android | External capture-card/window capture when explicitly configured |
Call hs.app.capabilities() when a shared test can adapt safely; otherwise make the target requirement explicit with test.runIf.
Input APIs
Remote and keyboard-style input use the same semantic keys:
await hs.remote.press('Right');
await hs.remote.pressSequence(['Down', 'Down', 'Select']);
await hs.remote.keyDown('Right');
await hs.remote.keyUp('Right');
Browser and TV Web DOM targets send these through the Hosanna debugger input path. A Roku device uses ECP. This tests application navigation semantics without pretending the transports are identical, and it does not replace a real-remote timing test on TV hardware.
The public client exposes these calls for browser contexts created with touch enabled:
await hs.touch.tap(hs.control.byTestId('touch-card'));
await hs.touch.swipe({
from: { x: 900, y: 700 },
to: { x: 900, y: 300 },
durationMs: 250,
});
tap(locator) uses serialized control bounds. Prefer it over coordinates. The current public client has no separate pointer/mouse API; do not claim mouse coverage from a touch or remote test.
In the current launcher, a browser reattached through connectOverCDP can
advertise touch while Playwright rejects touchscreen.tap because hasTouch
was not enabled when that persistent context was created.
hosanna-ui-samples therefore uses the app-owned
integration/support/browser.ts helper to dispatch CDP touch events at the
center of semantic control bounds. Treat that helper as a documented browser
transport workaround until the owned context enables Playwright touch directly.
The same helper covers pointer activation with a real mouse click. It connects
to the fixture's browserCdpEndpoint, finds the owned test page, and clicks the
center of semantic control bounds. The pointer test is restricted to
{ platform: 'browser', target: 'web' }. Keep host-specific extensions like these
out of shared cross-target helpers.
Text entry is browser-only and fills the focused native HTML input after activating the Hosanna control. Pass an envSecret result for credentials so serialized diagnostics contain only the secret label.
Sample browser profile matrix
hosanna-ui-samples maps HS_TEST_DEVICE into HosannaTestConfig.device and provides these scripts:
| Script | Hosanna platform/preset | Intended expression/input |
|---|---|---|
npm run test:ui:web | browser, default Browser launch | desktop browser/remote-style tests |
npm run test:ui:tizen | tizen + tizen | Samsung initializer and keyboard-to-Tizen semantic path |
npm run test:ui:webos | webos + webos | LG initializer and keyboard-to-webOS semantic path |
npm run test:ui:ios-browser | ios + iphone-15 | phone design profile with touch |
npm run test:ui:tablet-browser | ios + ipad-10 | tablet design profile with touch |
npm run test:ui:android-browser | android + pixel-8 | phone design profile with touch |
npm run test:ui:tv-browser | apple-tv + apple-tv-4k | TV design profile with remote-style input |
npm run test:ui:devices | all seven preview scripts in sequence | complete sample browser matrix |
A device preset expands into Hosanna launch state: platform expression, logical
design size, DPI, default adapters, and orientation. tizen and webos
presets do not select an initializer; the launcher must build the matching
platform first. These profiles exercise layout and input semantics, not native
TV services.
Sample native simulator matrix
These scripts build, install, launch, and handshake with the vendor-native simulator:
| Script | Native target |
|---|---|
npm run test:ui:ios:sim | iOS Simulator |
npm run test:ui:appletv:sim | Apple TV Simulator |
npm run test:ui:android:sim | Android phone AVD |
npm run test:ui:androidtv:sim | Android TV AVD |
Set HS_TEST_DEVICE when more than one matching simulator is online. These runs support semantic commands, deep-link relaunch, and host screenshots. They still do not turn on the fixture’s touch or text-entry transports.
Browser profiles versus hardware
The owned Playwright Chromium context itself currently uses a 1920×1080 viewport. The public test config does not expose browser engine selection or an arbitrary Playwright viewport/device-scale-factor option. Phone/TV presets change the Hosanna design surface and platform expression inside that browser. Native simulators and physical devices remain distinct test targets.
Therefore:
- use the sample matrix for deterministic desktop, phone, tablet, and TV-expression application behavior;
- label browser-preset, native-simulator, and physical-device results with their actual target type;
- run native simulator/device validation through
hst runand platform-specific tests where the test transport supports the required assertions; - use real hardware for remote timing, native rendering, GPU, decoder, accessibility, and device-service behavior.
Changing the video output size does not change these limitations. For design sizing and the full preset catalog, see Device and Resolution.
Physical Roku setup
A Roku run needs a device reachable from the development machine, developer mode, ECP, installer/screenshot access, and the debug log port. Configure the IP and password through the application config/environment, for example:
HS_TEST_PLATFORM=roku \
HS_TEST_TARGET=device \
HOSANNA_ROKU_DEVICE_IP=192.168.1.50 \
HOSANNA_ROKU_DEV_PASSWORD='<developer-password>' \
npm run test:ui
Set HS_TEST_DEBUG_HOST only when automatic LAN selection chooses an address the Roku cannot reach. Keep device credentials out of source and uploaded artifacts.
Physical Tizen and webOS setup
The test launcher recognizes Tizen and webOS device platforms after the Samsung or LG CLI already trusts a friendly device alias. Keep Samsung certificate profiles and LG SSH keys/passphrases in vendor stores. Set the LAN debug host and secret-backed stream/DRM inputs through the local environment.
Playwright coverage must dispatch real DOM keyboard events through
webKeyboardTizen or webKeyboardWebOs; use that path to exercise the actual
adapters. Device journeys then verify raw remote timing,
Back, media/color keys, native video, captions, accessibility, lifecycle,
persistence, and reconnect behavior.
On a physical Tizen/webOS session, no-argument hs.app.relaunch() performs a
real DeviceDriver terminate/launch and waits for the MCP test session to
reconnect. Test-rig navigation with query parameters uses ReloadPage and is
restricted by the runtime to the current file:// package file. It does not
prove that the vendor launch CLI accepts application deep-link parameters.
There is no physical-TV screenshot transport; configure separate capture-card
or macOS window/display recording when the test needs video evidence. Store that
capture with the report for the tested model.
Next: Running in CI.
Public-mirror helpers: support/target.ts and the browser-only support/browser.ts.