jest-teamcity
Advanced tools
Comparing version 1.11.0 to 1.12.0
@@ -14,6 +14,12 @@ [ | ||
{ "ancestorTitles": ["path2", "to", "test4"], "title": "title4", "status": "failed", "duration": 123 }, | ||
{ "ancestorTitles": ["path2", "to", "test5"], "title": "title5", "status": "failed", "failureMessages": ["Unexpected exception\n at path/to/file1.js:1\n at path/to/file2.js:2"], "duration": 123 }, | ||
{ | ||
"ancestorTitles": ["path2", "to", "test5"], | ||
"title": "title5", | ||
"status": "failed", | ||
"failureMessages": ["Unexpected exception\n at path/to/file1.js:1\n at path/to/file2.js:2"], | ||
"duration": 123 | ||
}, | ||
{ "ancestorTitles": ["path2", "to", "constructor"], "title": "title6", "status": "passed", "duration": 123 } | ||
] | ||
} | ||
] | ||
] |
@@ -37,3 +37,5 @@ "use strict"; | ||
["##teamcity[testStarted name='title5' flowId='12345']"], | ||
["##teamcity[testFailed name='title5' message='Unexpected exception' details='at path/to/file1.js:1|n at path/to/file2.js:2' flowId='12345']"], | ||
[ | ||
"##teamcity[testFailed name='title5' message='Unexpected exception' details='at path/to/file1.js:1|n at path/to/file2.js:2' flowId='12345']", | ||
], | ||
["##teamcity[testFinished name='title5' duration='123' flowId='12345']"], | ||
@@ -47,3 +49,3 @@ ["##teamcity[testSuiteFinished name='test5' flowId='12345']"], | ||
["##teamcity[testSuiteFinished name='path2' flowId='12345']"], | ||
["##teamcity[testSuiteFinished name='foo/__tests__/file2.js' flowId='12345']"] | ||
["##teamcity[testSuiteFinished name='foo/__tests__/file2.js' flowId='12345']"], | ||
]; | ||
@@ -57,4 +59,4 @@ | ||
beforeAll(() => { | ||
console.log = jest.fn().mockImplementation(s => s); | ||
const formatterMock = path.sep == "/" ? s => formatterFn(s) : s => formatterFn(s.replace(/\\/g, "/")); | ||
console.log = jest.fn().mockImplementation((s) => s); | ||
const formatterMock = path.sep == "/" ? (s) => formatterFn(s) : (s) => formatterFn(s.replace(/\\/g, "/")); | ||
formatter.log = jest.fn().mockImplementation(formatterMock); | ||
@@ -83,3 +85,3 @@ }); | ||
formatter.escape(`|test[test2]| | ||
test3`) | ||
test3`), | ||
).toEqual("||test|[test2|]|||ntest3"); | ||
@@ -91,3 +93,3 @@ }); | ||
test("empty tests", () => { | ||
["", null, undefined, {}, [], 0].forEach(data => { | ||
["", null, undefined, {}, [], 0].forEach((data) => { | ||
formatter.printTestLog(data); | ||
@@ -126,5 +128,5 @@ expect(console.log.mock.calls).toHaveLength(0); | ||
test1: expect.any(Object), | ||
test2: expect.any(Object) | ||
}) | ||
}) | ||
test2: expect.any(Object), | ||
}), | ||
}), | ||
}, | ||
@@ -135,6 +137,6 @@ [file2Key]: { | ||
test3: expect.any(Object), | ||
test4: expect.any(Object) | ||
}) | ||
}) | ||
} | ||
test4: expect.any(Object), | ||
}), | ||
}), | ||
}, | ||
}); | ||
@@ -150,15 +152,24 @@ }); | ||
test("textExecError", () => { | ||
formatter.formatReport([{ | ||
"testFilePath": "/Users/spec-with-error/failing.spec.ts", | ||
"testResults": [], | ||
"testExecError": { | ||
"message": "Error:\nSomething bad is happened!", | ||
"stack": "Error: Timeout of 181000 waiting for jest process 168 reached!\nThat means that your test suite, the spec file, took too much time to execute. Try spliting the spec to multiple specs.\n at Timeout._onTimeout (evalmachine.<anonymous>:1901:31)\n at listOnTimeout (internal/timers.js:549:17)\n at processTimers (internal/timers.js:492:7)", | ||
"type": "Error" | ||
} | ||
}], "/Users/spec-with-error", "12345"); | ||
formatter.formatReport( | ||
[ | ||
{ | ||
testFilePath: "/Users/spec-with-error/failing.spec.ts", | ||
testResults: [], | ||
testExecError: { | ||
message: "Error:\nSomething bad is happened!", | ||
stack: | ||
"Error: Timeout of 181000 waiting for jest process 168 reached!\nThat means that your test suite, the spec file, took too much time to execute. Try spliting the spec to multiple specs.\n at Timeout._onTimeout (evalmachine.<anonymous>:1901:31)\n at listOnTimeout (internal/timers.js:549:17)\n at processTimers (internal/timers.js:492:7)", | ||
type: "Error", | ||
}, | ||
}, | ||
], | ||
"/Users/spec-with-error", | ||
"12345", | ||
); | ||
expect(console.log.mock.calls).toEqual([ | ||
["##teamcity[testSuiteStarted name='failing.spec.ts' flowId='12345']"], | ||
["##teamcity[testStarted name='Jest failed to execute suite' flowId='12345']"], | ||
["##teamcity[testFailed name='Jest failed to execute suite' message='Error:|nSomething bad is happened!' details='Error: Timeout of 181000 waiting for jest process 168 reached!|nThat means that your test suite, the spec file, took too much time to execute. Try spliting the spec to multiple specs.|n at Timeout._onTimeout (evalmachine.<anonymous>:1901:31)|n at listOnTimeout (internal/timers.js:549:17)|n at processTimers (internal/timers.js:492:7)' flowId='12345']"], | ||
[ | ||
"##teamcity[testFailed name='Jest failed to execute suite' message='Error:|nSomething bad is happened!' details='Error: Timeout of 181000 waiting for jest process 168 reached!|nThat means that your test suite, the spec file, took too much time to execute. Try spliting the spec to multiple specs.|n at Timeout._onTimeout (evalmachine.<anonymous>:1901:31)|n at listOnTimeout (internal/timers.js:549:17)|n at processTimers (internal/timers.js:492:7)' flowId='12345']", | ||
], | ||
["##teamcity[testFinished name='Jest failed to execute suite' duration='0' flowId='12345']"], | ||
@@ -165,0 +176,0 @@ ["##teamcity[testSuiteFinished name='failing.spec.ts' flowId='12345']"], |
@@ -32,3 +32,5 @@ const consoleOutput = [ | ||
["##teamcity[testStarted name='title5' flowId='12345']"], | ||
["##teamcity[testFailed name='title5' message='Unexpected exception' details='at path/to/file1.js:1|n at path/to/file2.js:2' flowId='12345']"], | ||
[ | ||
"##teamcity[testFailed name='title5' message='Unexpected exception' details='at path/to/file1.js:1|n at path/to/file2.js:2' flowId='12345']", | ||
], | ||
["##teamcity[testFinished name='title5' duration='123' flowId='12345']"], | ||
@@ -42,3 +44,3 @@ ["##teamcity[testSuiteFinished name='test5' flowId='12345']"], | ||
["##teamcity[testSuiteFinished name='path2' flowId='12345']"], | ||
["##teamcity[testSuiteFinished name='foo/__tests__/file2.js' flowId='12345']"] | ||
["##teamcity[testSuiteFinished name='foo/__tests__/file2.js' flowId='12345']"], | ||
]; | ||
@@ -51,3 +53,3 @@ const testData = require("./data"); | ||
process.env.TEAMCITY_FLOWID = 12345; | ||
console.log = jest.fn().mockImplementation(s => s); | ||
console.log = jest.fn().mockImplementation((s) => s); | ||
}); | ||
@@ -64,3 +66,3 @@ | ||
const originalCwd = process.cwd(); | ||
process.cwd = function() { | ||
process.cwd = function () { | ||
return "/Users/test"; | ||
@@ -67,0 +69,0 @@ }; |
#CHANGELOG | ||
## 1.5.0 - 2019-10-07 | ||
### Changed | ||
- Updated dependencies | ||
@@ -9,25 +12,37 @@ - Add Prettier | ||
## 1.4.0 - 2019-02-05 | ||
### Changed | ||
- Updated dependencies | ||
## 1.3.0 - 2017-06-27 | ||
### Fixed | ||
- Fixed issue with doing exit(1) in case of failed test suites | ||
## 1.2.1, 1.2.2 - 2017-06-26 | ||
### Removed | ||
- Removed captureStandardOutput attr from report in order to allow test suite do exist(1) | ||
## 1.2.0 - 2017-05-18 | ||
### Added | ||
- Included filename into suite hierarchy | ||
## 1.1.0 - 2017-05-04 | ||
### Added | ||
- covered with Unit Tests | ||
### Removed | ||
- Removed `parsec` dependency | ||
### Changed | ||
- Use `TEAMCITY_VERSION` env param instead of using `--teamcity` to activate a reporter | ||
@@ -37,4 +52,6 @@ - Updated usage section in README.md | ||
## 1.0.0 - 2016-12-25 | ||
### Added | ||
- Formatter module | ||
- Use `--teamcity` params to enable reporter |
@@ -37,6 +37,6 @@ "use strict"; | ||
if (tests) { | ||
Object.keys(tests).forEach(suiteName => { | ||
Object.keys(tests).forEach((suiteName) => { | ||
if (suiteName === "_tests_") { | ||
// print test details | ||
tests[suiteName].forEach(test => { | ||
tests[suiteName].forEach((test) => { | ||
this.log(`##teamcity[testStarted name='${this.escape(test.title)}' flowId='${flowId}']`); | ||
@@ -46,8 +46,8 @@ switch (test.status) { | ||
if (test.failureMessages) { | ||
test.failureMessages.forEach(error => { | ||
test.failureMessages.forEach((error) => { | ||
const [message, ...stack] = error.split(errorMessageStackSeparator); | ||
this.log( | ||
`##teamcity[testFailed name='${this.escape(test.title)}' message='${this.escape( | ||
message | ||
)}' details='${this.escape(stack.join(errorMessageStackSeparator))}' flowId='${flowId}']` | ||
message, | ||
)}' details='${this.escape(stack.join(errorMessageStackSeparator))}' flowId='${flowId}']`, | ||
); | ||
@@ -62,3 +62,3 @@ }); | ||
this.log( | ||
`##teamcity[testIgnored name='${this.escape(test.title)}' message='pending' flowId='${flowId}']` | ||
`##teamcity[testIgnored name='${this.escape(test.title)}' message='pending' flowId='${flowId}']`, | ||
); | ||
@@ -72,3 +72,3 @@ break; | ||
test.duration | ||
}' flowId='${flowId}']` | ||
}' flowId='${flowId}']`, | ||
); | ||
@@ -78,5 +78,3 @@ }); | ||
// print suite names | ||
this.log(`##teamcity[testSuiteStarted name='${this.escape(suiteName)}' flowId='${flowId}']`); | ||
this.printTestLog(tests[suiteName], flowId); | ||
this.log(`##teamcity[testSuiteFinished name='${this.escape(suiteName)}' flowId='${flowId}']`); | ||
this.printSuiteBlock(suiteName, flowId, () => this.printTestLog(tests[suiteName], flowId)); | ||
} | ||
@@ -109,5 +107,5 @@ }); | ||
const suites = {}; | ||
testResults.forEach(testFile => { | ||
testResults.forEach((testFile) => { | ||
const filename = path.relative(cwd, testFile.testFilePath); | ||
testFile.testResults.forEach(test => { | ||
testFile.testResults.forEach((test) => { | ||
const path = [filename].concat(test.ancestorTitles); | ||
@@ -135,8 +133,12 @@ | ||
suites[filename] = suites[filename] || {}; | ||
suites[filename]['_tests_'] = [{ | ||
status: 'failed', | ||
title: 'Jest failed to execute suite', | ||
duration: 0, | ||
failureMessages: [`${testFile.testExecError.message}${errorMessageStackSeparator}${testFile.testExecError.stack}`], | ||
}]; | ||
suites[filename]["_tests_"] = [ | ||
{ | ||
status: "failed", | ||
title: "Jest failed to execute suite", | ||
duration: 0, | ||
failureMessages: [ | ||
`${testFile.testExecError.message}${errorMessageStackSeparator}${testFile.testExecError.stack}`, | ||
], | ||
}, | ||
]; | ||
} | ||
@@ -149,9 +151,28 @@ }); | ||
/** | ||
* @param {string} suiteName | ||
* @param {string} flowId | ||
* @param {function} printLogFn | ||
*/ | ||
printSuiteBlock(suiteName, flowId, printLogFn) { | ||
this.log(`##teamcity[testSuiteStarted name='${this.escape(suiteName)}' flowId='${flowId}']`); | ||
printLogFn(); | ||
this.log(`##teamcity[testSuiteFinished name='${this.escape(suiteName)}' flowId='${flowId}']`); | ||
}, | ||
/** | ||
* Formats and outputs tests results | ||
* @param {array} testResults | ||
* @param {string} cwd | ||
* @param {string} flowId | ||
* @param {string} [projectSuiteName] | ||
*/ | ||
formatReport(testResults, cwd, flowId) { | ||
formatReport(testResults, cwd, flowId, projectSuiteName) { | ||
const suites = this.collectSuites(testResults, cwd); | ||
this.printTestLog(suites, flowId); | ||
} | ||
if (projectSuiteName) { | ||
this.printSuiteBlock(projectSuiteName, flowId, () => this.printTestLog(suites, flowId)); | ||
} else { | ||
this.printTestLog(suites, flowId); | ||
} | ||
}, | ||
}; |
@@ -7,6 +7,7 @@ /** | ||
module.exports = function(result) { | ||
module.exports = function (result) { | ||
const flowId = process.env.TEAMCITY_FLOWID || process.pid.toString(); | ||
const teamCityVersion = process.env.TEAMCITY_VERSION; | ||
const projectSuiteName = process.env.PROJECT_NAME; | ||
// Constructor call means usage as a Jest reporter | ||
@@ -17,11 +18,11 @@ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new.target | ||
this.onTestResult = (_, result) => { | ||
formatter.formatReport([result], process.cwd(), flowId) | ||
} | ||
formatter.formatReport([result], process.cwd(), flowId, projectSuiteName); | ||
}; | ||
} | ||
return | ||
return; | ||
} | ||
if (teamCityVersion) { | ||
formatter.formatReport(result.testResults, process.cwd(), flowId); | ||
formatter.formatReport(result.testResults, process.cwd(), flowId, projectSuiteName); | ||
} | ||
@@ -28,0 +29,0 @@ |
{ | ||
"name": "jest-teamcity", | ||
"version": "1.11.0", | ||
"version": "1.12.0", | ||
"description": "Teamcity Reporter for Jest Testing framework", | ||
@@ -9,7 +9,8 @@ "homepage": "https://github.com/itereshchenkov/jest-teamcity", | ||
"devDependencies": { | ||
"jest": "^27.5.1", | ||
"prettier": "^2.6.2" | ||
"jest": "^29.7.0", | ||
"prettier": "^3.3.2" | ||
}, | ||
"scripts": { | ||
"test": "jest" | ||
"test": "jest", | ||
"format": "prettier . --write" | ||
}, | ||
@@ -16,0 +17,0 @@ "jest": { |
@@ -10,7 +10,8 @@ # jest-teamcity | ||
* grouping tests by test suites | ||
* output tests duration | ||
* output pending, failed test with message and stack | ||
- grouping tests by test suites | ||
- output tests duration | ||
- output pending, failed test with message and stack | ||
## Install | ||
Install with npm: `npm install --save-dev jest-teamcity` | ||
@@ -21,2 +22,3 @@ | ||
Add this into the jest configuration file: | ||
```javascript | ||
@@ -35,2 +37,3 @@ "reporters": ["default", "jest-teamcity"] | ||
Package.json example: | ||
```javascript | ||
@@ -37,0 +40,0 @@ "scripts": { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
23996
436
47
6