@ -1,104 +1,297 @@ 
			
		
	
		
		
			
				
					
					import  {  test ,  expect  }  from  '@playwright/test' ; / * *  
			
				
				
			
		
	
		
		
	
		
		
			
				
					 *  Contact  Management  and  Gift  Recording  Test  Suite  
			
		
	
		
		
			
				
					 *   
			
		
	
		
		
			
				
					 *  This  test  suite  verifies  the  contact  management  and  gift  recording  functionality   
			
		
	
		
		
			
				
					 *  of  the  application .  It  includes  tests  for  adding  contacts ,  recording  gifts ,   
			
		
	
		
		
			
				
					 *  and  confirming  gifts .  
			
		
	
		
		
			
				
					 *   
			
		
	
		
		
			
				
					 *  Key  Components :  
			
		
	
		
		
			
				
					 *   
			
		
	
		
		
			
				
					 *  1 .  Constants  
			
		
	
		
		
			
				
					 *     -  ALERT_TIMEOUT : For  alert - related  operations  ( 5000 ms )  
			
		
	
		
		
			
				
					 *     -  NETWORK_TIMEOUT : For  network  operations  ( 10000 ms )  
			
		
	
		
		
			
				
					 *     -  ANIMATION_TIMEOUT : For  animation  completion  ( 1000 ms )  
			
		
	
		
		
			
				
					 *   
			
		
	
		
		
			
				
					 *  2 .  Main  Test  Cases  
			
		
	
		
		
			
				
					 *     -  "Add contact, record gift, confirm gift"  
			
		
	
		
		
			
				
					 *       Tests  complete  flow  of  adding  contact  and  managing  gifts  
			
		
	
		
		
			
				
					 *     -  "Without being registered, add contacts without registration"  
			
		
	
		
		
			
				
					 *       Verifies  contact  addition  without  registration  
			
		
	
		
		
			
				
					 *     -  "Add contact, copy details, delete, and import"  
			
		
	
		
		
			
				
					 *       Tests  contact  import / export  functionality  
			
		
	
		
		
			
				
					 *   
			
		
	
		
		
			
				
					 *  3 .  Helper  Functions  
			
		
	
		
		
			
				
					 *     -  generateRandomString : Creates  unique  test  identifiers  
			
		
	
		
		
			
				
					 *     -  dismissAlertWithRetry : Handles  alert  dismissal  with  retry  logic  
			
		
	
		
		
			
				
					 *     -  recordGift : Encapsulates  gift  recording  workflow  
			
		
	
		
		
			
				
					 *     -  confirmGift : Manages  gift  confirmation  process  
			
		
	
		
		
			
				
					 *   
			
		
	
		
		
			
				
					 *  Best  Practices :  
			
		
	
		
		
			
				
					 *  -  Comprehensive  error  handling  with  try - catch  blocks  
			
		
	
		
		
			
				
					 *  -  Random  test  data  generation  
			
		
	
		
		
			
				
					 *  -  Consistent  verification  steps  
			
		
	
		
		
			
				
					 *  -  Page  object  patterns  for  maintainability  
			
		
	
		
		
			
				
					 *  -  Debug  logging  support  
			
		
	
		
		
			
				
					 *  -  Cross - browser  compatibility  considerations  
			
		
	
		
		
			
				
					 *   
			
		
	
		
		
			
				
					 *  @file  40 - add - contact . spec . ts  
			
		
	
		
		
			
				
					 * /  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					import  {  test ,  expect ,  Page  }  from  '@playwright/test' ;  
			
		
	
		
		
			
				
					import  {  importUser  }  from  './testUtils' ; import  {  importUser  }  from  './testUtils' ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
					test ( 'Add contact, record gift, confirm gift' ,  async  ( {  page  } )  = >  { // Add timeout constants
  
			
				
				
			
		
	
		
		
			
				
					
					
const  ALERT_TIMEOUT  =  5000 ;  
			
				
				
			
		
	
		
		
			
				
					
					  // Generate a random string of 16 characters
 const  NETWORK_TIMEOUT  =  10000 ;  
			
				
				
			
		
	
		
		
			
				
					
					  let  randomString  =  Math . random ( ) . toString ( 36 ) . substring ( 2 ,  18 ) ; const  ANIMATION_TIMEOUT  =  1000 ;  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
					  // In case the string is shorter than 16 characters, generate more characters until it is 16 characters long
 test ( 'Add contact, record gift, confirm gift' ,  async  ( {  page  } )  = >  {  
			
				
				
			
		
	
		
		
			
				
					
					  while  ( randomString . length  <  16 )  {   try  {  
			
				
				
			
		
	
		
		
			
				
					
					    randomString  +=  Math . random ( ) . toString ( 36 ) . substring ( 2 ,  18 ) ;     // Generate test data with error checking
  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					    const  randomString  =  await  generateRandomString ( 16 ) ;  
			
		
	
		
		
			
				
					    const  randomNonZeroNumber  =  Math . floor ( Math . random ( )  *  99 )  +  1 ;  
			
		
	
		
		
			
				
					    if  ( randomNonZeroNumber  <=  0 )  throw  new  Error ( 'Failed to generate valid number' ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					    const  finalTitle  =  ` Gift  ${ randomString } ` ;  
			
		
	
		
		
			
				
					    const  contactName  =  'Contact #000 renamed' ;  
			
		
	
		
		
			
				
					    const  userName  =  'User #000' ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					    // Import user with error handling
  
			
		
	
		
		
			
				
					    try  {  
			
		
	
		
		
			
				
					      await  importUser ( page ,  '01' ) ;  
			
		
	
		
		
			
				
					    }  catch  ( e )  {  
			
		
	
		
		
			
				
					      throw  new  Error ( ` Failed to import user:  ${ e  instanceof  Error  ?  e.message  : String ( e ) } ` ) ;  
			
		
	
		
		
			
				
					    }  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					    // Add new contact with verification
  
			
		
	
		
		
			
				
					    await  page . goto ( './contacts' ) ;  
			
		
	
		
		
			
				
					    await  page . getByPlaceholder ( 'URL or DID, Name, Public Key' ) . fill ( ` did:ethr:0x0000694B58C2cC69658993A90D3840C560f2F51F,  ${ userName } ` ) ;  
			
		
	
		
		
			
				
					    await  page . locator ( 'button > svg.fa-plus' ) . click ( ) ;  
			
		
	
		
		
			
				
					     
			
		
	
		
		
			
				
					    // Handle the registration alert properly
  
			
		
	
		
		
			
				
					    await  handleRegistrationAlert ( page ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					    // Add a small delay to ensure UI is stable
  
			
		
	
		
		
			
				
					    await  page . waitForTimeout ( 500 ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					    // Verify contact was added and is clickable
  
			
		
	
		
		
			
				
					    const  contactElement  =  page . locator ( 'li.border-b' ) ;  
			
		
	
		
		
			
				
					    await  expect ( contactElement ) . toContainText ( userName ,  {  timeout : ANIMATION_TIMEOUT  } ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					    // Ensure no alerts are present before clicking
  
			
		
	
		
		
			
				
					    await  expect ( page . locator ( 'div[role="alert"]' ) ) . toBeHidden ( ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					    // Click the info icon with force option if needed
  
			
		
	
		
		
			
				
					    await  page . locator ( ` li[data-testid="contactListItem"] h2:has-text(" ${ userName } ") + span svg.fa-circle-info ` ) . click ( {  force : true  } ) ;  
			
		
	
		
		
			
				
					     
			
		
	
		
		
			
				
					    // Wait for navigation to contact details page
  
			
		
	
		
		
			
				
					    await  expect ( page . getByRole ( 'heading' ,  {  name :  'Identifier Details'  } ) ) . toBeVisible ( {  timeout : NETWORK_TIMEOUT  } ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					    // Click edit button and wait for navigation
  
			
		
	
		
		
			
				
					    await  page . locator ( 'h2 svg.fa-pen' ) . click ( ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					    // Debug: Log all headings on the page
  
			
		
	
		
		
			
				
					    const  headings  =  await  page . locator ( 'h1, h2, h3, h4, h5, h6' ) . allInnerTexts ( ) ;  
			
		
	
		
		
			
				
					    console . log ( 'Available headings:' ,  headings ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					    // Then look for the actual heading we expect to see
  
			
		
	
		
		
			
				
					    await  expect ( page . getByRole ( 'heading' ,  {  name :  'Contact Methods'  } ) ) . toBeVisible ( {  timeout : NETWORK_TIMEOUT  } ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					    // Now look for the input field
  
			
		
	
		
		
			
				
					    const  nameInput  =  page . getByTestId ( 'contactName' ) . locator ( 'input' ) ;  
			
		
	
		
		
			
				
					    await  expect ( nameInput ) . toBeVisible ( {  timeout : NETWORK_TIMEOUT  } ) ;  
			
		
	
		
		
			
				
					    await  expect ( nameInput ) . toHaveValue ( userName ) ;  
			
		
	
		
		
			
				
					     
			
		
	
		
		
			
				
					    // Perform rename with verification
  
			
		
	
		
		
			
				
					    await  nameInput . fill ( contactName ) ;  
			
		
	
		
		
			
				
					    await  page . getByRole ( 'button' ,  {  name :  'Save'  } ) . click ( ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					    // Wait for save to complete and verify new name
  
			
		
	
		
		
			
				
					    await  expect ( page . locator ( 'h2' ,  {  hasText : contactName  } ) ) . toBeVisible ( {  timeout : NETWORK_TIMEOUT  } ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					    // Record gift with error handling
  
			
		
	
		
		
			
				
					    try  {  
			
		
	
		
		
			
				
					      await  recordGift ( page ,  contactName ,  finalTitle ,  randomNonZeroNumber ) ;  
			
		
	
		
		
			
				
					    }  catch  ( e )  {  
			
		
	
		
		
			
				
					      throw  new  Error ( ` Failed to record gift:  ${ e  instanceof  Error  ?  e.message  : String ( e ) } ` ) ;  
			
		
	
		
		
			
				
					    }  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					    // Switch users with verification
  
			
		
	
		
		
			
				
					    try  {  
			
		
	
		
		
			
				
					      await  switchToUser00 ( page ) ;  
			
		
	
		
		
			
				
					    }  catch  ( e )  {  
			
		
	
		
		
			
				
					      throw  new  Error ( ` Failed to switch users:  ${ e  instanceof  Error  ?  e.message  : String ( e ) } ` ) ;  
			
		
	
		
		
			
				
					    }  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					    // Confirm gift with error handling
  
			
		
	
		
		
			
				
					    await  confirmGift ( page ,  finalTitle ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					  }  catch  ( error )  {  
			
		
	
		
		
			
				
					    // Add more context to the error
  
			
		
	
		
		
			
				
					    if  ( error  instanceof  Error  &&  error . message . includes ( 'Edit Contact' ) )  {  
			
		
	
		
		
			
				
					      console . error ( 'Failed to find Edit page heading. Available elements:' ,  await  page . locator ( '*' ) . allInnerTexts ( ) ) ;  
			
		
	
		
		
			
				
					    }  
			
		
	
		
		
			
				
					    throw  error ;  
			
		
	
		
		
			
				
					  }   }  
			
		
	
		
		
			
				
					
					  const  finalRandomString  =  randomString . substring ( 0 ,  16 ) ; } ) ;  
			
				
				
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					  // Generate a random non-zero single-digit number
  
			
		
	
		
		
			
				
					  const  randomNonZeroNumber  =  Math . floor ( Math . random ( )  *  99 )  +  1 ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					  // Standard title prefix
  
			
		
	
		
		
			
				
					  const  standardTitle  =  'Gift ' ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					  // Combine title prefix with the random string
  
			
		
	
		
		
			
				
					  const  finalTitle  =  standardTitle  +  finalRandomString ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					  const  contactName  =  'Contact #000 renamed' ;  
			
		
	
		
		
			
				
					  const  userName  =  'User #000' ;  
			
		
	
		
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
					  // Import user 01
 // Helper functions
  
			
				
				
			
		
	
		
		
			
				
					
					  await  importUser ( page ,  '01' ) ; async  function  generateRandomString ( length : number ) :  Promise < string >  {  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					  let  result  =  Math . random ( ) . toString ( 36 ) . substring ( 2 ,  18 ) ;  
			
		
	
		
		
			
				
					  while  ( result . length  <  length )  {  
			
		
	
		
		
			
				
					    result  +=  Math . random ( ) . toString ( 36 ) . substring ( 2 ,  18 ) ;  
			
		
	
		
		
			
				
					  }  
			
		
	
		
		
			
				
					  return  result . substring ( 0 ,  length ) ;  
			
		
	
		
		
			
				
					}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					async  function  dismissAlertWithRetry ( page : Page ,  maxRetries  =  3 )  {  
			
		
	
		
		
			
				
					  for  ( let  i  =  0 ;  i  <  maxRetries ;  i ++ )  {  
			
		
	
		
		
			
				
					    try  {  
			
		
	
		
		
			
				
					      await  page . locator ( 'div[role="alert"] button > svg.fa-xmark' ) . click ( ) ;  
			
		
	
		
		
			
				
					      await  expect ( page . locator ( 'div[role="alert"]' ) ) . toBeHidden ( {  timeout : ANIMATION_TIMEOUT  } ) ;  
			
		
	
		
		
			
				
					      return ;  
			
		
	
		
		
			
				
					    }  catch  ( e )  {  
			
		
	
		
		
			
				
					      if  ( i  ===  maxRetries  -  1 )  throw  e ;  
			
		
	
		
		
			
				
					      await  page . waitForTimeout ( 1000 ) ;  // Wait before retry
  
			
		
	
		
		
			
				
					    }  
			
		
	
		
		
			
				
					  }  
			
		
	
		
		
			
				
					}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
					  // Add new contact
 async  function  recordGift ( page : Page ,  contactName : string ,  title : string ,  amount : number )  {  
			
				
				
			
		
	
		
		
			
				
					
					  await  page . goto ( './contacts' ) ;   // First navigate to home
  
			
				
				
			
		
	
		
		
			
				
					  await  page . getByPlaceholder ( 'URL or DID, Name, Public Key' ) . fill ( 'did:ethr:0x0000694B58C2cC69658993A90D3840C560f2F51F, '  +  userName ) ;  
			
		
	
		
		
			
				
					  await  page . locator ( 'button > svg.fa-plus' ) . click ( ) ;  
			
		
	
		
		
			
				
					  await  expect ( page . locator ( 'div[role="alert"] span:has-text("Contact Added")' ) ) . toBeVisible ( ) ;  
			
		
	
		
		
			
				
					  await  page . locator ( 'div[role="alert"] button:has-text("No")' ) . click ( ) ;  // don't register
  
			
		
	
		
		
			
				
					  await  page . locator ( 'div[role="alert"] button > svg.fa-xmark' ) . click ( ) ;  // dismiss info alert
  
			
		
	
		
		
			
				
					  await  expect ( page . locator ( 'div[role="alert"] button > svg.fa-xmark' ) ) . toBeHidden ( ) ;  // ensure alert is gone
  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					  // Verify added contact
  
			
		
	
		
		
			
				
					  await  expect ( page . locator ( 'li.border-b' ) ) . toContainText ( userName ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					  // Rename contact
  
			
		
	
		
		
			
				
					  await  page . locator ( ` li[data-testid="contactListItem"] h2:has-text(" ${ userName } ") + span svg.fa-circle-info ` ) . click ( ) ;  
			
		
	
		
		
			
				
					  // now on the DID view page
  
			
		
	
		
		
			
				
					  await  page . locator ( 'h2 svg.fa-pen' ) . click ( ) ;  
			
		
	
		
		
			
				
					  // now on the contact edit page
  
			
		
	
		
		
			
				
					  await  expect ( page . getByTestId ( 'contactName' ) . locator ( 'input' ) ) . toBeVisible ( ) ;  
			
		
	
		
		
			
				
					  // check that the input field has userName
  
			
		
	
		
		
			
				
					  await  expect ( page . getByTestId ( 'contactName' ) . locator ( 'input' ) ) . toHaveValue ( userName ) ;  
			
		
	
		
		
			
				
					  await  page . getByTestId ( 'contactName' ) . locator ( 'input' ) . fill ( contactName ) ;  
			
		
	
		
		
			
				
					  await  page . getByRole ( 'button' ,  {  name :  'Save'  } ) . click ( ) ;  
			
		
	
		
		
			
				
					  await  expect ( page . locator ( 'h2' ,  {  hasText : contactName  } ) ) . toBeVisible ( ) ;  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					  // Confirm that home shows contact in "Record Something…"
  
			
		
	
		
		
	
		
		
	
		
		
			
				
					  await  page . goto ( './' ) ;   await  page . goto ( './' ) ;  
			
		
	
		
		
			
				
					  await  page . getByTestId ( 'closeOnboardingAndFinish' ) . click ( ) ;   await  page . getByTestId ( 'closeOnboardingAndFinish' ) . click ( ) ;  
			
		
	
		
		
			
				
					
					  await  expect ( page . locator ( '#sectionRecordSomethingGiven ul li' ) . filter ( {  hasText : contactName  } ) . nth ( 0 ) ) . toBeVisible ( ) ;    
			
				
				
			
		
	
		
		
			
				
					
					
  // Click on the contact name and wait for navigation
  
			
				
				
			
		
	
		
		
			
				
					  // Record something given by new contact
  
			
		
	
		
		
	
		
		
	
		
		
			
				
					  await  page . getByRole ( 'heading' ,  {  name : contactName  } ) . click ( ) ;   await  page . getByRole ( 'heading' ,  {  name : contactName  } ) . click ( ) ;  
			
		
	
		
		
			
				
					
					  await  page . getByPlaceholder ( 'What was given' ) . fill ( finalTitle ) ;   await  expect ( page . getByPlaceholder ( 'What was given' ) ) . toBeVisible ( {  timeout : NETWORK_TIMEOUT  } ) ;  
			
				
				
			
		
	
		
		
			
				
					
					  await  page . getByRole ( 'spinbutton' ) . fill ( randomNonZeroNumber . toString ( ) ) ;    
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					  // Fill in gift details
  
			
		
	
		
		
			
				
					  await  page . getByPlaceholder ( 'What was given' ) . fill ( title ) ;  
			
		
	
		
		
			
				
					  await  page . getByRole ( 'spinbutton' ) . fill ( amount . toString ( ) ) ;  
			
		
	
		
		
			
				
					  await  page . getByRole ( 'button' ,  {  name :  'Sign & Send'  } ) . click ( ) ;   await  page . getByRole ( 'button' ,  {  name :  'Sign & Send'  } ) . click ( ) ;  
			
		
	
		
		
			
				
					
					  await  expect ( page . getByText ( 'That gift was recorded.' ) ) . toBeVisible ( ) ;    
			
				
				
			
		
	
		
		
			
				
					
					
  // Wait for confirmation
  
			
				
				
			
		
	
		
		
			
				
					
					  // Refresh home view and check gift
   await  expect ( page . getByText ( 'That gift was recorded.' ) ) . toBeVisible ( {  timeout : NETWORK_TIMEOUT  } ) ;  
			
				
				
			
		
	
		
		
			
				
					
					  await  page . goto ( './' ) ;   await  page . locator ( 'div[role="alert"] button > svg.fa-xmark' ) . click ( ) ;  // dismiss info alert
  
			
				
				
			
		
	
		
		
			
				
					
					
}  
			
				
				
			
		
	
		
		
			
				
					  // Firefox complains on load the initial feed here when we use the test server.
  
			
		
	
		
		
			
				
					  // It may be similar to the CORS problem below.
  
			
		
	
		
		
			
				
					  await  page . locator ( 'li' ) . filter ( {  hasText : finalTitle  } ) . locator ( 'a' ) . click ( ) ;  
			
		
	
		
		
			
				
					  await  expect ( page . getByRole ( 'heading' ,  {  name :  'Verifiable Claim Details'  } ) ) . toBeVisible ( ) ;  
			
		
	
		
		
			
				
					  await  expect ( page . getByText ( finalTitle ,  {  exact : true  } ) ) . toBeVisible ( ) ;  
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
					  // Switch to user 00
 async  function  switchToUser00 ( page : Page )  {  
			
				
				
			
		
	
		
		
	
		
		
			
				
					  await  page . goto ( './account' ) ;   await  page . goto ( './account' ) ;  
			
		
	
		
		
			
				
					  await  page . getByRole ( 'heading' ,  {  name :  'Advanced'  } ) . click ( ) ;   await  page . getByRole ( 'heading' ,  {  name :  'Advanced'  } ) . click ( ) ;  
			
		
	
		
		
			
				
					  await  page . getByRole ( 'link' ,  {  name :  'Switch Identifier'  } ) . click ( ) ;   await  page . getByRole ( 'link' ,  {  name :  'Switch Identifier'  } ) . click ( ) ;  
			
		
	
		
		
			
				
					  await  page . getByRole ( 'link' ,  {  name :  'Add Another Identity…'  } ) . click ( ) ;   await  page . getByRole ( 'link' ,  {  name :  'Add Another Identity…'  } ) . click ( ) ;  
			
		
	
		
		
			
				
					  await  page . getByText ( 'You have a seed' ) . click ( ) ;   await  page . getByText ( 'You have a seed' ) . click ( ) ;  
			
		
	
		
		
			
				
					
					  await  page . getByPlaceholder ( 'Seed Phrase' ) . fill ( 'rigid shrug mobile smart veteran half all pond toilet brave review universe ship congress found yard skate elite apology jar uniform subway slender luggage' ) ;    
			
				
				
			
		
	
		
		
	
		
		
			
				
					  const  seedPhrase  =  'rigid shrug mobile smart veteran half all pond toilet brave review universe ship congress found yard skate elite apology jar uniform subway slender luggage' ;  
			
		
	
		
		
			
				
					  await  page . getByPlaceholder ( 'Seed Phrase' ) . fill ( seedPhrase ) ;  
			
		
	
		
		
			
				
					  await  page . getByRole ( 'button' ,  {  name :  'Import'  } ) . click ( ) ;   await  page . getByRole ( 'button' ,  {  name :  'Import'  } ) . click ( ) ;  
			
		
	
		
		
			
				
					
					  await  expect ( page . getByRole ( 'code' ) ) . toContainText ( 'did:ethr:0x0000694B58C2cC69658993A90D3840C560f2F51F' ) ;    
			
				
				
			
		
	
		
		
	
		
		
			
				
					  await  expect ( page . getByRole ( 'code' ) ) . toContainText ( 'did:ethr:0x0000694B58C2cC69658993A90D3840C560f2F51F' ,   
			
		
	
		
		
			
				
					    {  timeout : NETWORK_TIMEOUT  } ) ;  
			
		
	
		
		
			
				
					}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
					  // Go to home view and look for gift
 async  function  confirmGift ( page : Page ,  title : string )  {  
			
				
				
			
		
	
		
		
	
		
		
			
				
					  await  page . goto ( './' ) ;   await  page . goto ( './' ) ;  
			
		
	
		
		
			
				
					  await  page . getByTestId ( 'closeOnboardingAndFinish' ) . click ( ) ;   await  page . getByTestId ( 'closeOnboardingAndFinish' ) . click ( ) ;  
			
		
	
		
		
			
				
					
					  await  page . locator ( 'li' ) . filter ( {  hasText : finalTitle  } ) . locator ( 'a' ) . click ( ) ;    
			
				
				
			
		
	
		
		
			
				
					
					
  // Wait for the gift to be visible and clickable
  
			
				
				
			
		
	
		
		
			
				
					
					  // Confirm gift as user 00
   const  giftElement  =  page . locator ( 'li' ) . filter ( {  hasText : title  } ) ;  
			
				
				
			
		
	
		
		
			
				
					
					  await  page . getByTestId ( 'confirmGiftLink' ) . click ( ) ;   await  expect ( giftElement ) . toBeVisible ( {  timeout : NETWORK_TIMEOUT  } ) ;  
			
				
				
			
		
	
		
		
			
				
					
					  await  page . getByRole ( 'button' ,  {  name :  'Confirm'  } ) . click ( ) ;    
			
				
				
			
		
	
		
		
			
				
					
					  await  page . getByRole ( 'button' ,  {  name :  'Yes'  } ) . click ( ) ;   // Route all API requests to port 3000
  
			
				
				
			
		
	
		
		
			
				
					
					  await  expect ( page . getByText ( 'Confirmation submitted.' ) ) . toBeVisible ( ) ;   await  page . route ( '**/api/**' ,  async  route  = >  {  
			
				
				
			
		
	
		
		
			
				
					
					  await  page . locator ( 'div[role="alert"] button > svg.fa-xmark' ) . click ( ) ;  // dismiss info alert
     const  url  =  new  URL ( route . request ( ) . url ( ) ) ;  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					    if  ( url . port  ===  '8081' )  {  
			
		
	
		
		
			
				
					      const  newUrl  =  ` http://localhost:3000 ${ url . pathname } ${ url . search } ` ;  
			
		
	
		
		
			
				
					      console . log ( ` Redirecting  ${ url . toString ( ) }  to  ${ newUrl } ` ) ;  
			
		
	
		
		
			
				
					      route . continue ( {  url : newUrl  } ) ;  
			
		
	
		
		
			
				
					    }  else  {  
			
		
	
		
		
			
				
					      route . continue ( ) ;  
			
		
	
		
		
			
				
					    }  
			
		
	
		
		
			
				
					  } ) ;  
			
		
	
		
		
			
				
					   
			
		
	
		
		
			
				
					  await  giftElement . locator ( 'a' ) . click ( ) ;  
			
		
	
		
		
			
				
					   
			
		
	
		
		
			
				
					  // Wait for both load states with a try-catch
  
			
		
	
		
		
			
				
					  try  {  
			
		
	
		
		
			
				
					    await  Promise . all ( [  
			
		
	
		
		
			
				
					      page . waitForLoadState ( 'networkidle' ,  {  timeout : NETWORK_TIMEOUT  } ) ,  
			
		
	
		
		
			
				
					      page . waitForLoadState ( 'domcontentloaded' ,  {  timeout : NETWORK_TIMEOUT  } )  
			
		
	
		
		
			
				
					    ] ) ;  
			
		
	
		
		
			
				
					  }  catch  ( e )  {  
			
		
	
		
		
			
				
					    console . log ( 'Load state error:' ,  e . message ) ;  
			
		
	
		
		
			
				
					  }  
			
		
	
		
		
			
				
					   
			
		
	
		
		
			
				
					  // Debug: Log all headings and content
  
			
		
	
		
		
			
				
					  const  headings  =  await  page . locator ( 'h1, h2, h3, h4, h5, h6' ) . allInnerTexts ( ) ;  
			
		
	
		
		
			
				
					  console . log ( 'Gift page headings:' ,  headings ) ;  
			
		
	
		
		
			
				
					   
			
		
	
		
		
			
				
					  // Log the current URL
  
			
		
	
		
		
			
				
					  console . log ( 'Current URL:' ,  page . url ( ) ) ;  
			
		
	
		
		
			
				
					   
			
		
	
		
		
			
				
					  // Check for error message and retry if needed
  
			
		
	
		
		
			
				
					  const  errorMessage  =  page . getByText ( 'Something went wrong retrieving claim data' ) ;  
			
		
	
		
		
			
				
					  const  isError  =  await  errorMessage . isVisible ( ) ;  
			
		
	
		
		
			
				
					   
			
		
	
		
		
			
				
					  if  ( isError )  {  
			
		
	
		
		
			
				
					    console . log ( 'Error detected, will retry' ) ;  
			
		
	
		
		
			
				
					    await  page . waitForTimeout ( 2000 ) ;  // Increased delay
  
			
		
	
		
		
			
				
					    await  page . goto ( './' ) ;  
			
		
	
		
		
			
				
					    await  page . waitForTimeout ( 2000 ) ;  // Increased delay
  
			
		
	
		
		
			
				
					    await  giftElement . locator ( 'a' ) . click ( ) ;  
			
		
	
		
		
			
				
					    await  page . waitForLoadState ( 'networkidle' ,  {  timeout : NETWORK_TIMEOUT  } ) ;  
			
		
	
		
		
			
				
					  }  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
					  // Refresh claim page, Confirm button should throw an alert because they already confirmed
   // Wait for either the confirm link or button with increased timeout
  
			
				
				
			
		
	
		
		
			
				
					
					  await  page . reload ( ) ;   const  confirmLink  =  page . getByTestId ( 'confirmGiftLink' ) ;  
			
				
				
			
		
	
		
		
			
				
					
					  await  page . getByRole ( 'button' ,  {  name :  'Confirm'  } ) . click ( ) ;   const  confirmButton  =  page . getByTestId ( 'confirmGiftButton' ) ;  
			
				
				
			
		
	
		
		
			
				
					
					  await  expect ( page . locator ( 'div[role="alert"]' ) ) . toBeVisible ( ) ;    
			
				
				
			
		
	
		
		
			
				
					
					} ) ;   console . log ( 'Waiting for confirm element to be visible...' ) ;  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					   
			
		
	
		
		
			
				
					  try  {  
			
		
	
		
		
			
				
					    // Try both selectors with a longer timeout
  
			
		
	
		
		
			
				
					    const  confirmElement  =  await  Promise . race ( [  
			
		
	
		
		
			
				
					      confirmLink . waitFor ( {  state :  'visible' ,  timeout : NETWORK_TIMEOUT  *  2  } ) . then ( ( )  = >  confirmLink ) ,  
			
		
	
		
		
			
				
					      confirmButton . waitFor ( {  state :  'visible' ,  timeout : NETWORK_TIMEOUT  *  2  } ) . then ( ( )  = >  confirmButton )  
			
		
	
		
		
			
				
					    ] ) ;  
			
		
	
		
		
			
				
					     
			
		
	
		
		
			
				
					    // Log success and click
  
			
		
	
		
		
			
				
					    console . log ( 'Found confirm element, clicking...' ) ;  
			
		
	
		
		
			
				
					    await  confirmElement . click ( ) ;  
			
		
	
		
		
			
				
					  }  catch  ( e )  {  
			
		
	
		
		
			
				
					    console . log ( 'Error finding confirm element:' ,  e . message ) ;  
			
		
	
		
		
			
				
					    // Log the page content for debugging
  
			
		
	
		
		
			
				
					    console . log ( 'Page content:' ,  await  page . content ( ) ) ;  
			
		
	
		
		
			
				
					    throw  e ;  
			
		
	
		
		
			
				
					  }  
			
		
	
		
		
			
				
					   
			
		
	
		
		
			
				
					  // Handle confirmation dialog
  
			
		
	
		
		
			
				
					  const  confirmDialogButton  =  page . getByRole ( 'button' ,  {  name :  'Confirm'  } ) ;  
			
		
	
		
		
			
				
					  await  expect ( confirmDialogButton ) . toBeVisible ( {  timeout : NETWORK_TIMEOUT  } ) ;  
			
		
	
		
		
			
				
					  await  confirmDialogButton . click ( ) ;  
			
		
	
		
		
			
				
					   
			
		
	
		
		
			
				
					  const  yesButton  =  page . getByRole ( 'button' ,  {  name :  'Yes'  } ) ;  
			
		
	
		
		
			
				
					  await  expect ( yesButton ) . toBeVisible ( {  timeout : NETWORK_TIMEOUT  } ) ;  
			
		
	
		
		
			
				
					  await  yesButton . click ( ) ;  
			
		
	
		
		
			
				
					   
			
		
	
		
		
			
				
					  // Wait for confirmation
  
			
		
	
		
		
			
				
					  await  expect ( page . getByText ( 'Confirmation submitted.' ) ) . toBeVisible ( {  timeout : NETWORK_TIMEOUT  } ) ;  
			
		
	
		
		
			
				
					}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					async  function  handleRegistrationAlert ( page : Page )  {  
			
		
	
		
		
			
				
					  // Wait for the registration alert
  
			
		
	
		
		
			
				
					  await  expect ( page . locator ( 'div[role="alert"]' ) ) . toBeVisible ( {  timeout : ALERT_TIMEOUT  } ) ;  
			
		
	
		
		
			
				
					   
			
		
	
		
		
			
				
					  // Click "No" on registration prompt
  
			
		
	
		
		
			
				
					  await  page . locator ( 'div[role="alert"] button:has-text("No")' ) . click ( ) ;  
			
		
	
		
		
			
				
					   
			
		
	
		
		
			
				
					  // Wait for info alert and dismiss it
  
			
		
	
		
		
			
				
					  await  dismissAlertWithRetry ( page ) ;  
			
		
	
		
		
			
				
					   
			
		
	
		
		
			
				
					  // Ensure all alerts are gone before proceeding
  
			
		
	
		
		
			
				
					  await  expect ( page . locator ( 'div[role="alert"]' ) ) . toBeHidden ( {  timeout : ANIMATION_TIMEOUT  } ) ;  
			
		
	
		
		
			
				
					}  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					test ( 'Without being registered, add contacts without registration' ,  async  ( {  page ,  context  } )  = >  { test ( 'Without being registered, add contacts without registration' ,  async  ( {  page ,  context  } )  = >  {  
			
		
	
		
		
			
				
					  await  page . goto ( './account' ) ;   await  page . goto ( './account' ) ;