JetBase Logo
Banner

Das Wichtigste in Kürze

Eine Migration von Cypress zu Playwright muss kein risikoreicher Neuschreibungsprozess werden. Auf einer Gesundheitsplattform wurden 148 E2E-Tests schrittweise migriert, während Cypress aktiv in der CI blieb und die Release-Abdeckung während des gesamten Übergangs aufrechterhielt. GitHub Copilot reduzierte die wiederholte Konvertierungsarbeit um 70–80 %, aber eine sichere Migration erforderte dennoch eine menschliche Überprüfung, isolierte Framework-Konfigurationen und die Validierung Datei für Datei.

• Erstellen Sie den Playwright-Prototyp in 1–2 Tagen.
• Führen Sie beide Frameworks aus, bis jede Suite stabil ist.
• Migrieren Sie unterstützende Dateien vor Testdateien.
• Überprüfen Sie manuell Importe, Fixtures, Locator und Assertions.

Als wir die Anfrage erhielten, die Cypress-Tests nach Playwright zu migrieren, erwarteten wir einen langen, mühsamen Umschreibungsprozess.

Überraschenderweise gelang es uns mit Hilfe von GitHub Copilot, die Migration von Cypress zu Playwright in nur wenigen Tagen zu starten — und unseren CI-Pipeline die ganze Zeit über ohne Unterbrechung der Testprozesse am Laufen zu halten.

In diesem Artikel werde ich teilen, wie wir diese Migration angegangen sind, welche Lektionen wir auf dem Weg gelernt haben und wie KI-unterstützte Code-Migration den manuellen Aufwand bei Rahmenübergängen drastisch reduzieren kann.

1

Projektkontext

Das Projekt war eine komplexe Gesundheitsplattform mit viel im Hintergrund. Unsere Testkonfiguration umfasste:

  • End-to-End- (E2E) und Integrationstests
  • Eine benutzerdefinierte TAF-Architektur mit Setups, Teardowns und Entitätskreation
  • Multi-Umgebungs-Konfigurationen
  • Dynamische Daten und tiefe Navigationslogik

Insgesamt hatten wir 148 E2E-Tests, die auf Cypress liefen — alle funktionierten einwandfrei, aber die Organisation wollte die QA-Tools über die Teams hinweg standardisieren, was nur eines bedeutete: Migration zu Playwright.

2

Warum GitHub Copilot für die Migration verwenden?

Als die Migrationsanfrage eintraf, sah ich die Gelegenheit, mit GitHub Copilot zur Testautomatisierung zu experimentieren. Anstatt Hunderte von Testdateien manuell umzuschreiben, wollte ich sehen, wie weit wir die KI-Unterstützung nutzen konnten, um die Syntaxkonvertierung von Cypress nach Playwright zu automatisieren.

Und ehrlich gesagt, es hat viel besser funktioniert als erwartet.

GitHub Copilot übernahm die meisten wiederholenden Übersetzungen (Auswähler, Befehle, asynchrone Verarbeitung usw.), sodass wir uns auf Infrastruktur-Anpassungen und Feinabstimmungen konzentrieren konnten.

Innerhalb von 1–2 Tagen hatten wir bereits einen funktionierenden Prototyp des Playwright-Testautomatisierungsrahmens.

3

Zwei wichtige Hinweise

Überprüfen Sie immer den von der KI generierten Code

Auch wenn die KI-unterstützte Code-Migration die Dinge beschleunigt, müssen Sie jede Zeile überprüfen. Infrastruktur-Migrationen können leicht subtile Fehler oder Leistungsverschlechterungen einführen. Denken Sie an Copilot als Ihren Programmierpartner, nicht als Autopilot.

Behalten Sie das alte Framework bis zum Ende in Betrieb

Blockieren Sie niemals Releases oder Regressionen während der Migration. Lassen Sie Ihre Cypress-Tests im CI weiterlaufen, bis die entsprechenden Suiten vollständig stabil in Playwright sind. Sobald eine Suite migriert und validiert ist, entfernen Sie sie aus Cypress und schalten Sie das CI um, um sie in Playwright auszuführen.

Diese schrittweise Einführung gewährleistet null Ausfallzeiten und kontinuierliche Testabdeckung während des gesamten Prozesses.

