diff --git a/test-playwright/testUtils.ts b/test-playwright/testUtils.ts index 13cced1f..f6d5bfac 100644 --- a/test-playwright/testUtils.ts +++ b/test-playwright/testUtils.ts @@ -60,15 +60,130 @@ function createContactName(did: string): string { } export async function deleteContact(page: Page, did: string): Promise { + console.log('[DEBUG] deleteContact: Starting deletion for DID:', did); + await page.goto('./contacts'); + console.log('[DEBUG] deleteContact: Navigated to contacts page'); + + // Wait for the 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); + + 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 + } + 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"]'); + 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 + 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'); + } + + // 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); + + 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; + } + } + + 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}"`); + } + // go to the detail page for this contact - await page.locator(`li[data-testid="contactListItem"] h2:has-text("${contactName}") + span svg.fa-circle-info`).click(); + await infoIcon.click(); + console.log('[DEBUG] deleteContact: Clicked info icon, should be on detail page'); + + // 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'); + // delete the contact - await page.locator('button > svg.fa-trash-can').click(); - await page.locator('div[role="alert"] button:has-text("Yes")').click(); + const deleteButton = page.locator('button > svg.fa-trash-can'); + const deleteButtonExists = await deleteButton.count(); + console.log('[DEBUG] deleteContact: Delete button exists:', deleteButtonExists > 0); + + if (deleteButtonExists === 0) { + console.error('[DEBUG] deleteContact: Delete button not found'); + throw new Error('Delete button not found on detail page'); + } + + await deleteButton.click(); + console.log('[DEBUG] deleteContact: Clicked delete button'); + + // 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'); } export async function generateNewEthrUser(page: Page): Promise { @@ -85,19 +200,36 @@ export async function generateNewEthrUser(page: Page): Promise { // Generate a new random user and register them. // Note that this makes 000 the active user. Use switchToUser to switch to this DID. export async function generateAndRegisterEthrUser(page: Page): Promise { + console.log('[DEBUG] generateAndRegisterEthrUser: Starting user generation'); const newDid = await generateNewEthrUser(page); + console.log('[DEBUG] generateAndRegisterEthrUser: Generated new DID:', newDid); await importUser(page, '000'); // switch to user 000 + console.log('[DEBUG] generateAndRegisterEthrUser: Switched to user 000'); await page.goto('./contacts'); + console.log('[DEBUG] generateAndRegisterEthrUser: Navigated to contacts page'); + const contactName = createContactName(newDid); - await page.getByPlaceholder('URL or DID, Name, Public Key').fill(`${newDid}, ${contactName}`); + console.log('[DEBUG] generateAndRegisterEthrUser: Created contact name:', contactName); + + const contactInput = `${newDid}, ${contactName}`; + console.log('[DEBUG] generateAndRegisterEthrUser: Filling contact input with:', contactInput); + + await page.getByPlaceholder('URL or DID, Name, Public Key').fill(contactInput); await page.locator('button > svg.fa-plus').click(); + console.log('[DEBUG] generateAndRegisterEthrUser: Clicked add contact button'); + // register them await page.locator('div[role="alert"] button:has-text("Yes")').click(); + console.log('[DEBUG] generateAndRegisterEthrUser: Clicked registration confirmation'); + // wait for it to disappear because the next steps may depend on alerts being gone await expect(page.locator('div[role="alert"] button:has-text("Yes")')).toBeHidden(); + console.log('[DEBUG] generateAndRegisterEthrUser: Registration dialog dismissed'); + await expect(page.locator('li', { hasText: contactName })).toBeVisible(); + console.log('[DEBUG] generateAndRegisterEthrUser: Contact is now visible in list:', contactName); return newDid; } @@ -109,7 +241,7 @@ export async function generateRandomString(length: number): Promise { // Function to create an array of unique strings export async function createUniqueStringsArray(count: number): Promise { - const stringsArray = []; + const stringsArray: string[] = []; const stringLength = 16; for (let i = 0; i < count; i++) { @@ -122,7 +254,7 @@ export async function createUniqueStringsArray(count: number): Promise // Function to create an array of two-digit non-zero numbers export async function createRandomNumbersArray(count: number): Promise { - const numbersArray = []; + const numbersArray: number[] = []; for (let i = 0; i < count; i++) { let randomNumber = Math.floor(Math.random() * 99) + 1;