Run Vue Component Tests Where Vue Runs: The Browser
A Vue component's job is to produce DOM in a browser. Most component tests ask it to do that somewhere else: in Node, against a DOM that jsdom simulates. That has been the default since npm create vue@latest started offering Vitest with jsdom, and for plenty of tests it is the right trade. It does set a ceiling on what a green test proves, though. Nothing is ever drawn. Your CSS never runs and nothing has a size or a position, so a component can pass every assertion in the file and still be broken on screen. I co-maintain twd-js , which runs tests inside your actual dev server, in a sidebar, next to the app. It was built for flow testing: visit a route, click through the app, assert on what the user sees. Component testing was the thing it did not do. Then I tried calling render() from @testing-library/vue inside a TWD test. import { afterEach , describe , it } from " twd-js/runner " ; import { twd , userEvent } from " twd-js " ; import { render , screen , cleanup } from " @testing-library/vue " ; import HomeView from " ../../views/HomeView.vue " ; import { componentHost , restorePage } from " ../support/componentHost " ; describe ( " HomeView component " , () => { afterEach (() => { cleanup (); restorePage (); }); it ( " increments the counter on click " , async () => { // componentHost() is a blank div on an empty page. More on it below. render ( HomeView , { container : componentHost () }); const button = await screen . findByTestId ( " counter-button " ); twd . should ( button , " contain.text " , " Count is 0 " ); await userEvent . click ( button ); twd . should ( button , " contain.text " , " Count is 1 " ); }); }); Nothing broke. The component mounts into the page, the sidebar shows it running, and reactivity does what reactivity does, in a browser, against a DOM nobody had to simulate. Why this works at all Vue Testing Library is a thin layer. render() mounts your component with @vue/test-utils and binds @testing-library/dom queries to the result. Neither of