Skip to content

WebDriver for testing channels / screensavers on roku devices

License

Notifications You must be signed in to change notification settings

dlenroc/appium-roku-driver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

93 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Appium Roku Driver · NPM Version Node.js Version Node.js CI

Roku Driver is a WebDriver that allows testing channels/screensavers using any webdriver client.

Prerequisites

Installation

appium driver install --source npm @dlenroc/appium-roku-driver

Documentation

Thanks to the Appium and WebDriver protocol, this driver works just like other web drivers, but there are a couple of things worth mentioning.

Initialization

Like other drivers, roku-driver by default uses the so-called fast reset algorithm, in which registries are cleared before each test, and a full reinstallation occurs only if the channel differs from the one already installed.

Locators

The following location strategies are supported: tag name, link text, partial link text, css selector and xpath.

Contexts

  • ECP (default) External Control Protocol is a context that finds elements quickly, but does not see many attributes.

  • ODC (WIP) On Device Component is a context that finds elements slower, but see all attributes. (can be tunned using elementResponseAttributes setting).

Deep linking

  • input - Sends a custom event to the launched channel.

    driver.url('roku://input?<key>=<value>');
  • launch - Launches given channel with specific arguments.

    driver.url('roku://launch/:channel_id?<key>=<value>');

Channels

In roku appId is always dev for sideloaded channel or a number for channels installed from store (ex: 12 for Netflix).

driver.queryAppState('dev');
driver.queryAppState('12');

Note: most commands only work with SceneGrapth based sideloaded channels.

Screensaver / Screensaver Settings

Given driver allows testing of Screensavers via appium:entryPoint capability.

  • channel (default) - Opens channel itself.
  • screensaver - Opens your channel screen saver.
  • screensaver-settings - Opens your channel screen saver settings.

Note: Usually screensavers open on their own and close immediately after any user input is sent, but when entryPoint screensaver is used, it runs in the context of the channel, so the input interaction does not close it (BACK and HOME buttons are an exception).

Registries / Arguments

In Roku world:

So, knowing this, we can significantly speed up the automation by skipping authorization/configuration steps.

Note: appium:arguments and appium:registry will contain different values in your case.

const capabilities = {
  ...commonCapabilities,

  // Launch parameters
  'appium:arguments': {
    contentId: 1234,
    mediaType: 'movie',
  },

  // Registry sections Settings
  'appium:registry': {
    account: {
      token: '<user_token>',
    },
  },
};

BrightScript Logging

// Forward logs to the console
driver.on('log.entryAdded', (entry) => console.log(entry.text));

// Subscribe to BrightScript logs
await driver.sessionSubscribe({ events: ['log.entryAdded'] });

// Unsubscribe from BrightScript logs (optional)
await driver.sessionUnsubscribe({ events: ['log.entryAdded'] });

Note:

Actions

The following action types are supported:

  • keyDown, keyUp - presses/releases given key.
  • pointerMove - focuses the element using arrow buttons.
  • pause - waits given amounts of milliseconds.

Below are the key codes and their equivalents in the roku remote.

Code Keyboard Key Roku Key
\uE002 Help Info
\ue003 Backspace Backspace
\ue006 Return Enter
\ue007 Enter Select
\ue00b Pause Play
\uE00C Escape Back
\uE00E Page Up ChannelUp
\uE00F Page Down ChannelDown
\ue011 Home Home
\ue012 Arrow Left Left
\ue013 Arrow Up Up
\ue014 Arrow Right Right
\ue015 Arrow Down Down
\uE01A 0 InputAV1
\uE01B 1 InputHDMI1
\uE01C 2 InputHDMI2
\uE01D 3 InputHDMI3
\uE01E 4 InputHDMI4
\uE01F 5 InputTuner
\uE036 F6 InstantReplay
\uE037 F7 Rev
\uE038 F8 Play
\uE039 F9 Fwd
\uE03A F10 VolumeMute
\uE03B F11 VolumeDown
\uE03C F12 VolumeUp

