nuxt-spec 0.4.0-alpha.1 → 0.4.0-alpha.3

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.
Files changed (41) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +13 -13
  3. package/app/app.vue +10 -10
  4. package/app/components/NuxtSpecApiTestComponent.vue +24 -24
  5. package/app/components/NuxtSpecTestComponent.vue +9 -9
  6. package/app/components/index.d.ts +7 -7
  7. package/app/components/index.ts +2 -2
  8. package/app/utils/vitest-utils.ts +5 -5
  9. package/config/index.d.ts +36 -36
  10. package/config/index.mjs +147 -140
  11. package/config/report/report-entry.html +6 -6
  12. package/config/report/report-head.html +34 -34
  13. package/config/report/report-screenshot.html +8 -8
  14. package/config/report/report-tail.html +4 -4
  15. package/config/templates/.github/workflows/ci-test-update.yml.template +105 -0
  16. package/config/templates/.github/workflows/ci-test-verify.yml.template +68 -0
  17. package/config/templates/.gitlab/ci/ci-test-update.yml.template +69 -0
  18. package/config/templates/.gitlab/ci/ci-test-verify.yml.template +41 -0
  19. package/config/templates/.gitlab-ci.yml.template +6 -0
  20. package/config/templates/pnpm-workspace.yaml.template +19 -19
  21. package/config/templates/vitest.config.ts.template +5 -5
  22. package/config/utils/merge.mjs +43 -43
  23. package/config/utils/options.d.mts +59 -59
  24. package/config/utils/options.mjs +116 -116
  25. package/config/utils/reporter.mjs +409 -409
  26. package/config/utils/warnings.mjs +38 -38
  27. package/modules/spec-options.ts +23 -23
  28. package/nuxt.config.ts +20 -20
  29. package/package.json +23 -25
  30. package/utils/e2e.ts +131 -131
  31. package/utils/helpers/check-params.ts +44 -44
  32. package/utils/helpers/location-hint.ts +30 -30
  33. package/utils/helpers/screenshot-utils.ts +27 -27
  34. package/utils/index.ts +12 -12
  35. package/utils/playwright.ts +28 -28
  36. package/utils/screenshot.ts +201 -201
  37. package/bin/_internal/prepublish-check.js +0 -16
  38. package/bin/cli.js +0 -44
  39. package/bin/helpers/commands.js +0 -82
  40. package/bin/setup.js +0 -366
  41. package/bin/update.js +0 -94
