Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(test): extract proxy into a separate Given claim #3492

Merged
merged 1 commit into from
Apr 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
142 changes: 64 additions & 78 deletions test/e2e/step_definitions/core_steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()
})
}
})
}

Expand All @@ -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 () {
Expand Down Expand Up @@ -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) {
Expand Down
17 changes: 7 additions & 10 deletions test/e2e/step_definitions/hooks.js
Original file line number Diff line number Diff line change
@@ -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
}
})
16 changes: 7 additions & 9 deletions test/e2e/support/proxy.js
Original file line number Diff line number Diff line change
@@ -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'
Expand Down Expand Up @@ -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))()
}
}
}
5 changes: 3 additions & 2 deletions test/e2e/upstream-proxy.feature
Original file line number Diff line number Diff line change
@@ -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:
Expand All @@ -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
Expand Down