Skip to content
Vitest 3
Main Navigation Przewodnik & APIKonfiguracjaTryb przeglądarkiZaawansowane API
3.2.0
2.1.9
1.6.1
0.34.6

Polski

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Türkçe
čeština
magyar

Polski

English
简体中文
繁體中文
Español
Français
Русский
Português – Brasil
Deutsch
日本語
한국어
Italiano
Türkçe
čeština
magyar

Wygląd

Sidebar Navigation

Wprowadzenie

Dlaczego tryb przeglądarkowy

Tryb przeglądarkowy

Konfiguracja

Referencja konfiguracji przeglądarki

Konfigurowanie Playwright

Konfiguracja WebdriverIO

API

API kontekstowe

Interaktywne API

Lokatory

API asercji

Polecenia

Przewodnik

Wiele konfiguracji

Konfiguracja Vitest

Dokumentacja API testowego

Zaawansowane API

Na tej stronie

Lokatory ​

Lokator to reprezentacja pojedynczego elementu lub grupy elementów. Każdy lokator jest definiowany przez ciąg znaków, zwany selektorem. Vitest abstrahuje ten selektor, dostarczając wygodne metody, które generują go automatycznie.

API lokatorów wykorzystuje rozszerzenie lokatorów Playwrighta o nazwie Ivya. Jednak Vitest udostępnia to API wszystkim dostawcom przeglądarek, nie tylko Playwrightowi.

TIP

Ta strona opisuje użycie API lokatorów. Aby lepiej zrozumieć lokatory i ich zastosowanie, zapoznaj się z dokumentacją Playwrighta dotyczącą lokatorów.

getByRole ​

ts
function getByRole(
  role: ARIARole | string,
  options?: LocatorByRoleOptions
): Locator;

Tworzy lokator umożliwiający znalezienie elementu na podstawie jego roli ARIA, atrybutów ARIA i nazwy dostępnościowej.

TIP

Jeśli wyszukujesz tylko jeden element za pomocą getByText('Nazwa'), często lepszym rozwiązaniem jest użycie getByRole(expectedRole, { name: 'Nazwa' }). Zapytanie o nazwę dostępnościową nie zastępuje innych zapytań, takich jak *ByAltText czy *ByTitle. Chociaż nazwa dostępnościowa może być równa tym atrybutom, nie pełni ona tej samej funkcji co te atrybuty.

Rozważ następującą strukturę DOM:

html
<h3>Sign up</h3>
<label>
  Login
  <input type="text" />
</label>
<label>
  Password
  <input type="password" />
</label>
<br />
<button>Submit</button>

Możesz zlokalizować każdy element na podstawie jego niejawnej roli:

ts
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 są dopasowywane przez dokładne dopasowanie tekstowe, bez dziedziczenia z hierarchii ról ARIA. W rezultacie, zapytanie o rolę nadrzędną, taką jak checkbox, nie będzie zawierać elementów z rolą podrzędną, taką jak switch.

Domyślnie wiele elementów semantycznych w HTML ma przypisaną rolę; na przykład <input type="radio"> ma rolę "radio". Elementy niesemantyczne w HTML nie mają roli; <div> i <span> bez dodanych semantyk zwracają null. Atrybut role może dostarczyć semantyki.

Dostarczanie ról za pomocą atrybutów role lub aria-* do wbudowanych elementów, które już mają niejawną rolę, jest zdecydowanie odradzane przez wytyczne ARIA.

