nuxt-spec 0.2.4-alpha.3 → 0.2.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.
package/README.md CHANGED
@@ -1,413 +1,417 @@
1
- # Nuxt Spec
2
-
3
- ![Nuxt Spec](https://github.com/AloisSeckar/nuxt-spec/blob/main/public/nuxt-spec.png)
4
-
5
- **Nuxt Spec** (aka `nuxt-spec`) is a base layer for [Nuxt](https://nuxt.com/) applications incorporating together a couple of testing libraries and packages and providing some utility functions. I created this project in early 2025 because I was unable to find a convenient "one-dependency" way to start testing my Nuxt apps and I didn't want to repeat the same steps and maintain the same set of dependencies over and over.
6
-
7
- While Nuxt itself does have a [dedicated module for testing](https://nuxt.com/docs/getting-started/testing), to remain as versatile as possible, it has to be combined with other packages (which can be different based on your choice). I am trying to overcome this by defining "The Way". This is both the strength and the weakness of this project. You were warned.
8
-
9
- The most important client of `nuxt-spec` is my [Nuxt Ignis](https://github.com/AloisSeckar/nuxt-ignis) template starter that adds up even more ready-to-use cool stuff for your future awesome Nuxt websites.
10
-
11
- ## How to use
12
-
13
- Aside from being "forked" and used as you see fit, `nuxt-spec` is also available as an [NPM package](https://www.npmjs.com/package/nuxt-spec) that can be referenced as a single-import with all the features incoming.
14
-
15
- The `nuxt-spec` package comes with a built-in CLI tool that can help you:
16
-
17
- - setup the dependency in your project
18
- - scaffold the default `vitest.config.ts` (see [configuration](#configuration) section)
19
- - add a few test-related script shorthands into your `package.json` (see [running tests](#running-tests) section)
20
- - create demo test files in proposed file structure
21
-
22
- To use it, just run the CLI script in your terminal:
23
-
24
- | Manager | Command |
25
- | ----------------- | --------- |
26
- | npm | `npx nuxt-spec setup` |
27
- | yarn | `yarn dlx nuxt-spec setup` |
28
- | pnpm | `pnpx nuxt-spec setup` |
29
- | Bun | `bunx nuxt-spec setup` |
30
- | Deno | `deno run --allow-run npm:npx nuxt-spec setup` |
31
-
32
- First, the CLI tool will ask you whether you want to do the setup automatically. If you choose `y`es, it will perform all the steps for you. If you choose `n`o, it will guide you through the manual setup step-by-step (see [manual setup](#manual-setup) section).
33
-
34
- ### Manual setup
35
-
36
- If you don't want to use the CLI tool, or you want to understand its flow better, here are the detailed steps:
37
-
38
- **1)** - Add following dependency into your `package.json`:
39
-
40
- ```json
41
- "nuxt-spec": "0.2.4-alpha"
42
- ```
43
-
44
- It is advised to remove explicit `nuxt`, `vue` and `vue-router` dependencies, if present. The `nuxt-spec` layer brings them and there might be version clashes if defined in both places.
45
-
46
- **2)** - Add following section into your `nuxt.config.ts`:
47
-
48
- ```ts
49
- extends: [
50
- 'nuxt-spec'
51
- ]
52
- ```
53
-
54
- **3)** - If `pnpm` is used, add `pnpm-workspace.yaml` file with following content (if you don't have it yet):
55
-
56
- ```yaml
57
- shamefullyHoist: true
58
- ```
59
-
60
- **4)** Add `vitest.config.ts` file with following content (if you don't have it yet):
61
-
62
- ```ts
63
- import { loadVitestConfig } from 'nuxt-spec/config'
64
-
65
- export default loadVitestConfig({
66
- // your custom config here
67
- })
68
- ```
69
-
70
- **5)** Add `.nuxtrc` file with following content (if you don't have it yet):
71
-
72
- ```text
73
- setups.@nuxt/test-utils="4.0.3"
74
- ```
75
-
76
- **6)** - (Optional) Add following scripts into your `package.json`:
77
-
78
- ```json
79
- "scripts": {
80
- "test": "vitest run",
81
- "test-u": "vitest run -u",
82
- "test-i": "vitest"
83
- }
84
- ```
85
-
86
- **7)** - (Optional) Setup file structures for tests as follows:
87
-
88
- ```text
89
- test/
90
- ├── browser/
91
- │ └── vitest-browser.test.ts
92
- ├── e2e/
93
- │ └── nuxt-e2e.test.ts
94
- │ └── nuxt-visual.test.ts
95
- ├── nuxt/
96
- │ └── nuxt-unit.test.ts
97
- └── unit/
98
- └── vitest-unit.test.ts
99
- ```
100
-
101
- You can use sample files from the [project repository](https://github.com/AloisSeckar/nuxt-spec/tree/v0.2.4-alpha/test).
102
-
103
- ### Install and execute
104
-
105
- Whether you used the CLI tool or did the manual setup, you are ready to install and run the tests.
106
-
107
- **1)** - Install the dependencies:
108
-
109
- It is advised to remove `node_modules` and delete lock file first. Then proceed with fresh installation.
110
-
111
- <!-- tabs:start -->
112
-
113
- #### Install using **npm**
114
-
115
- ```bash
116
- npm install
117
- ```
118
-
119
- #### Install using **yarn**
120
-
121
- ```bash
122
- yarn install
123
- ```
124
-
125
- #### Install using **pnpm**
126
-
127
- ```bash
128
- pnpm install
129
- ```
130
-
131
- #### Install using **bun**
132
-
133
- ```bash
134
- bun install
135
- ```
136
-
137
- <!-- tabs:end -->
138
-
139
- **2)** - If you're prompted (for the first time when installing to a new machine), install headless browser runtimes:
140
-
141
- <!-- tabs:start -->
142
-
143
- #### Setup runtime using **npm**
144
-
145
- ```bash
146
- npx playwright-core install
147
- ```
148
-
149
- #### Setup runtime using **yarn**
150
-
151
- ```bash
152
- yarn dlx playwright-core install
153
- ```
154
-
155
- #### Setup runtime using **pnpm**
156
-
157
- ```bash
158
- pnpm exec playwright-core install
159
- ```
160
-
161
- #### Setup runtime using **bun**
162
-
163
- ```bash
164
- bunx playwright-core install
165
- ```
166
-
167
- <!-- tabs:end -->
168
-
169
- **3)** - Start the development server of your awesome Nuxt project:
170
-
171
- <!-- tabs:start -->
172
-
173
- #### Start server using **npm**
174
-
175
- ```bash
176
- npm run dev
177
- ```
178
-
179
- #### Start server using **yarn**
180
-
181
- ```bash
182
- yarn dev
183
- ```
184
-
185
- #### Start server using **pnpm**
186
-
187
- ```bash
188
- pnpm dev
189
- ```
190
-
191
- #### Start server using **bun**
192
-
193
- ```bash
194
- bun run dev
195
- ```
196
-
197
- <!-- tabs:end -->
198
-
199
- ### Running tests
200
-
201
- Once installed, Vitest automatically discovers all `*.test.ts` and `*.spec.ts` files in project and becomes capable of running them.
202
-
203
- You can use those three optional commands `package.json` file in `"scripts"` section in order to run tests easily:
204
-
205
- - `test: vitest run` - runs once and ends
206
- - `test-u: vitest run -u` - runs once and updates snapshots
207
- - `test-i: vitest` - runs and waits in HMR mode for test file changes
208
-
209
- Then you can call in terminal in root of your project:
210
-
211
- <!-- tabs:start -->
212
-
213
- #### Testing using **npm**
214
-
215
- ```bash
216
- npm run test # runs once and ends
217
- npm run test-u # runs once and updates snapshots
218
- npm run test-i # runs and waits in HMR mode
219
- ```
220
-
221
- #### Tsting using **yarn**
222
-
223
- ```bash
224
- yarn test # runs once and ends
225
- yarn test-u # runs once and updates snapshots
226
- yarn test-i # runs and waits in HMR mode
227
- ```
228
-
229
- #### Testing using **pnpm**
230
-
231
- ```bash
232
- pnpm test # runs once and ends
233
- pnpm test-u # runs once and updates snapshots
234
- pnpm test-i # runs and waits in HMR mode
235
- ```
236
-
237
- #### Testing using **bun**
238
-
239
- ```bash
240
- bun run test # runs once and ends
241
- bun run test-u # runs once and updates snapshots
242
- bun run test-i # runs and waits in HMR mode
243
- ```
244
-
245
- <!-- tabs:end -->
246
-
247
- Or you can use the `vitest` command directly with all its parameters. See [Vitest CLI documentation](https://vitest.dev/guide/cli.html) for more info.
248
-
249
- ## Overview
250
-
251
- **Nuxt Spec** currently contains:
252
-
253
- - [vitest](https://www.npmjs.com/package/vitest) **v4** as the fundamental testing framework
254
- - [@vitest/browser](https://www.npmjs.com/package/@vitest/browser) as more advanced browser-native testing runner
255
- - [@vitest/ui](https://www.npmjs.com/package/@vitest/ui) as graphic UI above the Vitest test runner
256
- - [happy-dom](https://www.npmjs.com/package/happy-dom) as the headless browser runtime
257
- - [playwright-core](https://www.npmjs.com/package/playwright-core) as the headless browser testing framework
258
- - [@vue/test-utils](https://www.npmjs.com/package/@vue/test-utils) for testing Vue stuff
259
- - [@nuxt/test-utils](https://www.npmjs.com/package/@nuxt/test-utils) for testing Nuxt stuff
260
-
261
- Planned future development:
262
-
263
- - reason about (not) using Vitest browser mode (or make it optional)
264
- - solution for visual regression testing - (currently there is experimental custom solution)
265
-
266
- See [CHANGELOG.md](https://github.com/AloisSeckar/nuxt-spec/blob/v0.2.4-alpha/CHANGELOG.md) for the latest updates and features.
267
-
268
- ## Configuration
269
-
270
- By default, `nuxt-spec` uses Vitest configuration defined in [`/config/index.mjs`](https://github.com/AloisSeckar/nuxt-spec/blob/v0.2.4-alpha/config/index.mjs). The configuration is based on [Nuxt team recommendations](https://nuxt.com/docs/4.x/getting-started/testing) and our best judgement.
271
-
272
- To add/override your custom config, you can create (or scaffold via CLI tool) a file named `vitest.config.ts` in the root of your project with the following content:
273
-
274
- ```ts
275
- import { loadVitestConfig } from 'nuxt-spec/config'
276
-
277
- export default loadVitestConfig({
278
- // your custom config here
279
- })
280
- ```
281
-
282
- And pass whatever you want as a parameter object. It will be defu-merged with the defaults (custom config takes precedence). The object is typed to be compatible with both [Vite](https://vite.dev/config/) and [Vitest](https://vitest.dev/config/) configuration options. Used type is derived from the respective `.d.ts` files of those packages.
283
-
284
- **NOTE**: Based on the [Vitest documentation](https://main.vitest.dev/config/), it is possible to pass in **any configuration option** valid for [Vite](https://vite.dev/config/). Configuration related directly to Vitest must be passed under the `test` key, e.g.:
285
-
286
- ```ts
287
- import { loadVitestConfig } from 'nuxt-spec/config'
288
-
289
- export default loadVitestConfig({
290
- test: {
291
- // your custom config specific to Vitest here
292
- }
293
- // by the nature of the Vitest config resolution,
294
- // you may also pass ANY OTHER valid Vite configuration options here
295
- })
296
- ```
297
-
298
- By default, Nuxt Spec built-in configuration establishes 4 `projects` + one fallback:
299
-
300
- - `unit` - for unit tests in `test/unit/**` - env is set to `node`
301
- - `nuxt` - for Nuxt-related tests in `test/nuxt/**` - env is set to `nuxt`
302
- - `e2e` - for end-to-end tests in `test/e2e/**` - env is set to `node`
303
- - `browser` - for browser-mode tests in `test/browser/**` - env is set to `node` (this is effectively an alternative to `nuxt` relying on `@vitest/browser` instead of `@nuxt/test-utils`)
304
- - `default` - fallback for all other tests in `test/**` and/or `tests/**` directories - env is set to `node`
305
-
306
- Vitest will then expect at least one test defined in either of those directories. Any parts of the `test.projects` config may be altered and user-defined values will be logically merged with the defaults. Also you may add new custom projects' definitions to fit your needs. If your project uses significantly different configuration (i.e. your tests reside in completely different path), you can pass `false` as a second parameter to `loadVitestConfig()` function to exclude default `test.projects` values from being injected completely:
307
-
308
- ```ts
309
- import { loadVitestConfig } from 'nuxt-spec/config'
310
-
311
- export default loadVitestConfig({
312
- // your custom config here
313
- }, false)
314
- ```
315
-
316
- Alternatively, if you don't want to use any part of the `nuxt-spec` default configuration at all, you can override `vitest.config.ts` file completely and define your own [Vitest configuration](https://vitest.dev/config/) from scratch.
317
-
318
- ### Filtering out log messages
319
-
320
- Some tedious and unrelevant log messages may keep appearing in running tests creating noise and hiding the real issues.
321
-
322
- Via `NUXT_SPEC_MESSAGE_FILTERS` env variable you may pass a comma-separated list of (plain) text patterns that should be omited.
323
-
324
- It only applies to logs processed by `vitest` though, so some messages might still prevail.
325
-
326
- ## Utilities
327
-
328
- Nuxt Spec offers a couple of utility functions that are exported via `nuxt-spec/utils` subpackage.
329
-
330
- You can use them in your test files as follows:
331
-
332
- ```ts
333
- import { compareScreenshot, gotoPage, getDataHtml, getAPIResultHtml, } from 'nuxt-spec/utils'
334
-
335
- // accepts instance of NuxtPage (from @nuxt/test-utils)
336
- // takes a screenshot of current viewport and compares it with stored baseline
337
- // the comparison is done using `pixelmatch` library
338
- // if screenshot doesn't exist, it will be created in __baseline__ subfolder
339
- // screenshot from current run is always captured into __current__ subfolder
340
- // if screenshots don't match, the method will cause Vitest test to fail
341
- // accepts optional object with extra options:
342
- // - `fileName` - name of the screenshot file (default is based on current route)
343
- // - `selector` - CSS selector of the element to capture (default is full page)
344
- // - `targetDir` - directory where the screenshots should be stored (default is `./test/e2e/`)
345
- // - `maxDiffPixelRatio` - allows mitigating cross-platform rendering differences by setting
346
- // a 0-1 scale tolerance (default 0)
347
- // - `maxDiffPixels` - same but with exact max value of different pixels which overrides setting
348
- // `maxDiffPixelRatio` (default 0)
349
- // - `threshold` - allows adjusting the tolerance for "same" color on 0-1 scale (default 0.1)
350
-
351
- // will produce "index.png" file in `./test/e2e/` directory
352
- await compareScreenshot(page)
353
- // will produce "homepage.png"
354
- await compareScreenshot(page, { fileName: 'homepage.png' })
355
- // will produce "component.png" only with id="test" element
356
- await compareScreenshot(page, { fileName: 'component.png', selector: '#test' })
357
- // will produce "homepage.png" in `/screenshots` directory
358
- await compareScreenshot(page, { fileName: 'homepage.png', targetDir: '/screenshots' })
359
- // will produce "homepage.png" and the comparison will only fail when more than 1000 pixels differ
360
- await compareScreenshot(page, { fileName: 'homepage.png', maxDiffPixels: 1000 })
361
- // will produce "homepage.png", the comparison will only fail when more than 1000 pixels differ
362
- // while more pixels will be considered "same" based on color
363
- await compareScreenshot(page, { fileName: 'homepage.png', maxDiffPixels: 1000, threshold: 0.5 })
364
-
365
- // navigates to given URL and returns the instance of NuxtPage (from @nuxt/test-utils)
366
- const page: NuxtPage = await gotoPage('url')
367
-
368
- // accepts either a URL string or instance of NuxtPage (from @nuxt/test-utils) and a CSS selector
369
- // returns `innerHTML` of the element matching the selector
370
- const html: string = await getDataHtml('/', '#test')
371
- const html: string = await getDataHtml(page, '#test')
372
-
373
- // accepts either a URL string or instance of NuxtPage (from @nuxt/test-utils)
374
- // css selector for element that triggers API call when clicked (i.e. button)
375
- // fragment of API endpoint URL that should be called (to test the response)
376
- // css selector for element where the API response should be rendered (i.e. div)
377
- // returns `innerHTML` of the element matching the result selector after the API call
378
- // is made by Playwright runner
379
- const html: string = await getAPIResultHtml('/', '#api-fetch', '/your-api', '#api-result')
380
- const html: string = await getAPIResultHtml(page, '#api-fetch', '/your-api', '#api-result')
381
- ```
382
-
383
- For detailed description, see [utils.d.ts](https://github.com/AloisSeckar/nuxt-spec/blob/v0.2.4-alpha/utils/index.d.ts).
384
-
385
- The `compareScreenshot` function usage results into HTML report file being automatically created. The file is generated within the specified `__current__` directory as `report_YYYYMMDDHHMMSS.html`. It contains all failed screenshots comparison. When test suite is over, file is attempted to be opened in system default browser (unless Node operates in `CI` mode).
386
-
387
- ### Notice on non-default setups
388
-
389
- The creation of the report file and it's proper wrap-up at the end is ensured via `globalSetup` function passed into default Vitest E2E suite defined by Nuxt Spec. If you need to override the default `e2e` project, you also need to make sure to call the setup function manually.
390
-
391
- Add following into your `vitest.config.ts`:
392
-
393
- ```ts
394
- // vitest.config.ts
395
- import { loadVitestConfig } from 'nuxt-spec/config'
396
-
397
- // resolve path to Nuxt Spec's setup function
398
- const screenshotReportSetup = fileURLToPath(new URL('../utils/screenshot.ts', import.meta.resolve('nuxt-spec/config')))
399
-
400
- export default loadVitestConfig({
401
- // whatever e2e test you are defining
402
- test: {
403
- // provide it to your `compareScreenshot` using test suite
404
- globalSetup: [screenshotReportSetup],
405
- // other config
406
- },
407
- // other config
408
- })
409
- ```
410
-
411
- ## Contact
412
-
413
- Use GitHub issues to report bugs or suggest improvements. I will be more than happy to address them.
1
+ # Nuxt Spec
2
+
3
+ ![Nuxt Spec](https://github.com/AloisSeckar/nuxt-spec/blob/main/public/nuxt-spec.png)
4
+
5
+ **Nuxt Spec** (aka `nuxt-spec`) is a base layer for [Nuxt](https://nuxt.com/) applications incorporating together a couple of testing libraries and packages and providing some utility functions. I created this project in early 2025 because I was unable to find a convenient "one-dependency" way to start testing my Nuxt apps and I didn't want to repeat the same steps and maintain the same set of dependencies over and over.
6
+
7
+ While Nuxt itself does have a [dedicated module for testing](https://nuxt.com/docs/getting-started/testing), to remain as versatile as possible, it has to be combined with other packages (which can be different based on your choice). I am trying to overcome this by defining "The Way". This is both the strength and the weakness of this project. You were warned.
8
+
9
+ The most important client of `nuxt-spec` is my [Nuxt Ignis](https://github.com/AloisSeckar/nuxt-ignis) template starter that adds up even more ready-to-use cool stuff for your future awesome Nuxt websites.
10
+
11
+ ## How to use
12
+
13
+ Aside from being "forked" and used as you see fit, `nuxt-spec` is also available as an [NPM package](https://www.npmjs.com/package/nuxt-spec) that can be referenced as a single-import with all the features incoming.
14
+
15
+ The `nuxt-spec` package comes with a built-in CLI tool that can help you:
16
+
17
+ - setup the dependency in your project
18
+ - scaffold the default `vitest.config.ts` (see [configuration](#configuration) section)
19
+ - add a few test-related script shorthands into your `package.json` (see [running tests](#running-tests) section)
20
+ - create demo test files in proposed file structure
21
+
22
+ To use it, just run the CLI script in your terminal:
23
+
24
+ | Manager | Command |
25
+ | ----------------- | --------- |
26
+ | npm | `npx nuxt-spec setup` |
27
+ | yarn | `yarn dlx nuxt-spec setup` |
28
+ | pnpm | `pnpx nuxt-spec setup` |
29
+ | Bun | `bunx nuxt-spec setup` |
30
+ | Deno | `deno run --allow-run npm:npx nuxt-spec setup` |
31
+
32
+ First, the CLI tool will ask you whether you want to do the setup automatically. If you choose `y`es, it will perform all the steps for you. If you choose `n`o, it will guide you through the manual setup step-by-step (see [manual setup](#manual-setup) section).
33
+
34
+ ### Manual setup
35
+
36
+ If you don't want to use the CLI tool, or you want to understand its flow better, here are the detailed steps:
37
+
38
+ **1)** - Add following dependency into your `package.json`:
39
+
40
+ ```json
41
+ "nuxt-spec": "0.2.4"
42
+ ```
43
+
44
+ It is advised to remove explicit `nuxt`, `vue` and `vue-router` dependencies, if present. The `nuxt-spec` layer brings them and there might be version clashes if defined in both places.
45
+
46
+ **2)** - Add following section into your `nuxt.config.ts`:
47
+
48
+ ```ts
49
+ extends: [
50
+ 'nuxt-spec'
51
+ ]
52
+ ```
53
+
54
+ **3)** - If `pnpm` is used, add `pnpm-workspace.yaml` file with following content (if you don't have it yet):
55
+
56
+ ```yaml
57
+ shamefullyHoist: true
58
+ ```
59
+
60
+ **4)** Add `vitest.config.ts` file with following content (if you don't have it yet):
61
+
62
+ ```ts
63
+ import { loadVitestConfig } from 'nuxt-spec/config'
64
+
65
+ export default loadVitestConfig({
66
+ // your custom config here
67
+ })
68
+ ```
69
+
70
+ **5)** Add `.nuxtrc` file with following content (if you don't have it yet):
71
+
72
+ ```text
73
+ setups.@nuxt/test-utils="4.0.3"
74
+ ```
75
+
76
+ **6)** - (Optional) Add following scripts into your `package.json`:
77
+
78
+ ```json
79
+ "scripts": {
80
+ "test": "vitest run",
81
+ "test-u": "vitest run -u",
82
+ "test-i": "vitest"
83
+ }
84
+ ```
85
+
86
+ **7)** - (Optional) Setup file structures for tests as follows:
87
+
88
+ ```text
89
+ test/
90
+ ├── browser/
91
+ │ └── vitest-browser.test.ts
92
+ ├── e2e/
93
+ │ └── nuxt-e2e.test.ts
94
+ │ └── nuxt-visual.test.ts
95
+ ├── nuxt/
96
+ │ └── nuxt-unit.test.ts
97
+ └── unit/
98
+ └── vitest-unit.test.ts
99
+ ```
100
+
101
+ You can use sample files from the [project repository](https://github.com/AloisSeckar/nuxt-spec/tree/v0.2.4/test).
102
+
103
+ ### Install and execute
104
+
105
+ Whether you used the CLI tool or did the manual setup, you are ready to install and run the tests.
106
+
107
+ **1)** - Install the dependencies:
108
+
109
+ It is advised to remove `node_modules` and delete lock file first. Then proceed with fresh installation.
110
+
111
+ <!-- tabs:start -->
112
+
113
+ #### Install using **npm**
114
+
115
+ ```bash
116
+ npm install
117
+ ```
118
+
119
+ #### Install using **yarn**
120
+
121
+ ```bash
122
+ yarn install
123
+ ```
124
+
125
+ #### Install using **pnpm**
126
+
127
+ ```bash
128
+ pnpm install
129
+ ```
130
+
131
+ #### Install using **bun**
132
+
133
+ ```bash
134
+ bun install
135
+ ```
136
+
137
+ <!-- tabs:end -->
138
+
139
+ **2)** - If you're prompted (for the first time when installing to a new machine), install headless browser runtimes:
140
+
141
+ <!-- tabs:start -->
142
+
143
+ #### Setup runtime using **npm**
144
+
145
+ ```bash
146
+ npx playwright-core install
147
+ ```
148
+
149
+ #### Setup runtime using **yarn**
150
+
151
+ ```bash
152
+ yarn dlx playwright-core install
153
+ ```
154
+
155
+ #### Setup runtime using **pnpm**
156
+
157
+ ```bash
158
+ pnpm exec playwright-core install
159
+ ```
160
+
161
+ #### Setup runtime using **bun**
162
+
163
+ ```bash
164
+ bunx playwright-core install
165
+ ```
166
+
167
+ <!-- tabs:end -->
168
+
169
+ **3)** - Start the development server of your awesome Nuxt project:
170
+
171
+ <!-- tabs:start -->
172
+
173
+ #### Start server using **npm**
174
+
175
+ ```bash
176
+ npm run dev
177
+ ```
178
+
179
+ #### Start server using **yarn**
180
+
181
+ ```bash
182
+ yarn dev
183
+ ```
184
+
185
+ #### Start server using **pnpm**
186
+
187
+ ```bash
188
+ pnpm dev
189
+ ```
190
+
191
+ #### Start server using **bun**
192
+
193
+ ```bash
194
+ bun run dev
195
+ ```
196
+
197
+ <!-- tabs:end -->
198
+
199
+ ### Running tests
200
+
201
+ Once installed, Vitest automatically discovers all `*.test.ts` and `*.spec.ts` files in project and becomes capable of running them.
202
+
203
+ You can use those three optional commands `package.json` file in `"scripts"` section in order to run tests easily:
204
+
205
+ - `test: vitest run` - runs once and ends
206
+ - `test-u: vitest run -u` - runs once and updates snapshots
207
+ - `test-i: vitest` - runs and waits in HMR mode for test file changes
208
+
209
+ Then you can call in terminal in root of your project:
210
+
211
+ <!-- tabs:start -->
212
+
213
+ #### Testing using **npm**
214
+
215
+ ```bash
216
+ npm run test # runs once and ends
217
+ npm run test-u # runs once and updates snapshots
218
+ npm run test-i # runs and waits in HMR mode
219
+ ```
220
+
221
+ #### Tsting using **yarn**
222
+
223
+ ```bash
224
+ yarn test # runs once and ends
225
+ yarn test-u # runs once and updates snapshots
226
+ yarn test-i # runs and waits in HMR mode
227
+ ```
228
+
229
+ #### Testing using **pnpm**
230
+
231
+ ```bash
232
+ pnpm test # runs once and ends
233
+ pnpm test-u # runs once and updates snapshots
234
+ pnpm test-i # runs and waits in HMR mode
235
+ ```
236
+
237
+ #### Testing using **bun**
238
+
239
+ ```bash
240
+ bun run test # runs once and ends
241
+ bun run test-u # runs once and updates snapshots
242
+ bun run test-i # runs and waits in HMR mode
243
+ ```
244
+
245
+ <!-- tabs:end -->
246
+
247
+ Or you can use the `vitest` command directly with all its parameters. See [Vitest CLI documentation](https://vitest.dev/guide/cli.html) for more info.
248
+
249
+ ## Overview
250
+
251
+ **Nuxt Spec** currently contains:
252
+
253
+ - [vitest](https://www.npmjs.com/package/vitest) **v4** as the fundamental testing framework
254
+ - [@vitest/browser](https://www.npmjs.com/package/@vitest/browser) as more advanced browser-native testing runner
255
+ - [@vitest/ui](https://www.npmjs.com/package/@vitest/ui) as graphic UI above the Vitest test runner
256
+ - [happy-dom](https://www.npmjs.com/package/happy-dom) as the headless browser runtime
257
+ - [playwright-core](https://www.npmjs.com/package/playwright-core) as the headless browser testing framework
258
+ - [@vue/test-utils](https://www.npmjs.com/package/@vue/test-utils) for testing Vue stuff
259
+ - [@nuxt/test-utils](https://www.npmjs.com/package/@nuxt/test-utils) for testing Nuxt stuff
260
+
261
+ Planned future development:
262
+
263
+ - reason about (not) using Vitest browser mode (or make it optional)
264
+ - solution for visual regression testing - (currently there is experimental custom solution)
265
+
266
+ See [CHANGELOG.md](https://github.com/AloisSeckar/nuxt-spec/blob/v0.2.4/CHANGELOG.md) for the latest updates and features.
267
+
268
+ ## Configuration
269
+
270
+ By default, `nuxt-spec` uses Vitest configuration defined in [`/config/index.mjs`](https://github.com/AloisSeckar/nuxt-spec/blob/v0.2.4/config/index.mjs). The configuration is based on [Nuxt team recommendations](https://nuxt.com/docs/4.x/getting-started/testing) and our best judgement.
271
+
272
+ To add/override your custom config, you can create (or scaffold via CLI tool) a file named `vitest.config.ts` in the root of your project with the following content:
273
+
274
+ ```ts
275
+ import { loadVitestConfig } from 'nuxt-spec/config'
276
+
277
+ export default loadVitestConfig({
278
+ // your custom config here
279
+ })
280
+ ```
281
+
282
+ And pass whatever you want as a parameter object. It will be defu-merged with the defaults (custom config takes precedence). The object is typed to be compatible with both [Vite](https://vite.dev/config/) and [Vitest](https://vitest.dev/config/) configuration options. Used type is derived from the respective `.d.ts` files of those packages.
283
+
284
+ **NOTE**: Based on the [Vitest documentation](https://main.vitest.dev/config/), it is possible to pass in **any configuration option** valid for [Vite](https://vite.dev/config/). Configuration related directly to Vitest must be passed under the `test` key, e.g.:
285
+
286
+ ```ts
287
+ import { loadVitestConfig } from 'nuxt-spec/config'
288
+
289
+ export default loadVitestConfig({
290
+ test: {
291
+ // your custom config specific to Vitest here
292
+ }
293
+ // by the nature of the Vitest config resolution,
294
+ // you may also pass ANY OTHER valid Vite configuration options here
295
+ })
296
+ ```
297
+
298
+ By default, Nuxt Spec built-in configuration establishes 4 `projects` + one fallback:
299
+
300
+ - `unit` - for unit tests in `test/unit/**` - env is set to `node`
301
+ - `nuxt` - for Nuxt-related tests in `test/nuxt/**` - env is set to `nuxt`
302
+ - `e2e` - for end-to-end tests in `test/e2e/**` - env is set to `node`
303
+ - `browser` - for browser-mode tests in `test/browser/**` - env is set to `node` (this is effectively an alternative to `nuxt` relying on `@vitest/browser` instead of `@nuxt/test-utils`)
304
+ - `default` - fallback for all other tests in `test/**` and/or `tests/**` directories - env is set to `node`
305
+
306
+ Vitest will then expect at least one test defined in either of those directories. Any parts of the `test.projects` config may be altered and user-defined values will be logically merged with the defaults. Also you may add new custom projects' definitions to fit your needs. If your project uses significantly different configuration (i.e. your tests reside in completely different path), you can pass `false` as a second parameter to `loadVitestConfig()` function to exclude default `test.projects` values from being injected completely:
307
+
308
+ ```ts
309
+ import { loadVitestConfig } from 'nuxt-spec/config'
310
+
311
+ export default loadVitestConfig({
312
+ // your custom config here
313
+ }, false)
314
+ ```
315
+
316
+ Alternatively, if you don't want to use any part of the `nuxt-spec` default configuration at all, you can override `vitest.config.ts` file completely and define your own [Vitest configuration](https://vitest.dev/config/) from scratch.
317
+
318
+ ### Filtering out log messages
319
+
320
+ Some tedious and unrelevant log messages may keep appearing in running tests creating noise and hiding the real issues.
321
+
322
+ Via `NUXT_SPEC_MESSAGE_FILTERS` env variable you may pass a comma-separated list of (plain) text patterns that should be omited.
323
+
324
+ It only applies to logs processed by `vitest` though, so some messages might still prevail.
325
+
326
+ ## Utilities
327
+
328
+ Nuxt Spec offers a couple of utility functions that are exported via `nuxt-spec/utils` subpackage.
329
+
330
+ You can use them in your test files as follows:
331
+
332
+ ```ts
333
+ import { compareScreenshot, gotoPage, getDataHtml, getAPIResultHtml, } from 'nuxt-spec/utils'
334
+
335
+ // accepts instance of NuxtPage (from @nuxt/test-utils)
336
+ // takes a screenshot of current viewport and compares it with stored baseline
337
+ // the comparison is done using `pixelmatch` library
338
+ // if screenshot doesn't exist, it will be created in __baseline__ subfolder
339
+ // screenshot from current run is always captured into __current__ subfolder
340
+ // if screenshots don't match, the method will cause Vitest test to fail
341
+ // accepts optional object with extra options:
342
+ // - `fileName` - name of the screenshot file (default is based on current route)
343
+ // - `selector` - CSS selector of the element to capture (default is full page)
344
+ // - `targetDir` - directory where the screenshots should be stored (default is `./test/e2e/`)
345
+ // - `maxDiffPixelRatio` - allows mitigating cross-platform rendering differences by setting
346
+ // a 0-1 scale tolerance (default 0)
347
+ // - `maxDiffPixels` - same but with exact max value of different pixels which overrides setting
348
+ // `maxDiffPixelRatio` (default 0)
349
+ // - `threshold` - allows adjusting the tolerance for "same" color on 0-1 scale (default 0.1)
350
+
351
+ // will produce "index.png" file in `./test/e2e/` directory
352
+ await compareScreenshot(page)
353
+ // will produce "homepage.png"
354
+ await compareScreenshot(page, { fileName: 'homepage.png' })
355
+ // will produce "component.png" only with id="test" element
356
+ await compareScreenshot(page, { fileName: 'component.png', selector: '#test' })
357
+ // will produce "homepage.png" in `/screenshots` directory
358
+ await compareScreenshot(page, { fileName: 'homepage.png', targetDir: '/screenshots' })
359
+ // will produce "homepage.png" and the comparison will only fail when more than 1000 pixels differ
360
+ await compareScreenshot(page, { fileName: 'homepage.png', maxDiffPixels: 1000 })
361
+ // will produce "homepage.png", the comparison will only fail when more than 1000 pixels differ
362
+ // while more pixels will be considered "same" based on color
363
+ await compareScreenshot(page, { fileName: 'homepage.png', maxDiffPixels: 1000, threshold: 0.5 })
364
+
365
+ // navigates to given URL and returns the instance of NuxtPage (from @nuxt/test-utils)
366
+ const page: NuxtPage = await gotoPage('url')
367
+
368
+ // accepts either a URL string or instance of NuxtPage (from @nuxt/test-utils) and a CSS selector
369
+ // returns `innerHTML` of the element matching the selector
370
+ const html: string = await getDataHtml('/', '#test')
371
+ const html: string = await getDataHtml(page, '#test')
372
+
373
+ // accepts either a URL string or instance of NuxtPage (from @nuxt/test-utils)
374
+ // css selector for element that triggers API call when clicked (i.e. button)
375
+ // fragment of API endpoint URL that should be called (to test the response)
376
+ // css selector for element where the API response should be rendered (i.e. div)
377
+ // returns `innerHTML` of the element matching the result selector after the API call
378
+ // is made by Playwright runner
379
+ const html: string = await getAPIResultHtml('/', '#api-fetch', '/your-api', '#api-result')
380
+ const html: string = await getAPIResultHtml(page, '#api-fetch', '/your-api', '#api-result')
381
+ ```
382
+
383
+ For detailed description, see [utils.d.ts](https://github.com/AloisSeckar/nuxt-spec/blob/v0.2.4/utils/index.d.ts).
384
+
385
+ The `compareScreenshot` function usage results into HTML report file being automatically created. The file is generated within the specified `__current__` directory as `report_YYYYMMDDHHMMSS.html`. It contains all failed screenshots comparison. When test suite is over, file is attempted to be opened in system default browser (unless Node operates in `CI` mode).
386
+
387
+ ### Notice on concurrent execution
388
+
389
+ The default setting for `e2e` project sets `maxConcurrency: availableParallelism() / 2` which is based on function provided by `node:os` module. You should adjust your tests to match this value or override the default if needed.
390
+
391
+ ### Notice on non-default setups
392
+
393
+ The creation of the report file and it's proper wrap-up at the end is ensured via `globalSetup` function passed into default Vitest E2E suite defined by Nuxt Spec. If you need to override the default `e2e` project, you also need to make sure to call the setup function manually.
394
+
395
+ Add following into your `vitest.config.ts`:
396
+
397
+ ```ts
398
+ // vitest.config.ts
399
+ import { loadVitestConfig } from 'nuxt-spec/config'
400
+
401
+ // resolve path to Nuxt Spec's setup function
402
+ const screenshotReportSetup = fileURLToPath(new URL('../utils/screenshot.ts', import.meta.resolve('nuxt-spec/config')))
403
+
404
+ export default loadVitestConfig({
405
+ // whatever e2e test you are defining
406
+ test: {
407
+ // provide it to your `compareScreenshot` using test suite
408
+ globalSetup: [screenshotReportSetup],
409
+ // other config
410
+ },
411
+ // other config
412
+ })
413
+ ```
414
+
415
+ ## Contact
416
+
417
+ Use GitHub issues to report bugs or suggest improvements. I will be more than happy to address them.