Exécution de JavaScript avec Playwright

Ce chapitre présente comment exécuter du code JavaScript dans Playwright, y compris l'exécution dans le contexte de la page, le passage de paramètres et l'injection initiale de script.


page.evaluate() Exécution dans le contexte de la page

page.evaluate()Exécutez du code dans l'environnement JavaScript de la page, avec accès au DOM et aux variables globales de la page.

Exemple

test('Obtenir les données de la page', async ({ page }) => {
  await page.goto('https://www.example.com/');

  // Obtenir le titre de la page (exécuté dans le contexte de la page)
  const title = await page.evaluate(() => {
    return document.title;
  });
  console.log('Titre de la page :', title);

  // Obtenir le nombre de tous les liens sur la page
  const linkCount = await page.evaluate(() => {
    return document.querySelectorAll('a').length;
  });
  console.log('Nombre de liens :', linkCount);

  // Obtenir la position de défilement de la page
  const scrollY = await page.evaluate(() => {
    return window.scrollY;
  });
});

Passage de paramètres à evaluate

page.evaluate()Son deuxième paramètre est passé à la fonction à l'intérieur de la page.

Exemple

test('Passer des paramètres à la page', async ({ page }) => {
  await page.goto('https://www.example.com/');

  // Passer un seul paramètre
  const result1 = await page.evaluate((name) => {
    return `Hello, ${name}!`;
  }, 'EXEMPLE');

  // Passer un paramètre objet
  const userInfo = { name: 'example', role: 'admin' };
  const result2 = await page.evaluate((user) => {
    return `${user.name}Son rôle est ${user.role}`;
  }, userInfo);

  // Passer plusieurs paramètres (en utilisant la déstructuration)
  const result3 = await page.evaluate(
    ({ x, y }) => {
      return x + y;
    },
    { x: 10, y: 20 }
  );
  console.log('10 + 20 =', result3); // 30
});

Les paramètres passés sont sérialisés en JSON et envoyés au contexte de la page, donc les objets qui ne peuvent pas être sérialisés, tels que les fonctions et les éléments DOM, ne peuvent pas être passés.

La valeur renvoyée est également sérialisée.


locator.evaluate() Exécution dans le contexte de l'élément

locator.evaluate()Exécutez le code dans le contexte de l'élément correspondant ; le paramètre inclut une référence au nœud DOM de cet élément.

Exemple

test('Obtenir les attributs DOM de l'élément', async ({ page }) => {
  await page.goto('https://www.example.com/');

  // Obtenir le textContent d'un élément spécifique
  const text = await page
    .getByRole('heading', { name: 'EXAMPLE' })
    .evaluate(node => node.textContent);

  // Obtenir l'attribut de style de l'élément
  const color = await page
    .getByRole('button', { name: 'Search' })
    .evaluate(node => getComputedStyle(node).backgroundColor);
});

locator.evaluateAll() Itération sur tous les éléments correspondants

evaluateAll()Exécute le même code pour tous les éléments correspondants et renvoie un tableau.

Exemple

test('Get the text of all list items', async ({ page }) => {
  await page.goto('https://www.example.com/');

  // Obtenir le texte de tous les éléments de menu
  const menuItems = await page
    .getByRole('navigation')
    .locator('a')
    .evaluateAll(links => links.map(link => link.textContent));

  console.log('Éléments de menu :', menuItems);
  // ['Accueil', 'Tutoriel', 'Outils', ...]
});

page.addInitScript() Injection de scripts initiaux

addInitScript()Injectez du code JavaScript avant le chargement de la page, ce qui peutavant l'exécution des scripts de la pagemodifier l'environnement du navigateur.

Exemple

test('Injecter un script initial', async ({ page }) => {
  // Modifier la propriété navigator avant le chargement de la page
  await page.addInitScript(() => {
    // Contourner la détection de WebDriver
    Object.defineProperty(navigator, 'webdriver', {
      get: () => false,
    });

    // Simuler des variables globales sur window
    window.EXAMPLE_CONFIG = {
      env: 'test',
      version: '1.0.0',
    };
  });

  await page.goto('https://www.example.com/');

  // Vérifier que les variables injectées prennent effet
  const config = await page.evaluate(() => window.EXAMPLE_CONFIG);
  console.log(config); // { env: 'test', version: '1.0.0' }
});

addInitScript()Cas d'utilisation courants :

Cas d'utilisationDescription
Simuler l'API du navigateurRedéfinitionnavigator.webdriver、navigator.languagewait
Injecter une configuration personnaliséeDéfinir les variables d'environnement de test, simuler les sources de données, etc.
Désactiver des fonctionnalitésDésactiver le Service Worker, désactiver la journalisation, etc.
PolyfillAjouter la fonctionnalité dont la page dépend mais qui manque dans l'environnement de test.

Utilisations et limites d'ElementHandle

ElementHandle est une référence directe à un élément DOM et était largement utilisé dans les premières versions de Playwright.

Dans la plupart des scénarios aujourd'hui, vous devriez utiliserLocatorau lieu d'ElementHandle.

Exemple

// Approche ElementHandle (ancien style, non recommandé)
const handle = await page.$('.my-element');
await handle.click();

// Approche Locator (nouveau style, recommandé)
await page.locator('.my-element').click();

ElementHandle n'est utilisé que lorsque vous avez besoin d'obtenirboundingBox()ou lors de l'exécution d'opérations DOM complexes.

Autres extensions