---
url: 'https://www.corbado.com/it/blog/passkeys-e2e-playwright-test-webauthn-autenticatore-virtuale'
title: 'Test E2E delle Passkey con Playwright tramite l''Autenticatore Virtuale WebAuthn'
description: 'Impara a configurare i test E2E per le passkey su diversi browser con Playwright, Nightwatch, Selenium e Puppeteer utilizzando l''autenticatore virtuale WebAuthn.'
lang: 'it'
author: 'Anders'
date: '2025-06-17T16:16:35.215Z'
lastModified: '2026-03-25T10:46:52.309Z'
keywords: 'test e2e, test end-to-end'
category: 'Passkeys Implementation'
---

# Test E2E delle Passkey con Playwright tramite l'Autenticatore Virtuale WebAuthn

> **La nostra missione è rendere Internet un posto più sicuro**, e il nuovo standard di
> login, le passkey, fornisce una soluzione superiore per raggiungere questo obiettivo.
> Ecco perché vogliamo aiutarti a comprendere meglio le passkey e le loro caratteristiche.

## 1. Introduzione: Test E2E delle Passkey

Le passkey stanno diventando sempre più accettate come metodo di
[autenticazione](https://www.corbado.com/it/blog/come-passare-autenticazione-completamente-passwordless),
basandosi su Web Authentication (WebAuthn) come standard sottostante. La loro crescente
popolarità è piuttosto recente, il che rende la documentazione e altre risorse
relativamente scarse. Questo, insieme alla natura complessa dell'implementazione delle
passkey, può rendere difficile per gli sviluppatori trovare informazioni pertinenti sulla
progettazione, l'implementazione e soprattutto il test delle passkey per le loro
piattaforme e servizi.

Questa guida mira a colmare questa lacuna, concentrandosi sugli aspetti dell'autenticatore
virtuale WebAuthn non trattati in modo approfondito nella sua documentazione ufficiale. Ad
esempio, discutiamo le opzioni di configurazione per l'autenticatore virtuale che non sono
autoesplicative nella documentazione, così come le soluzioni alternative per alcuni casi
d'uso per i quali l'autenticatore virtuale non fornisce una soluzione comoda. Altrimenti,
questa guida è utile anche per gli sviluppatori che cercano semplicemente esempi facili da
seguire per utilizzare l'autenticatore virtuale nel codice di test.

La nostra guida utilizza esempi di
[Playwright](https://www.corbado.com/blog/passkeys-e2e-playwright-testing-webauthn-virtual-authenticator) per
fornire una semplice procedura per testare efficacemente l'implementazione delle passkey
nel tuo progetto.
[Playwright](https://www.corbado.com/blog/passkeys-e2e-playwright-testing-webauthn-virtual-authenticator) è un
framework di test end-to-end (E2E) che utilizza il Chrome DevTools Protocol (CDP) come
protocollo per l'automazione del browser. Se stai cercando specificamente esempi tecnici
di test delle passkey in
[Playwright](https://www.corbado.com/blog/passkeys-e2e-playwright-testing-webauthn-virtual-authenticator), puoi
passare direttamente alla Sezione 5. D'altra parte, se stai utilizzando altri framework di
test E2E come
[Puppeteer](https://www.corbado.com/blog/passkeys-e2e-playwright-testing-webauthn-virtual-authenticator) o
[Selenium](https://www.corbado.com/blog/selenium-passkeys-testing-nodejs) e desideri testare le passkey su questi
framework, le implementazioni del codice di test saranno identiche o molto simili agli
esempi forniti in questa guida, a seconda del framework che stai utilizzando. Nella
prossima sezione forniremo un background sui diversi framework di test E2E e su quanto
questa guida sarà pertinente per questi framework.

## 2. Background: Automazione del Browser e Framework di Test E2E

### 2.1. Cos'è l'automazione del browser?

L'automazione del browser, come suggerisce il nome, è il processo di automatizzare azioni
ripetitive dell'utente sul browser allo scopo di estrarre dati dal web o, nel nostro caso,
di testare applicazioni web. WebDriver e Chrome DevTools Protocol (CDP) sono due dei
principali protocolli di automazione del browser rilevanti per questa guida, poiché
entrambi forniscono un'implementazione dell'autenticatore virtuale WebAuthn.

### 2.2. Cos'è WebDriver?

WebDriver è un'interfaccia controllata a distanza che può essere vista come un
intermediario nella comunicazione tra il client e il browser. L'obiettivo di questo
protocollo è fornire un'interfaccia neutrale rispetto alla piattaforma e al linguaggio che
supporti tutti i principali browser, inclusi quelli non basati su Chromium come Firefox e
Safari. Poiché l'interfaccia WebDriver deve gestire una connessione sia con il client che
con il browser, questo approccio sacrifica velocità e stabilità in cambio di un più ampio
supporto di browser (cioè una maggiore instabilità o 'flakiness'). Client WebDriver
notevoli includono [Selenium](https://www.corbado.com/blog/selenium-passkeys-testing-nodejs) e
[Nightwatch](https://www.corbado.com/blog/passkeys-e2e-playwright-testing-webauthn-virtual-authenticator).

![Client WebDriver per Passkey con Playwright](https://www.corbado.com/website-assets/66090bb89296b283f07f69eb_passkeys_playwright_webdriver_client_1efc6dec0e.jpg)

Tratto da jankaritech

### 2.3. Cos'è il Chrome DevTools Protocol (CDP)?

Il Chrome DevTools Protocol (CDP), d'altra parte, non ha un intermediario come
l'interfaccia WebDriver tra il client e il browser. Inoltre, la comunicazione tra il
client e il browser avviene tramite una connessione socket, in contrasto con la più lenta
connessione HTTP tra il client e l'interfaccia WebDriver nell'approccio precedente. Questi
punti rendono il CDP molto più veloce e meno instabile ('flaky') di WebDriver. Lo
svantaggio è che questo protocollo è supportato solo per i browser basati su Chromium come
Chrome ed Edge. Playwright e
[Puppeteer](https://www.corbado.com/blog/passkeys-e2e-playwright-testing-webauthn-virtual-authenticator) sono
esempi di client che utilizzano il CDP per comunicare con i browser.

![Client CDP per Passkey con Playwright](https://www.corbado.com/website-assets/66090be6820f38fba3e156f3_passkeys_playwright_cdp_client_44e000d341.jpg)

Tratto da jankaritech

### 2.4. Puppeteer e Playwright come framework di test E2E basati su CDP

[Puppeteer](https://www.corbado.com/blog/passkeys-e2e-playwright-testing-webauthn-virtual-authenticator), simile
a Playwright, è un framework E2E costruito direttamente sul CDP. Ciò significa che
Puppeteer e Playwright utilizzano entrambi la stessa implementazione dell'autenticatore
virtuale WebAuthn e che anche la comunicazione API tramite l'autenticatore virtuale
WebAuthn via connessione socket è identica.

Per dimostrare, confrontiamo il codice di test sia in Playwright che in Puppeteer per
chiamare il metodo getCredentials che restituisce un elenco di tutte le credenziali
registrate finora nell'autenticatore virtuale. Alleghiamo anche un semplice listener di
eventi per l'evento credentialAdded che viene attivato quando una credenziale passkey
viene registrata con successo. Non lasciarti intimidire dai dettagli dell'implementazione,
poiché saranno spiegati nelle sezioni successive. Questi esempi servono semplicemente a
dimostrare quanto siano simili le implementazioni tra i due framework.

**Playwright:**

```js
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:**

```js
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!');
});
```

Sebbene i metodi per inizializzare la sessione CDP all'inizio dei codici di test fossero
leggermente diversi, la chiamata dei metodi e la gestione degli eventi nell'API
dell'autenticatore virtuale WebAuthn del CDP è identica. Ciò significa che se stai
cercando di utilizzare l'autenticatore virtuale WebAuthn in Puppeteer, puoi seguire questa
guida riga per riga.

### 2.5. Selenium e Nightwatch come framework di test E2E basati su WebDriver

[Selenium](https://www.corbado.com/blog/selenium-passkeys-testing-nodejs) e
[Nightwatch](https://www.corbado.com/blog/passkeys-e2e-playwright-testing-webauthn-virtual-authenticator) sono
framework di test E2E che si basano su WebDriver per l'automazione del browser. Sebbene
l'implementazione dell'autenticatore virtuale WebAuthn per WebDriver sia separata dalla
sua implementazione per CDP, le loro specifiche API sono simili. Per quasi ogni metodo
nell'API dell'autenticatore virtuale WebAuthn del CDP, puoi trovare un metodo
corrispondente nell'API dell'autenticatore virtuale WebAuthn di WebDriver. Tuttavia, una
cosa da notare è che mentre era possibile associare listener di eventi per quando una
passkey viene aggiunta o asserita con successo nell'API dell'autenticatore virtuale
WebAuthn del CDP, questo non è possibile nella controparte WebDriver.

**Selenium:**

```js
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();
```

È evidente che la sintassi per configurare l'istanza dell'autenticatore virtuale e fare
chiamate API è diversa dalla corrispondente implementazione CDP. Tuttavia, poiché le
specifiche API dei due autenticatori virtuali WebAuthn sono molto simili, sarebbe
fattibile seguire questa guida per scrivere un'implementazione corrispondente su un
framework di test E2E basato su WebDriver.

### 2.6. Cypress come framework di test E2E con scripting nativo

[Cypress](https://www.corbado.com/blog/passkeys-e2e-playwright-testing-webauthn-virtual-authenticator) è un
framework di test E2E che non è costruito principalmente su WebDriver o CDP come i
framework menzionati sopra. Utilizza JavaScript nativo per comunicare con il browser.
Tuttavia, fornisce un accesso a basso livello al CDP, il che significa che è possibile
inviare comandi CDP grezzi per utilizzare l'autenticatore virtuale WebAuthn del CDP.

Poiché la sintassi per questo accesso a basso livello è noiosa e molto diversa dagli
esempi precedenti, non entreremo nei dettagli in questa guida. Tuttavia, ulteriori
informazioni su come chiamare i comandi CDP in
[Cypress](https://www.corbado.com/blog/passkeys-e2e-playwright-testing-webauthn-virtual-authenticator) sono
spiegate in questa guida. I concetti generali per l'utilizzo dell'autenticatore virtuale
WebAuthn del CDP presentati in questa guida sono ancora pertinenti per coloro che cercano
di testare le passkey su
[Cypress](https://www.corbado.com/blog/passkeys-e2e-playwright-testing-webauthn-virtual-authenticator).

## 3. Cosa rende problematico il test E2E delle passkey con Playwright?

Ci sono molte ragioni per cui testare l'implementazione delle passkey è naturalmente più
impegnativo rispetto ad altre azioni utente più semplici in un ambiente web. La necessità
di gestire interazioni utente dinamiche coinvolte con
l'[autenticazione](https://www.corbado.com/it/blog/come-passare-autenticazione-completamente-passwordless)
biometrica, come la scansione delle impronte digitali o il riconoscimento facciale,
aggiunge uno strato di complessità che potrebbe non essere pratico affrontare in dettaglio
durante la scrittura dei test. Poiché la
[sicurezza](https://www.corbado.com/it/blog/come-abilitare-passkey-su-android) è naturalmente una preoccupazione
principale nel contesto
dell'[autenticazione](https://www.corbado.com/it/blog/come-passare-autenticazione-completamente-passwordless), è
anche necessario garantire che l'autenticazione con passkey sia integrata senza problemi
su vari browser e dispositivi, senza lasciare spazio a vulnerabilità di
[sicurezza](https://www.corbado.com/it/blog/come-abilitare-passkey-su-android).

## 4. L'autenticatore virtuale WebAuthn rende possibile il test E2E delle passkey

Semplificare la complessità della gestione delle interazioni utente dinamiche coinvolte
nelle operazioni con le passkey, così come testare la loro integrazione in diversi browser
e dispositivi, è reso più facile utilizzando l'autenticatore virtuale WebAuthn.

### 4.1. Cos'è l'autenticatore virtuale WebAuthn?

L'autenticatore virtuale WebAuthn è una rappresentazione software del modello di
autenticatore specificato nello standard WebAuthn. Emula il comportamento di un
dispositivo autenticatore fisico, come una
[chiave di sicurezza](https://www.corbado.com/it/blog/migliori-chiavi-sicurezza-hardware-fido2-2025) hardware (ad
es. [YubiKey](https://www.corbado.com/glossary/yubikey)) o uno scanner biometrico (ad es. utilizzato in
[Face ID](https://www.corbado.com/faq/is-face-id-passkey), Touch ID o [Windows Hello](https://www.corbado.com/glossary/windows-hello)),
ma opera interamente via software (quindi non è coinvolta alcuna autenticazione fisica o
scansione biometrica).

### 4.2. Quali sono i vantaggi dell'autenticatore virtuale WebAuthn?

Ci sono due vantaggi principali per l'autenticatore virtuale WebAuthn.

#### 4.2.1. Test automatizzati con l'autenticatore virtuale WebAuthn

Poiché WebDriver e CDP sono strumenti di automazione del browser, è evidente che il caso
d'uso primario dell'implementazione dell'autenticatore virtuale WebAuthn in questi
protocolli è il test automatizzato. Sfruttando questi protocolli, l'autenticatore virtuale
consente test semplici ma completi delle funzionalità delle passkey in ambienti
controllati come i framework di test E2E (ad es. Playwright, Cypress,
[Nightwatch](https://www.corbado.com/blog/passkeys-e2e-playwright-testing-webauthn-virtual-authenticator)).

#### 4.2.2. Test manuale e dimostrazione con l'autenticatore virtuale WebAuthn

L'autenticatore virtuale WebAuthn del CDP è accessibile anche tramite i DevTools del
browser Chrome e può essere utilizzato per test manuali o semplicemente a scopo
dimostrativo. Con questa funzione è possibile simulare l'input di una passkey su un
dispositivo che non supporta nativamente le passkey. Di conseguenza, è anche possibile
simulare un ambiente non supportato dalle passkey su un dispositivo che le supporta.

![Autenticatore virtuale WebAuthn per Passkey con Playwright](https://www.corbado.com/website-assets/66090c090678d8241d6e9f67_passkeys_playwright_virtual_webauthn_authenticator_3d1fa5c566.jpg)

Lo screenshot qui sopra mostra un esempio di utilizzo dell'autenticatore virtuale in
Chrome per test manuali o a scopo dimostrativo. Si può vedere che sono possibili diverse
opzioni di configurazione per l'autenticatore virtuale, e si può anche tracciare
l'aggiunta e la cancellazione delle credenziali. Fai riferimento a questa guida di Google
per maggiori informazioni sull'utilizzo dell'autenticatore virtuale nel tuo browser,
incluse le opzioni di configurazione e i valori raccomandati per ciascuna.

### 4.3. Quali sono gli svantaggi dell'autenticatore virtuale WebAuthn?

Sebbene l'autenticatore virtuale WebAuthn sia una soluzione elegante per testare le
implementazioni delle passkey, ci sono alcuni svantaggi da notare.

#### 4.3.1. Incapacità di simulare funzionalità specifiche dell'hardware

Essendo una soluzione puramente basata su software, l'autenticatore virtuale WebAuthn non
può replicare le caratteristiche hardware uniche e le funzionalità di
[sicurezza](https://www.corbado.com/it/blog/come-abilitare-passkey-su-android) degli autenticatori fisici. La
distinzione tra l'uso di vari autenticatori di piattaforma (che sono integrati in un
dispositivo, come uno scanner biometrico su uno smartphone) e vari autenticatori
multipiattaforma (che sono dispositivi esterni, come le
[chiavi di sicurezza hardware](https://www.corbado.com/it/blog/migliori-chiavi-sicurezza-hardware-fido2-2025))
non può essere simulata utilizzando l'autenticatore virtuale WebAuthn. Sebbene la
semplificazione black-box delle complessità legate ai vari tipi di autenticatori di
piattaforma e multipiattaforma sia uno dei vantaggi dell'utilizzo dell'autenticatore
virtuale WebAuthn, se si cerca di simulare e testare le sfumature dei diversi tipi di
autenticatori, si dovrebbero esplorare altre soluzioni.

#### 4.3.2. Documentazione scarsa e problemi tecnici irrisolti

Data l'adozione relativamente recente di WebAuthn e la novità della tecnologia delle
passkey, l'ecosistema che circonda gli autenticatori virtuali è ancora in fase di
maturazione. Ciò si traduce in una scarsità di documentazione completa e in sfide tecniche
irrisolte, in particolare nel contesto dell'integrazione degli autenticatori virtuali con
i framework di test automatizzati. Questa guida mira ad affrontare questo problema
fornendo approfondimenti completi sul test delle passkey in un ambiente di test
automatizzato, concentrandosi anche sulla risoluzione degli inconvenienti ancora presenti
nell'uso di questi strumenti e presentando soluzioni alternative per questi problemi.

## 5. Come configurare l'autenticatore virtuale WebAuthn in Playwright

Dopo un'installazione riuscita di Playwright e delle sue dipendenze, puoi iniziare subito
a scrivere il tuo primo test creando un file con un nome che termina in .spec.ts o
.test.ts con il seguente contenuto:

```js
import { test, expect } from "@playwright/test";

test("my first test", async ({ page }) => {
    await page.goto("https://passkeys.eu");

    // start simulating user actions
});
```

Per utilizzare l'autenticatore virtuale WebAuthn in Playwright, è sufficiente avviare una
sessione CDP e collegare un autenticatore virtuale all'inizio di un caso di test, come
segue:

```js
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
...
});
```

Opzioni per la configurazione dell'autenticatore virtuale WebAuthn:

- **protocol:** Questa opzione specifica il protocollo parlato dall'autenticatore
  virtuale. I valori possibili sono "ctap2" e "u2f"
- **transport:** Questa opzione specifica il tipo di autenticatore simulato
  dall'autenticatore virtuale. I valori possibili sono "usb", "nfc", "ble" e "internal".
  Se impostato su "internal", simula un autenticatore di piattaforma, mentre gli altri
  valori simulano autenticatori multipiattaforma.
- **hasResidentKey:** Impostandolo su true si supporta la
  [Resident Key](https://www.corbado.com/blog/webauthn-resident-key-discoverable-credentials-passkeys) (cioè la
  [credenziale individuabile](https://www.corbado.com/it/blog/webauthn-resident-key-discoverable-credentials-passkeys)
  lato client).
- **hasUserVerification:** Impostandolo su true si supporta la
  [User Verification](https://www.corbado.com/blog/webauthn-user-verification). Si consiglia di impostarlo su
  true poiché consente la simulazione di input di passkey riusciti e falliti.
- **isUserVerified:** Impostandolo su true si emula uno scenario di autenticazione
  riuscito, mentre false imita un fallimento dell'autenticazione, come quando un utente
  annulla l'input della passkey. Nota che questa impostazione è efficace solo quando
  hasUserVerification è impostato su true.
- **automaticPresenceSimulation:** Quando impostato su true, l'input della passkey avviene
  automaticamente e immediatamente a ogni richiesta di autenticazione. Al contrario,
  impostandolo su false si richiede l'avvio manuale della simulazione dell'autenticazione
  con passkey nel codice di test. Si consiglia di optare per la simulazione manuale
  (false) per due motivi:
    - **Aumentare la leggibilità del codice di test:** La simulazione automatica può
      oscurare la comprensione del flusso di test, poiché i tentativi di autenticazione
      vengono simulati senza trigger espliciti nel codice di test.
    - **Evitare comportamenti indesiderati:** La simulazione automatica significa che
      l'input della passkey verrà attivato anche se il tester non è consapevole che la
      passkey è stata richiesta. Questo è un problema soprattutto per la
      [Conditional UI](https://www.corbado.com/glossary/conditional-ui), che sarebbe più facile da trascurare per
      il tester.

## 6. Casi d'uso dell'autenticatore virtuale WebAuthn

In questa sezione, esploriamo l'uso dei metodi e degli eventi dell'autenticatore virtuale
WebAuthn nel contesto di casi d'uso sia comuni che marginali.

### 6.1. Come simulare un tentativo di input di passkey in Playwright

Questo potrebbe essere il compito più importante ma anche più confusionario quando si
utilizza l'autenticatore virtuale WebAuthn in un codice di test, poiché non esiste un
metodo integrato esplicito per attivare un input di passkey. La soluzione risiede nelle
opzioni di configurazione dell'autenticatore virtuale WebAuthn, ovvero, isUserVerified e
automaticPresenceSimulation. Con queste opzioni possiamo simulare questa interazione
dell'utente tramite due approcci diversi descritti di seguito.

#### 6.1.1. Approccio 1: Simulazione automatica con automaticPresenceSimulation impostato su true

**Caso 1: Simulare un input di passkey riuscito**

```js
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 simulazione di un input di passkey riuscito di solito non richiede righe aggiuntive nel
codice di test. La riga finale (await expect...) attende che la pagina cambi (attivata
dall'input di passkey riuscito implicito).

**Caso 2: Simulare un input di passkey annullato (che non provoca modifiche
nell'interfaccia utente)**

Testare un input di passkey fallito o annullato è più complicato poiché potrebbe non
portare a cambiamenti osservabili nell'interfaccia utente. In altre parole, attendere che
la pagina cambi come nell'esempio precedente non è adeguato per garantire che l'input
della passkey abbia completato l'elaborazione. Controllare che la pagina non sia cambiata
dopo l'input implicito della passkey non ha senso, poiché il controllo avverrà quasi
certamente prima che l'input della passkey abbia completato l'elaborazione. Sebbene
l'autenticatore virtuale fornisca un modo per attendere che un input di passkey riuscito
venga elaborato ascoltando l'emissione di eventi (come verrà discusso nell'approccio 2),
attualmente non esiste un modo integrato per rilevare un input di passkey fallito o
annullato. Una soluzione alternativa sarebbe semplicemente aggiungere un timeout fisso per
attendere che l'operazione della passkey si completi prima di verificare che l'interfaccia
utente sia effettivamente rimasta la stessa.

```js
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
...
});
```

In entrambi i casi, la leggibilità del codice di test è limitata dall'implicità
dell'operazione della passkey. Come menzionato in precedenza, sarebbe anche facile
trascurare quando potrebbe essere richiesta una
[Conditional UI](https://www.corbado.com/glossary/conditional-ui), nel qual caso l'operazione della passkey si
completerebbe automaticamente senza che il tester ne sia a conoscenza.

#### 6.1.2. Approccio 2: Simulazione manuale con automaticPresenceSimulation impostato su false

Attivare manualmente un input di passkey cambiando il valore dell'opzione
automaticPresenceSimulation risolve i problemi riscontrati nell'approccio precedente, in
particolare in termini di leggibilità del codice di test.

**Caso 1: Simulare un input di passkey riuscito**

I seguenti frammenti di codice simulano un input di passkey riuscito:

```js
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,
  });
}
```

```js
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 funzione di supporto potrebbe essere piuttosto intimidatoria a prima vista. È utile
capire che tutte le complessità tecniche della simulazione di un'operazione con passkey
sono astratte nella funzione di supporto. Ciò significa che quando viene utilizzata
all'interno del codice di test, rende il codice semplice e chiaro, come si può vedere nel
secondo frammento di codice sopra.

Rispetto all'approccio implicito nella Sezione 6.1.1, questo approccio esplicito aumenta
anche la leggibilità del codice. Ciò sarebbe particolarmente utile quando viene richiesta
una [Conditional UI](https://www.corbado.com/glossary/conditional-ui), poiché questo approccio esplicito previene
il completamento involontario e implicito dell'operazione con passkey senza che lo
sviluppatore se ne accorga.

Ora analizziamo ogni parte della funzione di supporto.

Innanzitutto, definiamo la promise operationCompleted che attende l'evento
WebAuthn.credentialAdded o l'evento WebAuthn.credentialAsserted, che, come suggerisce il
nome, viene emesso quando una credenziale passkey viene registrata o verificata,
rispettivamente. Questa promise verrà utilizzata in seguito.

Successivamente, l'opzione isUserVerified viene impostata su true, in modo che la
successiva operazione con passkey da parte dell'autenticatore virtuale WebAuthn abbia
successo. Anche automaticPresenceSimulation viene impostato su true, in modo che
l'autenticatore virtuale WebAuthn risponda alla successiva richiesta di passkey dalla
pagina web.

L'attesa della promise operationTrigger è necessaria per evitare una race condition. La
race condition si verifica quando la pagina web richiede la passkey prima che
automaticPresenceSimulation sia impostato su true. Per evitare ciò, l'azione dell'utente
che attiva la richiesta di passkey deve essere eseguita dopo che
automaticPresenceSimulation è stato impostato su true. Nell'esempio sopra, l'utente fa
clic sul pulsante denominato Create account with passkeys per attivare la richiesta di
passkey.

Dopo che l'azione dell'utente è stata completata, dobbiamo attendere il completamento
dell'operazione di passkey riuscita. Questo viene fatto attendendo la promise che abbiamo
definito all'inizio della funzione di supporto. Il completamento dell'operazione di
passkey riuscita è contrassegnato dall'emissione dell'evento WebAuthn.credentialAdded o
WebAuthn.credentialAsserted. Nell'esempio sopra, poiché l'utente sta registrando una
passkey, verrebbe emesso l'evento WebAuthn.credentialAdded.

Infine, l'opzione automaticPresenceSimulation viene reimpostata su false, per evitare che
operazioni di passkey involontarie si verifichino più tardi nel codice di test.

**Caso 2: Simulare un input di passkey annullato**

Per un input di passkey annullato, dobbiamo apportare una leggera modifica
all'implementazione del caso precedente. Nel caso di un input di passkey riuscito, ci sono
eventi, ovvero WebAuthn.credentialAdded e WebAuthn.credentialAsserted, che vengono emessi
al completamento dell'operazione. Tuttavia, l'autenticatore virtuale WebAuthn non fornisce
alcun evento per un input di passkey annullato o fallito. Pertanto, dobbiamo utilizzare un
modo alternativo per verificare il completamento di un'operazione di passkey annullata o
fallita.

I seguenti frammenti di codice simulano un input di passkey fallito:

```js
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,
  });
}
```

```js

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
...
});
```

Nella funzione di supporto, i listener di eventi sono sostituiti da un parametro promise
postOperationCheck che attende che si verifichi una modifica prevista dell'interfaccia
utente prima che automaticPresenceSimulation possa essere reimpostato su false.

Nel codice di test, l'unica differenza è che la funzione di supporto deve essere chiamata
con una promise aggiuntiva che controlla la modifica prevista dell'interfaccia utente.
Nell'esempio sopra, controlliamo che l'applicazione web sia navigata con successo a una
pagina in cui l'intestazione ha il testo Something went wrong....

Come discusso nella Sezione 6.1.1, l'annullamento di un input di passkey potrebbe non
portare a cambiamenti osservabili nell'interfaccia utente. Come nell'esempio fornito in
quella sezione, dobbiamo aggiungere un'attesa fissa prima di verificare che l'interfaccia
utente sia effettivamente rimasta la stessa in tali casi:

```js
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. Come testare la creazione di passkey

La comodità di utilizzare un autenticatore virtuale WebAuthn è accresciuta dalla sua
capacità di comportarsi come un vero autenticatore in caso di creazione o cancellazione di
passkey da parte dell'applicazione web. Un test deve semplicemente eseguire azioni utente
per simulare la creazione o la cancellazione di una passkey sull'applicazione web, e
l'autenticatore virtuale WebAuthn modifica automaticamente le informazioni sulle
credenziali salvate senza alcun lavoro aggiuntivo da parte del codice di test.

Ecco l'esempio di codice di test che verifica che l'applicazione web registri
correttamente una nuova passkey nell'autenticatore:

```js
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);

...
});
```

Combinando questo frammento di codice con quelli della Sezione 6.1, possiamo testare il
flusso di registrazione sulla nostra pagina web demo. Il seguente video è una
visualizzazione del test in modalità UI di Playwright:

[Watch on YouTube](https://www.youtube.com/watch?v=HqqRgds2T94)

### 6.3. Come testare la verifica delle passkey

La verifica di una credenziale passkey con l'autenticatore virtuale WebAuthn funziona in
modo simile alla creazione di una passkey, in quanto l'autenticatore virtuale tiene
traccia automaticamente del numero di verifiche eseguite utilizzando una particolare
credenziale.

```js
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);

...
});
```

Il seguente video dimostra un test per il flusso di login sulla nostra pagina web demo:

[Watch on YouTube](https://www.youtube.com/watch?v=f3Vj0Dd562A)

### 6.4. Come testare la cancellazione delle passkey

La cancellazione di una passkey da un'applicazione web, d'altra parte, non dovrebbe
modificare alcuna informazione all'interno dell'autenticatore virtuale WebAuthn.
L'applicazione web dovrebbe essere in grado di cancellare solo le credenziali salvate nel
proprio server. Solo l'utente stesso dovrebbe essere in grado di cancellare
consapevolmente e manualmente una credenziale passkey dall'autenticatore virtuale
WebAuthn.

```js
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);

...
});
```

Il seguente video dimostra un test per la cancellazione di una credenziale passkey sulla
nostra pagina web demo:

[Watch on YouTube](https://www.youtube.com/watch?v=QG5_wPMY9q8)

### 6.5. Come simulare l'autenticazione tra dispositivi diversi

Il modo più intuitivo per simulare un'autenticazione tra dispositivi diversi da un secondo
dispositivo (che non ha ancora una passkey registrata) è semplicemente aggiungere una
nuova istanza dell'autenticatore virtuale WebAuthn tramite il comando CDP, in questo modo:

```js
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
..
});
```

Per evitare la complessità di gestire gli ID di più autenticatori virtuali, è anche
possibile simulare un nuovo dispositivo semplicemente cancellando le credenziali da un
singolo autenticatore e aggiungendole di nuovo quando necessario:

```js

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
...
});
```

Questo approccio può semplificare particolarmente l'implementazione nel caso in cui sia
necessario simulare un nuovo dispositivo, ma il vecchio dispositivo non debba più essere
utilizzato. In questo caso, è sufficiente cancellare le credenziali dall'autenticatore
virtuale e scartarle del tutto:

```js
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. Alternative all'autenticatore virtuale WebAuthn

Esplorare alternative all'autenticatore virtuale WebAuthn può offrire flessibilità nel
modo in cui i processi di [autenticazione passkey](https://www.corbado.com/it/blog/provider-passkey) / WebAuthn
vengono testati all'interno dei progetti.

### 7.1. Test con servizi mock

Lo sviluppo di servizi o endpoint mock può simulare efficacemente il comportamento di
autenticazione, semplificando i test astraendo le complessità del meccanismo di
autenticazione effettivo. Questo approccio è particolarmente vantaggioso quando si
utilizzano servizi di autenticazione esterni, consentendo di mantenere il focus
sull'integrazione e la funzionalità dei componenti del sistema senza approfondire le
specifiche dell'autenticazione.

### 7.2. Test di integrazione con autenticatori reali

Per un esame approfondito delle funzionalità di autenticazione, l'impiego di autenticatori
reali per i test di integrazione fornisce una visione dettagliata dell'interazione con le
[chiavi di sicurezza hardware](https://www.corbado.com/it/blog/migliori-chiavi-sicurezza-hardware-fido2-2025) (ad
es. YubiKeys) o i dispositivi biometrici (ad es. utilizzati in
[Face ID](https://www.corbado.com/faq/is-face-id-passkey), Touch ID o [Windows Hello](https://www.corbado.com/glossary/windows-hello)).
Sebbene tipicamente condotto manualmente a causa della natura complessa dell'integrazione
di dispositivi reali nei test automatizzati, è fattibile sviluppare script di automazione
personalizzati. Questi script possono collegare autenticatori reali con framework di test
end-to-end, offrendo un'approssimazione più vicina agli scenari utente reali e migliorando
l'affidabilità del processo di autenticazione in ambienti live.

## 8. Raccomandazioni per gli sviluppatori

Dopo aver dimostrato le diverse opzioni e mostrato frammenti di codice specifici per il
test E2E di passkey / WebAuthn con Playwright, vogliamo inoltre fornire alcune
raccomandazioni più generali per gli sviluppatori che si avvicinano a questo argomento.

### 8.1. Studia il panorama dei framework di test E2E

Prima di immergersi nel test delle passkey o di qualsiasi altro meccanismo di
autenticazione, è essenziale valutare i framework di test E2E disponibili e scegliere
l'opzione più appropriata in base ai requisiti del proprio progetto. Considera il
compromesso tra la velocità e la stabilità offerte dai framework basati su CDP come
Playwright e Puppeteer, e la compatibilità cross-browser fornita dai framework basati su
WebDriver come Selenium e Nightwatch. Mentre i framework basati su CDP offrono
un'automazione del browser più veloce e stabile, sono limitati ai browser basati su
Chromium. Al contrario, i framework basati su WebDriver forniscono una più ampia
compatibilità cross-browser, incluso il supporto per browser non-Chromium come Firefox e
Safari, sebbene con prestazioni potenzialmente più lente e meno stabili. Comprendere
questi compromessi ti aiuterà a prendere una decisione informata e a selezionare il
framework che meglio si adatta alle esigenze del tuo progetto.

### 8.2. Comprendi i concetti alla base di WebAuthn e delle passkey

Sebbene l'autenticatore virtuale WebAuthn semplifichi il processo di test delle
implementazioni delle passkey, è fondamentale che gli sviluppatori abbiano una solida
comprensione dei concetti alla base dello standard WebAuthn e delle passkey. Familiarizza
con le diverse configurazioni disponibili per l'autenticatore virtuale WebAuthn, come
protocol, transport, hasResidentKey, hasUserVerification e isUserVerified. Comprendere
queste configurazioni ti consentirà di affinare l'autenticatore virtuale per simulare
accuratamente vari scenari di autenticazione. Inoltre, approfondisci le complessità
dell'autenticazione con passkey, inclusa la sua integrazione con diversi browser e
dispositivi, nonché le potenziali considerazioni sulla sicurezza. Questa conoscenza
fondamentale ti darà il potere di progettare strategie di test complete ed efficaci per
l'autenticazione con passkey nelle tue applicazioni web.

## 9. Riepilogo

Questa guida ha approfondito l'uso dell'autenticatore virtuale WebAuthn del CDP con
Playwright, evidenziando concetti avanzati e affrontando problemi non trattati nella
documentazione ufficiale. Abbiamo anche esplorato alternative al CDP all'interno di
Playwright e altri framework di test E2E. Nonostante le diverse implementazioni, le
specifiche standardizzate dell'autenticatore virtuale WebAuthn garantiscono la pertinenza
di questa guida per diversi protocolli di automazione web e framework di test end-to-end.
Per approfondire i diversi concetti relativi alle passkey, fai riferimento al nostro
glossario di terminologie pertinenti che potrebbe aiutarti a perfezionare l'autenticatore
virtuale WebAuthn in base alle tue esigenze.
