Skip to content
8 changes: 6 additions & 2 deletions examples/app-playwright/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const devicesToTest = [
// Test against branded browsers.
// { ...devices['Desktop Edge'], channel: 'msedge' },
// { ...devices['Desktop Chrome'], channel: 'chrome' },
] satisfies Array<string | typeof devices[string]>
] satisfies Array<string | (typeof devices)[string]>

/* See https://playwright.dev/docs/test-configuration. */
export default defineConfig<ConfigOptions>({
Expand All @@ -34,8 +34,12 @@ export default defineConfig<ConfigOptions>({
trace: 'on-first-retry',
/* Nuxt configuration options */
nuxt: {
/* Reuse a server if it's already running. Useful when developing tests. */
reuseExistingServer: process.env.CI ? false : true,
rootDir: fileURLToPath(new URL('.', import.meta.url)),
},
},
projects: devicesToTest.map(p => typeof p === 'string' ? ({ name: p, use: devices[p] }) : p),
projects: devicesToTest.map(p =>
typeof p === 'string' ? { name: p, use: devices[p] } : p,
),
})
46 changes: 31 additions & 15 deletions src/core/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,23 @@ export interface StartServerOptions {
env?: Record<string, unknown>
}

export async function reuseExistingServer() {
const ctx = useTestContext()
const host = ctx.options.host || 'localhost' // Default to localhost since it's the host used by nuxt dev server
const port = ctx.options.port || 3000 // Default to 3000 since it's the port used by nuxt dev server

if (port === undefined) {
throw new Error('Port is required when reusing server')
}

ctx.url = `http://${host}:${port}`
}

export async function startServer(options: StartServerOptions = {}) {
const ctx = useTestContext()
await stopServer()
const host = '127.0.0.1'
const port = ctx.options.port || await getRandomPort(host)
const port = ctx.options.port || (await getRandomPort(host))
ctx.url = `http://${host}:${port}`
if (ctx.options.dev) {
const nuxiCLI = await kit.resolvePath('nuxi/cli')
Expand All @@ -39,7 +51,9 @@ export async function startServer(options: StartServerOptions = {}) {
for (let i = 0; i < 150; i++) {
await new Promise(resolve => setTimeout(resolve, 100))
try {
const res = await $fetch<string>(ctx.nuxt!.options.app.baseURL, { responseType: 'text' })
const res = await $fetch<string>(ctx.nuxt!.options.app.baseURL, {
responseType: 'text',
})
if (!res.includes('__NUXT_LOADING__')) {
return
}
Expand All @@ -52,18 +66,20 @@ export async function startServer(options: StartServerOptions = {}) {
throw lastError || new Error('Timeout waiting for dev server!')
}
else {
ctx.serverProcess = execa('node', [
resolve(ctx.nuxt!.options.nitro.output!.dir!, 'server/index.mjs'),
], {
stdio: 'inherit',
env: {
...process.env,
PORT: String(port),
HOST: host,
NODE_ENV: 'test',
...options.env,
ctx.serverProcess = execa(
'node',
[resolve(ctx.nuxt!.options.nitro.output!.dir!, 'server/index.mjs')],
{
stdio: 'inherit',
env: {
...process.env,
PORT: String(port),
HOST: host,
NODE_ENV: 'test',
...options.env,
},
},
})
)
await waitForPort(port, { retries: 20, host })
}
}
Expand All @@ -79,9 +95,9 @@ export function fetch(path: string, options?: RequestInit) {
return _fetch(url(path), options)
}

export const $fetch = (function (path: string, options?: FetchOptions) {
export const $fetch = function (path: string, options?: FetchOptions) {
return _$fetch(url(path), options)
}) as typeof globalThis['$fetch']
} as (typeof globalThis)['$fetch']

export function url(path: string) {
const ctx = useTestContext()
Expand Down
12 changes: 8 additions & 4 deletions src/core/setup/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createTestContext, setTestContext } from '../context'
import { buildFixture, loadFixture } from '../nuxt'
import { startServer, stopServer } from '../server'
import { reuseExistingServer, startServer, stopServer } from '../server'
import { createBrowser } from '../browser'
import type { TestHooks, TestOptions } from '../types'
import setupCucumber from './cucumber'
Expand Down Expand Up @@ -41,20 +41,24 @@ export function createTest(options: Partial<TestOptions>): TestHooks {
}

const setup = async () => {
if (ctx.options.reuseExistingServer) {
await reuseExistingServer()
}

if (ctx.options.fixture) {
await loadFixture()
}

if (ctx.options.build) {
if (ctx.options.build && !ctx.options.reuseExistingServer) {
await buildFixture()
}

if (ctx.options.server) {
if (ctx.options.server && !ctx.options.reuseExistingServer) {
await startServer()
}

if (ctx.options.waitFor) {
await (new Promise(resolve => setTimeout(resolve, ctx.options.waitFor)))
await new Promise(resolve => setTimeout(resolve, ctx.options.waitFor))
}

if (ctx.options.browser) {
Expand Down
2 changes: 2 additions & 0 deletions src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface TestOptions {
rootDir: string
buildDir: string
nuxtConfig: NuxtConfig
reuseExistingServer?: boolean
build: boolean
dev: boolean
setupTimeout: number
Expand All @@ -23,6 +24,7 @@ export interface TestOptions {
launch?: LaunchOptions
}
server: boolean
host?: string
port?: number
}

Expand Down