Opcje ​
  • exact: boolean

    Określa, czy name ma być dopasowywane dokładnie: z uwzględnieniem wielkości liter i całego ciągu. Domyślnie wyłączone. Ta opcja jest ignorowana, jeśli name jest wyrażeniem regularnym. Należy pamiętać, że dokładne dopasowanie nadal przycina białe znaki.

    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

    Określa, czy zaznaczone elementy (ustawione przez aria-checked lub <input type="checkbox"/>) mają być uwzględnione. Domyślnie filtr nie jest stosowany.

    Szczegółowe informacje znajdziesz w 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

    Określa, czy wyłączone elementy mają być uwzględnione. Domyślnie filtr nie jest stosowany. Należy pamiętać, że w przeciwieństwie do innych atrybutów, stan disabled jest dziedziczony.

    Szczegółowe informacje znajdziesz w aria-disabled.

    tsx
    <input type="text" disabled />;
    
    page.getByRole('textbox', { disabled: true }); // ✅
    page.getByRole('textbox', { disabled: false }); // ❌
  • expanded: boolean

    Określa, czy rozwinięte elementy mają być uwzględnione. Domyślnie filtr nie jest stosowany.

    Szczegółowe informacje znajdziesz w aria-expanded.

    tsx
    <a aria-expanded="true" href="example.com">
      Link
    </a>;
    
    page.getByRole('link', { expanded: true }); // ✅
    page.getByRole('link', { expanded: false }); // ❌
  • includeHidden: boolean

    Określa, czy elementy, które są normalnie wykluczone z drzewa dostępności, powinny być wyszukiwane. Domyślnie tylko elementy widoczne są dopasowywane przez selektor roli.

    Należy pamiętać, że role none i presentation są zawsze uwzględniane.

    tsx
    <button style="display: none" />;
    
    page.getByRole('button'); // ❌
    page.getByRole('button', { includeHidden: false }); // ❌
    page.getByRole('button', { includeHidden: true }); // ✅
  • level: number

    Atrybut liczbowy, który zazwyczaj występuje dla ról heading, listitem, row, treeitem i ma wartości domyślne dla elementów <h1>-<h6>. Domyślnie filtr nie jest stosowany.

    Szczegółowe informacje znajdziesz w 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

    Nazwa dostępnościowa. Domyślnie dopasowanie jest bez uwzględniania wielkości liter i dopasowuje podciągi. Użyj opcji exact, aby kontrolować to zachowanie.

    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

    Określa, czy naciśnięte elementy mają być uwzględnione. Domyślnie filtr nie jest stosowany.

    Szczegółowe informacje znajdziesz w aria-pressed.

    tsx
    <button aria-pressed="true">👍</button>;
    
    page.getByRole('button', { pressed: true }); // ✅
    page.getByRole('button', { pressed: false }); // ❌
  • selected: boolean

    Określa, czy wybrane elementy mają być uwzględnione. Domyślnie filtr nie jest stosowany.

    Szczegółowe informacje znajdziesz w aria-selected.

    tsx
    <button role="tab" aria-selected="true">
      Vue
    </button>;
    
    page.getByRole('button', { selected: true }); // ✅
    page.getByRole('button', { selected: false }); // ❌
Zobacz także ​
  • Lista ról ARIA na MDN
  • Lista ról ARIA na w3.org
  • testing-library's ByRole

getByAltText ​

ts
function getByAltText(text: string | RegExp, options?: LocatorOptions): Locator;

Tworzy lokator zdolny do znalezienia elementu z atrybutem alt, który pasuje do podanego tekstu. W przeciwieństwie do implementacji testing-library, Vitest dopasuje każdy element, który ma pasujący atrybut alt.

tsx
<img alt="Incredibles 2 Poster" src="/incredibles-2.png" />;

page.getByAltText(/incredibles.*? poster/i); // ✅
page.getByAltText('non existing alt text'); // ❌

Opcje ​

  • exact: boolean

    Określa, czy text ma być dopasowywany dokładnie: z uwzględnieniem wielkości liter i całego ciągu. Domyślnie wyłączone. Ta opcja jest ignorowana, jeśli text jest wyrażeniem regularnym. Należy pamiętać, że dokładne dopasowanie nadal przycina białe znaki.

Zobacz także ​

  • testing-library's ByAltText

getByLabelText ​

ts
function getByLabelText(
  text: string | RegExp,
  options?: LocatorOptions
): Locator;

Tworzy lokator zdolny do znalezienia elementu, który ma powiązaną etykietę.

Lokator page.getByLabelText('Username') znajdzie wszystkie pola input w poniższym przykładzie:

html
// powiązanie for/htmlFor między etykietą a ID elementu formularza
<label for="username-input">Username</label>
<input id="username-input" />

