nuxt-spec 0.2.0-alpha.8 → 0.2.0
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 +364 -364
- package/app/app.vue +10 -10
- package/app/components/NuxtSpecApiTestComponent.vue +24 -24
- package/app/components/NuxtSpecTestComponent.vue +9 -9
- package/app/components/index.ts +2 -0
- package/app/utils/vitest-utils.ts +5 -5
- package/bin/cli.js +53 -53
- package/bin/setup.js +243 -243
- package/config/index.d.ts +17 -17
- package/config/index.mjs +79 -79
- 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 +32 -26
- package/nuxt.config.ts +19 -14
- package/package.json +12 -4
- package/utils/e2e.ts +30 -30
- package/utils/index.d.ts +70 -70
- package/utils/index.ts +12 -12
- package/utils/screenshot.ts +89 -89
package/config/index.mjs
CHANGED
|
@@ -1,79 +1,79 @@
|
|
|
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 { onConsoleLog } from './utils/warnings.mjs' // filter out unnecessary logs
|
|
6
|
-
import { mergeConfig } from './utils/merge.mjs' // defu-based merge function
|
|
7
|
-
import { defineConfig } from 'vitest/config'
|
|
8
|
-
import { defineVitestProject } from '@nuxt/test-utils/config'
|
|
9
|
-
import { playwright } from '@vitest/browser-playwright'
|
|
10
|
-
import vue from '@vitejs/plugin-vue'
|
|
11
|
-
|
|
12
|
-
export async function loadVitestConfig(userVitestConfig, projects = true) {
|
|
13
|
-
const baseConfig = {
|
|
14
|
-
test: {
|
|
15
|
-
// filter-out unnecessary console logs coming from Vitest
|
|
16
|
-
// when the import is resolved, unnecessary stderr logs are also filtered-out
|
|
17
|
-
// as a side-effect
|
|
18
|
-
onConsoleLog,
|
|
19
|
-
},
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (projects === true) {
|
|
23
|
-
baseConfig.test.projects = [
|
|
24
|
-
// default fallback to catch tests directly in /test folder
|
|
25
|
-
{
|
|
26
|
-
test: {
|
|
27
|
-
name: 'default',
|
|
28
|
-
include: ['{test,tests}/**/*.{test,spec}.ts', '!test/{browser,e2e,nuxt,unit}/**'],
|
|
29
|
-
environment: 'node',
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
// proposed setup for Unit tests
|
|
33
|
-
{
|
|
34
|
-
test: {
|
|
35
|
-
name: 'node',
|
|
36
|
-
include: ['test/unit/**/*.{test,spec}.ts'],
|
|
37
|
-
environment: 'node',
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
// proposed setup for Nuxt component tests
|
|
41
|
-
await defineVitestProject({
|
|
42
|
-
test: {
|
|
43
|
-
name: 'nuxt',
|
|
44
|
-
include: ['test/nuxt/**/*.{test,spec}.ts'],
|
|
45
|
-
environment: 'nuxt',
|
|
46
|
-
},
|
|
47
|
-
}),
|
|
48
|
-
// proposed setup for classic E2E tests (node-based, using @nuxt/test-utils)
|
|
49
|
-
{
|
|
50
|
-
test: {
|
|
51
|
-
name: 'e2e',
|
|
52
|
-
include: ['test/e2e/**/*.{test,spec}.ts'],
|
|
53
|
-
environment: 'node',
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
// proposed setup for browser component tests (with Playwright runner)
|
|
57
|
-
{
|
|
58
|
-
// vue plugin is required for proper imports resolution
|
|
59
|
-
plugins: [vue()],
|
|
60
|
-
test: {
|
|
61
|
-
name: 'browser',
|
|
62
|
-
include: ['test/browser/**/*.{test,spec}.ts'],
|
|
63
|
-
environment: 'node',
|
|
64
|
-
browser: {
|
|
65
|
-
provider: playwright(),
|
|
66
|
-
enabled: true,
|
|
67
|
-
headless: true,
|
|
68
|
-
instances: [{
|
|
69
|
-
browser: 'chromium',
|
|
70
|
-
viewport: { width: 1280, height: 720 },
|
|
71
|
-
}],
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
]
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return mergeConfig(userVitestConfig, defineConfig(baseConfig))
|
|
79
|
-
}
|
|
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 { onConsoleLog } from './utils/warnings.mjs' // filter out unnecessary logs
|
|
6
|
+
import { mergeConfig } from './utils/merge.mjs' // defu-based merge function
|
|
7
|
+
import { defineConfig } from 'vitest/config'
|
|
8
|
+
import { defineVitestProject } from '@nuxt/test-utils/config'
|
|
9
|
+
import { playwright } from '@vitest/browser-playwright'
|
|
10
|
+
import vue from '@vitejs/plugin-vue'
|
|
11
|
+
|
|
12
|
+
export async function loadVitestConfig(userVitestConfig, projects = true) {
|
|
13
|
+
const baseConfig = {
|
|
14
|
+
test: {
|
|
15
|
+
// filter-out unnecessary console logs coming from Vitest
|
|
16
|
+
// when the import is resolved, unnecessary stderr logs are also filtered-out
|
|
17
|
+
// as a side-effect
|
|
18
|
+
onConsoleLog,
|
|
19
|
+
},
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (projects === true) {
|
|
23
|
+
baseConfig.test.projects = [
|
|
24
|
+
// default fallback to catch tests directly in /test folder
|
|
25
|
+
{
|
|
26
|
+
test: {
|
|
27
|
+
name: 'default',
|
|
28
|
+
include: ['{test,tests}/**/*.{test,spec}.ts', '!test/{browser,e2e,nuxt,unit}/**'],
|
|
29
|
+
environment: 'node',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
// proposed setup for Unit tests
|
|
33
|
+
{
|
|
34
|
+
test: {
|
|
35
|
+
name: 'node',
|
|
36
|
+
include: ['test/unit/**/*.{test,spec}.ts'],
|
|
37
|
+
environment: 'node',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
// proposed setup for Nuxt component tests
|
|
41
|
+
await defineVitestProject({
|
|
42
|
+
test: {
|
|
43
|
+
name: 'nuxt',
|
|
44
|
+
include: ['test/nuxt/**/*.{test,spec}.ts'],
|
|
45
|
+
environment: 'nuxt',
|
|
46
|
+
},
|
|
47
|
+
}),
|
|
48
|
+
// proposed setup for classic E2E tests (node-based, using @nuxt/test-utils)
|
|
49
|
+
{
|
|
50
|
+
test: {
|
|
51
|
+
name: 'e2e',
|
|
52
|
+
include: ['test/e2e/**/*.{test,spec}.ts'],
|
|
53
|
+
environment: 'node',
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
// proposed setup for browser component tests (with Playwright runner)
|
|
57
|
+
{
|
|
58
|
+
// vue plugin is required for proper imports resolution
|
|
59
|
+
plugins: [vue()],
|
|
60
|
+
test: {
|
|
61
|
+
name: 'browser',
|
|
62
|
+
include: ['test/browser/**/*.{test,spec}.ts'],
|
|
63
|
+
environment: 'node',
|
|
64
|
+
browser: {
|
|
65
|
+
provider: playwright(),
|
|
66
|
+
enabled: true,
|
|
67
|
+
headless: true,
|
|
68
|
+
instances: [{
|
|
69
|
+
browser: 'chromium',
|
|
70
|
+
viewport: { width: 1280, height: 720 },
|
|
71
|
+
}],
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return mergeConfig(userVitestConfig, defineConfig(baseConfig))
|
|
79
|
+
}
|
|
@@ -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 =
|
|
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,26 +1,32 @@
|
|
|
1
|
-
const messageFilters = [
|
|
2
|
-
// remove once @nuxt/test-utils starts depending on Vitest 4.1
|
|
3
|
-
// https://github.com/nuxt/test-utils/pull/1620
|
|
4
|
-
'Importing from "vitest/environments" is deprecated',
|
|
5
|
-
// Node+Windows false positive
|
|
6
|
-
// https://github.com/nuxt/icon/issues/140
|
|
7
|
-
'Use of deprecated trailing slash pattern mapping',
|
|
8
|
-
// remove once Vue stops considering <Suspense> experimental
|
|
9
|
-
'<Suspense> is an experimental feature',
|
|
10
|
-
]
|
|
11
|
-
|
|
12
|
-
// 1) filter-out unnecessary stderr logs coming from Vitest
|
|
13
|
-
// (applied as side-effect on import)
|
|
14
|
-
|
|
15
|
-
const _stderrWrite = process.stderr.write.bind(process.stderr)
|
|
16
|
-
process.stderr.write = (chunk, ...args) => {
|
|
17
|
-
if (typeof chunk === 'string' && messageFilters.some(f => chunk.includes(f))) return true
|
|
18
|
-
return _stderrWrite(chunk, ...args)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
1
|
+
const messageFilters = [
|
|
2
|
+
// remove once @nuxt/test-utils starts depending on Vitest 4.1
|
|
3
|
+
// https://github.com/nuxt/test-utils/pull/1620
|
|
4
|
+
'Importing from "vitest/environments" is deprecated',
|
|
5
|
+
// Node+Windows false positive
|
|
6
|
+
// https://github.com/nuxt/icon/issues/140
|
|
7
|
+
'Use of deprecated trailing slash pattern mapping',
|
|
8
|
+
// remove once Vue stops considering <Suspense> experimental
|
|
9
|
+
'<Suspense> is an experimental feature',
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
// 1) filter-out unnecessary stderr/stdout logs coming from Vitest
|
|
13
|
+
// (applied as side-effect on import)
|
|
14
|
+
|
|
15
|
+
const _stderrWrite = process.stderr.write.bind(process.stderr)
|
|
16
|
+
process.stderr.write = (chunk, ...args) => {
|
|
17
|
+
if (typeof chunk === 'string' && messageFilters.some(f => chunk.includes(f))) return true
|
|
18
|
+
return _stderrWrite(chunk, ...args)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const _stdoutWrite = process.stdout.write.bind(process.stdout)
|
|
22
|
+
process.stdout.write = (chunk, ...args) => {
|
|
23
|
+
if (typeof chunk === 'string' && messageFilters.some(f => chunk.includes(f))) return true
|
|
24
|
+
return _stdoutWrite(chunk, ...args)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// 2) filter-out unnecessary console logs coming from Vitest
|
|
28
|
+
// (used as Vitest onConsoleLog hook)
|
|
29
|
+
|
|
30
|
+
export function onConsoleLog(log) {
|
|
31
|
+
if (messageFilters.some(f => log.includes(f))) return false
|
|
32
|
+
}
|
package/nuxt.config.ts
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
export default defineNuxtConfig({
|
|
2
|
-
modules: [
|
|
3
|
-
'@nuxt/eslint',
|
|
4
|
-
'@nuxt/test-utils/module',
|
|
5
|
-
],
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
export default defineNuxtConfig({
|
|
2
|
+
modules: [
|
|
3
|
+
'@nuxt/eslint',
|
|
4
|
+
'@nuxt/test-utils/module',
|
|
5
|
+
],
|
|
6
|
+
|
|
7
|
+
// exclude file used for explicit exports (nuxt-spec/components) from Nuxt resolution
|
|
8
|
+
components: {
|
|
9
|
+
dirs: [{ path: '~/components', ignore: ['index.ts'] }],
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
compatibilityDate: '2026-03-15',
|
|
13
|
+
|
|
14
|
+
eslint: {
|
|
15
|
+
config: {
|
|
16
|
+
stylistic: true,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
})
|
package/package.json
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nuxt-spec",
|
|
3
|
-
"version": "0.2.0
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Test-pack layer for Nuxt Applications",
|
|
5
|
-
"repository":
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/AloisSeckar/nuxt-spec.git"
|
|
8
|
+
},
|
|
6
9
|
"license": "MIT",
|
|
7
10
|
"type": "module",
|
|
8
11
|
"main": "./nuxt.config.ts",
|
|
9
12
|
"bin": {
|
|
10
|
-
"nuxt-spec": "
|
|
13
|
+
"nuxt-spec": "bin/cli.js"
|
|
11
14
|
},
|
|
12
15
|
"exports": {
|
|
13
16
|
".": "./nuxt.config.ts",
|
|
@@ -20,6 +23,10 @@
|
|
|
20
23
|
"types": "./utils/index.d.ts",
|
|
21
24
|
"import": "./utils/index.ts",
|
|
22
25
|
"default": "./utils/index.ts"
|
|
26
|
+
},
|
|
27
|
+
"./components": {
|
|
28
|
+
"import": "./app/components/index.ts",
|
|
29
|
+
"default": "./app/components/index.ts"
|
|
23
30
|
}
|
|
24
31
|
},
|
|
25
32
|
"files": [
|
|
@@ -27,7 +34,8 @@
|
|
|
27
34
|
"bin",
|
|
28
35
|
"config",
|
|
29
36
|
"public",
|
|
30
|
-
"utils"
|
|
37
|
+
"utils",
|
|
38
|
+
"nuxt.config.ts"
|
|
31
39
|
],
|
|
32
40
|
"dependencies": {
|
|
33
41
|
"@nuxt/eslint": "1.15.2",
|
package/utils/e2e.ts
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import { createPage, url } from '@nuxt/test-utils/e2e'
|
|
2
|
-
import type { NuxtPage } from '@nuxt/test-utils'
|
|
3
|
-
|
|
4
|
-
// visit a specified URL and return the page instance for further interaction
|
|
5
|
-
export async function gotoPage(pageName: string): Promise<NuxtPage> {
|
|
6
|
-
const page = await createPage()
|
|
7
|
-
const urlPath = pageName.startsWith('/') ? url(pageName) : url(`/${pageName}`)
|
|
8
|
-
await page.goto(urlPath, { waitUntil: 'hydration' })
|
|
9
|
-
return page
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// extract HTML content from specified element on a given page
|
|
13
|
-
export async function getDataHtml(page: NuxtPage | string, element: string): Promise<string> {
|
|
14
|
-
const pageInstance = typeof page === 'string' ? await gotoPage(page) : page
|
|
15
|
-
const dataDiv = pageInstance.locator(element)
|
|
16
|
-
return await dataDiv.innerHTML()
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// execute an API call and extract HTML content from the result
|
|
20
|
-
// (assumes clickable element that triggers the request
|
|
21
|
-
// and separate element for displaying the response)
|
|
22
|
-
export async function getAPIResultHtml(page: NuxtPage | string, triggerElement: string, targetUrl: string, responseElement: string) {
|
|
23
|
-
const pageInstance = typeof page === 'string' ? await gotoPage(page) : page
|
|
24
|
-
await pageInstance.click(triggerElement)
|
|
25
|
-
await pageInstance.waitForResponse(response =>
|
|
26
|
-
response.url().includes(targetUrl) && response.ok(),
|
|
27
|
-
)
|
|
28
|
-
const resultDiv = pageInstance.locator(responseElement)
|
|
29
|
-
return await resultDiv.innerHTML()
|
|
30
|
-
}
|
|
1
|
+
import { createPage, url } from '@nuxt/test-utils/e2e'
|
|
2
|
+
import type { NuxtPage } from '@nuxt/test-utils'
|
|
3
|
+
|
|
4
|
+
// visit a specified URL and return the page instance for further interaction
|
|
5
|
+
export async function gotoPage(pageName: string): Promise<NuxtPage> {
|
|
6
|
+
const page = await createPage()
|
|
7
|
+
const urlPath = pageName.startsWith('/') ? url(pageName) : url(`/${pageName}`)
|
|
8
|
+
await page.goto(urlPath, { waitUntil: 'hydration' })
|
|
9
|
+
return page
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// extract HTML content from specified element on a given page
|
|
13
|
+
export async function getDataHtml(page: NuxtPage | string, element: string): Promise<string> {
|
|
14
|
+
const pageInstance = typeof page === 'string' ? await gotoPage(page) : page
|
|
15
|
+
const dataDiv = pageInstance.locator(element)
|
|
16
|
+
return await dataDiv.innerHTML()
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// execute an API call and extract HTML content from the result
|
|
20
|
+
// (assumes clickable element that triggers the request
|
|
21
|
+
// and separate element for displaying the response)
|
|
22
|
+
export async function getAPIResultHtml(page: NuxtPage | string, triggerElement: string, targetUrl: string, responseElement: string) {
|
|
23
|
+
const pageInstance = typeof page === 'string' ? await gotoPage(page) : page
|
|
24
|
+
await pageInstance.click(triggerElement)
|
|
25
|
+
await pageInstance.waitForResponse(response =>
|
|
26
|
+
response.url().includes(targetUrl) && response.ok(),
|
|
27
|
+
)
|
|
28
|
+
const resultDiv = pageInstance.locator(responseElement)
|
|
29
|
+
return await resultDiv.innerHTML()
|
|
30
|
+
}
|
package/utils/index.d.ts
CHANGED
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
import type { NuxtPage } from '@nuxt/test-utils'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Visit a specified URL and return the page instance for further interaction.
|
|
5
|
-
*
|
|
6
|
-
* @param pageName - Path segment appended to the base URL (e.g. `'about'` → `/<about>`)
|
|
7
|
-
* @returns Playwright page instance after navigation and hydration
|
|
8
|
-
*/
|
|
9
|
-
export declare function gotoPage(pageName: string): Promise<NuxtPage>
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Extract inner HTML content from a specified element on a given page.
|
|
13
|
-
*
|
|
14
|
-
* @param page - Playwright page instance, or a page name string (will call `gotoPage` internally)
|
|
15
|
-
* @param element - CSS selector identifying the target element
|
|
16
|
-
* @returns The inner HTML of the matched element
|
|
17
|
-
*/
|
|
18
|
-
export declare function getDataHtml(page: NuxtPage | string, element: string): Promise<string>
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Execute an API call by clicking a trigger element, wait for a successful
|
|
22
|
-
* response matching the target URL, then extract the inner HTML from the
|
|
23
|
-
* response element.
|
|
24
|
-
*
|
|
25
|
-
* @param page - Playwright page instance, or a page name string (will call `gotoPage` internally)
|
|
26
|
-
* @param triggerElement - CSS selector for the clickable element that triggers the API request
|
|
27
|
-
* @param targetUrl - Substring matched against the response URL to identify the expected API call
|
|
28
|
-
* @param responseElement - CSS selector for the element displaying the API response
|
|
29
|
-
* @returns The inner HTML of the response element
|
|
30
|
-
*/
|
|
31
|
-
export declare function getAPIResultHtml(
|
|
32
|
-
page: NuxtPage | string,
|
|
33
|
-
triggerElement: string,
|
|
34
|
-
targetUrl: string,
|
|
35
|
-
responseElement: string,
|
|
36
|
-
): Promise<string>
|
|
37
|
-
|
|
38
|
-
export interface CompareScreenshotOptions {
|
|
39
|
-
/** Name of the PNG file used for baseline storage and comparison (defaults to route and `index.png` for `/`) */
|
|
40
|
-
fileName?: string
|
|
41
|
-
/** Directory for baseline/current screenshots, relative to project root (defaults to `test/e2e`) */
|
|
42
|
-
targetDir?: string
|
|
43
|
-
/** CSS selector for a specific element to capture (defaults to full page) */
|
|
44
|
-
selector?: string
|
|
45
|
-
/** Max ratio of different pixels (0–1). Default: 0 (exact match) */
|
|
46
|
-
maxDiffPixelRatio?: number
|
|
47
|
-
/** Max absolute number of different pixels. Takes precedence over `maxDiffPixelRatio` when set. Default: 0 (exact match) */
|
|
48
|
-
maxDiffPixels?: number
|
|
49
|
-
/** Per-pixel color distance threshold (0–1). Lower = stricter. Default: 0.1 */
|
|
50
|
-
threshold?: number
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Capture a browser screenshot and compare it against a stored baseline PNG.
|
|
55
|
-
* When run with `-u` / `--update`, or when no baseline exists yet, the current
|
|
56
|
-
* screenshot is saved as the new baseline.
|
|
57
|
-
*
|
|
58
|
-
* Comparison uses pixelmatch for perceptual pixel diffing. By default,
|
|
59
|
-
* zero differing pixels are allowed (exact match). Set `maxDiffPixelRatio`
|
|
60
|
-
* or `maxDiffPixels` to tolerate cross-platform rendering differences.
|
|
61
|
-
*
|
|
62
|
-
* @param page - Playwright page instance obtained from `createPage()`
|
|
63
|
-
* @param options - extra options (see `CompareScreenshotOptions`)
|
|
64
|
-
* @returns `true` when the screenshot matches the baseline (or a new baseline was saved)
|
|
65
|
-
* @throws Fails the current Vitest test when a mismatch is detected
|
|
66
|
-
*/
|
|
67
|
-
export declare function compareScreenshot(
|
|
68
|
-
page: NuxtPage,
|
|
69
|
-
options?: CompareScreenshotOptions,
|
|
70
|
-
): Promise<boolean>
|
|
1
|
+
import type { NuxtPage } from '@nuxt/test-utils'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Visit a specified URL and return the page instance for further interaction.
|
|
5
|
+
*
|
|
6
|
+
* @param pageName - Path segment appended to the base URL (e.g. `'about'` → `/<about>`)
|
|
7
|
+
* @returns Playwright page instance after navigation and hydration
|
|
8
|
+
*/
|
|
9
|
+
export declare function gotoPage(pageName: string): Promise<NuxtPage>
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Extract inner HTML content from a specified element on a given page.
|
|
13
|
+
*
|
|
14
|
+
* @param page - Playwright page instance, or a page name string (will call `gotoPage` internally)
|
|
15
|
+
* @param element - CSS selector identifying the target element
|
|
16
|
+
* @returns The inner HTML of the matched element
|
|
17
|
+
*/
|
|
18
|
+
export declare function getDataHtml(page: NuxtPage | string, element: string): Promise<string>
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Execute an API call by clicking a trigger element, wait for a successful
|
|
22
|
+
* response matching the target URL, then extract the inner HTML from the
|
|
23
|
+
* response element.
|
|
24
|
+
*
|
|
25
|
+
* @param page - Playwright page instance, or a page name string (will call `gotoPage` internally)
|
|
26
|
+
* @param triggerElement - CSS selector for the clickable element that triggers the API request
|
|
27
|
+
* @param targetUrl - Substring matched against the response URL to identify the expected API call
|
|
28
|
+
* @param responseElement - CSS selector for the element displaying the API response
|
|
29
|
+
* @returns The inner HTML of the response element
|
|
30
|
+
*/
|
|
31
|
+
export declare function getAPIResultHtml(
|
|
32
|
+
page: NuxtPage | string,
|
|
33
|
+
triggerElement: string,
|
|
34
|
+
targetUrl: string,
|
|
35
|
+
responseElement: string,
|
|
36
|
+
): Promise<string>
|
|
37
|
+
|
|
38
|
+
export interface CompareScreenshotOptions {
|
|
39
|
+
/** Name of the PNG file used for baseline storage and comparison (defaults to route and `index.png` for `/`) */
|
|
40
|
+
fileName?: string
|
|
41
|
+
/** Directory for baseline/current screenshots, relative to project root (defaults to `test/e2e`) */
|
|
42
|
+
targetDir?: string
|
|
43
|
+
/** CSS selector for a specific element to capture (defaults to full page) */
|
|
44
|
+
selector?: string
|
|
45
|
+
/** Max ratio of different pixels (0–1). Default: 0 (exact match) */
|
|
46
|
+
maxDiffPixelRatio?: number
|
|
47
|
+
/** Max absolute number of different pixels. Takes precedence over `maxDiffPixelRatio` when set. Default: 0 (exact match) */
|
|
48
|
+
maxDiffPixels?: number
|
|
49
|
+
/** Per-pixel color distance threshold (0–1). Lower = stricter. Default: 0.1 */
|
|
50
|
+
threshold?: number
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Capture a browser screenshot and compare it against a stored baseline PNG.
|
|
55
|
+
* When run with `-u` / `--update`, or when no baseline exists yet, the current
|
|
56
|
+
* screenshot is saved as the new baseline.
|
|
57
|
+
*
|
|
58
|
+
* Comparison uses pixelmatch for perceptual pixel diffing. By default,
|
|
59
|
+
* zero differing pixels are allowed (exact match). Set `maxDiffPixelRatio`
|
|
60
|
+
* or `maxDiffPixels` to tolerate cross-platform rendering differences.
|
|
61
|
+
*
|
|
62
|
+
* @param page - Playwright page instance obtained from `createPage()`
|
|
63
|
+
* @param options - extra options (see `CompareScreenshotOptions`)
|
|
64
|
+
* @returns `true` when the screenshot matches the baseline (or a new baseline was saved)
|
|
65
|
+
* @throws Fails the current Vitest test when a mismatch is detected
|
|
66
|
+
*/
|
|
67
|
+
export declare function compareScreenshot(
|
|
68
|
+
page: NuxtPage,
|
|
69
|
+
options?: CompareScreenshotOptions,
|
|
70
|
+
): Promise<boolean>
|
package/utils/index.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { gotoPage, getDataHtml, getAPIResultHtml } from './e2e'
|
|
2
|
-
import { compareScreenshot } from './screenshot'
|
|
3
|
-
import type { CompareScreenshotOptions } from './screenshot'
|
|
4
|
-
|
|
5
|
-
export {
|
|
6
|
-
compareScreenshot,
|
|
7
|
-
gotoPage,
|
|
8
|
-
getDataHtml,
|
|
9
|
-
getAPIResultHtml,
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export type { CompareScreenshotOptions }
|
|
1
|
+
import { gotoPage, getDataHtml, getAPIResultHtml } from './e2e'
|
|
2
|
+
import { compareScreenshot } from './screenshot'
|
|
3
|
+
import type { CompareScreenshotOptions } from './screenshot'
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
compareScreenshot,
|
|
7
|
+
gotoPage,
|
|
8
|
+
getDataHtml,
|
|
9
|
+
getAPIResultHtml,
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export type { CompareScreenshotOptions }
|