Erinnern wir uns zuerst an die vielversprechenden Erkenntnisse aus dem ersten Teil der Analyse über das Zusammenspiel von Cucumber und Playwright: Browser-spezifische Feature, das gezielte Auffinden der Elemente mit Locators, sowie das automatische Warten auf die Integrierbarkeit von Elementen sind drei Stärken von Playwright, die wir auch mit Cucumber voll ausschöpfen können. Zugleich ist auch das Reporting-System von Cucumber problemlos und wie gewünscht einsetzbar.

Leichte Differenzen

Schauen wir uns nun als erstes Playwrights Funktionen und Vorzüge genauer an, die indirekt oder direkt vom Test Runner beeinflusst sind. Wie bereits im ersten Teil unserer Analyse erläutert, nutzen wir im Zusammenspiel mit Cucumber nicht den Playwright Test Runner, womit auch das Lesen der hauseigenen playwright.config.ts Datei entfällt. In dieser werden normalerweise alle für die Runtime benötigten Konfigurationen eingestellt: Retry-Wiederholungen, Timeouts für Actions, Navigation und Assertions, Auswahl der zu laufenden Szenarios, Skip und Fail einzelner Tests, Browser-Mode und vieles mehr. Natürlich existiert auch eine Config-Datei für Cucumber, die cucumber.js, in der wir ebenfalls Runtime-Konfigurationen vornehmen können. Dennoch kommen sich hier beide Frameworks schon mal gefährlich nahe.

Debugging: Inspector

Der erste kritische Grenzfall ist das Debugging. Playwright bringt eine ganze Reihe von Debugging- und Monitoring-Möglichkeiten mit sich, die eine enorme Hilfe bei der Vermeidung von Testcode-Fehlern bzw. beim Auffinden von „echten“ Fehlern sowie bei der Erstellung von Tests sind. In erster Linie ist dies der sehr umfangreiche Inspector, der step-by-step Debugging, Untersuchen von Elementen, sowie Ausprobieren und sogar Generieren von Locators umfasst. Der Inspector wird mit dem einfachen Prefix PWDEBUG=1 auf der Kommandozeile gestartet. Der Test läuft dann automatisch im headed mode, ein separates Inspector-Fenster öffnet sich zusätzlich. Alternativ stoppt ein await page.pause(); an einer gewünschten Stelle im Code und öffnet von da an auch den Inspector und damit den Debugging-Mode. Ist die Default-Einstellung in diesem Falle nicht auf
headed eingestellt, muss das --headed flag zum Teststart auf der Kommandozeile hinzugefügt werden.

Mit dem Inspector kann man nun schrittweise durch den Test gehen, dabei Code und die Aktion auf der GUI gleichzeitig anschauen. Dies funktioniert auch mit Cucumber einwandfrei. Aber Achtung beim Timing: Wird der Inspector mit der Variable PWDEBUG gestartet, setzt Playwright automatisch das Timeout auf „0“ (was z.B. bei page.pause() nicht der Fall ist), um ein zeitlich uneingeschränktes Inspizieren zu erlauben. Da wir aber in der Cucumber-Welt ebenfalls ein
Default-Timeout gesetzt haben, greift dieses nun trotzdem, da es nicht durch Playwright überlagert werden kann. Die Lösung ist, entweder das Cucumber-Timeout stark hochzusetzen oder für den Debug-Fall manuell komplett auszuschalten.

Eine weitere Funktion des Inspectors ist das Record: In diesem Modus zeichnet Playwright manuell ausgeführte Aktionen auf und generiert zeitgleich Code dafür. Dieser kann dann einfach per Copy-and-paste ins eigene Repo übertragen werden. Diese Funktion ist im Setup mit Cucumber problemlos nutzbar und bedarf keiner weiteren Einstellung.

Debugging: Trace

Neben dem Inspector gibt es ein weiteres GUI-Hilfsmittel seitens Playwright: die Trace. Diese zeichnet alle Aktionen inklusive Snapshots in eine Datei auf, die später mit dem Trace Viewer in beliebiger Reihenfolge noch einmal angesehen werden können. Dabei zeigt das Tool sowohl den Code der jeweiligen Stelle, den Snapshot und das Log der Aktionen an sich, als auch das Log der Konsole und des Netzwerks. Mit dem Kommandozeilen-Befehl show-trace öffnet sich das Tool, unter Angabe des jeweiligen Dateinamens auch direkt an der gesuchten Stelle.

npx playwright show-trace '.\src\reports\traces\Der Benutzer wird informiert, wenn keine Ergebnisse zum Suchbegriff gefunden werden.zip'

Die schon vorbefüllte Playwright-Config händelt die Trace als Default-Einstellung. Da die Config aber nicht gelesen wird, bedarf es in unserem Setup einer zusätzlichen Konfiguration. Im Before-Step muss die Trace wie folgt gestartet werden:

e2e/src/support/common-steps.ts
Before(async function (this: ScenarioWorld, scenario){
await this.context.tracing.start({ screenshots: true, snapshots: true });
}

und im After-Step logischerweise auch wieder geschlossen:

e2e/src/support/ common-steps.ts
After(async function (this: ScenarioWorld, scenario){
await this.context.tracing.stop({ path: `path/${scenario.pickle.name}.zip`});
}

Mit diesem kleinen Eingriff können wir das Trace-Tool fortan problemlos nutzen.

Hooks

Werfen wir noch einen schnellen Blick auf Hooks und Tagging. Hooks, wie BeforeAll(), After() etc., die für unser Test-Setup wichtig sind, können auf der Ebene des Test Runners sowohl bei Cucumber als auch bei Playwright gesetzt werden. Da wir den Cucumber Test Runner benutzen, nehmen wir die entsprechenden Hooks von Cucumber.js, ohne einen Nachteil dabei zu finden.

Tags

Bezüglich des Taggings sieht es so aus, dass Playwright grundsätzlich ein eigenes System anbietet. Einerseits lassen sich über den Namen des Files oder des Tests selbst gezielt einzelne oder mehrere Tests anstoßen:

npx playwright test $filename

Andererseits bietet Playwright hierfür auch eine Art Schlagwortsuche an:

npx playwright test --grep „Suchbegriff“

Diese Möglichkeiten stehen uns nur zur Verfügung, wenn wir auch den Playwright Test Runner benutzen. In unserem Falle greifen wir daher auf das Tagging-System von Cucumber zurück. Dafür legen wir in der cucumber.js fest, welche Tags angesteuert werden sollen und versehen unsere Tests im Gherkin-File dann mit einer entsprechenden Annotation, wie „@Beispiel“.

Ausblick

Auch wenn Playwright und Cucumber an einigen Stellen um die Vorherrschaft zu buhlen scheinen, vertragen sich beide Tools dennoch gut und lassen mit wenig Aufwand eine effiziente Lösung zu. Im letzten Teil unserer Analyse gehen wir aber richtig ins Eingemachte und durchleuchten diverse mögliche Schwachstellen in der Zusammenarbeit.