Skip to content

Commit

Permalink
refactor(test): reduce execKarma to a reasonable size (#3496)
Browse files Browse the repository at this point in the history
Finally!

Introduced extra step "I wait until server output contains" instead of hard-coded timeout. It will regularly evaluate a condition until it fulfills. This approach should potentially perform a little bit better than the previous solution.
  • Loading branch information
devoto13 committed May 6, 2020
1 parent a3d1f11 commit f375884
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 49 deletions.
7 changes: 6 additions & 1 deletion test/e2e/browser_console.feature
Expand Up @@ -183,7 +183,12 @@ Feature: Browser Console Configuration
];
singleRun = false;
"""
When I run Karma
When I start a server in background
And I wait until server output contains:
"""
Executed 1 of 1 SUCCESS
"""
And I run Karma
Then it passes with like:
"""
LOG: 'foo'
Expand Down
8 changes: 7 additions & 1 deletion test/e2e/error.feature
Expand Up @@ -18,6 +18,7 @@ Feature: Error Display
"""
SyntaxError: Unexpected token '}'
"""

Scenario: Not single-run Syntax Error in a test file
Given a configuration with:
"""
Expand All @@ -29,7 +30,12 @@ Feature: Error Display
];
singleRun = false;
"""
When I run Karma
When I start a server in background
And I wait until server output contains:
"""
Executed 2 of 2 (1 FAILED)
"""
And I run Karma
Then it fails with like:
"""
SyntaxError: Unexpected token '}'
Expand Down
7 changes: 6 additions & 1 deletion test/e2e/pass-opts.feature
Expand Up @@ -15,7 +15,12 @@ Feature: Passing Options
singleRun = false;
"""
And command line arguments of: "-- arg1 arg2"
When I run Karma
When I start a server in background
And I wait until server output contains:
"""
Executed 1 of 1 (1 FAILED)
"""
And I run Karma
Then it passes with no debug:
"""
.
Expand Down
64 changes: 18 additions & 46 deletions test/e2e/step_definitions/core_steps.js
Expand Up @@ -2,54 +2,21 @@ const { defineParameterType, Given, Then, When } = require('cucumber')
const fs = require('fs')
const path = require('path')
const { exec } = require('child_process')
const { waitForCondition } = require('./utils')
const stopper = require('../../../lib/stopper')

let additionalArgs = []

function execKarma (command, level, callback) {
level = level || 'warn'

const configFile = this.configFile
const runtimePath = this.karmaExecutable
const baseDir = this.workDir

const executor = (done) => {
const cmd = runtimePath + ' ' + command + ' --log-level ' + level + ' ' + configFile + ' ' + additionalArgs

return exec(cmd, {
cwd: baseDir
}, done)
}

if (command === 'run') {
this.runBackgroundProcess(['start', '--log-level', 'warn', configFile])
.then(() => {
const cmd = runtimePath + ' run ' + configFile + ' ' + additionalArgs

setTimeout(() => {
exec(cmd, {
cwd: baseDir
}, (error, stdout, stderr) => {
if (error) {
this.lastRun.error = error
}
this.lastRun.stdout = stdout
this.lastRun.stderr = stderr
callback()
})
}, 1000)
})
.catch((error) => callback(error))
} else {
executor((error, stdout, stderr) => {
if (error) {
this.lastRun.error = error
}
this.lastRun.stdout = stdout
this.lastRun.stderr = stderr
callback()
})
}
const cmd = `${this.karmaExecutable} ${command} --log-level ${level} ${this.configFile} ${additionalArgs}`
exec(cmd, { cwd: this.workDir }, (error, stdout, stderr) => {
this.lastRun.error = error
this.lastRun.stdout = stdout.toString()
this.lastRun.stderr = stderr.toString()
callback()
})
}

Given('a default configuration', function () {
Expand Down Expand Up @@ -83,6 +50,10 @@ When('I start a server in background', async function () {
await this.runBackgroundProcess(['start', '--log-level', 'debug', this.configFile])
})

When('I wait until server output contains:', async function (expectedOutput) {
await waitForCondition(() => this.backgroundProcess.stdout.includes(expectedOutput))
})

defineParameterType({
name: 'command',
regexp: /run|start|init|stop/
Expand All @@ -105,7 +76,7 @@ Then(/^it passes with(:? (no\sdebug|like|regexp))?:$/, { timeout: 10 * 1000 }, f
const noDebug = mode === 'no debug'
const like = mode === 'like'
const regexp = mode === 'regexp'
let actualOutput = this.lastRun.stdout.toString()
let actualOutput = this.lastRun.stdout
let lines

if (noDebug) {
Expand All @@ -132,9 +103,9 @@ Then(/^it passes with(:? (no\sdebug|like|regexp))?:$/, { timeout: 10 * 1000 }, f
})

Then('it fails with:', function (expectedOutput, callback) {
const actualOutput = this.lastRun.stdout.toString()
const actualOutput = this.lastRun.stdout
const actualError = this.lastRun.error
const actualStderr = this.lastRun.stderr.toString()
const actualStderr = this.lastRun.stderr

if (actualOutput.match(expectedOutput)) {
return callback()
Expand All @@ -146,9 +117,10 @@ Then('it fails with:', function (expectedOutput, callback) {
})

Then('it fails with like:', function (expectedOutput, callback) {
const actualOutput = this.lastRun.stdout.toString()
const actualOutput = this.lastRun.stdout
const actualError = this.lastRun.error
const actualStderr = this.lastRun.stderr.toString()
const actualStderr = this.lastRun.stderr

if (actualOutput.match(new RegExp(expectedOutput))) {
return callback()
}
Expand Down
15 changes: 15 additions & 0 deletions test/e2e/step_definitions/utils.js
@@ -0,0 +1,15 @@
const { promisify } = require('util')

const sleep = promisify(setTimeout)

module.exports.waitForCondition = async (evaluateCondition, timeout = 1000) => {
let remainingTime = timeout
while (!evaluateCondition()) {
if (remainingTime > 0) {
await sleep(50)
remainingTime -= 50
} else {
throw new Error(`Condition not fulfilled, waited ${timeout}ms`)
}
}
}

0 comments on commit f375884

Please sign in to comment.