Interaktivitás API
A Vitest a @testing-library/user-event API-k egy részhalmazát valósítja meg a Chrome DevTools Protocol vagy a Webdriver segítségével. Ez a megközelítés eseményszimuláció helyett valós böngészőinterakciókat használ, ami megbízhatóbbá és konzisztensebbé teszi a felhasználói interakciók tesztelését.
import { userEvent } from '@vitest/browser/context';
await userEvent.click(document.querySelector('.button'));Szinte minden userEvent metódus elfogadja a szolgáltató-specifikus opciókat. Az IDE-ben elérhető összes opció megtekintéséhez adja hozzá a webdriver vagy playwright típusokat (a használt szolgáltatótól függően) a beállítási fájljához vagy egy konfigurációs fájlhoz (attól függően, hogy mi szerepel a tsconfig.json fájl included szakaszában):
/// <reference types="@vitest/browser/providers/playwright" />/// <reference types="@vitest/browser/providers/webdriverio" />userEvent.setup
function setup(): UserEvent;Új userEvent példányt hoz létre. Ez akkor hasznos, ha meg kell őriznie a billentyűzet állapotát a billentyűk helyes lenyomásához és felengedéséhez.
WARNING
Az @testing-library/user-event-től eltérően a @vitest/browser/context alapértelmezett userEvent példánya egyszer jön létre, nem pedig minden metódushíváskor! A működésbeli különbséget az alábbi kódrészlet mutatja be:
import { userEvent as vitestUserEvent } from '@vitest/browser/context';
import { userEvent as originalUserEvent } from '@testing-library/user-event';
await vitestUserEvent.keyboard('{Shift}'); // Shift lenyomása felengedés nélkül
await vitestUserEvent.keyboard('{/Shift}'); // Shift felengedése
await originalUserEvent.keyboard('{Shift}'); // Shift lenyomása felengedés nélkül
await originalUserEvent.keyboard('{/Shift}'); // NEM engedi fel a Shiftet, mert az állapot másEz a viselkedés hasznosabb, mert nem emuláljuk a billentyűzetet, hanem ténylegesen lenyomjuk a Shift billentyűt. Az eredeti viselkedés fenntartása váratlan problémákat okozna a mezőbe történő bevitel során.
userEvent.click
function click(
element: Element | Locator,
options?: UserEventClickOptions
): Promise<void>;Kattintás egy elemen. Örökli a szolgáltató-specifikus opciókat. Kérjük, nézze meg a szolgáltató dokumentációját a metódus működésének részletes magyarázatáért.
import { page, userEvent } from '@vitest/browser/context';
test('clicks on an element', async () => {
const logo = page.getByRole('img', { name: /logo/ });
await userEvent.click(logo);
// vagy közvetlenül is elérheti a lokátoron
await logo.click();
});Hivatkozások:
userEvent.dblClick
function dblClick(
element: Element | Locator,
options?: UserEventDoubleClickOptions
): Promise<void>;Dupla kattintás eseményt vált ki egy elemen.
Kérjük, olvassa el a szolgáltató dokumentációját a metódus működésének részletes magyarázatáért.
import { page, userEvent } from '@vitest/browser/context';
test('triggers a double click on an element', async () => {
const logo = page.getByRole('img', { name: /logo/ });
await userEvent.dblClick(logo);
// vagy közvetlenül is elérheti a lokátoron
await logo.dblClick();
});Hivatkozások:
userEvent.tripleClick
function tripleClick(
element: Element | Locator,
options?: UserEventTripleClickOptions
): Promise<void>;Háromszoros kattintás eseményt vált ki egy elemen. Mivel a böngésző API-ban nincs tripleclick, ez a metódus három kattintás eseményt fog egymás után generálni. Ezért ellenőriznie kell a kattintás esemény részleteit az esemény szűréséhez: evt.detail === 3.
Kérjük, olvassa el a szolgáltató dokumentációját a metódus működésének részletes magyarázatáért.
import { page, userEvent } from '@vitest/browser/context';
test('triggers a triple click on an element', async () => {
const logo = page.getByRole('img', { name: /logo/ });
let tripleClickFired = false;
logo.addEventListener('click', evt => {
if (evt.detail === 3) {
tripleClickFired = true;
}
});
await userEvent.tripleClick(logo);
// vagy közvetlenül is elérheti a lokátoron
await logo.tripleClick();
expect(tripleClickFired).toBe(true);
});Hivatkozások:
- Playwright
locator.clickAPI:clicksegítségével implementálvaclickCount: 3paraméterrel. - WebdriverIO
browser.actionAPI: actions API segítségével implementálvamoveplusz háromdown + up + pauseesemény egymás után. - testing-library
tripleClickAPI
userEvent.fill
function fill(element: Element | Locator, text: string): Promise<void>;Értéket állít be az input/textarea/contenteditable elemnek. Ez eltávolítja a meglévő szöveget a beviteli elemből, mielőtt beállítaná az új értéket.
import { page, userEvent } from '@vitest/browser/context';
test('update input', async () => {
const input = page.getByRole('input');
await userEvent.fill(input, 'foo'); // input.value == foo
await userEvent.fill(input, '{{a[['); // input.value == {{a[[
await userEvent.fill(input, '{Shift}'); // input.value == {Shift}
// vagy közvetlenül is elérheti a lokátoron
await input.fill('foo'); // input.value == foo
});Ez a metódus fókuszálja az elemet, kitölti azt, és a kitöltés után input eseményt vált ki. Üres stringet is használhat a mező törléséhez.
TIP
Ez az API gyorsabb, mint a userEvent.type vagy a userEvent.keyboard használata, de nem támogatja a user-event keyboard szintaxist (pl. {Shift}{selectall}).
Javasoljuk, hogy ezt az API-t használja a userEvent.type helyett olyan esetekben, amikor nem kell speciális karaktereket beírnia, vagy finomabb vezérlésre van szüksége a billentyűleütési események terén.
Hivatkozások:
userEvent.keyboard
function keyboard(text: string): Promise<void>;A userEvent.keyboard lehetővé teszi a billentyűleütések kiváltását. Ha bármely beviteli mező fókuszban van, akkor karaktereket gépel abba a beviteli mezőbe. Ellenkező esetben billentyűzet eseményeket vált ki az aktuálisan fókuszált elemen (ha nincs fókuszált elem, akkor a document.body-n).
Ez az API támogatja a user-event keyboard szintaxist.
import { userEvent } from '@vitest/browser/context';
test('trigger keystrokes', async () => {
await userEvent.keyboard('foo'); // eredménye: f, o, o
await userEvent.keyboard('{{a[['); // eredménye: {, a, [
await userEvent.keyboard('{Shift}{f}{o}{o}'); // eredménye: Shift, f, o, o
await userEvent.keyboard('{a>5}'); // 'a' lenyomása felengedés nélkül és 5 keydown kiváltása
await userEvent.keyboard('{a>5/}'); // 'a' lenyomása 5 keydown-ra, majd felengedése
});Hivatkozások:
userEvent.tab
function tab(options?: UserEventTabOptions): Promise<void>;Tab billentyű eseményt küld. Ez a userEvent.keyboard('{tab}') rövidítése.
import { page, userEvent } from '@vitest/browser/context';
test('tab works', async () => {
const [input1, input2] = page.getByRole('input').elements();
expect(input1).toHaveFocus();
await userEvent.tab();
expect(input2).toHaveFocus();
await userEvent.tab({ shift: true });
expect(input1).toHaveFocus();
});Hivatkozások:
userEvent.type
function type(
element: Element | Locator,
text: string,
options?: UserEventTypeOptions
): Promise<void>;WARNING
Ha nem támaszkodik speciális karakterekre (pl. {shift} vagy {selectall}), akkor a jobb teljesítmény érdekében javasolt a userEvent.fill használata.
A type metódus implementálja a @testing-library/user-event type segédprogramját, amely a keyboard API-ra épül.
Ez a funkció lehetővé teszi karakterek beírását input/textarea/contenteditable elemekbe. Támogatja a user-event keyboard szintaxist.
Ha csak karaktereket kell lenyomnia bemenet nélkül, használja a userEvent.keyboard API-t.
import { page, userEvent } from '@vitest/browser/context';
test('update input', async () => {
const input = page.getByRole('input');
await userEvent.type(input, 'foo'); // input.value == foo
await userEvent.type(input, '{{a[['); // input.value == foo{a[
await userEvent.type(input, '{Shift}'); // input.value == foo{a[
});INFO
A Vitest nem teszi elérhetővé a .type metódust a lokátoron, mint az input.type, mert az csak a userEvent könyvtárral való kompatibilitás miatt létezik. Fontolja meg a .fill használatát helyette, mivel az gyorsabb.
Hivatkozások:
userEvent.clear
function clear(
element: Element | Locator,
options?: UserEventClearOptions
): Promise<void>;Ez a metódus törli a beviteli elem tartalmát.
import { page, userEvent } from '@vitest/browser/context';
test('clears input', async () => {
const input = page.getByRole('input');
await userEvent.fill(input, 'foo');
expect(input).toHaveValue('foo');
await userEvent.clear(input);
// vagy közvetlenül is elérheti a lokátoron
await input.clear();
expect(input).toHaveValue('');
});Hivatkozások:
userEvent.selectOptions
function selectOptions(
element: Element | Locator,
values: HTMLElement | HTMLElement[] | Locator | Locator[] | string | string[],
options?: UserEventSelectOptions
): Promise<void>;A userEvent.selectOptions lehetővé teszi érték kiválasztását egy <select> elemen belül.
WARNING
Ha a select elemnek nincs multiple attribútuma, a Vitest csak a tömb első elemét választja ki.
A @testing-library-vel ellentétben a Vitest jelenleg nem támogatja a listboxot, de a jövőben tervezzük a támogatás hozzáadását.
import { page, userEvent } from '@vitest/browser/context';
test('clears input', async () => {
const select = page.getByRole('select');
await userEvent.selectOptions(select, 'Option 1');
// vagy közvetlenül is elérheti a lokátoron
await select.selectOptions('Option 1');
expect(select).toHaveValue('option-1');
await userEvent.selectOptions(select, 'option-1');
expect(select).toHaveValue('option-1');
await userEvent.selectOptions(select, [
page.getByRole('option', { name: 'Option 1' }),
page.getByRole('option', { name: 'Option 2' }),
]);
expect(select).toHaveValue(['option-1', 'option-2']);
});WARNING
A webdriverio szolgáltató nem támogatja több elem kiválasztását, mert nem biztosít API-t ehhez.
Hivatkozások:
- Playwright
locator.selectOptionAPI - WebdriverIO
element.selectByIndexAPI - testing-library
selectOptionsAPI
userEvent.hover
function hover(
element: Element | Locator,
options?: UserEventHoverOptions
): Promise<void>;Ez a metódus a kurzor pozícióját a kiválasztott elemre helyezi. Kérjük, olvassa el a szolgáltató dokumentációját a metódus működésének részletes magyarázatáért.
WARNING
Ha webdriverio szolgáltatót használ, a kurzor alapértelmezés szerint az elem közepére mozog.
Ha playwright szolgáltatót használ, a kurzor az elem egy látható pontjára mozog.
import { page, userEvent } from '@vitest/browser/context';
test('hovers logo element', async () => {
const logo = page.getByRole('img', { name: /logo/ });
await userEvent.hover(logo);
// vagy közvetlenül is elérheti a lokátoron
await logo.hover();
});Hivatkozások:
userEvent.unhover
function unhover(
element: Element | Locator,
options?: UserEventHoverOptions
): Promise<void>;Ez ugyanúgy működik, mint a userEvent.hover, de a kurzort a document.body elemre mozgatja.
WARNING
Alapértelmezés szerint a kurzor pozíciója egy látható helyen (a playwright szolgáltatóban) vagy középen (a webdriverio szolgáltatóban) van a body elemen belül. Így ha az aktuálisan lebegtetett elem már ugyanabban a pozícióban van, ez a metódus hatástalan lesz.
import { page, userEvent } from '@vitest/browser/context';
test('unhover logo element', async () => {
const logo = page.getByRole('img', { name: /logo/ });
await userEvent.unhover(logo);
// vagy közvetlenül is elérheti a lokátoron
await logo.unhover();
});Hivatkozások:
userEvent.upload
function upload(
element: Element | Locator,
files: string[] | string | File[] | File,
options?: UserEventUploadOptions
): Promise<void>;Fájl beviteli elem feltöltése a megadott fájlokkal.
import { page, userEvent } from '@vitest/browser/context';
test('can upload a file', async () => {
const input = page.getByRole('button', { name: /Upload files/ });
const file = new File(['file'], 'file.png', { type: 'image/png' });
await userEvent.upload(input, file);
// vagy közvetlenül is elérheti a lokátoron
await input.upload(file);
// fájlútvonalakat is használhat a projekt gyökérkönyvtárához viszonyítva
await userEvent.upload(input, './fixtures/file.png');
});WARNING
A webdriverio szolgáltató csak a chrome és edge böngészőkben támogatja ezt a parancsot. Jelenleg csak karakterlánc típusokat támogat.
Hivatkozások:
userEvent.dragAndDrop
function dragAndDrop(
source: Element | Locator,
target: Element | Locator,
options?: UserEventDragAndDropOptions
): Promise<void>;A forrás elemet a cél elemre húzza. Ne feledje, hogy a source elemnek draggable attribútummal kell rendelkeznie, true értékre állítva.
import { page, userEvent } from '@vitest/browser/context';
test('drag and drop works', async () => {
const source = page.getByRole('img', { name: /logo/ });
const target = page.getByTestId('logo-target');
await userEvent.dragAndDrop(source, target);
// vagy közvetlenül is elérheti a lokátoron
await source.dropTo(target);
await expect.element(target).toHaveTextContent('Logo is processed');
});WARNING
Ezt az API-t az alapértelmezett preview szolgáltató nem támogatja.
Hivatkozások:
userEvent.copy
function copy(): Promise<void>;A kijelölt szöveg vágólapra másolása.
import { page, userEvent } from '@vitest/browser/context';
test('copy and paste', async () => {
// beírás a 'source'-ba
await userEvent.click(page.getByPlaceholder('source'));
await userEvent.keyboard('hello');
// 'source' kijelölése és másolása
await userEvent.dblClick(page.getByPlaceholder('source'));
await userEvent.copy();
// beillesztés a 'target'-be
await userEvent.click(page.getByPlaceholder('target'));
await userEvent.paste();
await expect
.element(page.getByPlaceholder('source'))
.toHaveTextContent('hello');
await expect
.element(page.getByPlaceholder('target'))
.toHaveTextContent('hello');
});Hivatkozások:
userEvent.cut
function cut(): Promise<void>;A kijelölt szöveg vágólapra kivágása.
import { page, userEvent } from '@vitest/browser/context';
test('copy and paste', async () => {
// beírás a 'source'-ba
await userEvent.click(page.getByPlaceholder('source'));
await userEvent.keyboard('hello');
// 'source' kijelölése és kivágása
await userEvent.dblClick(page.getByPlaceholder('source'));
await userEvent.cut();
// beillesztés a 'target'-be
await userEvent.click(page.getByPlaceholder('target'));
await userEvent.paste();
await expect.element(page.getByPlaceholder('source')).toHaveTextContent('');
await expect
.element(page.getByPlaceholder('target'))
.toHaveTextContent('hello');
});Hivatkozások:
userEvent.paste
function paste(): Promise<void>;Szöveg beillesztése a vágólapról. Használati példákért lásd a userEvent.copy és userEvent.cut részeket.
Hivatkozások: