diff --git a/examples/content/components/ComponentWithProse.vue b/examples/content/components/ComponentWithProse.vue
new file mode 100644
index 000000000..4aa7397d2
--- /dev/null
+++ b/examples/content/components/ComponentWithProse.vue
@@ -0,0 +1,11 @@
+
+ {{ heading }}
+ {{ content }}
+
+
+
diff --git a/examples/content/components/ComponentWithUseRuntimeConfig.vue b/examples/content/components/ComponentWithUseRuntimeConfig.vue
new file mode 100644
index 000000000..d746f0e74
--- /dev/null
+++ b/examples/content/components/ComponentWithUseRuntimeConfig.vue
@@ -0,0 +1,8 @@
+
+ Use Runtime Config
+ {{ config }}
+
+
+
diff --git a/examples/content/components/SomeComponent.vue b/examples/content/components/SomeComponent.vue
new file mode 100644
index 000000000..18e190625
--- /dev/null
+++ b/examples/content/components/SomeComponent.vue
@@ -0,0 +1,3 @@
+
+ This is an auto-imported component
+
diff --git a/examples/content/package.json b/examples/content/package.json
index e6137a303..f921e8e0e 100644
--- a/examples/content/package.json
+++ b/examples/content/package.json
@@ -1,4 +1,5 @@
{
+ "name": "example-app-vitest-content",
"private": true,
"type": "module",
"scripts": {
@@ -6,13 +7,17 @@
"dev": "nuxt dev",
"dev:prepare": "nuxt prepare",
"generate": "nuxt generate",
- "test": "vitest run",
+ "test": "pnpm test:nuxt-environment && pnpm test:browser",
+ "test:browser": "VITEST_BROWSER_ENABLED=true vitest run",
+ "test:nuxt-environment": "vitest run",
"preview": "nuxt preview"
},
"devDependencies": {
"@nuxt/content": "3.5.1",
"@nuxt/test-utils": "latest",
+ "@vitest/browser": "3.1.3",
"nuxt": "3.17.3",
- "vitest": "3.1.3"
+ "vitest": "3.1.3",
+ "vitest-browser-vue": "0.2.0"
}
}
diff --git a/examples/content/tests/browser/index.spec.ts b/examples/content/tests/browser/index.spec.ts
new file mode 100644
index 000000000..699a67dc9
--- /dev/null
+++ b/examples/content/tests/browser/index.spec.ts
@@ -0,0 +1,30 @@
+import { describe, expect, it } from 'vitest'
+import { mockNuxtImport, mountSuspended } from '@nuxt/test-utils/runtime'
+import { render } from 'vitest-browser-vue'
+import App from '~/app.vue'
+
+// Example usage: queryCollection(pages).path('/').first()
+mockNuxtImport('queryCollection', () => (_id: string) => ({
+ path: (_path: string) => ({
+ first: () => ({
+ title: 'My page',
+ }),
+ }),
+}))
+
+describe('App', () => {
+ it('works with mountSuspended', async () => {
+ const component = await mountSuspended(App)
+ expect(component.html()).toMatchInlineSnapshot(`
+ "
Index page
+ title: My page
"
+ `)
+ })
+
+ // TODO: render does not currently support
+ it.skip('works with vitest-browser-vue', () => {
+ const { getByText } = render(App)
+ expect(getByText('Index page')).toBeInTheDocument()
+ expect(getByText('title: My page')).toBeInTheDocument()
+ })
+})
diff --git a/examples/content/tests/browser/mount.spec.ts b/examples/content/tests/browser/mount.spec.ts
new file mode 100644
index 000000000..4fd11b613
--- /dev/null
+++ b/examples/content/tests/browser/mount.spec.ts
@@ -0,0 +1,31 @@
+import { expect, it } from 'vitest'
+import { render } from 'vitest-browser-vue'
+import { SomeComponent, ProseH3, ProseP, ComponentWithUseRuntimeConfig, ComponentWithProse } from '#components'
+
+it('should render any component', () => {
+ const { getByText } = render(SomeComponent)
+ expect(getByText('This is an auto-imported component')).toBeInTheDocument()
+})
+
+it('should render a ProseP component', () => {
+ const { getByText } = render(ProseP, { slots: { default: 'This is a Prose Paragraph component' } })
+ expect(getByText('This is a Prose Paragraph component')).toBeInTheDocument()
+})
+
+it('should render a ProseH3 component', () => {
+ const { getByText } = render(ProseH3, { slots: { default: 'This is a Prose heading component' } })
+ expect(getByText('This is a Prose heading component')).toBeInTheDocument()
+})
+
+it('should render a ComponentWithUseRuntimeConfig component', () => {
+ const { getByText } = render(ComponentWithUseRuntimeConfig)
+ expect(getByText('Use Runtime Config')).toBeInTheDocument()
+})
+
+it('should render a ComponentWithProse component', () => {
+ const headingText = 'Text rendered within ProseH3'
+ const paragraphText = 'Text rendered within paragraph'
+ const { getByText } = render(ComponentWithProse, { props: { heading: headingText, content: paragraphText } })
+ expect(getByText(headingText)).toBeInTheDocument()
+ expect(getByText(paragraphText)).toBeInTheDocument()
+})
diff --git a/examples/content/tests/mount.spec.ts b/examples/content/tests/mount.spec.ts
new file mode 100644
index 000000000..c7bc9d0de
--- /dev/null
+++ b/examples/content/tests/mount.spec.ts
@@ -0,0 +1,33 @@
+import { expect, it } from 'vitest'
+import { mountSuspended } from '@nuxt/test-utils/runtime'
+import { ComponentWithUseRuntimeConfig, ComponentWithProse, SomeComponent, ProseH3, ProseP } from '#components'
+
+it('should render any component', async () => {
+ const component = await mountSuspended(SomeComponent)
+ expect(component.html()).toContain('This is an auto-imported component')
+})
+
+it('should render a ProseH3 component', async () => {
+ const headingText = 'This is a Prose Heading component'
+ const component = await mountSuspended(ProseH3, { slots: { default: headingText } })
+ expect(component.html()).toContain(headingText)
+})
+
+it('should render a ProseP component', async () => {
+ const paragraphText = 'This is a Prose Paragraph component'
+ const component = await mountSuspended(ProseP, { slots: { default: paragraphText } })
+ expect(component.html()).toContain(paragraphText)
+})
+
+it('should render a ComponentWithUseRuntimeConfig component', async () => {
+ const component = await mountSuspended(ComponentWithUseRuntimeConfig)
+ expect(component.html()).toContain('Use Runtime Config')
+})
+
+it('should render a ComponentWithProse component', async () => {
+ const headingText = 'Text rendered within ProseH3'
+ const paragraphText = 'Text rendered within p'
+ const component = await mountSuspended(ComponentWithProse, { props: { heading: headingText, content: paragraphText } })
+ expect(component.html()).toContain(headingText)
+ expect(component.html()).toContain(paragraphText)
+})
diff --git a/examples/content/vitest.config.ts b/examples/content/vitest.config.ts
index 6410ffd85..88ec45b06 100644
--- a/examples/content/vitest.config.ts
+++ b/examples/content/vitest.config.ts
@@ -1,7 +1,21 @@
import { defineVitestConfig } from '@nuxt/test-utils/config'
-export default defineVitestConfig({
- test: {
- environment: 'nuxt',
+const browserConfig = {
+ browser: {
+ enabled: true,
+ provider: 'playwright',
+ instances: [{ browser: 'chromium' }],
},
+ environment: 'nuxt',
+ include: ['tests/browser/**/*.spec.ts'],
+ setupFiles: ['vitest-browser-vue'],
+}
+
+const defaultConfig = {
+ environment: 'nuxt',
+ exclude: ['tests/browser/**/*.spec.ts', 'node_modules/**', 'dist/**', '.data/**'],
+}
+
+export default defineVitestConfig({
+ test: process.env.VITEST_BROWSER_ENABLED === 'true' ? browserConfig : defaultConfig,
})
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b329b42e6..e637f51f7 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -388,12 +388,18 @@ importers:
'@nuxt/test-utils':
specifier: workspace:*
version: link:../..
+ '@vitest/browser':
+ specifier: 3.1.3
+ version: 3.1.3(playwright@1.52.0)(vite@6.3.5(@types/node@22.15.17)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vitest@3.1.3)
nuxt:
specifier: 3.17.3
version: 3.17.3(@parcel/watcher@2.5.1)(@types/node@22.15.17)(better-sqlite3@11.9.1)(db0@0.3.2(better-sqlite3@11.9.1))(encoding@0.1.13)(eslint@9.26.0(jiti@2.4.2))(idb-keyval@6.2.2)(ioredis@5.6.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.40.2)(terser@5.39.0)(typescript@5.8.3)(vite@6.3.5(@types/node@22.15.17)(jiti@2.4.2)(terser@5.39.0)(yaml@2.7.1))(vue-tsc@2.2.10(typescript@5.8.3))(yaml@2.7.1)
vitest:
specifier: 3.1.3
version: 3.1.3(@types/debug@4.1.12)(@types/node@22.15.17)(@vitest/browser@3.1.3)(happy-dom@17.4.7)(jiti@2.4.2)(jsdom@26.1.0)(terser@5.39.0)(yaml@2.7.1)
+ vitest-browser-vue:
+ specifier: 0.2.0
+ version: 0.2.0(@vitest/browser@3.1.3)(vitest@3.1.3)(vue@3.5.13(typescript@5.8.3))
examples/i18n:
devDependencies: