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

test('Obtener datos de la página', async ({ page }) => {
  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

test('Pasar parámetros a la página', async ({ page }) => {
  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

test('Obtener atributos DOM de un elemento', async ({ page }) => {
  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

test('Obtener el texto de todos los elementos de la lista', async ({ page }) => {
  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

test('Inyectar script inicial', async ({ page }) => {
  // 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:

UsoDescripción
Mock de API del navegadorAnularnavigator.webdriver、navigator.languageesperar
Inyectar configuración personalizadaEstablecer variables de entorno de prueba, simular fuentes de datos, etc.
Deshabilitar funcionesDesactivar Service Workers, deshabilitar registros, etc.
PolyfillAñ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

// Enfoque con ElementHandle (método antiguo, no recomendado)
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.

Otras extensiones