// Atrybut aria-labelledby z elementami formularza
<label id="username-label">Username</label>
<input aria-labelledby="username-label" />

// Etykiety opakowujące
<label>Username <input /></label>

// Etykiety opakowujące, gdzie tekst etykiety znajduje się w innym elemencie potomnym
<label>
  <span>Username</span>
  <input />
</label>

// Atrybuty aria-label
// Należy pamiętać, że nie jest to etykieta widoczna dla użytkowników na stronie, dlatego przeznaczenie pola input musi być oczywiste dla użytkowników wizualnych.
<input aria-label="Username" />

Opcje ​

  • exact: boolean

    Określa, czy text ma być dopasowywany dokładnie: z uwzględnieniem wielkości liter i całego ciągu. Domyślnie wyłączone. Ta opcja jest ignorowana, jeśli text jest wyrażeniem regularnym. Należy pamiętać, że dokładne dopasowanie nadal przycina białe znaki.

Zobacz także ​

  • testing-library's ByLabelText

getByPlaceholder ​

ts
function getByPlaceholder(
  text: string | RegExp,
  options?: LocatorOptions
): Locator;

Tworzy lokator zdolny do znalezienia elementu, który ma określony atrybut placeholder. Vitest dopasuje każdy element, który ma pasujący atrybut placeholder, nie ograniczając się tylko do input.

tsx
<input placeholder="Username" />;

page.getByPlaceholder('Username'); // ✅
page.getByPlaceholder('not found'); // ❌

WARNING

Generalnie lepiej jest polegać na etykiecie za pomocą getByLabelText niż na placeholderze.

Opcje ​

  • exact: boolean

    Określa, czy text ma być dopasowywany dokładnie: z uwzględnieniem wielkości liter i całego ciągu. Domyślnie wyłączone. Ta opcja jest ignorowana, jeśli text jest wyrażeniem regularnym. Należy pamiętać, że dokładne dopasowanie nadal przycina białe znaki.

Zobacz także ​

  • testing-library's ByPlaceholderText

getByText ​

ts
function getByText(text: string | RegExp, options?: LocatorOptions): Locator;

Tworzy lokator zdolny do znalezienia elementu, który zawiera określony tekst. Tekst będzie dopasowywany do nodeValue węzła tekstowego lub wartości elementu input, jeśli typ to button lub reset. Dopasowywanie tekstu zawsze normalizuje białe znaki, nawet przy dokładnym dopasowaniu. Na przykład, wiele spacji jest zamienianych na jedną, znaki nowej linii na spacje, a początkowe i końcowe białe znaki są ignorowane.

tsx
<a href="/about">About ℹ️</a>;

page.getByText(/about/i); // ✅
page.getByText('about', { exact: true }); // ❌

TIP

Ten lokator jest przydatny do lokalizowania elementów nieinteraktywnych. Jeśli musisz zlokalizować element interaktywny, taki jak przycisk lub pole tekstowe, preferuj getByRole.

Opcje ​

  • exact: boolean

    Określa, czy text ma być dopasowywany dokładnie: z uwzględnieniem wielkości liter i całego ciągu. Domyślnie wyłączone. Ta opcja jest ignorowana, jeśli text jest wyrażeniem regularnym. Należy pamiętać, że dokładne dopasowanie nadal przycina białe znaki.

Zobacz także ​

  • testing-library's ByText

getByTitle ​

ts
function getByTitle(text: string | RegExp, options?: LocatorOptions): Locator;

Tworzy lokator zdolny do znalezienia elementu, który ma określony atrybut title. W przeciwieństwie do getByTitle z testing-library, Vitest nie może znaleźć elementów title wewnątrz SVG.

tsx
<span title="Delete" id="2"></span>;

page.getByTitle('Delete'); // ✅
page.getByTitle('Create'); // ❌

Opcje ​

  • exact: boolean

    Określa, czy text ma być dopasowywany dokładnie: z uwzględnieniem wielkości liter i całego ciągu. Domyślnie wyłączone. Ta opcja jest ignorowana, jeśli text jest wyrażeniem regularnym. Należy pamiętać, że dokładne dopasowanie nadal przycina białe znaki.

