@toptal/davinci-qa 15.1.0 → 15.1.1
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 +7 -0
- package/package.json +3 -3
- package/src/commands/__snapshots__/code-metrics.test.js.snap +18 -0
- package/src/commands/code-metrics.js +20 -4
- package/src/commands/integration-open.js +15 -22
- package/src/commands/integration-run.js +19 -22
- package/src/commands/integration-run.test.js +8 -8
- package/src/commands/unit-tests.js +70 -22
- package/src/commands/unit-tests.test.js +11 -15
- package/src/index.js +9 -6
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toptal/davinci-qa",
|
|
3
|
-
"version": "15.1.
|
|
3
|
+
"version": "15.1.1",
|
|
4
4
|
"description": "QA package to test your application",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"@cypress/webpack-preprocessor": "^5.12.0",
|
|
53
53
|
"@testing-library/jest-dom": "^5.16.4",
|
|
54
54
|
"@testing-library/react": "^13.3.0",
|
|
55
|
-
"@toptal/davinci-cli-shared": "2.
|
|
55
|
+
"@toptal/davinci-cli-shared": "2.2.0",
|
|
56
56
|
"@types/jest": "^27.5.1",
|
|
57
57
|
"babel-jest": "^28.1.3",
|
|
58
58
|
"fs-extra": "^10.0.0",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"semver": "^7.3.2"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
|
-
"@jest/globals": "
|
|
75
|
+
"@jest/globals": "^29.4.2",
|
|
76
76
|
"cypress": "^12.5.1",
|
|
77
77
|
"json5": "^2.2.3",
|
|
78
78
|
"mocha": "^10.0.0"
|
|
@@ -5,5 +5,23 @@ exports[`codeMetricsCommandCreator has the correct command structure 1`] = `
|
|
|
5
5
|
"action": [Function],
|
|
6
6
|
"allowUnknownOptions": true,
|
|
7
7
|
"command": "code-metrics",
|
|
8
|
+
"options": [
|
|
9
|
+
{
|
|
10
|
+
"label": "Package Name",
|
|
11
|
+
"name": "-n, --name <packageName>",
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"label": "Package Version",
|
|
15
|
+
"name": "-v, --version <version>",
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"label": "Custom sonarqube url",
|
|
19
|
+
"name": "-u, --url <url>",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"label": "sonarqube login",
|
|
23
|
+
"name": "--login <login>",
|
|
24
|
+
},
|
|
25
|
+
],
|
|
8
26
|
}
|
|
9
27
|
`;
|
|
@@ -2,7 +2,7 @@ import fs from 'fs-extra'
|
|
|
2
2
|
import path from 'path'
|
|
3
3
|
import { runSync, print } from '@toptal/davinci-cli-shared'
|
|
4
4
|
|
|
5
|
-
const codeMetricsCommand = async
|
|
5
|
+
const codeMetricsCommand = async options => {
|
|
6
6
|
const projectPackageJsonPath = path.join(process.cwd(), 'package.json')
|
|
7
7
|
|
|
8
8
|
print.green('Running code metrics ...')
|
|
@@ -43,9 +43,25 @@ const codeMetricsCommand = async ({ options = [] }) => {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
const codeMetricsCommandCreator = {
|
|
46
|
-
action:
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
action: codeMetricsCommand,
|
|
47
|
+
options: [
|
|
48
|
+
{
|
|
49
|
+
name: '-n, --name <packageName>',
|
|
50
|
+
label: 'Package Name',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: '-v, --version <version>',
|
|
54
|
+
label: 'Package Version',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: '-u, --url <url>',
|
|
58
|
+
label: 'Custom sonarqube url',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: '--login <login>',
|
|
62
|
+
label: 'sonarqube login',
|
|
63
|
+
},
|
|
64
|
+
],
|
|
49
65
|
allowUnknownOptions: true,
|
|
50
66
|
command: 'code-metrics',
|
|
51
67
|
}
|
|
@@ -11,10 +11,10 @@ import getCypressConfigPath from '../utils/get-cypress-config-path.js'
|
|
|
11
11
|
|
|
12
12
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
13
13
|
|
|
14
|
-
const integrationOpenCommand = (
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
export const integrationOpenCommand = (
|
|
15
|
+
testFiles,
|
|
16
|
+
{ baseUrl, ...cypressOptions }
|
|
17
|
+
) => {
|
|
18
18
|
const prerequirementsError = packageUtils.checkPrerequirement({
|
|
19
19
|
dependencies:
|
|
20
20
|
packageUtils.getPackagePackageJson(__dirname).peerDependencies,
|
|
@@ -41,22 +41,15 @@ const integrationOpenCommand = ({
|
|
|
41
41
|
])
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
{
|
|
56
|
-
label: "URL used as prefix for cy.visit() or cy.request() command's URL",
|
|
57
|
-
name: '--baseUrl <baseUrl>',
|
|
58
|
-
},
|
|
59
|
-
],
|
|
44
|
+
export const createIntegrationOpenCommand = program => {
|
|
45
|
+
return program
|
|
46
|
+
.createCommand('open')
|
|
47
|
+
.allowUnknownOption()
|
|
48
|
+
.description('Open the Cypress Test Runner app')
|
|
49
|
+
.argument('[files...]', 'List of test path patterns', [])
|
|
50
|
+
.option(
|
|
51
|
+
'--baseUrl <baseUrl>',
|
|
52
|
+
"URL used as prefix for cy.visit() or cy.request() command's URL"
|
|
53
|
+
)
|
|
54
|
+
.action(integrationOpenCommand)
|
|
60
55
|
}
|
|
61
|
-
|
|
62
|
-
export default integrationOpenCommandCreator
|
|
@@ -10,10 +10,10 @@ import getCypressConfigPath from '../utils/get-cypress-config-path.js'
|
|
|
10
10
|
|
|
11
11
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
12
12
|
|
|
13
|
-
export const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
export const integrationRunCommand = (
|
|
14
|
+
testFiles,
|
|
15
|
+
{ baseUrl, anvilTag, ...cypressOptions }
|
|
16
|
+
) => {
|
|
17
17
|
const { convertToCLIParameters } = cliShared
|
|
18
18
|
|
|
19
19
|
const preRequirementsError = packageUtils.checkPrerequirement({
|
|
@@ -54,22 +54,19 @@ export const integrationRunCommandAction = ({
|
|
|
54
54
|
])
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
],
|
|
57
|
+
export const createIntegrationRunCommand = program => {
|
|
58
|
+
return program
|
|
59
|
+
.createCommand('run')
|
|
60
|
+
.allowUnknownOption()
|
|
61
|
+
.description('Run Cypress tests')
|
|
62
|
+
.argument('[files...]', 'List of test path patterns', [])
|
|
63
|
+
.option(
|
|
64
|
+
'--baseUrl <baseUrl>',
|
|
65
|
+
"URL used as prefix for cy.visit() or cy.request() command's URL"
|
|
66
|
+
)
|
|
67
|
+
.option(
|
|
68
|
+
'--anvilTag <anvilTag>',
|
|
69
|
+
"the project name matching Anvil's expected tag to generate Anvil Reports"
|
|
70
|
+
)
|
|
71
|
+
.action(integrationRunCommand)
|
|
73
72
|
}
|
|
74
|
-
|
|
75
|
-
export default integrationRunCommandCreator
|
|
@@ -2,7 +2,7 @@ import fs from 'fs'
|
|
|
2
2
|
import { jest } from '@jest/globals'
|
|
3
3
|
import davinciCliShared from '@toptal/davinci-cli-shared'
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { integrationRunCommand } from './integration-run.js'
|
|
6
6
|
|
|
7
7
|
const { existsSync } = fs
|
|
8
8
|
|
|
@@ -22,7 +22,7 @@ const runSync = jest
|
|
|
22
22
|
.spyOn(davinciCliShared, 'runSync')
|
|
23
23
|
.mockImplementation(() => {})
|
|
24
24
|
|
|
25
|
-
const action =
|
|
25
|
+
const action = integrationRunCommand
|
|
26
26
|
|
|
27
27
|
describe('integrationRunCommand', () => {
|
|
28
28
|
beforeEach(() => {
|
|
@@ -42,7 +42,7 @@ describe('integrationRunCommand', () => {
|
|
|
42
42
|
path === localConfig ? false : existsSync(path, ...rest)
|
|
43
43
|
)
|
|
44
44
|
|
|
45
|
-
action(
|
|
45
|
+
action([], {})
|
|
46
46
|
|
|
47
47
|
expect(runSync).toHaveBeenCalledWith('yarn', [
|
|
48
48
|
'cypress',
|
|
@@ -69,7 +69,7 @@ describe('integrationRunCommand', () => {
|
|
|
69
69
|
path === localConfig ? true : existsSync(path, ...rest)
|
|
70
70
|
)
|
|
71
71
|
|
|
72
|
-
action(
|
|
72
|
+
action([], {})
|
|
73
73
|
|
|
74
74
|
expect(runSync).toHaveBeenCalledWith('yarn', [
|
|
75
75
|
'cypress',
|
|
@@ -87,7 +87,7 @@ describe('integrationRunCommand', () => {
|
|
|
87
87
|
it('runs cypress with custom options', () => {
|
|
88
88
|
const localConfig = 'mock:cypress.config.js'
|
|
89
89
|
const davinciConfig = 'packages/qa/src/configs/cypress.config.js'
|
|
90
|
-
const
|
|
90
|
+
const baseUrl = 'http://something.com'
|
|
91
91
|
|
|
92
92
|
getPackageFilePathMock.mockReturnValueOnce(davinciConfig)
|
|
93
93
|
|
|
@@ -97,15 +97,15 @@ describe('integrationRunCommand', () => {
|
|
|
97
97
|
path === localConfig ? false : existsSync(path, ...rest)
|
|
98
98
|
)
|
|
99
99
|
|
|
100
|
-
action(
|
|
100
|
+
action([], { baseUrl })
|
|
101
101
|
|
|
102
102
|
expect(runSync).toHaveBeenCalledWith('yarn', [
|
|
103
103
|
'cypress',
|
|
104
104
|
'run',
|
|
105
105
|
'--config-file',
|
|
106
106
|
davinciConfig,
|
|
107
|
-
'--
|
|
108
|
-
|
|
107
|
+
'--config',
|
|
108
|
+
'baseUrl=http://something.com',
|
|
109
109
|
])
|
|
110
110
|
|
|
111
111
|
expect(getPackageFilePathMock).toHaveBeenCalledWith(
|
|
@@ -9,10 +9,7 @@ import { getCIDefaultOptions } from '../utils/jest/ci-options.js'
|
|
|
9
9
|
|
|
10
10
|
export const createUnitTestCommandAction =
|
|
11
11
|
jest =>
|
|
12
|
-
async ({
|
|
13
|
-
options: { anvilTag, ...jestOptions } = {},
|
|
14
|
-
files: testPathPattern = [],
|
|
15
|
-
}) => {
|
|
12
|
+
async (testPathPattern = [], { anvilTag, ...jestOptions }) => {
|
|
16
13
|
print.green('Running unit tests...')
|
|
17
14
|
|
|
18
15
|
const currentRunningDir = process.cwd()
|
|
@@ -61,22 +58,73 @@ export const createUnitTestCommandAction =
|
|
|
61
58
|
})
|
|
62
59
|
}
|
|
63
60
|
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
name
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
61
|
+
export const createLintCodeCommand = program => {
|
|
62
|
+
return program
|
|
63
|
+
.createCommand('unit')
|
|
64
|
+
.description('Run Jest tests')
|
|
65
|
+
.allowUnknownOption()
|
|
66
|
+
.argument('[files...]', 'List of test path patterns', [])
|
|
67
|
+
.option(
|
|
68
|
+
'--anvilTag <anvilTag>',
|
|
69
|
+
"the project name matching Anvil's expected tag. Used to generate Anvil-compatible test reports."
|
|
70
|
+
)
|
|
71
|
+
.option(
|
|
72
|
+
'--setupFilesAfterEnv <setupFilesAfterEnv>',
|
|
73
|
+
'a list of paths to modules that run some code to configure or set up the testing framework before each test file in the suite is executed'
|
|
74
|
+
)
|
|
75
|
+
.option('-c, --config <path>', 'the path to a Jest config file')
|
|
76
|
+
.option(
|
|
77
|
+
'-w, --maxWorkers <num>',
|
|
78
|
+
'specifies the maximum number of workers the worker-pool will spawn for running tests'
|
|
79
|
+
)
|
|
80
|
+
.option(
|
|
81
|
+
'--ci',
|
|
82
|
+
'when this option is provided, Jest will assume it is running in a CI environment'
|
|
83
|
+
)
|
|
84
|
+
.option(
|
|
85
|
+
'--testTimeout <number>',
|
|
86
|
+
'default timeout of a test in milliseconds'
|
|
87
|
+
)
|
|
88
|
+
.option(
|
|
89
|
+
'--silent',
|
|
90
|
+
'prevent tests from printing messages through the console'
|
|
91
|
+
)
|
|
92
|
+
.option(
|
|
93
|
+
'--watch',
|
|
94
|
+
'watch files for changes and rerun tests related to changed files'
|
|
95
|
+
)
|
|
96
|
+
.option(
|
|
97
|
+
'-i, --runInBand [value]',
|
|
98
|
+
'run all tests serially in the current process',
|
|
99
|
+
program.parseBoolean
|
|
100
|
+
)
|
|
101
|
+
.option(
|
|
102
|
+
'--passWithNoTests',
|
|
103
|
+
'allows the test suite to pass when no files are found'
|
|
104
|
+
)
|
|
105
|
+
.option('--json', 'prints the test results in JSON')
|
|
106
|
+
.option(
|
|
107
|
+
'-b, --bail [n]',
|
|
108
|
+
'exit the test suite immediately upon n number of failing test suite'
|
|
109
|
+
)
|
|
110
|
+
.option('--reporters <reporters...>', 'run tests with specified reporters')
|
|
111
|
+
.option('--collect-coverage')
|
|
112
|
+
.option(
|
|
113
|
+
'--coverage [value]',
|
|
114
|
+
'indicates that test coverage information should be collected and reported in the output',
|
|
115
|
+
program.parseBoolean
|
|
116
|
+
)
|
|
117
|
+
.option('--coverageDirectory <directory>')
|
|
118
|
+
.option('--collectCoverageFrom <from>')
|
|
119
|
+
.option('--testLocationInResults')
|
|
120
|
+
.option(
|
|
121
|
+
'--outputFile <filename>',
|
|
122
|
+
'write test results to a file when the --json option is also specified'
|
|
123
|
+
)
|
|
124
|
+
.option(
|
|
125
|
+
'--verbose [value]',
|
|
126
|
+
'display individual test results with the test suite hierarchy',
|
|
127
|
+
program.parseBoolean
|
|
128
|
+
)
|
|
129
|
+
.action(createUnitTestCommandAction(defaultJest))
|
|
80
130
|
}
|
|
81
|
-
|
|
82
|
-
export default unitTestsCommandCreator
|
|
@@ -57,7 +57,7 @@ describe('unitTestsCommand', () => {
|
|
|
57
57
|
|
|
58
58
|
getPackageFilePathMock.mockReturnValueOnce(davinciJestConfigPath)
|
|
59
59
|
|
|
60
|
-
await unitTestCommand({})
|
|
60
|
+
await unitTestCommand([], {})
|
|
61
61
|
|
|
62
62
|
expect(jestRunCLIMock).toHaveBeenCalledWith(
|
|
63
63
|
{ config: davinciJestConfigPath, testPathPattern: [] },
|
|
@@ -76,7 +76,7 @@ describe('unitTestsCommand', () => {
|
|
|
76
76
|
|
|
77
77
|
getPackageFilePathMock.mockReturnValueOnce(davinciJestConfigPath)
|
|
78
78
|
|
|
79
|
-
await unitTestCommand({})
|
|
79
|
+
await unitTestCommand([], {})
|
|
80
80
|
|
|
81
81
|
expect(jestRunCLIMock).toHaveBeenCalledWith(
|
|
82
82
|
expect.objectContaining({
|
|
@@ -114,7 +114,7 @@ describe('unitTestsCommand', () => {
|
|
|
114
114
|
|
|
115
115
|
getPackageFilePathMock.mockReturnValueOnce(davinciJestConfigPath)
|
|
116
116
|
|
|
117
|
-
await unitTestCommand(
|
|
117
|
+
await unitTestCommand([], { anvilTag: 'platform' })
|
|
118
118
|
|
|
119
119
|
expect(jestRunCLIMock).toHaveBeenCalledWith(
|
|
120
120
|
expect.objectContaining({
|
|
@@ -161,11 +161,9 @@ describe('unitTestsCommand', () => {
|
|
|
161
161
|
getPackageFilePathMock.mockReturnValueOnce(davinciJestConfigPath)
|
|
162
162
|
const customCLIReporter = 'My-CLI-Reporter'
|
|
163
163
|
|
|
164
|
-
await unitTestCommand({
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
reporters: customCLIReporter,
|
|
168
|
-
},
|
|
164
|
+
await unitTestCommand([], {
|
|
165
|
+
anvilTag: 'MyTag',
|
|
166
|
+
reporters: customCLIReporter,
|
|
169
167
|
})
|
|
170
168
|
|
|
171
169
|
expect(jestRunCLIMock).toHaveBeenCalledWith(
|
|
@@ -186,7 +184,7 @@ describe('unitTestsCommand', () => {
|
|
|
186
184
|
reporters: customJestConfigReporter,
|
|
187
185
|
})
|
|
188
186
|
|
|
189
|
-
await unitTestCommand(
|
|
187
|
+
await unitTestCommand([], { config: {} })
|
|
190
188
|
|
|
191
189
|
expect(jestRunCLIMock).toHaveBeenCalledWith(
|
|
192
190
|
expect.objectContaining({
|
|
@@ -207,12 +205,10 @@ describe('unitTestsCommand', () => {
|
|
|
207
205
|
reporters: customJestConfigReporter,
|
|
208
206
|
})
|
|
209
207
|
|
|
210
|
-
await unitTestCommand({
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
config: {},
|
|
215
|
-
},
|
|
208
|
+
await unitTestCommand([], {
|
|
209
|
+
anvilTag: 'MyTag',
|
|
210
|
+
reporters: customCLIReporter,
|
|
211
|
+
config: {},
|
|
216
212
|
})
|
|
217
213
|
|
|
218
214
|
expect(jestRunCLIMock).toHaveBeenCalledWith(
|
package/src/index.js
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
import integrationOpenCommandCreator from './commands/integration-open.js'
|
|
3
|
-
import integrationRunCommandCreator from './commands/integration-run.js'
|
|
1
|
+
import { createLintCodeCommand } from './commands/unit-tests.js'
|
|
4
2
|
import codeMetricsCommandCreator from './commands/code-metrics.js'
|
|
5
3
|
import happoConfig from './configs/happo.cjs'
|
|
4
|
+
import { createIntegrationRunCommand } from './commands/integration-run.js'
|
|
5
|
+
import { createIntegrationOpenCommand } from './commands/integration-open.js'
|
|
6
6
|
|
|
7
7
|
export const commands = [
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
createLintCodeCommand,
|
|
9
|
+
program =>
|
|
10
|
+
program
|
|
11
|
+
.createCommand('integration')
|
|
12
|
+
.addCommand(createIntegrationRunCommand(program))
|
|
13
|
+
.addCommand(createIntegrationOpenCommand(program)),
|
|
11
14
|
codeMetricsCommandCreator,
|
|
12
15
|
]
|
|
13
16
|
|