Tryb przeglądarki Eksperymentalny
Ta strona zawiera informacje o eksperymentalnej funkcji trybu przeglądarki w Vitest API, która umożliwia uruchamianie testów bezpośrednio w przeglądarce. Dzięki temu testy mają dostęp do globalnych obiektów przeglądarki, takich jak window i document. Funkcja ta jest obecnie w fazie rozwoju, a jej API mogą ulec zmianie w przyszłości.


Instalacja
Aby ułatwić konfigurację, możesz użyć polecenia vitest init browser, które zainstaluje wymagane zależności i utworzy konfigurację przeglądarki.
npx vitest init browseryarn exec vitest init browserpnpx vitest init browserbun add -D vitest @vitest/browserRęczna instalacja
Pakiety można również zainstalować ręcznie. Domyślnie tryb przeglądarki nie wymaga żadnego dodatkowego dostawcy E2E do uruchamiania testów lokalnie, ponieważ wykorzystuje już istniejącą przeglądarkę.
npm install -D vitest @vitest/browseryarn add -D vitest @vitest/browserpnpm add -D vitest @vitest/browserbun add -D vitest @vitest/browserWARNING
Aby uruchomić testy w środowisku CI, musisz zainstalować playwright lub webdriverio. Zalecamy również przejście na jednego z tych dostawców do testowania lokalnego, zamiast używania domyślnego dostawcy preview, ponieważ preview opiera się na symulowaniu zdarzeń, a nie na protokole Chrome DevTools.
Jeśli jeszcze nie używasz żadnego z tych narzędzi, zalecamy rozpoczęcie od Playwright, ponieważ wspiera on równoległe wykonywanie, co przyspiesza działanie testów. Dodatkowo, protokół Chrome DevTools wykorzystywany przez Playwright jest zazwyczaj szybszy niż WebDriver.
::: tabs key:provider == Playwright Playwright to framework do testowania i automatyzacji stron internetowych.
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 umożliwia uruchamianie testów lokalnie przy użyciu protokołu 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 webdriverioKonfiguracja
Aby włączyć tryb przeglądarki w konfiguracji Vitest, możesz użyć flagi --browser lub ustawić pole browser.enabled na true w pliku konfiguracyjnym Vitest. Oto przykład konfiguracji z użyciem pola browser:
export default defineConfig({
test: {
browser: {
provider: 'playwright', // lub 'webdriverio'
enabled: true,
name: 'chromium', // nazwa przeglądarki jest wymagana
},
},
});INFO
Vitest przypisuje port 63315, aby uniknąć konfliktów z serwerem deweloperskim, umożliwiając równoległe uruchamianie obu. Możesz to zmienić za pomocą opcji browser.api.
Od Vitest 2.1.5, CLI nie wyświetla już automatycznie adresu URL Vite. Możesz nacisnąć "b", aby wyświetlić adres URL podczas działania w trybie obserwacji.
Jeśli nie korzystałeś wcześniej z Vite, upewnij się, że masz zainstalowaną wtyczkę swojego frameworka i określoną w konfiguracji. Niektóre frameworki mogą wymagać dodatkowej konfiguracji do działania – sprawdź ich dokumentację związaną z Vite, aby się upewnić.
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 nie wymaga wtyczki do działania, ale preact wymaga dodatkowej konfiguracji, aby aliasy działały poprawnie.
Jeśli potrzebujesz uruchomić niektóre testy za pomocą runnera opartego na Node.js, możesz zdefiniować plik workspace'u z oddzielnymi konfiguracjami dla różnych strategii testowania:
// vitest.workspace.ts
import { defineWorkspace } from 'vitest/config';
export default defineWorkspace([
{
test: {
// przykład konwencji nazewniczej plików,
// nie musisz jej przestrzegać
include: [
'tests/unit/**/*.{test,spec}.ts',
'tests/**/*.unit.{test,spec}.ts',
],
name: 'unit',
environment: 'node',
},
},
{
test: {
// przykład konwencji nazewniczej plików,
// nie musisz jej przestrzegać
include: [
'tests/browser/**/*.{test,spec}.ts',
'tests/**/*.browser.{test,spec}.ts',
],
name: 'browser',
browser: {
enabled: true,
name: 'chrome',
},
},
},
]);Konfiguracja dostawcy
:::tabs key:provider == Playwright Możesz skonfigurować, jak Vitest uruchamia przeglądarkę i tworzy kontekst strony za pomocą pola providerOptions:
export default defineConfig({
test: {
browser: {
providerOptions: {
launch: {
devtools: true,
},
context: {
geolocation: {
latitude: 45,
longitude: -30,
},
reducedMotion: 'reduce',
},
},
},
},
});Aby uzyskać wskazówki dotyczące typów, dodaj @vitest/browser/providers/playwright do compilerOptions.types w pliku tsconfig.json. == WebdriverIO Możesz skonfigurować, jakie opcje Vitest powinien używać podczas uruchamiania przeglądarki za pomocą pola providerOptions:
export default defineConfig({
test: {
browser: {
browser: 'chrome',
providerOptions: {
region: 'eu',
capabilities: {
browserVersion: '27.0',
platformName: 'Windows 10',
},
},
},
},
});Aby uzyskać wskazówki dotyczące typów, dodaj @vitest/browser/providers/webdriverio do compilerOptions.types w pliku tsconfig.json. :::
Typy opcji przeglądarki
Opcja przeglądarki w Vitest zależy od dostawcy. Vitest zakończy się niepowodzeniem, jeśli przekażesz --browser i nie określisz jej nazwy w pliku konfiguracyjnym. Dostępne przeglądarki:
webdriveriowspiera następujące przeglądarki:firefoxchromeedgesafari
playwrightwspiera następujące przeglądarki:firefoxwebkitchromium
Kompatybilność przeglądarek
Vitest używa serwera deweloperskiego Vite do uruchamiania testów, dlatego obsługujemy tylko funkcje określone w opcji esbuild.target (domyślnie esnext).
Domyślnie Vite wspiera przeglądarki, które obsługują natywne moduły ES, natywny dynamiczny import ESM i import.meta. Ponadto wykorzystujemy BroadcastChannel do komunikacji między iframe'ami:
- Chrome >=87
- Firefox >=78
- Safari >=15.4
- Edge >=88
Uruchamianie testów
Gdy określisz nazwę przeglądarki w opcji browser, Vitest domyślnie spróbuje uruchomić określoną przeglądarkę za pomocą preview, a następnie wykona tam testy. Jeśli nie chcesz używać preview, możesz skonfigurować niestandardowego dostawcę przeglądarki za pomocą opcji browser.provider.
Aby podać przeglądarkę za pomocą CLI, użyj flagi --browser, a następnie nazwy przeglądarki, w ten sposób:
npx vitest --browser=chromeLub możesz podać opcje przeglądarki do CLI za pomocą notacji kropkowej:
npx vitest --browser.name=chrome --browser.headlessDomyślnie Vitest automatycznie otworzy UI przeglądarki do celów deweloperskich. Twoje testy będą uruchamiane wewnątrz iframe'a, w centralnej części ekranu. Możesz skonfigurować obszar widoku, wybierając preferowane wymiary, wywołując page.viewport wewnątrz testu lub ustawiając wartości domyślne w konfiguracji.
Tryb bezgłowy (Headless)
Tryb headless to kolejna opcja dostępna w trybie przeglądarki. W tym trybie przeglądarka działa w tle bez interfejsu użytkownika, co czyni ją przydatną do uruchamiania zautomatyzowanych testów. Opcja headless w Vitest może być ustawiona na wartość boolowską, aby włączyć lub wyłączyć tryb bezgłowy.
W trybie bezgłowym Vitest nie otworzy automatycznie interfejsu użytkownika. Jeśli chcesz nadal używać interfejsu użytkownika, ale testy mają być uruchamiane w trybie bezgłowym, możesz zainstalować pakiet @vitest/ui i przekazać flagę --ui podczas uruchamiania Vitest.
Oto przykład konfiguracji trybu bezgłowego:
export default defineConfig({
test: {
browser: {
provider: 'playwright',
enabled: true,
headless: true,
},
},
});Możesz również ustawić tryb bezgłowy za pomocą flagi --browser.headless w CLI, w ten sposób:
npx vitest --browser.name=chrome --browser.headlessW tym przypadku Vitest będzie działać w trybie bezgłowym z przeglądarką Chrome.
WARNING
Tryb bezgłowy nie jest domyślnie dostępny. Aby włączyć tę funkcję, musisz użyć dostawców playwright lub webdriverio.
Przykłady
Vitest dostarcza pakiety do renderowania komponentów dla kilku popularnych frameworków, dostępne od razu po instalacji:
vitest-browser-vuedo renderowania komponentów vuevitest-browser-sveltedo renderowania komponentów sveltevitest-browser-reactdo renderowania komponentów react
Jeśli Twój framework nie jest obsługiwany, śmiało stwórz własny pakiet – jest to prosta nakładka wokół renderera frameworka i API page.elementLocator. Dodamy do niego link na tej stronie. Upewnij się, że jego nazwa zaczyna się od vitest-browser-.
Oprócz renderowania komponentów i lokalizacji elementów, będziesz również musiał tworzyć asercje. Vitest zawiera bibliotekę @testing-library/jest-dom, aby zapewnić szeroki zakres asercji DOM dostępnych od razu po instalacji. Więcej informacji znajdziesz w API asercji.
import { expect } from 'vitest';
import { page } from '@vitest/browser/context';
// element jest poprawnie renderowany
await expect.element(page.getByText('Hello World')).toBeInTheDocument();Vitest udostępnia API kontekstu z zestawem narzędzi, które mogą być przydatne w testach. Na przykład, jeśli potrzebujesz interakcji, takiej jak kliknięcie elementu lub wpisanie tekstu do pola wejściowego, możesz użyć userEvent z @vitest/browser/context. Więcej informacji znajdziesz w API interaktywności.
import { page, userEvent } from '@vitest/browser/context';
await userEvent.fill(page.getByLabelText(/username/i), 'Alice');
// lub po prostu 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);
// Asercje dotyczące stanu początkowego.
await expect
.element(screen.getByText('Hi, my name is Alice'))
.toBeInTheDocument();
// Pobierz element DOM inputu, wyszukując powiązaną etykietę.
const usernameInput = screen.getByLabelText(/username/i);
// Wpisz nazwę do pola. To już waliduje, że pole
// jest poprawnie wypełnione, nie ma potrzeby ręcznego sprawdzania wartości.
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 () => {
// Renderuj element React w DOM
const screen = render(<Fetch url="/greeting" />);
await screen.getByText('Load Greeting').click();
// poczekaj przed rzuceniem błędu, jeśli element nie zostanie znaleziony
const heading = screen.getByRole('heading');
// sprawdź, czy komunikat alertu jest prawidłowy
await expect.element(heading).toHaveTextContent('hello there');
await expect.element(screen.getByRole('button')).toBeDisabled();
});Vitest nie obsługuje wszystkich frameworków od razu po wyjęciu z pudełka, ale możesz użyć zewnętrznych narzędzi do uruchamiania testów z tymi frameworkami. Zachęcamy również społeczność do tworzenia własnych wrapperów vitest-browser - jeśli masz taki, śmiało dodaj go do powyższych przykładów.
Dla nieobsługiwanych frameworków zalecamy użycie pakietów testing-library:
@testing-library/preactdo renderowania komponentów preact@solidjs/testing-librarydo renderowania komponentów solid@marko/testing-librarydo renderowania komponentów marko
WARNING
testing-library dostarcza pakiet @testing-library/user-event. Nie zalecamy używania go bezpośrednio, ponieważ symuluje on zdarzenia zamiast faktycznie je wyzwalać. Zamiast tego użyj userEvent importowanego z @vitest/browser/context, który pod spodem używa protokołu Chrome DevTools lub Webdriver (w zależności od dostawcy).
// na podstawie przykładu @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('shows the children when the checkbox is checked', async () => {
const testMessage = 'Test Message';
const { baseElement } = render(<HiddenMessage>{testMessage}</HiddenMessage>);
const screen = page.elementLocator(baseElement);
// Metoda `.query()` zwróci element lub `null`, jeśli nie zostanie znaleziony.
// Metoda `.element()` zwróci element lub rzuci błąd, jeśli nie zostanie znaleziony.
expect(screen.getByText(testMessage).query()).not.toBeInTheDocument();
// Zapytania mogą akceptować wyrażenie regularne, aby selektory były bardziej
// odporne na drobne zmiany w treści.
await screen.getByLabelText(/show/i).click();
await expect.element(screen.getByText(testMessage)).toBeInTheDocument();
});// na podstawie @testing-library/solid API
// https://testing-library.com/docs/solid-testing-library/api
import { render } from '@testing-library/solid';
test('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();
});// na podstawie @testing-library/marko API
// 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();
await expect.element(container.firstChild).toMatchInlineSnapshot(`
<h1>Hello, Marko!</h1>
`);
});Ograniczenia
Okna dialogowe blokujące wątek
Podczas korzystania z Vitest Browser ważne jest, aby pamiętać, że okna dialogowe blokujące wątek, takie jak alert lub confirm, nie mogą być używane natywnie. Dzieje się tak, ponieważ blokują one stronę internetową, co uniemożliwia Vitestowi kontynuowanie komunikacji ze stroną, powodując zawieszenie wykonania.
W takich sytuacjach Vitest dostarcza domyślne makiety z domyślnymi wartościami zwracanymi dla tych API. Zapewnia to, że jeśli użytkownik przypadkowo użyje synchronicznych webowych API wyskakujących okienek, wykonanie nie zostanie zawieszone. Nadal jednak zaleca się użytkownikowi mockowanie tych API przeglądarkowych dla lepszego doświadczenia. Więcej informacji znajdziesz w Mocking.