Zobacz także ​

  • testing-library's ByTitle

getByTestId ​

ts
function getByTestId(text: string | RegExp): Locator;

Tworzy lokator zdolny do znalezienia elementu, który pasuje do określonego atrybutu testowego ID. Możesz skonfigurować nazwę atrybutu za pomocą browser.locators.testIdAttribute.

tsx
<div data-testid="custom-element" />;

page.getByTestId('custom-element'); // ✅
page.getByTestId('non-existing-element'); // ❌

WARNING

Zaleca się używanie tego tylko wtedy, gdy inne lokatory nie spełniają Twoich potrzeb. Używanie atrybutów data-testid nie odzwierciedla rzeczywistego sposobu interakcji użytkownika z oprogramowaniem i należy tego unikać, jeśli to możliwe.

Opcje ​

  • exact: boolean

    Określa, czy text ma być dopasowywany dokładnie: z uwzględnieniem wielkości liter i całego ciągu. Domyślnie wyłączone. Ta opcja jest ignorowana, jeśli text jest wyrażeniem regularnym. Należy pamiętać, że dokładne dopasowanie nadal przycina białe znaki.

Zobacz także ​

  • testing-library's ByTestId

nth ​

ts
function nth(index: number): Locator;

Ta metoda zwraca nowy lokator, który dopasowuje tylko element o określonym indeksie w wyniku zapytania wieloelementowego. Jest to indeksowanie zerowe, nth(0) wybiera pierwszy element. W przeciwieństwie do elements()[n], lokator nth będzie ponawiał próbę, dopóki element nie będzie obecny.

html
<div aria-label="one"><input /><input /><input /></div>
<div aria-label="two"><input /></div>
tsx
page.getByRole('textbox').nth(0); // ✅
page.getByRole('textbox').nth(4); // ❌

TIP

Zanim użyjesz nth, możesz uznać za przydatne użycie połączonych lokatorów, aby zawęzić wyszukiwanie. Czasami nie ma lepszego sposobu na rozróżnienie niż pozycja elementu; chociaż może to prowadzić do niestabilnych testów, jest to lepsze niż nic.

tsx
page.getByLabel('two').getByRole('input'); // ✅ lepsza alternatywa dla page.getByRole('textbox').nth(3)
page.getByLabel('one').getByRole('input'); // ❌ zbyt niejednoznaczne
page.getByLabel('one').getByRole('input').nth(1); // ✅ pragmatyczny kompromis

first ​

ts
function first(): Locator;

Ta metoda zwraca nowy lokator, który dopasowuje tylko pierwszy element z wyniku zapytania wieloelementowego. Jest to skrót dla nth(0).

html
<input /> <input /> <input />
tsx
page.getByRole('textbox').first(); // ✅

last ​

ts
function last(): Locator;

Ta metoda zwraca nowy lokator, który dopasowuje tylko ostatni element z wyniku zapytania wieloelementowego. Jest to skrót dla nth(-1).

html
<input /> <input /> <input />
tsx
page.getByRole('textbox').last(); // ✅

and ​

ts
function and(locator: Locator): Locator;

Ta metoda tworzy nowy lokator, który dopasowuje elementy spełniające kryteria zarówno lokatora nadrzędnego, jak i dostarczonego. Poniższy przykład znajduje przycisk z określonym tytułem:

ts
page.getByRole('button').and(page.getByTitle('Subscribe'));

or ​

ts
function or(locator: Locator): Locator;

Ta metoda tworzy nowy lokator, który dopasowuje elementy spełniające kryteria jednego lub obu lokatorów.

WARNING

Zauważ, że jeśli lokator dopasowuje więcej niż jeden element, wywołanie innej metody może rzucić wyjątek, jeśli oczekuje ona pojedynczego elementu:

tsx
<>
  <button>Click me</button>
  <a href="https://vitest.dev">Error happened!</a>
</>;

page.getByRole('button').or(page.getByRole('link')).click(); // ❌ dopasowuje wiele elementów

