Locators 2.1.0+
Ein Locator repräsentiert ein oder mehrere Elemente. Jeder Locator wird durch eine Zeichenkette, einen sogenannten Selektor, definiert. Vitest abstrahiert diesen Selektor, indem es praktische Methoden bereitstellt, die diese Selektoren im Hintergrund generieren.
Die Locator-API verwendet einen Fork von Playwrights Locators, der Ivya genannt wird. Vitest stellt diese API jedoch jedem Provider zur Verfügung.
getByRole
function getByRole(
role: ARIARole | string,
options?: LocatorByRoleOptions
): Locator;
Erstellt einen Locator, um ein Element anhand seiner ARIA-Rolle, ARIA-Attribute und seines zugänglichen Namens zu finden.
TIP
Wenn Sie nur ein einzelnes Element mit getByText('Der Name')
abfragen, ist es oft besser, getByRole(erwarteteRolle, { name: 'Der Name' })
zu verwenden. Die Abfrage des zugänglichen Namens ersetzt nicht die Funktion anderer Abfragen wie *ByAltText
oder *ByTitle
. Obwohl der zugängliche Name diesen Attributen entsprechen kann, ersetzt er nicht deren Funktionalität.
Betrachten Sie die folgende DOM-Struktur:
<h3>Sign up</h3>
<label>
Login
<input type="text" />
</label>
<label>
Password
<input type="password" />
</label>
<br />
<button>Submit</button>
Sie können jedes Element anhand seiner impliziten Rolle lokalisieren:
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
Rollen werden durch Zeichenketten-Gleichheit abgeglichen, ohne die ARIA-Rollenhierarchie zu berücksichtigen. Folglich schließt die Abfrage einer Oberklassenrolle wie checkbox
keine Elemente mit einer Unterklassenrolle wie switch
ein.
Standardmäßig besitzen viele semantische HTML-Elemente eine Rolle; zum Beispiel hat <input type="radio">
die Rolle "radio". Nicht-semantische HTML-Elemente haben keine Rolle; <div>
und <span>
ohne hinzugefügte Semantik geben null
zurück. Das role
-Attribut kann Semantik bereitstellen.
Die ARIA-Richtlinien raten dringend davon ab, Rollen über role
oder aria-*
Attribute für integrierte Elemente bereitzustellen, die bereits eine implizite Rolle haben.
Optionen
exact: boolean
Gibt an, ob der
name
exakt übereinstimmen muss: Groß-/Kleinschreibung und gesamte Zeichenkette. Standardmäßig deaktiviert. Diese Option wird ignoriert, wennname
ein regulärer Ausdruck ist. Beachten Sie, dass die exakte Übereinstimmung immer noch Leerzeichen trimmt.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
Gibt an, ob aktivierte Elemente (die durch
aria-checked
oder<input type="checkbox"/>
gesetzt sind) eingeschlossen werden sollen oder nicht. Standardmäßig wird der Filter nicht angewendet.Siehe
aria-checked
für weitere Informationen.tsx<> <button role="checkbox" aria-checked="true" /> <input type="checkbox" checked /> </>; page.getByRole('checkbox', { checked: true }); // ✅ page.getByRole('checkbox', { checked: false }); // ❌
disabled: boolean
Gibt an, ob deaktivierte Elemente eingeschlossen werden sollen oder nicht. Standardmäßig wird der Filter nicht angewendet. Beachten Sie, dass der Deaktivierungszustand im Gegensatz zu anderen Attributen vererbt wird.
Siehe
aria-disabled
für weitere Informationen.tsx<input type="text" disabled />; page.getByRole('textbox', { disabled: true }); // ✅ page.getByRole('textbox', { disabled: false }); // ❌
expanded: boolean
Gibt an, ob erweiterte Elemente eingeschlossen werden sollen oder nicht. Standardmäßig wird der Filter nicht angewendet.
Siehe
aria-expanded
für weitere Informationen.tsx<a aria-expanded="true" href="example.com"> Link </a>; page.getByRole('link', { expanded: true }); // ✅ page.getByRole('link', { expanded: false }); // ❌
includeHidden: boolean
Gibt an, ob Elemente, die normalerweise ausgeschlossen sind, abgefragt werden sollen. Standardmäßig werden nur nicht-versteckte Elemente durch den Rollenselektor abgeglichen.
Beachten Sie, dass die Rollen
none
undpresentation
immer eingeschlossen sind.tsx<button style="display: none" />; page.getByRole('button'); // ❌ page.getByRole('button', { includeHidden: false }); // ❌ page.getByRole('button', { includeHidden: true }); // ✅
level: number
Ein numerisches Attribut, das normalerweise für die Rollen
heading
,listitem
,row
,treeitem
vorhanden ist, mit Standardwerten für<h1>-<h6>
Elemente. Standardmäßig wird der Filter nicht angewendet.Siehe
aria-level
für weitere Informationen.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
Ein zugänglicher Name. Standardmäßig wird beim Abgleich die Groß-/Kleinschreibung ignoriert und nach einer Teilzeichenkette gesucht. Verwenden Sie die Option
exact
, um dieses Verhalten zu steuern.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
Gibt an, ob gedrückte Elemente eingeschlossen werden sollen oder nicht. Standardmäßig wird der Filter nicht angewendet.
Siehe
aria-pressed
für weitere Informationen.tsx<button aria-pressed="true">👍</button>; page.getByRole('button', { pressed: true }); // ✅ page.getByRole('button', { pressed: false }); // ❌
selected: boolean
Gibt an, ob ausgewählte Elemente eingeschlossen werden sollen oder nicht. Standardmäßig wird der Filter nicht angewendet.
Siehe
aria-selected
für weitere Informationen.tsx<button role="tab" aria-selected="true"> Vue </button>; page.getByRole('button', { selected: true }); // ✅ page.getByRole('button', { selected: false }); // ❌
Siehe auch
getByAltText
function getByAltText(text: string | RegExp, options?: LocatorOptions): Locator;
Erstellt einen Locator, der ein Element mit einem alt
-Attribut finden kann, das dem Text entspricht. Im Gegensatz zur Implementierung von testing-library findet Vitest jedes Element, das ein passendes alt
-Attribut hat.
<img alt="Incredibles 2 Poster" src="/incredibles-2.png" />;
page.getByAltText(/incredibles.*? poster/i); // ✅
page.getByAltText('non existing alt text'); // ❌
Optionen
exact: boolean
Gibt an, ob der
text
exakt übereinstimmen muss: Groß-/Kleinschreibung und gesamte Zeichenkette. Standardmäßig deaktiviert. Diese Option wird ignoriert, wenntext
ein regulärer Ausdruck ist. Beachten Sie, dass die exakte Übereinstimmung immer noch Leerzeichen trimmt.
Siehe auch
getByLabelText
function getByLabelText(
text: string | RegExp,
options?: LocatorOptions
): Locator;
Erstellt einen Locator, der ein Element finden kann, das ein zugeordnetes Label hat.
Der Locator page.getByLabelText('Username')
findet jedes Eingabeelement im folgenden Beispiel:
<!-- for/htmlFor Beziehung zwischen Label und Formularelement-ID -->
<label for="username-input">Username</label>
<input id="username-input" />
<!-- Das aria-labelledby Attribut mit Formularelementen -->
<label id="username-label">Username</label>
<input aria-labelledby="username-label" />
<!-- Wrapper-Labels -->
<label>Username <input /></label>
<!-- Wrapper-Labels, bei denen der Label-Text in einem anderen Kindelement ist -->
<label>
<span>Username</span>
<input />
</label>
<!-- aria-label Attribute -->
<!-- Vorsicht, da dies kein Label ist, das Benutzer auf der Seite sehen können, -->
<!-- daher muss der Zweck Ihres Eingabefelds für visuelle Benutzer offensichtlich sein. -->
<input aria-label="Username" />
Optionen
exact: boolean
Gibt an, ob der
text
exakt übereinstimmen muss: Groß-/Kleinschreibung und gesamte Zeichenkette. Standardmäßig deaktiviert. Diese Option wird ignoriert, wenntext
ein regulärer Ausdruck ist. Beachten Sie, dass die exakte Übereinstimmung immer noch Leerzeichen trimmt.
Siehe auch
getByPlaceholder
function getByPlaceholder(
text: string | RegExp,
options?: LocatorOptions
): Locator;
Erstellt einen Locator, der ein Element finden kann, das das angegebene placeholder
-Attribut hat. Vitest findet jedes Element, das ein passendes placeholder
-Attribut hat, nicht nur Eingabefelder.
<input placeholder="Username" />;
page.getByPlaceholder('Username'); // ✅
page.getByPlaceholder('not found'); // ❌
WARNING
Es ist im Allgemeinen besser, sich auf ein Label mit getByLabelText
zu verlassen als auf einen Platzhalter.
Optionen
exact: boolean
Gibt an, ob der
text
exakt übereinstimmen muss: Groß-/Kleinschreibung und gesamte Zeichenkette. Standardmäßig deaktiviert. Diese Option wird ignoriert, wenntext
ein regulärer Ausdruck ist. Beachten Sie, dass die exakte Übereinstimmung immer noch Leerzeichen trimmt.
Siehe auch
getByText
function getByText(text: string | RegExp, options?: LocatorOptions): Locator;
Erstellt einen Locator, der ein Element finden kann, das den angegebenen Text enthält. Der Text wird mit dem nodeValue
des TextNode oder dem Wert des Eingabeelements abgeglichen, wenn der Typ button
oder reset
ist. Beim Abgleich nach Text werden Leerzeichen immer normalisiert, auch bei exakter Übereinstimmung. Zum Beispiel werden mehrere Leerzeichen zu einem zusammengefasst, Zeilenumbrüche in Leerzeichen umgewandelt und führende und nachfolgende Leerzeichen ignoriert.
<a href="/about">About ℹ️</a>;
page.getByText(/about/i); // ✅
page.getByText('about', { exact: true }); // ❌
TIP
Dieser Locator ist nützlich, um nicht-interaktive Elemente zu lokalisieren. Wenn Sie ein interaktives Element wie einen Button oder ein Eingabefeld lokalisieren müssen, bevorzugen Sie getByRole
.
Optionen
exact: boolean
Gibt an, ob der
text
exakt übereinstimmen muss: Groß-/Kleinschreibung und gesamte Zeichenkette. Standardmäßig deaktiviert. Diese Option wird ignoriert, wenntext
ein regulärer Ausdruck ist. Beachten Sie, dass die exakte Übereinstimmung immer noch Leerzeichen trimmt.
Siehe auch
getByTitle
function getByTitle(text: string | RegExp, options?: LocatorOptions): Locator;
Erstellt einen Locator, der ein Element finden kann, das das angegebene title
-Attribut hat. Im Gegensatz zu testing-librarys getByTitle
kann Vitest keine title
-Elemente innerhalb eines SVG finden.
<span title="Delete" id="2"></span>;
page.getByTitle('Delete'); // ✅
page.getByTitle('Create'); // ❌
Optionen
exact: boolean
Gibt an, ob der
text
exakt übereinstimmen muss: Groß-/Kleinschreibung und gesamte Zeichenkette. Standardmäßig deaktiviert. Diese Option wird ignoriert, wenntext
ein regulärer Ausdruck ist. Beachten Sie, dass die exakte Übereinstimmung immer noch Leerzeichen trimmt.
Siehe auch
getByTestId
function getByTestId(text: string | RegExp): Locator;
Erstellt einen Locator, der ein Element finden kann, das dem angegebenen Test-ID-Attribut entspricht. Sie können den Attributnamen mit browser.locators.testIdAttribute
konfigurieren.
<div data-testid="custom-element" />;
page.getByTestId('custom-element'); // ✅
page.getByTestId('non-existing-element'); // ❌
WARNING
Es wird empfohlen, dies nur zu verwenden, wenn die anderen Locator-Methoden für Ihren Anwendungsfall nicht geeignet sind. Die Verwendung von data-testid
-Attributen entspricht nicht der tatsächlichen Nutzung Ihrer Software und sollte, wenn möglich, vermieden werden.
Optionen
exact: boolean
Gibt an, ob der
text
exakt übereinstimmen muss: Groß-/Kleinschreibung und gesamte Zeichenkette. Standardmäßig deaktiviert. Diese Option wird ignoriert, wenntext
ein regulärer Ausdruck ist. Beachten Sie, dass die exakte Übereinstimmung immer noch Leerzeichen trimmt.
Siehe auch
Methoden
Alle Methoden sind asynchron und müssen mit await
aufgerufen werden. Seit Vitest 2.2 schlagen Tests fehl, wenn eine Methode nicht mit await
aufgerufen wird.
click
function click(options?: UserEventClickOptions): Promise<void>;
Klickt auf ein Element. Sie können die Optionen verwenden, um die Cursorposition festzulegen.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).click();
dblClick
function dblClick(options?: UserEventDoubleClickOptions): Promise<void>;
Löst ein Doppelklick-Ereignis auf einem Element aus. Sie können die Optionen verwenden, um die Cursorposition festzulegen.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).dblClick();
tripleClick
function tripleClick(options?: UserEventTripleClickOptions): Promise<void>;
Löst ein Dreifachklick-Ereignis auf einem Element aus. Da es in der Browser-API keinen tripleclick
gibt, sendet diese Methode drei Klick-Ereignisse hintereinander aus.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).tripleClick();
clear
function clear(): Promise<void>;
Löscht den Inhalt des Eingabeelements.
import { page } from '@vitest/browser/context';
await page.getByRole('textbox', { name: 'Full Name' }).clear();
hover
function hover(options?: UserEventHoverOptions): Promise<void>;
Bewegt die Cursorposition auf das ausgewählte Element.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).hover();
unhover
function unhover(options?: UserEventHoverOptions): Promise<void>;
Dies funktioniert genauso wie locator.hover
, bewegt den Cursor jedoch stattdessen auf das document.body
-Element.
import { page } from '@vitest/browser/context';
await page.getByRole('img', { name: 'Rose' }).unhover();
fill
function fill(text: string, options?: UserEventFillOptions): Promise<void>;
Setzt den Wert des aktuellen input
, textarea
oder contenteditable
Elements.
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>;
Zieht das aktuelle Element an die Zielposition.
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>;
Wählt einen oder mehrere Werte aus einem <select>
Element aus.
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>;
Erstellt einen Screenshot des Elements, das dem Selektor des Locators entspricht.
Sie können den Speicherort für den Screenshot mit der Option path
angeben, die relativ zur aktuellen Testdatei ist. Wenn die Option path
nicht gesetzt ist, verwendet Vitest standardmäßig browser.screenshotDirectory
(standardmäßig __screenshot__
) zusammen mit den Namen der Datei und des Tests, um den Dateipfad des Screenshots zu bestimmen.
Wenn Sie auch den Inhalt des Screenshots benötigen, können Sie base64: true
angeben, um ihn zusammen mit dem Dateipfad, unter dem der Screenshot gespeichert wird, zurückzugeben.
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, // also return base64 string
});
// path - vollständiger Pfad zum Screenshot
// base64 - base64-kodierter String des Screenshots
query
function query(): Element | null;
Diese Methode gibt ein einzelnes Element zurück, das dem Locator-Selektor entspricht, oder null
, wenn kein Element gefunden wird.
Wenn mehrere Elemente dem Selektor entsprechen, löst diese Methode einen Fehler aus. Verwenden Sie .elements()
, wenn Sie alle übereinstimmenden DOM-Elemente benötigen, oder .all()
, wenn Sie ein Array von Locators benötigen, die dem Selektor entsprechen.
Betrachten Sie die folgende DOM-Struktur:
<div>Hello <span>World</span></div>
<div>Hello</div>
Diese Locators lösen keinen Fehler aus:
page.getByText('Hello World').query(); // ✅ HTMLDivElement
page.getByText('Hello Germany').query(); // ✅ null
page.getByText('World').query(); // ✅ HTMLSpanElement
page.getByText('Hello', { exact: true }).query(); // ✅ HTMLSpanElement
Diese Locators lösen einen Fehler aus:
// gibt mehrere Elemente zurück
page.getByText('Hello').query(); // ❌
page.getByText(/^Hello/).query(); // ❌
element
function element(): Element;
Diese Methode gibt ein einzelnes Element zurück, das dem Locator-Selektor entspricht.
Wenn kein Element dem Selektor entspricht, wird ein Fehler ausgelöst. Erwägen Sie die Verwendung von .query()
, wenn Sie nur prüfen müssen, ob das Element existiert.
Wenn mehrere Elemente dem Selektor entsprechen, wird ein Fehler ausgelöst. Verwenden Sie .elements()
, wenn Sie alle übereinstimmenden DOM-Elemente benötigen, oder .all()
, wenn Sie ein Array von Locators benötigen, die dem Selektor entsprechen.
TIP
Diese Methode kann nützlich sein, wenn Sie sie an eine externe Bibliothek weitergeben müssen. Sie wird automatisch aufgerufen, wenn der Locator mit expect.element
verwendet wird, jedes Mal, wenn die Assertion wiederholt wird:
await expect.element(page.getByRole('button')).toBeDisabled();
Betrachten Sie die folgende DOM-Struktur:
<div>Hello <span>World</span></div>
<div>Hello Germany</div>
<div>Hello</div>
Diese Locators lösen keinen Fehler aus:
page.getByText('Hello World').element(); // ✅
page.getByText('Hello Germany').element(); // ✅
page.getByText('World').element(); // ✅
page.getByText('Hello', { exact: true }).element(); // ✅
Diese Locators lösen einen Fehler aus:
// gibt mehrere Elemente zurück
page.getByText('Hello').element(); // ❌
page.getByText(/^Hello/).element(); // ❌
// gibt keine Elemente zurück
page.getByText('Hello USA').element(); // ❌
elements
function elements(): Element[];
Diese Methode gibt ein Array von Elementen zurück, die dem Locator-Selektor entsprechen.
Diese Funktion löst niemals einen Fehler aus. Wenn keine Elemente dem Selektor entsprechen, gibt diese Methode ein leeres Array zurück.
Betrachten Sie die folgende DOM-Struktur:
<div>Hello <span>World</span></div>
<div>Hello</div>
Diese Locators sind immer erfolgreich:
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[];
Diese Methode gibt ein Array neuer Locators zurück, die dem Selektor entsprechen.
Intern ruft diese Methode .elements
auf und umschließt jedes Element mit page.elementLocator
.