Skip to content

Commit

Permalink
[Gradle, JS] Update npm versions
Browse files Browse the repository at this point in the history
(cherry picked from commit cb31b42)

[Gradle, JS] Update npm dependencies

- Karma - provide possibility to check exit code
- Webpack - bug fixes
- Mocha - bug fixes

(cherry picked from commit fa64768)

[Gradle, JS]  Fully copy of karma-teamcity-reporter (remove npm dependency on it)

[Gradle, JS] Copy mocha-teamcity-reporter with licensies

[Gradle, JS] Depends node test on our own mocha reporter

[Gradle, JS] Refactor and extract team city formatting in separate file

Check Karma exit code with disabled failOnFailingTestSuite

karma-runner/karma#3116
(cherry picked from commit 2cf79b7)
  • Loading branch information
ilgonmic committed Oct 23, 2019
1 parent be773a0 commit b55226e
Show file tree
Hide file tree
Showing 16 changed files with 383 additions and 549 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,37 @@ import org.jetbrains.kotlin.gradle.targets.js.npm.NpmDependency
class NpmVersions {
val dukat = NpmPackageVersion("dukat", "0.0.19")

val webpack = NpmPackageVersion("webpack", "4.29.6")
val webpackCli = NpmPackageVersion("webpack-cli", "3.3.0")
val webpackBundleAnalyzer = NpmPackageVersion("webpack-bundle-analyzer", "3.3.2")
val webpackDevServer = NpmPackageVersion("webpack-dev-server", "3.3.1")
val webpack = NpmPackageVersion("webpack", "4.41.2")
val webpackCli = NpmPackageVersion("webpack-cli", "3.3.9")
val webpackBundleAnalyzer = NpmPackageVersion("webpack-bundle-analyzer", "3.5.2")
val webpackDevServer = NpmPackageVersion("webpack-dev-server", "3.8.2")

// Temporarily use our own source-map-loader, while original source-map-loader is not updated
// https://github.com/webpack-contrib/source-map-loader/pull/91
val kotlinSourceMapLoader = KotlinGradleNpmPackage("source-map-loader")
val sourceMapLoader = NpmPackageVersion("source-map-loader", "0.2.4")
val sourceMapSupport = NpmPackageVersion("source-map-support", "0.5.12")
val sourceMapSupport = NpmPackageVersion("source-map-support", "0.5.13")

val mocha = NpmPackageVersion("mocha", "6.1.2")
val mochaTeamCityReporter = NpmPackageVersion("mocha-teamcity-reporter", ">=2.0.0")
val mocha = NpmPackageVersion("mocha", "6.2.2")

val karma = NpmPackageVersion("karma", "4.0.1")
val karmaTeamcityReporter = NpmPackageVersion("karma-teamcity-reporter", "1.1.0")
val karma = NpmPackageVersion("karma", "4.4.1")

val karmaChromeLauncher = NpmPackageVersion("karma-chrome-launcher", "2.2.0")
val karmaChromeLauncher = NpmPackageVersion("karma-chrome-launcher", "3.1.0")
val karmaPhantomJsLauncher = NpmPackageVersion("karma-phantomjs-launcher", "1.0.4")
val karmaFirefoxLauncher = NpmPackageVersion("karma-firefox-launcher", "1.1.0")
val karmaFirefoxLauncher = NpmPackageVersion("karma-firefox-launcher", "1.2.0")
val karmaOperaLauncher = NpmPackageVersion("karma-opera-launcher", "1.0.0")
val karmaIeLauncher = NpmPackageVersion("karma-ie-launcher", "1.0.0")
val karmaSafariLauncher = NpmPackageVersion("karma-safari-launcher", "1.0.0")

val karmaMocha = NpmPackageVersion("karma-mocha", "1.3.0")
val karmaWebpack = NpmPackageVersion("karma-webpack", "^4.0.0-rc.6")
val karmaCoverage = NpmPackageVersion("karma-coverage", "1.1.2")
val karmaWebpack = NpmPackageVersion("karma-webpack", "4.0.2")
val karmaCoverage = NpmPackageVersion("karma-coverage", "2.0.1")

val karmaSourceMapLoader = NpmPackageVersion("karma-sourcemap-loader", "0.3.7")

val puppeteer = NpmPackageVersion("puppeteer", "1.19.0")
val puppeteer = NpmPackageVersion("puppeteer", "1.20.0")

val kotlinJsTestRunner = KotlinGradleNpmPackage("test-js-runner")

val istanbulInstrumenterLoader = NpmPackageVersion("istanbul-instrumenter-loader", "3.0.1")
}

