@toptal/davinci-qa 6.0.1-alpha-pro-2952-allow-to-disable-type-checking-for-davinci-engine-build-command.22 → 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 CHANGED
@@ -1,5 +1,23 @@
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
+
15
+ ## 6.0.2
16
+
17
+ ### Patch Changes
18
+
19
+ - [#1252](https://github.com/toptal/davinci/pull/1252) [`a99253c4`](https://github.com/toptal/davinci/commit/a99253c41eb80f5a31d66766d0efd986d1710bd1) Thanks [@aesqe](https://github.com/aesqe)! - Adds babel-plugin-styled-components to the QA package's Jest config so that the forwardedAs prop is properly working in Jest tests. It also adds the forwardedAs prop to the Skeleton package's react module type.
20
+
3
21
  ## 6.0.1
4
22
 
5
23
  ### Patch Changes
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@toptal/davinci-qa",
3
+ "version": "7.0.0",
4
+ "description": "QA package to test your application",
5
+ "publishConfig": {
6
+ "access": "public"
7
+ },
8
+ "keywords": [
9
+ "qa",
10
+ "testing"
11
+ ],
12
+ "author": "Toptal",
13
+ "homepage": "https://github.com/toptal/davinci/tree/master/packages/qa#readme",
14
+ "license": "ISC",
15
+ "bin": {
16
+ "davinci-qa": "./bin/davinci-qa.js"
17
+ },
18
+ "main": "./src/index.js",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/toptal/davinci.git"
22
+ },
23
+ "scripts": {
24
+ "build:package": "../../bin/build-package.js",
25
+ "prepublishOnly": "../../bin/prepublish.js",
26
+ "test": "echo \"Error: run tests from root\" && exit 1"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/toptal/davinci/issues"
30
+ },
31
+ "dependencies": {
32
+ "@babel/core": "^7.14.8",
33
+ "@babel/preset-env": "^7.16.4",
34
+ "@babel/preset-react": "^7.10.4",
35
+ "@babel/preset-typescript": "^7.10.4",
36
+ "@cypress/code-coverage": "^3.9.12",
37
+ "@cypress/webpack-preprocessor": "^5.7.0",
38
+ "@testing-library/jest-dom": "^5.14.1",
39
+ "@testing-library/react": "^12.1.2",
40
+ "@toptal/davinci-cli-shared": "1.5.1",
41
+ "@types/jest": "^27.4.1",
42
+ "babel-jest": "^27.5.1",
43
+ "cypress": "^9.4.1",
44
+ "enhanced-resolve": "^5.9.2",
45
+ "fs-extra": "^10.0.0",
46
+ "glob": "^7.2.0",
47
+ "jest": "^27.5.1",
48
+ "jest-html-reporters": "^3.0.6",
49
+ "jest-junit": "^13.1.0",
50
+ "jest-silent-reporter": "^0.5.0",
51
+ "jest-styled-components": "^7.0.8",
52
+ "jsdom": "^19.0.0",
53
+ "matchmedia-polyfill": "^0.3.2",
54
+ "semver": "^7.3.2"
55
+ },
56
+ "devDependencies": {
57
+ "mocha": "^9.2.2"
58
+ }
59
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toptal/davinci-qa",
3
- "version": "6.0.1-alpha-pro-2952-allow-to-disable-type-checking-for-davinci-engine-build-command.22+cc36cfc5",
3
+ "version": "7.0.0",
4
4
  "description": "QA package to test your application",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -37,7 +37,7 @@
37
37
  "@cypress/webpack-preprocessor": "^5.7.0",
38
38
  "@testing-library/jest-dom": "^5.14.1",
39
39
  "@testing-library/react": "^12.1.2",
40
- "@toptal/davinci-cli-shared": "1.5.2-alpha-pro-2952-allow-to-disable-type-checking-for-davinci-engine-build-command.44+cc36cfc5",
40
+ "@toptal/davinci-cli-shared": "1.5.1",
41
41
  "@types/jest": "^27.4.1",
42
42
  "babel-jest": "^27.5.1",
43
43
  "cypress": "^9.4.1",
@@ -53,5 +53,7 @@
53
53
  "matchmedia-polyfill": "^0.3.2",
54
54
  "semver": "^7.3.2"
55
55
  },
