nuxt-spec 0.4.0-alpha.1 → 0.4.0-alpha.2
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/bin/cli.js +18 -9
- package/bin/commands/ci.js +124 -0
- package/bin/{setup.js → commands/setup.js} +14 -13
- package/bin/{update.js → commands/update.js} +38 -6
- package/bin/helpers/constants.js +8 -0
- package/bin/helpers/git.js +73 -0
- package/config/index.mjs +7 -0
- package/config/templates/.github/workflows/ci-test-update.yml.template +105 -0
- package/config/templates/.github/workflows/ci-test-verify.yml.template +68 -0
- package/config/templates/.gitlab/ci/ci-test-update.yml.template +69 -0
- package/config/templates/.gitlab/ci/ci-test-verify.yml.template +41 -0
- package/config/templates/.gitlab-ci.yml.template +6 -0
- package/nuxt.config.ts +1 -1
- package/package.json +10 -6
package/bin/cli.js
CHANGED
|
@@ -5,12 +5,15 @@ import { getCmd, resolvePackageManager } from './helpers/commands.js'
|
|
|
5
5
|
/**
|
|
6
6
|
* CLI tool to scaffold necessary adjustments in project folder.
|
|
7
7
|
*
|
|
8
|
-
* Allows `setup` or `
|
|
8
|
+
* Allows `setup`, `update` or `ci` to be passed as parameter.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
10
|
+
* `ci` requires the target Git host (`github` or `gitlab`) as the next parameter,
|
|
11
|
+
* the remaining optional parameters are shifted by one position (package manager is not used yet).
|
|
12
|
+
*
|
|
13
|
+
* Next (optional) parameter might be a boolean to indicate auto mode
|
|
11
14
|
* (no prompts, force = true) or manual mode (with prompts, force = false).
|
|
12
15
|
*
|
|
13
|
-
*
|
|
16
|
+
* Next (optional) parameter allows explicitly passing the package manager
|
|
14
17
|
* (`npm`, `pnpm`, `yarn`, `bun` or `deno`), bypassing auto-detection.
|
|
15
18
|
*/
|
|
16
19
|
|
|
@@ -22,18 +25,24 @@ const args = process.argv.slice(2);
|
|
|
22
25
|
(async () => {
|
|
23
26
|
let status = 0
|
|
24
27
|
try {
|
|
25
|
-
const
|
|
28
|
+
const command = args[0]
|
|
29
|
+
const host = command === 'ci' ? args[1] : undefined
|
|
30
|
+
const [autoRunArg, packageManagerArg] = args.slice(command === 'ci' ? 2 : 1)
|
|
31
|
+
const packageManager = resolvePackageManager(packageManagerArg)
|
|
26
32
|
// CLI args are always strings, so 'false' must be parsed explicitly rather than treated as truthy
|
|
27
|
-
const autoRun =
|
|
28
|
-
switch (
|
|
33
|
+
const autoRun = autoRunArg === 'true'
|
|
34
|
+
switch (command) {
|
|
29
35
|
case 'setup':
|
|
30
|
-
await (await import('./setup.js')).specSetup(autoRun, packageManager)
|
|
36
|
+
await (await import('./commands/setup.js')).specSetup(autoRun, packageManager)
|
|
31
37
|
break
|
|
32
38
|
case 'update':
|
|
33
|
-
await (await import('./update.js')).specUpdate(autoRun, packageManager)
|
|
39
|
+
await (await import('./commands/update.js')).specUpdate(autoRun, packageManager)
|
|
40
|
+
break
|
|
41
|
+
case 'ci':
|
|
42
|
+
await (await import('./commands/ci.js')).specCi(host, autoRun)
|
|
34
43
|
break
|
|
35
44
|
default:
|
|
36
|
-
console.log(`[Nuxt Spec] Usage: \`${getCmd(packageManager)} setup [true|false] [npm|pnpm|yarn|bun|deno]
|
|
45
|
+
console.log(`[Nuxt Spec] Usage: \`${getCmd(packageManager)} setup [true|false] [npm|pnpm|yarn|bun|deno]\`, \`${getCmd(packageManager)} update [true|false] [npm|pnpm|yarn|bun|deno]\` or \`${getCmd(packageManager)} ci <github|gitlab> [true|false]\``)
|
|
37
46
|
status = 1
|
|
38
47
|
}
|
|
39
48
|
} catch (error) {
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFileSync, writeFileSync } from 'node:fs'
|
|
4
|
+
import {
|
|
5
|
+
createFileFromWebTemplate, pathExists, promptUser, showMessage, updateYamlFile,
|
|
6
|
+
} from 'elrh-cosca'
|
|
7
|
+
import { isGitRepo, resolveDefaultBranch } from '../helpers/git.js'
|
|
8
|
+
import { COSCA_URL, PLAYWRIGHT_VERSION } from '../helpers/constants.js'
|
|
9
|
+
|
|
10
|
+
const SUPPORTED_CI_HOSTS = ['github', 'gitlab']
|
|
11
|
+
|
|
12
|
+
const GITLAB_ROOT_FILE = '.gitlab-ci.yml'
|
|
13
|
+
|
|
14
|
+
export const CI_TEMPLATES = {
|
|
15
|
+
github: [
|
|
16
|
+
{ template: '.github/workflows/ci-test-verify.yml.template', targetFile: '.github/workflows/ci-test-verify.yml' },
|
|
17
|
+
{ template: '.github/workflows/ci-test-update.yml.template', targetFile: '.github/workflows/ci-test-update.yml' },
|
|
18
|
+
],
|
|
19
|
+
gitlab: [
|
|
20
|
+
{ template: '.gitlab/ci/ci-test-verify.yml.template', targetFile: '.gitlab/ci/ci-test-verify.yml' },
|
|
21
|
+
{ template: '.gitlab/ci/ci-test-update.yml.template', targetFile: '.gitlab/ci/ci-test-update.yml' },
|
|
22
|
+
],
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function getDefaultBranch() {
|
|
26
|
+
if (!isGitRepo()) {
|
|
27
|
+
console.warn('[Nuxt Spec] Current folder is not a Git repository.')
|
|
28
|
+
}
|
|
29
|
+
const { branch, source } = resolveDefaultBranch()
|
|
30
|
+
// value is inserted into YAML unquoted
|
|
31
|
+
if (!/^[\w./+-]+$/.test(branch)) {
|
|
32
|
+
throw new Error(`Default branch name '${branch}' (resolved from ${source}) contains unsupported characters.`)
|
|
33
|
+
}
|
|
34
|
+
showMessage({ message: `[Nuxt Spec] Using '${branch}' as the default branch (resolved from ${source}).` })
|
|
35
|
+
return branch
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* CLI tool to scaffold CI test workflows for selected Git host.
|
|
40
|
+
*
|
|
41
|
+
* It first asks whether to run in "auto" mode (no prompts, force = true) or "manual" mode (with prompts, force = false).
|
|
42
|
+
*
|
|
43
|
+
* Then it:
|
|
44
|
+
* 1) creates CI workflow files for the selected host
|
|
45
|
+
* 2) fills in placeholders - Playwright version and default branch of the Git repository in the current folder (resolved only if used)
|
|
46
|
+
* 3) (GitLab only) adds CI files into `include` section of `.gitlab-ci.yml` (scaffolded from template if missing)
|
|
47
|
+
*
|
|
48
|
+
* @param {string} host - Target Git host (`github` or `gitlab`).
|
|
49
|
+
* @param {boolean} autoRun - Whether to run the scaffolding automatically without any prompts (defaults to false).
|
|
50
|
+
*/
|
|
51
|
+
export async function specCi(host, autoRun = false) {
|
|
52
|
+
showMessage({ message: 'NUXT SPEC CI' })
|
|
53
|
+
showMessage({ message: `This CLI tool will help you scaffold CI test workflows for '${host}'.` })
|
|
54
|
+
showMessage({ message: 'Refer to the documentation for more information.', linesAfter: 2 })
|
|
55
|
+
|
|
56
|
+
if (!SUPPORTED_CI_HOSTS.includes(host)) {
|
|
57
|
+
throw new Error(`${host ? `Unsupported CI host '${host}'` : 'Missing CI host'}. Use one of: ${SUPPORTED_CI_HOSTS.join(', ')}`)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const templates = CI_TEMPLATES[host]
|
|
61
|
+
|
|
62
|
+
const isAutoRun = autoRun || await promptUser({ question: '[Nuxt Spec] Do you want to scaffold everything automatically (no more prompts)?' })
|
|
63
|
+
showMessage({ message: '' })
|
|
64
|
+
|
|
65
|
+
let branch
|
|
66
|
+
const created = []
|
|
67
|
+
for (const { template, targetFile } of templates) {
|
|
68
|
+
// 1) create workflow files
|
|
69
|
+
const exists = pathExists({ targetPath: targetFile })
|
|
70
|
+
const proceed = isAutoRun || await promptUser({
|
|
71
|
+
question: exists
|
|
72
|
+
? `[Nuxt Spec] File '${targetFile}' already exists. Overwrite?`
|
|
73
|
+
: `[Nuxt Spec] This will create '${targetFile}' file. Continue?`,
|
|
74
|
+
})
|
|
75
|
+
if (!proceed) {
|
|
76
|
+
if (!exists) {
|
|
77
|
+
throw new Error(`Creation of '${targetFile}' declined - CI setup cannot be completed without it.`)
|
|
78
|
+
}
|
|
79
|
+
console.log(`[Nuxt Spec] Existing '${targetFile}' kept.`)
|
|
80
|
+
continue
|
|
81
|
+
}
|
|
82
|
+
await createFileFromWebTemplate({ url: `${COSCA_URL}/config/templates/${template}`, targetFile, force: true })
|
|
83
|
+
|
|
84
|
+
// 2) fill in placeholders
|
|
85
|
+
let content = readFileSync(targetFile, 'utf8').replaceAll('__PLAYWRIGHT_VERSION__', PLAYWRIGHT_VERSION)
|
|
86
|
+
if (content.includes('__DEFAULT_BRANCH__')) {
|
|
87
|
+
branch ??= getDefaultBranch()
|
|
88
|
+
content = content.replaceAll('__DEFAULT_BRANCH__', branch)
|
|
89
|
+
}
|
|
90
|
+
writeFileSync(targetFile, content)
|
|
91
|
+
created.push(targetFile)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 3) (GitLab only) register CI files in root pipeline
|
|
95
|
+
if (host === 'gitlab') {
|
|
96
|
+
if (pathExists({ targetPath: GITLAB_ROOT_FILE })) {
|
|
97
|
+
await updateYamlFile({
|
|
98
|
+
targetFile: GITLAB_ROOT_FILE,
|
|
99
|
+
yamlKey: 'include',
|
|
100
|
+
patch: templates.map(({ targetFile }) => ({ local: targetFile })),
|
|
101
|
+
force: isAutoRun,
|
|
102
|
+
prompt: `[Nuxt Spec] This will add CI files into 'include' section of your '${GITLAB_ROOT_FILE}'. Continue?`,
|
|
103
|
+
})
|
|
104
|
+
} else {
|
|
105
|
+
await createFileFromWebTemplate({
|
|
106
|
+
url: `${COSCA_URL}/config/templates/${GITLAB_ROOT_FILE}.template`,
|
|
107
|
+
targetFile: GITLAB_ROOT_FILE,
|
|
108
|
+
force: isAutoRun,
|
|
109
|
+
prompt: `[Nuxt Spec] This will create '${GITLAB_ROOT_FILE}' file including the CI files. Continue?`,
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// 4) inform user
|
|
115
|
+
showMessage({ message: '' })
|
|
116
|
+
showMessage({ message: 'NUXT SPEC CI COMPLETE', linesAfter: 2 })
|
|
117
|
+
if (created.length > 0) {
|
|
118
|
+
showMessage({ message: 'Review the created files and complete the prerequisites described in their headers.' })
|
|
119
|
+
}
|
|
120
|
+
if (branch) {
|
|
121
|
+
showMessage({ message: `Verify '${branch}' is the correct default branch.` })
|
|
122
|
+
showMessage({ message: `If not, run \`git remote set-head origin --auto\` and re-run this command, or adjust the files manually.` })
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -9,9 +9,8 @@ import {
|
|
|
9
9
|
} from 'elrh-cosca'
|
|
10
10
|
import {
|
|
11
11
|
getPlaywrightInstallCmd, getPrepareCmd,
|
|
12
|
-
} from '
|
|
13
|
-
|
|
14
|
-
const TARGET_VERSION = '0.4.0-alpha.1'
|
|
12
|
+
} from '../helpers/commands.js'
|
|
13
|
+
import { COSCA_VERSION, COSCA_URL } from '../helpers/constants.js'
|
|
15
14
|
|
|
16
15
|
/**
|
|
17
16
|
* CLI tool to scaffold necessary adjustments in project folder.
|
|
@@ -51,7 +50,7 @@ export async function specSetup(autoRun = false, packageManager) {
|
|
|
51
50
|
targetFile: 'package.json',
|
|
52
51
|
jsonKey: 'dependencies',
|
|
53
52
|
patch: {
|
|
54
|
-
['nuxt-spec']:
|
|
53
|
+
['nuxt-spec']: COSCA_VERSION,
|
|
55
54
|
},
|
|
56
55
|
force: isAutoRun,
|
|
57
56
|
prompt: `[Nuxt Spec] This will add 'nuxt-spec' dependency to your 'package.json'. Continue?`,
|
|
@@ -123,7 +122,7 @@ export async function specSetup(autoRun = false, packageManager) {
|
|
|
123
122
|
})
|
|
124
123
|
} else {
|
|
125
124
|
await createFileFromWebTemplate({
|
|
126
|
-
url:
|
|
125
|
+
url: `${COSCA_URL}/config/templates/pnpm-workspace.yaml.template`,
|
|
127
126
|
targetFile: 'pnpm-workspace.yaml',
|
|
128
127
|
force: isAutoRun,
|
|
129
128
|
prompt: '[Nuxt Spec] This will add \'pnpm-workspace.yaml\' file for your project. Continue?',
|
|
@@ -137,7 +136,7 @@ export async function specSetup(autoRun = false, packageManager) {
|
|
|
137
136
|
// 4) create vitest.config.ts
|
|
138
137
|
try {
|
|
139
138
|
await createFileFromWebTemplate({
|
|
140
|
-
url:
|
|
139
|
+
url: `${COSCA_URL}/config/templates/vitest.config.ts.template`,
|
|
141
140
|
targetFile: 'vitest.config.ts',
|
|
142
141
|
force: isAutoRun,
|
|
143
142
|
prompt: '[Nuxt Spec] This will create a new \'vitest.config.ts\' file for your project. Continue?',
|
|
@@ -150,7 +149,7 @@ export async function specSetup(autoRun = false, packageManager) {
|
|
|
150
149
|
if (!pathExists({ targetPath: '.nuxtrc' })) {
|
|
151
150
|
try {
|
|
152
151
|
await createFileFromWebTemplate({
|
|
153
|
-
url:
|
|
152
|
+
url: `${COSCA_URL}/.nuxtrc`,
|
|
154
153
|
targetFile: '.nuxtrc',
|
|
155
154
|
force: isAutoRun,
|
|
156
155
|
prompt: '[Nuxt Spec] This will create a \'.nuxtrc\' file to prevent @nuxt/test-utils setup from running automatically when dev server starts. Continue?',
|
|
@@ -168,6 +167,7 @@ export async function specSetup(autoRun = false, packageManager) {
|
|
|
168
167
|
patch: {
|
|
169
168
|
'test': 'vitest run',
|
|
170
169
|
'test-u': 'vitest run -u',
|
|
170
|
+
'test-c': 'vitest run --coverage',
|
|
171
171
|
'test-i': 'vitest',
|
|
172
172
|
},
|
|
173
173
|
force: isAutoRun,
|
|
@@ -182,7 +182,7 @@ export async function specSetup(autoRun = false, packageManager) {
|
|
|
182
182
|
if (createSampleTests) {
|
|
183
183
|
try {
|
|
184
184
|
await createFileFromWebTemplate({
|
|
185
|
-
url:
|
|
185
|
+
url: `${COSCA_URL}/test/browser/vitest-browser.test.ts`,
|
|
186
186
|
targetFile: 'test/browser/vitest-browser.test.ts',
|
|
187
187
|
force: true,
|
|
188
188
|
})
|
|
@@ -191,7 +191,7 @@ export async function specSetup(autoRun = false, packageManager) {
|
|
|
191
191
|
}
|
|
192
192
|
try {
|
|
193
193
|
await createFileFromWebTemplate({
|
|
194
|
-
url:
|
|
194
|
+
url: `${COSCA_URL}/test/e2e/nuxt-e2e.test.ts`,
|
|
195
195
|
targetFile: 'test/e2e/nuxt-e2e.test.ts',
|
|
196
196
|
force: true,
|
|
197
197
|
})
|
|
@@ -200,7 +200,7 @@ export async function specSetup(autoRun = false, packageManager) {
|
|
|
200
200
|
}
|
|
201
201
|
try {
|
|
202
202
|
await createFileFromWebTemplate({
|
|
203
|
-
url:
|
|
203
|
+
url: `${COSCA_URL}/test/e2e/nuxt-visual.test.ts`,
|
|
204
204
|
targetFile: 'test/e2e/nuxt-visual.test.ts',
|
|
205
205
|
force: true,
|
|
206
206
|
})
|
|
@@ -210,7 +210,7 @@ export async function specSetup(autoRun = false, packageManager) {
|
|
|
210
210
|
// pre-existing baseline ensures the sample "wrong" visual test fails as intended
|
|
211
211
|
try {
|
|
212
212
|
await createFileFromWebTemplate({
|
|
213
|
-
url:
|
|
213
|
+
url: `${COSCA_URL}/test/e2e/__baseline__/wrong.png`,
|
|
214
214
|
targetFile: 'test/e2e/__baseline__/wrong.png',
|
|
215
215
|
force: true,
|
|
216
216
|
})
|
|
@@ -219,7 +219,7 @@ export async function specSetup(autoRun = false, packageManager) {
|
|
|
219
219
|
}
|
|
220
220
|
try {
|
|
221
221
|
await createFileFromWebTemplate({
|
|
222
|
-
url:
|
|
222
|
+
url: `${COSCA_URL}/test/nuxt/nuxt-unit.test.ts`,
|
|
223
223
|
targetFile: 'test/nuxt/nuxt-unit.test.ts',
|
|
224
224
|
force: true,
|
|
225
225
|
})
|
|
@@ -228,7 +228,7 @@ export async function specSetup(autoRun = false, packageManager) {
|
|
|
228
228
|
}
|
|
229
229
|
try {
|
|
230
230
|
await createFileFromWebTemplate({
|
|
231
|
-
url:
|
|
231
|
+
url: `${COSCA_URL}/test/unit/vitest-unit.test.ts`,
|
|
232
232
|
targetFile: 'test/unit/vitest-unit.test.ts',
|
|
233
233
|
force: true,
|
|
234
234
|
})
|
|
@@ -241,6 +241,7 @@ export async function specSetup(autoRun = false, packageManager) {
|
|
|
241
241
|
try {
|
|
242
242
|
const gitignoreEntries = [
|
|
243
243
|
['# vitest output folder', '.vitest'],
|
|
244
|
+
['# vitest coverage output folder', 'coverage'],
|
|
244
245
|
['# nuxt-spec screenshots folder', '__current__'],
|
|
245
246
|
['# nuxt-spec HTML test reports folder', '__reports__'],
|
|
246
247
|
]
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { execSync } from 'node:child_process'
|
|
4
|
+
import { readFileSync, writeFileSync } from 'node:fs'
|
|
4
5
|
import {
|
|
5
|
-
hasJsonKey, promptUser, showMessage,
|
|
6
|
+
hasJsonKey, pathExists, promptUser, showMessage,
|
|
6
7
|
} from 'elrh-cosca'
|
|
8
|
+
import { CI_TEMPLATES } from './ci.js'
|
|
7
9
|
import {
|
|
8
10
|
getPlaywrightInstallCmd, getPrepareCmd, getUpdateCmd,
|
|
9
|
-
} from '
|
|
11
|
+
} from '../helpers/commands.js'
|
|
12
|
+
import { COSCA_VERSION, PLAYWRIGHT_VERSION } from '../helpers/constants.js'
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
// for automated version patching in CI workflow files
|
|
15
|
+
const PLAYWRIGHT_IMAGE_REGEX = /(mcr\.microsoft\.com\/playwright:v)\d+\.\d+\.\d+/g
|
|
12
16
|
|
|
13
17
|
/**
|
|
14
18
|
* CLI tool to update existing `nuxt-spec` installation.
|
|
@@ -20,6 +24,7 @@ const TARGET_VERSION = '0.4.0-alpha.1'
|
|
|
20
24
|
* 2) runs the package manager's update command to bump `nuxt-spec` to the latest version
|
|
21
25
|
* 3) run the `nuxt prepare` command to regenerate types and auto-imports
|
|
22
26
|
* 4) run the `playwright install` command to ensure the Playwright browser runtimes are up to date
|
|
27
|
+
* 5) bump the Playwright container image version in CI workflow files created by the `ci` command
|
|
23
28
|
*
|
|
24
29
|
* @param {boolean} autoRun - Whether to run the update automatically without any prompts (defaults to false).
|
|
25
30
|
* @param {string} [packageManager] - Package manager to be used (`npm`, `pnpm`, `yarn`, `bun` or `deno`).
|
|
@@ -41,8 +46,8 @@ export async function specUpdate(autoRun = false, packageManager) {
|
|
|
41
46
|
showMessage({ message: '' })
|
|
42
47
|
|
|
43
48
|
// 1) run 'update nuxt-spec'
|
|
44
|
-
const updateCmd = getUpdateCmd(packageManager, `nuxt-spec@${
|
|
45
|
-
const runUpdate = isAutoRun || await promptUser({ question: `[Nuxt Spec] This will bump 'nuxt-spec' to version '${
|
|
49
|
+
const updateCmd = getUpdateCmd(packageManager, `nuxt-spec@${COSCA_VERSION}`)
|
|
50
|
+
const runUpdate = isAutoRun || await promptUser({ question: `[Nuxt Spec] This will bump 'nuxt-spec' to version '${COSCA_VERSION}' by running \`${updateCmd}\`. Continue?` })
|
|
46
51
|
if (runUpdate) {
|
|
47
52
|
try {
|
|
48
53
|
showMessage({ message: `Running \`${updateCmd}\`...` })
|
|
@@ -76,7 +81,31 @@ export async function specUpdate(autoRun = false, packageManager) {
|
|
|
76
81
|
}
|
|
77
82
|
}
|
|
78
83
|
|
|
79
|
-
// 4)
|
|
84
|
+
// 4) bump Playwright container image in CI workflow files
|
|
85
|
+
const outdatedCiFiles = []
|
|
86
|
+
const ciFiles = Object.values(CI_TEMPLATES).flat()
|
|
87
|
+
.map(({ targetFile }) => targetFile)
|
|
88
|
+
.filter(targetFile => pathExists({ targetPath: targetFile }))
|
|
89
|
+
for (const targetFile of ciFiles) {
|
|
90
|
+
try {
|
|
91
|
+
const content = readFileSync(targetFile, 'utf8')
|
|
92
|
+
const bumped = content.replace(PLAYWRIGHT_IMAGE_REGEX, `$1${PLAYWRIGHT_VERSION}`)
|
|
93
|
+
if (bumped === content) {
|
|
94
|
+
continue
|
|
95
|
+
}
|
|
96
|
+
const runBump = isAutoRun || await promptUser({ question: `[Nuxt Spec] This will bump the Playwright container image in '${targetFile}' to version '${PLAYWRIGHT_VERSION}'. Continue?` })
|
|
97
|
+
if (runBump) {
|
|
98
|
+
writeFileSync(targetFile, bumped)
|
|
99
|
+
showMessage({ message: `Playwright container image in '${targetFile}' bumped to version '${PLAYWRIGHT_VERSION}'.` })
|
|
100
|
+
} else {
|
|
101
|
+
outdatedCiFiles.push(targetFile)
|
|
102
|
+
}
|
|
103
|
+
} catch (error) {
|
|
104
|
+
console.error(`[Nuxt Spec] Error bumping Playwright container image in '${targetFile}':\n`, error.message)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// 5) inform user
|
|
80
109
|
showMessage({ message: '' })
|
|
81
110
|
showMessage({ message: 'NUXT SPEC UPDATE COMPLETE', linesAfter: 2 })
|
|
82
111
|
if (!runUpdate) {
|
|
@@ -88,6 +117,9 @@ export async function specUpdate(autoRun = false, packageManager) {
|
|
|
88
117
|
if (!runPlaywrightUpdate) {
|
|
89
118
|
showMessage({ message: `Run \`${playwrightUpdateCmd}\` to update the Playwright browser runtimes for e2e tests.` })
|
|
90
119
|
}
|
|
120
|
+
for (const targetFile of outdatedCiFiles) {
|
|
121
|
+
showMessage({ message: `Bump the Playwright container image in '${targetFile}' to version '${PLAYWRIGHT_VERSION}' to match the \`playwright\` dependency.` })
|
|
122
|
+
}
|
|
91
123
|
|
|
92
124
|
// force exit to prevent #20
|
|
93
125
|
process.exit(0)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// current elrh-cosca version for usage in CLI scripts
|
|
2
|
+
export const COSCA_VERSION = '0.4.0-alpha.2'
|
|
3
|
+
|
|
4
|
+
// URL to current tag in GitHub repository to fetch template files in CLI scripts
|
|
5
|
+
export const COSCA_URL = `https://raw.githubusercontent.com/AloisSeckar/nuxt-spec/refs/tags/v${COSCA_VERSION}`
|
|
6
|
+
|
|
7
|
+
// current Playwright version for usage in CLI scripts
|
|
8
|
+
export const PLAYWRIGHT_VERSION = '1.64.0'
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process'
|
|
2
|
+
|
|
3
|
+
export const FALLBACK_DEFAULT_BRANCH = 'main'
|
|
4
|
+
|
|
5
|
+
// run a read-only git command, returning trimmed stdout or `undefined` on failure
|
|
6
|
+
function git(...args) {
|
|
7
|
+
try {
|
|
8
|
+
return execFileSync('git', args, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim() || undefined
|
|
9
|
+
} catch {
|
|
10
|
+
return undefined
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function hasRef(ref) {
|
|
15
|
+
try {
|
|
16
|
+
execFileSync('git', ['show-ref', '--verify', '--quiet', ref], { stdio: 'ignore' })
|
|
17
|
+
return true
|
|
18
|
+
} catch {
|
|
19
|
+
return false
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function isGitRepo() {
|
|
24
|
+
return git('rev-parse', '--is-inside-work-tree') === 'true'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Resolve the default branch of the Git repository in the current working directory.
|
|
29
|
+
*
|
|
30
|
+
* Tries (in order):
|
|
31
|
+
* 1) HEAD of `origin` remote (or the first available remote) - set when cloned or via `git remote set-head <remote> --auto`
|
|
32
|
+
* 2) existing local or remote-tracking `main` or `master` branch
|
|
33
|
+
* 3) the only local branch, or current branch if there are no commits yet
|
|
34
|
+
* 4) `init.defaultBranch` from Git config
|
|
35
|
+
*
|
|
36
|
+
* @returns {{ branch: string, source: string }} resolved branch name and description of where it came from
|
|
37
|
+
*/
|
|
38
|
+
export function resolveDefaultBranch() {
|
|
39
|
+
if (isGitRepo()) {
|
|
40
|
+
const remotes = git('remote')?.split(/\r?\n/) ?? []
|
|
41
|
+
const remote = remotes.includes('origin') ? 'origin' : remotes[0]
|
|
42
|
+
if (remote) {
|
|
43
|
+
const remoteHead = git('symbolic-ref', '--quiet', '--short', `refs/remotes/${remote}/HEAD`)
|
|
44
|
+
if (remoteHead?.startsWith(`${remote}/`)) {
|
|
45
|
+
return { branch: remoteHead.slice(remote.length + 1), source: `HEAD of '${remote}' remote` }
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
for (const candidate of ['main', 'master']) {
|
|
50
|
+
if (hasRef(`refs/heads/${candidate}`) || (remote && hasRef(`refs/remotes/${remote}/${candidate}`))) {
|
|
51
|
+
return { branch: candidate, source: 'existing branch' }
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const localBranches = git('for-each-ref', '--format=%(refname:short)', 'refs/heads')?.split(/\r?\n/) ?? []
|
|
56
|
+
if (localBranches.length === 1) {
|
|
57
|
+
return { branch: localBranches[0], source: 'the only local branch' }
|
|
58
|
+
}
|
|
59
|
+
if (localBranches.length === 0) {
|
|
60
|
+
const unbornHead = git('symbolic-ref', '--quiet', '--short', 'HEAD')
|
|
61
|
+
if (unbornHead) {
|
|
62
|
+
return { branch: unbornHead, source: 'current branch of repository without commits' }
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const configured = git('config', '--get', 'init.defaultBranch')
|
|
68
|
+
if (configured) {
|
|
69
|
+
return { branch: configured, source: 'Git config \'init.defaultBranch\'' }
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return { branch: FALLBACK_DEFAULT_BRANCH, source: 'fallback value' }
|
|
73
|
+
}
|
package/config/index.mjs
CHANGED
|
@@ -32,6 +32,13 @@ export async function loadVitestConfig(userVitestConfig, projects = true) {
|
|
|
32
32
|
// Vitest defaults to 5 which might be unnecessarily restrictive
|
|
33
33
|
// if the host machine can support more
|
|
34
34
|
maxConcurrency: availableParallelism() / 2,
|
|
35
|
+
// coverage is NOT enabled by default
|
|
36
|
+
// (use `test-c` command or `--coverage` flag)
|
|
37
|
+
// Bun runtime lacks support for the V8 provider
|
|
38
|
+
// (`bun run` without `--bun` still runs Vitest in Node, where V8 works)
|
|
39
|
+
coverage: {
|
|
40
|
+
provider: process.versions.bun ? 'istanbul' : 'v8',
|
|
41
|
+
},
|
|
35
42
|
},
|
|
36
43
|
}
|
|
37
44
|
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# GitHub Actions workflow (scaffolded by Nuxt Spec) to update test baselines (manually triggered).
|
|
2
|
+
# Runs in the same pinned Playwright container as "verify" workflow.
|
|
3
|
+
# Updated baselines (`__baseline__`, `__screenshots__`) and snapshots (`__snapshots__`) are committed back to the dispatched branch.
|
|
4
|
+
# If the push is rejected (e.g. protected branch), a new branch with a pull request is created instead.
|
|
5
|
+
# PREREQUISITE: for the pull request fallback, enable
|
|
6
|
+
# "Settings > Actions > General > Allow GitHub Actions to create and approve pull requests".
|
|
7
|
+
# NOTE: commits and pull requests created via GITHUB_TOKEN don't trigger other workflows - run "verify" manually afterwards.
|
|
8
|
+
|
|
9
|
+
name: Nuxt Spec CI Tests (update baselines)
|
|
10
|
+
|
|
11
|
+
on:
|
|
12
|
+
workflow_dispatch:
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: ci-test-update-${{ github.ref }}
|
|
16
|
+
cancel-in-progress: false
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: write
|
|
20
|
+
pull-requests: write
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
update:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
container:
|
|
26
|
+
# must match `playwright` dependency version
|
|
27
|
+
image: mcr.microsoft.com/playwright:v__PLAYWRIGHT_VERSION__-jammy
|
|
28
|
+
steps:
|
|
29
|
+
- name: Checkout
|
|
30
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
31
|
+
with:
|
|
32
|
+
ref: ${{ github.ref_name }}
|
|
33
|
+
|
|
34
|
+
- name: Enable pnpm via corepack
|
|
35
|
+
run: corepack enable
|
|
36
|
+
|
|
37
|
+
- name: Resolve pnpm store path
|
|
38
|
+
id: pnpm-store
|
|
39
|
+
run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"
|
|
40
|
+
|
|
41
|
+
- name: Cache pnpm store
|
|
42
|
+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
43
|
+
with:
|
|
44
|
+
path: ${{ steps.pnpm-store.outputs.path }}
|
|
45
|
+
key: pnpm-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
|
46
|
+
restore-keys: pnpm-${{ runner.os }}-
|
|
47
|
+
|
|
48
|
+
- name: Install dependencies
|
|
49
|
+
run: pnpm install --frozen-lockfile
|
|
50
|
+
|
|
51
|
+
- name: Prune pnpm store
|
|
52
|
+
run: pnpm store prune
|
|
53
|
+
|
|
54
|
+
- name: Regenerate test baselines
|
|
55
|
+
run: pnpm test-u
|
|
56
|
+
|
|
57
|
+
- name: Commit updated baselines
|
|
58
|
+
env:
|
|
59
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
60
|
+
REPO: ${{ github.repository }}
|
|
61
|
+
REF_NAME: ${{ github.ref_name }}
|
|
62
|
+
RUN_NUMBER: ${{ github.run_number }}
|
|
63
|
+
run: |
|
|
64
|
+
set -eu
|
|
65
|
+
|
|
66
|
+
git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
|
67
|
+
git config user.name "github-actions[bot]"
|
|
68
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
69
|
+
|
|
70
|
+
# `git add` fails on a glob without matches, `git ls-files` doesn't
|
|
71
|
+
git ls-files -z -m -d -o --exclude-standard -- \
|
|
72
|
+
':(glob)**/__baseline__/**' \
|
|
73
|
+
':(glob)**/__screenshots__/**' \
|
|
74
|
+
':(glob)**/__snapshots__/**' \
|
|
75
|
+
| xargs -0 -r git add -A --
|
|
76
|
+
if git diff --cached --quiet; then
|
|
77
|
+
echo "No baseline changes to commit."
|
|
78
|
+
exit 0
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
git commit -m "test(ci): update test baselines"
|
|
82
|
+
|
|
83
|
+
if git push origin "HEAD:$REF_NAME"; then
|
|
84
|
+
echo "Updated baselines pushed to '$REF_NAME'."
|
|
85
|
+
exit 0
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
echo "Push to '$REF_NAME' was rejected (e.g. protected branch) - creating pull request..."
|
|
89
|
+
export NEW_BRANCH="ci-test/update-$(date +%Y%m%d%H%M%S)"
|
|
90
|
+
git push origin "HEAD:refs/heads/$NEW_BRANCH"
|
|
91
|
+
BODY=$(node -e '
|
|
92
|
+
const { NEW_BRANCH, REF_NAME, RUN_NUMBER } = process.env
|
|
93
|
+
console.log(JSON.stringify({
|
|
94
|
+
title: "test(ci): update test baselines",
|
|
95
|
+
head: NEW_BRANCH,
|
|
96
|
+
base: REF_NAME,
|
|
97
|
+
body: `Test baselines update triggered on run #${RUN_NUMBER} against branch \`${REF_NAME}\`.`,
|
|
98
|
+
}))')
|
|
99
|
+
curl -sS -X POST \
|
|
100
|
+
-H "Authorization: Bearer $GH_TOKEN" \
|
|
101
|
+
-H "Accept: application/vnd.github+json" \
|
|
102
|
+
-H "Content-Type: application/json" \
|
|
103
|
+
-d "$BODY" \
|
|
104
|
+
--fail-with-body \
|
|
105
|
+
"https://api.github.com/repos/$REPO/pulls"
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# GitHub Actions workflow (scaffolded by Nuxt Spec) to run test suite in a pinned Playwright container for reproducible results.
|
|
2
|
+
# Triggered automatically on push/pull requests to default branch with possible manual dispatch.
|
|
3
|
+
# Uses pnpm - the pnpm store is cached so subsequent `pnpm install` runs reuse downloaded deps.
|
|
4
|
+
# If tests fail, `ci-test-report` artifact (HTML report, current screenshots, Vitest attachments) is uploaded for inspection.
|
|
5
|
+
# NOTE: commits pushed by "update baselines" workflow don't trigger this workflow - dispatch it manually afterwards.
|
|
6
|
+
|
|
7
|
+
name: Nuxt Spec CI Tests (verify)
|
|
8
|
+
|
|
9
|
+
on:
|
|
10
|
+
push:
|
|
11
|
+
branches: [__DEFAULT_BRANCH__]
|
|
12
|
+
pull_request:
|
|
13
|
+
branches: [__DEFAULT_BRANCH__]
|
|
14
|
+
workflow_dispatch:
|
|
15
|
+
|
|
16
|
+
concurrency:
|
|
17
|
+
group: ci-test-verify-${{ github.ref }}
|
|
18
|
+
cancel-in-progress: true
|
|
19
|
+
|
|
20
|
+
permissions:
|
|
21
|
+
contents: read
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
verify:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
container:
|
|
27
|
+
# must match `playwright` dependency version
|
|
28
|
+
image: mcr.microsoft.com/playwright:v__PLAYWRIGHT_VERSION__-jammy
|
|
29
|
+
steps:
|
|
30
|
+
- name: Checkout
|
|
31
|
+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
32
|
+
|
|
33
|
+
- name: Enable pnpm via corepack
|
|
34
|
+
run: corepack enable
|
|
35
|
+
|
|
36
|
+
- name: Resolve pnpm store path
|
|
37
|
+
id: pnpm-store
|
|
38
|
+
run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"
|
|
39
|
+
|
|
40
|
+
- name: Cache pnpm store
|
|
41
|
+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
42
|
+
with:
|
|
43
|
+
path: ${{ steps.pnpm-store.outputs.path }}
|
|
44
|
+
key: pnpm-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
|
45
|
+
restore-keys: pnpm-${{ runner.os }}-
|
|
46
|
+
|
|
47
|
+
- name: Install dependencies
|
|
48
|
+
run: pnpm install --frozen-lockfile
|
|
49
|
+
|
|
50
|
+
- name: Prune pnpm store
|
|
51
|
+
run: pnpm store prune
|
|
52
|
+
|
|
53
|
+
- name: Run tests
|
|
54
|
+
run: pnpm test
|
|
55
|
+
|
|
56
|
+
- name: Upload test report
|
|
57
|
+
if: failure()
|
|
58
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
59
|
+
with:
|
|
60
|
+
name: ci-test-report-${{ github.run_id }}-${{ github.run_attempt }}
|
|
61
|
+
path: |
|
|
62
|
+
test/__reports__
|
|
63
|
+
**/__current__/**
|
|
64
|
+
.vitest/attachments
|
|
65
|
+
!**/node_modules/**
|
|
66
|
+
include-hidden-files: true
|
|
67
|
+
if-no-files-found: ignore
|
|
68
|
+
retention-days: 14
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# GitLab CI/CD job (scaffolded by Nuxt Spec) to update test baselines (manually triggered).
|
|
2
|
+
# Start it via "Build > Pipelines > Run pipeline" on selected branch with `NUXT_SPEC_UPDATE_BASELINES` set to `true`.
|
|
3
|
+
# Runs in the same pinned Playwright container as "verify" job.
|
|
4
|
+
# Updated baselines (`__baseline__`, `__screenshots__`) and snapshots (`__snapshots__`) are committed back to the selected branch.
|
|
5
|
+
# If the push is rejected (e.g. protected branch), a new branch with a merge request is created instead.
|
|
6
|
+
# PREREQUISITE: project access token with `write_repository` scope stored as masked CI/CD variable `NUXT_SPEC_CI_TOKEN`
|
|
7
|
+
# (CI_JOB_TOKEN cannot be used for pushing; the token role decides whether it may push into protected branches).
|
|
8
|
+
|
|
9
|
+
variables:
|
|
10
|
+
NUXT_SPEC_UPDATE_BASELINES:
|
|
11
|
+
value: "false"
|
|
12
|
+
options: ["false", "true"]
|
|
13
|
+
description: Set to "true" to regenerate and commit test baselines (Nuxt Spec).
|
|
14
|
+
|
|
15
|
+
ci-test-update:
|
|
16
|
+
stage: test
|
|
17
|
+
# must match `playwright` dependency version
|
|
18
|
+
image: mcr.microsoft.com/playwright:v__PLAYWRIGHT_VERSION__-jammy
|
|
19
|
+
resource_group: ci-test-update-$CI_COMMIT_REF_SLUG
|
|
20
|
+
rules:
|
|
21
|
+
- if: $CI_PIPELINE_SOURCE == "web" && $NUXT_SPEC_UPDATE_BASELINES == "true" && $CI_COMMIT_BRANCH
|
|
22
|
+
variables:
|
|
23
|
+
PNPM_STORE_DIR: $CI_PROJECT_DIR/.pnpm-store
|
|
24
|
+
cache:
|
|
25
|
+
key:
|
|
26
|
+
prefix: pnpm
|
|
27
|
+
files:
|
|
28
|
+
- pnpm-lock.yaml
|
|
29
|
+
paths:
|
|
30
|
+
- .pnpm-store/
|
|
31
|
+
before_script:
|
|
32
|
+
- ': "${NUXT_SPEC_CI_TOKEN:?CI/CD variable NUXT_SPEC_CI_TOKEN (project access token with write_repository scope) is required}"'
|
|
33
|
+
- corepack enable
|
|
34
|
+
- pnpm install --frozen-lockfile --store-dir "$PNPM_STORE_DIR"
|
|
35
|
+
- pnpm store prune --store-dir "$PNPM_STORE_DIR"
|
|
36
|
+
script:
|
|
37
|
+
- pnpm test-u
|
|
38
|
+
- |
|
|
39
|
+
set -eu
|
|
40
|
+
|
|
41
|
+
git config user.name "$GITLAB_USER_NAME"
|
|
42
|
+
git config user.email "$GITLAB_USER_EMAIL"
|
|
43
|
+
|
|
44
|
+
# `git add` fails on a glob without matches, `git ls-files` doesn't
|
|
45
|
+
git ls-files -z -m -d -o --exclude-standard -- \
|
|
46
|
+
':(glob)**/__baseline__/**' \
|
|
47
|
+
':(glob)**/__screenshots__/**' \
|
|
48
|
+
':(glob)**/__snapshots__/**' \
|
|
49
|
+
| xargs -0 -r git add -A --
|
|
50
|
+
if git diff --cached --quiet; then
|
|
51
|
+
echo "No baseline changes to commit."
|
|
52
|
+
exit 0
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
git commit -m "test(ci): update test baselines"
|
|
56
|
+
|
|
57
|
+
PUSH_URL="${CI_SERVER_PROTOCOL}://oauth2:${NUXT_SPEC_CI_TOKEN}@${CI_SERVER_HOST}:${CI_SERVER_PORT}/${CI_PROJECT_PATH}.git"
|
|
58
|
+
if git push "$PUSH_URL" "HEAD:refs/heads/$CI_COMMIT_BRANCH"; then
|
|
59
|
+
echo "Updated baselines pushed to '$CI_COMMIT_BRANCH'."
|
|
60
|
+
exit 0
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
echo "Push to '$CI_COMMIT_BRANCH' was rejected (e.g. protected branch) - creating merge request..."
|
|
64
|
+
NEW_BRANCH="ci-test/update-$(date +%Y%m%d%H%M%S)"
|
|
65
|
+
git push "$PUSH_URL" "HEAD:refs/heads/$NEW_BRANCH" \
|
|
66
|
+
-o merge_request.create \
|
|
67
|
+
-o merge_request.target="$CI_COMMIT_BRANCH" \
|
|
68
|
+
-o merge_request.title="test(ci): update test baselines" \
|
|
69
|
+
-o merge_request.description="Test baselines update triggered by pipeline #$CI_PIPELINE_IID against branch \`$CI_COMMIT_BRANCH\`."
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# GitLab CI/CD job (scaffolded by Nuxt Spec) to run test suite in a pinned Playwright container for reproducible results.
|
|
2
|
+
# Triggered automatically on push to default branch and on merge requests targeting it.
|
|
3
|
+
# Can be started manually via "Build > Pipelines > Run pipeline" (with `NUXT_SPEC_UPDATE_BASELINES` left as `false`).
|
|
4
|
+
# Uses pnpm - the pnpm store is cached so subsequent `pnpm install` runs reuse downloaded deps.
|
|
5
|
+
# If tests fail, artifacts (HTML report, current screenshots, Vitest attachments) are kept for inspection.
|
|
6
|
+
|
|
7
|
+
ci-test-verify:
|
|
8
|
+
stage: test
|
|
9
|
+
# must match `playwright` dependency version
|
|
10
|
+
image: mcr.microsoft.com/playwright:v__PLAYWRIGHT_VERSION__-jammy
|
|
11
|
+
interruptible: true
|
|
12
|
+
rules:
|
|
13
|
+
- if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
|
14
|
+
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH
|
|
15
|
+
- if: $CI_PIPELINE_SOURCE == "web" && $NUXT_SPEC_UPDATE_BASELINES != "true"
|
|
16
|
+
variables:
|
|
17
|
+
PNPM_STORE_DIR: $CI_PROJECT_DIR/.pnpm-store
|
|
18
|
+
cache:
|
|
19
|
+
key:
|
|
20
|
+
prefix: pnpm
|
|
21
|
+
files:
|
|
22
|
+
- pnpm-lock.yaml
|
|
23
|
+
paths:
|
|
24
|
+
- .pnpm-store/
|
|
25
|
+
before_script:
|
|
26
|
+
- corepack enable
|
|
27
|
+
- pnpm install --frozen-lockfile --store-dir "$PNPM_STORE_DIR"
|
|
28
|
+
- pnpm store prune --store-dir "$PNPM_STORE_DIR"
|
|
29
|
+
script:
|
|
30
|
+
- pnpm test
|
|
31
|
+
artifacts:
|
|
32
|
+
name: ci-test-report-$CI_PIPELINE_ID
|
|
33
|
+
when: on_failure
|
|
34
|
+
expire_in: 14 days
|
|
35
|
+
paths:
|
|
36
|
+
- test/__reports__/
|
|
37
|
+
- "**/__current__/"
|
|
38
|
+
- .vitest/attachments/
|
|
39
|
+
exclude:
|
|
40
|
+
- node_modules/**/*
|
|
41
|
+
- .pnpm-store/**/*
|
package/nuxt.config.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-spec",
|
|
3
|
-
"version": "0.4.0-alpha.
|
|
3
|
+
"version": "0.4.0-alpha.2",
|
|
4
4
|
"description": "Test-pack layer for Nuxt Applications",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"start": "nuxt start",
|
|
22
22
|
"test": "vitest run",
|
|
23
23
|
"test-u": "vitest run -u",
|
|
24
|
+
"test-c": "vitest run --coverage",
|
|
24
25
|
"test-i": "vitest"
|
|
25
26
|
},
|
|
26
27
|
"bin": {
|
|
@@ -53,21 +54,24 @@
|
|
|
53
54
|
"nuxt.config.ts"
|
|
54
55
|
],
|
|
55
56
|
"dependencies": {
|
|
57
|
+
"@nuxt/devtools": "4.0.0-beta.4",
|
|
56
58
|
"@nuxt/eslint": "~1.17.0",
|
|
57
59
|
"@nuxt/hints": "1.1.4",
|
|
58
60
|
"@nuxt/test-utils": "4.3.3",
|
|
59
61
|
"@vitejs/plugin-vue": "~6.0.9",
|
|
60
62
|
"@vitest/browser": "5.0.3",
|
|
61
63
|
"@vitest/browser-playwright": "5.0.3",
|
|
64
|
+
"@vitest/coverage-istanbul": "5.0.3",
|
|
65
|
+
"@vitest/coverage-v8": "5.0.3",
|
|
62
66
|
"@vitest/ui": "5.0.3",
|
|
63
67
|
"@vue/test-utils": "2.5.1",
|
|
64
|
-
"elrh-cosca": "0.4.
|
|
68
|
+
"elrh-cosca": "0.4.3",
|
|
65
69
|
"fast-png": "~8.0.0",
|
|
66
70
|
"happy-dom": "~20.14.5",
|
|
67
|
-
"nuxt": "4.6.
|
|
71
|
+
"nuxt": "4.6.1",
|
|
68
72
|
"pixelmatch": "~7.2.0",
|
|
69
|
-
"playwright": "~1.
|
|
70
|
-
"playwright-core": "~1.
|
|
73
|
+
"playwright": "~1.64.0",
|
|
74
|
+
"playwright-core": "~1.64.0",
|
|
71
75
|
"typescript": "~6.0.3",
|
|
72
76
|
"vitest": "5.0.3",
|
|
73
77
|
"vitest-browser-vue": "3.1.0",
|
|
@@ -75,5 +79,5 @@
|
|
|
75
79
|
"vue-router": "~5.3.1",
|
|
76
80
|
"vue-tsc": "~3.3.12"
|
|
77
81
|
},
|
|
78
|
-
"packageManager": "pnpm@12.
|
|
82
|
+
"packageManager": "pnpm@12.11.2"
|
|
79
83
|
}
|