Les API keyboard et mouse de Playwright donnent un contrôle direct sur les appuis de touches, les combinaisons de touches et les états de survol. Elles couvrent aussi les menus contextuels du clic droit, les interactions de glisser-déposer et le positionnement précis de la souris.
Événements clavier
Appuis de touches simples
// Appuyer sur une touche unique
await page.keyboard.press('Enter');
await page.keyboard.press('Tab');
await page.keyboard.press('Escape');
await page.keyboard.press('ArrowDown');
// Combinaisons modificateur + touche
await page.keyboard.press('Control+a'); // Tout sélectionner
await page.keyboard.press('Control+c'); // Copier
await page.keyboard.press('Control+v'); // Coller
await page.keyboard.press('Shift+Tab'); // Tab inverse
await page.keyboard.press('Meta+k'); // Cmd+K sur MacLes noms de touches suivent la spec KeyboardEvent.key. Les plus courants : 'Enter', 'Tab', 'Escape', 'Backspace', 'Delete', 'ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Home', 'End', 'PageUp', 'PageDown', 'F1' à 'F12'.
Saisir du texte
// Saisir dans l'élément focalisé
await page.getByRole('searchbox').focus();
await page.keyboard.type('playwright testing');
// Saisir avec délai entre les frappes (simule la frappe réelle)
await page.keyboard.type('frappe lente', { delay: 50 });keyboard.type() déclenche les événements keydown, keypress, keyup et input pour chaque caractère. Cela compte pour les applications qui gèrent les frappes individuelles (autocomplétion, validation en temps réel, éditeurs de texte enrichi).
Maintenir les touches modificatrices
// Shift + clic pour sélectionner une plage
await page.keyboard.down('Shift');
await page.getByRole('row').nth(5).click();
await page.keyboard.up('Shift');Tests de navigation clavier
Vérifier que votre application est accessible au clavier est à la fois une exigence d'accessibilité et une préoccupation QA :
test('la modale se ferme avec Escape', async ({ page }) => {
await page.getByRole('button', { name: 'Ouvrir la modale' }).click();
await expect(page.getByRole('dialog')).toBeVisible();
await page.keyboard.press('Escape');
await expect(page.getByRole('dialog')).not.toBeVisible();
});
test('le dropdown se navigue avec les touches fléchées', async ({ page }) => {
await page.getByRole('combobox', { name: 'Pays' }).focus();
await page.keyboard.press('ArrowDown'); // Ouvre le dropdown, sélectionne le premier
await page.keyboard.press('ArrowDown'); // Sélectionne le deuxième
await page.keyboard.press('Enter'); // Confirme la sélection
await expect(page.getByRole('combobox', { name: 'Pays' })).toHaveValue('France');
});Événements souris
Variantes de clic
// Double clic
await page.getByRole('row').first().dblclick();
// Clic droit (menu contextuel)
await page.getByText('Document.pdf').click({ button: 'right' });
await expect(page.getByRole('menuitem', { name: 'Télécharger' })).toBeVisible();
// Clic à des coordonnées spécifiques relatives à l'élément
await page.getByRole('slider').click({ position: { x: 10, y: 0 } });
// Clic en maintenant une touche modificatrice
await page.getByRole('checkbox', { name: 'Élément 3' }).click({ modifiers: ['Shift'] });Survol
// Survoler pour révéler un tooltip ou un dropdown
await page.getByRole('button', { name: 'Aide' }).hover();
await expect(page.getByRole('tooltip')).toBeVisible();
await expect(page.getByRole('tooltip')).toHaveText('Cliquez pour la documentation');
// Survoler pour révéler un bouton d'action caché dans une ligne de tableau
await page.getByRole('row', { name: 'Alice Johnson' }).hover();
await page.getByRole('button', { name: 'Modifier' }).click();Mouvement de la souris
// Déplacer la souris vers des coordonnées absolues de page
await page.mouse.move(100, 200);
// Glisser d'une position à une autre
await page.mouse.move(100, 200);
await page.mouse.down();
await page.mouse.move(300, 200, { steps: 10 }); // steps rend le mouvement plus fluide
await page.mouse.up();Le paramètre steps pour mouse.move() décompose le déplacement en points intermédiaires, ce qui compte pour les implémentations de glisser-déposer qui tracent les événements mousemove le long du chemin.
Glisser-déposer
Pour le glisser-déposer HTML5 standard :
// Avec dragTo — l'approche la plus simple
await page.getByText('Carte A').dragTo(page.getByText('Colonne B'));
// Avec une position de dépôt spécifique dans la cible
await page.getByText('Fichier.pdf').dragTo(page.locator('.upload-zone'), {
targetPosition: { x: 50, y: 50 },
});Pour les implémentations de glisser personnalisées qui utilisent les événements mousedown/mousemove/mouseup :
const source = page.getByTestId('draggable-card');
const target = page.getByTestId('drop-zone');
const sourceBounds = await source.boundingBox();
const targetBounds = await target.boundingBox();
await page.mouse.move(sourceBounds!.x + sourceBounds!.width / 2, sourceBounds!.y + sourceBounds!.height / 2);
await page.mouse.down();
await page.mouse.move(targetBounds!.x + targetBounds!.width / 2, targetBounds!.y + targetBounds!.height / 2, { steps: 20 });
await page.mouse.up();Défilement
// Faire défiler la page
await page.mouse.wheel(0, 500); // Faire défiler vers le bas de 500px
// Faire défiler dans un élément spécifique
await page.getByRole('log').hover();
await page.mouse.wheel(0, 300);
// Faire défiler jusqu'à un élément (à utiliser avant d'interagir avec des éléments hors écran)
await page.getByTestId('submit-section').scrollIntoViewIfNeeded();Combiner clavier et souris
Les schémas d'interaction les plus réalistes combinent les deux :
test('sélection multiple avec Ctrl+clic', async ({ page }) => {
await page.goto('/files');
// Sélectionner le premier élément
await page.getByRole('row').nth(0).click();
// Ctrl+clic pour ajouter à la sélection
await page.getByRole('row').nth(2).click({ modifiers: ['Control'] });
await page.getByRole('row').nth(4).click({ modifiers: ['Control'] });
// Supprimer les éléments sélectionnés
await page.keyboard.press('Delete');
await expect(page.getByRole('row')).toHaveCount(7); // Démarré avec 10, supprimé 3
});Quand utiliser ces API
La plupart de vos tests doivent utiliser les méthodes de locators de haut niveau (click(), fill(), selectOption()). Descendez aux API clavier/souris quand :
- Vous testez des raccourcis clavier ou l'accessibilité
- Vous testez des éléments UI déclenchés par survol
- Vous testez des interactions de glisser-déposer
- Vous testez des menus contextuels
- Vous testez des éditeurs de texte enrichi
- Vous simulez des interactions complexes en plusieurs étapes
Les événements clavier et souris directs sont plus lents et plus fragiles que les actions de haut niveau. Utilisez-les seulement quand l'API de haut niveau ne peut pas exprimer ce dont vous avez besoin.
→ See also: Locators Playwright: getByRole, getByLabel, getByText, getByTestId Comparés | Tests d'Accessibilité avec Playwright: Vérifications a11y Automatisées | Chargement et Téléchargement de Fichiers dans les Tests Playwright