56
- "gitHead": "cc36cfc59a2ad73402f1d49fc3a029900f4c69e0"
56
+ "devDependencies": {
57
+ "mocha": "^9.2.2"
58
+ }
57
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: 'opens the Cypress Test Runner',
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,65 @@
1
+ const convertToCLIParametersMock = jest.fn()
2
+ const getPackageFilePathMock = jest.fn()
3
+
4
+ jest.mock('@toptal/davinci-cli-shared', () => ({
5
+ runSync: jest.fn(),
6
+ print: {
7
+ green: jest.fn()
8
+ },
9
+ convertToCLIParameters: convertToCLIParametersMock,
10
+ files: {
11
+ getPackageFilePath: getPackageFilePathMock
12
+ }
13
+ }))
14
+
15
+ const { runSync } = require('@toptal/davinci-cli-shared')
16
+
17
+ const { action } = require('./end-to-end-tests')
18
+
19
+ describe('endToEndTestCommand', () => {
20
+ it('runs cypress with default options', () => {
21
+ convertToCLIParametersMock.mockReturnValueOnce([])
22
+ getPackageFilePathMock.mockReturnValueOnce('packages/qa/src/configs/cypress.config.json')
23
+
24
+ action({ options: {} })
25
+
26
+ expect(runSync).toHaveBeenCalledWith('yarn', [
27
+ 'cypress',
28
+ 'run',
29
+ '--config-file',
30
+ 'packages/qa/src/configs/cypress.config.json'
31
+ ])
32
+
33
+ expect(convertToCLIParametersMock).toHaveBeenCalledWith({})
34
+ expect(getPackageFilePathMock).toHaveBeenCalledWith(
35
+ '@toptal/davinci-qa',
36
+ 'src/configs/cypress.config.json'
37
+ )
38
+ })
39
+
40
+ it('runs cypress with custom options', () => {
41
+ const spec = 'cypress/integration/activation_flow.spec.ts'
42
+
43
+ convertToCLIParametersMock.mockReturnValueOnce(['--spec', spec])
44
+ getPackageFilePathMock.mockReturnValueOnce('packages/qa/src/configs/cypress.config.json')
45
+
46
+ action({ options: { spec } })
47
+
48
+ expect(runSync).toHaveBeenCalledWith('yarn', [
49
+ 'cypress',
50
+ 'run',
51
+ '--config-file',
52
+ 'packages/qa/src/configs/cypress.config.json',
53
+ '--spec',
54
+ spec
55
+ ])
56
+
57
+ expect(convertToCLIParametersMock).toHaveBeenCalledWith({
58
+ spec
59
+ })
60
+ expect(getPackageFilePathMock).toHaveBeenCalledWith(
61
+ '@toptal/davinci-qa',
62
+ 'src/configs/cypress.config.json'
63
+ )
64
+ })
65
+ })
@@ -0,0 +1,164 @@
1
+ const jestRunCLIMock =jest.fn().mockResolvedValue({ results: {success: true}})
2
+ const getPackageFilePathMock = jest.fn()
3
+ const getProjectRootFilePathMock = jest.fn()
4
+ const getProjectRootFileContentMock = jest.fn().mockReturnValue({
5
+ devDependencies: {}, dependencies: {},
6
+ })
7
+
8
+ jest.mock('@toptal/davinci-cli-shared', () => ({
9
+ runSync: jest.fn(),
10
+ print: {
11
+ green: jest.fn(),
12
+ grey: jest.fn(),
13
+ red: jest.fn(),
14
+ },
15
+ files: {
16
+ getPackageFilePath: getPackageFilePathMock,
17
+ getProjectRootFileContent: getProjectRootFileContentMock,
18
+ getProjectRootFilePath: getProjectRootFilePathMock
19
+ }
20
+ }))
21
+
22
+ jest.mock('jest', () => ({
23
+ runCLI: jestRunCLIMock
24
+ }))
25
+
26
+ const { action } = require('./unit-tests')
27
+ const originalEnv = process.env
28
+
29
+ beforeEach(() => {
30
+ jest.clearAllMocks()
31
+ })
32
+
33
+ afterEach(() => {
34
+ process.env = originalEnv
35
+ })
36
+
37
+ describe('unitTestsCommand', () => {
38
+ describe('when running locally', () => {
39
+ beforeEach(() => {
40
+ delete process.env.CI
41
+ })
42
+
43
+ it('calls the jest CLI without additional reporters', async () => {
44
+ const davinciJestConfigPath = 'packages/qa/src/configs/jest.config.js'
45
+ getPackageFilePathMock.mockReturnValueOnce(davinciJestConfigPath)
46
+
47
+ await action({})
48
+
49
+ expect(jestRunCLIMock).toBeCalledWith(
50
+ {"config": davinciJestConfigPath, "testPathPattern": []},
51
+ expect.anything()
52
+ )
53
+ })
54
+
55
+ })
56
+
57
+ describe('when running on CI', () => {
58
+ beforeEach(() => {
59
+ process.env.CI = true
60
+ })
61
+
62
+ it('calls the jest CLI with default Davinci reporters', async () => {
63
+ const davinciJestConfigPath = 'packages/qa/src/configs/jest.config.js'
64
+ getPackageFilePathMock.mockReturnValueOnce(davinciJestConfigPath)
65
+
66
+ await action({})
67
+
68
+ expect(jestRunCLIMock).toBeCalledWith(
69
+ expect.objectContaining({
70
+ reporters: [
71
+ [
72
+ "jest-silent-reporter",
73
+ {
74
+ useDots: true,
75
+ showPaths: true,
76
+ showWarnings: true,
77
+ },
78
+ ],
79
+ [
80
+ "jest-junit",
81
+ {
82
+ outputDirectory: "reports",
83
+ },
84
+ ],
85
+ [
86
+ "jest-html-reporters",
87
+ {
88
+ publicPath: "./reports",
89
+ },
90
+ ],
91
+ [
92
+ expect.stringContaining("davinci/packages/qa/src/reporters/jest-anvil-reporter.js"),
93
+ {
94
+ anvilTag: undefined,
95
+ },
96
+ ],
97
+ ],
98
+ }),
99
+ expect.anything()
100
+ )
101
+ })
102
+
103
+ it('allows overriding of the default Davinci reporters via custom configuration', async () => {
104
+ const davinciJestConfigPath = 'packages/qa/src/configs/jest.config.js'
105
+ getPackageFilePathMock.mockReturnValueOnce(davinciJestConfigPath)
106
+ const customCLIReporter = 'My-CLI-Reporter'
107
+
108
+ await action({
109
+ options: {
110
+ anvilTag: 'MyTag',
111
+ reporters: customCLIReporter
112
+ }
113
+ })
114
+
115
+ expect(jestRunCLIMock).toBeCalledWith(
116
+ expect.objectContaining({
117
+ reporters: [customCLIReporter],
118
+ }),
119
+ expect.anything()
120
+ )
121
+ })
122
+
123
+ it('allows overriding the default Davinci reporters via custom jest config', async () => {
124
+ const davinciJestConfigPath = 'packages/qa/src/configs/jest.config.js'
125
+ getPackageFilePathMock.mockReturnValueOnce(davinciJestConfigPath)
126
+ const customJestConfigReporter = 'My-Jest-Config-Reporter'
127
+
128
+ getProjectRootFileContentMock.mockReturnValue({reporters: customJestConfigReporter})
129
+
130
+ await action({ options: { config: {}}})
131
+
132
+ expect(jestRunCLIMock).toBeCalledWith(
133
+ expect.objectContaining({
134
+ reporters: [customJestConfigReporter],
135
+ }),
136
+ expect.anything()
137
+ )
138
+ })
139
+
140
+ it('prioritizes the CLI reporters over the custom jest config or the default Davinci reporters', async () => {
141
+ const davinciJestConfigPath = 'packages/qa/src/configs/jest.config.js'
142
+ getPackageFilePathMock.mockReturnValueOnce(davinciJestConfigPath)
143
+ const customCLIReporter = 'My-CLI-Reporter'
144
+ const customJestConfigReporter = 'My-Jest-Config-Reporter'
145
+
146
+ getProjectRootFileContentMock.mockReturnValue({ reporters: customJestConfigReporter })
147
+
148
+ await action({
149
+ options: {
150
+ anvilTag: 'MyTag',
151
+ reporters: customCLIReporter,
152
+ config: {}
153
+ }
154
+ })
155
+
156
+ expect(jestRunCLIMock).toBeCalledWith(
157
+ expect.objectContaining({
158
+ reporters: [customCLIReporter],
159
+ }),
160
+ expect.anything()
161
+ )
162
+ })
163
+ })
164
+ })
@@ -10,6 +10,9 @@ const babelOptions = {
10
10
  ],
11
11
  '@babel/preset-typescript',
12
12
  '@babel/preset-react'
13
+ ],
14
+ plugins: [
15
+ 'babel-plugin-styled-components'
13
16
  ]
14
17
  }
15
18
 
@@ -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