filter ​

ts
function filter(options: LocatorOptions): Locator;

Ta metoda zawęża lokator zgodnie z podanymi opcjami, takimi jak filtrowanie według tekstu. Można ją łączyć kaskadowo, aby zastosować wiele filtrów.

has ​

  • Typ: Locator

Ta opcja zawęża selektor, aby dopasować elementy, które zawierają inne elementy zgodne z dostarczonym lokatorem. Na przykład, z tym HTML:

html
<article>
  <div>Vitest</div>
</article>
<article>
  <div>Rolldown</div>
</article>

Możemy zawęzić lokator, aby znaleźć tylko article z tekstem Vitest w środku:

ts
page.getByRole('article').filter({ has: page.getByText('Vitest') }); // ✅

WARNING

Dostarczony lokator (page.getByText('Vitest') w przykładzie) musi być względny względem lokatora nadrzędnego (page.getByRole('article') w przykładzie). Wyszukiwanie rozpocznie się od lokatora nadrzędnego, a nie od korzenia dokumentu.

Oznacza to, że nie możesz przekazać lokatora, który wyszukuje element poza zakresem lokatora nadrzędnego:

ts
page.getByText('Vitest').filter({ has: page.getByRole('article') }); // ❌

Ten przykład zakończy się niepowodzeniem, ponieważ element article znajduje się poza zakresem elementu zawierającego tekst Vitest.

TIP

Tę metodę można łączyć kaskadowo, aby jeszcze bardziej zawęzić element:

ts
page
  .getByRole('article')
  .filter({ has: page.getByRole('button', { name: 'delete row' }) })
  .filter({ has: page.getByText('Vitest') });

hasNot ​

  • Typ: Locator

Ta opcja zawęża selektor, aby dopasować elementy, które nie zawierają innych elementów pasujących do dostarczonego lokatora. Na przykład, z tym HTML:

html
<article>
  <div>Vitest</div>
</article>
<article>
  <div>Rolldown</div>
</article>

Możemy zawęzić lokator, aby znaleźć tylko article, który nie ma w sobie Rolldown.

ts
page.getByRole('article').filter({ hasNot: page.getByText('Rolldown') }); // ✅
page.getByRole('article').filter({ hasNot: page.getByText('Vitest') }); // ❌

WARNING

Zauważ, że dostarczony lokator jest wyszukiwany względem elementu nadrzędnego, a nie korzenia dokumentu, tak jak opcja has.

hasText ​

  • Typ: string | RegExp

Ta opcja zawęża selektor, aby dopasować tylko elementy, które zawierają podany tekst gdzieś w środku. Gdy przekazany jest string, dopasowanie jest bez uwzględniania wielkości liter i dopasowuje podciągi.

html
<article>
  <div>Vitest</div>
</article>
<article>
  <div>Rolldown</div>
</article>

Oba lokatory znajdą ten sam element, ponieważ wyszukiwanie jest bez uwzględniania wielkości liter:

ts
page.getByRole('article').filter({ hasText: 'Vitest' }); // ✅
page.getByRole('article').filter({ hasText: 'Vite' }); // ✅

hasNotText ​

  • Typ: string | RegExp

Ta opcja zawęża selektor, aby dopasować tylko elementy, które nie zawierają podanego tekstu gdzieś w środku. Gdy przekazany jest string, dopasowanie jest bez uwzględniania wielkości liter i dopasowuje podciągi.

Metody ​

Wszystkie metody są asynchroniczne i wymagają użycia await. Od Vitest 3, testy zakończą się niepowodzeniem, jeśli metoda nie zostanie wywołana z await.

click ​

ts
function click(options?: UserEventClickOptions): Promise<void>;

Kliknij na element. Możesz użyć opcji, aby ustawić pozycję kursora.

ts
import { page } from '@vitest/browser/context';

await page.getByRole('img', { name: 'Rose' }).click();
  • Więcej informacji w userEvent.click

dblClick ​

ts
function dblClick(options?: UserEventDoubleClickOptions): Promise<void>;

