JetBase Logo
  • Hjem
  • Blogg
  • Migrering av Cypress-tester til Playwright med Copilot
Banner

Hovedpunkter

En migrering fra Cypress til Playwright trenger ikke å bli en høy-risiko omskrivning. På en helseplattform ble 148 E2E-tester flyttet gradvis mens Cypress forble aktiv i CI, noe som bevarte utgivelsesdekningen gjennom overgangen. GitHub Copilot reduserte repetitivt konverteringsarbeid med 70–80%, men trygg migrering krevde fortsatt menneskelig gjennomgang, isolerte rammeverkskonfigurasjoner og fil-for-fil validering.

• Bygg Playwright-prototypen på 1–2 dager.
• Kjør begge rammeverkene til hver pakke er stabil.
• Migrer støttefiler før testfiler.
• Gå gjennom importer, fixtures, lokatorer og påstander manuelt.

Når vi fikk en forespørsel om å migrere Cypress-tester til Playwright, forventet vi en lang, tidkrevende omskrivingsprosess.

Overraskende nok, med hjelp fra GitHub Copilot, klarte vi å starte migreringen fra Cypress til Playwright på bare noen dager — og holde CI-pipelinen kjørende hele tiden uten å forstyrre noen testprosesser.

I denne artikkelen vil jeg dele hvordan vi nærmet oss denne migreringen, hvilke lærdommer vi fikk underveis, og hvordan AI-assistert kode-migrering kan drastisk redusere den manuelle overhodet ved rammeverksoverganger.

1

Prosjektkontekst

Prosjektet var en kompleks helseservieplattform med mye som foregikk under panseret. Vår testoppsett inkluderte:

  • End-to-end (E2E) og integrasjonstester
  • Et tilpasset TAF-arkitektur med oppsett, nedleggelse og enhetsopprettelse
  • Multi-miljø konfigurasjoner
  • Dynamiske data og dyp navigasjonslogikk

Totalt hadde vi 148 E2E-tester som kjørte på Cypress — alle fungerte fint, men organisasjonen ønsket å standardisere QA-verktøy på tvers av teamene, noe som betydde én ting: migrering til Playwright.

2

Hvorfor Use GitHub Copilot for Migrering?

Når forespørselen om migrering kom inn, så jeg en mulighet til å eksperimentere med GitHub Copilot for testautomatisering. I stedet for å omskrive hundrevis av testfiler manuelt, ønsket jeg å se hvor langt vi kunne presse AI-assistansen for å automatisere syntaksomformingen fra Cypress til Playwright.

Og ærlig talt, det fungerte langt bedre enn forventet.

GitHub Copilot håndterte de fleste av de gjentagende oversettelsene (selektorer, kommandoer, asynkron håndtering, osv.), noe som lot oss fokusere på infrastrukturjusteringer og finjustering.

Innen 1–2 dager hadde vi allerede en fungerende prototype av Playwright testautomatiseringsrammeverket.

3

To Viktige Ansvarsfraskrivelser

Verifiser Alltid AI-Generert Kode

Selv om AI-assistert kode-migrering får ting til å gå raskere, må du gjennomgå hver linje. Infrastrukturmigreringer kan lett introdusere subtile feil eller ytelsesregresjoner. Tenk på Copilot som din parprogrammerer, ikke som autopilot.

Hold Det Gamle Rammeverket Kjørende Til Slutt

Aldri blokkere utgivelser eller regresjoner under migrering. Hold Cypress-testene dine kjørende på CI inntil de tilsvarende suiteene er helt stabile i Playwright. Når en suite er migrert og validert, fjern den fra Cypress og bytt CI for å kjøre den i Playwright.

Denne gradvise utrullingen sikrer null nedetid og kontinuerlig testdekning gjennom hele prosessen.

4

Arbeidsflyt for å Migrere fra Cypress til Playwright

Når grunnlaget var klart, gikk vi videre til den praktiske migreringen.  
Nedenfor er arbeidsflyten som hjalp oss å kjøre begge rammeverkene parallelt, opprettholde CI-stabilitet, og starte migreringen av tester inkrementelt — uten å blokkere pågående utgivelser.

1. Initialiser Playwright og Opprett Mappen Struktur

Det første steget var å initialisere Playwright og opprette en ren, isolert mappestruktur.

Vi ønsket at begge rammeverkene skulle leve side om side i det samme depotet, slik at vi kunne kjøre dem samtidig under overgangen.

Den oppsetningen tillot oss å:

  • Migrere gradvis
  • Sammenligne resultater og tider mellom Cypress og Playwright
  • Holde CI-pipelines kjørende for begge

Eksempel på initialisering:

Initialization example.webp

Her er den foreslåtte mappestrukturen vi brukte for Playwright:

├── 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. Konfigurer Separate tsconfig Filer for Hvert Rammeverk

