@putdotio/rokit 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -106,6 +106,7 @@ App-specific scenario scripts can import the generic helpers:
106
106
  import {
107
107
  assertMediaPlayerContainer,
108
108
  assertSceneGraphNode,
109
+ captureScreenshot,
109
110
  pressKey,
110
111
  querySceneGraph,
111
112
  waitForSceneGraphAssertion,
@@ -124,9 +125,14 @@ const context: RokuContext = {
124
125
  };
125
126
 
126
127
  await pressKey(context, "Info");
127
- await querySceneGraph(context, { attempts: 3, requireComplete: true });
128
+ await querySceneGraph(context, { attempts: 3, requireAppNode: true, requireComplete: true });
128
129
  await assertSceneGraphNode(context, "videoPlayerScreen", { state: "visible" });
129
130
  await assertMediaPlayerContainer(context, "mp4");
131
+ await captureScreenshot(
132
+ { ...context, password: process.env.ROKIT_PASSWORD ?? "" },
133
+ "artifacts/player.jpg",
134
+ { attempts: 3 },
135
+ );
130
136
  await waitForSceneGraphAssertion(context, "player ready", (xml) => {
131
137
  if (!xml.includes("videoPlayerScreen")) {
132
138
  throw new Error("expected player screen");
@@ -4,6 +4,8 @@ import { existsSync } from "node:fs";
4
4
  import { basename, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
5
5
  import * as rokuDeploy from "roku-deploy";
6
6
  import { createSocket } from "node:dgram";
7
+ import { access, copyFile, mkdir, mkdtemp, rm } from "node:fs/promises";
8
+ import { tmpdir } from "node:os";
7
9
  //#region src/errors.ts
8
10
  var InvalidInput = class extends Schema.TaggedErrorClass()("InvalidInput", { message: Schema.String }) {};
9
11
  var MissingTarget = class extends Schema.TaggedErrorClass()("MissingTarget", {}) {
@@ -335,22 +337,31 @@ const waitForMediaPlayerState = async (context, expectedState, timeoutMs = 1e4)
335
337
  };
336
338
  const querySceneGraph = async (context, options = {}) => {
337
339
  const attempts = options.attempts ?? 1;
340
+ const requireAppNode = options.requireAppNode ?? false;
338
341
  const requireComplete = options.requireComplete ?? false;
339
342
  const retryDelayMs = options.retryDelayMs ?? 500;
340
343
  let lastXml = "";
341
344
  let lastError;
345
+ let lastMissingAppNode = false;
342
346
  for (let attempt = 0; attempt < attempts; attempt += 1) {
343
347
  try {
344
348
  const xml = await queryEcp(context, "/query/sgnodes/all");
345
- if (!requireComplete || isCompleteSceneGraph(xml)) return xml;
349
+ const complete = !requireComplete || isCompleteSceneGraph(xml);
350
+ const hasAppNode = !requireAppNode || !xml.includes("<All_Nodes>") || xml.includes("<App ");
351
+ if (complete && hasAppNode) return xml;
346
352
  lastXml = xml;
353
+ lastMissingAppNode = complete && !hasAppNode;
347
354
  } catch (error) {
348
355
  lastError = error;
349
356
  lastXml = "";
357
+ lastMissingAppNode = false;
350
358
  }
351
359
  if (attempt < attempts - 1) await sleep(retryDelayMs);
352
360
  }
353
- if (lastXml !== "") throw new Error("SceneGraph query returned incomplete XML");
361
+ if (lastXml !== "") {
362
+ if (lastMissingAppNode) throw new Error("SceneGraph query returned complete XML without an App node");
363
+ throw new Error("SceneGraph query returned incomplete XML");
364
+ }
354
365
  throw new Error(`SceneGraph query failed: ${formatErrorMessage$1(lastError)}`);
355
366
  };
356
367
  const assertSceneGraphNode = async (context, nodeName, expectation) => {
@@ -411,6 +422,41 @@ const takeScreenshot = async (context, outputPath) => {
411
422
  password: context.password
412
423
  });
413
424
  };
425
+ const captureScreenshot = async (context, outputPath, options = {}) => {
426
+ const attempts = options.attempts ?? 3;
427
+ const retryDelayMs = options.retryDelayMs ?? 1500;
428
+ const resolvedOutput = resolve(outputPath);
429
+ await mkdir(dirname(resolvedOutput), { recursive: true });
430
+ let lastError = "unknown";
431
+ for (let attempt = 1; attempt <= attempts; attempt += 1) {
432
+ const captureDir = await mkdtemp(join(tmpdir(), `${safeTempPrefix(options.tempDirPrefix ?? "rokit-screenshot")}-`));
433
+ const capturePath = join(captureDir, basename(resolvedOutput));
434
+ try {
435
+ const tempResult = await firstExistingPath([await takeScreenshot(context, capturePath), capturePath]);
436
+ if (tempResult !== void 0) {
437
+ await copyFile(tempResult, resolvedOutput);
438
+ return resolvedOutput;
439
+ }
440
+ const directResult = await firstExistingPath([resolvedOutput, await takeScreenshot(context, resolvedOutput)]);
441
+ if (directResult === resolvedOutput) return resolvedOutput;
442
+ if (directResult !== void 0) {
443
+ await copyFile(directResult, resolvedOutput);
444
+ return resolvedOutput;
445
+ }
446
+ throw new Error("screenshot capture succeeded without writing an image file");
447
+ } catch (error) {
448
+ lastError = formatErrorMessage$1(error);
449
+ if (attempt === attempts) break;
450
+ await sleep(retryDelayMs);
451
+ } finally {
452
+ await rm(captureDir, {
453
+ force: true,
454
+ recursive: true
455
+ });
456
+ }
457
+ }
458
+ throw new Error(`failed to capture ${basename(resolvedOutput)}: ${lastError}`);
459
+ };
414
460
  const packageChannel = async (outputPath, rootDir = process.cwd()) => {
415
461
  const options = packageOptions(outputPath, rootDir);
416
462
  await rokuDeploy.createPackage(options);
@@ -444,6 +490,18 @@ const rejectUnsafeInput$1 = (value, label) => {
444
490
  return code < 32 || code === 127;
445
491
  })) throw new Error(`${label} contains control characters`);
446
492
  };
493
+ const safeTempPrefix = (value) => value.replace(/[^a-zA-Z0-9_-]/g, "-");
494
+ const firstExistingPath = async (paths) => {
495
+ for (const path of paths) if (await fileExists(path)) return path;
496
+ };
497
+ const fileExists = async (path) => {
498
+ try {
499
+ await access(path);
500
+ return true;
501
+ } catch {
502
+ return false;
503
+ }
504
+ };
447
505
  const validateRemoteKey = (key) => {
448
506
  if (key.startsWith("Lit_")) return;
449
507
  if (!remoteKeySet.has(key)) throw new Error(`unsupported remote key: ${key}`);
@@ -747,4 +805,4 @@ const validateNonNegativeInteger = (value, label) => {
747
805
  if (!Number.isInteger(parsed) || parsed < 0) fail(`Invalid ${label}: ${value}`);
748
806
  };
749
807
  //#endregion
750
- export { readNamedNodeBounds as $, readMediaPlayerInfo as A, waitForSceneGraphNode as B, queryEcp as C, queryMediaPlayerXmlSafe as D, queryMediaPlayerXml as E, validateEcpPath as F, assertNamedNodeTranslation as G, assertNamedNodeSize as H, validateRemoteKey as I, isCompleteSceneGraph as J, assertSceneGraphNumberNear as K, waitForActiveApp as L, readMediaPlayerState as M, resolvePackageOutputPath as N, querySceneGraph as O, takeScreenshot as P, readNamedNodeAttributes as Q, waitForMediaPlayerState as R, queryActiveApp as S, queryMediaPlayerSafe as T, assertNamedNodeState as U, assertNamedNode as V, assertNamedNodeText as W, parseSceneGraphNumberList as X, isNamedNodeVisible as Y, readNamedNodeAttribute as Z, installPackage as _, loadEnv as a, readActiveApp as at, packageChannel as b, requirePassword as c, normalizeError as ct, resolveOutputPath as d, readNamedNodeNumber as et, assertMediaPlayerContainer as f, getDeviceInfo as g, discoverRokuDevices as h, fail as i, sceneGraphContainsText as it, readMediaPlayerPositionMs as j, readMediaPlayerContainer as k, requireTarget as l, renderError as lt, checkDevice as m, captureDebugConsole as n, readSceneGraphFailure as nt, loadLocalEnv as o, readXmlAttribute as ot, assertSceneGraphNode as p, escapeXmlAttribute as q, runDebugCommand as r, readSceneGraphStatus as rt, rejectUnsafeEcpPath as s, readXmlTag as st, buildDebugCommand as t, readNamedNodeTranslation as tt, resolveFileOutputPath as u, isActiveMediaPlayerState as v, queryMediaPlayer as w, pressKey as x, launchApp as y, waitForSceneGraphAssertion as z };
808
+ export { readNamedNodeAttributes as $, readMediaPlayerContainer as A, waitForSceneGraphAssertion as B, queryActiveApp as C, queryMediaPlayerXml as D, queryMediaPlayerSafe as E, takeScreenshot as F, assertNamedNodeText as G, assertNamedNode as H, validateEcpPath as I, escapeXmlAttribute as J, assertNamedNodeTranslation as K, validateRemoteKey as L, readMediaPlayerPositionMs as M, readMediaPlayerState as N, queryMediaPlayerXmlSafe as O, resolvePackageOutputPath as P, readNamedNodeAttribute as Q, waitForActiveApp as R, pressKey as S, queryMediaPlayer as T, assertNamedNodeSize as U, waitForSceneGraphNode as V, assertNamedNodeState as W, isNamedNodeVisible as X, isCompleteSceneGraph as Y, parseSceneGraphNumberList as Z, getDeviceInfo as _, loadEnv as a, sceneGraphContainsText as at, launchApp as b, requirePassword as c, readXmlTag as ct, resolveOutputPath as d, readNamedNodeBounds as et, assertMediaPlayerContainer as f, discoverRokuDevices as g, checkDevice as h, fail as i, readSceneGraphStatus as it, readMediaPlayerInfo as j, querySceneGraph as k, requireTarget as l, normalizeError as lt, captureScreenshot as m, captureDebugConsole as n, readNamedNodeTranslation as nt, loadLocalEnv as o, readActiveApp as ot, assertSceneGraphNode as p, assertSceneGraphNumberNear as q, runDebugCommand as r, readSceneGraphFailure as rt, rejectUnsafeEcpPath as s, readXmlAttribute as st, buildDebugCommand as t, readNamedNodeNumber as tt, resolveFileOutputPath as u, renderError as ut, installPackage as v, queryEcp as w, packageChannel as x, isActiveMediaPlayerState as y, waitForMediaPlayerState as z };
package/dist/index.d.mts CHANGED
@@ -88,6 +88,7 @@ type MediaPlayerInfo = {
88
88
  };
89
89
  type RetryOptions = {
90
90
  readonly attempts?: number;
91
+ readonly requireAppNode?: boolean;
91
92
  readonly requireComplete?: boolean;
92
93
  readonly retryDelayMs?: number;
93
94
  };
@@ -99,6 +100,11 @@ type WaitForSceneGraphAssertionOptions = {
99
100
  type PackageResult = {
100
101
  readonly path: string;
101
102
  };
103
+ type ScreenshotCaptureOptions = {
104
+ readonly attempts?: number;
105
+ readonly retryDelayMs?: number;
106
+ readonly tempDirPrefix?: string;
107
+ };
102
108
  declare const checkDevice: (context: RokuContext) => Promise<DeviceSummary>;
103
109
  declare const getDeviceInfo: (context: RokuContext) => Promise<rokuDeploy.DeviceInfo>;
104
110
  declare const queryActiveApp: (context: RokuContext) => Promise<ActiveApp>;
@@ -128,6 +134,9 @@ declare const installPackage: (context: RokuContext & {
128
134
  declare const takeScreenshot: (context: RokuContext & {
129
135
  readonly password: string;
130
136
  }, outputPath: string) => Promise<string>;
137
+ declare const captureScreenshot: (context: RokuContext & {
138
+ readonly password: string;
139
+ }, outputPath: string, options?: ScreenshotCaptureOptions) => Promise<string>;
131
140
  declare const packageChannel: (outputPath: string, rootDir?: string) => Promise<PackageResult>;
132
141
  declare const validateEcpPath: (path: string) => string;
133
142
  declare const validateRemoteKey: (key: string) => void;
@@ -159,4 +168,4 @@ declare const buildDebugCommand: (command: string, args: readonly string[]) => R
159
168
  declare const runDebugCommand: (context: RokuContext, command: RokuDebugCommand, durationMs: number, idleTimeoutMs: number) => Promise<DebugCommandResult>;
160
169
  declare const captureDebugConsole: (context: RokuContext, durationMs: number) => Promise<DebugConsoleCapture>;
161
170
  //#endregion
162
- export { type ActiveApp, type DebugCommandResult, type DebugConsoleCapture, type DeviceSummary, type DiscoveredRokuDevice, type MediaPlayerInfo, type MediaPlayerState, type NodeExpectation, type NodeState, type PackageResult, type RemoteKey, type RetryOptions, type RokuContext, type RokuDebugCommand, type RokuDebugPort, type SceneGraphAssertion, type SceneGraphBounds, type SceneGraphPoint, type SceneGraphStatus, type WaitForSceneGraphAssertionOptions, assertMediaPlayerContainer, assertNamedNode, assertNamedNodeSize, assertNamedNodeState, assertNamedNodeText, assertNamedNodeTranslation, assertSceneGraphNode, assertSceneGraphNumberNear, buildDebugCommand, captureDebugConsole, checkDevice, discoverRokuDevices, escapeXmlAttribute, getDeviceInfo, installPackage, isActiveMediaPlayerState, isCompleteSceneGraph, isNamedNodeVisible, launchApp, packageChannel, parseSceneGraphNumberList, pressKey, queryActiveApp, queryEcp, queryMediaPlayer, queryMediaPlayerSafe, queryMediaPlayerXml, queryMediaPlayerXmlSafe, querySceneGraph, readActiveApp, readMediaPlayerContainer, readMediaPlayerInfo, readMediaPlayerPositionMs, readMediaPlayerState, readNamedNodeAttribute, readNamedNodeAttributes, readNamedNodeBounds, readNamedNodeNumber, readNamedNodeTranslation, readSceneGraphFailure, readSceneGraphStatus, readXmlAttribute, readXmlTag, runDebugCommand, sceneGraphContainsText, takeScreenshot, validateEcpPath, validateRemoteKey, waitForActiveApp, waitForMediaPlayerState, waitForSceneGraphAssertion, waitForSceneGraphNode };
171
+ export { type ActiveApp, type DebugCommandResult, type DebugConsoleCapture, type DeviceSummary, type DiscoveredRokuDevice, type MediaPlayerInfo, type MediaPlayerState, type NodeExpectation, type NodeState, type PackageResult, type RemoteKey, type RetryOptions, type RokuContext, type RokuDebugCommand, type RokuDebugPort, type SceneGraphAssertion, type SceneGraphBounds, type SceneGraphPoint, type SceneGraphStatus, type ScreenshotCaptureOptions, type WaitForSceneGraphAssertionOptions, assertMediaPlayerContainer, assertNamedNode, assertNamedNodeSize, assertNamedNodeState, assertNamedNodeText, assertNamedNodeTranslation, assertSceneGraphNode, assertSceneGraphNumberNear, buildDebugCommand, captureDebugConsole, captureScreenshot, checkDevice, discoverRokuDevices, escapeXmlAttribute, getDeviceInfo, installPackage, isActiveMediaPlayerState, isCompleteSceneGraph, isNamedNodeVisible, launchApp, packageChannel, parseSceneGraphNumberList, pressKey, queryActiveApp, queryEcp, queryMediaPlayer, queryMediaPlayerSafe, queryMediaPlayerXml, queryMediaPlayerXmlSafe, querySceneGraph, readActiveApp, readMediaPlayerContainer, readMediaPlayerInfo, readMediaPlayerPositionMs, readMediaPlayerState, readNamedNodeAttribute, readNamedNodeAttributes, readNamedNodeBounds, readNamedNodeNumber, readNamedNodeTranslation, readSceneGraphFailure, readSceneGraphStatus, readXmlAttribute, readXmlTag, runDebugCommand, sceneGraphContainsText, takeScreenshot, validateEcpPath, validateRemoteKey, waitForActiveApp, waitForMediaPlayerState, waitForSceneGraphAssertion, waitForSceneGraphNode };
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { $ as readNamedNodeBounds, A as readMediaPlayerInfo, B as waitForSceneGraphNode, C as queryEcp, D as queryMediaPlayerXmlSafe, E as queryMediaPlayerXml, F as validateEcpPath, G as assertNamedNodeTranslation, H as assertNamedNodeSize, I as validateRemoteKey, J as isCompleteSceneGraph, K as assertSceneGraphNumberNear, L as waitForActiveApp, M as readMediaPlayerState, O as querySceneGraph, P as takeScreenshot, Q as readNamedNodeAttributes, R as waitForMediaPlayerState, S as queryActiveApp, T as queryMediaPlayerSafe, U as assertNamedNodeState, V as assertNamedNode, W as assertNamedNodeText, X as parseSceneGraphNumberList, Y as isNamedNodeVisible, Z as readNamedNodeAttribute, _ as installPackage, at as readActiveApp, b as packageChannel, et as readNamedNodeNumber, f as assertMediaPlayerContainer, g as getDeviceInfo, h as discoverRokuDevices, it as sceneGraphContainsText, j as readMediaPlayerPositionMs, k as readMediaPlayerContainer, m as checkDevice, n as captureDebugConsole, nt as readSceneGraphFailure, ot as readXmlAttribute, p as assertSceneGraphNode, q as escapeXmlAttribute, r as runDebugCommand, rt as readSceneGraphStatus, st as readXmlTag, t as buildDebugCommand, tt as readNamedNodeTranslation, v as isActiveMediaPlayerState, w as queryMediaPlayer, x as pressKey, y as launchApp, z as waitForSceneGraphAssertion } from "./debug-af6vvS9T.mjs";
2
- export { assertMediaPlayerContainer, assertNamedNode, assertNamedNodeSize, assertNamedNodeState, assertNamedNodeText, assertNamedNodeTranslation, assertSceneGraphNode, assertSceneGraphNumberNear, buildDebugCommand, captureDebugConsole, checkDevice, discoverRokuDevices, escapeXmlAttribute, getDeviceInfo, installPackage, isActiveMediaPlayerState, isCompleteSceneGraph, isNamedNodeVisible, launchApp, packageChannel, parseSceneGraphNumberList, pressKey, queryActiveApp, queryEcp, queryMediaPlayer, queryMediaPlayerSafe, queryMediaPlayerXml, queryMediaPlayerXmlSafe, querySceneGraph, readActiveApp, readMediaPlayerContainer, readMediaPlayerInfo, readMediaPlayerPositionMs, readMediaPlayerState, readNamedNodeAttribute, readNamedNodeAttributes, readNamedNodeBounds, readNamedNodeNumber, readNamedNodeTranslation, readSceneGraphFailure, readSceneGraphStatus, readXmlAttribute, readXmlTag, runDebugCommand, sceneGraphContainsText, takeScreenshot, validateEcpPath, validateRemoteKey, waitForActiveApp, waitForMediaPlayerState, waitForSceneGraphAssertion, waitForSceneGraphNode };
1
+ import { $ as readNamedNodeAttributes, A as readMediaPlayerContainer, B as waitForSceneGraphAssertion, C as queryActiveApp, D as queryMediaPlayerXml, E as queryMediaPlayerSafe, F as takeScreenshot, G as assertNamedNodeText, H as assertNamedNode, I as validateEcpPath, J as escapeXmlAttribute, K as assertNamedNodeTranslation, L as validateRemoteKey, M as readMediaPlayerPositionMs, N as readMediaPlayerState, O as queryMediaPlayerXmlSafe, Q as readNamedNodeAttribute, R as waitForActiveApp, S as pressKey, T as queryMediaPlayer, U as assertNamedNodeSize, V as waitForSceneGraphNode, W as assertNamedNodeState, X as isNamedNodeVisible, Y as isCompleteSceneGraph, Z as parseSceneGraphNumberList, _ as getDeviceInfo, at as sceneGraphContainsText, b as launchApp, ct as readXmlTag, et as readNamedNodeBounds, f as assertMediaPlayerContainer, g as discoverRokuDevices, h as checkDevice, it as readSceneGraphStatus, j as readMediaPlayerInfo, k as querySceneGraph, m as captureScreenshot, n as captureDebugConsole, nt as readNamedNodeTranslation, ot as readActiveApp, p as assertSceneGraphNode, q as assertSceneGraphNumberNear, r as runDebugCommand, rt as readSceneGraphFailure, st as readXmlAttribute, t as buildDebugCommand, tt as readNamedNodeNumber, v as installPackage, w as queryEcp, x as packageChannel, y as isActiveMediaPlayerState, z as waitForMediaPlayerState } from "./debug-BbJdwNkW.mjs";
2
+ export { assertMediaPlayerContainer, assertNamedNode, assertNamedNodeSize, assertNamedNodeState, assertNamedNodeText, assertNamedNodeTranslation, assertSceneGraphNode, assertSceneGraphNumberNear, buildDebugCommand, captureDebugConsole, captureScreenshot, checkDevice, discoverRokuDevices, escapeXmlAttribute, getDeviceInfo, installPackage, isActiveMediaPlayerState, isCompleteSceneGraph, isNamedNodeVisible, launchApp, packageChannel, parseSceneGraphNumberList, pressKey, queryActiveApp, queryEcp, queryMediaPlayer, queryMediaPlayerSafe, queryMediaPlayerXml, queryMediaPlayerXmlSafe, querySceneGraph, readActiveApp, readMediaPlayerContainer, readMediaPlayerInfo, readMediaPlayerPositionMs, readMediaPlayerState, readNamedNodeAttribute, readNamedNodeAttributes, readNamedNodeBounds, readNamedNodeNumber, readNamedNodeTranslation, readSceneGraphFailure, readSceneGraphStatus, readXmlAttribute, readXmlTag, runDebugCommand, sceneGraphContainsText, takeScreenshot, validateEcpPath, validateRemoteKey, waitForActiveApp, waitForMediaPlayerState, waitForSceneGraphAssertion, waitForSceneGraphNode };
package/dist/rokit.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { B as waitForSceneGraphNode, C as queryEcp, I as validateRemoteKey, L as waitForActiveApp, N as resolvePackageOutputPath, O as querySceneGraph, P as takeScreenshot, R as waitForMediaPlayerState, S as queryActiveApp, _ as installPackage, a as loadEnv, b as packageChannel, c as requirePassword, ct as normalizeError, d as resolveOutputPath, g as getDeviceInfo, h as discoverRokuDevices, i as fail, l as requireTarget, lt as renderError, m as checkDevice, n as captureDebugConsole, nt as readSceneGraphFailure, o as loadLocalEnv, p as assertSceneGraphNode, r as runDebugCommand, rt as readSceneGraphStatus, s as rejectUnsafeEcpPath, t as buildDebugCommand, u as resolveFileOutputPath, w as queryMediaPlayer, x as pressKey, y as launchApp } from "./debug-af6vvS9T.mjs";
2
+ import { C as queryActiveApp, L as validateRemoteKey, P as resolvePackageOutputPath, R as waitForActiveApp, S as pressKey, T as queryMediaPlayer, V as waitForSceneGraphNode, _ as getDeviceInfo, a as loadEnv, b as launchApp, c as requirePassword, d as resolveOutputPath, g as discoverRokuDevices, h as checkDevice, i as fail, it as readSceneGraphStatus, k as querySceneGraph, l as requireTarget, lt as normalizeError, m as captureScreenshot, n as captureDebugConsole, o as loadLocalEnv, p as assertSceneGraphNode, r as runDebugCommand, rt as readSceneGraphFailure, s as rejectUnsafeEcpPath, t as buildDebugCommand, u as resolveFileOutputPath, ut as renderError, v as installPackage, w as queryEcp, x as packageChannel, z as waitForMediaPlayerState } from "./debug-BbJdwNkW.mjs";
3
3
  import { createRequire } from "node:module";
4
4
  import { Effect } from "effect";
5
5
  import { mkdirSync, writeFileSync } from "node:fs";
@@ -255,8 +255,7 @@ const runCommand = async (context, command, dryRun) => {
255
255
  const path = timestampOutputPath(resolveFileOutputPath(command.outputPath, "screenshot output path"));
256
256
  if (dryRun) return dryRunResult(command.name, { path });
257
257
  const password = requirePassword(deviceContext);
258
- mkdirSync(dirname(path), { recursive: true });
259
- const screenshotPath = await takeScreenshot({
258
+ const screenshotPath = await captureScreenshot({
260
259
  ...deviceContext,
261
260
  password
262
261
  }, path);
@@ -405,7 +404,7 @@ const writeProof = async (context, outputDir, includeScreenshot) => {
405
404
  writeJson("media-player", await observe(async () => await queryMediaPlayer(context)));
406
405
  if (includeScreenshot) {
407
406
  const password = requirePassword(context);
408
- const path = await takeScreenshot({
407
+ const path = await captureScreenshot({
409
408
  ...context,
410
409
  password
411
410
  }, timestampOutputPath(`${outputDir}/screenshot.png`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@putdotio/rokit",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "A tiny CLI companion for Roku device harness work.",
5
5
  "keywords": [
6
6
  "cli",