From 36e9ccae21649594b997cd61c89c073e1721ecfd Mon Sep 17 00:00:00 2001 From: Mike Kalinin Date: Wed, 18 Apr 2018 19:06:04 +0300 Subject: [PATCH] run testcafe with https protocol (#1985) --- src/cli/argument-parser.js | 18 ++++++++++++++++++ src/cli/cli.js | 8 +++++++- src/errors/runtime/message.js | 1 + src/index.js | 4 ++-- src/testcafe.js | 4 ++-- 5 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/cli/argument-parser.js b/src/cli/argument-parser.js index 91e5931ab7b..8152f2bffa2 100644 --- a/src/cli/argument-parser.js +++ b/src/cli/argument-parser.js @@ -12,6 +12,7 @@ import { assertType, is } from '../errors/runtime/type-assertions'; import getViewPortWidth from '../utils/get-viewport-width'; import { wordWrap, splitQuotedText } from '../utils/string'; import { stat, ensureDir } from '../utils/promisified-functions'; +import fs from 'fs'; const REMOTE_ALIAS_RE = /^remote(?::(\d*))?$/; @@ -106,6 +107,8 @@ export default class CLIArgumentParser { .option('--speed ', 'set the speed of test execution (0.01 ... 1)') .option('--ports ', 'specify custom port numbers') .option('--hostname ', 'specify the hostname') + .option('--ssl', 'enable HTTPS for the proxy server') + .option('--certificate ', 'specify SSL certificate files') .option('--proxy ', 'specify the host of the proxy server') .option('--proxy-bypass ', 'specify a comma-separated list of rules that define URLs accessed bypassing the proxy server') .option('--qr-code', 'outputs QR-code that repeats URLs used to connect the remote browsers') @@ -202,6 +205,20 @@ export default class CLIArgumentParser { } } + _parseCertificate () { + if (this.opts.certificate) { + const parts = this.opts.certificate.split(','); + + if (parts.length < 2) + throw new GeneralError(MESSAGE.certificateOptionRequiresTwoPaths); + + this.opts.certificate = { + key: fs.readFileSync(resolve(this.cwd, parts[0])), + cert: fs.readFileSync(resolve(this.cwd, parts[1])) + }; + } + } + _parseBrowserList () { var browsersArg = this.program.args[0] || ''; @@ -317,6 +334,7 @@ export default class CLIArgumentParser { this._parseAppInitDelay(); this._parseSpeed(); this._parsePorts(); + this._parseCertificate(); this._parseBrowserList(); this._parseConcurrency(); diff --git a/src/cli/cli.js b/src/cli/cli.js index b0a0d73f8f4..9594c882217 100644 --- a/src/cli/cli.js +++ b/src/cli/cli.js @@ -70,9 +70,15 @@ async function runTests (argParser) { var externalProxyHost = opts.proxy; var proxyBypass = opts.proxyBypass; + var options = { + ssl: Boolean(opts.ssl), + key: String(opts.certificate && opts.certificate.key), + cert: String(opts.certificate && opts.certificate.cert), + }; + log.showSpinner(); - var testCafe = await createTestCafe(opts.hostname, port1, port2); + var testCafe = await createTestCafe(opts.hostname, port1, port2, options); var concurrency = argParser.concurrency || 1; var remoteBrowsers = await remotesWizard(testCafe, argParser.remoteCount, opts.qrCode); var browsers = argParser.browsers.concat(remoteBrowsers); diff --git a/src/errors/runtime/message.js b/src/errors/runtime/message.js index db9199d6849..b28dbbb0252 100644 --- a/src/errors/runtime/message.js +++ b/src/errors/runtime/message.js @@ -28,5 +28,6 @@ export default { invalidValueType: '{smthg} is expected to be a {type}, but it was {actual}.', unsupportedUrlProtocol: 'The specified "{url}" test page URL uses an unsupported {protocol}:// protocol. Only relative URLs or absolute URLs with http://, https:// and file:// protocols are supported.', unableToOpenBrowser: 'Was unable to open the browser "{alias}" due to error.\n\n{errMessage}', + certificateOptionRequiresTwoPaths: 'The "--certificate" option requires two paths to be specified.', testControllerProxyCantResolveTestRun: `Cannot implicitly resolve the test run in the context of which the test controller action should be executed. Use test function's 't' argument instead.` }; diff --git a/src/index.js b/src/index.js index b03ebd9c922..ec32fa0704a 100644 --- a/src/index.js +++ b/src/index.js @@ -36,14 +36,14 @@ async function getValidPort (port) { } // API -async function createTestCafe (hostname, port1, port2) { +async function createTestCafe (hostname, port1, port2, options) { [hostname, port1, port2] = await Promise.all([ getValidHostname(hostname), getValidPort(port1), getValidPort(port2) ]); - var testcafe = new TestCafe(hostname, port1, port2); + var testcafe = new TestCafe(hostname, port1, port2, options); setupExitHook(cb => testcafe.close().then(cb)); diff --git a/src/testcafe.js b/src/testcafe.js index 253a3332a50..061656d9b4d 100644 --- a/src/testcafe.js +++ b/src/testcafe.js @@ -18,9 +18,9 @@ const FAVICON = read('./client/ui/favicon.ico', true); export default class TestCafe { - constructor (hostname, port1, port2) { + constructor (hostname, port1, port2, options) { this.closed = false; - this.proxy = new Proxy(hostname, port1, port2); + this.proxy = new Proxy(hostname, port1, port2, options); this.browserConnectionGateway = new BrowserConnectionGateway(this.proxy); this.runners = [];