diff --git a/bin/commands/init.js b/bin/commands/init.js index 16e17011..6bd7246b 100644 --- a/bin/commands/init.js +++ b/bin/commands/init.js @@ -6,16 +6,47 @@ const fileHelpers = require("../helpers/fileHelpers"), util = require("util"), path = require('path'); -module.exports = function init(args) { - if (args.p) { - var path_to_bsconf = path.join(args.p + "/browserstack.json"); - } else { - var path_to_bsconf = "./browserstack.json"; + +function get_path(args) { + if (args._.length > 1 && args.p) { + let filename = args._[1]; + if (filename !== path.basename(filename)) { + let message = Constants.userMessages.CONFLICTING_INIT_ARGUMENTS; + logger.error(message); + utils.sendUsageReport(null, args, message, Constants.messageTypes.ERROR, 'conflicting_path_json_init'); + return; + } + + return path.join(args.p, filename); + } else if (args.p) { + return path.join(args.p, "browserstack.json"); + } else if (args._.length > 1) { + let filename = args._[1]; + if (filename !== path.basename(filename)) { + // filename is an absolute path + return filename; + } + return path.join(process.cwd(), args._[1]); } - var config = { + return path.join(process.cwd(), "browserstack.json"); +} + + +module.exports = function init(args) { + + let path_to_json = get_path(args); + if (path_to_json === undefined) return; + + // append .json if filename passed is not of json type + if (path.extname(path_to_json) !== '' && path.extname(path_to_json) !== ".json") path_to_json += ".json"; + + // append browserstack.json if filename is a path without filename + if (path.extname(path_to_json) === '') path_to_json = path.join(path_to_json, "browserstack.json"); + + let config = { file: require('../templates/configTemplate')(), - path: path_to_bsconf + path: path_to_json }; return fileHelpers.dirExists(config.path, function(dirExists){ diff --git a/bin/helpers/constants.js b/bin/helpers/constants.js index 945eb3c5..890c6fa1 100644 --- a/bin/helpers/constants.js +++ b/bin/helpers/constants.js @@ -13,6 +13,7 @@ const userMessages = { API_DEPRECATED: "This version of API is deprecated, please use latest version of API.", FAILED_TO_ZIP: "Failed to zip files.", VISIT_DASHBOARD: "Visit the Automate dashboard for test reporting:", + CONFLICTING_INIT_ARGUMENTS: "Conflicting arguments given. You can use --path only with a file name, and not with a file path.", NO_PARALLELS: "Your tests will run sequentially. Read more about running your tests in parallel here: https://www.browserstack.com/docs/automate/cypress/run-tests-in-parallel", NO_NPM_DEPENDENCIES: "No npm dependencies specified. Read more here: https://www.browserstack.com/docs/automate/cypress/npm-packages. You can suppress this warning by using --disable-npm-warning flag." }; diff --git a/bin/runner.js b/bin/runner.js index edc4f9a3..f97bc7d9 100755 --- a/bin/runner.js +++ b/bin/runner.js @@ -22,7 +22,7 @@ var argv = yargs .demand(1, Constants.cliMessages.VERSION.DEMAND) .command('init', Constants.cliMessages.INIT.INFO, function(yargs) { argv = yargs - .usage("usage: $0 init [options]") + .usage("usage: $0 init [filename] [options]") .options({ 'p': { alias: "path", diff --git a/test/unit/bin/commands/init.js b/test/unit/bin/commands/init.js index 2275c39c..b4331492 100644 --- a/test/unit/bin/commands/init.js +++ b/test/unit/bin/commands/init.js @@ -1,14 +1,21 @@ const chai = require("chai"), + assert = chai.assert, + expect = chai.expect, sinon = require("sinon"), chaiAsPromised = require("chai-as-promised"), - util = require("util"); + rewire = require("rewire"), + util = require("util"), + path = require('path'); const Constants = require("../../../../bin/helpers/constants"), logger = require("../../../../bin/helpers/logger").winstonLogger, - testObjects = require("../../support/fixtures/testObjects"); + testObjects = require("../../support/fixtures/testObjects") + utils = require("../../../../bin/helpers/utils"); const proxyquire = require("proxyquire").noCallThru(); +const get_path = rewire("../../../../bin/commands/init").__get__("get_path");; + chai.use(chaiAsPromised); logger.transports["console.info"].silent = true; @@ -29,6 +36,79 @@ describe("init", () => { sinon.restore(); }); + describe("get_path", () => { + it("filename passed, -path passed", () => { + let args = { + _: ["init", "filename.json"], + p: '/sample-path', + path: '/sample-path', + $0: "browserstack-cypress", + }; + + expect(get_path(args)).to.be.eql('/sample-path/filename.json'); + }); + + it("filename passed, -path not passed", () => { + let args = { + _: ["init", "filename.json"], + p: false, + path: false, + $0: "browserstack-cypress", + }; + + let args2 = { + _: ["init", "~/filename.json"], + p: false, + path: false, + $0: "browserstack-cypress", + }; + + expect(get_path(args)).to.be.eql(path.join(process.cwd(), 'filename.json')); + expect(get_path(args2)).to.be.eql('~/filename.json'); + }); + + it("filepath passed, -path passed", () => { + let args = { + _: ["init", "/sample-path/filename.json"], + p: '/sample-path2', + path: '/sample-path2', + "disable-usage-reporting": undefined, + disableUsageReporting: undefined, + $0: "browserstack-cypress", + }; + + loggerStub = sandbox.stub(logger, 'error'); + usageStub = sandbox.stub(utils, 'sendUsageReport'); + + expect(get_path(args)).to.be.undefined; + sinon.assert.calledOnce(loggerStub); + sinon.assert.calledOnce(usageStub); + }); + + it("filename not passed, -path passed", () => { + let args = { + _: ["init"], + p: '/sample-path', + path: '/sample-path', + $0: "browserstack-cypress", + }; + + expect(get_path(args)).to.be.eql('/sample-path/browserstack.json'); + }); + + it("filename not passed, -path not passed", () => { + let args = { + _: ["init"], + p: false, + path: false, + $0: "browserstack-cypress", + }; + + expect(get_path(args)).to.be.eql(path.join(process.cwd(), 'browserstack.json')); + }); + }); + + describe("init", () => { it("fail if given path is not present", () => { dirExistsStub = sandbox.stub().yields(false);