Los tests de Playwright usan una porción acotada de JavaScript: variables, funciones, objetos, arrays, destructuring y async/await. La mayoría de los principiantes o se salta el lenguaje por completo y no puede depurar cuando algo falla, o intenta aprender todo JavaScript primero y nunca llega a escribir tests. Este artículo cubre solo lo que aparece en el código real de tests de Playwright, con async/await como prioridad porque olvidar await antes de una llamada al navegador es la causa más común de fallos intermitentes y difíciles de rastrear.
Por qué JavaScript específicamente para QA
Los tests de Playwright son archivos JavaScript (o TypeScript). Cuando escribes:
await page.click('.submit-button');Esa keyword await, esa arrow function, ese argumento string son todo JavaScript. Si no entendés qué hace await, no podés depurar un test que se cuelga. Si no entendés variables, no podés extraer un valor de la página y verificarlo.
La buena noticia: la automatización de QA usa una porción pequeña y predecible de JavaScript. No estás construyendo aplicaciones web. Estás escribiendo scripts que interactúan con ellas. Los patrones de código se repiten.
Variables: let y const
Dos formas de almacenar valores:
// const: el valor no cambia después de la asignación
const baseUrl = 'https://lab.becomeqa.com';
const timeout = 5000;
// let: el valor puede cambiar
let loginAttempts = 0;
loginAttempts = loginAttempts + 1;En el código de tests, usa const por defecto. Recurre a let solo cuando necesitas reasignar.
También vas a ver var en código más antiguo. Ignóralo. Tiene un comportamiento de scope que genera bugs. const y let lo reemplazaron.
Tipos de datos
Los tipos que realmente vas a usar en el código de tests:
// String: texto
const username = 'admin@becomeqa.com';
const password = 'testpass123';
// Number: para timeouts, conteos, verificaciones de precios
const timeout = 30000; // 30 segundos en ms
const itemCount = 5;
// Boolean: para condiciones
const isLoggedIn = true;
const hasError = false;
// null / undefined: ausencia de valor
// Los verás en aserciones
const itemTitle = null; // intencionalmente vacíoEn los tests de Playwright, strings y números aparecen en todos lados. Los booleanos aparecen en condiciones. null aparece cuando algo no se encuentra.
Funciones
Las funciones empaquetan código para reutilizarlo. Dos estilos que vas a ver:
// Función regular (estilo más antiguo, todavía común)
function generateEmail() {
return `user_${Date.now()}@test.com`;
}
// Arrow function (moderna, común en código de Playwright)
const generateEmail = () => `user_${Date.now()}@test.com`;
// Arrow function con cuerpo (múltiples líneas)
const login = async (page, email, password) => {
await page.getByRole('button', { name: 'Login' }).click();
await page.getByLabel('Email').fill(email);
await page.getByLabel('Password').fill(password);
await page.getByRole('button', { name: 'Submit' }).click();
};Las arrow functions son el estándar en el código moderno de Playwright. async antes de la función significa que usa await adentro.
Objetos
Los objetos agrupan datos relacionados:
// Un objeto con propiedades
const user = {
email: 'admin@becomeqa.com',
password: 'testpass123',
role: 'admin',
};
// Acceder a una propiedad con notación de punto
console.log(user.email); // 'admin@becomeqa.com'
// O notación de corchetes
console.log(user['email']); // mismo resultadoEn Playwright, los objetos aparecen constantemente como opciones que se pasan a funciones:
// { name: 'Login' } es un objeto
await page.getByRole('button', { name: 'Login' }).click();
// { data: { title: 'Tokio' } } es un objeto anidado
await request.post('/api/items', { data: { title: 'Tokio' } });Arrays
Los arrays almacenan listas de valores:
const estados = ['Planificado', 'En progreso', 'Completado'];
const precios = [9.99, 14.99, 29.99];
// Acceso por índice (empieza en 0)
console.log(estados[0]); // 'Planificado'
console.log(estados[2]); // 'Completado'
// Longitud
console.log(estados.length); // 3En los tests, los arrays aparecen cuando obtenés múltiples elementos de la página:
// Obtener todos los textos de filas de una tabla
const filas = await page.getByRole('row').allTextContents();
// filas ahora es un array: ['Tokio', 'París', 'Londres']
expect(filas).toContain('Tokio');if / else: tomar decisiones
// Condición básica
if (user.role === 'admin') {
await page.goto('/admin');
} else {
await page.goto('/dashboard');
}
// Verificar si algo está ausente
const errorMessage = await page.getByText('Credenciales inválidas').isVisible();
if (errorMessage) {
console.log('Login fallido como se esperaba');
}La comparación === (triple igual) verifica tanto el valor como el tipo. Usa siempre === en lugar de == en JavaScript.
Template literals: construir strings
Forma antigua (confusa con muchas variables):
const url = 'https://' + environment + '.lab.becomeqa.com/item/' + itemId;Forma moderna con backticks:
const url = `https://${environment}.lab.becomeqa.com/item/${itemId}`;Los template literals (strings con backticks) permiten insertar variables con ${}. Los vas a ver constantemente en el código de tests para construir URLs, mensajes y datos de prueba.
Destructuring: extraer de objetos y arrays
Este patrón aparece en todas partes en los fixtures de Playwright y en el código del Page Object Model:
// En lugar de esto:
const email = user.email;
const password = user.password;
// Podés hacer esto (destructuring):
const { email, password } = user;Con arrays:
const [primero, segundo] = ['Tokio', 'París', 'Londres'];
// primero = 'Tokio', segundo = 'París'En Playwright, lo ves constantemente en los parámetros de los tests:
// { page, request } acá es destructuring del objeto fixture
test('debería funcionar', async ({ page, request }) => {
// page y request están disponibles directamente
});Módulos: import y export
Los archivos de tests de Playwright importan del framework y de tu propio código:
// Importar del paquete de Playwright
import { test, expect } from '@playwright/test';
// Importar tu page object
import { LoginPage } from '../pages/LoginPage';
// Importar datos de prueba
import { testUsers } from '../data/users';Cuando creas un archivo de utilidades, exportas desde él:
// En utils/helpers.ts
export const baseUrl = 'https://lab.becomeqa.com';
export function generateTestEmail() {
return `test_${Date.now()}@example.com`;
}import trae cosas. export las hace disponibles para importar en otro lugar. Ese es todo el sistema.
¿Qué hay de los bucles?
Ocasionalmente vas a necesitar bucles en el código de tests, pero menos de lo que esperarías. Los casos principales:
// Iterar sobre un array de datos de prueba
const destinos = ['Tokio', 'París', 'Londres'];
for (const destino of destinos) {
await page.getByLabel('Destination').fill(destino);
await page.getByRole('button', { name: 'Save' }).click();
}El bucle for...of es el más claro para iterar arrays. forEach, map y filter se cubren en un artículo separado sobre métodos de array.
Lo que confunde a todos: async/await
Casi cada línea de código de Playwright tiene await delante:
await page.goto('https://lab.becomeqa.com');
await page.getByRole('button', { name: 'Login' }).click();
await expect(page.getByText('Dashboard')).toBeVisible();La regla es simple: cualquier método de Playwright que interactúa con el navegador devuelve una Promesa, y necesitás await para esperar a que termine.
Si olvidás await, el test generalmente ejecuta la siguiente línea antes de que se complete la acción actual, causando fallos confusos e intermitentes.
La versión corta: siempre pon await antes de las llamadas a Playwright. TypeScript te va a avisar si lo olvidas.
Lo que todavía no necesitás
Cosas que los ingenieros QA frecuentemente intentan aprender antes de necesitarlas, lo que genera confusión innecesaria:
- Clases: útiles para el Page Object Model, pero puedes entender POM sin conocer profundamente las clases primero
- Promises/then/catch:
async/awaites el reemplazo moderno; aprendeawaitprimero - Closures, prototipos, el event loop: internos de JavaScript que raramente afectan el código de tests
- Manipulación del DOM: estás usando Playwright para interactuar con el DOM; no lo manipulas directamente
Aprendé estas cosas cuando un problema específico las requiera. No antes.
Un test completo usando todo lo anterior
Un test de Playwright que usa todos los conceptos de este artículo:
import { test, expect } from '@playwright/test';
// Objeto: datos del usuario
const testUser = {
email: 'admin@becomeqa.com',
password: 'testpass123',
};
// Template literal: URL dinámica
const baseUrl = 'https://lab.becomeqa.com';
test('el usuario puede agregar un ítem de viaje', async ({ page }) => {
// Destructuring: extraer email y password del objeto
const { email, password } = testUser;
// Funciones (métodos de Playwright) con await
await page.goto(baseUrl);
await page.getByRole('button', { name: 'Login' }).click();
await page.getByLabel('Username').fill(email);
await page.getByLabel('Password').fill(password);
await page.getByRole('button', { name: 'Submit' }).click();
// Variable string
const destination = 'Tokio';
await page.getByRole('button', { name: 'Add Item' }).click();
await page.getByLabel('Destination').fill(destination);
// Boolean: verificar si algo es visible
const saveButton = page.getByRole('button', { name: 'Save' });
// Condicional
if (await saveButton.isVisible()) {
await saveButton.click();
}
// Array: allTextContents devuelve un array
const rows = await page.getByRole('row').allTextContents();
// expect sobre el array
expect(rows.some(row => row.includes(destination))).toBeTruthy();
});Este es un test real y completo. El JavaScript que usa es exactamente lo que se cubre en este artículo. Nada más.
FAQ
¿Necesito completar un curso completo de JavaScript antes de empezar con Playwright?No. Aprendé conceptos de JavaScript a medida que los necesitás. Empieza a escribir tests de Playwright inmediatamente usando los patrones de arriba, y busca cosas cuando estés confundido. "Primero aprendo JS, después Playwright" lleva a muchas personas a aprender JS por meses y nunca llegar a Playwright.
¿JavaScript o TypeScript para Playwright?TypeScript. La documentación oficial de Playwright usa TypeScript. TypeScript agrega tipos a JavaScript, lo que significa que el editor detecta errores antes de ejecutar los tests. La diferencia es pequeña para principiantes.
¿Qué hago si no entiendo un fragmento de código de Playwright?Buscalo. MDN Web Docs (developer.mozilla.org) es la mejor referencia para características del lenguaje JavaScript. La documentación de Playwright (playwright.dev) cubre las APIs específicas de Playwright. Entre esas dos fuentes, cada pregunta sobre el código de tests tiene respuesta.
¿Cuánto lleva aprender suficiente JavaScript para escribir tests de Playwright?2 a 4 semanas de práctica diaria suelen ser suficientes para ser productivo. Vas a seguir aprendiendo cosas específicas a medida que las encuentres, pero 2 a 4 semanas de trabajo enfocado en los conceptos de este artículo te llevan a escribir y entender tests reales.
El concepto que más confunde a los principiantes es async/await. Está en cada interacción de Playwright. Entenderlo desbloquea la depuración.
→ See also: Async/Await en Español Sencillo (para Testers que se Confunden con las Promesas) | TypeScript para QA: Por Qué los Tipos Estáticos Mejoran tus Tests