Wyzwala zdarzenie podwójnego kliknięcia na wskazanym elemencie. Możesz użyć opcji, aby ustawić pozycję kursora.

ts
import { page } from '@vitest/browser/context';

await page.getByRole('img', { name: 'Rose' }).dblClick();
  • Więcej informacji w userEvent.dblClick

tripleClick ​

ts
function tripleClick(options?: UserEventTripleClickOptions): Promise<void>;

Wyzwala zdarzenie potrójnego kliknięcia na elemencie. Ponieważ w API przeglądarki nie ma tripleclick, ta metoda wywoła trzy zdarzenia kliknięcia kolejno.

ts
import { page } from '@vitest/browser/context';

await page.getByRole('img', { name: 'Rose' }).tripleClick();
  • Więcej informacji w userEvent.tripleClick

clear ​

ts
function clear(options?: UserEventClearOptions): Promise<void>;

Czyści zawartość pola input.

ts
import { page } from '@vitest/browser/context';

await page.getByRole('textbox', { name: 'Full Name' }).clear();
  • Więcej informacji w userEvent.clear

hover ​

ts
function hover(options?: UserEventHoverOptions): Promise<void>;

Przesuwa kursor na wybrany element.

ts
import { page } from '@vitest/browser/context';

await page.getByRole('img', { name: 'Rose' }).hover();
  • Więcej informacji w userEvent.hover

unhover ​

ts
function unhover(options?: UserEventHoverOptions): Promise<void>;

Działa tak samo jak locator.hover, ale przenosi kursor na element document.body (czyli poza aktualnie najeżdżany element).

ts
import { page } from '@vitest/browser/context';

await page.getByRole('img', { name: 'Rose' }).unhover();
  • Więcej informacji w userEvent.unhover

fill ​

ts
function fill(text: string, options?: UserEventFillOptions): Promise<void>;

Ustawia wartość bieżącego pola input, textarea lub elementu contenteditable.

ts
import { page } from '@vitest/browser/context';

await page.getByRole('input', { name: 'Full Name' }).fill('Mr. Bean');
  • Więcej informacji w userEvent.fill

dropTo ​

ts
function dropTo(
  target: Locator,
  options?: UserEventDragAndDropOptions
): Promise<void>;

Przeciąga bieżący element do wskazanego miejsca docelowego.

ts
import { page } from '@vitest/browser/context';

const paris = page.getByText('Paris');
const france = page.getByText('France');

await paris.dropTo(france);
  • Więcej informacji w userEvent.dragAndDrop

selectOptions ​

ts
function selectOptions(
  values: HTMLElement | HTMLElement[] | Locator | Locator[] | string | string[],
  options?: UserEventSelectOptions
): Promise<void>;

Wybierz jedną lub więcej wartości z elementu rozwijanego <select>.

ts
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' }),
]);
  • Więcej informacji w userEvent.selectOptions

screenshot ​

ts
function screenshot(
  options: LocatorScreenshotOptions & { save: false }
): Promise<string>;
function screenshot(
  options: LocatorScreenshotOptions & { base64: true }
): Promise<{
  path: string;
  base64: string;
}>;
function screenshot(
  options?: LocatorScreenshotOptions & { base64?: false }
): Promise<string>;

Tworzy zrzut ekranu elementu znalezionego za pomocą selektora lokatora.

Możesz określić miejsce zapisu zrzutu ekranu za pomocą opcji path, która jest względna względem bieżącego pliku testowego. Jeśli opcja path nie jest ustawiona, Vitest domyślnie użyje browser.screenshotDirectory (domyślnie __screenshot__), a nazwy pliku i testu posłużą do określenia ścieżki zrzutu ekranu.

Jeśli potrzebujesz również zawartości zrzutu ekranu, możesz określić base64: true, aby zwrócić ją wraz ze ścieżką pliku, w którym zrzut ekranu jest zapisany.

ts
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, // zwróć również ciąg base64
});
// path - pełna ścieżka do zrzutu ekranu
// base64 - zrzut ekranu zakodowany w base64

OSTRZEŻENIE 3.2.0+

