Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Test command line on Node.js.
$ npm i coffee --save-dev
Coffee is useful for test command line in test frammework (like Mocha).
You can use fork
for spawning Node processes.
const coffee = require('coffee');
describe('cli', () => {
it('should fork node cli', () => {
return coffee.fork('/path/to/file.js')
.expect('stdout', '12\n')
.expect('stderr', /34/)
.expect('code', 0)
.end();
});
});
In file.js
console.log(12);
console.error(34);
You can pass args
and opts
to child_process fork.
coffee.fork('/path/to/file.js', [ 'args' ], { execArgv: [ '--inspect' ]})
.expect('stdout', '12\n')
.expect('stderr', '34\n')
.expect('code', 0)
.end();
And more:
coffee.fork('/path/to/file.js')
// print origin stdio
.debug()
// inject a script
.beforeScript(mockScript)
// interact with prompt
.waitForPrompt()
.write('tz\n')
// string strict equals
.expect('stdout', 'abcdefg')
// regex
.expect('stdout', /^abc/)
// multiple
.expect('stdout', [ 'abcdefg', /abc/ ])
.expect('code', 0)
.end();
see the API chapter below for more details.
You can also use spawn
for spawning normal shell scripts.
coffee.spawn('cat')
.write('1')
.write('2')
.expect('stdout', '12')
.expect('code', 0)
.end();
Check the exit code.
coffee.fork('/path/to/file.js', [ 'args' ])
.expect('code', 0)
// .expect('code', 1)
.end();
Check the stdout and stderr.
coffee.fork('/path/to/file.js', [ 'args' ])
.expect('stdout', '12\n')
.expect('stderr', '34\n')
.expect('code', 0)
.end();
Support custom rules, see test/fixtures/extendable
for more details.
const { Coffee, Rule } = require('coffee');
class FileRule extends Rule {
constructor(opts) {
super(opts);
// `args` is which pass to `expect(type, ...args)`, `expected` is the first args.
const { args, expected } = opts;
}
assert(actual, expected, message) {
// do sth
return super.assert(fs.existsSync(expected), true, `should exists file ${expected}`);
}
}
class MyCoffee extends Coffee {
constructor(...args) {
super(...args);
this.setRule('file', FileRule);
}
static fork(modulePath, args, opt) {
return new MyCoffee({
method: 'fork',
cmd: modulePath,
args,
opt,
});
}
}
Usage:
// test/custom.test.js
const coffee = require('MyCoffee');
coffee.fork('/path/to/file.js', [ 'args' ])
.expect('file', `${root}/README.md`);
.notExpect('file', `${root}/not-exist`);
Recommend to use nyc for coverage, you can use any test frammework supported by nyc.
Run command using child_process.spawn
, then return Coffee
instance.
Arguments see child_process.spawn
Run command using child_process.fork
, then return Coffee
instance.
Arguments see child_process.fork
Assertion object
Assert type with expected value, expected value can be string, regular expression, and array.
coffee.spawn('echo', [ 'abcdefg' ])
.expect('stdout', 'abcdefg')
.expect('stdout', /^abc/)
.expect('stdout', [ 'abcdefg', /abc/ ])
.end();
Accept type: stdout
/ stderr
/ code
/ error
, see built-in rules description above.
The opposite assertion of expect
.
Assert type with expected string value, expected value should be string only.
coffee.spawn('echo', [ 'abcdefg' ])
.includes('stdout', 'abc')
.expect('stdout', [ 'abc', 'efg' ])
.end();
Accept type: stdout
/ stderr
, see built-in rules description above.
The opposite assertion of includes
.
Write data to stdin.
coffee.fork(path.join(fixtures, 'stdin.js'))
.write('1\n')
.write('2')
.expect('stdout', '1\n2')
.end();
Write special key sequence to stdin, support UP
/ DOWN
/ LEFT
/ RIGHT
/ ENTER
/ SPACE
.
All args will join as one key.
coffee.fork(path.join(fixtures, 'stdin.js'))
.writeKey('1', 'ENTER', '2')
.expect('stdout', '1\n2')
.end();
If you set false, coffee will write stdin immediately, otherwise will wait for prompt
message.
coffee.fork('/path/to/cli', [ 'abcdefg' ])
.waitForPrompt()
.write('tz\n')
// choose the second item
.writeKey('DOWN', 'DOWN', 'ENTER');
.end(done);
cli process should emit prompt
message:
Or use
coffee.on('stdout', callback)
instead, see docs below.
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
function ask(q, callback) {
process.send({ type: 'prompt' });
rl.question(q, callback);
}
ask('What\'s your name? ', answer => {
console.log(`hi, ${answer}`);
ask('How many coffee do you want? ', answer => {
console.log(`here is your ${answer} coffee`);
rl.close();
});
});
Callback will be called after completing the assertion, the first argument is Error if throw exception.
coffee.fork('path/to/cli')
.expect('stdout', 'abcdefg')
.end(done);
// recommended to left undefind and use promise style.
const { stdout, stderr, code } = await coffee.fork('path/to/cli').end();
assert(stdout.includes(abcdefg));
Emit stdout/stderr
event.
use for kill long-run process:
coffee.fork('path/to/cli')
.on('stdout', (buf, { proc }) => {
if (buf.includes('egg-ready')) {
proc.exitCode = 0;
proc.kill();
}
})
.expect('stdout', 'egg-ready')
.end(done);
use for prompt:
// do not call `waitForPrompt` / `write` / `writeKey`
coffee.fork('path/to/cli')
.on('stdout', (buf, { proc }) => {
if (buf.includes('Your Name: ')) {
proc.stdin.write('TZ\n');
}
})
.expect('stdout', 'Your Name: TZ\n')
.end(done);
Write data to process.stdout and process.stderr for debug
level
can be
Alternative you can use COFFEE_DEBUG
env.
If you set false, coffee will not generate coverage.json, default: true.
Add a hook script before fork child process run.
Assertion Rule base class.
Copyright (c) 2017 - 2019 node-modules. Licensed under the MIT license.
FAQs
Test command line on Node.js.
The npm package coffee receives a total of 17,439 weekly downloads. As such, coffee popularity was classified as popular.
We found that coffee demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.