Et av de tidlige problemene vi stod overfor var TypeScript-konflikter — begge rammeverkene definerer lignende metodenavn (expect, request, osv.), og deling av en enkelt tsconfig.json førte til kompilasjonsfeil.

Løsningen var enkel: del TypeScript-konfigurasjonene. Denne strukturen sikrer at hvert rammeverk initierer sine egne typebetegnelser og unngår typekonflikter:

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

Hoved tsconfig.json
Legg til composite-alternativet for å støtte prosjektreferanser.

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"]
}

Med denne separasjonen på plass kunne begge rammeverkene sameksistere fredelig i ett repo — ikke flere kompilatorkonflikter, og ingen risiko for å ved et uhell initialisere delte metoder to ganger.

3.

Opprett en prompt for å automatisere migrering med GitHub Copilot

Når Playwright var initialisert og prosjektet var strukturert, var det på tide å la GitHub Copilot hjelpe med det tunge løftet.

For å gjøre dette, opprettet vi en tilpasset prompt som definerer hvordan Copilot skal oppføre seg når den omskriver tester fra Cypress til Playwright. Prompten forteller agenten hva den skal gjøre, hvordan den skal gjøre det, og hva som skal ignoreres — noe som gir konsistente resultater på tvers av alle migreringer.

Slik legger du til prompten

Inne i ditt GitHub-repositorium, åpne tannhjulikonet ⚙️ i Copilot Chat og opprett en ny prompt.  
Filene lagres automatisk under: ./github/prompts/

Du kan navngi den noe som migrate_tests.md.

Eksempel på prompt:

---
mode: agent
---
Du er en Playwright Test Generator, en ekspert på nettleserautomatisering og ende-til-ende-testing.
Din spesialitet er å lage robuste, pålitelige Playwright-tester som nøyaktig simulerer brukerinteraksjoner og validerer applikasjonsatferd.
Din oppgave er å hjelpe med å migrere eksisterende Cypress-tester til Playwright-tester.
Cypress-testene, sideobjektene, komponentene og hjelpefilene er gitt som input, og du må generere tilsvarende Playwright-testkode.
Output ALL migrert kode til chatten.
Når du genererer Playwright-testkode eller noen sideobjekter, må du sikre at:
1. Teststrukturen følger den samme strukturen som Cypress-testene.
2. Opprett en global fixture for oppsett og nedsetting og gjenbruk den i testene.
3. Alle brukerinteraksjoner (klikk, skriving, navigasjon) oversettes nøyaktig til Playwright-syntaks i sideobjekter og testfiler.
4. Påstander i Cypress konverteres til tilsvarende Playwright-påstander.
5. Ignorer nettverksinnsyning og stubbing-deler av Cypress-testene.
6. Kommenter ut alle metodene med venting (f.eks. cy.wait) i Playwright-koden.
7. Ikke bruk get-metoder i sideobjekter; bruk direkte metoder i stedet `backbackItem = () => this.page.locator('[id="item_4_title_link"]');`

Hvorfor dette hjelper

Denne typen strukturerte prompt gjør at GitHub Copilot kan oppføre seg mer som en spesialisert migreringsassistent, ikke en generell kodegenerator.

Med riktig kontekst og regler kan Copilot automatisk:

  • Omskrive store biter av Cypress-tester til Playwright-syntaks
  • Opprettholde konsistens i mappe- og teststruktur 
  • Redusere manuell konverteringstid med 70–80%

I hovedsak lager du ditt eget AI-migreringsverktøy — skreddersydd for prosjektets struktur og konvensjoner.

4. Velg agentmodus og kjør migreringen trinn for trinn

Når prompten var klar, var neste steg å faktisk kjøre migreringen med GitHub Copilot i agentmodus. I denne fasen lar vi AI-modellen prosessere hver fil — sideobjekter, komponenter, hjelpere, og til slutt testene — én etter én.

For this task, we used the GPT-4.1-modellen, som leverer de mest konsistente og kontekstsensitive kodeforvandlinger.

Slik starter du migrasjonen

1. Åpne Copilot Chat i VS Code

2. Bruk / for å velge prosjektfilen du opprettet tidligere

3. Bruk # for å velge en spesifikk fil (for eksempel en Cypress-test eller sideobjekt) som du ønsker å migrere

Copilot vil nå bruke migreringsprompten din og generere en Playwright-kompatibel versjon av filen direkte i chatten.

How to Start Migration.webpEksempel på migrering av inventoryPage Sideobjekt

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().

Justering av agentens atferd

Ikke bekymre deg hvis den første utdataen ikke er perfekt. Fra vår erfaring får AI-agenten vanligvis 60–70 % av koden riktig ved første forsøk. Nøkkelen er å holde samtalekonteksten aktiv — fortsett å forbedre den samme chat-tråden ved å be om rettelser eller justeringer. Når du gjør dette, begynner Copilot å lære prosjektmønstrene dine og produserer mer nøyaktig, gjenbrukbar kode.

