nuxt-spec 0.3.2 → 0.3.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.
- package/LICENSE +21 -21
- package/README.md +13 -13
- package/app/app.vue +10 -10
- package/app/components/NuxtSpecApiTestComponent.vue +24 -24
- package/app/components/NuxtSpecTestComponent.vue +9 -9
- package/app/components/index.d.ts +7 -7
- package/app/components/index.ts +2 -2
- package/app/utils/vitest-utils.ts +5 -5
- package/bin/cli.js +38 -38
- package/bin/helpers/commands.js +52 -52
- package/bin/prepublish-check.js +16 -16
- package/bin/setup.js +270 -270
- package/bin/update.js +75 -75
- package/config/index.d.ts +33 -33
- package/config/index.mjs +132 -114
- package/config/templates/pnpm-workspace.yaml.template +4 -4
- package/config/templates/vitest.config.ts.template +5 -5
- package/config/utils/merge.mjs +43 -43
- package/config/utils/warnings.mjs +33 -33
- package/nuxt.config.ts +24 -24
- package/package.json +27 -25
- package/utils/e2e.ts +131 -131
- package/utils/helpers/check-params.ts +41 -41
- package/utils/helpers/location-hint.ts +30 -30
- package/utils/index.ts +12 -12
- package/utils/playwright.ts +20 -0
- package/utils/screenshot/report-entry.html +8 -8
- package/utils/screenshot/report-head.html +24 -24
- package/utils/screenshot/report-tail.html +4 -4
- package/utils/screenshot/report-utils.ts +236 -236
- package/utils/screenshot.ts +172 -172
package/bin/update.js
CHANGED
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { execSync } from 'node:child_process'
|
|
4
|
-
import { getPackageManager, hasJsonKey, promptUser, showMessage } from 'elrh-cosca'
|
|
5
|
-
import { getPlaywrightInstallCmd, getUpdateCmd } from './helpers/commands.js'
|
|
6
|
-
|
|
7
|
-
const TARGET_VERSION = '0.3.
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* CLI tool to update existing `nuxt-spec` installation.
|
|
11
|
-
*
|
|
12
|
-
* It first asks whether to run in "auto" mode (no prompts, force = true) or "manual" mode (with prompts, force = false).
|
|
13
|
-
*
|
|
14
|
-
* Then it:
|
|
15
|
-
* 1) verifies `nuxt-spec` is present in `package.json` (fails with a hint to run `setup` otherwise)
|
|
16
|
-
* 2) runs the package manager's update command to bump `nuxt-spec` to the latest version
|
|
17
|
-
* 3) run the `playwright-core install` command to ensure the Playwright browser runtimes are up to date
|
|
18
|
-
*
|
|
19
|
-
* @param {boolean} autoRun - Whether to run the update automatically without any prompts (defaults to false).
|
|
20
|
-
*/
|
|
21
|
-
export async function specUpdate(autoRun = false) {
|
|
22
|
-
showMessage('NUXT SPEC UPDATE')
|
|
23
|
-
showMessage('This CLI tool will help you update Nuxt Spec in your project.')
|
|
24
|
-
showMessage('Refer to the documentation for more information.', 2)
|
|
25
|
-
|
|
26
|
-
// fail fast if there is nothing to update
|
|
27
|
-
const isInstalled = hasJsonKey('package.json', `dependencies.nuxt-spec`)
|
|
28
|
-
|| hasJsonKey('package.json', `devDependencies.nuxt-spec`)
|
|
29
|
-
if (!isInstalled) {
|
|
30
|
-
console.error(`'nuxt-spec' was not found in your 'package.json'. Run the 'setup' command first.`)
|
|
31
|
-
process.exit(1)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const isAutoRun = autoRun || await promptUser('Do you want to update everything automatically (no more prompts)?')
|
|
35
|
-
showMessage('')
|
|
36
|
-
|
|
37
|
-
const packageManager = getPackageManager()
|
|
38
|
-
|
|
39
|
-
// 1) run 'update nuxt-spec'
|
|
40
|
-
const updateCmd = getUpdateCmd(packageManager, `nuxt-spec@${TARGET_VERSION}`)
|
|
41
|
-
const runUpdate = isAutoRun || await promptUser(`This will bump 'nuxt-spec' to version '${TARGET_VERSION}' by running \`${updateCmd}\`. Continue?`)
|
|
42
|
-
if (runUpdate) {
|
|
43
|
-
try {
|
|
44
|
-
showMessage(`Running \`${updateCmd}\`...`)
|
|
45
|
-
execSync(updateCmd, { stdio: 'inherit' })
|
|
46
|
-
} catch (error) {
|
|
47
|
-
console.error(`Error running \`${updateCmd}\`:\n`, error.message)
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// 2) run 'playwright-core install'
|
|
52
|
-
const playwrightUpdateCmd = getPlaywrightInstallCmd(packageManager)
|
|
53
|
-
const runPlaywrightUpdate = isAutoRun || await promptUser(`Playwright browser runtimes might need to be updated for e2e tests. Do you want to run \`${playwrightUpdateCmd}\` now?`)
|
|
54
|
-
if (runPlaywrightUpdate) {
|
|
55
|
-
try {
|
|
56
|
-
showMessage(`Running \`${playwrightUpdateCmd}\`...`)
|
|
57
|
-
execSync(playwrightUpdateCmd, { stdio: 'inherit' })
|
|
58
|
-
} catch (error) {
|
|
59
|
-
console.error(`Error running \`${playwrightUpdateCmd}\`:\n`, error.message)
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// 3) inform user
|
|
64
|
-
showMessage('')
|
|
65
|
-
showMessage('NUXT SPEC UPDATE COMPLETE', 2)
|
|
66
|
-
if (!runUpdate) {
|
|
67
|
-
showMessage(`Run \`${updateCmd}\` to update 'nuxt-spec'.`)
|
|
68
|
-
}
|
|
69
|
-
if (!runPlaywrightUpdate) {
|
|
70
|
-
showMessage(`Run \`${playwrightUpdateCmd}\` to update the Playwright browser runtimes for e2e tests.`)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// force exit to prevent #20
|
|
74
|
-
process.exit(0)
|
|
75
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { execSync } from 'node:child_process'
|
|
4
|
+
import { getPackageManager, hasJsonKey, promptUser, showMessage } from 'elrh-cosca'
|
|
5
|
+
import { getPlaywrightInstallCmd, getUpdateCmd } from './helpers/commands.js'
|
|
6
|
+
|
|
7
|
+
const TARGET_VERSION = '0.3.3'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* CLI tool to update existing `nuxt-spec` installation.
|
|
11
|
+
*
|
|
12
|
+
* It first asks whether to run in "auto" mode (no prompts, force = true) or "manual" mode (with prompts, force = false).
|
|
13
|
+
*
|
|
14
|
+
* Then it:
|
|
15
|
+
* 1) verifies `nuxt-spec` is present in `package.json` (fails with a hint to run `setup` otherwise)
|
|
16
|
+
* 2) runs the package manager's update command to bump `nuxt-spec` to the latest version
|
|
17
|
+
* 3) run the `playwright-core install` command to ensure the Playwright browser runtimes are up to date
|
|
18
|
+
*
|
|
19
|
+
* @param {boolean} autoRun - Whether to run the update automatically without any prompts (defaults to false).
|
|
20
|
+
*/
|
|
21
|
+
export async function specUpdate(autoRun = false) {
|
|
22
|
+
showMessage('NUXT SPEC UPDATE')
|
|
23
|
+
showMessage('This CLI tool will help you update Nuxt Spec in your project.')
|
|
24
|
+
showMessage('Refer to the documentation for more information.', 2)
|
|
25
|
+
|
|
26
|
+
// fail fast if there is nothing to update
|
|
27
|
+
const isInstalled = hasJsonKey('package.json', `dependencies.nuxt-spec`)
|
|
28
|
+
|| hasJsonKey('package.json', `devDependencies.nuxt-spec`)
|
|
29
|
+
if (!isInstalled) {
|
|
30
|
+
console.error(`'nuxt-spec' was not found in your 'package.json'. Run the 'setup' command first.`)
|
|
31
|
+
process.exit(1)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const isAutoRun = autoRun || await promptUser('Do you want to update everything automatically (no more prompts)?')
|
|
35
|
+
showMessage('')
|
|
36
|
+
|
|
37
|
+
const packageManager = getPackageManager()
|
|
38
|
+
|
|
39
|
+
// 1) run 'update nuxt-spec'
|
|
40
|
+
const updateCmd = getUpdateCmd(packageManager, `nuxt-spec@${TARGET_VERSION}`)
|
|
41
|
+
const runUpdate = isAutoRun || await promptUser(`This will bump 'nuxt-spec' to version '${TARGET_VERSION}' by running \`${updateCmd}\`. Continue?`)
|
|
42
|
+
if (runUpdate) {
|
|
43
|
+
try {
|
|
44
|
+
showMessage(`Running \`${updateCmd}\`...`)
|
|
45
|
+
execSync(updateCmd, { stdio: 'inherit' })
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.error(`Error running \`${updateCmd}\`:\n`, error.message)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// 2) run 'playwright-core install'
|
|
52
|
+
const playwrightUpdateCmd = getPlaywrightInstallCmd(packageManager)
|
|
53
|
+
const runPlaywrightUpdate = isAutoRun || await promptUser(`Playwright browser runtimes might need to be updated for e2e tests. Do you want to run \`${playwrightUpdateCmd}\` now?`)
|
|
54
|
+
if (runPlaywrightUpdate) {
|
|
55
|
+
try {
|
|
56
|
+
showMessage(`Running \`${playwrightUpdateCmd}\`...`)
|
|
57
|
+
execSync(playwrightUpdateCmd, { stdio: 'inherit' })
|
|
58
|
+
} catch (error) {
|
|
59
|
+
console.error(`Error running \`${playwrightUpdateCmd}\`:\n`, error.message)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 3) inform user
|
|
64
|
+
showMessage('')
|
|
65
|
+
showMessage('NUXT SPEC UPDATE COMPLETE', 2)
|
|
66
|
+
if (!runUpdate) {
|
|
67
|
+
showMessage(`Run \`${updateCmd}\` to update 'nuxt-spec'.`)
|
|
68
|
+
}
|
|
69
|
+
if (!runPlaywrightUpdate) {
|
|
70
|
+
showMessage(`Run \`${playwrightUpdateCmd}\` to update the Playwright browser runtimes for e2e tests.`)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// force exit to prevent #20
|
|
74
|
+
process.exit(0)
|
|
75
|
+
}
|
package/config/index.d.ts
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
import type { UserConfig } from 'vite'
|
|
2
|
-
import type { TestUserConfig } from 'vitest/config'
|
|
3
|
-
|
|
4
|
-
/** Typed Vite configuration object for tests */
|
|
5
|
-
type ExtendedUserConfig = UserConfig & {
|
|
6
|
-
test?: TestUserConfig
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Allows fine-grained control over default Vitest `projects`.
|
|
11
|
-
*
|
|
12
|
-
* By default, everything is included.
|
|
13
|
-
* If set to `false`, `test.projects` key is not merged at all.
|
|
14
|
-
* If set to object, specific projects can be omitted by setting respective key to `false`.
|
|
15
|
-
*/
|
|
16
|
-
type ProjectsConfig = boolean | {
|
|
17
|
-
default?: boolean
|
|
18
|
-
node?: boolean
|
|
19
|
-
nuxt?: boolean
|
|
20
|
-
e2e?: boolean
|
|
21
|
-
browser?: boolean
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Prepare Vitest configuration object - user config merged with nuxt-spec defaults
|
|
26
|
-
* @param userVitestConfig - custom Vitest config passed from the user
|
|
27
|
-
* @param projects - allows fine-grained control over default `test.projects` - see `ProjectsConfig` for details
|
|
28
|
-
* @returns Promise resolving to defu-merged Vitest configuration
|
|
29
|
-
*/
|
|
30
|
-
export declare function loadVitestConfig(
|
|
31
|
-
userVitestConfig: ExtendedUserConfig,
|
|
32
|
-
projects?: ProjectsConfig,
|
|
33
|
-
): Promise<ExtendedUserConfig>
|
|
1
|
+
import type { UserConfig } from 'vite'
|
|
2
|
+
import type { TestUserConfig } from 'vitest/config'
|
|
3
|
+
|
|
4
|
+
/** Typed Vite configuration object for tests */
|
|
5
|
+
type ExtendedUserConfig = UserConfig & {
|
|
6
|
+
test?: TestUserConfig
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Allows fine-grained control over default Vitest `projects`.
|
|
11
|
+
*
|
|
12
|
+
* By default, everything is included.
|
|
13
|
+
* If set to `false`, `test.projects` key is not merged at all.
|
|
14
|
+
* If set to object, specific projects can be omitted by setting respective key to `false`.
|
|
15
|
+
*/
|
|
16
|
+
type ProjectsConfig = boolean | {
|
|
17
|
+
default?: boolean
|
|
18
|
+
node?: boolean
|
|
19
|
+
nuxt?: boolean
|
|
20
|
+
e2e?: boolean
|
|
21
|
+
browser?: boolean
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Prepare Vitest configuration object - user config merged with nuxt-spec defaults
|
|
26
|
+
* @param userVitestConfig - custom Vitest config passed from the user
|
|
27
|
+
* @param projects - allows fine-grained control over default `test.projects` - see `ProjectsConfig` for details
|
|
28
|
+
* @returns Promise resolving to defu-merged Vitest configuration
|
|
29
|
+
*/
|
|
30
|
+
export declare function loadVitestConfig(
|
|
31
|
+
userVitestConfig: ExtendedUserConfig,
|
|
32
|
+
projects?: ProjectsConfig,
|
|
33
|
+
): Promise<ExtendedUserConfig>
|
package/config/index.mjs
CHANGED
|
@@ -1,114 +1,132 @@
|
|
|
1
|
-
// this is the default Vitest config object
|
|
2
|
-
// based on https://nuxt.com/docs/4.x/getting-started/testing#setup
|
|
3
|
-
// `projects=false` can be used to suspend the default usage of "projects" in Vitest config
|
|
4
|
-
|
|
5
|
-
import { availableParallelism } from 'node:os'
|
|
6
|
-
import { fileURLToPath } from 'node:url'
|
|
7
|
-
import { onConsoleLog } from './utils/warnings.mjs' // filter out unnecessary logs
|
|
8
|
-
import { mergeConfig } from './utils/merge.mjs' // defu-based merge function
|
|
9
|
-
import { defineConfig } from 'vitest/config'
|
|
10
|
-
import { defineVitestProject } from '@nuxt/test-utils/config'
|
|
11
|
-
import { playwright } from '@vitest/browser-playwright'
|
|
12
|
-
import vue from '@vitejs/plugin-vue'
|
|
13
|
-
|
|
14
|
-
// absolute
|
|
15
|
-
const screenshotReportSetup = fileURLToPath(new URL('../utils/screenshot.ts', import.meta.url))
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
1
|
+
// this is the default Vitest config object
|
|
2
|
+
// based on https://nuxt.com/docs/4.x/getting-started/testing#setup
|
|
3
|
+
// `projects=false` can be used to suspend the default usage of "projects" in Vitest config
|
|
4
|
+
|
|
5
|
+
import { availableParallelism } from 'node:os'
|
|
6
|
+
import { fileURLToPath } from 'node:url'
|
|
7
|
+
import { onConsoleLog } from './utils/warnings.mjs' // filter out unnecessary logs
|
|
8
|
+
import { mergeConfig } from './utils/merge.mjs' // defu-based merge function
|
|
9
|
+
import { defineConfig } from 'vitest/config'
|
|
10
|
+
import { defineVitestProject } from '@nuxt/test-utils/config'
|
|
11
|
+
import { playwright } from '@vitest/browser-playwright'
|
|
12
|
+
import vue from '@vitejs/plugin-vue'
|
|
13
|
+
|
|
14
|
+
// absolute paths so it works from within the nuxt-ignis package
|
|
15
|
+
const screenshotReportSetup = fileURLToPath(new URL('../utils/screenshot.ts', import.meta.url))
|
|
16
|
+
const externalPlaywrightSetup = fileURLToPath(new URL('../utils/playwright.ts', import.meta.url))
|
|
17
|
+
|
|
18
|
+
// external Playwright instance (if configured)
|
|
19
|
+
const externalPlaywright = process.env.NUXT_SPEC_EXTERNAL_PLAYWRIGHT
|
|
20
|
+
|
|
21
|
+
export async function loadVitestConfig(userVitestConfig, projects = true) {
|
|
22
|
+
const baseConfig = {
|
|
23
|
+
test: {
|
|
24
|
+
// filter-out unnecessary console logs coming from Vitest
|
|
25
|
+
// when the import is resolved, unnecessary stderr logs are also filtered-out
|
|
26
|
+
// as a side-effect
|
|
27
|
+
onConsoleLog,
|
|
28
|
+
// Vitest defaults to 5 which might be unnecessarily restrictive
|
|
29
|
+
// if the host machine can support more
|
|
30
|
+
maxConcurrency: availableParallelism() / 2,
|
|
31
|
+
},
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// add proposed projects settings
|
|
35
|
+
// user can control the inclusion via `projects: ProjectsConfig` config object
|
|
36
|
+
// projects are included by default unless not explicitly disabled
|
|
37
|
+
if (projects !== false) {
|
|
38
|
+
baseConfig.test.projects = []
|
|
39
|
+
|
|
40
|
+
// default fallback to catch tests directly in /test folder
|
|
41
|
+
if (projects.default !== false) {
|
|
42
|
+
baseConfig.test.projects.push({
|
|
43
|
+
extends: true,
|
|
44
|
+
test: {
|
|
45
|
+
name: 'default',
|
|
46
|
+
include: ['{test,tests}/**/*.{test,spec}.ts', '!test/{browser,e2e,nuxt,unit}/**'],
|
|
47
|
+
environment: 'node',
|
|
48
|
+
},
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// proposed setup for Unit tests
|
|
53
|
+
if (projects.node !== false) {
|
|
54
|
+
baseConfig.test.projects.push({
|
|
55
|
+
extends: true,
|
|
56
|
+
test: {
|
|
57
|
+
name: 'node',
|
|
58
|
+
include: ['test/unit/**/*.{test,spec}.ts'],
|
|
59
|
+
environment: 'node',
|
|
60
|
+
},
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// proposed setup for Nuxt component tests
|
|
65
|
+
if (projects.nuxt !== false) {
|
|
66
|
+
baseConfig.test.projects.push(
|
|
67
|
+
await defineVitestProject({
|
|
68
|
+
extends: true,
|
|
69
|
+
test: {
|
|
70
|
+
name: 'nuxt',
|
|
71
|
+
include: ['test/nuxt/**/*.{test,spec}.ts'],
|
|
72
|
+
environment: 'nuxt',
|
|
73
|
+
},
|
|
74
|
+
}),
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// proposed setup for classic E2E tests (node-based, using @nuxt/test-utils)
|
|
79
|
+
if (projects.e2e !== false) {
|
|
80
|
+
baseConfig.test.projects.push({
|
|
81
|
+
extends: true,
|
|
82
|
+
test: {
|
|
83
|
+
name: 'e2e',
|
|
84
|
+
include: ['test/e2e/**/*.{test,spec}.ts'],
|
|
85
|
+
environment: 'node',
|
|
86
|
+
// create report file for visual regression testing
|
|
87
|
+
globalSetup: [screenshotReportSetup],
|
|
88
|
+
// allows connecting to an external Playwright instance,
|
|
89
|
+
// if NUXT_SPEC_EXTERNAL_PLAYWRIGHT is set
|
|
90
|
+
setupFiles: externalPlaywright ? [externalPlaywrightSetup] : [],
|
|
91
|
+
},
|
|
92
|
+
})
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// proposed setup for browser component tests (with Playwright runner)
|
|
96
|
+
if (projects.browser !== false) {
|
|
97
|
+
// allows connecting to an external Playwright instance,
|
|
98
|
+
// if NUXT_SPEC_EXTERNAL_PLAYWRIGHT is set
|
|
99
|
+
const playwrightConfig = {}
|
|
100
|
+
if (externalPlaywright) {
|
|
101
|
+
console.log(`[Nuxt Spec - browser] Using external Playwright instance at: ${externalPlaywright}`)
|
|
102
|
+
playwrightConfig.connectOptions = {
|
|
103
|
+
wsEndpoint: externalPlaywright,
|
|
104
|
+
// this allows reaching caller's localhost from within the external Playwright
|
|
105
|
+
exposeNetwork: '<loopback>',
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
baseConfig.test.projects.push({
|
|
109
|
+
extends: true,
|
|
110
|
+
// vue plugin is required for proper imports resolution
|
|
111
|
+
plugins: [vue()],
|
|
112
|
+
test: {
|
|
113
|
+
name: 'browser',
|
|
114
|
+
include: ['test/browser/**/*.{test,spec}.ts'],
|
|
115
|
+
environment: 'node',
|
|
116
|
+
// only chromium browser by default - add others manually if needed
|
|
117
|
+
browser: {
|
|
118
|
+
provider: playwright(playwrightConfig),
|
|
119
|
+
enabled: true,
|
|
120
|
+
headless: true,
|
|
121
|
+
instances: [{
|
|
122
|
+
browser: 'chromium',
|
|
123
|
+
viewport: { width: 1280, height: 720 },
|
|
124
|
+
}],
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return mergeConfig(userVitestConfig, defineConfig(baseConfig))
|
|
132
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# settings for Nuxt & pnpm
|
|
2
|
-
|
|
3
|
-
# https://pnpm.io/settings#shamefullyhoist
|
|
4
|
-
shamefullyHoist: true
|
|
1
|
+
# settings for Nuxt & pnpm
|
|
2
|
+
|
|
3
|
+
# https://pnpm.io/settings#shamefullyhoist
|
|
4
|
+
shamefullyHoist: true
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { loadVitestConfig } from 'nuxt-spec/config'
|
|
2
|
-
|
|
3
|
-
export default loadVitestConfig({
|
|
4
|
-
// custom config here
|
|
5
|
-
})
|
|
1
|
+
import { loadVitestConfig } from 'nuxt-spec/config'
|
|
2
|
+
|
|
3
|
+
export default loadVitestConfig({
|
|
4
|
+
// custom config here
|
|
5
|
+
})
|
package/config/utils/merge.mjs
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
// custom merger function based on defu
|
|
2
|
-
// allows working with the "projects" array properly
|
|
3
|
-
// user-defined config overrides are merged by "name"
|
|
4
|
-
|
|
5
|
-
// for consistent and predictable results, passing "include" or "browser.instances"
|
|
6
|
-
// will result in OVERRIDE instead of merging with nuxt-spec defaults
|
|
7
|
-
|
|
8
|
-
import { createDefu } from 'defu'
|
|
9
|
-
|
|
10
|
-
// in real Vitest config, "name" is nested inside another "test" object
|
|
11
|
-
const getProjectName = project => project?.name ?? project?.test?.name
|
|
12
|
-
|
|
13
|
-
export const mergeConfig = createDefu((obj, key, value) => {
|
|
14
|
-
if (key === 'projects' && Array.isArray(obj[key]) && Array.isArray(value)) {
|
|
15
|
-
const defaults = obj[key]
|
|
16
|
-
const overrides = value
|
|
17
|
-
|
|
18
|
-
// override default values if user-defined config specifies them
|
|
19
|
-
obj[key] = defaults.map((defaultProject) => {
|
|
20
|
-
const override = overrides.find(o => getProjectName(o) === getProjectName(defaultProject))
|
|
21
|
-
return override ? mergeProject(override, defaultProject) : defaultProject
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
// add any user projects that don't exist in defaults
|
|
25
|
-
for (const override of overrides) {
|
|
26
|
-
if (!defaults.some(d => getProjectName(d) === getProjectName(override))) {
|
|
27
|
-
obj[key].push(override)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return true
|
|
32
|
-
}
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
// Keys where user value should fully replace the default, not merge
|
|
36
|
-
const overrideKeys = new Set(['include', 'instances'])
|
|
37
|
-
|
|
38
|
-
const mergeProject = createDefu((obj, key, value) => {
|
|
39
|
-
if (overrideKeys.has(key)) {
|
|
40
|
-
obj[key] = value
|
|
41
|
-
return true
|
|
42
|
-
}
|
|
43
|
-
})
|
|
1
|
+
// custom merger function based on defu
|
|
2
|
+
// allows working with the "projects" array properly
|
|
3
|
+
// user-defined config overrides are merged by "name"
|
|
4
|
+
|
|
5
|
+
// for consistent and predictable results, passing "include" or "browser.instances"
|
|
6
|
+
// will result in OVERRIDE instead of merging with nuxt-spec defaults
|
|
7
|
+
|
|
8
|
+
import { createDefu } from 'defu'
|
|
9
|
+
|
|
10
|
+
// in real Vitest config, "name" is nested inside another "test" object
|
|
11
|
+
const getProjectName = project => project?.name ?? project?.test?.name
|
|
12
|
+
|
|
13
|
+
export const mergeConfig = createDefu((obj, key, value) => {
|
|
14
|
+
if (key === 'projects' && Array.isArray(obj[key]) && Array.isArray(value)) {
|
|
15
|
+
const defaults = obj[key]
|
|
16
|
+
const overrides = value
|
|
17
|
+
|
|
18
|
+
// override default values if user-defined config specifies them
|
|
19
|
+
obj[key] = defaults.map((defaultProject) => {
|
|
20
|
+
const override = overrides.find(o => getProjectName(o) === getProjectName(defaultProject))
|
|
21
|
+
return override ? mergeProject(override, defaultProject) : defaultProject
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
// add any user projects that don't exist in defaults
|
|
25
|
+
for (const override of overrides) {
|
|
26
|
+
if (!defaults.some(d => getProjectName(d) === getProjectName(override))) {
|
|
27
|
+
obj[key].push(override)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return true
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// Keys where user value should fully replace the default, not merge
|
|
36
|
+
const overrideKeys = new Set(['include', 'instances'])
|
|
37
|
+
|
|
38
|
+
const mergeProject = createDefu((obj, key, value) => {
|
|
39
|
+
if (overrideKeys.has(key)) {
|
|
40
|
+
obj[key] = value
|
|
41
|
+
return true
|
|
42
|
+
}
|
|
43
|
+
})
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
const messageFilters = [
|
|
2
|
-
// Node+Windows false positive
|
|
3
|
-
// https://github.com/nuxt/icon/issues/140
|
|
4
|
-
'Use of deprecated trailing slash pattern mapping',
|
|
5
|
-
// remove once Vue stops considering <Suspense> experimental
|
|
6
|
-
'<Suspense> is an experimental feature',
|
|
7
|
-
// merge defaults with user-defined filters from NUXT_SPEC_MESSAGE_FILTERS env variable
|
|
8
|
-
...(process.env.NUXT_SPEC_MESSAGE_FILTERS
|
|
9
|
-
? process.env.NUXT_SPEC_MESSAGE_FILTERS.split(',')
|
|
10
|
-
: []),
|
|
11
|
-
]
|
|
12
|
-
|
|
13
|
-
// 1) filter-out unnecessary stderr/stdout logs coming from Vitest
|
|
14
|
-
// (applied as side-effect on import)
|
|
15
|
-
|
|
16
|
-
const _stderrWrite = process.stderr.write.bind(process.stderr)
|
|
17
|
-
process.stderr.write = (chunk, ...args) => {
|
|
18
|
-
if (typeof chunk === 'string' && messageFilters.some(f => chunk.includes(f))) return true
|
|
19
|
-
return _stderrWrite(chunk, ...args)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const _stdoutWrite = process.stdout.write.bind(process.stdout)
|
|
23
|
-
process.stdout.write = (chunk, ...args) => {
|
|
24
|
-
if (typeof chunk === 'string' && messageFilters.some(f => chunk.includes(f))) return true
|
|
25
|
-
return _stdoutWrite(chunk, ...args)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// 2) filter-out unnecessary console logs coming from Vitest
|
|
29
|
-
// (used as Vitest onConsoleLog hook)
|
|
30
|
-
|
|
31
|
-
export function onConsoleLog(log) {
|
|
32
|
-
if (messageFilters.some(f => log.includes(f))) return false
|
|
33
|
-
}
|
|
1
|
+
const messageFilters = [
|
|
2
|
+
// Node+Windows false positive
|
|
3
|
+
// https://github.com/nuxt/icon/issues/140
|
|
4
|
+
'Use of deprecated trailing slash pattern mapping',
|
|
5
|
+
// remove once Vue stops considering <Suspense> experimental
|
|
6
|
+
'<Suspense> is an experimental feature',
|
|
7
|
+
// merge defaults with user-defined filters from NUXT_SPEC_MESSAGE_FILTERS env variable
|
|
8
|
+
...(process.env.NUXT_SPEC_MESSAGE_FILTERS
|
|
9
|
+
? process.env.NUXT_SPEC_MESSAGE_FILTERS.split(',')
|
|
10
|
+
: []),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
// 1) filter-out unnecessary stderr/stdout logs coming from Vitest
|
|
14
|
+
// (applied as side-effect on import)
|
|
15
|
+
|
|
16
|
+
const _stderrWrite = process.stderr.write.bind(process.stderr)
|
|
17
|
+
process.stderr.write = (chunk, ...args) => {
|
|
18
|
+
if (typeof chunk === 'string' && messageFilters.some(f => chunk.includes(f))) return true
|
|
19
|
+
return _stderrWrite(chunk, ...args)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const _stdoutWrite = process.stdout.write.bind(process.stdout)
|
|
23
|
+
process.stdout.write = (chunk, ...args) => {
|
|
24
|
+
if (typeof chunk === 'string' && messageFilters.some(f => chunk.includes(f))) return true
|
|
25
|
+
return _stdoutWrite(chunk, ...args)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// 2) filter-out unnecessary console logs coming from Vitest
|
|
29
|
+
// (used as Vitest onConsoleLog hook)
|
|
30
|
+
|
|
31
|
+
export function onConsoleLog(log) {
|
|
32
|
+
if (messageFilters.some(f => log.includes(f))) return false
|
|
33
|
+
}
|