untestutils

Recipe-based test harness for Vitest and Playwright — thin facade over @untestutils/* packages
6,052 1
Install
npm install untestutils
Latest Version:0.7.2
Vue:3
License:MIT
Last Updated:Sep 28, 2026
Links: GitHub  ·  npm
Maintainer: s00d

npm version npm downloads License CI Docs Donate

untestutils

Docs: https://s00d.github.io/untestutils/

Test the product the way it actually runs — not a mock of a mock of a framework.

Most “test utils” help you write more tests. untestutils changes what you test: the same prepare → start → URL/dir path your users hit, with real cookies, SEO headers, redirects, locale payloads, and browser behavior — shared once across Vitest and Playwright.

The idea

Shipping software is not “a component mounted in happy-dom”. It is:

  • a built (or generated) app
  • a running process on a real URL
  • data and side effects that only appear after prepare/start (i18n merges, cookies, sitemap, Nitro routes, …)

If your suite never walks that path, you are testing a parallel universe. Failures show up in staging instead.

untestutils is a harness around one contract:

Recipe  →  prepare?  →  start  →  { url } and/or { dir }
Harness →  useHarness('id')  /  Playwright test.use({ harness })

You describe how the real target comes up. Specs assert against that live target. Prepare is cached and shared — so “test like production” stays fast enough for CI.

Why not “just helpers”?

Usual approach With untestutils
Restart / re-mock the app per file One prepare, many files
Framework-special APIs that hide the URL Same Recipe ids in Vitest and Playwright
Assert on stubs and fixtures only Assert on live $fetch, page, SEO, cookies, redirects
Glue globalSetup / webServer by hand Drivers (nuxt, vite, next, staticDir, command, host, …)

Utils (untestutils/utils) exist, but they are tools for real-runtime checks — not a second testing philosophy.

What you get

  • Recipes, not preset zoos — compose targets; Nuxt is a factory, not a special universe
  • Shared prepare — warm once, reuse across workers / projects
  • Vitest + Playwright — same ids; fixtures page / goto / $fetch
  • Remote host() — post-deploy smoke against staging/prod
  • Reality-oriented utils — cookies, SEO head, domain emulation, redirect tracking, poll
  • CLI — init, doctor, optional AI fix / cover / generate
  • Perf suite — build + load against the same recipe mindset (untestutils/perf)
  • Support matrix — what is stable in CI vs optional / out of 1.0

Quick start

pnpm add -D untestutils vitest
# optional
pnpm add -D @playwright/test playwright-core

pnpm dlx untestutils init --preset vitest
// recipes.ts — how the real app comes up
import { defineRecipes } from 'untestutils'
import { nuxt } from 'untestutils/nuxt'
import { resolve } from 'node:path'

export const recipes = defineRecipes({
  basic: nuxt({
    id: 'basic',
    root: resolve('./fixtures/basic'),
    run: 'server',
  }),
}, import.meta.url)
// vitest.config.ts — plugin from untestutils/vitest/plugin
import { defineConfig } from 'vitest/config'
import { untestutils } from 'untestutils/vitest/plugin'
import { recipes } from './recipes'

export default defineConfig({
  plugins: [
    untestutils({
      recipes,
      prewarm: ['basic'],
    }),
  ],
  test: { include: ['tests/e2e/**/*.test.ts'] },
})
// tests/e2e/locale.test.ts — specs from untestutils/vitest
import { describe, test, expect, useHarness } from 'untestutils/vitest'
import { setLocaleCookie, getLocaleCookie } from 'untestutils/utils'

describe('locale', () => {
  test('cookie survives reload on the live app', async ({ page }) => {
    const app = await useHarness('basic')
    await page.goto(app.url)
    await setLocaleCookie(page, 'de')
    await page.reload()
    expect(await getLocaleCookie(page)).toBe('de')
  })
})

Same Recipe id works from Playwright via createPlaywrightConfig — one definition of “how the app runs”, two runners.

Links

License

MIT

Related Packages

@i18n-micro/test-utils

Testing helpers for Nuxt I18n Micro (translations, locales, formatting mocks).

152,219 251
vite-plugin-nuxt-test

Vite plugin to test a Nuxt 3 application.

975 8
nuxt-vitest-shared-app

Run Nuxt component tests in Vitest on one shared app per worker, with per-test c...

546 0
nuxt-hydration-gate

Mark Nuxt app hydration with a DOM attribute for CSS, scripts, and end-to-end te...

211 0
@piwitests/instrumentation-nitro

Nitro/Nuxt server plugin for Piwi Dashboard: backend logs (X-Piwi-Logs), server...

6,016 40

Version History

Version Released License
0.7.2 MIT
0.7.1 MIT
0.7.0 MIT
0.6.11 MIT
0.6.10 MIT