Skip to content

Commit fa0dc8a

Browse files
committed
test for passkey exampel
1 parent a7f8ee0 commit fa0dc8a

File tree

2 files changed

+54
-45
lines changed

2 files changed

+54
-45
lines changed

tests/e2e/passkey-example.test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { expect, test as setup } from '@playwright/test'
2+
3+
setup('partial passkey signup', async ({ page }) => {
4+
const client = await page.context().newCDPSession(page)
5+
await client.send('WebAuthn.enable')
6+
const { authenticatorId } = await client.send(
7+
'WebAuthn.addVirtualAuthenticator',
8+
{
9+
options: {
10+
protocol: 'ctap2',
11+
transport: 'usb',
12+
hasResidentKey: true,
13+
hasUserVerification: true,
14+
isUserVerified: true,
15+
automaticPresenceSimulation: true,
16+
},
17+
},
18+
)
19+
20+
await page.goto('https://webauthn.io/')
21+
await page.getByPlaceholder('example_username').click()
22+
await page.getByPlaceholder('example_username').fill('test_user')
23+
await page.getByRole('button', { name: 'Register' }).click()
24+
25+
await expect(page.getByText('Success!')).toBeVisible()
26+
27+
const passkey = await client.send('WebAuthn.getCredentials', {
28+
authenticatorId,
29+
})
30+
31+
expect(passkey.credentials).toHaveLength(1)
32+
33+
let asserted = new Promise<void>((resolve) => {
34+
client.once('WebAuthn.credentialAsserted', () => resolve())
35+
})
36+
37+
await page.getByRole('button', { name: 'Authenticate' }).click()
38+
39+
await asserted
40+
41+
await expect(page.getByText("You're logged in!")).toBeVisible()
42+
})

tests/e2e/passkey.test.ts

Lines changed: 12 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { faker } from '@faker-js/faker'
2-
import { type CDPSession } from '@playwright/test'
32
import { expect, test } from '#tests/playwright-utils.ts'
43

54
async function setupWebAuthn(page: any) {
@@ -19,42 +18,6 @@ async function setupWebAuthn(page: any) {
1918
return { client, authenticatorId: result.authenticatorId }
2019
}
2120

22-
async function waitOnce(
23-
client: CDPSession,
24-
event: Parameters<CDPSession['once']>[0],
25-
) {
26-
let resolve: () => void
27-
client.once(event, () => resolve())
28-
return new Promise<void>((r) => {
29-
resolve = r
30-
})
31-
}
32-
33-
async function simulateSuccessfulPasskeyInput(
34-
client: CDPSession,
35-
operationTrigger: () => Promise<void>,
36-
) {
37-
// initialize event listeners to wait for a successful passkey input event
38-
let resolve: () => void
39-
const credentialAddedHandler = () => resolve()
40-
const credentialAssertedHandler = () => resolve()
41-
const operationCompleted = new Promise<void>((r) => {
42-
resolve = r
43-
client.on('WebAuthn.credentialAdded', credentialAddedHandler)
44-
client.on('WebAuthn.credentialAsserted', credentialAssertedHandler)
45-
})
46-
47-
// perform a user action that triggers passkey prompt
48-
await operationTrigger()
49-
50-
// wait to receive the event that the passkey was successfully registered or verified
51-
await operationCompleted
52-
53-
// clean up event listeners
54-
client.off('WebAuthn.credentialAdded', credentialAddedHandler)
55-
client.off('WebAuthn.credentialAsserted', credentialAssertedHandler)
56-
}
57-
5821
test('Users can register and use passkeys', async ({ page, login }) => {
5922
const user = await login()
6023

@@ -70,7 +33,9 @@ test('Users can register and use passkeys', async ({ page, login }) => {
7033

7134
await page.goto('/settings/profile/passkeys')
7235

73-
const passkeyRegisteredPromise = waitOnce(client, 'WebAuthn.credentialAdded')
36+
const passkeyRegisteredPromise = new Promise<void>((resolve) => {
37+
client.once('WebAuthn.credentialAdded', () => resolve())
38+
})
7439
await page.getByRole('button', { name: /register new passkey/i }).click()
7540
await passkeyRegisteredPromise
7641

@@ -96,7 +61,9 @@ test('Users can register and use passkeys', async ({ page, login }) => {
9661
await page.goto('/login')
9762
const signCount1 = afterRegistrationCredentials.credentials[0].signCount
9863

99-
const passkeyAssertedPromise = waitOnce(client, 'WebAuthn.credentialAsserted')
64+
const passkeyAssertedPromise = new Promise<void>((resolve) => {
65+
client.once('WebAuthn.credentialAsserted', () => resolve())
66+
})
10067

10168
await page.getByRole('button', { name: /login with a passkey/i }).click()
10269

@@ -143,10 +110,14 @@ test('Users can register and use passkeys', async ({ page, login }) => {
143110

144111
// Try logging in with the deleted passkey
145112
await page.goto('/login')
146-
await simulateSuccessfulPasskeyInput(client, async () => {
147-
await page.getByRole('button', { name: /login with a passkey/i }).click()
113+
const deletedPasskeyAssertedPromise = new Promise<void>((resolve) => {
114+
client.once('WebAuthn.credentialAsserted', () => resolve())
148115
})
149116

117+
await page.getByRole('button', { name: /login with a passkey/i }).click()
118+
119+
await deletedPasskeyAssertedPromise
120+
150121
// Verify error message appears
151122
await expect(page.getByText(/passkey not found/i)).toBeVisible()
152123

@@ -157,11 +128,7 @@ test('Users can register and use passkeys', async ({ page, login }) => {
157128
test('Failed passkey verification shows error', async ({ page, login }) => {
158129
const password = faker.internet.password()
159130
await login({ password })
160-
161-
// Set up WebAuthn
162131
const { client, authenticatorId } = await setupWebAuthn(page)
163-
164-
// Navigate to passkeys page
165132
await page.goto('/settings/profile/passkeys')
166133

167134
// Try to register with failed verification

0 commit comments

Comments
 (0)