@@ -1,116 +1,116 @@
1
- // Nuxt Spec options resolution
2
- // - values can be set via `spec` key in nuxt.config.ts or via NUXT_SPEC_* env variables
3
- // - precedence: env variables > nuxt.config.ts > defaults
4
-
5
- import { loadNuxtConfig } from 'nuxt/kit'
6
-
7
- export const NUXT_SPEC_DEFAULTS = {
8
- hints: true,
9
- externalPlaywright: undefined,
10
- htmlReport: {
11
- enabled: true,
12
- open: 'failed',
13
- },
14
- messageFilters: [],
15
- }
16
-
17
- const HTML_REPORT_OPEN_MODES = ['always', 'failed', 'never']
18
-
19
- // raw `spec` values per cwd - nuxt.config.ts is only loaded once
20
- const specCache = new Map()
21
-
22
- // options are resolved by both the Nuxt module and the Vitest config in the same process
23
- const reportedWarnings = new Set()
24
-
25
- /**
26
- * Resolve final Nuxt Spec options.
27
- * @param {import('./options.d.mts').NuxtSpecOptions | false | null} [fromConfig] - `spec` key from nuxt.config.ts
28
- * @param {Record<string, string | undefined>} [env] - env variables
29
- * @returns {import('./options.d.mts').ResolvedNuxtSpecOptions}
30
- */
31
- export function resolveSpecOptions(fromConfig, env = process.env) {
32
- const config = isObject(fromConfig) ? fromConfig : {}
33
- const htmlReport = checkType('htmlReport', config.htmlReport, 'object') ?? {}
34
- return {
35
- hints: toBoolean(env.NUXT_SPEC_HINTS_ENABLED)
36
- ?? checkType('hints', config.hints, 'boolean')
37
- ?? NUXT_SPEC_DEFAULTS.hints,
38
- externalPlaywright: env.NUXT_SPEC_EXTERNAL_PLAYWRIGHT
39
- || checkType('externalPlaywright', config.externalPlaywright, 'string')
40
- || NUXT_SPEC_DEFAULTS.externalPlaywright,
41
- htmlReport: {
42
- enabled: toBoolean(env.NUXT_SPEC_HTML_REPORT)
43
- ?? checkType('htmlReport.enabled', htmlReport.enabled, 'boolean')
44
- ?? NUXT_SPEC_DEFAULTS.htmlReport.enabled,
45
- open: env.NUXT_SPEC_HTML_REPORT_OPEN
46
- ? toOpenMode('NUXT_SPEC_HTML_REPORT_OPEN', env.NUXT_SPEC_HTML_REPORT_OPEN)
47
- : toOpenMode('htmlReport.open', htmlReport.open),
48
- },
49
- messageFilters: [
50
- ...(checkType('messageFilters', config.messageFilters, 'array') ?? []),
51
- ...(env.NUXT_SPEC_MESSAGE_FILTERS?.split(',') ?? []),
52
- ]
53
- .filter((f) => {
54
- if (typeof f === 'string') return true
55
- warnInvalid('messageFilters', f, 'string', 'Value is ignored.')
56
- return false
57
- })
58
- .map(f => f.trim())
59
- // empty pattern would match (and swallow) every message
60
- .filter(Boolean),
61
- }
62
- }
63
-
64
- /**
65
- * Load `spec` key from nuxt.config.ts (including extended layers)
66
- * and resolve final Nuxt Spec options.
67
- * @param {string} [cwd] - directory with nuxt.config.ts
68
- * @returns {Promise<import('./options.d.mts').ResolvedNuxtSpecOptions>}
69
- */
70
- export async function loadSpecOptions(cwd = process.cwd()) {
71
- if (!specCache.has(cwd)) {
72
- specCache.set(cwd, loadNuxtConfig({ cwd })
73
- .then(config => config.spec)
74
- .catch((error) => {
75
- console.warn(`[Nuxt Spec] Failed to read \`spec\` options from nuxt.config: ${error?.message ?? error}`)
76
- return undefined
77
- }))
78
- }
79
- return resolveSpecOptions(await specCache.get(cwd))
80
- }
81
-
82
- function isObject(value) {
83
- return typeof value === 'object' && value !== null && !Array.isArray(value)
84
- }
85
-
86
- // returns the value if it matches the expected type, otherwise warns and returns undefined
87
- function checkType(option, value, type) {
88
- if (value === undefined) return undefined
89
- const matches = type === 'object'
90
- ? isObject(value)
91
- : type === 'array' ? Array.isArray(value) : typeof value === type
92
- if (matches) return value
93
- warnInvalid(option, value, type)
94
- return undefined
95
- }
96
-
97
- function toOpenMode(option, value) {
98
- if (value === undefined) return NUXT_SPEC_DEFAULTS.htmlReport.open
99
- const normalized = typeof value === 'string' ? value.trim().toLowerCase() : value
100
- if (HTML_REPORT_OPEN_MODES.includes(normalized)) return normalized
101
- warnInvalid(option, value, HTML_REPORT_OPEN_MODES.map(m => `'${m}'`).join(' | '))
102
- return NUXT_SPEC_DEFAULTS.htmlReport.open
103
- }
104
-
105
- function warnInvalid(option, value, expected, outcome = 'Falling back to default.') {
106
- const message = `[Nuxt Spec] Invalid value ${JSON.stringify(value) ?? String(value)} for \`${option}\` (expected ${expected}). ${outcome}`
107
- if (reportedWarnings.has(message)) return
108
- reportedWarnings.add(message)
109
- console.warn(message)
110
- }
111
-
112
- // unset or empty = not defined, only explicit 'false' disables
113
- function toBoolean(value) {
114
- if (value === undefined || value === '') return undefined
115
- return value !== 'false'
116
- }
1
+ // Nuxt Spec options resolution
2
+ // - values can be set via `spec` key in nuxt.config.ts or via NUXT_SPEC_* env variables
3
+ // - precedence: env variables > nuxt.config.ts > defaults
4
+
5
+ import { loadNuxtConfig } from 'nuxt/kit'
6
+
7
+ export const NUXT_SPEC_DEFAULTS = {
8
+ hints: true,
9
+ externalPlaywright: undefined,
10
+ htmlReport: {
11
+ enabled: true,
12
+ open: 'failed',
13
+ },
14
+ messageFilters: [],
15
+ }
16
+
17
+ const HTML_REPORT_OPEN_MODES = ['always', 'failed', 'never']
18
+
19
+ // raw `spec` values per cwd - nuxt.config.ts is only loaded once
20
+ const specCache = new Map()
21
+
22
+ // options are resolved by both the Nuxt module and the Vitest config in the same process
23
+ const reportedWarnings = new Set()
24
+
25
+ /**
26
+ * Resolve final Nuxt Spec options.
27
+ * @param {import('./options.d.mts').NuxtSpecOptions | false | null} [fromConfig] - `spec` key from nuxt.config.ts
28
+ * @param {Record<string, string | undefined>} [env] - env variables
29
+ * @returns {import('./options.d.mts').ResolvedNuxtSpecOptions}
30
+ */
31
+ export function resolveSpecOptions(fromConfig, env = process.env) {
32
+ const config = isObject(fromConfig) ? fromConfig : {}
33
+ const htmlReport = checkType('htmlReport', config.htmlReport, 'object') ?? {}
34
+ return {
35
+ hints: toBoolean(env.NUXT_SPEC_HINTS_ENABLED)
36
+ ?? checkType('hints', config.hints, 'boolean')
37
+ ?? NUXT_SPEC_DEFAULTS.hints,
38
+ externalPlaywright: env.NUXT_SPEC_EXTERNAL_PLAYWRIGHT
39
+ || checkType('externalPlaywright', config.externalPlaywright, 'string')
40
+ || NUXT_SPEC_DEFAULTS.externalPlaywright,
41
+ htmlReport: {
42
+ enabled: toBoolean(env.NUXT_SPEC_HTML_REPORT)
43
+ ?? checkType('htmlReport.enabled', htmlReport.enabled, 'boolean')
44
+ ?? NUXT_SPEC_DEFAULTS.htmlReport.enabled,
45
+ open: env.NUXT_SPEC_HTML_REPORT_OPEN
46
+ ? toOpenMode('NUXT_SPEC_HTML_REPORT_OPEN', env.NUXT_SPEC_HTML_REPORT_OPEN)
47
+ : toOpenMode('htmlReport.open', htmlReport.open),
48
+ },
49
+ messageFilters: [
50
+ ...(checkType('messageFilters', config.messageFilters, 'array') ?? []),
51
+ ...(env.NUXT_SPEC_MESSAGE_FILTERS?.split(',') ?? []),
52
+ ]
53
+ .filter((f) => {
54
+ if (typeof f === 'string') return true
55
+ warnInvalid('messageFilters', f, 'string', 'Value is ignored.')
56
+ return false
57
+ })
58
+ .map(f => f.trim())
59
+ // empty pattern would match (and swallow) every message
60
+ .filter(Boolean),
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Load `spec` key from nuxt.config.ts (including extended layers)
66
+ * and resolve final Nuxt Spec options.
67
+ * @param {string} [cwd] - directory with nuxt.config.ts
68
+ * @returns {Promise<import('./options.d.mts').ResolvedNuxtSpecOptions>}
69
+ */
70
+ export async function loadSpecOptions(cwd = process.cwd()) {
71
+ if (!specCache.has(cwd)) {
72
+ specCache.set(cwd, loadNuxtConfig({ cwd })
73
+ .then(config => config.spec)
74
+ .catch((error) => {
75
+ console.warn(`[Nuxt Spec] Failed to read \`spec\` options from nuxt.config: ${error?.message ?? error}`)
76
+ return undefined
77
+ }))
78
+ }
79
+ return resolveSpecOptions(await specCache.get(cwd))
80
+ }
81
+
82
+ function isObject(value) {
83
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
84
+ }
85
+
86
+ // returns the value if it matches the expected type, otherwise warns and returns undefined
87
+ function checkType(option, value, type) {
88
+ if (value === undefined) return undefined
89
+ const matches = type === 'object'
90
+ ? isObject(value)
91
+ : type === 'array' ? Array.isArray(value) : typeof value === type
92
+ if (matches) return value
93
+ warnInvalid(option, value, type)
94
+ return undefined
95
+ }
96
+
97
+ function toOpenMode(option, value) {
98
+ if (value === undefined) return NUXT_SPEC_DEFAULTS.htmlReport.open
99
+ const normalized = typeof value === 'string' ? value.trim().toLowerCase() : value
100
+ if (HTML_REPORT_OPEN_MODES.includes(normalized)) return normalized
101
+ warnInvalid(option, value, HTML_REPORT_OPEN_MODES.map(m => `'${m}'`).join(' | '))
102
+ return NUXT_SPEC_DEFAULTS.htmlReport.open
103
+ }
104
+
105
+ function warnInvalid(option, value, expected, outcome = 'Falling back to default.') {
106
+ const message = `[Nuxt Spec] Invalid value ${JSON.stringify(value) ?? String(value)} for \`${option}\` (expected ${expected}). ${outcome}`
107
+ if (reportedWarnings.has(message)) return
108
+ reportedWarnings.add(message)
109
+ console.warn(message)
110
+ }
111
+
112
+ // unset or empty = not defined, only explicit 'false' disables
113
+ function toBoolean(value) {
114
+ if (value === undefined || value === '') return undefined
115
+ return value !== 'false'
116
+ }