Skip to content

Commit

Permalink
sending cli error message in send events and fixing stdin bug (#1485)
Browse files Browse the repository at this point in the history
* sending cli error message in send events and fixing stdin

* fixing tests

* addressing comments: refactoring code
  • Loading branch information
prklm10 authored Jan 4, 2024
1 parent 4f0f287 commit 7ee2fc5
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 7 deletions.
10 changes: 9 additions & 1 deletion packages/cli-exec/src/exec.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export const exec = command('exec', {
async function* spawn(cmd, args, percy) {
let { default: crossSpawn } = await import('cross-spawn');
let proc, closed, error;
let errorMessage = '';

try {
proc = crossSpawn(cmd, args, { stdio: 'pipe' });
Expand All @@ -109,9 +110,12 @@ async function* spawn(cmd, args, percy) {
process.stdout.write(`${data}`);
});
}
// Piping proc sdtin to process
process.stdin.pipe(proc.stdin);

if (proc.stderr) {
proc.stderr.on('data', (data) => {
errorMessage += data.toString();
process.stderr.write(`${data}`);
});
}
Expand All @@ -121,13 +125,17 @@ async function* spawn(cmd, args, percy) {
proc.on('close', code => {
closed = code;
if (code !== 0) {
// Only send cli error when PERCY_CLIENT_ERROR_LOGS is set to true
if (process.env.PERCY_CLIENT_ERROR_LOGS === 'false') {
errorMessage = 'Log sharing is disabled';
}
// Only send event when there is a global error code and
// percy token is present
if (process.env.PERCY_TOKEN) {
const myObject = {
errorKind: 'cli',
cliVersion: pkg.version,
message: '1'
message: errorMessage
};
percy.client.sendBuildEvents(percy.build.id, myObject);
}
Expand Down
67 changes: 61 additions & 6 deletions packages/cli-exec/test/exec.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ describe('percy exec', () => {
delete process.env.PERCY_BUILD_ID;
delete process.env.PERCY_PARALLEL_TOTAL;
delete process.env.PERCY_PARTIAL_BUILD;
delete process.env.PERCY_CLIENT_ERROR_LOGS;
});

describe('projectType is app', () => {
Expand Down Expand Up @@ -144,18 +145,45 @@ describe('percy exec', () => {
]);
});

it('tests process.stderr when token is present', async () => {
it('tests process.stderr when token is present and PERCY_CLIENT_ERROR_LOGS is not present', async () => {
delete process.env.PERCY_CLIENT_ERROR_LOGS;
const pkg = getPackageJSON(import.meta.url);
let stderrSpy = spyOn(process.stderr, 'write').and.resolveTo('some response');
let stderrSpy = spyOn(process.stderr, 'write').and.resolveTo(jasmine.stringMatching(/Some error/));
await expectAsync(
exec(['--', 'node', 'random.js']) // invalid command
exec(['--', 'node', './test/test-data/test_prog.js', 'error']) // Throws Error
).toBeRejectedWithError('EEXIT: 1');

expect(logger.stderr).toEqual([]);
expect(logger.stdout).toEqual([
'[percy] Percy has started!',
'[percy] Running "node ./test/test-data/test_prog.js error"',
'[percy] Finalized build #1: https://percy.io/test/test/123'
]);

expect(stderrSpy).toHaveBeenCalled();
expect(api.requests['/builds/123/send-events']).toBeDefined();
expect(api.requests['/builds/123/send-events'][0].body).toEqual({
data: {
errorKind: 'cli',
cliVersion: pkg.version,
message: jasmine.stringMatching(/Some error/)
}
});
});

it('tests process.stderr when token is present and PERCY_CLIENT_ERROR_LOGS is present and set to false', async () => {
process.env.PERCY_CLIENT_ERROR_LOGS = 'false';
const pkg = getPackageJSON(import.meta.url);
let stderrSpy = spyOn(process.stderr, 'write').and.resolveTo(jasmine.stringMatching(/Some error/));
await expectAsync(
exec(['--', 'node', './test/test-data/test_prog.js', 'error']) // Throws Error
).toBeRejectedWithError('EEXIT: 1');

expect(stderrSpy).toHaveBeenCalled();
expect(logger.stderr).toEqual([]);
expect(logger.stdout).toEqual([
'[percy] Percy has started!',
'[percy] Running "node random.js"',
'[percy] Running "node ./test/test-data/test_prog.js error"',
'[percy] Finalized build #1: https://percy.io/test/test/123'
]);

Expand All @@ -164,7 +192,33 @@ describe('percy exec', () => {
data: {
errorKind: 'cli',
cliVersion: pkg.version,
message: '1'
message: 'Log sharing is disabled'
}
});
});

it('tests process.stderr when token is present and PERCY_CLIENT_ERROR_LOGS is present and set to true', async () => {
process.env.PERCY_CLIENT_ERROR_LOGS = 'true';
const pkg = getPackageJSON(import.meta.url);
let stderrSpy = spyOn(process.stderr, 'write').and.resolveTo(jasmine.stringMatching(/Some error/));
await expectAsync(
exec(['--', 'node', './test/test-data/test_prog.js', 'error']) // Throws Error
).toBeRejectedWithError('EEXIT: 1');

expect(stderrSpy).toHaveBeenCalled();
expect(logger.stderr).toEqual([]);
expect(logger.stdout).toEqual([
'[percy] Percy has started!',
'[percy] Running "node ./test/test-data/test_prog.js error"',
'[percy] Finalized build #1: https://percy.io/test/test/123'
]);

expect(api.requests['/builds/123/send-events']).toBeDefined();
expect(api.requests['/builds/123/send-events'][0].body).toEqual({
data: {
errorKind: 'cli',
cliVersion: pkg.version,
message: jasmine.stringMatching(/Some error/)
}
});
});
Expand Down Expand Up @@ -213,9 +267,10 @@ describe('percy exec', () => {
let [e, err] = [new EventEmitter(), new Error('spawn error')];
let crossSpawn = () => (setImmediate(() => e.emit('error', err)), e);
global.__MOCK_IMPORTS__.set('cross-spawn', { default: crossSpawn });
let stdinSpy = spyOn(process.stdin, 'pipe').and.resolveTo('some response');

await expectAsync(exec(['--', 'foobar'])).toBeRejected();

expect(stdinSpy).toHaveBeenCalled();
expect(logger.stderr).toEqual([
'[percy] Error: spawn error'
]);
Expand Down
9 changes: 9 additions & 0 deletions packages/cli-exec/test/test-data/test_prog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Error
function throwError() {
throw new Error('Some error');
}
const args = process.argv.slice(2); // Extract command-line arguments, excluding the first two (node and script path)

if (args.length > 0 && args[0].toLowerCase() === 'error') {
throwError();
}

0 comments on commit 7ee2fc5

Please sign in to comment.