Playwright Java Test Writer
Wandeln Sie manuelle Testfälle in wartbare Playwright-Java-Tests um, die aussehen, als wären sie von jemandem geschrieben, der das Framework beherrscht: parallel-sicher, keine flaky Sleeps, Page Objects, die Locators kapseln, und Allure-Berichte, die bis zu den ursprünglichen Testfall-IDs zurückverfolgbar sind.
Arbeitsablauf
1. Manuelle Testfälle parsen
Extrahieren Sie für jeden Fall: ID, Titel, Priorität/Schweregrad, Vorbedingungen, Testdaten, Schritte, erwartetes Ergebnis pro Schritt. Die Eingaben variieren (Excel-Zeilen, Jira-Exporte, Gherkin, Freitext), also normalisieren Sie sie in diese Form, bevor Sie Code schreiben.
Wenn ein Fall so nicht automatisierbar ist (benötigt OTP von einem echten Telefon, visuelle Beurteilung wie „sieht korrekt aus“, Zahlung mit echtem Geld über Drittanbieter), täuschen Sie ihn nicht vor. Listen Sie ihn unter Nicht automatisiert in der Ausgabe auf, mit Begründung und einem Vorschlag (API mocken, Test-OTP verwenden, visuellen Snapshot-Vergleich durchführen).
2. Zuerst vorhandene Framework-Konventionen erkennen
Wenn der Benutzer Repo-Dateien teilt (BaseTest, eine Page-Klasse, testng.xml, pom.xml), spiegeln Sie diese exakt wider: Paketnamen, Basisklassennamen, Namenskonvention, Assertion-Stil, Konfigurationseinlesung. Konsistenz mit ihrer Codebasis hat Vorrang vor dem untenstehenden Referenzstil.
Wenn nichts geteilt wird, verwenden Sie das Gerüst aus references/framework-scaffold.md. Generieren Sie die Gerüstdateien (BaseTest, PlaywrightFactory, BasePage, Config) nur, wenn der Benutzer explizit nach einem Framework fragt oder offensichtlich keines hat; andernfalls nehmen Sie an, dass sie existieren, und generieren Sie nur Page Objects und Tests.
3. Page Objects entwerfen
- Eine Klasse pro Seite oder wiederverwendbaren Komponente (Header, Warenkorb-Bereich, Filterpanel). Komponenten erhalten eine eigene Klasse und werden in Seiten eingebunden.
- Locators sind
private final Locator-Felder, die im Konstruktor initialisiert werden. Tests rufen niemals direktpage.locator(...)auf. - Seitenmethoden beschreiben die Benutzerabsicht (
login(user, pass),addToCart(productName)), nicht die Mechanik (clickButton2). Versehen Sie sie mit Allure@Step("...")unter Verwendung von Parameterplatzhaltern, sodass der Bericht wie der manuelle Fallaussieht. - Aktionen, die navigieren, geben das nächste Page Object zurück (fließender Ablauf). Methoden, die auf der Seite bleiben, geben
thisoder void zurück. - Verwenden Sie vorhandene Seitenmethoden wieder, bevor Sie neue hinzufügen. Wenn zwei Schritte dieselbe Absicht abbilden, verwenden Sie eine Methode.
- Machen Sie Zustände für Assertionen über absichtsbenannte Getter zugänglich, die
Locatorzurückgeben (z. B.errorMessage()), sodass Tests Web-First-Assertions verwenden können.
Locator-Priorität (vom stabilsten zum am wenigsten stabilen):
getByTestId(konfigurieren Sie den Attributnamen einmal, wenn die Appdata-test,data-qausw. verwendet)getByRolemit zugänglichem NamengetByLabel/getByPlaceholder/getByTextfür sichtbaren Text- CSS auf stabilen Attributen
- XPath, nur als letztes Mittel, mit einem Kommentar, der den Grund angibt
Wenn der Benutzer kein DOM, HTML oder Screenshots bereitstellt, raten Sie Locators. Schreiben Sie die beste Schätzung und markieren Sie sie mit // TODO-VERIFY locator, damit nichts mit erfundenen Selektoren unentdeckt bleibt. Erwähnen Sie die Anzahl der nicht verifizierten Locators in der Zusammenfassung.
4. Tests schreiben
- Eine
@Test-Methode pro manuellem Fall. Methodenname = Verhalten (shouldShowErrorForLockedUser), nicht die ID. - Rückverfolgbarkeit: Setzen Sie die Fall-ID in
@TmsLink("TC-012")und indescription. Fügen Sie@Epic,@Feature,@Story,@Severityhinzu, abgebildet von der Priorität des Falls (P0/Kritisch →BLOCKER/CRITICAL, P1 →NORMAL, P2+ →MINOR). - Jedes erwartete Ergebnis wird zu einer Assertion. Ein Schritt ohne Assertion bedeutet, dass die manuelle Prüfung entfallen ist – überprüfen Sie daher vor dem Abschluss.
- Vorbedingungen gehen in Setup-Helfer oder API-Aufrufe, nicht in lange UI-Klickketten, wenn eine API oder ein Deep Link existiert. Für Login-Vorbedingungen (insbesondere OTP/SSO) bevorzugen Sie einen API-Login einmalig und verwenden Sie ihn über
context.storageState()/Browser.NewContextOptions().setStorageStatePath(...)wieder. - Wiederholte Fälle mit unterschiedlichen Daten → ein Test mit einem TestNG
@DataProvider.@TmsLinkist statisch, also übergeben Sie die Fall-ID als erste Datenspalte und rufen SieAllure.link(caseId, "tms", caseId)innerhalb des Tests auf, um die Rückverfolgbarkeit pro Zeile zu behalten. Halten Sie Testdaten aus dem Testkörper heraus (Data Provider, JSON, oder Constants-Klasse). Niemals echte Kundendaten. - Tests müssen unabhängig sein: keine Abhängigkeit von der Ausführungsreihenfolge, frischer Kontext pro Test, Aufräumen aller erstellten Ressourcen.
5. Wartezeiten: nur konditionsbasiert
Dies ist die Hauptursache für Flakiness, also behandeln Sie es als harte Regel:
- Verwenden Sie niemals
Thread.sleepoderpage.waitForTimeout. - Bevorzugen Sie Web-First-Assertions:
assertThat(locator).isVisible(),hasText,hasCount,assertThat(page).hasURL(...). Sie wiederholen sich automatisch. - Aktionen warten bereits automatisch auf die Ausführbarkeit; fügen Sie keine redundanten Wartezeiten vor
click()/fill()hinzu. - Wenn eine Aktion einen Netzwerkaufruf auslöst, dessen Ergebnis wichtig ist, umschließen Sie ihn:
page.waitForResponse(r -> r.url().contains("/cart") && r.ok(), () -> addButton.click()). - Für Spinner/Ladeanzeigen:
assertThat(loader).isHidden(). - Für Navigation:
page.waitForURL("**/checkout**"). - Benutzerdefinierte Timeouts stammen aus der Konfiguration, niemals als magische Zahlen inline.
Siehe references/framework-scaffold.md → "Wait patterns" für Code-Snippets.
6. Parallelitätssicherheit
Alle Playwright-Objekte (Playwright, Browser, BrowserContext, Page) leben in ThreadLocals, die von der Basisklasse/Fabrik verwaltet werden und pro Testmethode erstellt und geschlossen werden. Speichern Sie sie niemals in statischen Feldern oder teilen Sie eine Page zwischen Tests. Page Objects erhalten die Page über den Konstruktor. Statischer Zustand in Page Objects ist nicht erlaubt.
Ausgabeformat
Antworten Sie in dieser Reihenfolge:
- Dateien: jede Datei in einem eigenen Codeblock mit vollständigem Pfad als Überschrift (z. B.
src/test/java/com/example/pages/LoginPage.java). Vollständige, kompilierbare Dateien mit Imports, keine Fragmente, es sei denn, der Benutzer hat nach einem Snippet gefragt. Wenn mehr als ~3 Dateien oder der Benutzer sie herunterladen möchte, schreiben Sie sie auch als Projektordner auf die Festplatte. - Rückverfolgbarkeitstabelle:
Fall-ID | Testmethode | Automatisierte Schritte | Anmerkungen. - Nicht automatisiert / Lücken: Fälle oder Schritte, die übersprungen wurden, und warum.
- Überprüfung erforderlich: Anzahl und Liste der
TODO-VERIFY-Locators, Annahmen über Testdaten oder Umgebung.
Halten Sie den Fließtext kurz; der Code ist das Lieferobjekt.
Vertraulichkeit
Wenn der Benutzer ein öffentliches Portfolio aufbaut oder die Anfrage eine öffentliche Demo-App erwähnt, halten Sie alles generisch: Paket com.example (oder was angegeben wird), keine Firmennamen, internen URLs, internen Endpunkte, echten Benutzerdaten oder proprietären Ereignisnamen. Wenn eingefügte manuelle Testfälle solche enthalten, tauschen Sie sie gegen neutrale Äquivalente aus und erwähnen Sie dies in einer Zeile.
Referenzdateien
references/framework-scaffold.md: pom.xml-Abhängigkeiten, PlaywrightFactory mit ThreadLocals, BaseTest mit Tracing und Allure-Anhängen bei Fehlern, BasePage, ConfigReader, testng.xml für parallele Ausführung, Wartezeit-Snippets. Lesen Sie es beim Erstellen des Gerüsts oder wenn Sie die genaue API-Struktur benötigen.references/example-saucedemo.md: ein vollständiges Beispiel (manuelle Testfälle → Page Objects → Tests → Rückverfolgbarkeitstabelle) für die öffentliche App saucedemo.com. Lesen Sie es, um den Ausgabestil zu kalibrieren.