From 4763a7fa496908ac564c1ade5490d6b8d7eee986 Mon Sep 17 00:00:00 2001 From: Ndifreke000 Date: Sun, 18 Oct 2026 15:43:08 +0100 Subject: [PATCH] fix: E2E selector bug and networkidle timeouts on stream detail page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - contract-integration.spec.ts: fix the malformed CSS selector (missing closing bracket) in the recipient-address-format test by switching to getByPlaceholder, which is also more resilient to markup changes. - accessibility.spec.ts: the stream detail page polls continuously, so waitForLoadState('networkidle') never resolves and times out after 30s. Replaced the three networkidle waits scoped to /app/stream/* (the stream-detail axe scan, and the Cancel-stream and Fee-estimate dialog beforeEach hooks) with a wait for the loading skeleton to detach. Verified contracts/streaming/src/lib.rs already has StreamTransferEvent properly closed and TopUpEvent annotated with #[soroban_sdk::contractevent] (#139), and already uses a #[contracterror] StreamError enum with Result returns instead of panic! (#1) — no changes needed for those two. Closes #902 Closes #901 Closes #139 Closes #1 Co-Authored-By: Claude Sonnet 5 --- e2e/accessibility.spec.ts | 13 +++++++++---- e2e/contract-integration.spec.ts | 2 +- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/e2e/accessibility.spec.ts b/e2e/accessibility.spec.ts index 12dfdb3..c08c6f5 100644 --- a/e2e/accessibility.spec.ts +++ b/e2e/accessibility.spec.ts @@ -87,8 +87,9 @@ test.describe('Axe automated scans', () => { test('stream-detail page passes axe wcag2a/2aa', async ({ page }) => { await withWallet(page) await page.goto('/app/stream/test-id') - // wait for any async content to settle - await page.waitForLoadState('networkidle') + // The stream detail page polls, so the network never goes idle — wait for + // the loading skeleton to disappear instead of waitForLoadState('networkidle'). + await page.waitForSelector('div.space-y-6.animate-pulse', { state: 'detached' }) await checkA11y(page) }) @@ -116,7 +117,9 @@ test.describe('Cancel-stream dialog — keyboard & focus', () => { test.beforeEach(async ({ page }) => { await withWallet(page) await page.goto('/app/stream/1') - await page.waitForLoadState('networkidle') + // The stream detail page polls, so the network never goes idle — wait for + // the loading skeleton to disappear instead of waitForLoadState('networkidle'). + await page.waitForSelector('div.space-y-6.animate-pulse', { state: 'detached' }) }) test('Cancel button opens dialog; dialog has role=dialog and aria-modal', async ({ page }) => { @@ -339,7 +342,9 @@ test.describe('Fee-estimate dialog — keyboard & focus', () => { test.beforeEach(async ({ page }) => { await withWallet(page) await page.goto('/app/stream/1') - await page.waitForLoadState('networkidle') + // The stream detail page polls, so the network never goes idle — wait for + // the loading skeleton to disappear instead of waitForLoadState('networkidle'). + await page.waitForSelector('div.space-y-6.animate-pulse', { state: 'detached' }) }) async function openFeeDialog(page: Page): Promise { diff --git a/e2e/contract-integration.spec.ts b/e2e/contract-integration.spec.ts index abd6a28..5791ab4 100644 --- a/e2e/contract-integration.spec.ts +++ b/e2e/contract-integration.spec.ts @@ -56,7 +56,7 @@ test.describe('Contract Integration Tests', () => { test('should validate recipient address format', async ({ page }) => { await page.goto('/app/create') - const recipientInput = page.locator('input[placeholder*="Recipient"]').or(page.locator('input[placeholder*="recipient"')).first() + const recipientInput = page.getByPlaceholder(/recipient/i).first() if (await recipientInput.isVisible()) { await recipientInput.fill('invalid-address')