Skip to content

danecodes/roku-cert

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@danecodes/roku-cert

Roku certification preflight checker. Runs automatable certification checks against a Roku device and produces a report before you submit to Roku.

Install

npm install @danecodes/roku-cert

Quick Start

# Full certification preflight
roku-cert run --device 192.168.0.30 --channel dev

# Single check
roku-cert check app_launch_time --device 192.168.0.30

# List all checks
roku-cert checks

CLI

# Run all checks
roku-cert run

# Run with options
roku-cert run --device 192.168.0.30 --channel dev

# Run a specific category
roku-cert run --category launch
roku-cert run --category navigation
roku-cert run --category playback
roku-cert run --category stability

# Run a single check
roku-cert check app_launch_time
roku-cert check trick_play

# Skip checks (non-video apps can skip playback)
roku-cert run --skip playback_initiation,trick_play,playback_error_handling

# With deep link config
roku-cert run --deeplinks ./deeplinks.json

# Output formats
roku-cert run --format text        # default, colorful terminal output
roku-cert run --format json
roku-cert run --format junit       # for CI integration
roku-cert run --format markdown    # for PRs / docs

# Save report to file
roku-cert run --output report.json --format json
roku-cert run --output report.xml --format junit

# Quick single-purpose commands
roku-cert launch-time              # just test launch time
roku-cert cpu                      # just sample CPU for 30s
roku-cert stability                # rapid input + console check

Environment Variables

  • ROKU_DEVICE_IP — device IP (alternative to --device)
  • ROKU_DEV_PASSWORD — dev password for sideloaded channels

Library API

import { CertRunner } from '@danecodes/roku-cert';

const runner = new CertRunner('192.168.0.30', {
  channelId: 'dev',
  deepLinks: './deeplinks.json',
  launchTimeout: 15000,
  playbackTimeout: 8000,
  cpuThreshold: 80,
  skip: ['playback_initiation', 'trick_play'],
});

// Run all checks
const report = await runner.runAll();

// Run a specific category
const report = await runner.runCategory('launch');

// Run a single check
const result = await runner.runCheck('app_launch_time');

// List available checks
const checks = runner.listChecks();

// Format report
console.log(runner.formatReport(report));  // terminal text
const json = runner.toJSON(report);         // JSON string
const junit = runner.toJUnit(report);       // JUnit XML
const md = runner.toMarkdown(report);       // Markdown

Checks

Launch & Performance

ID Check What it does
app_launch_time App launch time Cold start, measures time to UI render. Must be <15s.
relaunch_stability Relaunch stability Close and relaunch 3 times. No crashes or console errors.
cpu_usage CPU usage Samples CPU for 30s during idle. Must stay below threshold.
memory_baseline Memory baseline Records memAnon/memFile during idle. Warns if high.

Navigation & Focus

ID Check What it does
back_button Back button Navigate forward 3 screens, back 3 times. Must not crash.
home_exit Home exit Press Home from various screens. Must exit cleanly.
focus_visible Focus visible After each nav action, focus must never disappear.
deep_link_cold Deep link cold Deep link with app not running. Delegates to roku-deeplink.
deep_link_warm Deep link warm Deep link with app running. Delegates to roku-deeplink.

Playback

ID Check What it does
playback_initiation Playback initiation Verify playback starts within timeout via media player.
trick_play Trick play Pause, resume, rewind, fast forward. Verify state changes.
playback_error_handling Error handling Invalid content ID must show error screen, not crash.

Stability

ID Check What it does
console_idle No errors idle Launch, wait 10s, check console for BrightScript errors.
console_navigation No errors nav Navigate 5 screens, check console after each.
rapid_input Rapid input Send 20 keys at 100ms intervals. Must not crash.

Accessibility

ID Check What it does
text_readability Text readability Verify key screens have text elements, not just images.

Report Output

The text formatter produces a terminal report:

╔══════════════════════════════════════════════╗
║  Roku Certification Preflight Report         ║
╠══════════════════════════════════════════════╣
║ Device: Roku Ultra (4800X) — OS 14.0.2       ║
║ Channel: dev                                 ║
║ Date: 2026-04-15                             ║
╚══════════════════════════════════════════════╝

Launch & Performance
────────────────────
✓ App launch time              2.3s (< 15s)
✓ Relaunch stability           3/3 clean
✓ CPU usage                    avg 34% (< 80%)
⚠ Memory baseline              85MB (high but noted)

═══════════════════════════════════════════════
14/15 PASSED | 1 FAILED | 0 SKIPPED
Total time: 2m 14s
═══════════════════════════════════════════════

Exit codes: 0 = all passed, 1 = failures present.

Deep Link Config

Deep link checks use a config file compatible with @danecodes/roku-deeplink:

{
  "channelId": "dev",
  "tests": [
    {
      "name": "Movie playback",
      "contentId": "MOVIE_001",
      "mediaType": "movie",
      "expect": { "playback": true, "noErrors": true }
    }
  ]
}

Non-Video Apps

Skip playback checks for channels without playable content:

roku-cert run --skip playback_initiation,trick_play,playback_error_handling

Or programmatically:

const runner = new CertRunner('192.168.0.30', {
  channelId: 'dev',
  skip: ['playback_initiation', 'trick_play', 'playback_error_handling'],
});

License

MIT

Contributors