Lokátory 2.1.0+
Lokátor představuje jeden nebo více prvků na webové stránce. Každý lokátor je definován řetězcem nazývaným selektor. Vitest zjednodušuje práci se selektory tím, že poskytuje pohodlné metody pro jejich generování na pozadí.
API lokátorů ve Vitestu vychází z forku lokátorů Playwright nazvaného Ivya. Vitest však toto API zpřístupňuje každému poskytovateli.
getByRole
function getByRole(
role: ARIARole | string,
options?: LocatorByRoleOptions
): Locator;
Umožňuje najít prvek podle jeho role ARIA, atributů ARIA a přístupného názvu.
TIP
Pokud dotazujete pouze jeden prvek pomocí getByText('Název')
, je často vhodnější použít getByRole(expectedRole, { name: 'Název' })
. Vyhledávání podle přístupného názvu nenahrazuje jiné dotazy, jako jsou *ByAltText
nebo *ByTitle
. I když přístupný název může být stejný jako tyto atributy, nenahrazuje jejich funkčnost.
Podívejte se na následující strukturu DOM:
<h3>Sign up</h3>
<label>
Login
<input type="text" />
</label>
<label>
Password
<input type="password" />
</label>
<br />
<button>Submit</button>
Každý prvek můžete lokalizovat podle jeho implicitní role:
await expect
.element(page.getByRole('heading', { name: 'Sign up' }))
.toBeVisible();
await page.getByRole('textbox', { name: 'Login' }).fill('admin');
await page.getByRole('textbox', { name: 'Password' }).fill('admin');
await page.getByRole('button', { name: /submit/i }).click();
WARNING
Role se porovnávají na základě přesné shody řetězců a nedědí se z hierarchie rolí ARIA. V důsledku toho dotaz na nadřazenou roli, jako je checkbox
, nezahrne prvky s podřazenou rolí, jako je switch
.
Ve výchozím nastavení má mnoho sémantických prvků v HTML přiřazenou roli; například <input type="radio">
má roli "radio". Nesémantické prvky v HTML nemají roli; <div>
a <span>
bez přidané sémantiky vrátí null
. Atribut role
může poskytnout sémantiku.
Přiřazování rolí prostřednictvím atributů role
nebo aria-*
nativním prvkům, které již mají implicitní roli, je silně nedoporučováno podle pokynů ARIA.
Možnosti
exact: boolean
Určuje, zda se
name
shoduje přesně, tj. rozlišuje velká a malá písmena a celý řetězec. Ve výchozím nastavení je zakázáno. Tato možnost se ignoruje, pokud jename
regulární výraz. Všimněte si, že přesná shoda stále odstraňuje bílé znaky na začátku a na konci.tsx<button>Hello World</button>; page.getByRole('button', { name: 'hello world' }); // ✅ page.getByRole('button', { name: 'hello world', exact: true }); // ❌ page.getByRole('button', { name: 'Hello World', exact: true }); // ✅
checked: boolean
Určuje, zda mají být zahrnuty zaškrtnuté prvky, které jsou nastaveny pomocí
aria-checked
nebo<input type="checkbox"/>
. Ve výchozím nastavení se filtr nepoužívá.Další informace naleznete v
aria-checked
.tsx<> <button role="checkbox" aria-checked="true" /> <input type="checkbox" checked /> </>; page.getByRole('checkbox', { checked: true }); // ✅ page.getByRole('checkbox', { checked: false }); // ❌
disabled: boolean
Určuje, zda mají být zahrnuty zakázané prvky. Ve výchozím nastavení se filtr nepoužívá. Všimněte si, že na rozdíl od jiných atributů se stav zakázání dědí.
Další informace naleznete v
aria-disabled
.tsx<input type="text" disabled />; page.getByRole('textbox', { disabled: true }); // ✅ page.getByRole('textbox', { disabled: false }); // ❌
expanded: boolean
Určuje, zda mají být zahrnuty rozbalené prvky. Ve výchozím nastavení se filtr nepoužívá.
Další informace naleznete v
aria-expanded
.tsx<a aria-expanded="true" href="example.com"> Link </a>; page.getByRole('link', { expanded: true }); // ✅ page.getByRole('link', { expanded: false }); // ❌
includeHidden: boolean
Určuje, zda se mají dotazovat prvky, které jsou normálně vyloučeny z přístupnostního stromu. Ve výchozím nastavení selektor role shoduje pouze neskryté prvky.
Všimněte si, že role
none
apresentation
jsou vždy zahrnuty.tsx<button style="display: none" />; page.getByRole('button'); // ❌ page.getByRole('button', { includeHidden: false }); // ❌ page.getByRole('button', { includeHidden: true }); // ✅
level: number
Číselný atribut, který je obvykle přítomen u rolí
heading
,listitem
,row
,treeitem
s výchozími hodnotami pro prvky<h1>-<h6>
. Ve výchozím nastavení se filtr nepoužívá.Další informace naleznete v
aria-level
.tsx<> <h1>Heading Level One</h1> <div role="heading" aria-level="1"> Second Heading Level One </div> </>; page.getByRole('heading', { level: 1 }); // ✅ page.getByRole('heading', { level: 2 }); // ❌
name: string | RegExp
Přístupný název. Ve výchozím nastavení je shoda bez rozlišování velkých a malých písmen a hledá podřetězec. K ovládání tohoto chování použijte možnost
exact
.tsx<button>Click Me!</button>; page.getByRole('button', { name: 'Click Me!' }); // ✅ page.getByRole('button', { name: 'click me!' }); // ✅ page.getByRole('button', { name: 'Click Me?' }); // ❌
pressed: boolean
Určuje, zda mají být zahrnuty stisknuté prvky. Ve výchozím nastavení se filtr nepoužívá.
Další informace naleznete v
aria-pressed
.tsx<button aria-pressed="true">👍</button>; page.getByRole('button', { pressed: true }); // ✅ page.getByRole('button', { pressed: false }); // ❌
selected: boolean
Určuje, zda mají být zahrnuty vybrané prvky. Ve výchozím nastavení se filtr nepoužívá.
Další informace naleznete v
aria-selected
.tsx<button role="tab" aria-selected="true"> Vue </button>; page.getByRole('button', { selected: true }); // ✅ page.getByRole('button', { selected: false }); // ❌
Viz také
getByAltText
function getByAltText(text: string | RegExp, options?: LocatorOptions): Locator;
Vytvoří lokátor schopný najít prvek s atributem alt
, jehož hodnota odpovídá zadanému textu. Na rozdíl od implementace testing-library Vitest najde jakýkoli prvek, který má odpovídající atribut alt
.
<img alt="Incredibles 2 Poster" src="/incredibles-2.png" />;
page.getByAltText(/incredibles.*? poster/i); // ✅
page.getByAltText('non existing alt text'); // ❌
Možnosti
exact: boolean
Určuje, zda se
text
shoduje přesně, tj. rozlišuje velká a malá písmena a celý řetězec. Ve výchozím nastavení je zakázáno. Tato možnost se ignoruje, pokud jetext
regulární výraz. Všimněte si, že přesná shoda stále odstraňuje bílé znaky na začátku a na konci.
Viz také
getByLabelText
function getByLabelText(
text: string | RegExp,
options?: LocatorOptions
): Locator;
Vytvoří lokátor schopný najít prvek, ke kterému je přidružen popisek.
Lokátor page.getByLabelText('Uživatelské jméno')
najde všechny vstupy v následujícím příkladu:
<!-- for/htmlFor vztah mezi popiskem a id prvku formuláře -->
<label for="username-input">Username</label>
<input id="username-input" />
<!-- Atribut aria-labelledby u prvků formuláře -->
<label id="username-label">Username</label>
<input aria-labelledby="username-label" />
<!-- Popisky v obalu -->
<label>Username <input /></label>
<!-- Popisky v obalu, kde text popisku je v jiném podřízeném prvku -->
<label>
<span>Username</span>
<input />
</label>
<!-- atributy aria-label -->
<!-- Pozor, protože toto není popisek, který uživatelé vidí na stránce, -->
<!-- takže účel vašeho vstupu musí být pro vizuální uživatele zřejmý. -->
<input aria-label="Username" />
Možnosti
exact: boolean
Určuje, zda se
text
shoduje přesně, tj. rozlišuje velká a malá písmena a celý řetězec. Ve výchozím nastavení je zakázáno. Tato možnost se ignoruje, pokud jetext
regulární výraz. Všimněte si, že přesná shoda stále odstraňuje bílé znaky na začátku a na konci.
Viz také
getByPlaceholder
function getByPlaceholder(
text: string | RegExp,
options?: LocatorOptions
): Locator;
Vytvoří lokátor schopný najít prvek se zadaným atributem placeholder
. Vitest najde jakýkoli prvek, který má odpovídající atribut placeholder
, nejen input
.
<input placeholder="Username" />;
page.getByPlaceholder('Username'); // ✅
page.getByPlaceholder('not found'); // ❌
WARNING
Obecně je lepší spoléhat se na popisek nalezený pomocí getByLabelText
než na placeholder.
Možnosti
exact: boolean
Určuje, zda se
text
shoduje přesně, tj. rozlišuje velká a malá písmena a celý řetězec. Ve výchozím nastavení je zakázáno. Tato možnost se ignoruje, pokud jetext
regulární výraz. Všimněte si, že přesná shoda stále odstraňuje bílé znaky na začátku a na konci.
Viz také
getByText
function getByText(text: string | RegExp, options?: LocatorOptions): Locator;
Vytvoří lokátor schopný najít prvek obsahující zadaný text. Text bude porovnán s nodeValue
TextNode nebo hodnotou vstupu, pokud je typ button
nebo reset
. Při porovnávání podle textu se vždy normalizují bílé znaky, i při přesné shodě. Například mění více mezer na jednu, mění konce řádků na mezery a ignoruje bílé znaky na začátku a na konci.
<a href="/about">About ℹ️</a>;
page.getByText(/about/i); // ✅
page.getByText('about', { exact: true }); // ❌
TIP
Tento lokátor je užitečný pro lokalizaci neinteraktivních prvků. Pokud potřebujete lokalizovat interaktivní prvek, jako je tlačítko nebo vstup, preferujte getByRole
.
Možnosti
exact: boolean
Určuje, zda se
text
shoduje přesně, tj. rozlišuje velká a malá písmena a celý řetězec. Ve výchozím nastavení je zakázáno. Tato možnost se ignoruje, pokud jetext
regulární výraz. Všimněte si, že přesná shoda stále odstraňuje bílé znaky na začátku a na konci.
Viz také
getByTitle
function getByTitle(text: string | RegExp, options?: LocatorOptions): Locator;
Vytvoří lokátor schopný najít prvek se zadaným atributem title
. Na rozdíl od getByTitle
z testing-library Vitest nemůže najít prvky s atributem title
uvnitř SVG.
<span title="Delete" id="2"></span>;
page.getByTitle('Delete'); // ✅
page.getByTitle('Create'); // ❌
Možnosti
exact: boolean
Určuje, zda se
text
shoduje přesně, tj. rozlišuje velká a malá písmena a celý řetězec. Ve výchozím nastavení je zakázáno. Tato možnost se ignoruje, pokud jetext
regulární výraz. Všimněte si, že přesná shoda stále odstraňuje bílé znaky na začátku a na konci.
Viz také
getByTestId
function getByTestId(text: string | RegExp): Locator;
Vytvoří lokátor schopný najít prvek, který odpovídá zadanému atributu testovacího ID. Název atributu lze nakonfigurovat pomocí browser.locators.testIdAttribute
.
<div data-testid="custom-element" />;
page.getByTestId('custom-element'); // ✅
page.getByTestId('non-existing-element'); // ❌
WARNING
Doporučuje se to použít pouze tehdy, když ostatní lokátory pro váš případ použití nefungují. Použití atributů data-testid
neodpovídá tomu, jak se váš software používá, a pokud je to možné, je třeba se mu vyhnout.
Možnosti
exact: boolean
Určuje, zda se
text
shoduje přesně, tj. rozlišuje velká a malá písmena a celý řetězec. Ve výchozím nastavení je zakázáno. Tato možnost se ignoruje, pokud jetext
regulární výraz. Všimněte si, že přesná shoda stále odstraňuje bílé znaky na začátku a na konci.
Viz také
Metody
Všechny metody jsou asynchronní a je třeba je očekávat pomocí await
. Od Vitest 2.2 testy selžou, pokud metoda není očekávána.
click
function click(options?: UserEventClickOptions): Promise<void>;
Klikne na prvek. Pomocí možností můžete nastavit pozici kurzoru.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).click();
dblClick
function dblClick(options?: UserEventDoubleClickOptions): Promise<void>;
Spustí událost dvojitého kliknutí na prvku. Možnosti můžete použít k nastavení pozice kurzoru.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).dblClick();
tripleClick
function tripleClick(options?: UserEventTripleClickOptions): Promise<void>;
Spustí událost trojitého kliknutí na prvku. Jelikož v API prohlížeče neexistuje tripleclick
, tato metoda spustí tři události kliknutí za sebou.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).tripleClick();
clear
function clear(): Promise<void>;
Vymaže obsah vstupního prvku.
import { page } from '@vitest/browser/context';
await page.getByRole('textbox', { name: 'Full Name' }).clear();
hover
function hover(options?: UserEventHoverOptions): Promise<void>;
Přesune pozici kurzoru na vybraný prvek.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).hover();
unhover
function unhover(options?: UserEventHoverOptions): Promise<void>;
Tato metoda funguje stejně jako locator.hover
, ale místo toho přesune kurzor na prvek document.body
.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).unhover();
fill
function fill(text: string, options?: UserEventFillOptions): Promise<void>;
Nastaví hodnotu aktuálního prvku input
, textarea
nebo prvku s atributem contenteditable
.
import { page } from '@vitest/browser/context';
await page.getByRole('input', { name: 'Full Name' }).fill('Mr. Bean');
dropTo
function dropTo(
target: Locator,
options?: UserEventDragAndDropOptions
): Promise<void>;
Přetáhne aktuální prvek na cílové místo.
import { page } from '@vitest/browser/context';
const paris = page.getByText('Paris');
const france = page.getByText('France');
await paris.dropTo(france);
selectOptions
function selectOptions(
values: HTMLElement | HTMLElement[] | Locator | Locator[] | string | string[],
options?: UserEventSelectOptions
): Promise<void>;
Vyberte jednu nebo více hodnot z prvku <select>
.
import { page } from '@vitest/browser/context';
const languages = page.getByRole('select', { name: 'Languages' });
await languages.selectOptions('EN');
await languages.selectOptions(['ES', 'FR']);
await languages.selectOptions([
languages.getByRole('option', { name: 'Spanish' }),
languages.getByRole('option', { name: 'French' }),
]);
screenshot
function screenshot(
options: LocatorScreenshotOptions & { base64: true }
): Promise<{
path: string;
base64: string;
}>;
function screenshot(
options?: LocatorScreenshotOptions & { base64?: false }
): Promise<string>;
Vytvoří snímek obrazovky prvku, který odpovídá selektoru lokátoru.
Místo uložení snímku obrazovky můžete zadat pomocí možnosti path
, která je relativní k aktuálnímu testovacímu souboru. Pokud možnost path
není nastavena, Vitest ve výchozím nastavení použije browser.screenshotDirectory
(ve výchozím nastavení __screenshot__
), a cestu k souboru snímku obrazovky určí na základě názvů souboru a testu.
Pokud také potřebujete obsah snímku obrazovky, můžete zadat base64: true
pro jeho vrácení spolu s cestou k souboru, kam je snímek obrazovky uložen.
import { page } from '@vitest/browser/context';
const button = page.getByRole('button', { name: 'Click Me!' });
const path = await button.screenshot();
const { path, base64 } = await button.screenshot({
path: './button-click-me.png',
base64: true, // také vrátí řetězec base64
});
// path - úplná cesta ke snímku obrazovky
// bas64 - řetězec snímku obrazovky kódovaný v base64
query
function query(): Element | null;
Tato metoda vrátí jeden prvek, který odpovídá selektoru lokátoru, nebo null
, pokud není nalezen žádný prvek.
Pokud selektoru odpovídá více prvků, tato metoda vyvolá chybu. Použijte .elements()
, když potřebujete všechny odpovídající prvky DOM, nebo .all()
, pokud potřebujete pole lokátorů, které odpovídají selektoru.
Zvažte následující strukturu DOM:
<div>Hello <span>World</span></div>
<div>Hello</div>
Tyto lokátory nevyvolají chybu:
page.getByText('Hello World').query(); // ✅ HTMLDivElement
page.getByText('Hello Germany').query(); // ✅ null
page.getByText('World').query(); // ✅ HTMLSpanElement
page.getByText('Hello', { exact: true }).query(); // ✅ HTMLSpanElement
Tyto lokátory vyvolají chybu:
// vrátí více prvků
page.getByText('Hello').query(); // ❌
page.getByText(/^Hello/).query(); // ❌
element
function element(): Element;
Tato metoda vrátí jeden prvek, který odpovídá selektoru lokátoru.
Pokud žádný prvek neodpovídá selektoru, vyvolá se chyba. Zvažte použití .query()
, když potřebujete pouze zkontrolovat, zda prvek existuje.
Pokud více prvků odpovídá selektoru, vyvolá se chyba. Použijte .elements()
, když potřebujete všechny odpovídající prvky DOM, nebo .all()
, pokud potřebujete pole lokátorů, které odpovídají selektoru.
TIP
Tato metoda může být užitečná, pokud ji potřebujete předat externí knihovně. Je volána automaticky, když je lokátor použit s expect.element
při každém opakování tvrzení:
await expect.element(page.getByRole('button')).toBeDisabled();
Zvažte následující strukturu DOM:
<div>Hello <span>World</span></div>
<div>Hello Germany</div>
<div>Hello</div>
Tyto lokátory nevyvolají chybu:
page.getByText('Hello World').element(); // ✅
page.getByText('Hello Germany').element(); // ✅
page.getByText('World').element(); // ✅
page.getByText('Hello', { exact: true }).element(); // ✅
Tyto lokátory vyvolají chybu:
// vrátí více prvků
page.getByText('Hello').element(); // ❌
page.getByText(/^Hello/).element(); // ❌
// vrátí žádné prvky
page.getByText('Hello USA').element(); // ❌
elements
function elements(): Element[];
Tato metoda vrátí pole prvků, které odpovídají selektoru lokátoru.
Tato funkce nikdy nevyvolá chybu. Pokud selektoru neodpovídají žádné prvky, tato metoda vrátí prázdné pole.
Zvažte následující strukturu DOM:
<div>Hello <span>World</span></div>
<div>Hello</div>
Tyto lokátory budou vždy úspěšné:
page.getByText('Hello World').elements(); // ✅ [HTMLElement]
page.getByText('World').elements(); // ✅ [HTMLElement]
page.getByText('Hello', { exact: true }).elements(); // ✅ [HTMLElement]
page.getByText('Hello').elements(); // ✅ [HTMLElement, HTMLElement]
page.getByText('Hello USA').elements(); // ✅ []
all
function all(): Locator[];
Tato metoda vrátí pole nových lokátorů, které odpovídají selektoru.
Interně tato metoda volá .elements
a každý prvek obalí pomocí page.elementLocator
.