I hovedsak, jo flere iterasjoner du gjør i den samme chatten, jo bedre blir migreringskvaliteten.

Migreringsrekkefølge: Filer først, deretter tester

For å holde avhengigheter konsistente og unngå manglende referanser, følg denne rekkefølgen:

1. Generer ikke-testfiler først:

  • Sideobjekter
  • Komponenter
  • Hjelpefiler
  • Konstanter

2. Når alle støttefiler er generert og verifisert, legg til #app-mappen i chatkonteksten, og migrer deretter testfilene selv.

Verifiseringstrinn

Når en Playwright-test genereres:

1. Gå gjennom koden — bekreft at side-lokatorer, testtrinn og påstander er riktige.

2. Kjør testen ved hjelp av Playwright CLI for å sikre at den kjører ordentlig.

3. Fiks mindre syntaks- eller fixture-mismatcher hvis Copilot misforsto en Cypress-kommando.

Ved å verifisere etter hver fil holder du migreringen stabil og inkrementell, og unngår storstilt feilsøking senere.

Eksempel på migrert inventoryPage-test som er vellykket bestått:

```html backbackItem().should("ha en tekst", itemsNames.backpackItemName); inventoryPage.clickBackbackAddItemButton(); inventoryPage.assertCartLogoItems(1); inventoryPage.clickBikeLightsAddItemButton(); inventoryPage.assertCartLogoItems(2); }); });

 

import { test, expect } from "…/fixtures/test.fixture";
import { itemsNames } from "../..‌/constants/data.json";
// InventoryPage tester migrert fra Cypress til Playwright
test.describe("InventoryPage tester", () => {
  test.beforeEach(async ({ pageManager }) => {
    await pageManager.loginPage.loginWithValidData();
  });
  test("Brukeren skal legge til en vare i handlekurven", async ({ pageManager }) => {
    await expect(
    pageManager.inventoryPage.item.itemByName(itemsNames.bikeLight)).toHaveText(itemsNames.bikeLight);
    await pageManager.inventoryPage.item.addToCartByName(itemsNames.bikeLight);
    await pageManager.inventoryPage.assertCartLogoItems(1);
  });
  test("Brukeren skal fjerne en vare fra handlekurven", async ({ pageManager }) => {
    await expect(
      pageManager.inventoryPage.backbackItem()).toHaveText(itemsNames.backpackItemName);
    await pageManager.inventoryPage.clickBackbackAddItemButton();
    await pageManager.inventoryPage.assertCartLogoItems(1);
    await pageManager.inventoryPage.clickBackbackRemoveItemButton();
    await expect(pageManager.inventoryPage.shoppingCartLogo()).not.toHaveText(/\d/); // Skal ikke ha noen nummertekst
  });
  test("Brukeren skal legge til flere varer i handlekurven", async ({ pageManager }) => {
    await expect(pageManager.inventoryPage.backbackItem()).toHaveText(itemsNames.backpackItemName);
    await pageManager.inventoryPage.clickBackbackAddItemButton();
    await pageManager.inventoryPage.assertCartLogoItems(1);
    await pageManager.inventoryPage.clickBikeLightsAddItemButton();
    await pageManager.inventoryPage.assertCartLogoItems(2);
  });
});

5. Endelig mappestruktur etter migrering

Når migreringen var fullført, nådde vårt lager en stabil, dual-rammeverksstatus — som fullt kjørte både Cypress og Playwright side om side. Denne strukturen tillot oss å:

  • Gradvis avvikle Cypress testsett etter hvert som de ble erstattet
  • Holde CI/CD-pipeline operative for begge rammer
  • Opprettholde en ren og modulær arkitektur

Nedenfor er den endelige strukturen etter å ha fullført migreringsarbeidsflyten.

Endelig mappestruktur

├── .env
├── .gitignore
├── readme.md
├── package.json
├── playwright.config.ts
├── smoke.config.ts
├── tsconfig.cypress.json
├── tsconfig.playwright.json
├── tsconfig.json
├── .github/
│   ├── prompts/
│   └── workflows/
├── cypress/
│   ├── app/
│   ├── downloads/
│   ├── e2e/
│   ├── fixtures/
│   ├── screenshots/
│   ├── support/
│   └── videos/
├── playwright/
│   ├── app/
│   ├── constants/
│   ├── helpers/
│   ├── reports/
│   ├── test-results/
│   └── tests/

Notater om strukturen

  • .github/prompts/ — inneholder migrasjonsprompter for Copilot. Å holde disse versjonert lar deg oppdatere eller gjenbruke dem for fremtidige rammeverksmigrasjoner eller omstruktureringer.
  • .github/workflows/ — holder definisjonene for CI/CD. Du kan kjøre både Playwright- og Cypress-jobber parallelt inntil full avvikling av det gamle rammeverket.
  • playwright/ mappe — fungerer nå som primær automatiseringskilde fremover. Den speiler strukturen til den tidligere Cypress-implementeringen for å lette onboarding og sikre konsistens.
  • tsconfig.playwright.json og tsconfig.cypress.json — forblir separate for full typeisolasjon, og forhindrer konflikter under bygging.

Denne strukturen støttet ikke bare en jevn overgang, men posisjonerte også prosjektet for fremtidig skalerbarhet, CI-fleksibilitet og modulært testeierskap på tvers av team.

 
Planlegger du en migrasjon fra Cypress til Playwright?

Flytt testsviten din uten å forstyrre utgivelser eller miste dekning. Våre QA-ingeniører kan hjelpe deg med å planlegge migrasjonen, tilpasse automatiseringsarkitekturen, og holde begge rammeverk stabile under overgangen.

5

Praktiske råd og lærdommer

Etter å ha migrert nesten 150 tester med Copilot og Playwright, her er noen nøkkel-lærdommer og virkelige tips som gjorde prosessen smidigere (og reddet oss fra noen hodepiner).

Generelle AI-relaterte råd

  • AI lyver — ofte overbevisende.  

Verifiser alltid hver linje med kode AI-en genererer. Stol aldri blindt på den, spesielt under infrastrukturmigrasjoner.

  • Hold deg til konsistente navnekonvensjoner.

Behold identiske variabel- og metodenavn på tvers av rammeverk — det hjelper AI-agenten å migrere koden mer nøyaktig og gjør det lettere for deg å finne og importere dem senere.

Generelle AI-relaterte råd.webp

  • Bygg importer på nytt manuelt.

Copilot har en tendens til å rote med importstier. Det er ofte raskere å slette dem og importere på nytt manuelt, eller sette opp globale importer som: import x from "playwright/foo/bar";

  • Gjenbruk den samme chatten for alle migrasjoner.

Hold deg til en enkelt Copilot chattråd — det bygger kontekst og "husker" prosjektkonvensjonene dine, noe som fører til bedre resultater.

  • Degrader migreringoppgaver.  

Generer 1–2 filer om gangen. Mindre oppgaver gir mer nøyaktige resultater og gjør manuell validasjon enklere.

Playwright-Spesifikke Råd

  • Aldri opprett flere instanser av det samme Page Object uten behov.

Å gjøre det kan føre til inkonsistent tilstand eller ødelagte selektorer når du navigerer mellom sider. Løsningen? Implementer en Page Manager som holder alle sideobjektene tilgjengelige gjennom en enkelt instans.

Her er et minimalt eksempel på oppsett:

// 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("The user should login with valid data", async ({ pageManager }) => {
    await pageManager.loginPage.clickLoginButton();
  });

Andre Tekniske Tips

  • Fjern alle "get" prefikser fra lokatorer som AI-agenten genererer — bruk direkte lokatormetoder i stedet.
  • Ikke glem å konfigurere dotenv for miljøvariabler og legitimasjon.
  • Tilpass din Playwright-konfigurasjon for å outputte alle rapporter under Playwright-mappen, slik at prosjektroten forblir ren:
reporter: [["html", { open: "never", outputFolder: ".‌/playwright/reports/" }]],
  outputDir: ".‌/playwright/test-results",
6

Etterord

Jeg inkluderte ikke ESLint-oppsettet her, da det varierer fra prosjekt til prosjekt.  
Den eneste universelle anbefalingen jeg kan gi er å installere Playwright ESLint-plugin for bedre regelhåndhevelse: eslint-plugin-playwright.

Hvis du ønsker å utforske et fullstendig fungerende eksempel på denne migreringen — inkludert promptfiler, tsconfigs og CI-oppsett — kan du sjekke ut det fullstendige depotet her: Repo eksempel.

 
Klar til å modernisere testautomatiseringen din?

Enten du migrerer fra Cypress, gjenoppbygger et ustabilt testsuite eller forbedrer QA-automatiseringen din, kan JetBase hjelpe deg med å gjøre overgangen med mindre manuelt arbeid og lavere leveringsrisiko.

Kommentarer

Logg inn for at legge igjen en kommentar
Fortsett med GoogleFortsett med Google
Moderne

Våre Caser

Innovasjon handler ikke bare om ideer - det handler om utførelse, å gjøre visjonen til virkelighet og skape løsninger som virkelig gjør en forskjell. Se hva vi har bygget og hvordan det fungerer:

  • Helse
  • Medier og Underholdning
  • e-handel
  • Amazon Web Services
  • Kostnadsoptimalisering i skyen
  • Serverløs applikasjon
  • Detaljhandel

Siste Artikler