nuxt-spec 0.3.2 → 0.3.4

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.
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div style="margin: 1rem 0; padding: 0.5rem; border: 1px solid black;">
2
+ <div data-testid="test-component" style="margin: 1rem 0; padding: 0.5rem; border: 1px solid black;">
3
3
  {{ text }}
4
4
  </div>
5
5
  </template>
package/bin/cli.js CHANGED
@@ -1,14 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { getCmd } from './helpers/commands.js'
3
+ import { getCmd, resolvePackageManager } from './helpers/commands.js'
4
4
 
5
5
  /**
6
6
  * CLI tool to scaffold necessary adjustments in project folder.
7
7
  *
8
8
  * Allows `setup` or `update` to be passed as parameter.
9
9
  *
10
- * Second parameter might be a boolean to indicate auto mode
10
+ * Second (optional) parameter might be a boolean to indicate auto mode
11
11
  * (no prompts, force = true) or manual mode (with prompts, force = false).
12
+ *
13
+ * Third (optional) parameter allows explicitly passing the package manager
14
+ * (`npm`, `pnpm`, `yarn`, `bun` or `deno`), bypassing auto-detection.
12
15
  */
13
16
 
14
17
  // get parameters passed by user
@@ -19,19 +22,22 @@ const args = process.argv.slice(2);
19
22
  (async () => {
20
23
  let status = 0
21
24
  try {
25
+ const packageManager = resolvePackageManager(args[2])
26
+ // CLI args are always strings, so 'false' must be parsed explicitly rather than treated as truthy
27
+ const autoRun = args[1] === 'true'
22
28
  switch (args[0]) {
23
29
  case 'setup':
24
- await (await import('./setup.js')).specSetup(args[1] || false)
30
+ await (await import('./setup.js')).specSetup(autoRun, packageManager)
25
31
  break
26
32
  case 'update':
27
- await (await import('./update.js')).specUpdate(args[1] || false)
33
+ await (await import('./update.js')).specUpdate(autoRun, packageManager)
28
34
  break
29
35
  default:
30
- console.log(`Usage: \`${getCmd()} setup [true|false]\` or \`${getCmd()} update [true|false]\``)
36
+ console.log(`Usage: \`${getCmd(packageManager)} setup [true|false] [npm|pnpm|yarn|bun|deno]\` or \`${getCmd(packageManager)} update [true|false] [npm|pnpm|yarn|bun|deno]\``)
31
37
  status = 1
32
38
  }
33
39
  } catch (error) {
34
- console.error('Setup failed:', error.message)
40
+ console.error('nuxt-spec CLI failed:', error.message)
35
41
  status = 1
36
42
  }
37
43
  process.exit(status)
@@ -1,9 +1,22 @@
1
1
  import { getPackageManager } from 'elrh-cosca'
2
2
 
3
+ export const SUPPORTED_PACKAGE_MANAGERS = ['npm', 'pnpm', 'yarn', 'bun', 'deno']
4
+
5
+ // get the package manager name for usage in commands
6
+ // explicit override takes precedence over auto-detection
7
+ export function resolvePackageManager(override) {
8
+ if (override) {
9
+ if (!SUPPORTED_PACKAGE_MANAGERS.includes(override)) {
10
+ throw new Error(`Unsupported package manager '${override}'. Use one of: ${SUPPORTED_PACKAGE_MANAGERS.join(', ')}`)
11
+ }
12
+ return override
13
+ }
14
+ return getPackageManager()
15
+ }
16
+
3
17
  // use nuxt-spec CLI tool
4
- export function getCmd() {
18
+ export function getCmd(packageManager) {
5
19
  const command = 'nuxt-spec'
6
- const packageManager = getPackageManager()
7
20
  switch (packageManager) {
8
21
  case 'pnpm':
9
22
  return `pnpx ${command}`
@@ -24,19 +37,36 @@ export function getUpdateCmd(packageManager, target) {
24
37
  case 'pnpm':
25
38
  return `pnpm update ${target}`
26
39
  case 'yarn':
27
- return `yarn upgrade ${target}`
40
+ return `yarn up ${target}`
28
41
  case 'bun':
29
42
  return `bun update ${target}`
30
43
  case 'deno':
31
44
  return `deno add npm:${target}`
32
45
  default:
33
- return `npm update ${target}`
46
+ return `npm install ${target}`
47
+ }
48
+ }
49
+
50
+ // generate Nuxt types and auto-imports
51
+ export function getPrepareCmd(packageManager) {
52
+ const command = 'nuxt prepare'
53
+ switch (packageManager) {
54
+ case 'pnpm':
55
+ return `pnpm exec ${command}`
56
+ case 'yarn':
57
+ return `yarn ${command}`
58
+ case 'bun':
59
+ return `bunx ${command}`
60
+ case 'deno':
61
+ return `deno run -A npm:${command}`
62
+ default:
63
+ return `npx ${command}`
34
64
  }
35
65
  }
36
66
 
37
67
  // install/update playwright
38
68
  export function getPlaywrightInstallCmd(packageManager) {
39
- const command = 'playwright-core install'
69
+ const command = 'playwright install'
40
70
  switch (packageManager) {
41
71
  case 'pnpm':
42
72
  return `pnpm exec ${command}`
package/bin/setup.js CHANGED
@@ -2,13 +2,15 @@
2
2
 
3
3
  import { execSync } from 'node:child_process'
4
4
  import {
5
- createFileFromWebTemplate, deletePath, getPackageManager, hasJsonKey,
5
+ createFileFromWebTemplate, deletePath, hasJsonKey,
6
6
  pathExists, promptUser, removeFromJsonFile, showMessage,
7
7
  updateConfigFile, updateJsonFile, updateTextFile,
8
8
  } from 'elrh-cosca'
9
- import { getPlaywrightInstallCmd } from './helpers/commands.js'
9
+ import {
10
+ getPlaywrightInstallCmd, getPrepareCmd,
11
+ } from './helpers/commands.js'
10
12
 
11
- const TARGET_VERSION = '0.3.2'
13
+ const TARGET_VERSION = '0.3.4'
12
14
 
13
15
  /**
14
16
  * CLI tool to scaffold necessary adjustments in project folder.
@@ -25,11 +27,13 @@ const TARGET_VERSION = '0.3.2'
25
27
  * 7) creates sample test files
26
28
  * 8) clear node_modules and lock file(s)
27
29
  * 9) run install command
28
- * 10) run Playwright setup command
30
+ * 10) run Nuxt prepare command to generate types and auto-imports
31
+ * 11) run Playwright setup command
29
32
  *
30
33
  * @param {boolean} autoRun - Whether to run the setup automatically without any prompts (defaults to false).
34
+ * @param {string} [packageManager] - Package manager to be used (`npm`, `pnpm`, `yarn`, `bun` or `deno`).
31
35
  */
32
- export async function specSetup(autoRun = false) {
36
+ export async function specSetup(autoRun = false, packageManager) {
33
37
  showMessage('NUXT SPEC SETUP')
34
38
  showMessage('This CLI tool will help you include Nuxt Spec in your project.')
35
39
  showMessage('Refer to the documentation for more information.', 2)
@@ -37,8 +41,6 @@ export async function specSetup(autoRun = false) {
37
41
  const isAutoRun = autoRun || await promptUser('Do you want to set everything up automatically (no more prompts)?')
38
42
  showMessage('')
39
43
 
40
- const packageManager = getPackageManager()
41
-
42
44
  // 1) manage dependencies in package.json
43
45
 
44
46
  // add nuxt-spec
@@ -243,7 +245,19 @@ export async function specSetup(autoRun = false) {
243
245
  }
244
246
  }
245
247
 
246
- // 10) run Playwright browser install command
248
+ // 10) run Nuxt prepare command to generate types and auto-imports
249
+ const prepareCmd = getPrepareCmd(packageManager)
250
+ const runPrepare = isAutoRun || await promptUser(`Nuxt needs to generate types and auto-imports before the project is fully usable. Do you want to run \`${prepareCmd}\` now?`)
251
+ if (runPrepare) {
252
+ try {
253
+ showMessage(`Running \`${prepareCmd}\`...`)
254
+ execSync(prepareCmd, { stdio: 'inherit' })
255
+ } catch (error) {
256
+ console.error(`Error running \`${prepareCmd}\`:\n`, error.message)
257
+ }
258
+ }
259
+
260
+ // 11) run Playwright browser install command
247
261
  const playwrightInstallCmd = getPlaywrightInstallCmd(packageManager)
248
262
  const runPlaywrightInstall = isAutoRun || await promptUser(`Playwright browser runtimes might need to be installed locally for e2e tests. Do you want to run \`${playwrightInstallCmd}\` now?`)
249
263
  if (runPlaywrightInstall) {
@@ -255,12 +269,15 @@ export async function specSetup(autoRun = false) {
255
269
  }
256
270
  }
257
271
 
258
- // 11) inform user
272
+ // 12) inform user
259
273
  showMessage('')
260
274
  showMessage('NUXT SPEC SETUP COMPLETE', 2)
261
275
  if (!runInstall) {
262
276
  showMessage(`Proceed with \`${packageManager} install\` to install dependencies.`)
263
277
  }
278
+ if (!runPrepare) {
279
+ showMessage(`Run \`${prepareCmd}\` to generate the required Nuxt types and auto-imports.`)
280
+ }
264
281
  if (!runPlaywrightInstall) {
265
282
  showMessage(`Run \`${playwrightInstallCmd}\` to setup the Playwright browser runtimes for e2e tests.`)
266
283
  }
package/bin/update.js CHANGED
@@ -1,10 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import { execSync } from 'node:child_process'
4
- import { getPackageManager, hasJsonKey, promptUser, showMessage } from 'elrh-cosca'
5
- import { getPlaywrightInstallCmd, getUpdateCmd } from './helpers/commands.js'
4
+ import {
5
+ hasJsonKey, promptUser, showMessage,
6
+ } from 'elrh-cosca'
7
+ import {
8
+ getPlaywrightInstallCmd, getPrepareCmd, getUpdateCmd,
9
+ } from './helpers/commands.js'
6
10
 
7
- const TARGET_VERSION = '0.3.2'
11
+ const TARGET_VERSION = '0.3.4'
8
12
 
9
13
  /**
10
14
  * CLI tool to update existing `nuxt-spec` installation.
@@ -14,11 +18,13 @@ const TARGET_VERSION = '0.3.2'
14
18
  * Then it:
15
19
  * 1) verifies `nuxt-spec` is present in `package.json` (fails with a hint to run `setup` otherwise)
16
20
  * 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
21
+ * 3) run the `nuxt prepare` command to regenerate types and auto-imports
22
+ * 4) run the `playwright install` command to ensure the Playwright browser runtimes are up to date
18
23
  *
19
24
  * @param {boolean} autoRun - Whether to run the update automatically without any prompts (defaults to false).
25
+ * @param {string} [packageManager] - Package manager to be used (`npm`, `pnpm`, `yarn`, `bun` or `deno`).
20
26
  */
21
- export async function specUpdate(autoRun = false) {
27
+ export async function specUpdate(autoRun = false, packageManager) {
22
28
  showMessage('NUXT SPEC UPDATE')
23
29
  showMessage('This CLI tool will help you update Nuxt Spec in your project.')
24
30
  showMessage('Refer to the documentation for more information.', 2)
@@ -34,8 +40,6 @@ export async function specUpdate(autoRun = false) {
34
40
  const isAutoRun = autoRun || await promptUser('Do you want to update everything automatically (no more prompts)?')
35
41
  showMessage('')
36
42
 
37
- const packageManager = getPackageManager()
38
-
39
43
  // 1) run 'update nuxt-spec'
40
44
  const updateCmd = getUpdateCmd(packageManager, `nuxt-spec@${TARGET_VERSION}`)
41
45
  const runUpdate = isAutoRun || await promptUser(`This will bump 'nuxt-spec' to version '${TARGET_VERSION}' by running \`${updateCmd}\`. Continue?`)
@@ -48,7 +52,19 @@ export async function specUpdate(autoRun = false) {
48
52
  }
49
53
  }
50
54
 
51
- // 2) run 'playwright-core install'
55
+ // 2) run 'nuxt prepare'
56
+ const prepareCmd = getPrepareCmd(packageManager)
57
+ const runPrepare = isAutoRun || await promptUser(`Nuxt types and auto-imports should be regenerated after the update. Do you want to run \`${prepareCmd}\` now?`)
58
+ if (runPrepare) {
59
+ try {
60
+ showMessage(`Running \`${prepareCmd}\`...`)
61
+ execSync(prepareCmd, { stdio: 'inherit' })
62
+ } catch (error) {
63
+ console.error(`Error running \`${prepareCmd}\`:\n`, error.message)
64
+ }
65
+ }
66
+
67
+ // 3) run 'playwright install'
52
68
  const playwrightUpdateCmd = getPlaywrightInstallCmd(packageManager)
53
69
  const runPlaywrightUpdate = isAutoRun || await promptUser(`Playwright browser runtimes might need to be updated for e2e tests. Do you want to run \`${playwrightUpdateCmd}\` now?`)
54
70
  if (runPlaywrightUpdate) {
@@ -60,12 +76,15 @@ export async function specUpdate(autoRun = false) {
60
76
  }
61
77
  }
62
78
 
63
- // 3) inform user
79
+ // 4) inform user
64
80
  showMessage('')
65
81
  showMessage('NUXT SPEC UPDATE COMPLETE', 2)
66
82
  if (!runUpdate) {
67
83
  showMessage(`Run \`${updateCmd}\` to update 'nuxt-spec'.`)
68
84
  }
85
+ if (!runPrepare) {
86
+ showMessage(`Run \`${prepareCmd}\` to regenerate the Nuxt types and auto-imports.`)
87
+ }
69
88
  if (!runPlaywrightUpdate) {
70
89
  showMessage(`Run \`${playwrightUpdateCmd}\` to update the Playwright browser runtimes for e2e tests.`)
71
90
  }
package/config/index.d.ts CHANGED
@@ -15,7 +15,7 @@ type ExtendedUserConfig = UserConfig & {
15
15
  */
16
16
  type ProjectsConfig = boolean | {
17
17
  default?: boolean
18
- node?: boolean
18
+ unit?: boolean
19
19
  nuxt?: boolean
20
20
  e2e?: boolean
21
21
  browser?: boolean
package/config/index.mjs CHANGED
@@ -11,8 +11,12 @@ import { defineVitestProject } from '@nuxt/test-utils/config'
11
11
  import { playwright } from '@vitest/browser-playwright'
12
12
  import vue from '@vitejs/plugin-vue'
13
13
 
14
- // absolute path so it works from nuxt-ignis package
14
+ // absolute paths so it works from within the nuxt-ignis package
15
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
16
20
 
17
21
  export async function loadVitestConfig(userVitestConfig, projects = true) {
18
22
  const baseConfig = {
@@ -46,11 +50,11 @@ export async function loadVitestConfig(userVitestConfig, projects = true) {
46
50
  }
47
51
 
48
52
  // proposed setup for Unit tests
49
- if (projects.node !== false) {
53
+ if (projects.unit !== false) {
50
54
  baseConfig.test.projects.push({
51
55
  extends: true,
52
56
  test: {
53
- name: 'node',
57
+ name: 'unit',
54
58
  include: ['test/unit/**/*.{test,spec}.ts'],
55
59
  environment: 'node',
56
60
  },
@@ -81,12 +85,26 @@ export async function loadVitestConfig(userVitestConfig, projects = true) {
81
85
  environment: 'node',
82
86
  // create report file for visual regression testing
83
87
  globalSetup: [screenshotReportSetup],
88
+ // allows connecting to an external Playwright instance,
89
+ // if NUXT_SPEC_EXTERNAL_PLAYWRIGHT is set
90
+ setupFiles: externalPlaywright ? [externalPlaywrightSetup] : [],
84
91
  },
85
92
  })
86
93
  }
87
94
 
88
95
  // proposed setup for browser component tests (with Playwright runner)
89
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
+ }
90
108
  baseConfig.test.projects.push({
91
109
  extends: true,
92
110
  // vue plugin is required for proper imports resolution
@@ -95,9 +113,9 @@ export async function loadVitestConfig(userVitestConfig, projects = true) {
95
113
  name: 'browser',
96
114
  include: ['test/browser/**/*.{test,spec}.ts'],
97
115
  environment: 'node',
98
- // only chromium browser - add others manually if needed
116
+ // only chromium browser by default - add others manually if needed
99
117
  browser: {
100
- provider: playwright(),
118
+ provider: playwright(playwrightConfig),
101
119
  enabled: true,
102
120
  headless: true,
103
121
  instances: [{
@@ -1,4 +1,19 @@
1
1
  # settings for Nuxt & pnpm
2
2
 
3
- # https://pnpm.io/settings#shamefullyhoist
3
+ # https://pnpm.io/settings/node-modules#shamefullyhoist
4
+ # required to handle transitive dependencies
5
+ # without having to explicitly declare them
4
6
  shamefullyHoist: true
7
+
8
+ # https://pnpm.io/settings/build#allowbuilds
9
+ # pnpm naturally blocks all post-install scripts
10
+ # some are required for development, others are not relevant
11
+ allowBuilds:
12
+ # provides fallback repair of platform-specific Rust native engine
13
+ 'unrs-resolver': true
14
+ # allows node-gyp build of associated native binaries from local sources
15
+ # disabled because it would require an explicit opt-in
16
+ '@parcel/watcher': false
17
+ # optimization for CLI usage of 'esbuild'
18
+ # disabled because its runtime resolves native binaries itself
19
+ 'esbuild': false
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-spec",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
4
4
  "description": "Test-pack layer for Nuxt Applications",
5
5
  "repository": {
6
6
  "type": "git",
@@ -40,24 +40,26 @@
40
40
  "dependencies": {
41
41
  "@nuxt/eslint": "~1.17.0",
42
42
  "@nuxt/hints": "1.1.4",
43
- "@nuxt/test-utils": "4.1.0",
43
+ "@nuxt/test-utils": "4.2.0",
44
44
  "@vitejs/plugin-vue": "~6.0.8",
45
- "@vitest/browser": "4.1.10",
46
- "@vitest/browser-playwright": "4.1.10",
47
- "@vitest/ui": "4.1.10",
48
- "@vue/test-utils": "2.4.11",
45
+ "@vitest/browser": "4.1.11",
46
+ "@vitest/browser-playwright": "4.1.11",
47
+ "@vitest/ui": "4.1.11",
48
+ "@vue/test-utils": "2.5.0",
49
49
  "elrh-cosca": "0.3.6",
50
50
  "fast-png": "~8.0.0",
51
- "happy-dom": "~20.11.2",
51
+ "h3-next": "npm:h3@~2.0.1-rc.31",
52
+ "happy-dom": "~20.14.0",
52
53
  "nuxt": "4.5.2",
53
54
  "pixelmatch": "~7.2.0",
55
+ "playwright": "~1.62.1",
54
56
  "playwright-core": "~1.62.1",
55
57
  "typescript": "~6.0.3",
56
- "vitest": "4.1.10",
58
+ "vitest": "4.1.11",
57
59
  "vitest-browser-vue": "2.1.0",
58
- "vue": "~3.5.40",
59
- "vue-router": "~5.2.0",
60
- "vue-tsc": "~3.3.9"
60
+ "vue": "~3.5.42",
61
+ "vue-router": "~5.3.1",
62
+ "vue-tsc": "~3.3.11"
61
63
  },
62
64
  "scripts": {
63
65
  "analyze": "nuxt analyze",
@@ -0,0 +1,20 @@
1
+ // Vitest setup file for the `e2e` project
2
+ // allows connecting to an external Playwright instance,
3
+ // if NUXT_SPEC_EXTERNAL_PLAYWRIGHT is set
4
+
5
+ import { chromium, firefox, webkit } from 'playwright-core'
6
+ import type { Browser, BrowserType } from 'playwright-core'
7
+
8
+ const externalPlaywright = process.env.NUXT_SPEC_EXTERNAL_PLAYWRIGHT
9
+
10
+ if (externalPlaywright) {
11
+ for (const browserType of [chromium, firefox, webkit] as BrowserType[]) {
12
+ console.log(`[Nuxt Spec - e2e] Using external Playwright instance at: ${externalPlaywright}`)
13
+ // @nuxt/test-utils always calls `playwright[type].launch()` with no way to opt into
14
+ // `connect()`, so the launch method is swapped for a connect against the WS endpoint
15
+ browserType.launch = (): Promise<Browser> => browserType.connect(externalPlaywright, {
16
+ // this allows reaching caller's localhost from within the external Playwright
17
+ exposeNetwork: '<loopback>',
18
+ })
19
+ }
20
+ }