Get your free and exclusive 80-page Banking Passkey Report
passkeys e2e playwright testing webauthn virtual authenticator

Tests E2E des passkeys avec Playwright via l'authentificateur virtuel WebAuthn

Apprenez à configurer des tests E2E pour les passkeys sur différents navigateurs avec Playwright, Nightwatch, Selenium et Puppeteer en utilisant l'authentificateur virtuel WebAuthn.

Blog-Post-Author

Anders

Created: June 17, 2025

Updated: June 24, 2025


Notre mission est de rendre Internet plus sûr, et le nouveau standard de connexion que sont les passkeys offre une solution supérieure pour y parvenir. C'est pourquoi nous voulons vous aider à mieux comprendre les passkeys et leurs caractéristiques.

1. Introduction : Tests E2E des passkeys#

Les passkeys sont de plus en plus largement acceptés comme méthode d'authentification, s'appuyant sur la norme sous-jacente Web Authentication (WebAuthn). Leur popularité est assez récente, ce qui rend la documentation et les autres ressources relativement rares. Ceci, combiné à la nature complexe de la mise en œuvre des passkeys, peut rendre difficile pour les développeurs de trouver des informations pertinentes sur la conception, l'implémentation et surtout les tests des passkeys pour leurs plateformes et services.

Ce guide vise à combler cette lacune, en se concentrant sur les aspects de l'authentificateur virtuel WebAuthn qui ne sont pas traités en profondeur dans sa documentation officielle. Par exemple, nous abordons des options de configuration pour l'authentificateur virtuel qui ne sont pas explicites dans la documentation, ainsi que des solutions de contournement pour certains cas d'utilisation pour lesquels l'authentificateur virtuel ne fournit pas de solution pratique. Ce guide est également utile pour les développeurs qui cherchent simplement des exemples faciles à suivre pour utiliser l'authentificateur virtuel dans leur code de test.

Notre guide utilise des exemples de Playwright pour fournir une procédure simple permettant de tester efficacement l'implémentation des passkeys dans votre projet. Playwright est un framework de test de bout en bout (E2E) qui utilise le Chrome DevTools Protocol (CDP) comme protocole pour l'automatisation des navigateurs. Si vous recherchez spécifiquement des exemples techniques de tests de passkeys dans Playwright, vous pouvez passer directement à la section 5. D'un autre côté, si vous utilisez d'autres frameworks de test E2E comme Puppeteer ou Selenium et que vous cherchez à tester les passkeys sur ces frameworks, les implémentations du code de test seront identiques ou très similaires aux exemples fournis dans ce guide, selon le framework que vous utilisez. Dans la section suivante, nous fournissons un contexte sur les différents frameworks E2E et la pertinence de ce guide pour ces frameworks.

2. Contexte : Automatisation des navigateurs et frameworks de test E2E#

2.1. Qu'est-ce que l'automatisation des navigateurs ?#

L'automatisation des navigateurs, comme son nom l'indique, est le processus d'automatisation des actions utilisateur répétitives sur le navigateur à des fins de scraping de données sur le web ou, dans notre cas, de test d'applications web. WebDriver et le Chrome DevTools Protocol (CDP) sont deux des principaux protocoles d'automatisation de navigateur pertinents pour ce guide, car ils fournissent chacun une implémentation de l'authentificateur virtuel WebAuthn.

2.2. Qu'est-ce que WebDriver ?#

