80 lines
2.3 KiB
TypeScript
80 lines
2.3 KiB
TypeScript
export class TeamcityReporter {
|
|
/**
|
|
* Escape special characters for TeamCity service messages
|
|
* https://www.jetbrains.com/help/teamcity/service-messages.html#Escaped+values
|
|
*/
|
|
private static escape(str: string): string {
|
|
return str
|
|
.replace(/\|/g, "||")
|
|
.replace(/'/g, "|'")
|
|
.replace(/\n/g, "|n")
|
|
.replace(/\r/g, "|r")
|
|
.replace(/\[/g, "|[")
|
|
.replace(/]/g, "|]");
|
|
}
|
|
|
|
public static reportSuiteStart(suiteName: string): void {
|
|
console.log(
|
|
`##teamcity[testSuiteStarted name='${this.escape(suiteName)}']`,
|
|
);
|
|
}
|
|
|
|
public static reportSuiteEnd(suiteName: string): void {
|
|
console.log(
|
|
`##teamcity[testSuiteFinished name='${this.escape(suiteName)}']`,
|
|
);
|
|
}
|
|
|
|
public static reportTestStart(testName: string): void {
|
|
console.log(`##teamcity[testStarted name='${this.escape(testName)}']`);
|
|
}
|
|
|
|
public static reportTestFailed(
|
|
testName: string,
|
|
failureMessage: string,
|
|
details: string,
|
|
{
|
|
comparisonFailure,
|
|
expected,
|
|
actual,
|
|
}: { comparisonFailure: boolean; expected: string; actual: string },
|
|
): void {
|
|
const attrs = [
|
|
`name='${this.escape(testName)}'`,
|
|
`message='${this.escape(failureMessage)}'`,
|
|
`details='${this.escape(details)}'`,
|
|
];
|
|
|
|
if (comparisonFailure) {
|
|
attrs.push(`type='comparisonFailure'`);
|
|
attrs.push(`expected='${this.escape(expected)}'`);
|
|
attrs.push(`actual='${this.escape(actual)}'`);
|
|
}
|
|
|
|
console.log(`##teamcity[testFailed ${attrs.join(" ")}]`);
|
|
}
|
|
|
|
public static reportTestEnd(testName: string, duration?: number): void {
|
|
const durationAttr =
|
|
duration !== undefined ? ` duration='${duration}'` : "";
|
|
console.log(
|
|
`##teamcity[testFinished name='${this.escape(testName)}'${durationAttr}]`,
|
|
);
|
|
}
|
|
|
|
public static reportTestError(testName: string, error: Error): void {
|
|
const message = this.escape(error.message || "Unknown error");
|
|
const details = this.escape(error.stack || "");
|
|
console.log(
|
|
`##teamcity[testFailed name='${this.escape(testName)}' message='${message}' details='${details}']`,
|
|
);
|
|
}
|
|
|
|
public static reportTestIgnored(testName: string, message?: string): void {
|
|
const msgAttr = message ? ` message='${this.escape(message)}'` : "";
|
|
console.log(
|
|
`##teamcity[testIgnored name='${this.escape(testName)}'${msgAttr}]`,
|
|
);
|
|
}
|
|
}
|