diff --git a/src/RokuDeploy.spec.ts b/src/RokuDeploy.spec.ts index 02ef5de..9f51329 100644 --- a/src/RokuDeploy.spec.ts +++ b/src/RokuDeploy.spec.ts @@ -3215,11 +3215,6 @@ describe('index', () => { expect(rokuDeploy.getOptions().outFile).to.equal('rokudeploy-outfile'); }); - it('if bsconfig.json config file is available it should use those values instead of the default', () => { - fsExtra.writeJsonSync(`${rootDir}/bsconfig.json`, { outFile: 'bsconfig-outfile' }); - expect(rokuDeploy.getOptions().outFile).to.equal('bsconfig-outfile'); - }); - it('if rokudeploy.json config file is available and bsconfig.json is also available it should use rokudeploy.json instead of bsconfig.json', () => { fsExtra.outputJsonSync(`${rootDir}/bsconfig.json`, { outFile: 'bsconfig-outfile' }); fsExtra.outputJsonSync(`${rootDir}/rokudeploy.json`, { outFile: 'rokudeploy-outfile' }); @@ -3227,23 +3222,11 @@ describe('index', () => { }); it('if runtime options are provided, they should override any existing config file options', () => { - fsExtra.writeJsonSync(`${rootDir}/bsconfig.json`, { outFile: 'bsconfig-outfile' }); fsExtra.writeJsonSync(`${rootDir}/rokudeploy.json`, { outFile: 'rokudeploy-outfile' }); expect(rokuDeploy.getOptions({ outFile: 'runtime-outfile' }).outFile).to.equal('runtime-outfile'); }); - - it('if runtime config should override any existing config file options', () => { - fsExtra.writeJsonSync(s`${rootDir}/rokudeploy.json`, { outFile: 'rokudeploy-outfile' }); - fsExtra.writeJsonSync(s`${rootDir}/bsconfig`, { outFile: 'rokudeploy-outfile' }); - - fsExtra.writeJsonSync(s`${rootDir}/brsconfig.json`, { outFile: 'project-config-outfile' }); - options = { - project: 'brsconfig.json' - }; - expect(rokuDeploy.getOptions(options).outFile).to.equal('project-config-outfile'); - }); }); }); diff --git a/src/RokuDeploy.ts b/src/RokuDeploy.ts index a6c81f7..91d02a9 100644 --- a/src/RokuDeploy.ts +++ b/src/RokuDeploy.ts @@ -183,33 +183,35 @@ export class RokuDeploy { return baseRequestOptions; } - public async keypress(options: { key: string }) { + public async keyPress(options: KeyPressOptions) { return this.sendKeyEvent({ ...options, + key: 'all.the.others', action: 'keypress' }); } - public async keyup(options: any) { + public async keyUp(options: KeyUpOptions) { return this.sendKeyEvent({ ...options, action: 'keyup' }); } - public async keydown(options: any) { + public async keyDown(options: KeyDownOptions) { return this.sendKeyEvent({ ...options, action: 'keydown' }); } - public async sendText(options: any) { + public async sendText(options: SendTextOptions) { const chars = options.text.split(''); for (const char of chars) { - await this.keypress({ + await this.sendKeyEvent({ ...options, - key: `lit_${char}` + key: `lit_${char}`, + action: 'keypress' }); } } @@ -217,18 +219,13 @@ export class RokuDeploy { /** * Simulate pressing the home button on the remote for this roku. * This makes the roku return to the home screen - * @param host - the host - * @param port - the port that should be used for the request. defaults to 8060 - * @param timeout - request timeout duration in milliseconds. defaults to 150000 */ - private async sendKeyEvent(options: { host: string; port?: string; key: 'home' | 'left' | 'all.the.others'; action: 'keypress' | 'keyup' | 'keydown'; timeout?: number }) { - let options = this.getOptions(); - port = port ? port : options.remotePort; - timeout = timeout ? timeout : options.timeout; + private async sendKeyEvent(options: SendKeyEventOptions) { + let filledOptions = this.getOptions(options); // press the home button to return to the main screen return this.doPostRequest({ - url: `http://${host}:${port}/keypress/Home`, - timeout: timeout + url: `http://${filledOptions.host}:${filledOptions.remotePort}/${filledOptions.action}/${filledOptions.key}`, + timeout: filledOptions.timeout }, false); } @@ -964,6 +961,41 @@ export interface GetDeviceInfoOptions { enhance?: boolean; } +type RokuKey = 'home' | 'rev' | 'fwd' | 'play' | 'select' | 'left' | 'right' | 'down' | 'up' | 'back' | 'instantreplay' | 'info' | 'backspace' | 'search' | 'enter' | 'findremote' | 'volumeup' | 'volumedown' | 'volumemute' | 'poweroff' | 'channelup' | 'channeldown' | 'inputtuner' | 'inputhdmi1' | 'inputhdmi2' | 'inputhdmi3' | 'inputhdmi4' | 'inputav1'; +export interface SendKeyEventOptions { + action?: 'keypress' | 'keydown' | 'keyup'; + host: string; + key: RokuKey | string; + remotePort?: number; + timeout?: number; +} + +export interface KeyUpOptions extends SendKeyEventOptions { + action?: 'keyup'; + key: RokuKey; +} + +export interface KeyDownOptions extends SendKeyEventOptions { + action?: 'keydown'; + key: RokuKey; +} + +export interface KeyPressOptions extends SendKeyEventOptions { + action?: 'keypress'; + key: RokuKey; +} + +export interface SendTextOptions extends SendKeyEventOptions { + action?: 'keypress'; + text: string; +} + +export interface CloseChannelOptions { + host: string; + remotePort: number; + timeout?: number; + +} export interface StageOptions { rootDir?: string; files?: FileEntry[]; diff --git a/src/cli.ts b/src/cli.ts index 8f4c249..f3c3ead 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,8 +1,7 @@ #!/usr/bin/env node import * as yargs from 'yargs'; -import { rokuDeploy } from './index'; import { ExecCommand } from './commands/ExecCommand'; -import { TextCommand } from './commands/TextCommand'; +import { SendTextCommand } from './commands/SendTextCommand'; import { PrepublishCommand } from './commands/PrepublishCommand'; import { ZipPackageCommand } from './commands/ZipPackageCommand'; import { PublishCommand } from './commands/PublishCommand'; @@ -16,6 +15,10 @@ import { GetOutputPkgFilePathCommand } from './commands/GetOutputPkgFilePathComm import { GetDeviceInfoCommand } from './commands/GetDeviceInfoCommand'; import { GetDevIdCommand } from './commands/GetDevIdCommand'; import { ZipCommand } from './commands/ZipCommand'; +import { KeyPressCommand } from './commands/KeyPressCommand'; +import { KeyUpCommand } from './commands/KeyUpCommand'; +import { KeyDownCommand } from './commands/KeyDownCommand'; +import type { RokuDeploy } from './RokuDeploy'; void yargs @@ -57,32 +60,44 @@ void yargs return new ExecCommand(args.actions, args.configPath).run(); }) - .command(['sendText', 'text'], 'Send text command', (builder) => { + .command('keypress', 'send keypress command', (builder) => { return builder - .option('text', { type: 'string', description: 'The text to send', demandOption: true }); + .option('key', { type: 'string', description: 'The key to send', demandOption: true }) + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('remoteport', { type: 'number', description: 'The port to use for remote', demandOption: false }) + .option('timeout', { type: 'number', description: 'The timeout for the command', demandOption: false }); }, (args: any) => { - return new TextCommand().run(args); //TODO: do this through exec command to get default args like host and port? or add those to here and go through separate command for better testing + return new KeyPressCommand().run(args); }) - .command('keypress', 'send keypress command', (builder) => { + .command('keyup', 'send keyup command', (builder) => { return builder - .option('key', { type: 'string', description: 'The key to send', demandOption: true }); - }, async (args: any) => { - await rokuDeploy.keyPress(args.text); //TODO: Go through exec command, separate command, or use key event? + .option('key', { type: 'string', description: 'The key to send', demandOption: true }) + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('remoteport', { type: 'number', description: 'The port to use for remote', demandOption: false }) + .option('timeout', { type: 'number', description: 'The timeout for the command', demandOption: false }); + }, (args: any) => { + return new KeyUpCommand().run(args); }) - .command('keyup', 'send keyup command', (builder) => { + .command('keydown', 'send keydown command', (builder) => { return builder - .option('key', { type: 'string', description: 'The key to send', demandOption: true }); - }, async (args: any) => { - await rokuDeploy.keyUp(args.text); //TODO: Go through exec command, separate command, or use key event? + .option('key', { type: 'string', description: 'The key to send', demandOption: true }) + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('remoteport', { type: 'number', description: 'The port to use for remote', demandOption: false }) + .option('timeout', { type: 'number', description: 'The timeout for the command', demandOption: false }); + }, (args: any) => { + return new KeyDownCommand().run(args); }) - .command('keydown', 'send keydown command', (builder) => { + .command(['sendText', 'text'], 'Send text command', (builder) => { return builder - .option('key', { type: 'string', description: 'The key to send', demandOption: true }); - }, async (args: any) => { - await rokuDeploy.keyDown(args.text); //TODO: Go through exec command, separate command, or use key event? + .option('text', { type: 'string', description: 'The text to send', demandOption: true }) + .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) + .option('remoteport', { type: 'number', description: 'The port to use for remote', demandOption: false }) + .option('timeout', { type: 'number', description: 'The timeout for the command', demandOption: false }); + }, (args: any) => { + return new SendTextCommand().run(args); //TODO: Add default options }) .command(['stage', 'prepublishToStaging'], 'Copies all of the referenced files to the staging folder', (builder) => { @@ -141,21 +156,12 @@ void yargs return new CreateSignedPackageCommand().run(args); }) - .command('deploy', 'Deploy a pre-existing packaged zip file to a remote Roku', (builder) => { - return builder - .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) - .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }) - .option('rootDir', { type: 'string', description: 'The root directory', demandOption: false }); - }, (args: any) => { - return new DeployCommand().run(args); - }) - .command(['deleteDevChannel', 'deleteInstalledChannel', 'rmdev', 'delete'], 'Delete an installed channel', (builder) => { return builder .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }); }, (args: any) => { - return new DeleteInstalledChannelCommand().run(args); + return new DeleteDevChannelCommand().run(args); }) .command(['screenshot', 'captureScreenshot'], 'Take a screenshot', (builder) => { @@ -163,7 +169,7 @@ void yargs .option('host', { type: 'string', description: 'The IP Address of the host Roku', demandOption: false }) .option('password', { type: 'string', description: 'The password of the host Roku', demandOption: false }); }, (args: any) => { - return new TakeScreenshotCommand().run(args);//TODO: rename + return new TakeScreenshotCommand().run(args); }) .command('getOutputZipFilePath', 'Centralizes getting output zip file path based on passed in options', (builder) => {