4

Workflow zur Migration von Cypress nach Playwright

Sobald die Grundlagen klar waren, gingen wir in die praktische Migration über.  
Im Folgenden ist der Workflow aufgeführt, der uns half, beide Rahmen parallel auszuführen, die CI-Stabilität aufrechtzuerhalten und Tests schrittweise zu migrieren — ohne laufende Releases zu blockieren.

1. Playwright initialisieren und die Ordnerstruktur erstellen

Der erste Schritt bestand darin, Playwright zu initialisieren und eine saubere, isolierte Ordnerstruktur zu erstellen.

Wir wollten, dass beide Frameworks nebeneinander im selben Repository leben, damit wir sie während der Übergangsphase gleichzeitig ausführen konnten.

Diese Einrichtung ermöglichte es uns:

  • Allmähliche Migration
  • Ergebnisse und Zeitmessungen zwischen Cypress und Playwright zu vergleichen
  • CI-Pipelines für beide am Laufen zu halten

Beispiel zur Initialisierung:

Beispiel zur Initialisierung.webp

Hier ist die vorgeschlagene Ordnerstruktur, die wir für Playwright verwendet haben:

├── cypress/
│   ├── app/
│   ├── downloads/
│   ├── e2e/
│   ├── fixtures/
│   ├── screenshots/
│   ├── support/
│   └── videos/
├── playwright/
│ 	├── app/
│	│   ├── components/
│	│   ├── fixtures/
│	│   └── pageobjects/
│   ├── constants/
│   ├── helpers/
│   ├── reports/
│   ├── test-results/
│   └── tests/
├── .gitignore
├── package.json
├── playwright.config.ts
├── smoke.config.ts
├── tsconfig.json

2. Konfigurieren Sie separate tsconfig-Dateien für jedes Framework

Ein frühes Problem, mit dem wir konfrontiert waren, waren TypScript-Konflikte — beide Frameworks definieren ähnliche Methodennamen (expect, request usw.), und die gemeinsame Nutzung einer einzigen tsconfig.json führte zu Kompilierungsfehlern.

Die Lösung war einfach: Teilen Sie die TypeScript-Konfigurationen. Diese Struktur sorgt dafür, dass jedes Framework seine eigenen Typdefinitionen initialisiert und Typenkollisionen vermeidet:

├── tsconfig.json
├── tsconfig.cypress.json
├── tsconfig.playwright.json

Haupt tsconfig.json
Fügen Sie die Option composite hinzu, um Projektverweise zu unterstützen.

tsconfig.json

{
  "compilerOptions": {
    "composite": true
  }
}

tsconfig.cypress.json

{
  "extends": ".‌/tsconfig.json",
  "compilerOptions": {
    "types": ["cypress", "@testing-library/cypress", "node"],
    "isolatedModules": false
  },
  "include": ["cypress/**/*.ts"]
}

tsconfig.playwright.json

{
  "extends": ".‌/tsconfig.json",
  "compilerOptions": {
    "types": ["node", "@playwright/test"]
  },
  "include": ["playwright/**/*.ts", "playwright.config.ts"]
}

Mit dieser Trennung konnten beide Frameworks friedlich in einem Repository coexistieren — keine Compilerkonflikte mehr und kein Risiko, versehentlich gemeinsam genutzte Methoden zweimal zu initialisieren.

3.

Erstellen Sie eine Aufforderung zur Automatisierung der Migration mit GitHub Copilot

Sobald Playwright initialisiert und das Projekt strukturiert war, war es an der Zeit, GitHub Copilot bei der schweren Arbeit zu helfen.

Dazu haben wir eine benutzerdefinierte Aufforderung erstellt, die definiert, wie Copilot sich verhalten soll, wenn Tests von Cypress zu Playwright umgeschrieben werden. Die Aufforderung sagt dem Agenten, was zu tun ist, wie es zu tun ist und was ignoriert werden soll — und sorgt so für konsistente Ergebnisse bei allen Migrationen.

So fügen Sie die Aufforderung hinzu

