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 a oggetti globali del browser come window e document. Questa funzionalità è attualmente in fase di sviluppo e le API potrebbero subire modifiche in futuro.


Installazione
Per una configurazione più semplice, puoi utilizzare il comando vitest init browser per installare le dipendenze richieste e creare la configurazione del browser.
npx vitest init browseryarn exec vitest init browserpnpx vitest init browserbunx vitest init browserInstallazione Manuale
Puoi anche installare i pacchetti manualmente. Per impostazione predefinita, la modalità browser non richiede alcun provider E2E aggiuntivo per eseguire i test localmente, poiché riutilizza il browser già installato.
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. Consigliamo inoltre di passare a uno di essi per i test locali invece di utilizzare il provider preview predefinito, poiché quest'ultimo si basa sulla simulazione degli eventi anziché sull'utilizzo del Chrome DevTools Protocol.
Se non utilizzi 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, il Chrome DevTools Protocol utilizzato da Playwright è generalmente più veloce di WebDriver.
::: tabs key:provider == Playwright Playwright è un framework per il testing e l'automazione 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 ti 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, puoi usare il flag --browser o impostare il campo browser.enabled su true nel tuo file di configurazione Vitest. Ecco un esempio di configurazione che utilizza il campo browser:
export default defineConfig({
test: {
browser: {
provider: 'playwright', // o 'webdriverio'
enabled: true,
name: 'chromium', // il nome del browser è richiesto
},
},
});INFO
Vitest assegna la porta 63315 per evitare conflitti con il server di sviluppo, permettendoti di eseguire entrambi in parallelo. Puoi cambiarla con l'opzione browser.api.
A partire da Vitest 2.1.5, la CLI non visualizza più automaticamente l'URL di Vite. Puoi premere "b" per stampare l'URL quando esegui in modalità watch.
Se non hai mai usato Vite prima, assicurati di avere il plugin del tuo framework installato e specificato nella configurazione. Alcuni framework potrebbero richiedere una configurazione extra per funzionare - consulta la loro documentazione relativa a Vite per maggiori dettagli.
import { defineConfig } from 'vitest/config';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
test: {
browser: {
enabled: true,
provider: 'playwright',
name: 'chromium',
},
},
});import { defineConfig } from 'vitest/config';
import { svelte } from '@sveltejs/vite-plugin-svelte';
export default defineConfig({
plugins: [svelte()],
test: {
browser: {
enabled: true,
provider: 'playwright',
name: 'chromium',
},
},
});import { defineConfig } from 'vitest/config';
import solidPlugin from 'vite-plugin-solid';
export default defineConfig({
plugins: [solidPlugin()],
test: {
browser: {
enabled: true,
provider: 'playwright',
name: 'chromium',
},
},
});import { defineConfig } from 'vitest/config';
import marko from '@marko/vite';
export default defineConfig({
plugins: [marko()],
test: {
browser: {
enabled: true,
provider: 'playwright',
name: 'chromium',
},
},
});TIP
react non richiede alcun plugin per funzionare, ma preact richiede configurazione extra per abilitare gli alias.
Se hai bisogno di eseguire alcuni test utilizzando un runner basato su Node, puoi definire un file workspace con configurazioni separate per diverse strategie di test:
// vitest.workspace.ts
import { defineWorkspace } from 'vitest/config';
export default defineWorkspace([
{
test: {
// un esempio di convenzione basata su file,
// non devi seguirla
include: [
'tests/unit/**/*.{test,spec}.ts',
'tests/**/*.unit.{test,spec}.ts',
],
name: 'unit',
environment: 'node',
},
},
{
test: {
// un esempio di convenzione basata su file,
// non devi seguirla
include: [
'tests/browser/**/*.{test,spec}.ts',
'tests/**/*.browser.{test,spec}.ts',
],
name: 'browser',
browser: {
enabled: true,
name: 'chrome',
},
},
},
]);Configurazione del Provider
:::tabs key:provider == Playwright Puoi configurare come Vitest avvia il browser e crea il contesto della pagina tramite il campo providerOptions:
export default defineConfig({
test: {
browser: {
providerOptions: {
launch: {
devtools: true,
},
context: {
geolocation: {
latitude: 45,
longitude: -30,
},
reducedMotion: 'reduce',
},
},
},
},
});Per avere il supporto per i tipi, aggiungi @vitest/browser/providers/playwright a compilerOptions.types nel tuo file tsconfig.json. == WebdriverIO Puoi configurare quali opzioni Vitest dovrebbe usare all'avvio di un browser tramite il campo providerOptions:
export default defineConfig({
test: {
browser: {
browser: 'chrome',
providerOptions: {
region: 'eu',
capabilities: {
browserVersion: '27.0',
platformName: 'Windows 10',
},
},
},
},
});Per avere il supporto per i tipi, aggiungi @vitest/browser/providers/webdriverio a compilerOptions.types nel tuo file tsconfig.json. :::
Tipi di Opzioni Browser
L'opzione browser in Vitest dipende dal provider. Vitest genererà un errore se passi --browser e non specifichi il suo nome nel file di configurazione. Opzioni disponibili:
webdriveriosupporta questi browser:firefoxchromeedgesafari
playwrightsupporta questi browser:firefoxwebkitchromium
Compatibilità Browser
Vitest usa il server di sviluppo Vite per eseguire i tuoi test, quindi supportiamo solo le funzionalità specificate nell'opzione esbuild.target (esnext per impostazione predefinita).
Di default, Vite si rivolge ai browser che supportano i Moduli ES nativi, l'importazione dinamica ESM nativa 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 usando 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=chromeOppure puoi fornire le opzioni del browser alla CLI con la notazione a punti:
npx vitest --browser.name=chrome --browser.headlessPer impostazione predefinita, Vitest aprirà automaticamente l'interfaccia utente del browser per lo sviluppo. I tuoi test verranno eseguiti all'interno di un iframe. Puoi configurare il viewport selezionando le dimensioni preferite, invocando page.viewport all'interno del test, o impostando i valori predefiniti nella configurazione.
Headless
La modalità headless è un'altra opzione disponibile nella modalità browser. In questa modalità, 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 questa modalità.
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 che abilita la modalità headless:
export default defineConfig({
test: {
browser: {
provider: 'playwright',
enabled: true,
headless: true,
},
},
});Puoi anche impostare la modalità headless usando il flag --browser.headless nella CLI, in questo modo:
npx vitest --browser.name=chrome --browser.headlessIn questo caso, Vitest verrà eseguito 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
Vitest fornisce pacchetti per il rendering di componenti per diversi framework popolari, disponibili out-of-the-box:
vitest-browser-vueper il rendering di componenti vuevitest-browser-svelteper il rendering di componenti sveltevitest-browser-reactper il rendering di componenti react
Se il tuo framework non è rappresentato, sentiti libero di creare il tuo pacchetto - è un semplice wrapper attorno al renderer del framework e all'API page.elementLocator. Aggiungeremo un link a esso su questa pagina. Assicurati che abbia un nome che inizi con vitest-browser-.
Oltre a renderizzare componenti e localizzare elementi, dovrai anche effettuare asserzioni. Vitest include la libreria @testing-library/jest-dom per fornire un'ampia gamma di asserzioni DOM già pronte. Maggiori informazioni nell'API delle 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 un piccolo set di utility che potrebbero esserti utili nei test. Ad esempio, se hai bisogno di fare un'interazione, come cliccare un elemento o digitare testo in un input, puoi usare userEvent da @vitest/browser/context. Maggiori informazioni nell'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('gestisce correttamente v-model', async () => {
const screen = render(Component);
// Verifica lo stato iniziale.
await expect
.element(screen.getByText('Ciao, mi chiamo Alice'))
.toBeInTheDocument();
// Ottiene il nodo DOM dell'input tramite la query dell'etichetta associata.
const usernameInput = screen.getByLabelText(/username/i);
// Digita il nome nell'input. Questo convalida automaticamente che l'input
// sia riempito correttamente, senza bisogno di controllare il valore manualmente.
await usernameInput.fill('Bob');
await expect
.element(screen.getByText('Ciao, mi chiamo Bob'))
.toBeInTheDocument();
});import { render } from 'vitest-browser-svelte';
import { expect, test } from 'vitest';
import Greeter from './greeter.svelte';
test('il saluto compare al click', async () => {
const screen = render(Greeter, { name: 'World' });
const button = screen.getByRole('button');
await button.click();
const greeting = screen.getByText(/ciao mondo/iu);
await expect.element(greeting).toBeInTheDocument();
});import { render } from 'vitest-browser-react';
import Fetch from './fetch';
test('carica e visualizza il saluto', async () => {
// Renderizza un elemento React nel DOM
const screen = render(<Fetch url="/greeting" />);
await screen.getByText('Carica Saluto').click();
// attende prima di sollevare un errore se non riesce a trovare un elemento
const heading = screen.getByRole('heading');
// verifica che il messaggio sia corretto
await expect.element(heading).toHaveTextContent('ciao a tutti');
await expect.element(screen.getByRole('button')).toBeDisabled();
});Vitest non supporta tutti i framework in modo nativo, ma puoi usare strumenti esterni per eseguire test con questi framework. Incoraggiamo anche la community a creare i propri wrapper vitest-browser - se ne hai uno, sentiti libero di aggiungerlo agli esempi sopra.
Per i framework non supportati, consigliamo di utilizzare i pacchetti testing-library:
@testing-library/preactper il rendering di componenti preact@solidjs/testing-libraryper il rendering di componenti solid@marko/testing-libraryper il rendering di componenti marko
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 il Chrome DevTools Protocol o Webdriver (a seconda del provider) internamente.
// basato sull'esempio di @testing-library/preact
// https://testing-library.com/docs/preact-testing-library/example
import { h } from 'preact';
import { page } from '@vitest/browser/context';
import { render } from '@testing-library/preact';
import HiddenMessage from '../hidden-message';
test('mostra i figli quando la checkbox è selezionata', async () => {
const testMessage = 'Messaggio di Test';
const { baseElement } = render(<HiddenMessage>{testMessage}</HiddenMessage>);
const screen = page.elementLocator(baseElement);
// .query() restituirà l'elemento o null se non viene trovato.
// .element() restituirà l'elemento o solleverà un errore se non viene trovato.
expect(screen.getByText(testMessage).query()).not.toBeInTheDocument();
// Le query possono accettare una regex per rendere i tuoi selettori più
// resistenti a modifiche e cambiamenti di contenuto.
await screen.getByLabelText(/mostra/i).click();
await expect.element(screen.getByText(testMessage)).toBeInTheDocument();
});// basato sull'API @testing-library/solid
// https://testing-library.com/docs/solid-testing-library/api
import { render } from '@testing-library/solid';
it('usa i parametri', async () => {
const App = () => (
<>
<Route
path="/ids/:id"
component={() => (
<p>
Id:
{useParams()?.id}
</p>
)}
/>
<Route path="/" component={() => <p>Inizio</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('renderizza un messaggio', async () => {
const { baseElement } = await render(Greeting, { name: 'Marko' });
const screen = page.elementLocator(baseElement);
await expect.element(screen.getByText(/Marko/)).toBeInTheDocument();
await expect.element(container.firstChild).toMatchInlineSnapshot(`
<h1>Ciao, 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 in modo nativo. Questo perché bloccano la pagina web, impedendo a Vitest di comunicare con essa e causando il blocco dell'esecuzione.
In tali situazioni, Vitest fornisce mock predefiniti con valori di ritorno predefiniti per queste API. Questo garantisce che, anche se l'utente utilizza accidentalmente API web popup sincrone, l'esecuzione non si blocchi. Tuttavia, è comunque consigliabile che l'utente effettui il mocking di queste API web per una migliore esperienza. Maggiori informazioni in Mocking.