@@ -241,12 +241,12 @@ test("Create passkey account and send ETH", async ({ page }) => {
241241 . toBeGreaterThan ( endBalance + 0.1 ) ;
242242} ) ;
243243
244- test ( "Create passkey account and verify paymaster button " , async ( { page } ) => {
244+ test ( "Create passkey account and send ETH with paymaster " , async ( { page } ) => {
245245 // Create account with regular connect
246246 await page . getByRole ( "button" , { name : "Connect" , exact : true } ) . click ( ) ;
247247
248248 await page . waitForTimeout ( 2000 ) ;
249- const popup = page . context ( ) . pages ( ) [ 1 ] ;
249+ let popup = page . context ( ) . pages ( ) [ 1 ] ;
250250 await expect ( popup . getByText ( "Connect to" ) ) . toBeVisible ( ) ;
251251 popup . on ( "console" , ( msg ) => {
252252 if ( msg . type ( ) === "error" ) console . log ( `Auth server error console: "${ msg . text ( ) } "` ) ;
@@ -256,8 +256,13 @@ test("Create passkey account and verify paymaster button", async ({ page }) => {
256256 } ) ;
257257
258258 // Setup WebAuthn for passkey creation
259- const client = await popup . context ( ) . newCDPSession ( popup ) ;
259+ let client = await popup . context ( ) . newCDPSession ( popup ) ;
260260 await client . send ( "WebAuthn.enable" ) ;
261+ let newCredential : WebAuthnCredential | null = null ;
262+ client . on ( "WebAuthn.credentialAdded" , ( credentialAdded ) => {
263+ console . log ( "New Passkey credential added" ) ;
264+ newCredential = credentialAdded . credential ;
265+ } ) ;
261266 await client . send ( "WebAuthn.addVirtualAuthenticator" , {
262267 options : {
263268 protocol : "ctap2" ,
@@ -279,16 +284,129 @@ test("Create passkey account and verify paymaster button", async ({ page }) => {
279284 await expect ( page . getByText ( "Disconnect" ) ) . toBeVisible ( { timeout : 10000 } ) ;
280285 await expect ( page . getByText ( "Balance:" ) ) . toBeVisible ( ) ;
281286
282- const balanceText = await page . getByText ( "Balance:" ) . innerText ( ) ;
283- const balance = + balanceText . replace ( "Balance: " , "" ) . replace ( " ETH" , "" ) ;
287+ const startBalanceText = await page . getByText ( "Balance:" ) . innerText ( ) ;
288+ const startBalance = + startBalanceText . replace ( "Balance: " , "" ) . replace ( " ETH" , "" ) ;
289+ console . log ( `Starting balance: ${ startBalance } ETH` ) ;
284290
285- // Verify paymaster button exists and is enabled
291+ // Click "Send 0.1 ETH (Paymaster)" button
286292 await expect ( page . getByRole ( "button" , { name : "Send 0.1 ETH (Paymaster)" , exact : true } ) ) . toBeVisible ( ) ;
293+ await page . getByRole ( "button" , { name : "Send 0.1 ETH (Paymaster)" , exact : true } ) . click ( ) ;
294+
295+ // Wait for Auth Server to pop back up
296+ await page . waitForTimeout ( 2000 ) ;
297+
298+ // Check if popup appeared
299+ const pages = page . context ( ) . pages ( ) ;
300+ console . log ( `Number of pages after clicking paymaster button: ${ pages . length } ` ) ;
301+ if ( pages . length < 2 ) {
302+ console . log ( "ERROR: Auth server popup did not appear!" ) ;
303+ console . log ( "This means the paymaster transaction may not require confirmation" ) ;
304+ throw new Error ( "Auth server popup did not appear after clicking paymaster button" ) ;
305+ }
306+
307+ popup = pages [ 1 ] ;
308+
309+ // Debug: Check what screen the popup is showing
310+ console . log ( `Popup URL: ${ popup . url ( ) } ` ) ;
311+ const popupTitle = await popup . title ( ) ;
312+ console . log ( `Popup title: ${ popupTitle } ` ) ;
313+
314+ // Check if this is a connection screen or transaction screen
315+ const isConnectionScreen = popup . url ( ) . includes ( "/connect" ) ;
316+ console . log ( `Is connection screen: ${ isConnectionScreen } ` ) ;
317+
318+ if ( isConnectionScreen ) {
319+ console . log ( "⚠️ Popup is showing connection approval, not transaction confirmation!" ) ;
320+ console . log ( "This means disconnect/reconnect triggered a new connection request" ) ;
321+ console . log ( "We need to approve the connection first, then wait for transaction popup" ) ;
322+
323+ // Recreate the virtual authenticator for connection approval
324+ client = await popup . context ( ) . newCDPSession ( popup ) ;
325+ await client . send ( "WebAuthn.enable" ) ;
326+ const connResult = await client . send ( "WebAuthn.addVirtualAuthenticator" , {
327+ options : {
328+ protocol : "ctap2" ,
329+ transport : "usb" ,
330+ hasResidentKey : true ,
331+ hasUserVerification : true ,
332+ isUserVerified : true ,
333+ automaticPresenceSimulation : true ,
334+ } ,
335+ } ) ;
336+ await expect ( newCredential ) . not . toBeNull ( ) ;
337+ await client . send ( "WebAuthn.addCredential" , {
338+ authenticatorId : connResult . authenticatorId ,
339+ credential : newCredential ! ,
340+ } ) ;
341+
342+ // Click "Connect" to approve the connection
343+ console . log ( "Clicking Connect button to approve reconnection..." ) ;
344+ await popup . getByTestId ( "connect" ) . click ( ) ;
345+
346+ // Wait for connection popup to close and transaction popup to open
347+ await page . waitForTimeout ( 3000 ) ;
348+ const pagesAfterConnection = page . context ( ) . pages ( ) ;
349+ console . log ( `Pages after connection approval: ${ pagesAfterConnection . length } ` ) ;
350+
351+ if ( pagesAfterConnection . length < 2 ) {
352+ throw new Error ( "Transaction popup did not appear after connection approval" ) ;
353+ }
354+
355+ // Get the NEW popup (transaction confirmation)
356+ popup = pagesAfterConnection [ pagesAfterConnection . length - 1 ] ;
357+ console . log ( `New popup URL: ${ popup . url ( ) } ` ) ;
358+ }
359+
360+ // Now we should have the transaction confirmation popup
361+ // Recreate the virtual authenticator for transaction signature
362+ client = await popup . context ( ) . newCDPSession ( popup ) ;
363+ await client . send ( "WebAuthn.enable" ) ;
364+ const result = await client . send ( "WebAuthn.addVirtualAuthenticator" , {
365+ options : {
366+ protocol : "ctap2" ,
367+ transport : "usb" ,
368+ hasResidentKey : true ,
369+ hasUserVerification : true ,
370+ isUserVerified : true ,
371+ automaticPresenceSimulation : true ,
372+ } ,
373+ } ) ;
374+ await expect ( newCredential ) . not . toBeNull ( ) ;
375+ await client . send ( "WebAuthn.addCredential" , {
376+ authenticatorId : result . authenticatorId ,
377+ credential : newCredential ! ,
378+ } ) ;
379+
380+ // Verify the transaction details in auth server
381+ await expect ( popup . getByText ( "-0.1" ) ) . toBeVisible ( ) ;
382+ await expect ( popup . getByText ( "Sending to" ) ) . toBeVisible ( ) ;
383+
384+ // CRITICAL: Verify that fees are shown as sponsored (paymaster covers them)
385+ await expect ( popup . getByText ( "Fees" ) ) . toBeVisible ( ) ;
386+ const sponsoredText = popup . getByText ( "0 ETH (Sponsored)" ) ;
387+ await expect ( sponsoredText , "Paymaster should cover fees - expecting '0 ETH (Sponsored)' to be shown" ) . toBeVisible ( ) ;
388+ console . log ( "✓ Auth server shows fees are sponsored by paymaster" ) ;
389+
390+ // Confirm the transfer
391+ await popup . getByTestId ( "confirm" ) . click ( ) ;
392+
393+ // Wait for confirmation to complete and popup to close
394+ await page . waitForTimeout ( 2000 ) ;
395+
396+ // Verify transaction completed
287397 await expect ( page . getByRole ( "button" , { name : "Send 0.1 ETH (Paymaster)" , exact : true } ) ) . toBeEnabled ( ) ;
288398
289- console . log ( `Account created with balance: ${ balance } ETH. Paymaster button verified.` ) ;
290- // Note: Actual paymaster transaction testing is covered by Test 4 (session + paymaster)
291- // which successfully tests paymaster sponsorship via the "Connect Session (Paymaster)" flow
399+ const endBalanceText = await page . getByText ( "Balance:" ) . innerText ( ) ;
400+ const endBalance = + endBalanceText . replace ( "Balance: " , "" ) . replace ( " ETH" , "" ) ;
401+ console . log ( `Ending balance: ${ endBalance } ETH` ) ;
402+
403+ const balanceChange = startBalance - endBalance ;
404+ console . log ( `Balance change: ${ balanceChange } ETH` ) ;
405+
406+ // Balance should decrease by EXACTLY 0.1 ETH (no gas fees paid by user)
407+ // Allow small tolerance for rounding
408+ expect ( Math . abs ( balanceChange - 0.1 ) , "Balance should decrease by exactly 0.1 ETH (paymaster pays gas)" ) . toBeLessThan ( 0.001 ) ;
409+ console . log ( "✓ Paymaster successfully covered gas fees - balance decreased by exactly 0.1 ETH" ) ;
292410} ) ;
293411
294412test ( "Create account with session, create session via paymaster, and send ETH" , async ( { page } ) => {
0 commit comments