Öffnen Sie in Ihrem GitHub-Repository das Zahnrad-Symbol ⚙️ im Copilot-Chat und erstellen Sie eine neue Aufforderung.  
Die Datei wird automatisch unter gespeichert: ./github/prompts/

Sie können sie beispielsweise migrate_tests.md nennen.

Beispiel für die Aufforderung:

---
mode: agent
---
You are a Playwright Test Generator, an expert in browser automation and end-to-end testing.
Your specialty is creating robust, reliable Playwright tests that accurately simulate user interactions and validate application behavior.
Your task is to help migrate existing Cypress tests to Playwright tests.
The Cypress tests, page object, components, and helper files are provided as input, and you need to generate equivalent Playwright test code.
Output ALL migrated code to the chat.
When generating the Playwright test code or any page objects, ensure that:
1. The test structure follows the same structure as the Cypress tests.
2. Create a global fixture for setup and teardown and reuse it in the tests.
3. All user interactions (clicks, typing, navigation) are accurately translated to Playwright syntax in page objects and test files.
4. Assertions in Cypress are converted to equivalent Playwright assertions.
5. Ignore the network spying and stubbing parts of the Cypress tests.
6. Comment out all the methods with waits (e.g., cy.wait) in the Playwright code.
7. Do not use get methods in page objects; use direct methods instead `backbackItem = () => this.page.locator('[id="item_4_title_link"]');`

Warum das hilft

Diese Art von strukturierter Aufforderung ermöglicht es GitHub Copilot, sich eher wie ein spezialisierter Migrationsassistent zu verhalten und nicht wie ein generischer Code-Generator.

Mit dem richtigen Kontext und den Regeln kann Copilot automatisch:

  • Große Teile von Cypress-Tests in Playwright-Syntax umschreiben
  • Ordner- und Teststruktur konsistent halten 
  • Die manuelle Umwandlungszeit um 70–80 % reduzieren

Im Wesentlichen erstellen Sie Ihre eigene KI-Migrationswerkzeugkette — maßgeschneidert für die Struktur und Konventionen Ihres Projekts.

4. Wählen Sie den Agentenmodus und führen Sie die Migration Schritt für Schritt durch

Sobald die Aufforderung bereit war, bestand der nächste Schritt darin, die Migration tatsächlich im Agentenmodus mit GitHub Copilot durchzuführen. In dieser Phase ließ der AI-Modell jedes Datei — Page Objects, Komponenten, Helfer und schließlich die Tests — eins nach dem anderen verarbeiten.

Für diese Aufgabe haben wir das Modell GPT-4.1 verwendet, das die konsistentesten und kontextbewusstesten Code-Transformationen liefert.

So starten Sie die Migration

1. Öffnen Sie Copilot Chat in VS Code

2. Verwenden Sie /, um die zuvor erstellte Eingabedatei auszuwählen

3. Verwenden Sie #, um eine bestimmte Datei auszuwählen (zum Beispiel einen Cypress-Test oder ein Seitenobjekt), das Sie migrieren möchten

Copilot wird nun Ihre Migrationsaufforderung anwenden und eine Playwright-kompatible Version der Datei direkt im Chat generieren.

So starten Sie die Migration.webpBeispiel für die Migration des inventoryPage Seitenobjekts

import { ItemComponent } from "..‌/components/item.component";
import Common from ".‌/common";
class InventoryPage extends Common {
  item = new ItemComponent();
  backbackItem = () => cy.get("#item_4_title_link");
  backbackAddItemButton = () => cy.getByTestId("add-to-cart-sauce-labs-backpack");
  bikeLightsAddItemButton = () => cy.getByTestId("add-to-cart-sauce-labs-bike-light");
  backbackRemoveItemButton = () => cy.getByTestId("remove-sauce-labs-backpack");
  shoppingCartLogo = () => cy.get("#shopping_cart_container");
  clickBackbackAddItemButton = () => this.backbackAddItemButton().click();
  clickBikeLightsAddItemButton = () => this.bikeLightsAddItemButton().click();
  clickBackbackRemoveItemButton = () => this.backbackRemoveItemButton().click();
  assertCartLogoItems = (itemsNum: number) => this.shoppingCartLogo().should("have.text", itemsNum);
}
export default new InventoryPage();

 