Zauważ, że screenshot zawsze zwróci dane w formacie base64, jeśli save jest ustawione na false. W takim przypadku path jest również ignorowane.

query ​

ts
function query(): Element | null;

Ta metoda zwraca pojedynczy element pasujący do selektora lokatora lub null, jeśli nie znaleziono żadnego elementu.

Jeśli wiele elementów pasuje do selektora, ta metoda rzuci wyjątek. Użyj .elements(), gdy potrzebujesz wszystkich pasujących elementów DOM, lub .all(), jeśli potrzebujesz tablicy lokatorów odpowiadających selektorowi.

Rozważ następującą strukturę DOM:

html
<div>Hello <span>World</span></div>
<div>Hello</div>

Te lokatory nie rzucą wyjątku:

ts
page.getByText('Hello World').query(); // ✅ HTMLDivElement
page.getByText('Hello Germany').query(); // ✅ null
page.getByText('World').query(); // ✅ HTMLSpanElement
page.getByText('Hello', { exact: true }).query(); // ✅ HTMLSpanElement

Te lokatory rzucą wyjątek:

ts
// zwraca wiele elementów
page.getByText('Hello').query(); // ❌
page.getByText(/^Hello/).query(); // ❌

element ​

ts
function element(): Element;

Ta metoda zwraca pojedynczy element pasujący do selektora lokatora.

Jeśli żaden element nie pasuje do selektora, wyrzucany jest błąd. Rozważ użycie .query(), gdy potrzebujesz tylko sprawdzić, czy element istnieje.

Jeśli wiele elementów pasuje do selektora, wyrzucany jest błąd. Użyj .elements(), gdy potrzebujesz wszystkich pasujących elementów DOM, lub .all(), jeśli potrzebujesz tablicy lokatorów odpowiadających selektorowi.

TIP

Ta metoda może być przydatna, jeśli musisz przekazać ją do zewnętrznej biblioteki. Jest ona wywoływana automatycznie, gdy lokator jest używany z expect.element za każdym razem, gdy asercja jest ponawiana:

ts
await expect.element(page.getByRole('button')).toBeDisabled();

Rozważ następującą strukturę DOM:

html
<div>Hello <span>World</span></div>
<div>Hello Germany</div>
<div>Hello</div>

Te lokatory nie rzucą wyjątku:

ts
page.getByText('Hello World').element(); // ✅
page.getByText('Hello Germany').element(); // ✅
page.getByText('World').element(); // ✅
page.getByText('Hello', { exact: true }).element(); // ✅

Te lokatory rzucą wyjątek:

ts
// zwraca wiele elementów
page.getByText('Hello').element(); // ❌
page.getByText(/^Hello/).element(); // ❌

// nie zwraca żadnych elementów
page.getByText('Hello USA').element(); // ❌

elements ​

ts
function elements(): Element[];

Ta metoda zwraca tablicę elementów pasujących do selektora lokatora.

Ta funkcja nigdy nie wyrzuca błędu. Jeśli nie ma elementów pasujących do selektora, ta metoda zwróci pustą tablicę.

Rozważ następującą strukturę DOM:

html
<div>Hello <span>World</span></div>
<div>Hello</div>

Te lokatory zawsze zakończą się sukcesem:

ts
page.getByText('Hello World').elements(); // ✅ [HTMLElement]
page.getByText('World').elements(); // ✅ [HTMLElement]
page.getByText('Hello', { exact: true }).elements(); // ✅ [HTMLElement]
page.getByText('Hello').element(); // ✅ [HTMLElement, HTMLElement]
page.getByText('Hello USA').elements(); // ✅ []

all ​

ts
function all(): Locator[];

Ta metoda zwraca tablicę nowych lokatorów, które pasują do selektora.

Wewnętrznie, ta metoda wywołuje .elements i tworzy lokator dla każdego elementu za pomocą page.elementLocator.

  • Zobacz locator.elements()

Właściwości ​

selector ​

selector to ciąg znaków, który zostanie użyty do zlokalizowania elementu przez dostawcę przeglądarki. Playwright użyje swojej składni lokatora, podczas gdy preview i webdriverio użyją CSS.

