Modalità Browser Sperimentale
Questa pagina fornisce informazioni sulla funzionalità sperimentale della modalità browser nell'API Vitest, che consente di eseguire i test nativamente nel browser, fornendo accesso agli oggetti globali del browser come window e document. Questa funzionalità è in fase di sviluppo e le API potrebbero subire modifiche in futuro.
TIP
Se stai cercando la documentazione per expect, vi o qualsiasi API generale come i test di progetti o i test di tipizzazione, fai riferimento alla guida "Per iniziare".


Installazione
Per una configurazione semplice, puoi usare il comando vitest init browser per installare le dipendenze e creare la configurazione del browser.
npx vitest init browseryarn exec vitest init browserpnpx vitest init browserbunx vitest init browserInstallazione Manuale
Puoi installare i pacchetti anche manualmente. Per impostazione predefinita, la Modalità Browser non richiede provider E2E aggiuntivi per eseguire test localmente, poiché riutilizza il browser esistente.
npm install -D vitest @vitest/browseryarn add -D vitest @vitest/browserpnpm add -D vitest @vitest/browserbun add -D vitest @vitest/browserWARNING
Tuttavia, per eseguire i test in CI è necessario installare playwright o webdriverio. Si consiglia inoltre di passare a uno di essi per i test locali, anziché utilizzare il provider preview predefinito, poiché quest'ultimo si basa sulla simulazione di eventi invece di sfruttare il Chrome DevTools Protocol.
Se non usi già uno di questi strumenti, ti consigliamo di iniziare con Playwright perché supporta l'esecuzione parallela, il che rende i tuoi test più veloci. Inoltre, Playwright utilizza il Chrome DevTools Protocol che è generalmente più veloce di WebDriver.
::: tabs key:provider == Playwright Playwright è un framework per il Test Web e l'Automazione.
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 consente di eseguire test localmente utilizzando il protocollo 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 webdriverioConfigurazione
Per attivare la modalità browser nella tua configurazione Vitest, imposta il campo browser.enabled su true nel tuo file di configurazione Vitest. Ecco un esempio di configurazione che utilizza il campo browser:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
browser: {
provider: 'playwright', // o 'webdriverio'
enabled: true,
// è richiesta almeno un'istanza
instances: [{ browser: 'chromium' }],
},
},
});INFO
Vitest assegna la porta 63315 per evitare conflitti con il server di sviluppo, consentendoti di eseguire entrambi in parallelo. Puoi cambiarla con l'opzione browser.api.
Da Vitest 2.1.5, la CLI non stampa più automaticamente l'URL di Vite. Puoi premere "b" per stampare l'URL quando esegui in modalità watch.
Se non hai mai usato Vite, assicurati di avere il plugin del tuo framework installato e specificato nella configurazione. Alcuni framework potrebbero richiedere una configurazione aggiuntiva per funzionare; consulta la loro documentazione relativa a Vite per maggiori dettagli.
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' }],
},
},
});Se hai bisogno di eseguire test con un runner Node, puoi definire un'opzione projects con configurazioni separate per diverse strategie di test:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
projects: [
{
test: {
// un esempio di convenzione basata su file,
// che non è obbligatorio seguire
include: [
'tests/unit/**/*.{test,spec}.ts',
'tests/**/*.unit.{test,spec}.ts',
],
name: 'unit',
environment: 'node',
},
},
{
test: {
// un esempio di convenzione basata su file,
// che non è obbligatorio seguire
include: [
'tests/browser/**/*.{test,spec}.ts',
'tests/**/*.browser.{test,spec}.ts',
],
name: 'browser',
browser: {
enabled: true,
instances: [{ browser: 'chromium' }],
},
},
},
],
},
});Tipi di Opzioni Browser
L'opzione browser in Vitest dipende dal provider scelto. Vitest fallirà se utilizzi --browser senza specificare il suo nome nel file di configurazione. Opzioni disponibili:
webdriveriosupporta questi browser:firefoxchromeedgesafari
playwrightsupporta questi browser:firefoxwebkitchromium
TypeScript
Per impostazione predefinita, TypeScript non riconosce le opzioni dei provider e le proprietà expect aggiuntive. Se non usi provider, assicurati che @vitest/browser/matchers sia referenziato nei tuoi test, in un file di setup o in un file di configurazione per acquisire le definizioni expect aggiuntive. Se stai usando provider personalizzati, assicurati di aggiungere @vitest/browser/providers/playwright o @vitest/browser/providers/webdriverio allo stesso file in modo che TypeScript possa acquisire le definizioni per le opzioni personalizzate:
/// <reference types="@vitest/browser/matchers" />/// <reference types="@vitest/browser/providers/playwright" />/// <reference types="@vitest/browser/providers/webdriverio" />In alternativa, puoi aggiungerli al campo compilerOptions.types nel tuo tsconfig.json. Nota che specificare qualcosa in questo campo disabiliterà il caricamento automatico dei pacchetti @types/*.
{
"compilerOptions": {
"types": ["@vitest/browser/matchers"]
}
}{
"compilerOptions": {
"types": ["@vitest/browser/providers/playwright"]
}
}{
"compilerOptions": {
"types": ["@vitest/browser/providers/webdriverio"]
}
}Compatibilità Browser
Vitest utilizza il server di sviluppo Vite per eseguire i test, supportando solo le funzionalità specificate nell'opzione esbuild.target (esnext per impostazione predefinita).
Per impostazione predefinita, Vite si rivolge ai browser che supportano i Moduli ES nativi, l'importazione dinamica ESM e import.meta. Inoltre, utilizziamo BroadcastChannel per comunicare tra gli iframe:
- Chrome >=87
- Firefox >=78
- Safari >=15.4
- Edge >=88
Esecuzione dei Test
Quando specifichi un nome di browser nell'opzione browser, Vitest tenterà di eseguire il browser specificato utilizzando preview per impostazione predefinita, e successivamente eseguirà i test al suo interno. Se non vuoi usare preview, puoi configurare il provider di browser personalizzato usando l'opzione browser.provider.
Per specificare un browser usando la CLI, usa il flag --browser seguito dal nome del browser, in questo modo:
npx vitest --browser=chromiumOppure puoi fornire opzioni del browser alla CLI con la notazione a punti:
npx vitest --browser.headlessWARNING
A partire da Vitest 3.2, se non hai l'opzione browser nella tua configurazione ma specifichi il flag --browser, Vitest fallirà perché non può presumere che la configurazione sia destinata al browser e non ai test Node.js.
Per impostazione predefinita, Vitest aprirà automaticamente l'interfaccia utente del browser per lo sviluppo. I tuoi test verranno eseguiti all'interno di un iframe al centro. Puoi configurare il viewport selezionando le dimensioni preferite, chiamando page.viewport all'interno del test, oppure impostando i valori predefiniti nella configurazione.
Headless
La modalità headless è un'altra opzione nella modalità browser. In modalità headless, il browser viene eseguito in background senza un'interfaccia utente, il che lo rende utile per l'esecuzione di test automatizzati. L'opzione headless in Vitest può essere impostata su un valore booleano per abilitare o disabilitare la modalità headless.
Quando si utilizza la modalità headless, Vitest non aprirà automaticamente l'interfaccia utente. Se desideri continuare a utilizzare l'interfaccia utente ma eseguire i test in modalità headless, puoi installare il pacchetto @vitest/ui e passare il flag --ui quando esegui Vitest.
Ecco un esempio di configurazione per abilitare la modalità headless:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
browser: {
provider: 'playwright',
enabled: true,
headless: true,
},
},
});Puoi anche impostare la modalità headless usando il flag --browser.headless nella CLI, così:
npx vitest --browser.headlessIn questo caso, Vitest eseguirà in modalità headless usando il browser Chrome.
WARNING
La modalità headless non è disponibile per impostazione predefinita. È necessario utilizzare i provider playwright o webdriverio per abilitare questa funzionalità.
Esempi
Per impostazione predefinita, non hai bisogno di pacchetti esterni per lavorare con la Modalità Browser:
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(); // monta gli elementi DOM
// Verifica lo stato iniziale.
await expect
.element(page.getByText('Hi, my name is Alice'))
.toBeInTheDocument();
// Recupera l'elemento input cercando l'etichetta corrispondente.
const usernameInput = page.getByLabelText(/username/i);
// Digita il nome nell'input. Questo verifica automaticamente che l'input
// sia compilato correttamente, non è necessario controllare il valore manualmente.
await usernameInput.fill('Bob');
await expect
.element(page.getByText('Hi, my name is Bob'))
.toBeInTheDocument();
});Tuttavia, Vitest fornisce anche pacchetti per il rendering di componenti per diversi framework popolari, pronti all'uso:
vitest-browser-vueper il rendering di componenti vuevitest-browser-svelteper il rendering di componenti sveltevitest-browser-reactper il rendering di componenti react
Sono disponibili pacchetti della community per altri framework:
vitest-browser-litper il rendering di componenti litvitest-browser-preactper il rendering di componenti preact
Se il tuo framework non è rappresentato, non esitare a creare il tuo pacchetto: si tratta di un semplice wrapper attorno al renderer del framework e all'API page.elementLocator. Aggiungeremo un link ad esso su questa pagina. Assicurati che il suo nome inizi con vitest-browser-.
Oltre a renderizzare componenti e localizzare elementi, dovrai fare asserzioni. Vitest ha fatto un fork della libreria @testing-library/jest-dom per fornire un'ampia gamma di asserzioni DOM pronte all'uso. Per maggiori informazioni, consulta l'API di Asserzioni.
import { expect } from 'vitest';
import { page } from '@vitest/browser/context';
// l'elemento è renderizzato correttamente
await expect.element(page.getByText('Hello World')).toBeInTheDocument();Vitest espone un'API di Contesto con utility utili nei test. Ad esempio, per fare un'interazione, come cliccare un elemento o digitare testo in un input, usa userEvent da @vitest/browser/context. Per maggiori informazioni, consulta l'API di Interattività.
import { page, userEvent } from '@vitest/browser/context';
await userEvent.fill(page.getByLabelText(/username/i), 'Alice');
// o semplicemente 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 lo stato iniziale.
await expect
.element(screen.getByText('Hi, my name is Alice'))
.toBeInTheDocument();
// Recupera l'elemento input cercando l'etichetta corrispondente.
const usernameInput = screen.getByLabelText(/username/i);
// Digita il nome nell'input. Questo verifica automaticamente che l'input
// sia compilato correttamente, non è necessario controllare il valore 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 () => {
// Renderizza un elemento React nel DOM
const screen = render(<Fetch url="/greeting" />);
await screen.getByText('Load Greeting').click();
// aspetta prima di lanciare un errore se non riesce a trovare un elemento
const heading = screen.getByRole('heading');
// asserisce che il messaggio di avviso sia corretto
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 non supporta tutti i framework pronti all'uso, ma puoi utilizzare strumenti esterni per eseguire test con questi framework. Incoraggiamo anche la community a creare i propri wrapper vitest-browser; se ne hai uno, non esitare ad aggiungerlo agli esempi sopra.
Per i framework non supportati, consigliamo di utilizzare i pacchetti testing-library:
@solidjs/testing-libraryper il rendering di componenti solid@marko/testing-libraryper il rendering di componenti marko
Puoi vedere altri esempi nel repository browser-examples.
WARNING
testing-library fornisce un pacchetto @testing-library/user-event. Non consigliamo di usarlo direttamente perché simula gli eventi invece di attivarli realmente; usa invece userEvent importato da @vitest/browser/context che utilizza internamente il Chrome DevTools Protocol o Webdriver (a seconda del provider).
// basato sull'API @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();
});// basato sull'API @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>
`);
});Limitazioni
Finestre di Dialogo che Bloccano il Thread
Quando si utilizza Vitest Browser, è importante notare che le finestre di dialogo che bloccano il thread come alert o confirm non possono essere utilizzate nativamente. Questo perché bloccano la pagina web, il che significa che Vitest non può continuare a comunicare con la pagina, causando il blocco dell'esecuzione.
In tali situazioni, Vitest fornisce mock predefiniti con valori di ritorno predefiniti per queste API. Ciò garantisce che se l'utente utilizza accidentalmente API web popup sincrone, l'esecuzione non si blocchi. Tuttavia, si consiglia comunque all'utente di creare dei mock per queste API web per una migliore esperienza. Maggiori informazioni in Mocking.