@toptal/davinci-qa 6.0.2 → 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist-package/package.json +6 -3
- package/package.json +6 -3
- package/src/commands/end-to-end-tests.js +19 -6
- package/src/reporters/anvil-results-helper.js +46 -0
- package/src/reporters/anvil-results-helper.test.js +87 -0
- package/src/reporters/cypress-anvil-reporter.js +121 -0
- package/src/reporters/cypress-anvil-reporter.test.js +269 -0
- package/src/reporters/jest-anvil-reporter.js +54 -45
- package/src/reporters/jest-anvil-reporter.test.js +146 -68
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 7.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- [#1224](https://github.com/toptal/davinci/pull/1224) [`caf0ee02`](https://github.com/toptal/davinci/commit/caf0ee027107be2acf0315deed33ef89d34f6b69) Thanks [@rafael-anachoreta](https://github.com/rafael-anachoreta)! - ---
|
|
8
|
+
|
|
9
|
+
### Anvil reporter
|
|
10
|
+
|
|
11
|
+
- Add Anvil test mapper
|
|
12
|
+
- Add Anvil reporter to Cypress
|
|
13
|
+
- Update Jest Anvil reporter to use new mapper
|
|
14
|
+
|
|
3
15
|
## 6.0.2
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toptal/davinci-qa",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"description": "QA package to test your application",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"@types/jest": "^27.4.1",
|
|
42
42
|
"babel-jest": "^27.5.1",
|
|
43
43
|
"cypress": "^9.4.1",
|
|
44
|
+
"enhanced-resolve": "^5.9.2",
|
|
44
45
|
"fs-extra": "^10.0.0",
|
|
45
46
|
"glob": "^7.2.0",
|
|
46
47
|
"jest": "^27.5.1",
|
|
@@ -50,7 +51,9 @@
|
|
|
50
51
|
"jest-styled-components": "^7.0.8",
|
|
51
52
|
"jsdom": "^19.0.0",
|
|
52
53
|
"matchmedia-polyfill": "^0.3.2",
|
|
53
|
-
"semver": "^7.3.2"
|
|
54
|
-
|
|
54
|
+
"semver": "^7.3.2"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"mocha": "^9.2.2"
|
|
55
58
|
}
|
|
56
59
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toptal/davinci-qa",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.0.0",
|
|
4
4
|
"description": "QA package to test your application",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"@types/jest": "^27.4.1",
|
|
42
42
|
"babel-jest": "^27.5.1",
|
|
43
43
|
"cypress": "^9.4.1",
|
|
44
|
+
"enhanced-resolve": "^5.9.2",
|
|
44
45
|
"fs-extra": "^10.0.0",
|
|
45
46
|
"glob": "^7.2.0",
|
|
46
47
|
"jest": "^27.5.1",
|
|
@@ -50,7 +51,9 @@
|
|
|
50
51
|
"jest-styled-components": "^7.0.8",
|
|
51
52
|
"jsdom": "^19.0.0",
|
|
52
53
|
"matchmedia-polyfill": "^0.3.2",
|
|
53
|
-
"semver": "^7.3.2"
|
|
54
|
-
|
|
54
|
+
"semver": "^7.3.2"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"mocha": "^9.2.2"
|
|
55
58
|
}
|
|
56
59
|
}
|
|
@@ -6,11 +6,7 @@ const {
|
|
|
6
6
|
} = require('@toptal/davinci-cli-shared')
|
|
7
7
|
|
|
8
8
|
const endToEndTestCommand = ({
|
|
9
|
-
options: {
|
|
10
|
-
open = false,
|
|
11
|
-
baseUrl,
|
|
12
|
-
...cypressOptions
|
|
13
|
-
} = {},
|
|
9
|
+
options: { open = false, baseUrl, anvilTag, ...cypressOptions } = {},
|
|
14
10
|
files: testFiles = []
|
|
15
11
|
}) => {
|
|
16
12
|
print.green('Running end to end tests...')
|
|
@@ -19,6 +15,10 @@ const endToEndTestCommand = ({
|
|
|
19
15
|
'@toptal/davinci-qa',
|
|
20
16
|
'src/configs/cypress.config.json'
|
|
21
17
|
)
|
|
18
|
+
const cypressReporterPath = files.getPackageFilePath(
|
|
19
|
+
'@toptal/davinci-qa',
|
|
20
|
+
'src/reporters/cypress-anvil-reporter.js'
|
|
21
|
+
)
|
|
22
22
|
|
|
23
23
|
const mode = open ? 'open' : 'run'
|
|
24
24
|
|
|
@@ -29,6 +29,14 @@ const endToEndTestCommand = ({
|
|
|
29
29
|
configPath,
|
|
30
30
|
...testFiles,
|
|
31
31
|
...(baseUrl ? ['--config', `baseUrl=${baseUrl}`] : []),
|
|
32
|
+
...(!open && anvilTag
|
|
33
|
+
? [
|
|
34
|
+
'--reporter',
|
|
35
|
+
cypressReporterPath,
|
|
36
|
+
'--reporter-options',
|
|
37
|
+
`anvilTag=${anvilTag}`
|
|
38
|
+
]
|
|
39
|
+
: []),
|
|
32
40
|
...convertToCLIParameters(cypressOptions)
|
|
33
41
|
])
|
|
34
42
|
}
|
|
@@ -45,8 +53,13 @@ const endToEndCommandCreator = {
|
|
|
45
53
|
name: '--open'
|
|
46
54
|
},
|
|
47
55
|
{
|
|
48
|
-
label:
|
|
56
|
+
label: "URL used as prefix for cy.visit() or cy.request() command's URL",
|
|
49
57
|
name: '--baseUrl <baseUrl>'
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
label:
|
|
61
|
+
"the project name matching Anvil's expected tag to generate Anvil Reports",
|
|
62
|
+
name: '--anvilTag <anvilTag>'
|
|
50
63
|
}
|
|
51
64
|
]
|
|
52
65
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const { print } = require('@toptal/davinci-cli-shared')
|
|
2
|
+
const fs = require('fs-extra')
|
|
3
|
+
|
|
4
|
+
const anvilMapper = ({
|
|
5
|
+
fileName,
|
|
6
|
+
lineNumber,
|
|
7
|
+
status,
|
|
8
|
+
durationInSeconds,
|
|
9
|
+
scenarioName,
|
|
10
|
+
description,
|
|
11
|
+
error,
|
|
12
|
+
backtrace,
|
|
13
|
+
testType,
|
|
14
|
+
pendingMessage,
|
|
15
|
+
tag
|
|
16
|
+
}) => ({
|
|
17
|
+
file_name: fileName,
|
|
18
|
+
line_number: lineNumber,
|
|
19
|
+
status: status === 'todo' ? 'pending' : status,
|
|
20
|
+
duration: durationInSeconds,
|
|
21
|
+
scenario_name: scenarioName,
|
|
22
|
+
description,
|
|
23
|
+
error,
|
|
24
|
+
backtrace,
|
|
25
|
+
test_type: testType,
|
|
26
|
+
pending_message: pendingMessage,
|
|
27
|
+
tag
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
const generateAnvilResults = (fileName, testResults) => {
|
|
31
|
+
const reportPath = './reports'
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
fs.ensureDirSync(reportPath)
|
|
35
|
+
fs.writeJsonSync(`${reportPath}/${fileName}`, testResults)
|
|
36
|
+
print.green('[anvil-reporter] Anvil reports generated successfully!')
|
|
37
|
+
} catch (err) {
|
|
38
|
+
print.red('[anvil-reporter] Failed to create Anvil test results!', err)
|
|
39
|
+
throw err
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = {
|
|
44
|
+
anvilMapper,
|
|
45
|
+
generateAnvilResults
|
|
46
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const fs = require('fs-extra')
|
|
2
|
+
const { print } = require('@toptal/davinci-cli-shared')
|
|
3
|
+
|
|
4
|
+
const { anvilMapper, generateAnvilResults } = require('./anvil-results-helper')
|
|
5
|
+
|
|
6
|
+
describe('Anvil results helper', () => {
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
jest.resetModules()
|
|
9
|
+
jest.resetAllMocks()
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
describe('anvilMapper', () => {
|
|
13
|
+
it('outputs an Anvil-compatible object', () => {
|
|
14
|
+
const mappedValue = anvilMapper({
|
|
15
|
+
fileName:
|
|
16
|
+
'/davinci/packages/qa/src/reporters/jest-anvil-reporter-mocker.test.js',
|
|
17
|
+
backtrace: null,
|
|
18
|
+
description: '1 + 1 returns 2',
|
|
19
|
+
durationInSeconds: 0.003,
|
|
20
|
+
error: null,
|
|
21
|
+
lineNumber: 2,
|
|
22
|
+
pendingMessage: null,
|
|
23
|
+
scenarioName: 'Example test suite/1 + 1 returns 2',
|
|
24
|
+
status: 'passed',
|
|
25
|
+
tag: 'platform',
|
|
26
|
+
testType: 'unit'
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
expect(mappedValue).toEqual({
|
|
30
|
+
file_name:
|
|
31
|
+
'/davinci/packages/qa/src/reporters/jest-anvil-reporter-mocker.test.js',
|
|
32
|
+
line_number: 2,
|
|
33
|
+
status: 'passed',
|
|
34
|
+
duration: 0.003,
|
|
35
|
+
scenario_name: 'Example test suite/1 + 1 returns 2',
|
|
36
|
+
description: '1 + 1 returns 2',
|
|
37
|
+
error: null,
|
|
38
|
+
backtrace: null,
|
|
39
|
+
test_type: 'unit',
|
|
40
|
+
pending_message: null,
|
|
41
|
+
tag: 'platform'
|
|
42
|
+
})
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('converts "todo" status to pending', () => {
|
|
46
|
+
const mappedValue = anvilMapper({ status: 'todo' })
|
|
47
|
+
|
|
48
|
+
expect(mappedValue.status).toBe('pending')
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
describe('generateAnvilResults', () => {
|
|
53
|
+
it('creates a report with the data passed in', () => {
|
|
54
|
+
const writeJsonMock = jest.spyOn(fs, 'writeJsonSync')
|
|
55
|
+
const printMock = jest.spyOn(print, 'green')
|
|
56
|
+
|
|
57
|
+
generateAnvilResults('anvil_cypress_test_results.json', { test: 123 })
|
|
58
|
+
|
|
59
|
+
expect(writeJsonMock).toHaveBeenCalledWith(
|
|
60
|
+
'./reports/anvil_cypress_test_results.json',
|
|
61
|
+
{ test: 123 }
|
|
62
|
+
)
|
|
63
|
+
expect(printMock).toHaveBeenCalledWith(
|
|
64
|
+
'[anvil-reporter] Anvil reports generated successfully!'
|
|
65
|
+
)
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('throws an error when unable to create report', () => {
|
|
69
|
+
const mockError = new Error('My error!')
|
|
70
|
+
|
|
71
|
+
jest.spyOn(fs, 'ensureDirSync').mockImplementation(() => {
|
|
72
|
+
throw mockError
|
|
73
|
+
})
|
|
74
|
+
const printMock = jest.spyOn(print, 'red')
|
|
75
|
+
|
|
76
|
+
expect(() =>
|
|
77
|
+
generateAnvilResults('anvil_cypress_test_results.json', { test: 123 })
|
|
78
|
+
).toThrow()
|
|
79
|
+
|
|
80
|
+
expect(printMock).toHaveBeenCalledTimes(1)
|
|
81
|
+
expect(printMock).toHaveBeenCalledWith(
|
|
82
|
+
'[anvil-reporter] Failed to create Anvil test results!',
|
|
83
|
+
mockError
|
|
84
|
+
)
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
})
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
const { print } = require('@toptal/davinci-cli-shared')
|
|
2
|
+
const { Runner, reporters } = require('mocha')
|
|
3
|
+
|
|
4
|
+
const { anvilMapper, generateAnvilResults } = require('./anvil-results-helper')
|
|
5
|
+
|
|
6
|
+
const { Spec, Base } = reporters
|
|
7
|
+
const {
|
|
8
|
+
EVENT_RUN_END,
|
|
9
|
+
EVENT_TEST_FAIL,
|
|
10
|
+
EVENT_TEST_PASS,
|
|
11
|
+
EVENT_TEST_PENDING,
|
|
12
|
+
EVENT_TEST_RETRY
|
|
13
|
+
} = Runner.constants
|
|
14
|
+
|
|
15
|
+
class CypressAnvilReporter extends Base {
|
|
16
|
+
constructor(runner, options) {
|
|
17
|
+
super(runner, options)
|
|
18
|
+
const tests = []
|
|
19
|
+
const joinParentTitles = obj =>
|
|
20
|
+
obj?.parent?.title
|
|
21
|
+
? `${joinParentTitles(obj.parent)}/${obj.title}`
|
|
22
|
+
: obj.title
|
|
23
|
+
|
|
24
|
+
// Spec is Cypress's default reporter, but it misses retries
|
|
25
|
+
this._specReporter = new Spec(
|
|
26
|
+
runner.on(EVENT_TEST_RETRY, test => {
|
|
27
|
+
print.yellow(
|
|
28
|
+
`(Attempt ${test?.currentRetry + 1} of ${test?.retries}) ${
|
|
29
|
+
test?.title
|
|
30
|
+
}`
|
|
31
|
+
)
|
|
32
|
+
}),
|
|
33
|
+
options
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
const anvilTag = options?.reporterOptions?.anvilTag
|
|
37
|
+
|
|
38
|
+
if (!anvilTag) {
|
|
39
|
+
print.yellow(
|
|
40
|
+
"[anvil-reporter] --anvilTag option is missing! anvil_cypress_test_results.json won't be generated."
|
|
41
|
+
)
|
|
42
|
+
} else {
|
|
43
|
+
runner
|
|
44
|
+
.on(EVENT_TEST_PASS, test => {
|
|
45
|
+
tests.push(
|
|
46
|
+
anvilMapper({
|
|
47
|
+
fileName: test?.invocationDetails?.absoluteFile,
|
|
48
|
+
lineNumber: test?.invocationDetails?.line,
|
|
49
|
+
status: test?.state,
|
|
50
|
+
durationInSeconds: test?.duration / 1000,
|
|
51
|
+
scenarioName: joinParentTitles(test),
|
|
52
|
+
description: test?.title,
|
|
53
|
+
error: test?.err?.message || null,
|
|
54
|
+
backtrace: test?.err?.stack || null,
|
|
55
|
+
testType: 'integration',
|
|
56
|
+
pendingMessage: null,
|
|
57
|
+
tag: anvilTag
|
|
58
|
+
})
|
|
59
|
+
)
|
|
60
|
+
})
|
|
61
|
+
.on(EVENT_TEST_FAIL, test => {
|
|
62
|
+
tests.push(
|
|
63
|
+
anvilMapper({
|
|
64
|
+
fileName: test?.invocationDetails?.absoluteFile,
|
|
65
|
+
lineNumber: test?.invocationDetails?.line,
|
|
66
|
+
status: test?.state,
|
|
67
|
+
durationInSeconds: test?.duration / 1000,
|
|
68
|
+
scenarioName: joinParentTitles(test),
|
|
69
|
+
description: test?.title,
|
|
70
|
+
error: test?.err?.message || null,
|
|
71
|
+
backtrace: test?.err?.stack || null,
|
|
72
|
+
testType: 'integration',
|
|
73
|
+
pendingMessage: null,
|
|
74
|
+
tag: anvilTag
|
|
75
|
+
})
|
|
76
|
+
)
|
|
77
|
+
})
|
|
78
|
+
.on(EVENT_TEST_PENDING, test => {
|
|
79
|
+
tests.push(
|
|
80
|
+
anvilMapper({
|
|
81
|
+
fileName: test?.invocationDetails?.absoluteFile,
|
|
82
|
+
lineNumber: test?.invocationDetails?.line,
|
|
83
|
+
status: test?.state,
|
|
84
|
+
durationInSeconds: 0,
|
|
85
|
+
scenarioName: joinParentTitles(test),
|
|
86
|
+
description: test?.title,
|
|
87
|
+
error: test?.err?.message || null,
|
|
88
|
+
backtrace: test?.err?.stack || null,
|
|
89
|
+
testType: 'integration',
|
|
90
|
+
pendingMessage: null,
|
|
91
|
+
tag: anvilTag
|
|
92
|
+
})
|
|
93
|
+
)
|
|
94
|
+
})
|
|
95
|
+
.on(EVENT_TEST_RETRY, test => {
|
|
96
|
+
tests.push(
|
|
97
|
+
anvilMapper({
|
|
98
|
+
fileName: test?.invocationDetails?.absoluteFile,
|
|
99
|
+
lineNumber: test?.invocationDetails?.line,
|
|
100
|
+
status: 'retried',
|
|
101
|
+
durationInSeconds: test?.duration / 1000,
|
|
102
|
+
scenarioName: joinParentTitles(test),
|
|
103
|
+
description: test?.title,
|
|
104
|
+
error: test?.err?.message || null,
|
|
105
|
+
backtrace: test?.err?.stack || null,
|
|
106
|
+
testType: 'integration',
|
|
107
|
+
pendingMessage: null,
|
|
108
|
+
tag: anvilTag
|
|
109
|
+
})
|
|
110
|
+
)
|
|
111
|
+
})
|
|
112
|
+
.once(EVENT_RUN_END, () => {
|
|
113
|
+
generateAnvilResults('anvil_cypress_test_results.json', {
|
|
114
|
+
test_results: tests
|
|
115
|
+
})
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
module.exports = CypressAnvilReporter
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/* eslint-disable jest/no-done-callback */
|
|
2
|
+
// If you need to extend these tests, have a look at these other reporters for inspiration:
|
|
3
|
+
// - https://github.com/adamgruber/mochawesome/blob/963f073fe3f4522070788a702329dd6b61014df3/test/reporter.test.js
|
|
4
|
+
// - https://github.com/michaelleeallen/mocha-junit-reporter/blob/3b65764449f6f3a0ec6f54da5842a2a21d788382/test/mocha-junit-reporter-spec.js#L176
|
|
5
|
+
const generateAnvilResultsMock = jest.fn()
|
|
6
|
+
|
|
7
|
+
jest.mock('./anvil-results-helper', () => ({
|
|
8
|
+
...jest.requireActual('./anvil-results-helper'),
|
|
9
|
+
generateAnvilResults: generateAnvilResultsMock
|
|
10
|
+
}))
|
|
11
|
+
const { print } = require('@toptal/davinci-cli-shared')
|
|
12
|
+
const Mocha = require('mocha')
|
|
13
|
+
const { AssertionError } = require('assert')
|
|
14
|
+
|
|
15
|
+
const CypressAnvilReporter = require('./cypress-anvil-reporter')
|
|
16
|
+
|
|
17
|
+
const { Runner, Suite, Test } = Mocha
|
|
18
|
+
|
|
19
|
+
const createRunner = suite => {
|
|
20
|
+
const runner = new Runner(suite)
|
|
21
|
+
|
|
22
|
+
runner.stats = {
|
|
23
|
+
passes: 0,
|
|
24
|
+
duration: 0
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return runner
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const configureReporter = (runner, reporter, options = {}) => {
|
|
31
|
+
const mocha = new Mocha({
|
|
32
|
+
reporter: reporter,
|
|
33
|
+
allowUncaught: true
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
new mocha._reporter(runner, {
|
|
37
|
+
reporterOptions: options
|
|
38
|
+
})
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
describe('Cypress Anvil reporter', () => {
|
|
42
|
+
const rootSuiteName = 'my root suite'
|
|
43
|
+
const testName = 'my test'
|
|
44
|
+
const anvilTag = 'talent_portal'
|
|
45
|
+
|
|
46
|
+
beforeEach(() => {
|
|
47
|
+
jest.resetModules()
|
|
48
|
+
jest.resetAllMocks()
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('generates an Anvil-compatible report when anvilTag is set', done => {
|
|
52
|
+
const suite = new Suite(rootSuiteName, 'root').addTest(
|
|
53
|
+
new Test(testName, () => {})
|
|
54
|
+
)
|
|
55
|
+
const runner = createRunner(suite)
|
|
56
|
+
|
|
57
|
+
configureReporter(runner, CypressAnvilReporter, { anvilTag })
|
|
58
|
+
|
|
59
|
+
runner.run(failures => {
|
|
60
|
+
expect(failures).toBe(0)
|
|
61
|
+
expect(generateAnvilResultsMock).toHaveBeenCalledWith(
|
|
62
|
+
'anvil_cypress_test_results.json',
|
|
63
|
+
{
|
|
64
|
+
test_results: [
|
|
65
|
+
{
|
|
66
|
+
status: 'passed',
|
|
67
|
+
duration: expect.any(Number),
|
|
68
|
+
scenario_name: `${rootSuiteName}/${testName}`,
|
|
69
|
+
description: testName,
|
|
70
|
+
error: null,
|
|
71
|
+
backtrace: null,
|
|
72
|
+
test_type: 'integration',
|
|
73
|
+
pending_message: null,
|
|
74
|
+
tag: anvilTag
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
done()
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
it('does not generate a report if anvilTag is not specified', done => {
|
|
85
|
+
const printSpy = jest.spyOn(print, 'yellow')
|
|
86
|
+
const suite = new Suite(rootSuiteName, 'root').addTest(
|
|
87
|
+
new Test(testName, () => {})
|
|
88
|
+
)
|
|
89
|
+
const runner = createRunner(suite)
|
|
90
|
+
|
|
91
|
+
configureReporter(runner, CypressAnvilReporter)
|
|
92
|
+
|
|
93
|
+
runner.run(() => {
|
|
94
|
+
expect(printSpy).toHaveBeenCalledWith(
|
|
95
|
+
expect.stringContaining(
|
|
96
|
+
"[anvil-reporter] --anvilTag option is missing! anvil_cypress_test_results.json won't be generated."
|
|
97
|
+
)
|
|
98
|
+
)
|
|
99
|
+
expect(generateAnvilResultsMock).not.toHaveBeenCalled()
|
|
100
|
+
|
|
101
|
+
done()
|
|
102
|
+
})
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
it('returns the scenario name with all parents listed', done => {
|
|
106
|
+
const grandchildSuiteName = 'my grandchild suite'
|
|
107
|
+
const childSuiteName = 'my child suite'
|
|
108
|
+
|
|
109
|
+
const grandchildSuite = new Suite(grandchildSuiteName, 'root').addTest(
|
|
110
|
+
new Test(testName, () => {})
|
|
111
|
+
)
|
|
112
|
+
const childSuite = new Suite(childSuiteName, 'root').addSuite(
|
|
113
|
+
grandchildSuite
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
new Suite(rootSuiteName, 'root').addSuite(childSuite)
|
|
117
|
+
|
|
118
|
+
const runner = createRunner(grandchildSuite)
|
|
119
|
+
|
|
120
|
+
configureReporter(runner, CypressAnvilReporter, { anvilTag })
|
|
121
|
+
|
|
122
|
+
runner.run(failures => {
|
|
123
|
+
expect(failures).toBe(0)
|
|
124
|
+
expect(generateAnvilResultsMock).toHaveBeenCalledWith(
|
|
125
|
+
'anvil_cypress_test_results.json',
|
|
126
|
+
{
|
|
127
|
+
test_results: [
|
|
128
|
+
{
|
|
129
|
+
status: 'passed',
|
|
130
|
+
duration: expect.any(Number),
|
|
131
|
+
scenario_name: `${rootSuiteName}/${childSuiteName}/${grandchildSuiteName}/${testName}`,
|
|
132
|
+
description: testName,
|
|
133
|
+
error: null,
|
|
134
|
+
backtrace: null,
|
|
135
|
+
test_type: 'integration',
|
|
136
|
+
pending_message: null,
|
|
137
|
+
tag: anvilTag
|
|
138
|
+
}
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
done()
|
|
144
|
+
})
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
it('returns errors and backtrace when tests fail', done => {
|
|
148
|
+
const errorMessage = 'Expected foo, got bar'
|
|
149
|
+
const suite = new Suite(rootSuiteName, 'root').addTest(
|
|
150
|
+
new Test(testName, callback => {
|
|
151
|
+
callback(new AssertionError({ message: errorMessage }))
|
|
152
|
+
})
|
|
153
|
+
)
|
|
154
|
+
const runner = createRunner(suite)
|
|
155
|
+
|
|
156
|
+
configureReporter(runner, CypressAnvilReporter, { anvilTag })
|
|
157
|
+
|
|
158
|
+
runner.run(failures => {
|
|
159
|
+
expect(failures).toBe(1)
|
|
160
|
+
expect(generateAnvilResultsMock).toHaveBeenCalledWith(
|
|
161
|
+
'anvil_cypress_test_results.json',
|
|
162
|
+
{
|
|
163
|
+
test_results: [
|
|
164
|
+
{
|
|
165
|
+
status: 'failed',
|
|
166
|
+
duration: expect.any(Number),
|
|
167
|
+
scenario_name: `${rootSuiteName}/${testName}`,
|
|
168
|
+
description: testName,
|
|
169
|
+
error: errorMessage,
|
|
170
|
+
backtrace: expect.stringMatching(
|
|
171
|
+
new RegExp(
|
|
172
|
+
`AssertionError.*${errorMessage}.*at new AssertionError`,
|
|
173
|
+
'gms'
|
|
174
|
+
)
|
|
175
|
+
),
|
|
176
|
+
test_type: 'integration',
|
|
177
|
+
pending_message: null,
|
|
178
|
+
tag: anvilTag
|
|
179
|
+
}
|
|
180
|
+
]
|
|
181
|
+
}
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
done()
|
|
185
|
+
})
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
it('supports retried tests', done => {
|
|
189
|
+
const suite = new Suite(rootSuiteName, 'root').retries(2).addTest(
|
|
190
|
+
new Test(testName, callback => {
|
|
191
|
+
expect(1).toBe(2)
|
|
192
|
+
|
|
193
|
+
callback()
|
|
194
|
+
})
|
|
195
|
+
)
|
|
196
|
+
const runner = createRunner(suite)
|
|
197
|
+
|
|
198
|
+
configureReporter(runner, CypressAnvilReporter, { anvilTag })
|
|
199
|
+
|
|
200
|
+
runner.run(failures => {
|
|
201
|
+
expect(failures).toBe(1)
|
|
202
|
+
expect(generateAnvilResultsMock).toHaveBeenCalledWith(
|
|
203
|
+
'anvil_cypress_test_results.json',
|
|
204
|
+
{
|
|
205
|
+
test_results: [
|
|
206
|
+
{
|
|
207
|
+
status: 'retried',
|
|
208
|
+
duration: expect.any(Number),
|
|
209
|
+
scenario_name: `${rootSuiteName}/${testName}`,
|
|
210
|
+
description: testName,
|
|
211
|
+
error: null,
|
|
212
|
+
backtrace: null,
|
|
213
|
+
test_type: 'integration',
|
|
214
|
+
pending_message: null,
|
|
215
|
+
tag: anvilTag
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
status: 'retried',
|
|
219
|
+
duration: expect.any(Number),
|
|
220
|
+
scenario_name: `${rootSuiteName}/${testName}`,
|
|
221
|
+
description: testName,
|
|
222
|
+
error: null,
|
|
223
|
+
backtrace: null,
|
|
224
|
+
test_type: 'integration',
|
|
225
|
+
pending_message: null,
|
|
226
|
+
tag: anvilTag
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
status: 'failed',
|
|
230
|
+
duration: expect.any(Number),
|
|
231
|
+
scenario_name: `${rootSuiteName}/${testName}`,
|
|
232
|
+
description: testName,
|
|
233
|
+
error: expect.anything(),
|
|
234
|
+
backtrace: expect.anything(),
|
|
235
|
+
test_type: 'integration',
|
|
236
|
+
pending_message: null,
|
|
237
|
+
tag: anvilTag
|
|
238
|
+
}
|
|
239
|
+
]
|
|
240
|
+
}
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
done()
|
|
244
|
+
})
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
it('calls the anvil test result mapper', done => {
|
|
248
|
+
const anvilMapperSpy = jest.fn()
|
|
249
|
+
|
|
250
|
+
jest.mock('./anvil-results-helper', () => ({
|
|
251
|
+
anvilMapper: anvilMapperSpy,
|
|
252
|
+
generateAnvilResults: jest.fn()
|
|
253
|
+
}))
|
|
254
|
+
const CypressAnvilReporter = require('./cypress-anvil-reporter')
|
|
255
|
+
|
|
256
|
+
const suite = new Suite('My suite', 'root').addTest(
|
|
257
|
+
new Test('My test', () => {})
|
|
258
|
+
)
|
|
259
|
+
const runner = createRunner(suite)
|
|
260
|
+
|
|
261
|
+
configureReporter(runner, CypressAnvilReporter, { anvilTag })
|
|
262
|
+
|
|
263
|
+
runner.run(() => {
|
|
264
|
+
expect(anvilMapperSpy).toHaveBeenCalledTimes(1)
|
|
265
|
+
|
|
266
|
+
done()
|
|
267
|
+
})
|
|
268
|
+
})
|
|
269
|
+
})
|
|
@@ -1,52 +1,61 @@
|
|
|
1
1
|
const { print } = require('@toptal/davinci-cli-shared')
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
const { anvilMapper, generateAnvilResults } = require('./anvil-results-helper')
|
|
3
4
|
|
|
4
5
|
class JestAnvilReporter {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
constructor(globalConfig, options) {
|
|
7
|
+
this._globalConfig = globalConfig
|
|
8
|
+
this._options = options
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
onRunComplete(contexts, results) {
|
|
12
|
+
print.grey('Starting Anvil reporter processing...')
|
|
13
|
+
console.time('Anvil reporter run')
|
|
14
|
+
const fileTestResults = results.testResults
|
|
15
|
+
const runPath = process.cwd()
|
|
16
|
+
const individualTestResults = fileTestResults.flatMap(fileTestResult => {
|
|
17
|
+
const fileName = fileTestResult.testFilePath.replace(runPath, '.')
|
|
18
|
+
|
|
19
|
+
return fileTestResult.testResults.map(res => ({ ...res, fileName }))
|
|
20
|
+
})
|
|
9
21
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
fs.writeFileSync('./anvil_test_results.json', JSON.stringify(anvilPayload, undefined, 2), err => {
|
|
43
|
-
if (err) {
|
|
44
|
-
print.red('Failed to create Anvil test results', err)
|
|
45
|
-
throw err
|
|
46
|
-
}
|
|
47
|
-
})
|
|
48
|
-
console.timeEnd('Anvil reporter run')
|
|
22
|
+
if (!this?._options?.anvilTag) {
|
|
23
|
+
print.yellow(
|
|
24
|
+
'Missing --anvilTag value! Anvil test results will be skipped.'
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
const anvilTestResults = individualTestResults.map(testResult => {
|
|
30
|
+
return anvilMapper({
|
|
31
|
+
fileName: testResult.fileName,
|
|
32
|
+
lineNumber: testResult.location && testResult.location.line,
|
|
33
|
+
status: testResult.status,
|
|
34
|
+
durationInSeconds: testResult.duration / 1000,
|
|
35
|
+
scenarioName: testResult.ancestorTitles
|
|
36
|
+
.concat(testResult.title)
|
|
37
|
+
.join('/'),
|
|
38
|
+
description: testResult.title,
|
|
39
|
+
error:
|
|
40
|
+
testResult.failureDetails.length > 0
|
|
41
|
+
? testResult.failureDetails[0].message
|
|
42
|
+
: null,
|
|
43
|
+
backtrace:
|
|
44
|
+
testResult.failureDetails.length > 0
|
|
45
|
+
? testResult.failureDetails.map(failure => failure.stack)
|
|
46
|
+
: null,
|
|
47
|
+
testType: 'unit',
|
|
48
|
+
pendingMessage: null,
|
|
49
|
+
tag: this._options.anvilTag
|
|
50
|
+
})
|
|
51
|
+
})
|
|
52
|
+
const anvilPayload = {
|
|
53
|
+
test_results: [...anvilTestResults]
|
|
49
54
|
}
|
|
55
|
+
|
|
56
|
+
generateAnvilResults('anvil_jest_test_results.json', anvilPayload)
|
|
57
|
+
console.timeEnd('Anvil reporter run')
|
|
58
|
+
}
|
|
50
59
|
}
|
|
51
|
-
|
|
60
|
+
|
|
52
61
|
module.exports = JestAnvilReporter
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
1
|
+
const generateAnvilResultsMock = jest.fn()
|
|
2
|
+
|
|
3
|
+
jest.mock('./anvil-results-helper', () => ({
|
|
4
|
+
...jest.requireActual('./anvil-results-helper'),
|
|
5
|
+
generateAnvilResults: generateAnvilResultsMock
|
|
6
|
+
}))
|
|
7
|
+
|
|
8
|
+
const { print } = require('@toptal/davinci-cli-shared')
|
|
9
|
+
|
|
10
|
+
const JestAnvilReporter = require('./jest-anvil-reporter')
|
|
3
11
|
const {
|
|
4
12
|
passedTestResults,
|
|
5
13
|
failedTestResults,
|
|
@@ -12,35 +20,40 @@ describe('Jest Anvil reporter', () => {
|
|
|
12
20
|
const expectedPassedTestResults = {
|
|
13
21
|
test_results: [
|
|
14
22
|
{
|
|
15
|
-
file_name:
|
|
23
|
+
file_name:
|
|
24
|
+
'/davinci/packages/qa/src/reporters/jest-anvil-reporter-mocker.test.js',
|
|
16
25
|
line_number: 2,
|
|
17
|
-
status:
|
|
18
|
-
duration:
|
|
19
|
-
scenario_name:
|
|
20
|
-
description:
|
|
26
|
+
status: 'passed',
|
|
27
|
+
duration: 0.003,
|
|
28
|
+
scenario_name: 'Example test suite/1 + 1 returns 2',
|
|
29
|
+
description: '1 + 1 returns 2',
|
|
21
30
|
error: null,
|
|
22
31
|
backtrace: null,
|
|
23
|
-
test_type:
|
|
32
|
+
test_type: 'unit',
|
|
24
33
|
pending_message: null,
|
|
25
|
-
tag:
|
|
34
|
+
tag: 'platform'
|
|
26
35
|
}
|
|
27
36
|
]
|
|
28
37
|
}
|
|
29
|
-
|
|
38
|
+
|
|
30
39
|
const expectedFailedTestResults = {
|
|
31
40
|
test_results: [
|
|
32
41
|
{
|
|
33
|
-
file_name:
|
|
42
|
+
file_name:
|
|
43
|
+
'/davinci/packages/qa/src/reporters/jest-anvil-reporter-mocker.test.js',
|
|
34
44
|
line_number: 2,
|
|
35
|
-
status:
|
|
36
|
-
duration:
|
|
37
|
-
scenario_name:
|
|
38
|
-
description:
|
|
39
|
-
error:
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
status: 'failed',
|
|
46
|
+
duration: 0.006,
|
|
47
|
+
scenario_name: 'Example test suite/1 + 1 returns 3',
|
|
48
|
+
description: '1 + 1 returns 3',
|
|
49
|
+
error:
|
|
50
|
+
'Error: \u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32m3\u001b[39m\nReceived: \u001b[31m2\u001b[39m',
|
|
51
|
+
backtrace: [
|
|
52
|
+
'Error: \u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32m3\u001b[39m\nReceived: \u001b[31m2\u001b[39m\n at Object.<anonymous> (/davinci/packages/qa/src/reporters/jest-anvil-reporter-mocker.test.js:3:17)\n at Object.asyncJestTest (/davinci/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:106:37)\n at /davinci/node_modules/jest-jasmine2/build/queueRunner.js:45:12\n at new Promise (<anonymous>)\n at mapper (/davinci/node_modules/jest-jasmine2/build/queueRunner.js:28:19)\n at /davinci/node_modules/jest-jasmine2/build/queueRunner.js:75:41'
|
|
53
|
+
],
|
|
54
|
+
test_type: 'unit',
|
|
42
55
|
pending_message: null,
|
|
43
|
-
tag:
|
|
56
|
+
tag: 'platform'
|
|
44
57
|
}
|
|
45
58
|
]
|
|
46
59
|
}
|
|
@@ -48,17 +61,18 @@ describe('Jest Anvil reporter', () => {
|
|
|
48
61
|
const expectedSkippedTestResults = {
|
|
49
62
|
test_results: [
|
|
50
63
|
{
|
|
51
|
-
file_name:
|
|
64
|
+
file_name:
|
|
65
|
+
'/davinci/packages/qa/src/reporters/jest-anvil-reporter-mocker.test.js',
|
|
52
66
|
line_number: 2,
|
|
53
|
-
status:
|
|
67
|
+
status: 'pending',
|
|
54
68
|
duration: 0,
|
|
55
|
-
scenario_name:
|
|
56
|
-
description:
|
|
69
|
+
scenario_name: 'Example test suite/1 + 1 returns 2',
|
|
70
|
+
description: '1 + 1 returns 2',
|
|
57
71
|
error: null,
|
|
58
72
|
backtrace: null,
|
|
59
|
-
test_type:
|
|
73
|
+
test_type: 'unit',
|
|
60
74
|
pending_message: null,
|
|
61
|
-
tag:
|
|
75
|
+
tag: 'platform'
|
|
62
76
|
}
|
|
63
77
|
]
|
|
64
78
|
}
|
|
@@ -66,17 +80,18 @@ describe('Jest Anvil reporter', () => {
|
|
|
66
80
|
const expectedToDoTestResults = {
|
|
67
81
|
test_results: [
|
|
68
82
|
{
|
|
69
|
-
file_name:
|
|
83
|
+
file_name:
|
|
84
|
+
'/davinci/packages/qa/src/reporters/jest-anvil-reporter-mocker.test.js',
|
|
70
85
|
line_number: null,
|
|
71
|
-
status:
|
|
86
|
+
status: 'pending',
|
|
72
87
|
duration: 0,
|
|
73
|
-
scenario_name:
|
|
74
|
-
description:
|
|
88
|
+
scenario_name: 'Example test suite/1+1 returns 2',
|
|
89
|
+
description: '1+1 returns 2',
|
|
75
90
|
error: null,
|
|
76
91
|
backtrace: null,
|
|
77
|
-
test_type:
|
|
92
|
+
test_type: 'unit',
|
|
78
93
|
pending_message: null,
|
|
79
|
-
tag:
|
|
94
|
+
tag: 'platform'
|
|
80
95
|
}
|
|
81
96
|
]
|
|
82
97
|
}
|
|
@@ -84,62 +99,125 @@ describe('Jest Anvil reporter', () => {
|
|
|
84
99
|
const expectedCombinedTestResults = {
|
|
85
100
|
test_results: [
|
|
86
101
|
{
|
|
87
|
-
file_name:
|
|
102
|
+
file_name:
|
|
103
|
+
'/davinci/packages/qa/src/reporters/jest-anvil-reporter-mocker.test.js',
|
|
88
104
|
line_number: 2,
|
|
89
|
-
status:
|
|
90
|
-
duration:
|
|
91
|
-
scenario_name:
|
|
92
|
-
description:
|
|
105
|
+
status: 'passed',
|
|
106
|
+
duration: 0.005,
|
|
107
|
+
scenario_name: 'Example test suite/1 + 1 returns 2 (passed)',
|
|
108
|
+
description: '1 + 1 returns 2 (passed)',
|
|
93
109
|
error: null,
|
|
94
110
|
backtrace: null,
|
|
95
|
-
test_type:
|
|
111
|
+
test_type: 'unit',
|
|
96
112
|
pending_message: null,
|
|
97
|
-
tag:
|
|
113
|
+
tag: 'platform'
|
|
98
114
|
},
|
|
99
115
|
{
|
|
100
|
-
file_name:
|
|
116
|
+
file_name:
|
|
117
|
+
'/davinci/packages/qa/src/reporters/jest-anvil-reporter-mocker.test.js',
|
|
101
118
|
line_number: 6,
|
|
102
|
-
status:
|
|
103
|
-
duration:
|
|
104
|
-
scenario_name:
|
|
105
|
-
description:
|
|
106
|
-
error:
|
|
107
|
-
|
|
108
|
-
|
|
119
|
+
status: 'failed',
|
|
120
|
+
duration: 0.007,
|
|
121
|
+
scenario_name: 'Example test suite/1 + 1 returns 3 (failed)',
|
|
122
|
+
description: '1 + 1 returns 3 (failed)',
|
|
123
|
+
error:
|
|
124
|
+
'Error: \u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32m3\u001b[39m\nReceived: \u001b[31m2\u001b[39m',
|
|
125
|
+
backtrace: [
|
|
126
|
+
'Error: \u001b[2mexpect(\u001b[22m\u001b[31mreceived\u001b[39m\u001b[2m).\u001b[22mtoBe\u001b[2m(\u001b[22m\u001b[32mexpected\u001b[39m\u001b[2m) // Object.is equality\u001b[22m\n\nExpected: \u001b[32m3\u001b[39m\nReceived: \u001b[31m2\u001b[39m\n at Object.<anonymous> (/davinci/packages/qa/src/reporters/jest-anvil-reporter-mocker.test.js:7:17)\n at Object.asyncJestTest (/davinci/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:106:37)\n at /davinci/node_modules/jest-jasmine2/build/queueRunner.js:45:12\n at new Promise (<anonymous>)\n at mapper (/davinci/node_modules/jest-jasmine2/build/queueRunner.js:28:19)\n at /davinci/node_modules/jest-jasmine2/build/queueRunner.js:75:41'
|
|
127
|
+
],
|
|
128
|
+
test_type: 'unit',
|
|
109
129
|
pending_message: null,
|
|
110
|
-
tag:
|
|
130
|
+
tag: 'platform'
|
|
111
131
|
},
|
|
112
132
|
{
|
|
113
|
-
file_name:
|
|
133
|
+
file_name:
|
|
134
|
+
'/davinci/packages/qa/src/reporters/jest-anvil-reporter-mocker.test.js',
|
|
114
135
|
line_number: 10,
|
|
115
|
-
status:
|
|
136
|
+
status: 'pending',
|
|
116
137
|
duration: 0,
|
|
117
|
-
scenario_name:
|
|
118
|
-
description:
|
|
138
|
+
scenario_name: 'Example test suite/1 + 1 returns 2 (skipped)',
|
|
139
|
+
description: '1 + 1 returns 2 (skipped)',
|
|
119
140
|
error: null,
|
|
120
141
|
backtrace: null,
|
|
121
|
-
test_type:
|
|
142
|
+
test_type: 'unit',
|
|
122
143
|
pending_message: null,
|
|
123
|
-
tag:
|
|
144
|
+
tag: 'platform'
|
|
124
145
|
}
|
|
125
146
|
]
|
|
126
147
|
}
|
|
127
148
|
|
|
128
149
|
beforeEach(() => {
|
|
129
|
-
jest.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
${
|
|
136
|
-
${
|
|
137
|
-
${
|
|
138
|
-
${
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
150
|
+
jest.resetModules()
|
|
151
|
+
jest.resetAllMocks()
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
it.each`
|
|
155
|
+
input | expectedOutput | testType
|
|
156
|
+
${passedTestResults} | ${expectedPassedTestResults} | ${'passing tests'}
|
|
157
|
+
${failedTestResults} | ${expectedFailedTestResults} | ${'failing tests'}
|
|
158
|
+
${skippedTestResults} | ${expectedSkippedTestResults} | ${'skipped tests'}
|
|
159
|
+
${toDoTestResults} | ${expectedToDoTestResults} | ${'todo tests'}
|
|
160
|
+
${combinedTestResults} | ${expectedCombinedTestResults} | ${'a combination of test results'}
|
|
161
|
+
`(
|
|
162
|
+
'calls generateAnvilResults with a payload matching Anvil for $testType',
|
|
163
|
+
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
|
|
164
|
+
({ input, expectedOutput, testType }) => {
|
|
165
|
+
const jestAnvilReporter = new JestAnvilReporter(undefined, {
|
|
166
|
+
anvilTag: 'platform'
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
jestAnvilReporter.onRunComplete(undefined, input)
|
|
170
|
+
|
|
171
|
+
expect(generateAnvilResultsMock).toHaveBeenCalledWith(
|
|
172
|
+
'anvil_jest_test_results.json',
|
|
173
|
+
expectedOutput
|
|
174
|
+
)
|
|
175
|
+
}
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
it('prints warning and exits when anvilTag is not defined', () => {
|
|
179
|
+
const printSpy = jest.spyOn(print, 'yellow')
|
|
180
|
+
const jestAnvilReporter = new JestAnvilReporter(undefined, {
|
|
181
|
+
anvilTag: undefined
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
jestAnvilReporter.onRunComplete(undefined, passedTestResults)
|
|
185
|
+
|
|
186
|
+
expect(printSpy).toHaveBeenCalledWith(
|
|
187
|
+
'Missing --anvilTag value! Anvil test results will be skipped.'
|
|
188
|
+
)
|
|
189
|
+
expect(generateAnvilResultsMock).not.toHaveBeenCalled()
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
it('calls the anvil mapper', () => {
|
|
193
|
+
const anvilMapperSpy = jest.fn()
|
|
194
|
+
|
|
195
|
+
jest.mock('./anvil-results-helper', () => ({
|
|
196
|
+
anvilMapper: anvilMapperSpy,
|
|
197
|
+
generateAnvilResults: jest.fn()
|
|
198
|
+
}))
|
|
199
|
+
const JestAnvilReporter = require('./jest-anvil-reporter')
|
|
200
|
+
|
|
201
|
+
const jestAnvilReporter = new JestAnvilReporter(undefined, {
|
|
202
|
+
anvilTag: 'platform'
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
jestAnvilReporter.onRunComplete(undefined, passedTestResults)
|
|
206
|
+
|
|
207
|
+
expect(anvilMapperSpy).toHaveBeenCalledWith({
|
|
208
|
+
backtrace: null,
|
|
209
|
+
description: '1 + 1 returns 2',
|
|
210
|
+
durationInSeconds: expect.any(Number),
|
|
211
|
+
error: null,
|
|
212
|
+
fileName: expect.stringContaining(
|
|
213
|
+
'/davinci/packages/qa/src/reporters/jest-anvil-reporter-mocker.test.js'
|
|
214
|
+
),
|
|
215
|
+
lineNumber: expect.any(Number),
|
|
216
|
+
pendingMessage: null,
|
|
217
|
+
scenarioName: 'Example test suite/1 + 1 returns 2',
|
|
218
|
+
status: 'passed',
|
|
219
|
+
tag: 'platform',
|
|
220
|
+
testType: 'unit'
|
|
221
|
+
})
|
|
144
222
|
})
|
|
145
223
|
})
|