diff --git a/README.md b/README.md index 499f731..c7a8c50 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,8 @@ sauceConnectLauncher(options, function (err, sauceConnectProcess) { ``` +Additional Sauce Connect options not specified above can still be passed. `additionalArg: "foo"` options will be converted to `--addtional-arg foo` args (camelCase to kebeb-case). Arrays will be `join()`ed (like `directDomains`) and boolean options will be passed as flags. See [Sauce Connect's docs](https://docs.saucelabs.com/reference/sauce-connect/) for a full list of arguments. + ### Credentials You can also pass the credentials as `SAUCE_USERNAME` and `SAUCE_ACCESS_KEY` environment variables. (reccommended) diff --git a/lib/sauce-connect-launcher.js b/lib/sauce-connect-launcher.js index aa4de22..f304f2d 100644 --- a/lib/sauce-connect-launcher.js +++ b/lib/sauce-connect-launcher.js @@ -9,6 +9,7 @@ var AdmZip = require("adm-zip"), spawn = require("child_process").spawn, exec = require("child_process").exec, + processOptions = require("./process_options"), archivefile, scDir = path.normalize(__dirname + "/../sc"), exists = fs.existsSync || path.existsSync, @@ -17,7 +18,8 @@ var cleanup_registered = false; function getScVersion() { - return process.env.SAUCE_CONNECT_VERSION || require("../package.json").sauceConnectLauncher.scVersion; + return process.env.SAUCE_CONNECT_VERSION || + require("../package.json").sauceConnectLauncher.scVersion; } function killProcesses(callback) { @@ -212,10 +214,7 @@ function run(options, callback) { watcher, readyfile, readyFileName = "sc-launcher-readyfile", - args = [ - "-u", options.username || process.env.SAUCE_USERNAME, - "-k", options.accessKey || process.env.SAUCE_ACCESS_KEY - ], + args = processOptions(options), error, handleError = function (data) { if (data.indexOf("Not authorized") !== -1 && !error) { @@ -242,52 +241,6 @@ function run(options, callback) { } }; - if (options.port) { - args.push("-P", options.port); - } - - if (options.proxy) { - args.push("--proxy", options.proxy); - } - - if (options.directDomains) { - if (_.isArray(options.directDomains)) { - options.directDomains = options.directDomains.join(","); - } - args.push("--direct-domains", options.directDomains); - } - - if (options.fastFailRegexps) { - if (_.isArray(options.fastFailRegexps)) { - options.fastFailRegexps = options.fastFailRegexps.join(","); - } - args.push("--fast-fail-regexps", options.fastFailRegexps); - } - - if (options.verboseDebugging) { - args.push("--verbose"); - } - - if (options.logfile) { - args.push("-l", options.logfile); - } - - if (options.logStats) { - args.push("--log-stats", options.logStats); - } - - if (options.maxLogsize) { - args.push("--max-logsize", options.maxLogsize); - } - - if (options.doctor) { - args.push("--doctor"); - } - - if (options.tunnelIdentifier) { - args.push("--tunnel-identifier", options.tunnelIdentifier); - } - if (options.readyFileId) { readyFileName = readyFileName + "_" + options.readyFileId; } @@ -344,7 +297,8 @@ function run(options, callback) { var message = "Closing Sauce Connect Tunnel"; if (code > 0) { - message = "Could not start Sauce Connect. Exit code " + code + " signal: " + signal; + message = "Could not start Sauce Connect. Exit code " + code + + " signal: " + signal; callback(new Error(message)); } logger(message); diff --git a/package.json b/package.json index e23d936..70ab7a8 100644 --- a/package.json +++ b/package.json @@ -21,10 +21,10 @@ "test": "make test" }, "dependencies": { - "lodash": "2.4.1", - "async": "~0.9.0", + "lodash": "3.5.0", + "async": "0.9.0", "adm-zip": "~0.4.3", - "rimraf": "~2.2.6" + "rimraf": "2.2.6" }, "devDependencies": { "colors": "~0.6.2", diff --git a/test/process_options.test.js b/test/process_options.test.js new file mode 100644 index 0000000..3abd00f --- /dev/null +++ b/test/process_options.test.js @@ -0,0 +1,71 @@ +var processOptions = require("../lib/process_options.js"); +var expect = require("expect.js"); + +describe("processOptions", function () { + var prevUser, prevKey; + + before(function () { + prevUser = process.env.SAUCE_USERNAME; + prevKey = process.env.SAUCE_ACCESS_KEY; + delete process.env.SAUCE_USERNAME; + delete process.env.SAUCE_ACCESS_KEY; + }); + + after(function () { + process.env.SAUCE_USERNAME = prevUser; + process.env.SAUCE_ACCESS_KEY = prevKey; + }); + + it("should process user and password", function () { + var result = processOptions({username: "bermi", accessKey: "1234"}); + expect(result).to.be.an(Array); + expect(result).to.eql([ + "-u", "bermi", + "-k", "1234" + ]); + }); + + it("should process user and password as env vars", function () { + process.env.SAUCE_USERNAME = "bermi"; + process.env.SAUCE_ACCESS_KEY = "1234"; + var result = processOptions({}); + expect(result).to.be.an(Array); + expect(result).to.eql([ + "-u", "bermi", + "-k", "1234" + ]); + delete process.env.SAUCE_USERNAME; + delete process.env.SAUCE_ACCESS_KEY; + }); + + it("should handle proxy ports", function () { + expect(processOptions({port: 1234})).to.eql(["-P", 1234]); + }); + + it("should handle boolean flags", function () { + var result = processOptions({doctor: true}); + expect(result).to.eql(["--doctor"]); + }); + + it("should handle array values", function () { + var result = processOptions({directDomains: ["google.com", "asdf.com"]}); + expect(result).to.eql(["--direct-domains", "google.com,asdf.com"]); + }); + + it("should handle future options", function () { + var result = processOptions({ + someFutureOption: "asdf", + futureBoolean: true + }); + expect(result).to.eql(["--some-future-option", "asdf", "--future-boolean"]); + }); + + it("should omit special launcher flags", function () { + expect(processOptions({ + readyFileId: "1", + verbose: true, + logger: function () {} + })).to.eql([]); + }); + +});