Capabilities

If adding a vendor prefix is a problem, @appium/relaxed-caps-plugin can be used to get rid of them.

Roku Capabilities

Capability Required Type Description
appium:ip + string The IP address of the target device
appium:password + string Password for the development environment
appium:username - string Username for the development environment
appium:context - string Sets the context to be used, default ECP
appium:registry - object Pre-fills the registry with the specified sections/keys
appium:arguments - object Parameters to be passed to the main method
appium:entryPoint - string Specifies the channel entry point, possible values are channel, screensaver, screensaver-settings

Appium Capabilities

Capability Required Type Description
platformName + string Must be roku
appium:automationName + string Must be roku
appium:deviceName +/- string Helps webdriver clients understand that they are dealing with appium
webSocketUrl - boolean Opt in to the use of the Bidi protocol. Defaults to false.
appium:app - string The absolute local path or remote http URL to channel
appium:noReset - boolean Do not stop app, do not clear app data, and do not uninstall app
appium:printPageSourceOnFindFailure - boolean When a find operation fails, print the current page source. Defaults to false
appium:newCommandTimeout - number How long (in seconds) Appium will wait for a new command from the client before assuming the client quit and ending the session
appium:settings[<key>] - any Update driver settings on session creation
appiun:shouldTerminateApp - boolean If true, the channel will be closed after the session is finished. Defaults to false

Settings

Name Type Description
elementResponseAttributes string Comma-separated list of element attribute names that will be available in page source and related actions

Supported Commands

The supported commands are listed in the sections below but note that they may have a different name in the client you are using

Example: calling the setContext command

// Java
driver.context('ECP');

// WebdriverIO
driver.switchContext('ECP');

WebDriver Commands

Command Description
createSession Create a new session
deleteSession End the running session
setUrl Open a deep link
active Get the currently focused element
findElement Search for an element
findElements Search for multiple elements
findElementFromElement Search for an element in parent element
findElementsFromElement Search multiple elements in parent element
getAttribute Get the value of an attribute from a given element
getProperty Get the value of an property from a given element
  • isFocused - returns true if the element is focused.
  • isInFocusChain - returns true if the element or any of its descendants are focused
  • isInFocusHierarchy - returns true if the element or any of its ancestors or descendants is focused
getText Get the visible text of a given element
getName Get the tag name of given element
getElementRect Get the position and size of the given element
elementDisplayed Check if the element is displayed
click Presses the Select button on given element
clear Clears the content of the given element
setValue Send a sequence of keystrokes to an element
getPageSource Get the XML representation of the current UI
execute Execute an roku command
performActions Performs a chain of actions
releaseActions Release depressed key
getScreenshot Take a screenshot

Appium Commands

Command Description
installApp Install the channel if it is not installed
activateApp Launch the given channel
terminateApp Terminate the channel (Available since Roku OS 13.0)
removeApp Remove the given channel from the device
isAppInstalled Checks if a channel is installed
queryAppState Queries the channel state
pushFile Push a file to the device
pullFile Pull a file from the device
pullFolder Pull a folder from the device
updateSettings Updates current test session settings
getCurrentContext Get the name of the current context
setContext Switches to the given context
getContexts Get the names of available contexts

BiDi Commands

Command Description
bidiSubscribe Enables certain events either globally or for a set of contexts
bidiUnsubscribe Disables events either globally or for a set of contexts

Roku Commands

In addition to the standard apium commands, Roku has several additional features that go beyond the appium protocol, so they are available through a javascript executor and a script in the following format <component>:<command>

The following components are available: ecp, debugServer, developerServer, and odc

Example:

// with args
driver.execute('ecp:launch', [{ appId: 'dev', params: {} }]);

// without args
const playerState = driver.execute('ecp:queryMediaPlayer');
playerState.duration;