diff --git a/playwright.config-local.ts b/playwright.config-local.ts index 29f4cf64..6be773e4 100644 --- a/playwright.config-local.ts +++ b/playwright.config-local.ts @@ -32,7 +32,7 @@ export default defineConfig({ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ use: { /* Base URL to use in actions like `await page.goto('/')`. */ - baseURL: "http://localhost:8081", + baseURL: "http://localhost:8080", /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ trace: "retain-on-failure", @@ -112,8 +112,8 @@ export default defineConfig({ */ webServer: { command: - "VITE_APP_SERVER=http://localhost:8081 VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000 VITE_DEFAULT_PARTNER_API_SERVER=http://localhost:3000 VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app VITE_PASSKEYS_ENABLED=true npm run dev -- --port=8081", - url: "http://localhost:8081", + "VITE_APP_SERVER=http://localhost:8080 VITE_DEFAULT_ENDORSER_API_SERVER=http://localhost:3000 VITE_DEFAULT_PARTNER_API_SERVER=http://localhost:3000 VITE_DEFAULT_IMAGE_API_SERVER=https://test-image-api.timesafari.app VITE_PASSKEYS_ENABLED=true npm run dev -- --port=8080", + url: "http://localhost:8080", reuseExistingServer: !process.env.CI, }, }); diff --git a/src/utils/notify.ts b/src/utils/notify.ts index a099320f..a886c086 100644 --- a/src/utils/notify.ts +++ b/src/utils/notify.ts @@ -13,10 +13,10 @@ export type NotifyFunction = ( // Standard timeouts export const TIMEOUTS = { BRIEF: 1000, // Very brief toasts ("Sent..." messages) - SHORT: 2000, // Short notifications (clipboard copies, quick confirmations) + SHORT: 6000, // Short notifications (clipboard copies, quick confirmations) STANDARD: 3000, // Standard notifications (success messages, general info) - LONG: 5000, // Longer notifications (errors, warnings, important info) - VERY_LONG: 7000, // Very long notifications (complex operations) + LONG: 8000, // Longer notifications (errors, warnings, important info) + VERY_LONG: 10000, // Very long notifications (complex operations) MODAL: -1, // Modal confirmations (no auto-dismiss) } as const; diff --git a/src/views/ShareMyContactInfoView.vue b/src/views/ShareMyContactInfoView.vue index 741002d8..24824a45 100644 --- a/src/views/ShareMyContactInfoView.vue +++ b/src/views/ShareMyContactInfoView.vue @@ -74,6 +74,22 @@ export default class ShareMyContactInfoView extends Vue { // Component state isLoading = false; + async mounted() { + // Debug logging for test diagnosis + const settings = await this.$settings(); + // @ts-ignore + const activeDid = settings?.activeDid; + // @ts-ignore + window.__SHARE_CONTACT_DEBUG__ = { settings, activeDid }; + // eslint-disable-next-line no-console + console.log('[ShareMyContactInfoView] mounted', { settings, activeDid }); + if (!activeDid) { + // eslint-disable-next-line no-console + console.log('[ShareMyContactInfoView] No activeDid, redirecting to root'); + this.$router.push({ name: 'home' }); + } + } + /** * Main share functionality - orchestrates the contact sharing process */ @@ -121,7 +137,7 @@ export default class ShareMyContactInfoView extends Vue { private async generateContactMessage( settings: Settings, account: Account, - ): Promise { + ) { const givenName = settings.firstName || ""; const isRegistered = !!settings.isRegistered; const profileImageUrl = settings.profileImageUrl || ""; diff --git a/test-playwright/00-noid-tests.spec.ts b/test-playwright/00-noid-tests.spec.ts index 6210b5b2..24a3d879 100644 --- a/test-playwright/00-noid-tests.spec.ts +++ b/test-playwright/00-noid-tests.spec.ts @@ -69,7 +69,7 @@ */ import { test, expect } from '@playwright/test'; -import { deleteContact, generateAndRegisterEthrUser, importUser } from './testUtils'; +import { deleteContact, generateAndRegisterEthrUser, importUser, importUserAndCloseOnboarding } from './testUtils'; test('Check activity feed - check that server is running', async ({ page }) => { // Load app homepage @@ -144,26 +144,90 @@ test('Check ID generation', async ({ page }) => { test('Check setting name & sharing info', async ({ page }) => { - // Load homepage to trigger ID generation (?) + // Do NOT import a user; start with a fresh, unregistered user state + + function now() { + return new Date().toISOString(); + } + + // Start by loading the homepage and looking for the onboarding notice and button await page.goto('./'); - await page.getByTestId('closeOnboardingAndFinish').click(); - // Check 'someone must register you' notice + + // Wait for page to fully load and check for overlays + await page.waitForTimeout(2000); + + // Loop to close all visible overlays/dialogs before proceeding + for (let i = 0; i < 5; i++) { + const overlayCount = await page.locator('.dialog-overlay').count(); + if (overlayCount === 0) break; + + // Try to close the overlay with various known close button texts + const closeButtons = [ + "That's enough help, thanks.", + 'Close', + 'Cancel', + 'Dismiss', + 'Got it', + 'OK' + ]; + + let closed = false; + for (const buttonText of closeButtons) { + const button = page.getByRole('button', { name: buttonText }); + if (await button.count() > 0) { + await button.click(); + closed = true; + break; + } + } + + // If no text button found, try the close icon (xmark) + if (!closed) { + const closeIcon = page.locator('.fa-xmark, .fa-times, [aria-label*="close"], [aria-label*="Close"]'); + if (await closeIcon.count() > 0) { + await closeIcon.first().click(); + closed = true; + } + } + + if (!closed) break; + + // Wait a bit for the overlay to close + await page.waitForTimeout(500); + } + await expect(page.getByText('someone must register you.')).toBeVisible(); - await page.getByRole('button', { name: /Show them/}).click(); - // fill in a name + + // Click the "Show them" button + await page.getByRole('button', { name: 'Show them' }).click(); + + // Wait for the "Set Your Name" dialog to appear await expect(page.getByText('Set Your Name')).toBeVisible(); - await page.getByRole('textbox').fill('Me Test User'); - await page.locator('button:has-text("Save")').click(); - await expect(page.getByText('share some other way')).toBeVisible(); - await page.getByRole('button', { name: /share some other way/ }).click(); - await expect(page.getByRole('button', { name: 'copy to clipboard' })).toBeVisible(); - await page.getByRole('button', { name: 'copy to clipboard' }).click(); - await expect(page.getByText('contact info was copied')).toBeVisible(); - // dismiss alert and wait for it to go away - await page.locator('div[role="alert"] button > svg.fa-xmark').click(); - await expect(page.getByText('contact info was copied')).toBeHidden(); - // check that they're on the Contacts screen - await expect(page.getByText('your contacts')).toBeVisible(); + + // Fill in the name + await page.getByRole('textbox').fill('Test User'); + + // Click Save + await page.getByRole('button', { name: 'Save' }).click(); + + // Wait for the choice dialog to appear + await expect(page.getByText('We will share some other way')).toBeVisible(); + + // Click "We will share some other way" + await page.getByRole('button', { name: 'We will share some other way' }).click(); + + // Wait up to 10 seconds for the heading + await expect(page.getByRole('heading', { name: 'Share Your Contact Info' })).toBeVisible({ timeout: 10000 }); + + // Click the Copy to Clipboard button + await expect(page.getByRole('button', { name: 'Copy contact information to clipboard' })).toBeVisible({ timeout: 10000 }); + await page.getByRole('button', { name: 'Copy contact information to clipboard' }).click(); + + // Wait for either the notification or navigation to contacts + await Promise.race([ + expect(page.getByText('contact info was copied')).toBeVisible({ timeout: 10000 }), + expect(page.getByText('your contacts')).toBeVisible({ timeout: 10000 }) + ]); }); test('Confirm test API setting (may fail if you are running your own Time Safari)', async ({ page }, testInfo) => {