import { Page, Locator, expect } from "@playwright/test";
import Common from ".‌/common";
class InventoryPage extends Common {
  constructor(page: Page) {
    super(page);
    this.item = new ItemComponent(page);
  }
  
  // Locators
  backbackItem(): Locator {
    return this.page.locator("#item_4_title_link");
  }
  backbackAddItemButton(): Locator {
    return this.page.getByTestId("add-to-cart-sauce-labs-backpack");
  }
  bikeLightsAddItemButton(): Locator {
    return this.page.getByTestId("add-to-cart-sauce-labs-bike-light");
  }
  backbackRemoveItemButton(): Locator {
    return this.page.getByTestId("remove-sauce-labs-backpack");
  }
  shoppingCartLogo(): Locator {
    return this.page.locator("#shopping_cart_container");
  }
  // Actions
  async clickBackbackAddItemButton(): Promise<void> {
    await this.backbackAddItemButton().click();
  }
  async clickBikeLightsAddItemButton(): Promise<void> {
    await this.bikeLightsAddItemButton().

Verhalten des Agents anpassen

Keine Sorge, wenn die erste Ausgabe nicht perfekt ist. Aus unserer Erfahrung erzielt der KI-Agent normalerweise 60–70 % des Codes beim ersten Versuch richtig. Der Schlüssel ist, den Gesprächskontext aktiv zu halten — fahren Sie fort, den gleichen Chatverlauf zu verfeinern, indem Sie nach Korrekturen oder Anpassungen fragen. Während Sie dies tun, beginnt Copilot, Ihre Projektmuster zu lernen und produziert genaueren, wiederverwendbaren Code.

Im Wesentlichen wird die Qualität der Migration umso besser, je mehr Iterationen Sie im gleichen Chat durchführen.

Migrationsreihenfolge: Zuerst Dateien, dann Tests

Um Abhängigkeiten konsistent zu halten und fehlende Referenzen zu vermeiden, befolgen Sie diese Reihenfolge:

1. Generieren Sie zuerst Nicht-Testdateien:

  • Seitenobjekte
  • Komponenten
  • Hilfsdateien
  • Konstanten

2. Sobald alle unterstützenden Dateien generiert und überprüft sind, fügen Sie den #app-Ordner zum Chatkontext hinzu und migrieren Sie dann die Testdateien selbst.

Überprüfungsschritt

Wenn ein Playwright-Test generiert wird:

1. Überprüfen Sie den Code — bestätigen Sie, dass die Seitenlokatoren, Testschritte und Assertions korrekt sind.

2. Führen Sie den Test mit Ihrer Playwright-CLI aus, um sicherzustellen, dass er ordnungsgemäß ausgeführt wird.

3. Beheben Sie kleinere Syntax- oder Fixture-Unstimmigkeiten, falls Copilot einen Cypress-Befehl missverstanden hat.

Durch die Überprüfung nach jeder Datei halten Sie die Migration stabil und schrittweise, um später großflächige Debugging zu vermeiden.

Beispiel eines migrierten inventoryPage-Tests, der erfolgreich besteht:

import inventoryPage from "cypress/app/pageobjects/inventoryPage";
import loginPage from "cypress/app/pageobjects/loginPage";
import { itemsNames } from "../..‌/fixtures/data.json";
describe("InventoryPage tests", () => {
  beforeEach(() => {
    loginPage.loginWithValidData();
  });
  it("Der Benutzer sollte einen Artikel in den Warenkorb legen", () => {
    inventoryPage.item.itemByName("Bike Light").should("have.text", itemsNames.bikeLight);
    inventoryPage.item.addToCartByName("Bike Light");
    inventoryPage.assertCartLogoItems(1);
  });
  it("Der Benutzer sollte einen Artikel aus dem Warenkorb entfernen", () => {
    inventoryPage.backbackItem().should("have.text", itemsNames.backpackItemName);
    inventoryPage.clickBackbackAddItemButton();
    inventoryPage.assertCartLogoItems(1);
    inventoryPage.clickBackbackRemoveItemButton();
    inventoryPage.shoppingCartLogo().should("not.have.text");
  });
  it("Der Benutzer sollte mehrere Artikel in den Warenkorb legen", () => {
    inventoryPage.`backbackItem().should("have.text", itemsNames.backpackItemName);  
inventoryPage.clickBackbackAddItemButton();  
inventoryPage.assertCartLogoItems(1);  
inventoryPage.clickBikeLightsAddItemButton();  
inventoryPage.assertCartLogoItems(2);  
});  
});`

### 5. Endgültige Repository-Struktur nach der Migration  
Nachdem die Migration abgeschlossen war, erreichte unser Repository einen stabilen Zustand mit zwei Frameworks — vollständig funktionierend mit sowohl Cypress als auch Playwright nebeneinander. Diese Struktur erlaubte es uns:  
- Schrittweise die Cypress-Test-Suiten abzulehnen, während sie ersetzt wurden  
- CI/CD-Pipelines für beide Frameworks betriebsbereit zu halten  
- Eine saubere und modulare Architektur aufrechtzuerhalten  

Nachfolgend die endgültige Struktur nach Abschluss des Migrations-Workflows.  
#### Endgültige Ordnerstruktur```
github/
│   ├── prompts/
│   └── workflows/
├── cypress/
│   ├── app/
│   ├── downloads/
│   ├── e2e/
│   ├── fixtures/
│   ├── screenshots/
│   ├── support/
│   └── videos/
├── playwright/
│   ├── app/
│   ├── constants/
│   ├── helpers/
│   ├── reports/
│   ├── test-results/
│   └── tests/

Hinweise zur Struktur

  • .github/prompts/ – enthält Ihre Copilot-Migrationsaufforderungen. Das Beibehalten dieser in Versionen ermöglicht es Ihnen, sie für zukünftige Framework-Migrationen oder Refaktorisierungen zu aktualisieren oder wiederzuverwenden.
  • .github/workflows/ – enthält Ihre CI/CD-Definitionen. Sie können sowohl Playwright- als auch Cypress-Jobs parallel ausführen, bis das alte Framework vollständig abgelöst wird.
  • playwright/ Ordner – fungiert jetzt als primäre Automatisierungsquelle für die Zukunft. Er spiegelt die Struktur der vorherigen Cypress-Implementierung wider, um die Einarbeitung zu erleichtern und Konsistenz sicherzustellen.
  • tsconfig.playwright.json und tsconfig.cypress.json – bleiben getrennt für vollständige Typisolierung, um Konflikte während der Builds zu verhindern.

Diese Struktur unterstützte nicht nur einen reibungslosen Übergang, sondern positionierte das Projekt auch für zukünftige Skalierbarkeit, CI-Flexibilität und modulare Testverantwortung über Teams hinweg.

 
Planen Sie eine Migration von Cypress zu Playwright?

Bewegen Sie Ihr Test-Suite, ohne Releases zu stören oder Coverage zu verlieren. Unser QA-Team kann Ihnen helfen, die Migration zu planen, Ihre Automatisierungsarchitektur anzupassen und beide Frameworks während des Übergangs stabil zu halten.

5

Praktische Ratschläge & Erkenntnisse

Nach der Migration von fast 150 Tests mit Copilot und Playwright sind hier einige wichtige Lektionen und praxisnahe Tipps, die den Prozess reibungsloser machten (und uns einige Kopfschmerzen ersparten).

Allgemeine Ratschläge zu KI

  • KI lügt – oft überzeugend.  

Überprüfen Sie immer jede Zeile Code, die die KI generiert. Vertrauen Sie ihr niemals blind, insbesondere während Infrastrukturmigrationen.

  • Halten Sie sich an konsistente Benennungsvereinbarungen.

Behalten Sie identische Variablen- und Methodennamen über Frameworks hinweg bei – das hilft der KI-Agentin, Code genauer zu migrieren, und erleichtert es Ihnen, diese später zu finden und zu importieren.

Allgemeine KI-bezogene Ratschläge.webp

  • Importe manuell neu aufbauen.

Copilot neigt dazu, Importpfade durcheinanderzubringen. Es ist oft schneller, sie zu löschen und manuell erneut zu importieren, oder globale Importe einzurichten wie: import x from "playwright/foo/bar";

  • Verwenden Sie denselben Chat für alle Migrationen. ```

Bleibe in einem einzelnen Copilot-Chatverlauf — das schafft Kontext und „merkt“ sich die Konventionen deines Projekts, was zu besseren Ergebnissen führt.

  • Migration Aufgaben aufteilen.  

Generiere 1–2 Dateien auf einmal. Kleinere Aufgaben führen zu genaueren Ergebnissen und erleichtern die manuelle Validierung.

Playwright-spezifische Tipps

  • Erstelle niemals mehrere Instanzen des gleichen Page Objects ohne Notwendigkeit.

Dies kann zu inkonsistentem Zustand oder defekten Selektoren führen, wenn zwischen Seiten navigiert wird. Die Lösung? Implementiere einen Page Manager, der alle Page Objects über eine einzige Instanz zugänglich macht.

Hier ist ein minimales Beispiel-Setup:

// login.page.ts
class LoginPage extends Common {
  async clickLoginButton(): Promise<void> {
    await this.loginButton().click();
  }
}
export default LoginPage;
//-----------------------------------------------------------
//PageManager.ts
export class PageManager {
  readonly loginPage: LoginPage;
  constructor(page: Page) {
    this.loginPage = new LoginPage(page);
  }
}
//-----------------------------------------------------------
//test.fixture.ts
export const test = base.extend<{
  pageManager: PageManager;
}>({
  pageManager: async ({ page }, use) => {
    const manager = new PageManager(page);
    await use(manager);
  },
});
export { expect };
//-----------------------------------------------------------
//userLogin.spec.ts
  test("Der Benutzer sollte sich mit gültigen Daten anmelden", async ({ pageManager }) => {
    await pageManager.loginPage.clickLoginButton();
  });

Weitere technische Tipps

  • Entferne alle „get“-Präfixe von Locatoren, die der KI-Agent generiert — benutze stattdessen direkte Locator-Methoden.
  • Vergiss nicht, dotenv für Umgebungsvariablen und Anmeldedaten zu konfigurieren.
  • Passe deine Playwright-Konfiguration an, um alle Berichte im Playwright-Ordner auszugeben, sodass dein Projektstamm sauber bleibt:
reporter: [["html", { open: "never", outputFolder: ".‌/playwright/reports/" }]],
  outputDir: ".‌/playwright/test-results",
6

Nachwort

Ich habe die ESLint-Konfiguration hier nicht mit aufgenommen, da sie von Projekt zu Projekt variiert.  
Die einzige universelle Empfehlung, die ich geben kann, ist, das Playwright ESLint-Plugin zu installieren, um die Regelanwendung zu verbessern: eslint-plugin-playwright.

Wenn du ein vollständiges funktionierendes Beispiel dieser Migration — einschließlich Prompt-Dateien, tsconfigs und CI-Setup — erkunden möchtest, kannst du das vollständige Repository hier ansehen: Repo-Beispiel.

 
Bereit, Ihre Testautomatisierung zu modernisieren?

Egal, ob Sie von Cypress migrieren, eine instabile Test-Suite neu aufbauen oder Ihre QA-Automatisierung verbessern möchten, JetBase kann Ihnen helfen, den Übergang mit weniger manueller Arbeit und einem geringeren Lieferrisiko zu gestalten.

Kommentare

Einloggen, um einen Kommentar zu schreiben
Weiter mit GoogleWeiter mit Google
Modern

Unsere Fälle

Bei Innovation geht es nicht nur um Ideen – es geht um die Umsetzung, darum, Visionen in die Realität umzusetzen und Lösungen zu schaffen, die wirklich etwas bewirken. Sehen Sie, was wir gebaut haben und wie es funktioniert:

  • Gesundheitswesen
  • Medien & Unterhaltung
  • E-Commerce
  • Amazon Web Services
  • Cloud-Kostenoptimierung
  • Serverlose Anwendung
  • Einzelhandel
  • Gesundheitswesen - Banner
    • 100%HIPAA-konform
    • 99,99% BetriebszeitMaximale Zuverlässigkeit
  • Gesundheitswesen - Banner
    • 10.000+Patientenunterstützung
    • Engagement 30 %+Anpassbare Benutzererfahrung

Neueste Artikel