page.waitForSelector() vs page.$() / page.$$()

Toutes ces fonctions renvoient des promesses (puisque Playwright est asynchrone).
Mais elles ne font pas la même chose :

MéthodeRenvoieComportement
page.waitForSelector(selector)Promise<ElementHandle>✅ Attend jusqu’à ce que l’élément apparaisse dans le DOM (sinon lève une erreur après le timeout).
page.$(selector)Promise<ElementHandle | null>🔍 Cherche immédiatement le premier élément correspondant, sans attendre.
page.$$(selector)Promise<ElementHandle[]>🔍 Cherche immédiatement tous les éléments correspondants, sans attendre (renvoie un tableau vide si rien trouvé).



Exemple concret :

// 1. Attend que l’élément apparaisse (peut prendre quelques secondes)
import { ElementHandle } from "@playwright/test";

try {
  const element1: ElementHandle | null = await page.waitForSelector('#login-button', { timeout: 3000 });
  if (element1) {
    console.log("✅ Élément trouvé !");
  }
} catch (e) {
  console.log("⚠️ Aucun sélecteur trouvé :", e);
}

// 2. Vérifie immédiatement si l’élément existe (ne patiente pas)
const element2 : ElementHandle<SVGElement | HTMLElement> | null = await page.$('#login-button');

// 3. Récupère tous les éléments (même logique, sans attente)
const elements : ElementHandle<SVGElement | HTMLElement>[] = await page.$$('.note-item');


💡 Précisions sur le type générique de ElementHandle

TypeExemple de sélecteurUtilisation
ElementHandle<HTMLElement>div, button, inputÉlément HTML classique
ElementHandle<SVGElement>svg, path, circleÉlément SVG
ElementHandle<Node>Type par défaut, générique
`ElementHandle<SVGElementHTMLElement>`#id pouvant viser l’un ou l’autre

Type inférent

Dans la pratique, tu peux écrire simplement :

// 1. Attend que l’élément apparaisse (peut prendre quelques secondes)
import { ElementHandle } from "@playwright/test";

try {
  const element1 = await page.waitForSelector('#login-button', { timeout: 3000 });
  if (element1) {
    console.log("✅ Élément trouvé !");
  }
} catch (e) {
  console.log("⚠️ Aucun sélecteur trouvé :", e);
}

// 2. Vérifie immédiatement si l’élément existe (ne patiente pas)
const element2 = await page.$('#login-button');

// 3. Récupère tous les éléments (même logique, sans attente)
const elements  = await page.$$('.note-item');

et laisser TypeScript inférer le bon type (Exemple: ElementHandle<SVGElement | HTMLElement> | null).
Playwright est très bien typé, donc le typage explicite n’est pas obligatoire sauf si tu veux une vérification stricte pour un type particulier.