DANGER

Nie należy używać tego ciągu w swoim kodzie testowym. Ciąg selector jest przeznaczony wyłącznie do użytku podczas pracy z API poleceń:

ts
import type { BrowserCommand } from 'vitest/node';

const test: BrowserCommand<string> = function test(context, selector) {
  // playwright
  await context.iframe.locator(selector).click();
  // webdriverio
  await context.browser.$(selector).click();
};
ts
import { test } from 'vitest';
import { commands, page } from '@vitest/browser/context';

test('works correctly', async () => {
  await commands.test(page.getByText('Hello').selector); // ✅
  // vitest automatycznie skonwertuje to na ciąg znaków
  await commands.test(page.getByText('Hello')); // ✅
});

Niestandardowe lokatory 3.2.0+ zaawansowane ​

Możesz rozszerzyć wbudowane API lokatorów, definiując obiekt zawierający fabryki lokatorów. Te metody będą dostępne jako metody na obiekcie page i każdym utworzonym lokatorze.

Te lokatory mogą być przydatne, jeśli wbudowane lokatory nie są wystarczające. Na przykład, gdy używasz niestandardowego frameworka dla swojego interfejsu użytkownika.

Fabryka lokatorów musi zwracać ciąg znaków selektora lub sam lokator.

TIP

Składnia selektora jest identyczna z lokatorami Playwrighta. Zapoznaj się z ich przewodnikiem, aby lepiej zrozumieć, jak z nimi pracować.

ts
import { locators } from '@vitest/browser/context';

locators.extend({
  getByArticleTitle(title) {
    return `[data-title="${title}"]`;
  },
  getByArticleCommentsCount(count) {
    return `.comments :text("${count} comments")`;
  },
  async previewComments() {
    // masz dostęp do bieżącego lokatora za pomocą "this"
    // należy pamiętać, że jeśli metoda została wywołana na `page`, `this` będzie `page`,
    // a nie lokatorem!
    if (this !== page) {
      await this.click();
    }
    // ...
  },
});

// jeśli używasz typescriptu, możesz rozszerzyć interfejs LocatorSelectors
// aby mieć autouzupełnianie w metodach locators.extend, page.* i locator.*
declare module '@vitest/browser/context' {
  interface LocatorSelectors {
    // jeśli niestandardowa metoda zwraca ciąg znaków, zostanie on przekonwertowany na lokator
    // jeśli zwraca coś innego, zostanie zwrócony bez zmian
    getByArticleTitle(title: string): Locator;
    getByArticleCommentsCount(count: number): Locator;

    // Vitest zwróci obiekt Promise i nie będzie próbował przekonwertować go na lokator
    previewComments(this: Locator): Promise<void>;
  }
}

Jeśli metoda jest wywoływana na globalnym obiekcie page, selektor zostanie zastosowany do całej strony. W poniższym przykładzie getByArticleTitle znajdzie wszystkie elementy z atrybutem data-title, których wartość wynosi title. Jednakże, jeśli metoda jest wywoływana na lokatorze, jej zakres zostanie ograniczony do tego lokatora.

html
<article data-title="Hello, World!">
  Hello, World!
  <button id="comments">2 comments</button>
</article>

<article data-title="Hello, Vitest!">
  Hello, Vitest!
  <button id="comments">0 comments</button>
</article>
ts
const articles = page.getByRole('article');
const worldArticle = page.getByArticleTitle('Hello, World!'); // ✅
const commentsElement = worldArticle.getByArticleCommentsCount(2); // ✅
const wrongCommentsElement = worldArticle.getByArticleCommentsCount(0); // ❌
const wrongElement = page.getByArticleTitle('No Article!'); // ❌

await commentsElement.previewComments(); // ✅
await wrongCommentsElement.previewComments(); // ❌
Pager
Poprzednia stronaInteraktywne API
Następna stronaAPI asercji

Opublikowano na licencji MIT.

Copyright (c) 2021-Present Vitest Team

https://vitest.dev/guide/browser/locators

Opublikowano na licencji MIT.

Copyright (c) 2021-Present Vitest Team