npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@roku-sdk/device-test-client

v2.19.1

Published

Roku SDK on-device integration test client (RkClient, DOM/screenshot/log assertions, Jest wiring).

Readme

@roku-sdk/device-test-client

Single entry-point SDK for writing integration tests that drive real Roku devices from a Jest suite running on your host. The package bundles:

  • a queued, rate-limited ECP client (RkClient) that talks to the device,
  • build + sideload + launch primitives with readiness and health checks,
  • DOM, screenshot, and log assertion pillars with baseline workflows,
  • precondition-aware it/describe wrappers that skip on firmware / model / resolution mismatches,
  • first-class Jest wiring (globalSetup, globalTeardown, installDeviceTestHooks, a custom test environment) that captures rich per-failure diagnostic bundles out of the box.

Everything is a named export of the package root — there is no deep-path import surface to remember.

import {
    createDefaultClient,
    installDeviceTestHooks,
    itOnDevice,
    expectTree,
    expectScreenshot,
    findNode
} from "@roku-sdk/device-test-client";

Install

pnpm add -D @roku-sdk/device-test-client
# or
npm install -D @roku-sdk/device-test-client

Requires Node 24+ (for global fetch), Jest 29+, and the [rk](../tooling) CLI/daemon checked in alongside this package. Log assertions need rk server running on the host.

60-second quick start

import {
    createDefaultClient,
    installDeviceTestHooks
} from "@roku-sdk/device-test-client";

const client = createDefaultClient();
installDeviceTestHooks({ client });

test("app launches and shows the home scene", async () => {
    await client.buildAndDeploy("apps/buttons", {
        readyNode: { attr: { id: "home-title", text: "Welcome" } }
    });
    await client.keypress("Select");
    await client.waitForNode(
        { focused: true, attr: { id: "first-button" } },
        { timeout: 3_000 }
    );
});

For a full Jest skeleton (config + setup files) jump to [docs/getting-started.md](docs/getting-started.md).

Documentation

The docs/ folder is the manual. Each page opens with a short summary so you can skim the table of contents; every documented symbol ships with its TypeScript signature and a runnable example.

| Topic | What's inside | | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- | | Getting started | Prerequisites, install, first test, Jest config skeleton | | [RkClient reference](docs/rkclient.md) | Every method, every option type, rate limits, retries | | DOM assertions | findNode, expectFocused, waitForNode, tree baselines | | Screenshot assertions | captureStableScreenshot, expectScreenshot, masks, thresholds, alignment tolerance | | Log assertions | logPosition, waitForLog, expectNoLog, gap handling | | Preconditions | itOnDevice / describeOnDevice / requirePrecondition, device-class tiering | | Jest integration | globalSetup / globalTeardown, installDeviceTestHooks, custom test environment, failure bundles | | Baselines | hd/ + fhd/ routing, UPDATE_BASELINES=1 workflow, CI guard | | Configuration | Env vars, tunable constants, test-results/ artifact layout | | Error reference | Every exported error class with fields and recovery advice |

Worked examples that cross feature boundaries live under [docs/examples/](docs/examples/):

  • [smoke-test](docs/examples/smoke-test.md) — shortest possible deploy + one assertion
  • [deep-link-cold-start](docs/examples/deep-link-cold-start.md) — reliable cold-sideload deep-link delivery
  • [focus-navigation](docs/examples/focus-navigation.md) — keysequence + focus-change polling
  • [screenshot-regression](docs/examples/screenshot-regression.md) — stable capture + masked expectScreenshot
  • [log-driven-assertion](docs/examples/log-driven-assertion.md) — logPosition → keypress → waitForLog
  • [precondition-skips](docs/examples/precondition-skips.md) — skipping by firmware / model / resolution

Feature matrix

  • ECP queries — queryAppUi, queryDeviceInfo (+ cache), queryActiveApp, captureScreenshot
  • Input — keypress, keysequence with validated key names and an enforced inter-key delay
  • Lifecycle — launch, buildAndDeploy, buildAndLaunchWithParams (cold sideload + reliable deep-link delivery)
  • Readiness & health — semantic readiness gate via readyNode, system dialog detection, per-worker health flag with fail-fast beforeEach
  • Polling — waitForNode, captureStableScreenshot with crash-probe on every iteration
  • DOM assertions — findNode / findAllNodes / findFocusedNode / expectFocused, plus baseline comparison via expectTree(...).toMatchBaseline(...)
  • Screenshot assertions — expectScreenshot(...).toMatchBaseline(...) with pixelmatch, mask regions, decoupled aggregate + per-pixel thresholds, and opt-in alignment tolerance for firmware-drawn surfaces that re-center between devices
  • Log assertions — logPosition, waitForLog, expectNoLog, bulk logs, gap-aware semantics
  • Preconditions — firmware semver ranges, videoMode prefix, exact modelFamily / locale / country, derived device-class tiering
  • Failure diagnostics — per-failure bundles under test-results/failures/<sanitized>/ (screenshot, DOM tree, recent logs, error) and a streaming test-results/device.log

Compatibility

  • Runtime: Node 24+ (global fetch).
  • Test runner: Jest 29 or 30 (the custom environment require()s jest-environment-node at runtime so either works).
  • Roku firmware: any firmware that serves the standard ECP surface (/query/app-ui, /query/device-info, /query/active-app, /launch/…, /keypress/…, /capture-screen/png).
  • Videomodes: 720p, 720p60, 1080p, 1080p60. See [SUPPORTED_VIDEO_MODES](docs/baselines.md#supported-video-modes).

Versioning

The package follows semver. The public surface is everything exported by @roku-sdk/device-test-client (see [src/index.ts](src/index.ts)) — no other import paths are supported. Renames of public symbols are major bumps; additions are minor.

License

See the repository root.