Cuando recibimos una solicitud para migrar pruebas de Cypress a Playwright, esperábamos un largo y tedioso proceso de reescritura.
Sorprendentemente, con la ayuda de GitHub Copilot, logramos iniciar la migración de Cypress a Playwright en solo un par de días — y mantener nuestra canalización de CI en funcionamiento todo el tiempo sin interrumpir ningún proceso de prueba.
En este artículo, compartiré cómo abordamos esta migración, las lecciones que aprendimos en el camino y cómo la migración de código asistida por IA puede reducir drásticamente la carga manual de las transiciones de marco.
Contexto del Proyecto
El proyecto era una plataforma de salud compleja con mucho sucediendo bajo el capó. Nuestra configuración de pruebas incluía:
- Pruebas de extremo a extremo (E2E) y pruebas de integración
- Una arquitectura TAF personalizada con configuraciones, desmantelamientos y creación de entidades
- Configuraciones multi-entorno
- Datos dinámicos y lógica de navegación profunda
En total, teníamos 148 pruebas E2E corriendo en Cypress — todas funcionando bien, pero la organización quería estandarizar las herramientas de QA entre equipos, lo que significaba una cosa: migración a Playwright.
¿Por qué usar GitHub Copilot para la migración?
Cuando llegó la solicitud de migración, vi una oportunidad para experimentar con la automatización de pruebas de GitHub Copilot. En lugar de reescribir manualmente cientos de archivos de prueba, quería ver hasta dónde podíamos llevar la asistencia de IA para automatizar la conversión de sintaxis de Cypress a Playwright.
Y, honestamente, funcionó mucho mejor de lo esperado.
GitHub Copilot manejó la mayor parte de la traducción repetitiva (selectores, comandos, manejo asíncrono, etc.), permitiéndonos concentrarnos en ajustes de infraestructura y ajustes finos.
Dentro de 1–2 días, ya teníamos un prototipo funcional del marco de automatización de pruebas de Playwright.
Dos Avisos Clave
Siempre Verifica el Código Generado por IA
A pesar de que la migración de código asistida por IA acelera las cosas, debes revisar cada línea. Las migraciones de infraestructura pueden introducir fácilmente errores sutiles o regresiones de rendimiento. Piensa en Copilot como tu compañero programador, no como un piloto automático.
Mantén el Antiguo Marco Funcionando Hasta el Final
Nunca bloquees lanzamientos o regresiones durante la migración. Mantén tus pruebas de Cypress corriendo en CI hasta que las suites correspondientes estén completamente estables en Playwright. Una vez que una suite esté migrada y validada, elimínala de Cypress y cambia CI para ejecutarla en Playwright.
Este despliegue gradual asegura cero tiempo de inactividad y cobertura continua de pruebas a lo largo del proceso.
Flujo de Trabajo para Migrar de Cypress a Playwright
Una vez que las bases fueron claras, pasamos a la migración práctica.
A continuación se presenta el flujo de trabajo que nos ayudó a ejecutar ambos marcos en paralelo, mantener la estabilidad de CI y comenzar a migrar pruebas de forma incremental — sin bloquear lanzamientos en curso.
1. Inicializar Playwright y Crear la Estructura de Carpetas
El primer paso fue inicializar Playwright y crear una estructura de carpetas limpia y aislada.
Queríamos que ambos frameworks coexistieran en el mismo repositorio, para que pudiéramos ejecutarlos simultáneamente durante la transición.Esa configuración nos permitió:
- Migrar gradualmente
- Comparar resultados y tiempos entre Cypress y Playwright
- Mantener los pipelines de CI en funcionamiento para ambos
Ejemplo de inicialización:

Aquí está la estructura de carpetas propuesta que usamos para 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.json2. Configurar archivos tsconfig separados para cada framework
Uno de los primeros problemas que enfrentamos fueron los conflictos de TypeScript: ambos frameworks definen nombres de métodos similares (expect, request, etc.), y compartir un solo tsconfig.json llevó a errores de compilación.
La solución fue simple: dividir las configuraciones de TypeScript. Esta estructura asegura que cada framework inicialice sus propias definiciones de tipo y evite colisiones de tipos:
├── tsconfig.json
├── tsconfig.cypress.json
├── tsconfig.playwright.jsonArchivo tsconfig.json principal
Agregue la opción composite para soportar referencias de proyecto.
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"]
}Con esta separación en su lugar, ambos frameworks podrían coexistir pacíficamente en un mismo repositorio: sin más conflictos de compilación y sin riesgo de inicializar accidentalmente métodos compartidos dos veces.
3.
Crear un aviso para automatizar la migración con GitHub Copilot
Una vez que se inicializó Playwright y se estructuró el proyecto, era hora de dejar que GitHub Copilot ayudara con el trabajo pesado.
Para hacer esto, creamos un aviso personalizado que define cómo debería comportarse Copilot al reescribir pruebas de Cypress a Playwright. El aviso le dice al agente qué hacer, cómo hacerlo y qué ignorar, proporcionando resultados consistentes en todas las migraciones.
Cómo agregar el aviso
Dentro de tu repositorio de GitHub, abre el ícono de engranaje ⚙️ en Copilot Chat y crea un nuevo aviso.
El archivo se guardará automáticamente en: ./github/prompts/
Puedes nombrarlo algo como migrate_tests.md.
Ejemplo de aviso:
---
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"]');`Por qué esto ayuda
Este tipo de aviso estructurado permite a GitHub Copilot comportarse más como un asistente de migración especializado, no como un generador de código de propósito general.
Con el contexto y las reglas adecuadas, Copilot puede automáticamente:
- Reescribir grandes bloques de pruebas de Cypress a sintaxis de Playwright
- Mantener la consistencia en la estructura de carpetas y pruebas
- Reducir el tiempo de conversión manual en un 70–80%
Esencialmente, estás creando tu propia herramienta de migración de IA, adaptada a la estructura y convenciones de tu proyecto.
4. Seleccionar el modo agente y ejecutar la migración paso a paso
Una vez que el aviso estuvo listo, el siguiente paso fue ejecutar realmente la migración con GitHub Copilot en modo agente. En esta fase, dejamos que el modelo de IA procesara cada archivo: objetos de página, componentes, ayudantes y, finalmente, las pruebas, uno por uno.
Para esta tarea, utilizamos el modelo GPT-4.1, que ofrece las transformaciones de código más consistentes y con mayor contexto.
Cómo Comenzar la Migración
1. Abre Copilot Chat en VS Code
2. Usa / para seleccionar el archivo de aviso que creaste anteriormente
3. Usa # para seleccionar un archivo específico (por ejemplo, una prueba de Cypress o un objeto de página) que deseas migrar
Copilot ahora aplicará tu aviso de migración y generará una versión compatible con Playwright del archivo directamente en el chat.
Ejemplo de migración del objeto de página inventoryPage
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().Ajustando el Comportamiento del Agente
No te preocupes si la primera salida no es perfecta. Según nuestra experiencia, el agente de IA generalmente acierta del 60 al 70 % del código en el primer intento. La clave es mantener activa la conversación — sigue refinando el mismo hilo de chat pidiendo correcciones o ajustes. A medida que haces esto, Copilot comienza a aprender los patrones de tu proyecto y produce un código más preciso y reutilizable.
En esencia, cuanto más iteraciones hagas en el mismo chat, mejor será la calidad de la migración.
Orden de Migración: Archivos Primero, Luego Pruebas
Para mantener las dependencias consistentes y evitar referencias faltantes, sigue este orden:
1. Genera primero los archivos no de prueba:
- Objetos de Página
- Componentes
- Archivos de Ayuda
- Constantes
2. Una vez que todos los archivos de soporte estén generados y verificados, añade la #app carpeta al contexto del chat, luego migra los archivos de prueba en sí.
Paso de Verificación
Cuando se genera una prueba de Playwright:
1. Revisa el código — confirma que los localizadores de página, los pasos de prueba y las afirmaciones sean correctos.
2. Ejecuta la prueba usando tu CLI de Playwright para asegurarte de que se ejecute correctamente.
3. Corrige coincidencias menores de sintaxis o fixture si Copilot malinterpretó un comando de Cypress.
Al verificar después de cada archivo, mantienes la migración estable e incremental, evitando depuraciones a gran escala más tarde.
Ejemplo de prueba de inventoryPage migrada que está pasando con éxito:
import inventoryPage from "cypress/app/pageobjects/inventoryPage";
import loginPage from "cypress/app/pageobjects/loginPage";
import { itemsNames } from "../../fixtures/data.json";
describe("Pruebas de InventoryPage", () => {
beforeEach(() => {
loginPage.loginWithValidData();
});
it("El usuario debería agregar un ítem al carrito", () => {
inventoryPage.item.itemByName("Bike Light").should("have.text", itemsNames.bikeLight);
inventoryPage.item.addToCartByName("Bike Light");
inventoryPage.assertCartLogoItems(1);
});
it("El usuario debería eliminar un ítem del carrito", () => {
inventoryPage.backbackItem().should("have.text", itemsNames.backpackItemName);
inventoryPage.clickBackbackAddItemButton();
inventoryPage.assertCartLogoItems(1);
inventoryPage.clickBackbackRemoveItemButton();
inventoryPage.shoppingCartLogo().should("not.have.text");
});
it("El usuario debería agregar múltiples ítems al carrito", () => {
inventoryPage.```html
5. Estructura Final del Repositorio Después de la Migración
Una vez que la migración se completó, nuestro repositorio alcanzó un estado estable de doble marco: funcionando completamente con Cypress y Playwright lado a lado. Esta estructura nos permitió:
- Degradar gradualmente los suites de pruebas de Cypress a medida que eran reemplazados
- Mantener operativos los pipelines de CI/CD para ambos marcos
- Mantener una arquitectura limpia y modular
A continuación se muestra la estructura final después de completar el flujo de trabajo de migración.
Estructura Final de Carpetas
```github/
│ ├── prompts/
│ └── workflows/
├── cypress/
│ ├── app/
│ ├── downloads/
│ ├── e2e/
│ ├── fixtures/
│ ├── screenshots/
│ ├── support/
│ └── videos/
├── playwright/
│ ├── app/
│ ├── constants/
│ ├── helpers/
│ ├── reports/
│ ├── test-results/
│ └── tests/
Notas sobre la Estructura
.github/prompts/ — contiene tus indicaciones de migración de Copilot. Mantener estas versionadas te permite actualizarlas o reutilizarlas para futuras migraciones o refactorizaciones de framework..github/workflows/ — contiene tus definiciones de CI/CD. Puedes ejecutar tanto trabajos de Playwright como de Cypress en paralelo hasta la completa deprecación del antiguo framework.playwright/ carpeta — actúa ahora como la fuente de automatización principal en adelante. Refleja la estructura de la implementación anterior de Cypress para facilitar la incorporación y garantizar coherencia.tsconfig.playwright.json y tsconfig.cypress.json — permanecen separados para una completa aislamiento de tipos, evitando conflictos durante las compilaciones.
Esta estructura no solo apoyó una transición fluida, sino que también posicionó al proyecto para una futura escalabilidad, flexibilidad en CI, y propiedad modular de pruebas a través de equipos.
¿Planeando una Migración de Cypress a Playwright?Mueve tu suite de pruebas sin interrumpir lanzamientos o perder cobertura. Nuestros ingenieros de QA pueden ayudarte a planificar la migración, adaptar tu arquitectura de automatización, y mantener estables ambos frameworks durante la transición.
5
Consejos Prácticos y Lecciones Aprendidas
Después de migrar casi 150 pruebas con Copilot y Playwright, aquí hay algunas lecciones clave y consejos del mundo real que hicieron el proceso más fluido (y nos salvaron de algunos dolores de cabeza).
Consejos Generales Relacionados con IA
- Las IA mienten — a menudo de manera convincente.
Siempre verifica cada línea de código que genera la IA. Nunca confíes en ella ciegamente, especialmente durante migraciones de infraestructura.
- Adhiérete a convenciones de nomenclatura consistentes.
Mantén nombres de variables y métodos idénticos a través de los frameworks — esto ayuda al Agente IA a migrar código con más precisión y te facilita encontrarlos e importarlos más adelante.

- Reconstruye importaciones manualmente.
Copilot tiende a confundir las rutas de importación. A menudo es más rápido eliminarlas y volver a importarlas manualmente, o configurar importaciones globales como: import x from "playwright/foo/bar";
- Reutiliza el mismo chat para todas las migraciones.
Mantente en un único hilo de chat de Copilot: esto ayuda a construir contexto y "recuerda" las convenciones de tu proyecto, lo que conduce a mejores resultados.
- Descompón las tareas de migración.
Genera de 1 a 2 archivos a la vez. Las tareas más pequeñas brindan resultados más precisos y facilitan la validación manual.
Consejos Específicos de Playwright
- Nunca crees múltiples instancias del mismo Objeto de Página sin necesidad.
Hacerlo puede causar un estado inconsistente o selectores rotos al navegar entre páginas. ¿La solución? Implementa un Gestor de Páginas que mantenga todos los objetos de página accesibles a través de una única instancia.
Aquí tienes un ejemplo de configuración mínima:
// 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("El usuario debe iniciar sesión con datos válidos", async ({ pageManager }) => {
await pageManager.loginPage.clickLoginButton();
});
Otros Consejos Técnicos
- Elimina todos los prefijos “get” de los localizadores que genera el Agente AI: utiliza métodos de localización directos en su lugar.
- No olvides configurar
dotenv para las variables de entorno y credenciales. - Personaliza tu configuración de Playwright para que todos los informes se guarden en la carpeta de Playwright, así tu root de proyecto se mantiene limpio:
reporter: [["html", { open: "never", outputFolder: "./playwright/reports/" }]],
outputDir: "./playwright/test-results",
6
Epílogo
No incluí la configuración de ESLint aquí ya que varía de un proyecto a otro.
La única recomendación universal que puedo hacer es instalar el plugin de ESLint para Playwright para una mejor aplicación de reglas: eslint-plugin-playwright.
Si deseas explorar un ejemplo completo de trabajo de esta migración — incluyendo archivos de prompts, tsconfigs y configuración de CI — puedes revisar el repositorio completo aquí: Ejemplo de repo.
¿Listo para Modernizar Su Automatización de Pruebas?Ya sea que esté migrando de Cypress, reconstruyendo un conjunto de pruebas inestable o mejorando su automatización de QA, JetBase puede ayudarle a hacer la transición con menos trabajo manual y un menor riesgo de entrega.















