Ejecución de JavaScript en Playwright
Este capítulo explica cómo ejecutar código JavaScript en Playwright, incluida la ejecución en el contexto de la página, el paso de parámetros y la inyección de scripts de inicialización.
page.evaluate() Ejecución en el contexto de la página
page.evaluate()Ejecuta código en el entorno JavaScript de la página, con acceso al DOM y a las variables globales de la página.
Ejemplo
await page.goto('https://www.example.com/');
// Obtener el título de la página (ejecutado en el contexto de la página)
const title = await page.evaluate(() => {
return document.title;
});
console.log('Título de la página:', title);
// Obtener el número de todos los enlaces en la página
const linkCount = await page.evaluate(() => {
return document.querySelectorAll('a').length;
});
console.log('Número de enlaces:', linkCount);
// Obtener la posición de desplazamiento de la página
const scrollY = await page.evaluate(() => {
return window.scrollY;
});
});
Pasar argumentos a evaluate
page.evaluate()El segundo parámetro se pasa a la función de la página.
Ejemplo
await page.goto('https://www.example.com/');
// Pasar un solo parámetro
const result1 = await page.evaluate((name) => {
return `Hello, ${name}!`;
}, 'EJEMPLO');
// Pasar un objeto como parámetro
const userInfo = { name: 'ejemplo', role: 'admin' };
const result2 = await page.evaluate((user) => {
return `${user.name}El rol es ${user.role}`;
}, userInfo);
// Pasar múltiples parámetros (usando desestructuración)
const result3 = await page.evaluate(
({ x, y }) => {
return x + y;
},
{ x: 10, y: 20 }
);
console.log('10 + 20 =', result3); // 30
});
Los parámetros pasados se serializan a JSON y se envían al contexto de la página, por lo que no se pueden pasar funciones, elementos DOM u otros objetos no serializables.
El valor devuelto también se serializa.
locator.evaluate() Ejecución en el contexto del elemento
locator.evaluate()Ejecuta código en el contexto del elemento coincidente; el parámetro contiene la referencia al nodo DOM de ese elemento.
Ejemplo
await page.goto('https://www.example.com/');
// Obtener el textContent de un elemento específico
const text = await page
.getByRole('heading', { name: 'EJEMPLO' })
.evaluate(node => node.textContent);
// Obtener los atributos de estilo del elemento
const color = await page
.getByRole('button', { name: 'Buscar' })
.evaluate(node => getComputedStyle(node).backgroundColor);
});
locator.evaluateAll() Iterar sobre todos los elementos coincidentes
evaluateAll()Ejecuta el mismo código en todos los elementos coincidentes y devuelve una matriz.
Ejemplo
await page.goto('https://www.example.com/');
// Obtener el texto de todos los elementos del menú
const menuItems = await page
.getByRole('navigation')
.locator('a')
.evaluateAll(links => links.map(link => link.textContent));
console.log('Elementos del menú:', menuItems);
// ['Inicio', 'Tutoriales', 'Herramientas', ...]
});
page.addInitScript() Inyectar script inicial
addInitScript()Inyecta código JavaScript antes de que la página se cargue; permiteantes de que se ejecuten los scripts de la páginamodificar el entorno del navegador.
Ejemplo
// Modificar la propiedad navigator antes de que la página cargue
await page.addInitScript(() => {
// Anular la detección de WebDriver
Object.defineProperty(navigator, 'webdriver', {
get: () => false,
});
// Mock de variables globales en window
window.EJEMPLO_CONFIG = {
env: 'test',
version: '1.0.0',
};
});
await page.goto('https://www.example.com/');
// Verificar que la variable inyectada tiene efecto
const config = await page.evaluate(() => window.EJEMPLO_CONFIG);
console.log(config); // { env: 'test', version: '1.0.0' }
});
addInitScript()Usos comunes:
| Uso | Descripción |
|---|---|
| Mock de API del navegador | Anularnavigator.webdriver、navigator.languageesperar |
| Inyectar configuración personalizada | Establecer variables de entorno de prueba, simular fuentes de datos, etc. |
| Deshabilitar funciones | Desactivar Service Workers, deshabilitar registros, etc. |
| Polyfill | Añadir funciones que la página necesita pero que faltan en el entorno de prueba |
Usos y limitaciones de ElementHandle
ElementHandle es una referencia directa a un elemento DOM, ampliamente utilizada en versiones anteriores de Playwright.
Ahora, en la mayoría de las situaciones, se debe usarLocatoren lugar de ElementHandle.
Ejemplo
const handle = await page.$('.my-element');
await handle.click();
// Enfoque con Locator (método nuevo, recomendado)
await page.locator('.my-element').click();
ElementHandle solo se usa cuando se necesita obtenerboundingBox()o para realizar operaciones DOM complejas.