cli-inspector
A library to help test CLI. Originally intended to test inquirer.js driven CLIs.
- Should work for other CLI applications, but YMMV.
- Developed on OSX, tested on *nix, windows.
- Pull requests, DX enhancements welcomed.
Installation
npm install cli-inspector
Usage
; inspector.run cmd_line, // command-line to spawn child process interactions, // array of Interactions (see below) options // extends child_process.spawnOptions ;
Action
The gif below shows a build of cli-inspector, including tests, which use cli-inspector to test an example inquirer.js pizza-ordering application.
API documentation
inspector.run()
cli-inspector
exposes a single method - run(). The idea is to provide it an
array of in-sequence CLI interaction.
An example interactions array: src/test/fixtures/inquirer/interactions.js.
/** * run an cli-test. * 1. spawn a child process with the cmd_line specified. * 2. Provide an array of individual interactions. See [tests](test/fixtures/inquirer/interactions.ts) * for a working example. `npm run build` to see it in action. * interactions.forEach( (interaction) => { * - wait for the prompt on interaction.stdout (string/regexp) * - pipe interaction.input to stdin * - wait for interaction.stdout/interaction.stderr if specified. * rinse and repeat * 3. Options provide control over the inspector and the child_process. * The most important control provided by `cli-inspector` are * - `delta`, the polling interval. Defaults to 1000 * - `timeout`, the time to wait in ms till * @export * @param * @param * @param */ ;
Interaction(s)
Options
Usage notes
CLIs have control sequences that make exact matching very cumbersome to create and maintain. It's much more convenient to use RegExps with wildcards and keywords.
This works well, but a few cautions:
- Prefer
[\s\S]*
to.*
with regular expressions that match multi-line strings with terminal control characters. - Escape all regexp special characters. There are a surprising number of them in regular CLIs. The set you should watch for:
^?[]()-{}!,*.
- Currently, the spawned process inserts a
\n
at column 80. The spawn operation however does not expose the underying TTY or control over it. Until we find a way around, the simplest thing is to add the[\n]?
as an optional character in the match sequence. - The interactions array is a command-response sequence. Creating it can get very complicated quickly. To help,
cli-inspector
adds adetails
object to erros thrown. Specifically,details.transcript
, which records a step-by-step pattern match, making it easier to see what is actually being seen. A sample is shown below:
// Using err.details to get inspector state and debugging insight.try catch err
Develop
git clone https://github.com/tufan-io/cli-inspector
cd cli-inspector
npm i
npm run build
How does it work?
- Spawns a child process with the supplied command line, under control of the cli-inspector.
- Pipes stdin, stdout and stderr appropriately.
+---------------+
| cli-inspector | +---------------+
| | stdin | child process |
| +----------------------> |
| | stdout | |
| <----------------------+ |
| | stderr | |
| <----------------------+ |
+---------------+ +---------------+
- Iterates over the supplied interactions, await interaction.prompt (on stdout) send interaction.userInput (on stdin) await interaction.response (on stdout) or interaction.error (on stderr)
- kills child-process on completion.
There are multiple debug controls provided, please look at the code or ask questions!
License
Apache 2.0
Support
Bugs, PRs, comments, suggestions welcomed!