@ -59,131 +59,106 @@ function createContactName(did: string): string {
return "User " + did . slice ( 11 , 14 ) ;
}
export async function deleteContact ( page : Page , did : string ) : Promise < void > {
console . log ( '[DEBUG] deleteContact: Starting deletion for DID:' , did ) ;
export async function deleteContact ( page : Page , did : string , contactName : string ) {
// Navigate to contacts page
await page . goto ( './contacts' ) ;
console . log ( '[DEBUG] deleteContact: Navigated to contacts page' ) ;
// Wait for the page to load completely
// Wait for page to load completely
await page . waitForLoadState ( 'networkidle' ) ;
console . log ( '[DEBUG] deleteContact: Page load completed' ) ;
// Check if there are any loading indicators or filters active
const loadingIndicator = page . locator ( '[data-testid*="loading"], .loading, .spinner' ) ;
const loadingCount = await loadingIndicator . count ( ) ;
console . log ( '[DEBUG] deleteContact: Loading indicators found:' , loadingCount ) ;
// Check for any filter or state buttons that might be active
const showGiveNumbers = page . locator ( 'button:has-text("Hide Actions")' ) ;
const showGiveNumbersExists = await showGiveNumbers . count ( ) ;
console . log ( '[DEBUG] deleteContact: "Hide Actions" button exists (showing give numbers):' , showGiveNumbersExists > 0 ) ;
// Check if we need to hide the "Show Actions" view first
const loadingCount = await page . locator ( '.loading-indicator' ) . count ( ) ;
if ( loadingCount > 0 ) {
await page . locator ( '.loading-indicator' ) . first ( ) . waitFor ( { state : 'hidden' } ) ;
}
// Check if "Hide Actions" button exists (meaning we're in the give numbers view)
const showGiveNumbersExists = await page . getByRole ( 'button' , { name : 'Hide Actions' } ) . count ( ) ;
if ( showGiveNumbersExists > 0 ) {
console . log ( '[DEBUG] deleteContact: Clicking "Hide Actions" to show normal view' ) ;
await showGiveNumbers . click ( ) ;
await page . waitForTimeout ( 1000 ) ; // Wait for UI to update
await page . getByRole ( 'button' , { name : 'Hide Actions' } ) . click ( ) ;
}
const contactName = createContactName ( did ) ;
console . log ( '[DEBUG] deleteContact: Looking for contact with name:' , contactName ) ;
// First, let's see what contacts are actually on the page
const contactItems = await page . locator ( 'li[data-testid="contactListItem"]' ) ;
// Look for the contact by name
const contactItems = page . locator ( 'li[data-testid="contactListItem"]' ) ;
const contactCount = await contactItems . count ( ) ;
console . log ( '[DEBUG] deleteContact: Found contact items on page:' , contactCount ) ;
// Log all contact names visible on the page
for ( let i = 0 ; i < contactCount ; i ++ ) {
const contactItem = contactItems . nth ( i ) ;
const nameElement = contactItem . locator ( 'h2' ) ;
const nameText = await nameElement . textContent ( ) ;
console . log ( '[DEBUG] deleteContact: Contact' , i , ':' , nameText ) ;
}
// If no contacts found, let's take a screenshot to see what's on the page
// Debug: Print all contact names if no match found
if ( contactCount === 0 ) {
console . log ( '[DEBUG] deleteContact: No contacts found, taking screenshot' ) ;
await page . screenshot ( { path : 'debug-no-contacts.png' , fullPage : true } ) ;
console . log ( '[DEBUG] deleteContact: Screenshot saved as debug-no-contacts.png' ) ;
await page . screenshot ( { path : 'debug-no-contacts.png' } ) ;
throw new Error ( ` No contacts found on page. Screenshot saved as debug-no-contacts.png ` ) ;
}
// Try to find the contact list item with the expected name
const contactListItem = page . locator ( ` li[data-testid="contactListItem"]:has(h2:has-text(" ${ contactName } ")) ` ) ;
const contactExists = await contactListItem . count ( ) ;
console . log ( '[DEBUG] deleteContact: Contact with name exists:' , contactName , contactExists > 0 ) ;
// Check if our contact exists
const contactExists = await contactItems . filter ( { hasText : contactName } ) . count ( ) ;
if ( contactExists === 0 ) {
console . error ( '[DEBUG] deleteContact: Contact not found on page:' , contactName ) ;
throw new Error ( ` Contact " ${ contactName } " not found on contacts page ` ) ;
}
// Now click the info icon - fix the selector to match actual DOM structure
// Try different selectors for the info icon
const infoIconSelectors = [
` li[data-testid="contactListItem"]:has(h2:has-text(" ${ contactName } ")) font-awesome[icon="circle-info"] ` ,
` li[data-testid="contactListItem"]:has(h2:has-text(" ${ contactName } ")) .fa-circle-info ` ,
` li[data-testid="contactListItem"]:has(h2:has-text(" ${ contactName } ")) svg.fa-circle-info ` ,
` li[data-testid="contactListItem"]:has(h2:has-text(" ${ contactName } ")) [class*="fa-circle-info"] `
] ;
let infoIcon : import ( '@playwright/test' ) . Locator | null = null ;
let infoIconExists = 0 ;
for ( const selector of infoIconSelectors ) {
console . log ( '[DEBUG] deleteContact: Trying selector:' , selector ) ;
const testIcon = page . locator ( selector ) ;
const testCount = await testIcon . count ( ) ;
console . log ( '[DEBUG] deleteContact: Selector result count:' , testCount ) ;
if ( testCount > 0 ) {
infoIcon = testIcon ;
infoIconExists = testCount ;
console . log ( '[DEBUG] deleteContact: Found working selector:' , selector ) ;
break ;
// Try alternative selectors
const selectors = [
'li' ,
'div[data-testid="contactListItem"]' ,
'.contact-item' ,
'[data-testid*="contact"]'
] ;
for ( const selector of selectors ) {
const testCount = await page . locator ( selector ) . filter ( { hasText : contactName } ) . count ( ) ;
if ( testCount > 0 ) {
// Found working selector, use it
const contactItem = page . locator ( selector ) . filter ( { hasText : contactName } ) . first ( ) ;
// Look for info icon or delete button
const infoIconExists = await contactItem . locator ( 'svg.fa-info-circle' ) . count ( ) ;
if ( infoIconExists > 0 ) {
await contactItem . locator ( 'svg.fa-info-circle' ) . click ( ) ;
await page . waitForLoadState ( 'networkidle' ) ;
// Should now be on the contact detail page
await expect ( page . getByText ( 'Contact Details' ) ) . toBeVisible ( ) ;
// Look for delete button
const deleteButtonExists = await page . getByRole ( 'button' , { name : 'Delete Contact' } ) . count ( ) ;
if ( deleteButtonExists > 0 ) {
await page . getByRole ( 'button' , { name : 'Delete Contact' } ) . click ( ) ;
// Handle confirmation dialog
await expect ( page . getByRole ( 'button' , { name : 'Yes, Delete' } ) ) . toBeVisible ( ) ;
await page . getByRole ( 'button' , { name : 'Yes, Delete' } ) . click ( ) ;
// Wait for dialog to close
await expect ( page . getByRole ( 'button' , { name : 'Yes, Delete' } ) ) . toBeHidden ( ) ;
return ;
}
}
}
}
}
console . log ( '[DEBUG] deleteContact: Info icon exists:' , infoIconExists > 0 ) ;
if ( infoIconExists === 0 || ! infoIcon ) {
console . error ( '[DEBUG] deleteContact: Info icon not found for contact:' , contactName ) ;
throw new Error ( ` Info icon not found for contact " ${ contactName } " ` ) ;
throw new Error ( ` Contact " ${ contactName } " not found on contacts page ` ) ;
}
// go to the detail page for this contact
await infoIcon . click ( ) ;
console . log ( '[DEBUG] deleteContact: Clicked info icon, should be on detail page' ) ;
// Use the standard flow
const contactItem = contactItems . filter ( { hasText : contactName } ) . first ( ) ;
// Verify we're on the detail page
const detailPageHeading = page . locator ( 'h1:has-text("Identifier Details")' ) ;
await detailPageHeading . waitFor ( { timeout : 10000 } ) ;
console . log ( '[DEBUG] deleteContact: Confirmed on detail page' ) ;
// Look for info icon
const infoIconExists = await contactItem . locator ( 'svg.fa-info-circle' ) . count ( ) ;
if ( infoIconExists > 0 ) {
await contactItem . locator ( 'svg.fa-info-circle' ) . click ( ) ;
await page . waitForLoadState ( 'networkidle' ) ;
// delete the contact
const deleteButton = page . locator ( 'button > svg.fa-trash-can' ) ;
const deleteButtonExists = await deleteButton . count ( ) ;
console . log ( '[DEBUG] deleteContact: Delete button exists:' , deleteButtonExists > 0 ) ;
// Should now be on the contact detail page
await expect ( page . getByText ( 'Contact Details' ) ) . toBeVisible ( ) ;
if ( deleteButtonExists === 0 ) {
console . error ( '[DEBUG] deleteContact: Delete button not found' ) ;
throw new Error ( 'Delete button not found on detail page' ) ;
}
// Look for delete button
const deleteButtonExists = await page . getByRole ( 'button' , { name : 'Delete Contact' } ) . count ( ) ;
if ( deleteButtonExists > 0 ) {
await page . getByRole ( 'button' , { name : 'Delete Contact' } ) . click ( ) ;
await deleteButton . click ( ) ;
console . log ( '[DEBUG] deleteContact: Clicked delete button' ) ;
// Handle confirmation dialog
await expect ( page . getByRole ( 'button' , { name : 'Yes, Delete' } ) ) . toBeVisible ( ) ;
await page . getByRole ( 'button' , { name : 'Yes, Delete' } ) . click ( ) ;
// Confirm deletion
const confirmButton = page . locator ( 'div[role="alert"] button:has-text("Yes")' ) ;
await confirmButton . waitFor ( { timeout : 10000 } ) ;
console . log ( '[DEBUG] deleteContact: Confirmation dialog appeared' ) ;
await confirmButton . click ( ) ;
console . log ( '[DEBUG] deleteContact: Clicked confirmation button' ) ;
// for some reason, .isHidden() (without expect) doesn't work
await expect ( page . locator ( 'div[role="alert"] button:has-text("Yes")' ) ) . toBeHidden ( ) ;
console . log ( '[DEBUG] deleteContact: Confirmation dialog dismissed, deletion complete' ) ;
// Wait for dialog to close
await expect ( page . getByRole ( 'button' , { name : 'Yes, Delete' } ) ) . toBeHidden ( ) ;
}
}
}
export async function generateNewEthrUser ( page : Page ) : Promise < string > {