Modo Navegador Experimental
Esta página proporciona información sobre la característica experimental del modo navegador en Vitest, que le permite ejecutar sus pruebas directamente en un navegador, proporcionando acceso a objetos globales del navegador como window y document. Esta característica está actualmente en desarrollo y sus APIs pueden cambiar en el futuro.
TIP
Si busca documentación para expect, vi o cualquier API general como proyectos de prueba o pruebas de tipo, consulte la guía de "Primeros pasos".


Instalación
Para facilitar la configuración, puede utilizar el comando vitest init browser para instalar las dependencias requeridas y crear la configuración del navegador.
npx vitest init browseryarn exec vitest init browserpnpx vitest init browserbunx vitest init browserInstalación Manual
También puede instalar los paquetes manualmente. Por defecto, el modo navegador no necesita ningún proveedor E2E adicional para ejecutar pruebas localmente, ya que aprovecha su navegador existente.
npm install -D vitest @vitest/browseryarn add -D vitest @vitest/browserpnpm add -D vitest @vitest/browserbun add -D vitest @vitest/browserWARNING
Sin embargo, para ejecutar pruebas en CI, necesita instalar playwright o webdriverio. También recomendamos cambiar a uno de ellos para realizar pruebas locales en lugar de emplear el proveedor preview predeterminado, dado que este simula eventos en lugar de utilizar el Protocolo de Herramientas de Desarrollo de Chrome.
Si aún no utiliza una de estas herramientas, le recomendamos comenzar con Playwright porque admite la ejecución paralela, lo que hace que sus pruebas se ejecuten más rápido. Además, Playwright utiliza el Protocolo de Herramientas de Desarrollo de Chrome, que generalmente es más rápido que WebDriver.
::: tabs key:provider == Playwright Playwright es un framework para pruebas y automatización web.
npm install -D vitest @vitest/browser playwrightyarn add -D vitest @vitest/browser playwrightpnpm add -D vitest @vitest/browser playwrightbun add -D vitest @vitest/browser playwright== WebdriverIO
WebdriverIO le permite ejecutar pruebas localmente usando el protocolo WebDriver.
npm install -D vitest @vitest/browser webdriverioyarn add -D vitest @vitest/browser webdriveriopnpm add -D vitest @vitest/browser webdriveriobun add -D vitest @vitest/browser webdriverioConfiguración
Para activar el modo navegador en su configuración de Vitest, establezca el campo browser.enabled en true en su archivo de configuración de Vitest. Aquí hay un ejemplo de configuración usando el campo browser:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
browser: {
provider: 'playwright', // o 'webdriverio'
enabled: true,
// se necesita al menos una instancia
instances: [{ browser: 'chromium' }],
},
},
});INFO
Vitest utiliza el puerto 63315 para evitar conflictos con el servidor de desarrollo, lo que permite ejecutar ambos en paralelo. Puede cambiar esto con la opción browser.api.
Desde Vitest 2.1.5, la CLI ya no imprime la URL de Vite automáticamente. Puede presionar "b" para mostrar la URL cuando se ejecuta en modo de observación.
Si no ha usado Vite antes, asegúrese de que el plugin de su framework esté instalado y especificado en su configuración. Algunos frameworks pueden requerir configuración adicional para funcionar; consulte su documentación relacionada con Vite para confirmarlo.
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
test: {
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
},
},
});import { defineConfig } from 'vitest/config';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
test: {
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
},
},
});import { defineConfig } from 'vitest/config';
import { svelte } from '@sveltejs/vite-plugin-svelte';
export default defineConfig({
plugins: [svelte()],
test: {
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
},
},
});import { defineConfig } from 'vitest/config';
import solidPlugin from 'vite-plugin-solid';
export default defineConfig({
plugins: [solidPlugin()],
test: {
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
},
},
});import { defineConfig } from 'vitest/config';
import marko from '@marko/vite';
export default defineConfig({
plugins: [marko()],
test: {
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
},
},
});Si necesita ejecutar algunas pruebas usando un ejecutor basado en Node, puede definir una opción projects con configuraciones separadas para diferentes estrategias de prueba:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
projects: [
{
test: {
// un ejemplo de convención basada en archivos,
// no es obligatorio seguirla
include: [
'tests/unit/**/*.{test,spec}.ts',
'tests/**/*.unit.{test,spec}.ts',
],
name: 'unit',
environment: 'node',
},
},
{
test: {
// un ejemplo de convención basada en archivos,
// no es necesario seguirla
include: [
'tests/browser/**/*.{test,spec}.ts',
'tests/**/*.browser.{test,spec}.ts',
],
name: 'browser',
browser: {
enabled: true,
instances: [{ browser: 'chromium' }],
},
},
},
],
},
});Tipos de Opciones del Navegador
La opción browser en Vitest depende del proveedor. Vitest fallará si usa --browser y no especifica su nombre en el archivo de configuración. Opciones disponibles:
webdriverioadmite estos navegadores:firefoxchromeedgesafari
playwrightadmite estos navegadores:firefoxwebkitchromium
TypeScript
Por defecto, TypeScript no reconoce las opciones de proveedor ni las propiedades expect adicionales. Si no utiliza ningún proveedor, asegúrese de que @vitest/browser/matchers esté referenciado en algún lugar de sus pruebas, archivo de configuración o un archivo de configuración (../../config/) para que se detecten las definiciones expect adicionales. Si está utilizando proveedores personalizados, asegúrese de agregar @vitest/browser/providers/playwright o @vitest/browser/providers/webdriverio al mismo archivo para que TypeScript pueda detectar las definiciones de las opciones personalizadas:
/// <reference types="@vitest/browser/matchers" />/// <reference types="@vitest/browser/providers/playwright" />/// <reference types="@vitest/browser/providers/webdriverio" />Alternativamente, también puede agregarlos al campo compilerOptions.types en su archivo tsconfig.json. Tenga en cuenta que la especificación de cualquier valor en este campo deshabilitará la carga automática de paquetes @types/*.
{
"compilerOptions": {
"types": ["@vitest/browser/matchers"]
}
}{
"compilerOptions": {
"types": ["@vitest/browser/providers/playwright"]
}
}{
"compilerOptions": {
"types": ["@vitest/browser/providers/webdriverio"]
}
}Compatibilidad con Navegadores
Vitest utiliza el servidor de desarrollo de Vite para ejecutar sus pruebas, por lo que solo se admiten las características especificadas en la opción esbuild.target (esnext por defecto).
Por defecto, Vite apunta a navegadores que admiten Módulos ES nativos, importación dinámica ESM nativa y import.meta. Además, utilizamos BroadcastChannel para comunicarnos entre iframes:
- Chrome >=87
- Firefox >=78
- Safari >=15.4
- Edge >=88
Ejecución de Pruebas
Cuando especifica un nombre de navegador en la opción browser, Vitest intentará ejecutar el navegador especificado usando preview por defecto, y luego ejecutará las pruebas en él. Si no desea usar preview, puede configurar el proveedor de navegador personalizado usando la opción browser.provider.
Para especificar un navegador usando la CLI, use la bandera --browser seguida del nombre del navegador, así:
npx vitest --browser=chromiumO puede proporcionar opciones de navegador a la CLI mediante notación de puntos:
npx vitest --browser.headlessWARNING
Desde Vitest 3.2, si no tiene la opción browser en su configuración pero usa la bandera --browser, Vitest fallará porque no puede determinar si la configuración es para el navegador o para pruebas de Node.js.
Por defecto, Vitest abrirá automáticamente la interfaz de usuario del navegador para el desarrollo. Sus pruebas se ejecutarán dentro de un iframe en el centro de la interfaz de usuario. Puede configurar el viewport seleccionando las dimensiones preferidas, mediante la llamada a page.viewport dentro de la prueba, o estableciendo valores predeterminados en la configuración (../../config/#browser-viewport).
Sin interfaz gráfica (Headless)
El modo headless es otra opción disponible en el modo navegador. En el modo headless, el navegador se ejecuta en segundo plano sin una interfaz de usuario, lo que lo hace útil para ejecutar pruebas automatizadas. La opción headless en Vitest se puede establecer en un valor booleano para habilitar o deshabilitar este modo.
Cuando se usa el modo headless, Vitest no abrirá la interfaz de usuario automáticamente. Si desea seguir usando la interfaz de usuario pero ejecutar las pruebas en modo headless, puede instalar el paquete @vitest/ui y usar la bandera --ui al ejecutar Vitest.
Aquí hay un ejemplo de configuración que habilita el modo headless:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
browser: {
provider: 'playwright',
enabled: true,
headless: true,
},
},
});También puede establecer el modo headless usando la bandera --browser.headless en la CLI, así:
npx vitest --browser.headlessEn este caso, Vitest se ejecutará en modo headless con el navegador Chrome.
WARNING
El modo headless no está disponible por defecto. Necesita usar los proveedores playwright o webdriverio para habilitar esta característica.
Ejemplos
Por defecto, no requiere ningún paquete externo para utilizar el Modo Navegador:
import { expect, test } from 'vitest';
import { page } from '@vitest/browser/context';
import { render } from './my-render-function.js';
test('properly handles form inputs', async () => {
render(); // montar elementos DOM
// Verifica el estado inicial.
await expect
.element(page.getByText('Hi, my name is Alice'))
.toBeInTheDocument();
// Recupera el nodo DOM de entrada consultando la etiqueta asociada.
const usernameInput = page.getByLabelText(/username/i);
// Escribe el nombre en la entrada. Esto ya valida que la entrada
// se ha llenado correctamente, no es necesario verificar el valor manualmente.
await usernameInput.fill('Bob');
await expect
.element(page.getByText('Hi, my name is Bob'))
.toBeInTheDocument();
});Sin embargo, Vitest también proporciona paquetes para renderizar componentes para varios frameworks populares de forma predeterminada:
vitest-browser-vuepara renderizar componentes vuevitest-browser-sveltepara renderizar componentes sveltevitest-browser-reactpara renderizar componentes react
Hay paquetes comunitarios disponibles para otros frameworks:
vitest-browser-litpara renderizar componentes litvitest-browser-preactpara renderizar componentes preact
Si su framework no está representado, no dude en crear su propio paquete; es un simple envoltorio alrededor del renderizador del framework y la API page.elementLocator. Agregaremos un enlace a él en esta página. Asegúrese de que su nombre comience con vitest-browser-.
Además de renderizar componentes y localizar elementos, también necesitará hacer aserciones. Vitest se basa en la biblioteca @testing-library/jest-dom para proporcionar una amplia gama de aserciones DOM de forma predeterminada. Lea más en la API de Aserciones.
import { expect } from 'vitest';
import { page } from '@vitest/browser/context';
// el elemento se renderiza correctamente
await expect.element(page.getByText('Hello World')).toBeInTheDocument();Vitest expone una API de Contexto con un pequeño conjunto de utilidades que pueden resultar útiles en las pruebas. Por ejemplo, si necesita realizar una interacción, como hacer clic en un elemento o escribir texto en una entrada, puede usar userEvent de @vitest/browser/context. Lea más en la API de Interactividad.
import { page, userEvent } from '@vitest/browser/context';
await userEvent.fill(page.getByLabelText(/username/i), 'Alice');
// o simplemente locator.fill
await page.getByLabelText(/username/i).fill('Alice');import { render } from 'vitest-browser-vue';
import Component from './Component.vue';
test('properly handles v-model', async () => {
const screen = render(Component);
// Verifica el estado inicial.
await expect
.element(screen.getByText('Hi, my name is Alice'))
.toBeInTheDocument();
// Recupera el nodo DOM de entrada consultando la etiqueta asociada.
const usernameInput = screen.getByLabelText(/username/i);
// Escribe el nombre en la entrada. Esto ya valida que la entrada
// se ha llenado correctamente, no es necesario verificar el valor manualmente.
await usernameInput.fill('Bob');
await expect
.element(screen.getByText('Hi, my name is Bob'))
.toBeInTheDocument();
});import { render } from 'vitest-browser-svelte';
import { expect, test } from 'vitest';
import Greeter from './greeter.svelte';
test('greeting appears on click', async () => {
const screen = render(Greeter, { name: 'World' });
const button = screen.getByRole('button');
await button.click();
const greeting = screen.getByText(/hello world/iu);
await expect.element(greeting).toBeInTheDocument();
});import { render } from 'vitest-browser-react';
import Fetch from './fetch';
test('loads and displays greeting', async () => {
// Renderiza un componente React en el DOM
const screen = render(<Fetch url="/greeting" />);
await screen.getByText('Load Greeting').click();
// espera antes de generar un error si no se encuentra un elemento
const heading = screen.getByRole('heading');
// verifica que el mensaje de alerta es correcto
await expect.element(heading).toHaveTextContent('hello there');
await expect.element(screen.getByRole('button')).toBeDisabled();
});import { render } from 'vitest-browser-lit';
import { html } from 'lit';
import './greeter-button';
test('greeting appears on click', async () => {
const screen = render(html`<greeter-button name="World"></greeter-button>`);
const button = screen.getByRole('button');
await button.click();
const greeting = screen.getByText(/hello world/iu);
await expect.element(greeting).toBeInTheDocument();
});import { render } from 'vitest-browser-preact';
import { createElement } from 'preact';
import Greeting from '.Greeting';
test('greeting appears on click', async () => {
const screen = render(<Greeting />);
const button = screen.getByRole('button');
await button.click();
const greeting = screen.getByText(/hello world/iu);
await expect.element(greeting).toBeInTheDocument();
});Vitest no es compatible con todos los frameworks de forma predeterminada, pero puede utilizar herramientas externas para ejecutar pruebas con ellos. También animamos a la comunidad a crear sus propios adaptadores vitest-browser; si ha desarrollado uno, no dude en agregarlo a los ejemplos anteriores.
Para frameworks no compatibles, recomendamos usar los paquetes testing-library:
@solidjs/testing-librarypara renderizar componentes solid@marko/testing-librarypara renderizar componentes marko
También puede ver más ejemplos en el repositorio browser-examples.
WARNING
testing-library proporciona un paquete @testing-library/user-event. No se recomienda usarlo directamente porque simula eventos en lugar de desencadenarlos; en su lugar, use userEvent importado de @vitest/browser/context, que utiliza el Protocolo de Herramientas de Desarrollo de Chrome o Webdriver (dependiendo del proveedor).
// basado en la API de @testing-library/solid
// https://testing-library.com/docs/solid-testing-library/api
import { render } from '@testing-library/solid';
it('uses params', async () => {
const App = () => (
<>
<Route
path="/ids/:id"
component={() => (
<p>
Id:
{useParams()?.id}
</p>
)}
/>
<Route path="/" component={() => <p>Start</p>} />
</>
);
const { baseElement } = render(() => <App />, { location: 'ids/1234' });
const screen = page.elementLocator(baseElement);
await expect.screen(screen.getByText('Id: 1234')).toBeInTheDocument();
});// basado en la API de @testing-library/marko
// https://testing-library.com/docs/marko-testing-library/api
import { render, screen } from '@marko/testing-library';
import Greeting from './greeting.marko';
test('renders a message', async () => {
const { baseElement } = await render(Greeting, { name: 'Marko' });
const screen = page.elementLocator(baseElement);
await expect.element(screen.getByText(/Marko/)).toBeInTheDocument();
expect(container.firstChild).toMatchInlineSnapshot(`
<h1>Hello, Marko!</h1>
`);
});Limitaciones
Diálogos de Bloqueo de Hilos
Al usar Vitest Browser, es importante tener en cuenta que los diálogos que bloquean hilos como alert o confirm no son compatibles de forma nativa. Esto se debe a que bloquean la página web, impidiendo que Vitest continúe comunicándose con ella y provocando que la ejecución se bloquee.
En tales situaciones, Vitest proporciona mocks con valores de retorno predeterminados para estas APIs. Esto asegura que, si el usuario utiliza accidentalmente APIs web síncronas de ventanas emergentes, la ejecución no se bloqueará. Sin embargo, aún se recomienda que el usuario proporcione mocks para estas APIs web para optimizar la experiencia. Lea más en Mocking.