diff --git a/src/testSession.ts b/src/testSession.ts index 73e67c1b..34653e4d 100644 --- a/src/testSession.ts +++ b/src/testSession.ts @@ -113,7 +113,7 @@ export class TestSession extends AsyncOptionalCreatable { projectDir = this.project.dir; } - // the default bin/run in execCmd will no longer resolve properly when + // The default bin/run in execCmd will no longer resolve properly when // a test project is used since process.cwd is changed. If the // TESTKIT_EXECUTABLE_PATH env var is not being used, then set it // to use the bin/run from the cwd now. @@ -265,10 +265,16 @@ export class TestSession extends AsyncOptionalCreatable { } } - // Add the json flag if it looks like an sfdx command so we can return - // parsed json in the command return. - if (cmd.split(' ')[0].includes('sfdx') && !cmd.includes('--json')) { - cmd += ' --json'; + // Detect when running sfdx cli commands + if (cmd.split(' ')[0].includes('sfdx')) { + if (!shell.which('sfdx')) { + throw new Error('sfdx executable not found for running sfdx setup commands'); + } + // Add the json flag if it looks like an sfdx command so we can return + // parsed json in the command return. + if (!cmd.includes('--json')) { + cmd += ' --json'; + } } const rv = shell.exec(cmd, { silent: true }); diff --git a/test/unit/testProject.test.ts b/test/unit/testProject.test.ts index a91345ad..57b6d854 100644 --- a/test/unit/testProject.test.ts +++ b/test/unit/testProject.test.ts @@ -92,6 +92,7 @@ describe('TestProject', () => { }); it('should generate from a name', () => { + stubMethod(sandbox, shelljs, 'which').returns(true); const shellString = new ShellString(''); shellString.code = 0; const execStub = stubMethod(sandbox, shelljs, 'exec').returns(shellString); @@ -104,6 +105,7 @@ describe('TestProject', () => { }); it('should generate by default', () => { + stubMethod(sandbox, shelljs, 'which').returns(true); const shellString = new ShellString(''); shellString.code = 0; const execStub = stubMethod(sandbox, shelljs, 'exec').returns(shellString); @@ -116,6 +118,7 @@ describe('TestProject', () => { }); it('should error if project:create fails', () => { + stubMethod(sandbox, shelljs, 'which').returns(true); const shellString = new ShellString(''); shellString.code = 1; shellString.stderr = 'project:create failed'; @@ -143,6 +146,7 @@ describe('TestProject', () => { }); it('should zip project contents with defaults', async () => { + stubMethod(sandbox, shelljs, 'which').returns(true); const expectedRv = 'zip_test'; const shellString = new ShellString(''); shellString.code = 0; @@ -161,6 +165,7 @@ describe('TestProject', () => { }); it('should zip project contents with params', async () => { + stubMethod(sandbox, shelljs, 'which').returns(true); const expectedRv = 'zip_test'; const shellString = new ShellString(''); shellString.code = 0; diff --git a/test/unit/testSession.test.ts b/test/unit/testSession.test.ts index 072e0357..a144f1cb 100644 --- a/test/unit/testSession.test.ts +++ b/test/unit/testSession.test.ts @@ -148,6 +148,7 @@ describe('TestSession', () => { }); it('should create a session with setup commands', async () => { + stubMethod(sandbox, shelljs, 'which').returns(true); const setupCommands = ['sfdx foo:bar -r testing']; const execRv = { result: { donuts: 'yum' } }; const shellString = new ShellString(JSON.stringify(execRv)); @@ -170,6 +171,7 @@ describe('TestSession', () => { }); it('should create a session with setup commands and retries', async () => { + stubMethod(sandbox, shelljs, 'which').returns(true); // set retry timeout to 0 ms so that the test runs quickly process.env.TESTKIT_SETUP_RETRIES_TIMEOUT = '0'; const retries = 2; @@ -198,6 +200,7 @@ describe('TestSession', () => { }); it('should create a session with org creation setup commands', async () => { + stubMethod(sandbox, shelljs, 'which').returns(true); const setupCommands = ['sfdx org:create -f config/project-scratch-def.json']; const username = 'hey@ho.org'; const execRv = { result: { username } }; @@ -224,6 +227,7 @@ describe('TestSession', () => { }); it('should create a session without org creation if TESTKIT_ORG_USERNAME is defined', async () => { + stubMethod(sandbox, shelljs, 'which').returns(true); const overriddenUsername = 'sherpa@tyrolean.org'; const homedir = path.join('some', 'other', 'home'); stubMethod(sandbox, env, 'getString') @@ -257,6 +261,7 @@ describe('TestSession', () => { }); it('should error if setup command fails', async () => { + stubMethod(sandbox, shelljs, 'which').returns(true); const setupCommands = ['sfdx foo:bar -r testing']; const expectedCmd = `${setupCommands[0]} --json`; const execRv = 'Cannot foo before bar'; @@ -271,6 +276,22 @@ describe('TestSession', () => { expect((err as Error).message).to.equal(`Setup command ${expectedCmd} failed due to: ${shellString.stdout}`); } }); + + it('should error if sfdx not found to run setup commands', async () => { + stubMethod(sandbox, shelljs, 'which').returns(null); + const setupCommands = ['sfdx foo:bar -r testing']; + const execRv = 'Cannot foo before bar'; + const shellString = new ShellString(JSON.stringify(execRv)); + shellString.code = 1; + stubMethod(sandbox, shelljs, 'exec').returns(shellString); + + try { + await TestSession.create({ setupCommands }); + assert(false, 'TestSession.create() should throw'); + } catch (err: unknown) { + expect((err as Error).message).to.equal('sfdx executable not found for running sfdx setup commands'); + } + }); }); describe('clean', () => {