WebDriver est une interface contrôlée à distance qui peut être considérée comme un intermédiaire dans la communication entre le client et le navigateur. L'objectif de ce protocole est de fournir une interface neutre en termes de plateforme et de langage qui prend en charge tous les principaux navigateurs, y compris ceux qui ne sont pas basés sur Chromium comme Firefox et Safari. Comme l'interface WebDriver doit gérer une connexion avec le client ainsi qu'avec le navigateur, cette approche sacrifie la vitesse et la stabilité en échange d'une plus large prise en charge des navigateurs (c'est-à-dire une plus grande instabilité). Parmi les clients WebDriver notables, on trouve Selenium et Nightwatch.

Source : jankaritech

2.3. Qu'est-ce que le Chrome DevTools Protocol (CDP) ?#

Le Chrome DevTools Protocol (CDP), en revanche, n'a pas d'intermédiaire comme l'interface WebDriver entre le client et le navigateur. De plus, la communication entre le client et le navigateur se fait via une connexion socket, contrairement à la connexion HTTP plus lente entre le client et l'interface WebDriver dans l'approche précédente. Ces points rendent le CDP beaucoup plus rapide et moins instable que WebDriver. L'inconvénient est que ce protocole n'est pris en charge que par les navigateurs basés sur Chromium comme Chrome et Edge. Playwright et Puppeteer sont des exemples de clients qui utilisent le CDP pour communiquer avec les navigateurs.

Source : jankaritech

2.4. Puppeteer & Playwright en tant que frameworks de test E2E basés sur le CDP#

Puppeteer, tout comme Playwright, est un framework E2E construit directement sur le CDP. Cela signifie que Puppeteer et Playwright utilisent tous deux la même implémentation de l'authentificateur virtuel WebAuthn et que la communication API utilisant l'authentificateur virtuel WebAuthn via la connexion socket est également identique.

Pour le démontrer, nous comparons le code de test dans Playwright et Puppeteer pour l'appel de la méthode getCredentials qui renvoie une liste de toutes les informations d'identification enregistrées jusqu'à présent dans l'authentificateur virtuel. Nous attachons également un simple écouteur d'événements pour l'événement credentialAdded qui est déclenché lorsqu'une information d'identification de passkey est enregistrée avec succès. Ne soyez pas intimidé par les détails de l'implémentation, car ils seront expliqués dans les sections suivantes. Ces exemples visent simplement à démontrer à quel point les implémentations sont similaires entre les deux frameworks.

Ben Gould Testimonial

Ben Gould

Head of Engineering

I’ve built hundreds of integrations in my time, including quite a few with identity providers and I’ve never been so impressed with a developer experience as I have been with Corbado.

10,000+ devs trust Corbado & make the Internet safer with passkeys. Got questions? We've written 150+ blog posts on passkeys.

Join Passkeys Community

Playwright :

const client = await page.context().newCDPSession(page); await client.send('WebAuthn.enable'); const authenticatorId = const result = await client.send('WebAuthn.addVirtualAuthenticator', { options }); ... // get all credentials registered in the virtual authenticator const result = await client.send('WebAuthn.getCredentials', { authenticatorId }); console.log(result.credentials); // add a listener to the credentialAdded event to output a log to the console whenever a passkey credential is registered client.on('WebAuthn.credentialAdded', () => { console.log('Credential Added!'); });

Puppeteer :

const client = await page.target().createCDPSession(); await client.send('WebAuthn.enable'); const authenticatorId = const result = await client.send('WebAuthn.addVirtualAuthenticator', { options }); ... // get all credentials registered in the virtual authenticator const result = await client.send('WebAuthn.getCredentials', { authenticatorId }); console.log(result.credentials); // add a listener to the credentialAdded event to output a log to the console whenever a passkey credential is registered client.on('WebAuthn.credentialAdded', () => { console.log('Credential Added!'); });

Bien que les méthodes d'initialisation de la session CDP au début des codes de test soient légèrement différentes, l'appel des méthodes et la gestion des événements dans l'API de l'authentificateur virtuel WebAuthn du CDP sont identiques. Cela signifie que si vous cherchez à utiliser l'authentificateur virtuel WebAuthn dans Puppeteer, vous pouvez suivre ce guide ligne par ligne.

Slack Icon

Become part of our Passkeys Community for updates & support.

Join

2.5. Selenium & Nightwatch en tant que frameworks de test E2E basés sur WebDriver#

Selenium et Nightwatch sont des frameworks de test E2E qui s'appuient sur WebDriver pour l'automatisation des navigateurs. Bien que l'implémentation de l'authentificateur virtuel WebAuthn pour WebDriver soit distincte de son implémentation pour le CDP, leurs spécifications d'API sont similaires. Pour presque chaque méthode de l'API de l'authentificateur virtuel WebAuthn du CDP, vous pouvez trouver une méthode correspondante dans l'API de l'authentificateur virtuel WebAuthn de WebDriver. Cependant, il convient de noter que s'il était possible d'attacher des écouteurs d'événements pour le moment où un passkey est ajouté ou affirmé avec succès dans l'API de l'authentificateur virtuel WebAuthn du CDP, cela n'est pas possible dans son homologue WebDriver.

Selenium :

const driver = await new Builder().forBrowser('chrome').build(); const options = new VirtualAuthenticatorOptions(); await driver.addVirtualAuthenticator(options); ... // get all credentials registered in the virtual authenticator const credentials = await driver.getCredentials();

Il est évident que la syntaxe pour configurer l'instance de l'authentificateur virtuel et effectuer des appels d'API est différente de l'implémentation CDP correspondante. Cependant, comme les spécifications d'API des deux authentificateurs virtuels WebAuthn sont très similaires, il serait viable de suivre ce guide pour écrire une implémentation correspondante sur un framework de test E2E basé sur WebDriver.

2.6. Cypress en tant que framework de test E2E avec script natif#

Cypress est un framework de test E2E qui n'est pas principalement construit sur WebDriver ou le CDP comme les frameworks mentionnés ci-dessus. Il utilise du JavaScript natif pour communiquer avec le navigateur. Cependant, il fournit un accès de bas niveau au CDP, ce qui signifie qu'il est possible d'envoyer des commandes CDP brutes pour utiliser l'authentificateur virtuel WebAuthn du CDP.

Substack Icon

Subscribe to our Passkeys Substack for the latest news.

Subscribe

Parce que la syntaxe de cet accès de bas niveau est fastidieuse et très différente des exemples ci-dessus, nous n'entrerons pas dans les détails dans ce guide. Cependant, de plus amples informations sur la manière d'appeler les commandes CDP dans Cypress sont expliquées dans ce guide. Les concepts généraux d'utilisation de l'authentificateur virtuel WebAuthn du CDP présentés dans ce guide restent pertinents pour ceux qui cherchent à tester les passkeys sur Cypress.

3. Qu'est-ce qui rend les tests E2E des passkeys avec Playwright problématiques ?#

Il y a de nombreuses raisons pour lesquelles tester l'implémentation des passkeys est naturellement plus difficile que d'autres actions utilisateur plus simples dans un environnement web. La nécessité de gérer les interactions utilisateur dynamiques impliquées dans l'authentification biométrique, comme la lecture d'empreintes digitales ou la reconnaissance faciale, ajoute une couche de complexité qui pourrait ne pas être pratique à aborder en détail lors de l'écriture des tests. Comme la sécurité est naturellement une préoccupation majeure dans le contexte de l'authentification, il est également nécessaire de s'assurer que l'authentification par passkey est intégrée de manière transparente sur divers navigateurs et appareils sans laisser de place à des vulnérabilités de sécurité.

4. L'authentificateur virtuel WebAuthn rend les tests E2E des passkeys possibles#

La simplification de la complexité de la gestion des interactions utilisateur dynamiques impliquées dans les opérations de passkey, ainsi que le test de son intégration dans différents navigateurs et appareils, sont facilités par l'utilisation de l'authentificateur virtuel WebAuthn.

4.1. Qu'est-ce que l'authentificateur virtuel WebAuthn ?#

L'authentificateur virtuel WebAuthn est une représentation logicielle du modèle d'authentificateur spécifié dans la norme WebAuthn. Il émule le comportement d'un appareil authentificateur physique, tel qu'une clé de sécurité matérielle (par ex. YubiKey) ou un scanner biométrique (par ex. utilisé dans Face ID, Touch ID ou Windows Hello), mais fonctionne entièrement de manière logicielle (aucune authentification physique ou lecture de données biométriques n'est donc impliquée).

4.2. Quels sont les avantages de l'authentificateur virtuel WebAuthn ?#

L'authentificateur virtuel WebAuthn présente deux avantages principaux.

4.2.1. Tests automatisés avec l'authentificateur virtuel WebAuthn#

Comme WebDriver et le CDP sont des outils d'automatisation de navigateur, il est évident que le principal cas d'utilisation de l'implémentation de l'authentificateur virtuel WebAuthn dans ces protocoles est le test automatisé. En tirant parti de ces protocoles, l'authentificateur virtuel permet des tests simples mais complets des fonctionnalités de passkey dans des environnements contrôlés tels que les frameworks de test E2E (par ex. Playwright, Cypress, Nightwatch).

4.2.2. Tests manuels et démonstration avec l'authentificateur virtuel WebAuthn#

L'authentificateur virtuel WebAuthn du CDP est également accessible via les DevTools du navigateur Chrome, et il peut être utilisé pour des tests manuels ou simplement à des fins de démonstration. Avec cette fonctionnalité, vous pouvez simuler une saisie de passkey sur un appareil qui ne prend pas en charge nativement les passkeys. De même, il est également possible de simuler un environnement non compatible avec les passkeys sur un appareil qui les prend en charge.

La capture d'écran ci-dessus montre un exemple d'utilisation de l'authentificateur virtuel dans Chrome à des fins de test manuel ou de démonstration. Vous pouvez voir que différentes options de configuration pour l'authentificateur virtuel sont possibles, et que l'ajout et la suppression d'informations d'identification peuvent également être suivis. Consultez ce guide de Google pour plus d'informations sur l'utilisation de l'authentificateur virtuel dans votre navigateur, y compris les options de configuration et les valeurs recommandées pour chacune.

4.3. Quels sont les inconvénients de l'authentificateur virtuel WebAuthn ?#

Bien que l'authentificateur virtuel WebAuthn soit une solution élégante pour tester les implémentations de passkeys, il y a quelques inconvénients à noter.

4.3.1. Incapacité à simuler les fonctionnalités spécifiques au matériel#

Étant une solution purement logicielle, l'authentificateur virtuel WebAuthn ne peut pas répliquer les caractéristiques matérielles uniques et les fonctionnalités de sécurité des authentificateurs physiques. La distinction entre l'utilisation de divers authentificateurs de plateforme (qui sont intégrés à un appareil, comme un scanner biométrique sur un smartphone) et de divers authentificateurs multiplateformes (qui sont des appareils externes, comme les clés de sécurité matérielles) ne peut pas être simulée à l'aide de l'authentificateur virtuel WebAuthn. Bien que la simplification en boîte noire des complexités liées aux différents types d'authentificateurs de plateforme et multiplateformes soit l'un des avantages de l'utilisation de l'authentificateur virtuel WebAuthn, si vous cherchez à simuler et à tester les nuances des différents types d'authentificateurs, d'autres solutions doivent être explorées.

4.3.2. Documentation éparse et problèmes techniques non résolus#

Étant donné l'adoption relativement récente de WebAuthn et la nouveauté de la technologie des passkeys, l'écosystème entourant les authentificateurs virtuels est encore en cours de maturation. Cela se traduit par une pénurie de documentation complète et des défis techniques non résolus, en particulier dans le contexte de l'intégration des authentificateurs virtuels avec les frameworks de tests automatisés. Ce guide vise à résoudre ce problème en fournissant des informations complètes sur les tests de passkeys dans un environnement de test automatisé, tout en se concentrant sur les inconvénients encore présents dans l'utilisation de ces outils et en présentant des solutions de contournement pour ces problèmes.

5. Comment configurer l'authentificateur virtuel WebAuthn dans Playwright#

Après une installation réussie de Playwright et de ses dépendances, vous pouvez commencer immédiatement à écrire votre premier test en créant un fichier dont le nom se termine par .spec.ts ou .test.ts avec le contenu suivant :

import { test, expect } from "@playwright/test"; test("my first test", async ({ page }) => { await page.goto("https://passkeys.eu"); // start simulating user actions });

Pour utiliser l'authentificateur virtuel WebAuthn dans Playwright, il suffit d'initier une session CDP et d'attacher un authentificateur virtuel au début d'un cas de test, comme suit :

test('signup with passkey', async ({ page }) => { // Initialize a CDP session for the current page const client = await page.context().newCDPSession(page); // Enable WebAuthn environment in this session await client.send('WebAuthn.enable'); // Attach a virtual authenticator with specific options const result = await client.send('WebAuthn.addVirtualAuthenticator', { options: { protocol: 'ctap2', transport: 'internal', hasResidentKey: true, hasUserVerification: true, isUserVerified: true, automaticPresenceSimulation: false, }, }); const authenticatorId = result.authenticatorId; // Further test steps to simulate user interactions and assertions ... });

Options de configuration de l'authentificateur virtuel WebAuthn :

  • protocol : Cette option spécifie le protocole utilisé par l'authentificateur virtuel. Les valeurs possibles sont « ctap2 » et « u2f »
  • transport : Cette option spécifie le type d'authentificateur que l'authentificateur virtuel simule. Les valeurs possibles sont « usb », « nfc », « ble » et « internal ». Si la valeur est « internal », il simule un authentificateur de plateforme, tandis que les autres valeurs simulent des authentificateurs multiplateformes.
  • hasResidentKey : Le définir sur true prend en charge la Resident Key (c'est-à-dire les informations d'identification détectables côté client).
  • hasUserVerification : Le définir sur true prend en charge la vérification de l'utilisateur (User Verification). Il est recommandé de le définir sur true car cela permet de simuler une saisie de passkey réussie ou échouée.
  • isUserVerified : Le définir sur true émule un scénario d'authentification réussi, tandis que false simule un échec d'authentification, par exemple lorsqu'un utilisateur annule la saisie du passkey. Notez que ce paramètre n'est effectif que si hasUserVerification est défini sur true.
  • automaticPresenceSimulation : Lorsqu'il est défini sur true, la saisie du passkey se produit automatiquement et immédiatement à chaque invite d'authentification. Inversement, le définir sur false nécessite une initiation manuelle de la simulation d'authentification par passkey dans le code de test. Opter pour la simulation manuelle (false) est recommandé pour deux raisons :
    • Amélioration de la lisibilité du code de test : La simulation automatique peut obscurcir la compréhension du flux de test, car les tentatives d'authentification sont simulées sans déclencheurs explicites dans le code de test.
    • Éviter les comportements non intentionnels : La simulation automatique signifie que la saisie du passkey sera déclenchée même si le testeur n'est pas conscient que le passkey a été demandé. C'est particulièrement un problème pour l'UI conditionnelle (Conditional UI) que le testeur pourrait plus facilement ignorer.

6. Cas d'utilisation de l'authentificateur virtuel WebAuthn#

Dans cette section, nous explorons l'utilisation des méthodes et des événements de l'authentificateur virtuel WebAuthn dans le contexte de cas d'utilisation courants et plus marginaux.

6.1. Comment simuler une tentative de saisie de passkey dans Playwright#

C'est peut-être la tâche la plus importante mais aussi la plus déroutante lors de l'utilisation de l'authentificateur virtuel WebAuthn dans un code de test, car il n'existe pas de méthode intégrée explicite pour déclencher une saisie de passkey. La solution réside dans les options de configuration de l'authentificateur virtuel WebAuthn, à savoir isUserVerified et automaticPresenceSimulation. Avec ces options, nous pouvons simuler cette interaction utilisateur via deux approches différentes décrites ci-dessous.

6.1.1. Approche 1 : Simulation automatique avec automaticPresenceSimulation défini sur true#

Cas 1 : Simuler une saisie de passkey réussie

test('signup with passkey', async ({ page }) => { ... await expect(page.getByRole('heading', { level: 1 })).toHaveText('Please log in'); await page.getByRole('button', { name: 'Login' }).click(); // successful passkey input is automatically simulated (isUserVerified=true) await expect(page.getByRole('heading', { level: 1 })).toHaveText('Welcome!'); ... });

La simulation d'une saisie de passkey réussie ne nécessite généralement aucune ligne supplémentaire dans le code de test. La dernière ligne (await expect...) attend que la page change (déclenché par la saisie implicite et réussie du passkey).

Cas 2 : Simuler une saisie de passkey annulée (qui ne déclenche pas de changements dans l'interface utilisateur)

Tester une saisie de passkey échouée ou annulée est plus compliqué car cela peut ne pas entraîner de changements observables dans l'interface utilisateur. En d'autres termes, attendre que la page change comme dans l'exemple précédent n'est pas suffisant pour s'assurer que la saisie du passkey a terminé son traitement. Vérifier que la page n'a pas changé après la saisie implicite du passkey n'a pas de sens, car la vérification se produira presque certainement avant que la saisie du passkey n'ait terminé son traitement. Bien que l'authentificateur virtuel offre un moyen d'attendre qu'une saisie de passkey réussie soit traitée en écoutant l'émission d'un événement (comme nous le verrons dans l'approche 2), il n'existe actuellement aucun moyen intégré de détecter une saisie de passkey échouée ou annulée. Une solution de contournement consisterait à simplement ajouter un délai d'attente fixe pour attendre que l'opération de passkey se termine avant de vérifier que l'interface utilisateur est bien restée la même.

test('signup with passkey', async ({ page }) => { // Simulate a set of user actions to trigger a passkey prompt ... await expect(page.getByRole('heading', { level: 1 })).toHaveText('Please log in'); // Simulate passkey input when prompted in the test await inputPasskey(async () => { await page.waitForTimeout(300); await expect(page.getByRole('heading', { level: 1 })).toHaveText('Please log in'); }); // Further test steps ... });

Dans les deux cas, la lisibilité du code de test est limitée par le caractère implicite de l'opération de passkey. Comme mentionné précédemment, il serait également facile d'ignorer le moment où une UI conditionnelle (Conditional UI) pourrait être demandée, auquel cas l'opération de passkey se terminerait automatiquement à l'insu du testeur.

6.1.2. Approche 2 : Simulation manuelle avec automaticPresenceSimulation défini sur false#

Déclencher manuellement une saisie de passkey en changeant la valeur de l'option automaticPresenceSimulation résout les problèmes rencontrés dans l'approche précédente, notamment en termes de lisibilité du code de test.

Cas 1 : Simuler une saisie de passkey réussie

Les extraits de code suivants simulent une saisie de passkey réussie :

async simulateSuccessfulPasskeyInput(operationTrigger: () => Promise<void>) { // initialize event listeners to wait for a successful passkey input event const operationCompleted = new Promise<void>(resolve => { client.on('WebAuthn.credentialAdded', () => resolve()); client.on('WebAuthn.credentialAsserted', () => resolve()); }); // set isUserVerified option to true // (so that subsequent passkey operations will be successful) await client.send('WebAuthn.setUserVerified', { authenticatorId: authenticatorId, isUserVerified: true, }); // set automaticPresenceSimulation option to true // (so that the virtual authenticator will respond to the next passkey prompt) await client.send('WebAuthn.setAutomaticPresenceSimulation', { authenticatorId: authenticatorId, enabled: true, }); // perform a user action that triggers passkey prompt await operationTrigger(); // wait to receive the event that the passkey was successfully registered or verified await operationCompleted; // set automaticPresenceSimulation option back to false await client.send('WebAuthn.setAutomaticPresenceSimulation', { authenticatorId, enabled: false, }); }
test('signup with passkey', async ({ page }) => { ... // Simulate passkey input with a promise that triggers a passkey prompt as the argument await simulateSuccessfulPasskeyInput(() => page.getByRole('button', { name: 'Create account with passkeys' }).click() ); ... });

La fonction d'assistance peut être assez intimidante au premier abord. Il est utile de comprendre que toutes les complexités techniques de la simulation d'une opération de passkey sont abstraites dans la fonction d'assistance. Cela signifie que lorsqu'elle est utilisée dans le code de test, elle rend le code simple et clair, comme on peut le voir dans le deuxième extrait de code ci-dessus.

Comparée à l'approche implicite de la section 6.1.1, cette approche explicite augmente également la lisibilité du code. Ce serait particulièrement utile lorsqu'une UI conditionnelle (Conditional UI) est demandée, car cette approche explicite empêche l'achèvement implicite et non intentionnel de l'opération de passkey à l'insu du développeur.

Comprenons maintenant chaque partie de la fonction d'assistance.

D'abord, nous définissons la promesse operationCompleted qui attend soit l'événement WebAuthn.credentialAdded, soit l'événement WebAuthn.credentialAsserted, qui sont, comme leur nom l'indique, émis respectivement lorsqu'une information d'identification de passkey est enregistrée ou vérifiée. Cette promesse sera utilisée plus tard.

Ensuite, l'option isUserVerified est définie sur true, afin que l'opération de passkey suivante par l'authentificateur virtuel WebAuthn réussisse. L'option automaticPresenceSimulation est également définie sur true, afin que l'authentificateur virtuel WebAuthn réponde à la prochaine invite de passkey de la page web.

L'attente de la promesse operationTrigger est nécessaire pour éviter une condition de concurrence. La condition de concurrence se produit lorsque la page web demande le passkey avant que automaticPresenceSimulation ne soit défini sur true. Pour éviter cela, l'action de l'utilisateur qui déclenche l'invite de passkey doit être effectuée après que automaticPresenceSimulation a été défini sur true. Dans l'exemple ci-dessus, l'utilisateur clique sur le bouton nommé « Create account with passkeys » pour déclencher l'invite de passkey.

Une fois l'action de l'utilisateur terminée, nous devons attendre que l'opération de passkey réussie se termine. Cela se fait en attendant la promesse que nous avons définie au début de la fonction d'assistance. L'achèvement de l'opération de passkey réussie est marqué par l'émission de l'événement WebAuthn.credentialAdded ou WebAuthn.credentialAsserted. Dans l'exemple ci-dessus, comme l'utilisateur enregistre un passkey, l'événement WebAuthn.credentialAdded serait émis.

Enfin, l'option automaticPresenceSimulation est redéfinie sur false, pour empêcher que des opérations de passkey non intentionnelles ne se produisent plus tard dans le code de test.

Cas 2 : Simuler une saisie de passkey annulée

Pour une saisie de passkey annulée, nous devons apporter une légère modification à l'implémentation du cas précédent. Dans le cas d'une saisie de passkey réussie, il y a des événements, à savoir WebAuthn.credentialAdded et WebAuthn.credentialAsserted, qui sont émis à la fin de l'opération. Cependant, l'authentificateur virtuel WebAuthn ne fournit aucun événement pour une saisie de passkey annulée ou échouée. Nous devons donc utiliser un autre moyen pour vérifier l'achèvement d'une opération de passkey annulée ou échouée.

Les extraits de code suivants simulent une saisie de passkey échouée :

async simulateFailedPasskeyInput(operationTrigger: () => Promise<void>, postOperationCheck: () => Promise<void>) { // set isUserVerified option to false // (so that subsequent passkey operations will fail) await client.send('WebAuthn.setUserVerified', { authenticatorId: authenticatorId, isUserVerified: false, }); // set automaticPresenceSimulation option to true // (so that the virtual authenticator will respond to the next passkey prompt) await client.send('WebAuthn.setAutomaticPresenceSimulation', { authenticatorId: authenticatorId, enabled: true, }); // perform a user action that triggers passkey prompt await operationTrigger(); // wait for an expected UI change that indicates the passkey operation has completed await postOperationCheck(); // set automaticPresenceSimulation option back to false await client.send('WebAuthn.setAutomaticPresenceSimulation', { authenticatorId, enabled: false, }); }
test('signup with passkey', async ({ page }) => { // Simulate a set of user actions to trigger a passkey prompt ... await expect(page.getByRole('heading', { level: 1 })).toHaveText('Please log in'); // Simulate passkey input when prompted in the test await inputPasskey(async () => { await page.waitForTimeout(300); await expect(page.getByRole('heading', { level: 1 })).toHaveText('Please log in'); }); // Further test steps ... });

Dans la fonction d'assistance, les écouteurs d'événements sont remplacés par un paramètre de promesse postOperationCheck qui attend qu'un changement d'interface utilisateur attendu se produise avant que automaticPresenceSimulation puisse être redéfini sur false.

Dans le code de test, la seule différence est que la fonction d'assistance doit être appelée avec une promesse supplémentaire qui vérifie le changement d'interface utilisateur prévu. Dans l'exemple ci-dessus, nous vérifions que l'application web a bien navigué vers une page dont l'en-tête contient le texte « Something went wrong... ».

Comme nous l'avons vu dans la section 6.1.1, l'annulation d'une saisie de passkey peut ne pas entraîner de changement observable dans l'interface utilisateur. Comme dans l'exemple fourni dans cette section, nous devons ajouter une attente fixe avant de vérifier que l'interface utilisateur est bien restée la même dans de tels cas :

test('signup with passkey', async ({ page }) => { ... await expect(page.getByRole('heading', { level: 1 })).toHaveText('Please log in'); // Simulate passkey input with a promise that triggers a passkey prompt as the argument await simulateFailedPasskeyInput( () => page.getByRole('button', { name: 'Create account with passkeys' }).click(), async () => { await page.waitForTimeout(300); await expect(page.getByRole('heading', { level: 1 })).toHaveText('Please log in'); } ); ... });

6.2. Comment tester la création de passkeys#

La commodité d'utiliser un authentificateur virtuel WebAuthn est renforcée par sa capacité à se comporter comme un véritable authentificateur en cas de création ou de suppression de passkey par l'application web. Un test doit simplement effectuer des actions utilisateur pour simuler la création ou la suppression d'un passkey sur l'application web, et l'authentificateur virtuel WebAuthn modifie automatiquement ses informations d'identification enregistrées sans aucun travail supplémentaire de la part du code de test.

Voici l'exemple de code de test qui vérifie que l'application web enregistre correctement un nouveau passkey dans l'authentificateur :

test('signup with passkey', async ({ page }) => { ... // Confirm there are currently no registered credentials const result1 = await client.send('WebAuthn.getCredentials', { authenticatorId }); expect(result1.credentials).toHaveLength(0); // Perform user actions to simulate creation of a passkey credential (e.g. user registration with passkey input) ... // Confirm the passkey was successfully registered const result2 = await client.send('WebAuthn.getCredentials', { authenticatorId }); expect(result2.credentials).toHaveLength(1); ... });

En combinant cet extrait de code avec ceux de la section 6.1, nous pouvons tester le flux d'inscription sur notre page de démonstration. La vidéo suivante est une visualisation du test en mode UI de Playwright :

6.3. Comment tester la vérification des passkeys#

La vérification d'une information d'identification de passkey avec l'authentificateur virtuel WebAuthn fonctionne de manière similaire à la création d'un passkey, en ce sens que l'authentificateur virtuel suit automatiquement le nombre de vérifications effectuées à l'aide d'une information d'identification particulière.

test('login with passkey', async ({ page }) => { ... // Confirm there is only one credential, and save its signCount const result1 = await client.send('WebAuthn.getCredentials', { authenticatorId }); expect(result1.credentials).toHaveLength(1); const signCount1 = result1.credentials[0].signCount; // Perform user actions to simulate verification of a passkey credential (e.g. login with passkey input) ... // Confirm the credential's new signCount is greater than the previous signCount const result2 = await client.send('WebAuthn.getCredentials', { authenticatorId }); expect(result2.credentials).toHaveLength(1); expect(result2.credentials[0].signCount).toBeGreaterThan(signCount1); ... });

La vidéo suivante montre un test du flux de connexion sur notre page de démonstration :

6.4. Comment tester la suppression des passkeys#

La suppression d'un passkey d'une application web, en revanche, ne devrait modifier aucune information dans l'authentificateur virtuel WebAuthn. L'application web ne devrait pouvoir supprimer que les informations d'identification enregistrées sur son propre serveur. Seul l'utilisateur lui-même devrait pouvoir supprimer consciemment et manuellement une information d'identification de passkey de l'authentificateur virtuel WebAuthn.

test('delete a registered passkey credential', async ({ page }) => { ... // Confirm there is currently one registered credential const result1 = await client.send('WebAuthn.getCredentials', { authenticatorId }); expect(result1.credentials).toHaveLength(1); // Perform user actions to simulate deletion of a passkey credential ... // Deleting a passkey credential from a website should not remove the credential from the authenticator const result2 = await client.send('WebAuthn.getCredentials', { authenticatorId }); expect(result2.credentials).toHaveLength(1); ... });

La vidéo suivante montre un test de suppression d'une information d'identification de passkey sur notre page de démonstration :

6.5. Comment simuler l'authentification inter-appareils#

La manière la plus intuitive de simuler une authentification inter-appareils à partir d'un deuxième appareil (qui n'a pas encore de passkey enregistré) est de simplement ajouter une nouvelle instance de l'authentificateur virtuel WebAuthn via la commande CDP, comme ceci :

test('signup with passkey', async ({ page }) => { ... // add a virtual authenticator for the first device const authenticatorId1 = await client.send('WebAuthn.addVirtualAuthenticator', { options }); // perform test actions of the first device ... // add a virtual authenticator for the second device const authenticatorId2 = await client.send('WebAuthn.addVirtualAuthenticator', { options }); // perform test actions of the second device .. });

Pour éviter la complexité de la gestion des ID de plusieurs authentificateurs virtuels, il est également possible de simuler un nouvel appareil en supprimant simplement les informations d'identification d'un seul authentificateur, et en les rajoutant si nécessaire :

test('signup with passkey', async ({ page }) => { ... const result = await client.send('WebAuthn.getCredentials', { authenticatorId }); const credential = result.credentials[0]; // assuming only one registered passkey const credentialId = credential.credentialId; await client.send('WebAuthn.removeCredential', { authenticatorId, credentialId }); // Perform test actions of the second device which doesn't have a registered passkey ... // Call if it's necessary to simulate the first device which has a registered passkey await client.send('WebAuthn.addCredential', { credential }); // Perform test actions of the first device ... });

Cette approche peut particulièrement simplifier l'implémentation dans le cas où un nouvel appareil doit être simulé, mais l'ancien appareil n'a plus besoin d'être utilisé. Dans ce cas, il vous suffit de vider les informations d'identification de l'authentificateur virtuel et de les supprimer complètement :

test('signup with passkey', async ({ page }) => { ... const result = await client.send('WebAuthn.getCredentials', { authenticatorId }); const credential = result.credentials[0]; // assuming only one registered passkey const credentialId = credential.credentialId; await client.send('WebAuthn.clearCredentials', { authenticatorId }); // Perform test actions of the second device which doesn't have a registered passkey ... });

7. Alternatives à l'authentificateur virtuel WebAuthn#

L'exploration d'alternatives à l'authentificateur virtuel WebAuthn peut offrir de la flexibilité dans la manière dont les processus d'authentification par passkey / WebAuthn sont testés au sein des projets.

7.1. Tests avec des services simulés (mock)#

Le développement de services ou de points de terminaison simulés (mock) peut simuler efficacement le comportement d'authentification, simplifiant les tests en faisant abstraction des subtilités du mécanisme d'authentification réel. Cette approche est particulièrement bénéfique lorsque des services d'authentification externes sont utilisés, permettant de se concentrer sur l'intégration et la fonctionnalité des composants du système sans entrer dans les détails de l'authentification.

7.2. Tests d'intégration avec de vrais authentificateurs#

Pour un examen approfondi des fonctionnalités d'authentification, l'utilisation de vrais authentificateurs pour les tests d'intégration fournit un aperçu détaillé de l'interaction avec les clés de sécurité matérielles (par ex. YubiKeys) ou les appareils biométriques (par ex. utilisés dans Face ID, Touch ID ou Windows Hello). Bien que généralement effectués manuellement en raison de la nature complexe de l'intégration d'appareils réels dans des tests automatisés, il est possible de développer des scripts d'automatisation personnalisés. Ces scripts peuvent faire le pont entre les vrais authentificateurs et les frameworks de test de bout en bout, offrant une approximation plus proche des scénarios utilisateur réels et améliorant la fiabilité du processus d'authentification dans les environnements de production.

8. Recommandations pour les développeurs#

Après avoir démontré les différentes options et présenté des extraits de code spécifiques pour les tests E2E des passkeys / WebAuthn avec Playwright, nous souhaitons également fournir quelques recommandations plus générales aux développeurs qui découvrent le sujet.

8.1. Étudiez le paysage des frameworks de test E2E#

Avant de vous lancer dans les tests de passkeys ou de tout autre mécanisme d'authentification, il est essentiel d'évaluer les frameworks de test E2E disponibles et de choisir l'option la plus appropriée en fonction des exigences de votre projet. Considérez le compromis entre la vitesse et la stabilité offertes par les frameworks basés sur le CDP comme Playwright et Puppeteer, et la compatibilité multi-navigateurs fournie par les frameworks basés sur WebDriver comme Selenium et Nightwatch. Alors que les frameworks basés sur le CDP offrent une automatisation de navigateur plus rapide et plus stable, ils sont limités aux navigateurs basés sur Chromium. En revanche, les frameworks basés sur WebDriver offrent une compatibilité multi-navigateurs plus large, y compris la prise en charge des navigateurs non-Chromium comme Firefox et Safari, bien qu'avec des performances potentiellement plus lentes et moins stables. Comprendre ces compromis vous aidera à prendre une décision éclairée et à sélectionner le framework qui correspond le mieux aux besoins de votre projet.

8.2. Comprenez les concepts sous-jacents de WebAuthn et des passkeys#

Bien que l'authentificateur virtuel WebAuthn simplifie le processus de test des implémentations de passkeys, il est crucial pour les développeurs d'avoir une solide compréhension des concepts sous-jacents de la norme WebAuthn et des passkeys. Familiarisez-vous avec les différentes configurations disponibles pour l'authentificateur virtuel WebAuthn, telles que protocol, transport, hasResidentKey, hasUserVerification et isUserVerified. La compréhension de ces configurations vous permettra d'affiner l'authentificateur virtuel pour simuler avec précision divers scénarios d'authentification. De plus, plongez dans les subtilités de l'authentification par passkey, y compris son intégration avec différents navigateurs et appareils, ainsi que les considérations de sécurité potentielles. Ces connaissances fondamentales vous permettront de concevoir des stratégies de test complètes et efficaces pour l'authentification par passkey dans vos applications web.

9. Résumé#

Ce guide a exploré l'utilisation de l'authentificateur virtuel WebAuthn du CDP avec Playwright, en mettant en évidence des concepts avancés et en abordant des problèmes non couverts par la documentation officielle. Nous avons également exploré des alternatives au CDP au sein de Playwright et d'autres frameworks de test E2E. Malgré des implémentations variables, les spécifications standardisées de l'authentificateur virtuel WebAuthn garantissent la pertinence de ce guide à travers différents protocoles d'automatisation web et frameworks de test de bout en bout. Pour en savoir plus sur les différents concepts relatifs aux passkeys, consultez notre glossaire des terminologies pertinentes qui pourraient vous aider à affiner l'authentificateur virtuel WebAuthn en fonction de vos besoins.

Add passkeys to your app in <1 hour with our UI components, SDKs & guides.

Start for free

Share this article


LinkedInTwitterFacebook

Enjoyed this read?

🤝 Join our Passkeys Community

Share passkeys implementation tips and get support to free the world from passwords.

🚀 Subscribe to Substack

Get the latest news, strategies, and insights about passkeys sent straight to your inbox.

Related Articles

Table of Contents