diff --git a/test/e2e/step_definitions/core_steps.js b/test/e2e/step_definitions/core_steps.js index 0c96aa2b9..5f8d4bbab 100644 --- a/test/e2e/step_definitions/core_steps.js +++ b/test/e2e/step_definitions/core_steps.js @@ -24,90 +24,76 @@ function cleanseIfNeeded () { } } -function execKarma (command, level, proxyPort, proxyPath, callback) { +function execKarma (command, level, callback) { level = level || 'warn' - const startProxy = (done) => { - if (proxyPort) { - this.proxy.start(proxyPort, proxyPath, done) - } else { - done() + this.writeConfigFile(tmpDir, tmpConfigFile, (err, hash) => { + if (err) { + return callback.fail(new Error(err)) } - } + const configFile = path.join(tmpDir, hash + '.' + tmpConfigFile) + const runtimePath = path.join(baseDir, 'bin', 'karma') - startProxy((err) => { - if (err) { - return callback.fail(err) + const executor = (done) => { + const cmd = runtimePath + ' ' + command + ' --log-level ' + level + ' ' + configFile + ' ' + additionalArgs + + return exec(cmd, { + cwd: baseDir + }, done) } - this.writeConfigFile(tmpDir, tmpConfigFile, (err, hash) => { - if (err) { - return callback.fail(new Error(err)) + const runOut = command === 'runOut' + if (command === 'run' || command === 'runOut') { + let isRun = false + this.child = spawn('' + runtimePath, ['start', '--log-level', 'warn', configFile]) + const done = () => { + cleansingNeeded = true + this.child && this.child.kill() + callback() } - const configFile = path.join(tmpDir, hash + '.' + tmpConfigFile) - const runtimePath = path.join(baseDir, 'bin', 'karma') - const executor = (done) => { - const cmd = runtimePath + ' ' + command + ' --log-level ' + level + ' ' + configFile + ' ' + additionalArgs + this.child.on('error', (error) => { + this.lastRun.error = error + done() + }) - return exec(cmd, { - cwd: baseDir - }, done) - } + this.child.stderr.on('data', (chunk) => { + this.lastRun.stderr += chunk.toString() + }) - const runOut = command === 'runOut' - if (command === 'run' || command === 'runOut') { - let isRun = false - this.child = spawn('' + runtimePath, ['start', '--log-level', 'warn', configFile]) - const done = () => { - cleansingNeeded = true - this.child && this.child.kill() - callback() + this.child.stdout.on('data', (chunk) => { + this.lastRun.stdout += chunk.toString() + const cmd = runtimePath + ' run ' + configFile + ' ' + additionalArgs + if (!isRun) { + isRun = true + + setTimeout(() => { + exec(cmd, { + cwd: baseDir + }, (error, stdout, stderr) => { + if (error) { + this.lastRun.error = error + } + if (runOut) { + this.lastRun.stdout = stdout + this.lastRun.stderr = stderr + } + done() + }) + }, 1000) } - - this.child.on('error', (error) => { + }) + } else { + executor((error, stdout, stderr) => { + if (error) { this.lastRun.error = error - done() - }) - - this.child.stderr.on('data', (chunk) => { - this.lastRun.stderr += chunk.toString() - }) - - this.child.stdout.on('data', (chunk) => { - this.lastRun.stdout += chunk.toString() - const cmd = runtimePath + ' run ' + configFile + ' ' + additionalArgs - if (!isRun) { - isRun = true - - setTimeout(() => { - exec(cmd, { - cwd: baseDir - }, (error, stdout, stderr) => { - if (error) { - this.lastRun.error = error - } - if (runOut) { - this.lastRun.stdout = stdout - this.lastRun.stderr = stderr - } - done() - }) - }, 1000) - } - }) - } else { - executor((error, stdout, stderr) => { - if (error) { - this.lastRun.error = error - } - this.lastRun.stdout = stdout - this.lastRun.stderr = stderr - cleansingNeeded = true - callback() - }) - } - }) + } + this.lastRun.stdout = stdout + this.lastRun.stderr = stderr + cleansingNeeded = true + callback() + }) + } }) } @@ -122,6 +108,10 @@ Given('command line arguments of: {string}', function (args, callback) { return callback() }) +Given('a proxy on port {int} that prepends {string} to the base path', async function (proxyPort, proxyPath) { + return this.proxy.start(proxyPort, proxyPath) +}) + When('I stop a server programmatically', function (callback) { const _this = this setTimeout(function () { @@ -164,15 +154,11 @@ defineParameterType({ }) When('I {command} Karma', function (command, callback) { - execKarma.apply(this, [command, undefined, undefined, undefined, callback]) + execKarma.apply(this, [command, undefined, callback]) }) When('I {command} Karma with log-level {loglevel}', function (command, level, callback) { - execKarma.apply(this, [command, level, undefined, undefined, callback]) -}) - -When('I {command} Karma behind a proxy on port {int} that prepends {string} to the base path', function (command, proxyPort, proxyPath, callback) { - execKarma.apply(this, [command, 'debug', proxyPort, proxyPath, callback]) + execKarma.apply(this, [command, level, callback]) }) Then(/^it passes with(:? (no\sdebug|like|regexp))?:$/, { timeout: 10 * 1000 }, function (mode, expectedOutput, callback) { diff --git a/test/e2e/step_definitions/hooks.js b/test/e2e/step_definitions/hooks.js index 8e3391d94..12ef627a2 100644 --- a/test/e2e/step_definitions/hooks.js +++ b/test/e2e/step_definitions/hooks.js @@ -1,14 +1,11 @@ const { After } = require('cucumber') -After(function (scenario, callback) { - const running = this.child != null && typeof this.child.kill === 'function' +After(async function () { + await this.proxy.stopIfRunning() - // stop the proxy if it was started - this.proxy.stop(() => { - if (running) { - this.child.kill() - this.child = null - } - callback() - }) + const running = this.child != null && typeof this.child.kill === 'function' + if (running) { + this.child.kill() + this.child = null + } }) diff --git a/test/e2e/support/proxy.js b/test/e2e/support/proxy.js index 832a2626f..5bf17c1fd 100644 --- a/test/e2e/support/proxy.js +++ b/test/e2e/support/proxy.js @@ -1,9 +1,11 @@ const http = require('http') const httpProxy = require('http-proxy') +const { promisify } = require('util') module.exports = class Proxy { constructor () { this.running = false + this.proxyPathRegExp = null this.proxy = httpProxy.createProxyServer({ target: 'http://localhost:9876' @@ -31,20 +33,16 @@ module.exports = class Proxy { }) } - start (port, proxyPath, callback) { + async start (port, proxyPath) { this.proxyPathRegExp = new RegExp('^' + proxyPath + '(.*)') - this.server.listen(port, (error) => { - this.running = !error - callback(error) - }) + await promisify(this.server.listen.bind(this.server))(port) + this.running = true } - stop (callback) { + async stopIfRunning () { if (this.running) { this.running = false - this.server.close(callback) - } else { - callback() + await promisify(this.server.close.bind(this.server))() } } } diff --git a/test/e2e/upstream-proxy.feature b/test/e2e/upstream-proxy.feature index c813f8cf3..8e3414b8d 100644 --- a/test/e2e/upstream-proxy.feature +++ b/test/e2e/upstream-proxy.feature @@ -1,7 +1,7 @@ Feature: UpstreamProxy In order to use Karma As a person who wants to write great tests - I want to Karma to to work when it is behind a proxy that prepends to the base path. + I want Karma to work when it is behind a proxy that prepends to the base path. Scenario: UpstreamProxy Given a configuration with: @@ -17,7 +17,8 @@ Feature: UpstreamProxy path: '/__proxy__/' }; """ - When I start Karma behind a proxy on port 9875 that prepends '/__proxy__/' to the base path + And a proxy on port 9875 that prepends '/__proxy__/' to the base path + When I start Karma with log-level debug Then it passes with regexp: """ Chrome Headless.*Executed.*SUCCESS