interface RequiredKotlinJsDependency {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ data class KarmaConfig(
val client: KarmaClient = KarmaClient(),
val browsers: MutableList<String> = mutableListOf(),
val customLaunchers: MutableMap<String, CustomLauncher> = mutableMapOf(),
val failOnFailingTestSuite: Boolean = false,
val reporters: MutableList<String> = mutableListOf(),
val preprocessors: MutableMap<String, MutableList<String>> = mutableMapOf(),
var coverageReporter: CoverageReporter? = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ class KotlinKarma(override val compilation: KotlinJsCompilation) : KotlinJsTestF
}

private fun useKotlinReporter() {
requiredDependencies.add(versions.karmaTeamcityReporter)
config.reporters.add("karma-kotlin-reporter")

confJsWriters.add {
Expand Down Expand Up @@ -325,22 +324,15 @@ class KotlinKarma(override val compilation: KotlinJsCompilation) : KotlinJsTestF
return object : JSServiceMessagesTestExecutionSpec(
forkOptions,
args,
false,
true,
clientSettings
) {
lateinit var progressLogger: ProgressLogger

var isLaunchFailed: Boolean = false

override fun wrapExecute(body: () -> Unit) {
project.operation("Running and building tests with karma and webpack") {
progressLogger = this
body()

if (isLaunchFailed) {
showSuppressedOutput()
throw IllegalStateException("Launch of some browsers was failed")
}
}
}

Expand All @@ -358,7 +350,7 @@ class KotlinKarma(override val compilation: KotlinJsCompilation) : KotlinJsTestF
val value = text.trimEnd()
progressLogger.progress(value)

parseConsole(value)
super.printNonTestOutput(text)
}

override fun processStackTrace(stackTrace: String): String =
Expand Down Expand Up @@ -389,16 +381,6 @@ class KotlinKarma(override val compilation: KotlinJsCompilation) : KotlinJsTestF

return rawSuiteNameOnly.replace(" ", ".") // sample.a.DeepPackageTest.Inner
}

private fun parseConsole(text: String) {
if (KARMA_PROBLEM.matches(text)) {
log.error(text)
isLaunchFailed = true
return
}

super.printNonTestOutput(text)
}
}
}
}
Expand All @@ -418,7 +400,5 @@ class KotlinKarma(override val compilation: KotlinJsCompilation) : KotlinJsTestF
companion object {
const val CHROME_BIN = "CHROME_BIN"
const val CHROME_CANARY_BIN = "CHROME_CANARY_BIN"

val KARMA_PROBLEM = "(?m)^.*\\d{2} \\d{2} \\d{4,} \\d{2}:\\d{2}:\\d{2}.\\d{3}:(ERROR|WARN) \\[.*]: (.*)\$".toRegex()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ class KotlinMocha(override val compilation: KotlinJsCompilation) : KotlinJsTestF
override val requiredNpmDependencies: Collection<RequiredKotlinJsDependency>
get() = listOf(
KotlinGradleNpmPackage("test-js-runner"),
versions.mocha,
versions.mochaTeamCityReporter
versions.mocha
)

override fun createTestExecutionSpec(
Expand Down Expand Up @@ -66,7 +65,7 @@ class KotlinMocha(override val compilation: KotlinJsCompilation) : KotlinJsTestF
nodeModules.map {
npmProject.require(it)
} + cliArgs.toList() +
listOf("--reporter", "mocha-teamcity-reporter") +
listOf("--reporter", "kotlin-test-js-runner/mocha-kotlin-reporter.js") +
listOf(
"-r", "kotlin-test-js-runner/kotlin-nodejs-source-map-support.js"
)
Expand Down
1 change: 1 addition & 0 deletions libraries/tools/kotlin-test-js-runner/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ tasks {
"nodejs.ts",
"karma.ts",
"karma-kotlin-reporter.js",
"mocha-kotlin-reporter.js",
"nodejs-source-map-support.js",
"package.json",
"rollup.config.js",
Expand Down
160 changes: 109 additions & 51 deletions libraries/tools/kotlin-test-js-runner/karma-kotlin-reporter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
const util = require('util');
import {
BLOCK_CLOSED,
BLOCK_OPENED,
formatMessage,
SUITE_END,
SUITE_START,
TEST_END,
TEST_FAILED,
TEST_IGNORED,
TEST_START
} from "./src/teamcity-format";

const resolve = require('path').resolve;

/**
Expand Down Expand Up @@ -72,50 +83,55 @@ function createFormatError(config, emitter) {
* The MIT License
* Copyright (C) 2011-2013 Vojta Jína and contributors
*/
const escapeMessage = function (message) {
if (message === null || message === undefined) {
return ''
}

return message.toString()
.replace(/\|/g, '||')
.replace(/'/g, "|'")
.replace(/\n/g, '|n')
.replace(/\r/g, '|r')
.replace(/\u0085/g, '|x')
.replace(/\u2028/g, '|l')
.replace(/\u2029/g, '|p')
.replace(/\[/g, '|[')
.replace(/]/g, '|]')
};

const formatMessage = function () {
const args = Array.prototype.slice.call(arguments);

for (let i = args.length - 1; i > 0; i--) {
args[i] = escapeMessage(args[i])
const hashString = function (s) {
let hash = 0
let i
let chr
let len

if (s === 0) return hash
for (i = 0, len = s.length; i < len; i++) {
chr = s.charCodeAt(i)
hash = ((hash << 5) - hash) + chr
hash |= 0
}

return util.format.apply(null, args) + '\n'
};
return hash
}

// This reporter extends karma-teamcity-reporter
// It is necessary, because karma-teamcity-reporter can't write browser's log
// And additionally it overrides flushLogs, because flushLogs adds redundant spaces after some messages
const KarmaKotlinReporter = function (baseReporterDecorator, config, emitter) {
const teamcityReporter = require("karma-teamcity-reporter")["reporter:teamcity"][1];
teamcityReporter.call(this, baseReporterDecorator);
baseReporterDecorator(this)
const self = this

const formatError = createFormatError(config, emitter)

const END_KOTLIN_TEST = "'--END_KOTLIN_TEST--"

const reporter = this
const initializeBrowser = function (browser) {
reporter.browserResults[browser.id] = {
name: browser.name,
log: [],
consoleCollector: [],
consoleResultCollector: [],
lastSuite: null,
flowId: 'karmaTC' + hashString(browser.name + ((new Date()).getTime())) + browser.id
}
}

const formatError = createFormatError(config, emitter);
this.onRunStart = function (browsers) {
this.write(formatMessage(BLOCK_OPENED, 'JavaScript Unit Tests'))

const END_KOTLIN_TEST = "'--END_KOTLIN_TEST--";
this.browserResults = {}
// Support Karma 0.10 (TODO: remove)
browsers.forEach(initializeBrowser)
}

const tcOnBrowserStart = this.onBrowserStart;
this.onBrowserStart = function (browser) {
tcOnBrowserStart.call(this, browser);
this.browserResults[browser.id].consoleCollector = [];
this.browserResults[browser.id].consoleResultCollector = {};
};
initializeBrowser(browser)
}

const concatenateFqn = function (result) {
return `${result.suite.join(".")}.${result.description}`
Expand All @@ -125,7 +141,7 @@ const KarmaKotlinReporter = function (baseReporterDecorator, config, emitter) {
const browserResult = this.browserResults[browser.id];

if (log.startsWith(END_KOTLIN_TEST)) {
var result = JSON.parse(log.substring(END_KOTLIN_TEST.length, log.length - 1));
const result = JSON.parse(log.substring(END_KOTLIN_TEST.length, log.length - 1));
browserResult.consoleResultCollector[concatenateFqn(result)] = browserResult.consoleCollector;
browserResult.consoleCollector = [];
return
Expand All @@ -136,45 +152,87 @@ const KarmaKotlinReporter = function (baseReporterDecorator, config, emitter) {
}
};

const tcSpecSuccess = this.specSuccess;
this.specSuccess = function (browser, result) {
tcSpecSuccess.call(this, browser, result);

const log = this.getLog(browser, result);
const log = this.getLog(browser, result)
const testName = result.description

const endMessage = log.pop();
log.push(formatMessage(TEST_START, testName))
this.browserResults[browser.id].consoleResultCollector[concatenateFqn(result)].forEach(item => {
log.push(item)
});
log.push(endMessage);
};

log.push(formatMessage(TEST_END, testName, result.time))
}

this.specFailure = function (browser, result) {
const log = this.getLog(browser, result);
const testName = result.description;
const log = this.getLog(browser, result)
const testName = result.description

log.push(formatMessage(TEST_START, testName))

log.push(formatMessage(this.TEST_START, testName));
this.browserResults[browser.id].consoleResultCollector[concatenateFqn(result)].forEach(item => {
log.push(item)
});

log.push(formatMessage(this.TEST_FAILED, testName,
log.push(formatMessage(TEST_FAILED, testName, "FAILED",
result.log
.map(log => formatError(log))
.join('\n\n')
));
log.push(formatMessage(this.TEST_END, testName, result.time));
};

log.push(formatMessage(TEST_END, testName, result.time))
}

this.specSkipped = function (browser, result) {
const log = this.getLog(browser, result)
const testName = result.description

log.push(formatMessage(TEST_IGNORED, testName))
}

this.onRunComplete = function () {
Object.keys(this.browserResults).forEach(function (browserId) {
const browserResult = self.browserResults[browserId]
const log = browserResult.log
if (browserResult.lastSuite) {
log.push(formatMessage(SUITE_END, browserResult.lastSuite))
}

self.flushLogs(browserResult)
})
self.write(formatMessage(BLOCK_CLOSED, 'JavaScript Unit Tests'))
}

this.getLog = function (browser, result) {
const browserResult = this.browserResults[browser.id]
let suiteName = browser.name
const moduleName = result.suite.join(' ')

if (moduleName) {
suiteName = moduleName.concat('.', suiteName)
}

const log = browserResult.log
if (browserResult.lastSuite !== suiteName) {
if (browserResult.lastSuite) {
log.push(formatMessage(SUITE_END, browserResult.lastSuite))
}
this.flushLogs(browserResult)
browserResult.lastSuite = suiteName
log.push(formatMessage(SUITE_START, suiteName))
}
return log
}

this.flushLogs = function (browserResult) {
while (browserResult.log.length > 0) {
let line = browserResult.log.shift();
line = line.replace("flowId=''", "flowId='" + browserResult.flowId + "'");
line = line.replace("flowId='%s'", "flowId='" + browserResult.flowId + "'");

this.write(line);
}
}
};
}

KarmaKotlinReporter.$inject = ['baseReporterDecorator', 'config', 'emitter'];

Expand Down
Loading

0 comments on commit b55226e

Please sign in to comment.