diff --git a/scripts/harb-evaluator/helpers/wallet.ts b/scripts/harb-evaluator/helpers/wallet.ts index 7b24730..62f6bad 100644 --- a/scripts/harb-evaluator/helpers/wallet.ts +++ b/scripts/harb-evaluator/helpers/wallet.ts @@ -43,10 +43,17 @@ export async function connectWallet(page: Page): Promise { const screenWidth = await page.evaluate(() => window.screen.width); console.log(`[wallet] screen.width = ${screenWidth}`); + // Check if wallet is already connected (e.g. wagmi auto-reconnected from storage) + const connectedButton = page.locator('.connect-button--connected').first(); + if (await connectedButton.isVisible({ timeout: 1_000 }).catch(() => false)) { + console.log('[wallet] Wallet already connected (auto-reconnect)'); + return; + } + let panelOpened = false; const connectButton = page.locator('.connect-button--disconnected').first(); - if (await connectButton.isVisible({ timeout: 5_000 })) { + if (await connectButton.isVisible({ timeout: 10_000 })) { console.log('[wallet] Found desktop Connect button, clicking...'); await connectButton.click(); panelOpened = true; diff --git a/tests/e2e/01-acquire-and-stake.spec.ts b/tests/e2e/01-acquire-and-stake.spec.ts index cf43386..45ccb90 100644 --- a/tests/e2e/01-acquire-and-stake.spec.ts +++ b/tests/e2e/01-acquire-and-stake.spec.ts @@ -93,49 +93,54 @@ test.describe('Acquire & Stake', () => { // We expect the desktop Connect button to be visible. console.log('[TEST] Looking for Connect button...'); - // Desktop Connect button - const connectButton = page.locator('.connect-button--disconnected').first(); - - let panelOpened = false; - - // Wait for the Connect button with a reasonable timeout - if (await connectButton.isVisible({ timeout: 5_000 })) { - console.log('[TEST] Found desktop Connect button, clicking...'); - await connectButton.click(); - panelOpened = true; + // Check if wallet already connected (wagmi may auto-reconnect from storage) + const alreadyConnected = page.locator('.connect-button--connected').first(); + if (await alreadyConnected.isVisible({ timeout: 1_000 }).catch(() => false)) { + console.log('[TEST] Wallet already connected (auto-reconnect), skipping connect flow'); } else { - // Debug: Log current screen.width and navbar-end contents - const screenWidth = await page.evaluate(() => window.screen.width); - const navbarEndHtml = await page.locator('.navbar-end').innerHTML().catch(() => 'not found'); - console.log(`[TEST] DEBUG: screen.width = ${screenWidth}`); - console.log(`[TEST] DEBUG: navbar-end HTML = ${navbarEndHtml.substring(0, 500)}`); - console.log('[TEST] Connect button not visible - checking for mobile fallback...'); + // Desktop Connect button — wait up to 10s for wagmi to settle into disconnected state + const connectButton = page.locator('.connect-button--disconnected').first(); - // Fallback to mobile login icon (SVG in navbar-end when disconnected) - const mobileLoginIcon = page.locator('.navbar-end svg').first(); - if (await mobileLoginIcon.isVisible({ timeout: 2_000 })) { - console.log('[TEST] Found mobile login icon, clicking...'); - await mobileLoginIcon.click(); + let panelOpened = false; + + if (await connectButton.isVisible({ timeout: 10_000 })) { + console.log('[TEST] Found desktop Connect button, clicking...'); + await connectButton.click(); panelOpened = true; } else { - console.log('[TEST] No Connect button or mobile icon visible - wallet may already be connected'); + // Debug: Log current screen.width and navbar-end contents + const screenWidth = await page.evaluate(() => window.screen.width); + const navbarEndHtml = await page.locator('.navbar-end').innerHTML().catch(() => 'not found'); + console.log(`[TEST] DEBUG: screen.width = ${screenWidth}`); + console.log(`[TEST] DEBUG: navbar-end HTML = ${navbarEndHtml.substring(0, 500)}`); + console.log('[TEST] Connect button not visible - checking for mobile fallback...'); + + // Fallback to mobile login icon (SVG in navbar-end when disconnected) + const mobileLoginIcon = page.locator('.navbar-end svg').first(); + if (await mobileLoginIcon.isVisible({ timeout: 2_000 })) { + console.log('[TEST] Found mobile login icon, clicking...'); + await mobileLoginIcon.click(); + panelOpened = true; + } else { + console.log('[TEST] No Connect button or mobile icon visible - wallet may already be connected'); + } } - } - if (panelOpened) { - // eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for Ponder indexing lag and UI re-renders after on-chain transactions in E2E tests. See AGENTS.md #Engineering Principles. - await page.waitForTimeout(1_000); - - // Look for the injected wallet connector in the slideout panel - console.log('[TEST] Looking for wallet connector in panel...'); - const injectedConnector = page.locator('.connectors-element').first(); - if (await injectedConnector.isVisible({ timeout: 5_000 })) { - console.log('[TEST] Clicking first wallet connector...'); - await injectedConnector.click(); + if (panelOpened) { // eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for Ponder indexing lag and UI re-renders after on-chain transactions in E2E tests. See AGENTS.md #Engineering Principles. - await page.waitForTimeout(2_000); - } else { - console.log('[TEST] WARNING: No wallet connector found in panel'); + await page.waitForTimeout(1_000); + + // Look for the injected wallet connector in the slideout panel + console.log('[TEST] Looking for wallet connector in panel...'); + const injectedConnector = page.locator('.connectors-element').first(); + if (await injectedConnector.isVisible({ timeout: 5_000 })) { + console.log('[TEST] Clicking first wallet connector...'); + await injectedConnector.click(); + // eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for Ponder indexing lag and UI re-renders after on-chain transactions in E2E tests. See AGENTS.md #Engineering Principles. + await page.waitForTimeout(2_000); + } else { + console.log('[TEST] WARNING: No wallet connector found in panel'); + } } } diff --git a/tests/e2e/02-max-stake-all-tax-rates.spec.ts b/tests/e2e/02-max-stake-all-tax-rates.spec.ts index 378a783..09b9b51 100644 --- a/tests/e2e/02-max-stake-all-tax-rates.spec.ts +++ b/tests/e2e/02-max-stake-all-tax-rates.spec.ts @@ -114,49 +114,54 @@ test.describe('Max Stake All Tax Rates', () => { // We expect the desktop Connect button to be visible. console.log('[TEST] Looking for Connect button...'); - // Desktop Connect button - const connectButton = page.locator('.connect-button--disconnected').first(); - - let panelOpened = false; - - // Wait for the Connect button with a reasonable timeout - if (await connectButton.isVisible({ timeout: 5_000 })) { - console.log('[TEST] Found desktop Connect button, clicking...'); - await connectButton.click(); - panelOpened = true; + // Check if wallet already connected (wagmi may auto-reconnect from storage) + const alreadyConnected = page.locator('.connect-button--connected').first(); + if (await alreadyConnected.isVisible({ timeout: 1_000 }).catch(() => false)) { + console.log('[TEST] Wallet already connected (auto-reconnect), skipping connect flow'); } else { - // Debug: Log current screen.width and navbar-end contents - const screenWidth = await page.evaluate(() => window.screen.width); - const navbarEndHtml = await page.locator('.navbar-end').innerHTML().catch(() => 'not found'); - console.log(`[TEST] DEBUG: screen.width = ${screenWidth}`); - console.log(`[TEST] DEBUG: navbar-end HTML = ${navbarEndHtml.substring(0, 500)}`); - console.log('[TEST] Connect button not visible - checking for mobile fallback...'); + // Desktop Connect button — wait up to 10s for wagmi to settle into disconnected state + const connectButton = page.locator('.connect-button--disconnected').first(); - // Fallback to mobile login icon (SVG in navbar-end when disconnected) - const mobileLoginIcon = page.locator('.navbar-end svg').first(); - if (await mobileLoginIcon.isVisible({ timeout: 2_000 })) { - console.log('[TEST] Found mobile login icon, clicking...'); - await mobileLoginIcon.click(); + let panelOpened = false; + + if (await connectButton.isVisible({ timeout: 10_000 })) { + console.log('[TEST] Found desktop Connect button, clicking...'); + await connectButton.click(); panelOpened = true; } else { - console.log('[TEST] No Connect button or mobile icon visible - wallet may already be connected'); + // Debug: Log current screen.width and navbar-end contents + const screenWidth = await page.evaluate(() => window.screen.width); + const navbarEndHtml = await page.locator('.navbar-end').innerHTML().catch(() => 'not found'); + console.log(`[TEST] DEBUG: screen.width = ${screenWidth}`); + console.log(`[TEST] DEBUG: navbar-end HTML = ${navbarEndHtml.substring(0, 500)}`); + console.log('[TEST] Connect button not visible - checking for mobile fallback...'); + + // Fallback to mobile login icon (SVG in navbar-end when disconnected) + const mobileLoginIcon = page.locator('.navbar-end svg').first(); + if (await mobileLoginIcon.isVisible({ timeout: 2_000 })) { + console.log('[TEST] Found mobile login icon, clicking...'); + await mobileLoginIcon.click(); + panelOpened = true; + } else { + console.log('[TEST] No Connect button or mobile icon visible - wallet may already be connected'); + } } - } - if (panelOpened) { - // eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for Ponder indexing lag and UI re-renders after on-chain transactions in E2E tests. See AGENTS.md #Engineering Principles. - await page.waitForTimeout(1_000); - - // Look for the injected wallet connector in the slideout panel - console.log('[TEST] Looking for wallet connector in panel...'); - const injectedConnector = page.locator('.connectors-element').first(); - if (await injectedConnector.isVisible({ timeout: 5_000 })) { - console.log('[TEST] Clicking first wallet connector...'); - await injectedConnector.click(); + if (panelOpened) { // eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for Ponder indexing lag and UI re-renders after on-chain transactions in E2E tests. See AGENTS.md #Engineering Principles. - await page.waitForTimeout(2_000); - } else { - console.log('[TEST] WARNING: No wallet connector found in panel'); + await page.waitForTimeout(1_000); + + // Look for the injected wallet connector in the slideout panel + console.log('[TEST] Looking for wallet connector in panel...'); + const injectedConnector = page.locator('.connectors-element').first(); + if (await injectedConnector.isVisible({ timeout: 5_000 })) { + console.log('[TEST] Clicking first wallet connector...'); + await injectedConnector.click(); + // eslint-disable-next-line no-restricted-syntax -- waitForTimeout: no event source exists for Ponder indexing lag and UI re-renders after on-chain transactions in E2E tests. See AGENTS.md #Engineering Principles. + await page.waitForTimeout(2_000); + } else { + console.log('[TEST] WARNING: No wallet connector found in panel'); + } } } diff --git a/tests/e2e/usertest/helpers.ts b/tests/e2e/usertest/helpers.ts index 3c7b848..9dd249d 100644 --- a/tests/e2e/usertest/helpers.ts +++ b/tests/e2e/usertest/helpers.ts @@ -138,27 +138,39 @@ export interface TestReport { */ export async function connectWallet(page: Page): Promise { console.log('[HELPER] Connecting wallet...'); - + // Wait for Vue app to mount (increased timeout for post-chain-reset scenarios) const navbarTitle = page.locator('.navbar-title').first(); await navbarTitle.waitFor({ state: 'visible', timeout: 60_000 }); - + // Trigger resize event for mobile detection; connectButton.isVisible below waits for layout await page.evaluate(() => { window.dispatchEvent(new Event('resize')); }); - // Try desktop Connect button first + // Wait for wagmi to settle — the connect button or connected display must appear. + // After the wallet-provider fix, eth_accounts returns [] when not connected, + // so wagmi should land on 'disconnected' status and render the connect button. const connectButton = page.locator('.connect-button--disconnected').first(); - - if (await connectButton.isVisible({ timeout: 5_000 })) { - console.log('[HELPER] Found desktop Connect button'); - await connectButton.click(); - // Wait for the connector panel to open — .connectors-element appearing is the observable event - const injectedConnector = page.locator('.connectors-element').first(); - await injectedConnector.waitFor({ state: 'visible', timeout: 10_000 }); - console.log('[HELPER] Clicking wallet connector...'); - await injectedConnector.click(); + const connectedButton = page.locator('.connect-button--connected').first(); + + // Wait for either the disconnect button (normal case) or connected button (auto-reconnect) + const desktopButton = page.locator('.connect-button--disconnected, .connect-button--connected').first(); + + if (await desktopButton.isVisible({ timeout: 10_000 })) { + if (await connectedButton.isVisible({ timeout: 500 }).catch(() => false)) { + // Wallet already connected (e.g. wagmi reconnected from storage) — skip connect flow + console.log('[HELPER] Wallet already connected (auto-reconnect)'); + } else { + // Desktop connect button found — click to open connector panel + console.log('[HELPER] Found desktop Connect button'); + await connectButton.click(); + // Wait for the connector panel to open — .connectors-element appearing is the observable event + const injectedConnector = page.locator('.connectors-element').first(); + await injectedConnector.waitFor({ state: 'visible', timeout: 10_000 }); + console.log('[HELPER] Clicking wallet connector...'); + await injectedConnector.click(); + } } else { // Try mobile fallback const mobileLoginIcon = page.locator('.navbar-end svg').first(); @@ -170,7 +182,7 @@ export async function connectWallet(page: Page): Promise { await injectedConnector.click(); } } - + // Verify wallet is connected const walletDisplay = page.getByText(/0x[a-fA-F0-9]{4}/i).first(); await walletDisplay.waitFor({ state: 'visible', timeout: 15_000 }); diff --git a/tests/setup/wallet-provider.ts b/tests/setup/wallet-provider.ts index cc05116..1f0b948 100644 --- a/tests/setup/wallet-provider.ts +++ b/tests/setup/wallet-provider.ts @@ -107,7 +107,7 @@ export async function createWalletContext( emit('accountsChanged', [account]); return [account]; case 'eth_accounts': - return [account]; + return connected ? [account] : []; case 'eth_chainId': return cidHex; case 'net_version': @@ -160,7 +160,7 @@ export async function createWalletContext( requestPermissions: () => Promise.resolve([{ parentCapability: 'eth_accounts' }]), getProviderState: async () => ({ - accounts: [account], + accounts: connected ? [account] : [], chainId: cidHex, isConnected: connected, }),