Playwright Locators
Ein Locator ist eines der Kernkonzepte in Playwright. Er stellt eine Möglichkeit dar, Elemente auf einer Seite zu finden.
Dieses Kapitel stellt die von Playwright empfohlenen Lokalisierungsmethoden vor: Lokalisierung von Elementen nach Rolle, Text, Label und Platzhalter.
Was ist ein Locator
Ein Locator ist ein abstraktes Objekt, das Playwright verwendet, um Elemente auf einer Seite zu finden.
Im Gegensatz zu traditionellendocument.querySelector()In vielerlei Hinsicht hat der Locator von Playwrightautomatisches Warten und automatisches WiederholenFähigkeiten.
Wenn sich der Seiteninhalt dynamisch ändert, sucht der Locator kontinuierlich nach Elementen, bis er ein passendes Element findet oder ein Timeout auftritt.
Beispiel
const button = page.getByRole('button', { name: 'Submit' });
// Wenn eine Aktion ausgeführt wird, wartet Playwright automatisch darauf, dass die Schaltfläche erscheint und interagierbar wird.
await button.click();
Wie Locators funktionieren
Wenn du einen Locator erstellst, zeichnet Playwright nur eine Suchregel auf.
Wenn Sie.click()、.fill()Aktionen oderexpect(locator)Assertions aufrufen, beginnt der Locator tatsächlich, Elemente zu finden.
Wenn das Element nicht gefunden werden kann, wird der Locator weiterhin versuchen, bis für den Vorgang ein Timeout eintritt.
Lokalisieren nach Rolle: getByRole()
getByRole()ist die von Playwright am meisten empfohlene Lokalisierungsmethode.
Es verwendet dieBarrierefreiheitsrolle (ARIA Role)des Elements, um Elemente zu finden, was der Art und Weise, wie Benutzer sie wahrnehmen, am nächsten kommt.
Grundlegende Verwendung
Beispiel
const submitBtn = page.getByRole('button', { name: 'Submit' });
await submitBtn.click();
// Einen Link anhand der Rolle "link" lokalisieren
const homeLink = page.getByRole('link', { name: 'Startseite' });
await homeLink.click();
// Eine Überschrift anhand der Rolle "heading" suchen
const mainTitle = page.getByRole('heading', { name: 'Willkommen bei EXAMPLE' });
// Ein Textfeld anhand der Rolle "textbox" suchen
const searchBox = page.getByRole('textbox', { name: 'Suche' });
await searchBox.fill('Playwright');
Häufige ARIA-Rollen
| Rolle | Entsprechende HTML-Elemente | Anwendungsbeispiel |
|---|---|---|
'button' | <button>、role="button" | getByRole('button', { name: '登录' }) |
'link' | <a> | getByRole('link', { name: '了解更多' }) |
'heading' | <h1>~<h6> | getByRole('heading', { name: 'EXAMPLE 教程' }) |
'textbox' | <input type="text">、<textarea> | getByRole('textbox', { name: '用户名' }) |
'checkbox' | <input type="checkbox"> | getByRole('checkbox', { name: '记住我' }) |
'radio' | <input type="radio"> | getByRole('radio', { name: '男' }) |
'combobox' | <select> | getByRole('combobox', { name: '城市' }) |
'img' | <img> | getByRole('img', { name: 'Logo' }) |
'list' | <ul>、<ol> | getByRole('list') |
'listitem' | <li> | getByRole('listitem') |
'navigation' | <nav> | getByRole('navigation') |
'table' | <table> | getByRole('table') |
Die Option „name“
nameDie Option verwendet denzugänglichen Namendes Elements, um den Bereich einzugrenzen.
Zu den Quellen des zugänglichen Namens gehören: der Textinhalt des Elements,aria-labelAttribute, zugehörig<label>usw.
Beispiel
page.getByRole('button', { name: 'Login' });
// Nach aria-label abgleichen
page.getByRole('button', { name: 'Close dialog' });
// Abgleich mit regulärem Ausdruck
page.getByRole('link', { name: /EXAMPLE|rookie/ });
Zustandsoptionen
Zusätzlich zuname,getByRoleunterstützt es außerdem mehrere Zustandsoptionen:
Beispiel
page.getByRole('checkbox', { checked: true });
// Den deaktivierten Button lokalisieren
page.getByRole('button', { disabled: true });
// Das erweiterte Dropdown-Menü lokalisieren
page.getByRole('button', { expanded: true });
// Die ausgewählte Option lokalisieren
page.getByRole('option', { selected: true });
// Mehrere Zustände kombinieren
page.getByRole('checkbox', { name: 'Agree to the terms', checked: false });
Lokalisierung nach Text: getByText()
getByText()Anhand desTextinhaltsdes Elements lokalisieren.
Beispiel
page.getByText('Welcome to EXAMPLE');
// Teilweise Übereinstimmung (Standard)
page.getByText('EXAMPLE');
// Exakte Übereinstimmung erzwingen
page.getByText('EXAMPLE', { exact: true });
// Übereinstimmung mit regulärem Ausdruck
page.getByText(/EXAMPLE|rookie tutorial/);
getByTextEs stimmt mit dem vollständigen Textinhalt des Elements überein, dahergetByText('EXAMPLE', { exact: true })stimmt es nur mit Elementen überein, deren Textinhalt genau "EXAMPLE" ist.
Standardmäßig, wenn keine exakte Übereinstimmung verwendet wird, ist eine Teilstring-Übereinstimmung ausreichend (zum Beispiel,getByText('EXAMPLE')wird es mit "Welcome to EXAMPLE" übereinstimmen).
Auffinden anhand von Label: getByLabel()
getByLabel()Wird verwendet zum Auffinden<label>zugehöriger Formularelemente.
Beispiel
// <label for="username">Username</label>
// <input id="username" type="text" />
// Das Eingabefeld über den Labeltext lokalisieren
await page.getByLabel('Username').fill('example_user');
// HTML-Struktur:
// <label>Password <input type="password" /></label>
// Verschachtelte Labels sind ebenfalls gültig
await page.getByLabel('Password').fill('password123');
Es unterstützt außerdem{ exact: true }Optionen für exakte Übereinstimmung.
Auffinden anhand des Platzhalters: getByPlaceholder()
getByPlaceholder()Durch dieplaceholderplaceholder-Attribut, um Eingabefelder zu lokalisieren.
Beispiel
await page.getByPlaceholder('Please enter a search keyword').fill('Playwright');
// HTML-Struktur: <textarea placeholder="Tell us what you think..."></textarea>
await page.getByPlaceholder('Tell us what you think...').fill('The EXAMPLE tutorial is great!');
Auswahl zwischen getByLabel und getByPlaceholder
| Methode | Anwendungsszenario | Priorität |
|---|---|---|
getByLabel() | Wenn ein <label>-Element vorhanden ist | Zuerst verwenden |
getByPlaceholder() | Wenn kein Label vorhanden ist, aber ein Placeholder existiert | Zweite Wahl |
getByRoleist die von Playwright am meisten empfohlene Lokalisierungsmethode, da sie simuliert, wie Benutzer Elemente anhand ihrer Rolle identifizieren. Als Nächstes folgengetByLabelundgetByPlaceholder. Ziehen Sie es nur in Betracht, wenn keine semantischen Elemente vorhanden sind.getByTestIdoder CSS-Selektoren.
getByAltText() zur Bildlokalisierung
getByAltText()Durch dasaltalt-Attribut des Bildes zum Auffinden<img>des <img>-Elements.
Beispiel
await expect(page.getByAltText('EXAMPLE Logo')).toBeVisible();
// Übereinstimmung mit regulärem Ausdruck
await expect(page.getByAltText(/logo/i)).toBeVisible();
getByTitle() zum Auffinden über das title-Attribut
getByTitle()Durch dastitletitle-Attribut des Elements zum Auffinden.
Beispiel
await page.getByTitle('Close current page').click();
getByAltTextundgetByTitleWird seltener verwendet; nur wenn das Element ein explizites alt- oder title-Attribut hat und nicht auf andere Weise lokalisiert werden kann.
getByTestId
getByTestId()JaFallback-Lösung, überdata-testidAttribut, um das Element zu lokalisieren.
Beispiel
await page.getByTestId('submit-btn').click();
// Kann mehrere Übereinstimmungen enthalten (z. B. Listenelemente)
const items = page.getByTestId('todo-item');
await expect(items).toHaveCount(3);
Anpassen des testId-Attributs
Wenn Ihr Projekt nicht verwendetdata-testid, können Sieplaywright.config.tsPassen Sie den Attributnamen an in:
Beispiel
export default defineConfig({
Verwenden Sie: {
// data-cy statt data-testid verwenden (für Cypress-Migration)
testIdAttribute: 'data-cy',
// Oder id als testId verwenden
// testIdAttribute: 'id',
},
});
page.locator() CSS- und XPath-Lokalisierung
page.locator()Unterstützt CSS-Selektoren und XPath und dient als flexiblerer Fallback.
CSS-Selektoren
Beispiel
await page.locator('.submit-btn').click();
// Nach ID
await page.locator('#username').fill('example_user');
// Nach Attribut
await page.locator('[data-type="primary"]').click();
// Nach Tag- + Klassen-Kombination
await page.locator('button.primary').click();
// Nach Eltern-Kind-Beziehung
await page.locator('nav a').first().click();
// CSS-Selektor, der bestimmten Text enthält
await page.locator('button:has-text("Submit")').click();
XPath-Lokalisierung
Beispiel
await page.locator('xpath=//button[@type="submit"]').click();
// Nach Text lokalisieren
await page.locator('xpath=//h1[contains(text(), "EXAMPLE")]').click();
CSS-Selektoren und XPath sind das letzte Mittel; priorisiere die Verwendung von
getByRole、getByTextSemantische Lokalisierungsmethoden. CSS-Selektoren neigen dazu, durch Style-Refactoring zu brechen, und XPath ist schlecht lesbar und langsamer.
Locator-Verkettung
Der Locator von Playwright unterstützt Verkettung, wodurch die aktuellen Treffer weiter gefiltert werden können.
.first()、.last()、.nth()
Beispiel
const firstItem = page.getByRole('listitem').first();
// Letztes abrufen
const lastItem = page.getByRole('listitem').last();
// Das zweite abrufen (Index beginnt bei 0)
const secondItem = page.getByRole('listitem').nth(1);
.filter() Filterung
Beispiel
page.getByRole('button').filter({ hasText: 'Save' });
// Diejenigen herausfiltern, die keinen bestimmten Text enthalten
page.getByRole('listitem').filter({ hasNotText: 'Deleted' });
// Diejenigen filtern, die ein bestimmtes untergeordnetes Element enthalten
page.getByRole('listitem').filter({ has: page.getByRole('button') });
// Diejenigen filtern, die kein bestimmtes untergeordnetes Element enthalten
page.getByRole('listitem').filter({ hasNot: page.getByTestId('badge') });
.locator() zum Lokalisieren von untergeordneten Elementen
Beispiel
const list = page.getByTestId('todo-list');
const deleteBtn = list.locator('button.delete');
await deleteBtn.click();
// Mehrstufige Verschachtelung
page
.getByRole('dialog')
.locator('div.content')
.locator('button')
.filter({ hasText: 'Confirm' })
.click();
.and() und .or() Logische Kombinationen (1.63+)
Beispiel
const btn = page.getByRole('button')
.und(page.getByText('Submit'));
// Eine der beiden Bedingungen erfüllen
const target = page.getByText('EXAMPLE')
.oder(page.getByTitle('EXAMPLE'));
Zusammenfassung der Priorität der Locator-Strategie
Geordnet von der höchsten zur niedrigsten Empfehlung:
| Priorität | Methode | Verwendungsbedingung |
|---|---|---|
| 1 (Am meisten empfohlen) | getByRole() | Element hat eine klare ARIA-Rolle |
| 2 | getByLabel() | Formularelement hat ein zugehöriges Label |
| 3 | getByPlaceholder() | Eingabefeld hat einen Platzhalter |
| 4 | getByText() | Element hat klaren Textinhalt |
| 5 | getByAltText() | Bild hat alt-Attribut |
| 6 | getByTitle() | Element hat title-Attribut |
| 7 (Fallback) | getByTestId() | Wenn die Lokalisierung mit den oben genannten Methoden nicht möglich ist |
| 8 (Letzter Ausweg) | locator() | CSS-Selektoren / XPath |