From 655066ed73b789cb24d7c2fc78a6a9ba88866925 Mon Sep 17 00:00:00 2001 From: Jack Kingsman Date: Sun, 8 Mar 2026 14:30:47 -0700 Subject: [PATCH] Fix playwright tests for new radio status indicator --- tests/e2e/specs/apprise.spec.ts | 10 +++++----- tests/e2e/specs/bot.spec.ts | 2 +- tests/e2e/specs/channel-info-and-search.spec.ts | 8 ++++---- tests/e2e/specs/channel-message-persistence.spec.ts | 6 +++--- tests/e2e/specs/contacts.spec.ts | 6 +++--- tests/e2e/specs/conversation-delete.spec.ts | 4 ++-- tests/e2e/specs/create-contact.spec.ts | 2 +- tests/e2e/specs/create-hashtag.spec.ts | 4 ++-- tests/e2e/specs/favorites.spec.ts | 4 ++-- tests/e2e/specs/hash-routing.spec.ts | 6 +++--- tests/e2e/specs/health.spec.ts | 4 ++-- tests/e2e/specs/historical-decryption.spec.ts | 2 +- tests/e2e/specs/incoming-message.spec.ts | 4 ++-- tests/e2e/specs/reopen-last-conversation.spec.ts | 4 ++-- tests/e2e/specs/sidebar-search.spec.ts | 2 +- tests/e2e/specs/sidebar-sort.spec.ts | 2 +- tests/e2e/specs/statistics.spec.ts | 2 +- tests/e2e/specs/unread-indicator.spec.ts | 2 +- tests/e2e/specs/webhook.spec.ts | 10 +++++----- tests/e2e/specs/zz-radio-settings.spec.ts | 6 ++++-- 20 files changed, 46 insertions(+), 44 deletions(-) diff --git a/tests/e2e/specs/apprise.spec.ts b/tests/e2e/specs/apprise.spec.ts index 87fe328..b2ceeb8 100644 --- a/tests/e2e/specs/apprise.spec.ts +++ b/tests/e2e/specs/apprise.spec.ts @@ -33,7 +33,7 @@ test.describe('Apprise integration settings', () => { test('create apprise via UI, configure URLs, save as enabled', async ({ page }) => { await openFanoutSettings(page); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Open add menu and pick Apprise await page.getByRole('button', { name: 'Add Integration' }).click(); @@ -89,7 +89,7 @@ test.describe('Apprise integration settings', () => { createdAppriseId = apprise.id; await openFanoutSettings(page); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Click Edit on our apprise config const row = fanoutHeader(page, 'API Apprise'); @@ -129,7 +129,7 @@ test.describe('Apprise integration settings', () => { createdAppriseId = apprise.id; await openFanoutSettings(page); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); const row = fanoutHeader(page, 'Scope Apprise'); await expect(row).toBeVisible(); @@ -163,7 +163,7 @@ test.describe('Apprise integration settings', () => { createdAppriseId = apprise.id; await openFanoutSettings(page); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Should show "Disabled" status text const row = fanoutHeader(page, 'Disabled Apprise'); @@ -192,7 +192,7 @@ test.describe('Apprise integration settings', () => { createdAppriseId = apprise.id; await openFanoutSettings(page); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); const row = fanoutHeader(page, 'Delete Me Apprise'); await expect(row).toBeVisible(); diff --git a/tests/e2e/specs/bot.spec.ts b/tests/e2e/specs/bot.spec.ts index 4136969..8b38e32 100644 --- a/tests/e2e/specs/bot.spec.ts +++ b/tests/e2e/specs/bot.spec.ts @@ -42,7 +42,7 @@ test.describe('Bot functionality', () => { // --- Step 2: Verify bot appears in settings UI --- await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); await page.getByText('Settings').click(); await page.getByRole('button', { name: /MQTT.*Automation/ }).click(); diff --git a/tests/e2e/specs/channel-info-and-search.spec.ts b/tests/e2e/specs/channel-info-and-search.spec.ts index adccab2..36c98fc 100644 --- a/tests/e2e/specs/channel-info-and-search.spec.ts +++ b/tests/e2e/specs/channel-info-and-search.spec.ts @@ -35,7 +35,7 @@ test.describe('Channel info pane', () => { test('opens channel info pane and shows message activity', async ({ page }) => { await page.goto(`/#channel/${channelKey}/flightless`); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Wait for messages to load await expect(page.getByText('seed-0')).toBeVisible({ timeout: 15_000 }); @@ -83,7 +83,7 @@ test.describe('Message search and jump-to-message', () => { test('search finds seeded messages', async ({ page }) => { await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Open search view via sidebar await page.getByText('Message Search').click(); @@ -109,7 +109,7 @@ test.describe('Message search and jump-to-message', () => { test('clicking a search result jumps to the message in conversation', async ({ page }) => { await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Open search await page.getByText('Message Search').click(); @@ -135,7 +135,7 @@ test.describe('Message search and jump-to-message', () => { test('search returns no results for nonsense query', async ({ page }) => { await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); await page.getByText('Message Search').click(); diff --git a/tests/e2e/specs/channel-message-persistence.spec.ts b/tests/e2e/specs/channel-message-persistence.spec.ts index 3f9bf8b..d13eaca 100644 --- a/tests/e2e/specs/channel-message-persistence.spec.ts +++ b/tests/e2e/specs/channel-message-persistence.spec.ts @@ -33,7 +33,7 @@ test.describe('Channel message persistence across delete/re-add', () => { // Verify message appears in UI await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); await page.getByText(channelName, { exact: true }).first().click(); await expect(page.getByText(testMessage)).toBeVisible({ timeout: 15_000 }); @@ -42,7 +42,7 @@ test.describe('Channel message persistence across delete/re-add', () => { // Verify channel is gone from sidebar await page.reload(); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); await expect(page.getByText(channelName, { exact: true })).not.toBeVisible({ timeout: 10_000 }); // Re-create the same hashtag channel (derives same key) @@ -51,7 +51,7 @@ test.describe('Channel message persistence across delete/re-add', () => { // Navigate to it await page.reload(); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); await page.getByText(channelName, { exact: true }).first().click(); // Verify original message is still visible as outgoing diff --git a/tests/e2e/specs/contacts.spec.ts b/tests/e2e/specs/contacts.spec.ts index 06e4f9c..ac25942 100644 --- a/tests/e2e/specs/contacts.spec.ts +++ b/tests/e2e/specs/contacts.spec.ts @@ -25,7 +25,7 @@ test.describe('Contacts sidebar & info pane', () => { } await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Click the contact in the sidebar await page.getByText(named.name!, { exact: true }).first().click(); @@ -46,7 +46,7 @@ test.describe('Contacts sidebar & info pane', () => { } await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Open contact conversation await page.getByText(named.name!, { exact: true }).first().click(); @@ -74,7 +74,7 @@ test.describe('Contacts sidebar & info pane', () => { } await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); await page.getByText(named.name!, { exact: true }).first().click(); const escapedName = escapeRegex(named.name!.trim()); diff --git a/tests/e2e/specs/conversation-delete.spec.ts b/tests/e2e/specs/conversation-delete.spec.ts index 114ff99..559d96a 100644 --- a/tests/e2e/specs/conversation-delete.spec.ts +++ b/tests/e2e/specs/conversation-delete.spec.ts @@ -14,7 +14,7 @@ test.describe('Conversation deletion flow', () => { const channel = await createChannel(channelName); await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); await page.getByText(channelName, { exact: true }).first().click(); await expect(page.getByPlaceholder(new RegExp(`message\\s+${channelName}`, 'i'))).toBeVisible(); @@ -40,7 +40,7 @@ test.describe('Conversation deletion flow', () => { const channel = await createChannel(channelName); await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); await page.getByText(channelName, { exact: true }).first().click(); await expect(page.getByPlaceholder(new RegExp(`message\\s+${channelName}`, 'i'))).toBeVisible(); diff --git a/tests/e2e/specs/create-contact.spec.ts b/tests/e2e/specs/create-contact.spec.ts index bca96f6..357dd59 100644 --- a/tests/e2e/specs/create-contact.spec.ts +++ b/tests/e2e/specs/create-contact.spec.ts @@ -16,7 +16,7 @@ test.describe('Create contact flow', () => { test('create a new contact via the new message modal', async ({ page }) => { await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Open new message modal await page.getByTitle('New Message').click(); diff --git a/tests/e2e/specs/create-hashtag.spec.ts b/tests/e2e/specs/create-hashtag.spec.ts index 22d2f98..66206d0 100644 --- a/tests/e2e/specs/create-hashtag.spec.ts +++ b/tests/e2e/specs/create-hashtag.spec.ts @@ -23,7 +23,7 @@ test.describe('Create hashtag channel flow', () => { test('create a hashtag channel via UI', async ({ page }) => { await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Open new message modal await page.getByTitle('New Message').click(); @@ -47,7 +47,7 @@ test.describe('Create hashtag channel flow', () => { test('create & add another keeps modal open', async ({ page }) => { await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); await page.getByTitle('New Message').click(); const dialog = page.getByRole('dialog'); diff --git a/tests/e2e/specs/favorites.spec.ts b/tests/e2e/specs/favorites.spec.ts index 4fd671f..1eadd34 100644 --- a/tests/e2e/specs/favorites.spec.ts +++ b/tests/e2e/specs/favorites.spec.ts @@ -39,7 +39,7 @@ test.describe('Favorites persistence', () => { test('add and remove favorite channel with persistence across reload', async ({ page }) => { await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); await page.getByText(channelName, { exact: true }).first().click(); @@ -57,7 +57,7 @@ test.describe('Favorites persistence', () => { .toBe(true); await page.reload(); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); await page.getByText(channelName, { exact: true }).first().click(); await expect(page.getByTitle('Remove from favorites')).toBeVisible(); await expect(page.getByText('Favorites')).toBeVisible(); diff --git a/tests/e2e/specs/hash-routing.spec.ts b/tests/e2e/specs/hash-routing.spec.ts index fae0356..2620faa 100644 --- a/tests/e2e/specs/hash-routing.spec.ts +++ b/tests/e2e/specs/hash-routing.spec.ts @@ -61,7 +61,7 @@ test.describe('Hash routing and conversation identity', () => { const legacyToken = channelName.slice(1); // no leading '#' await page.goto(`/#channel/${encodeURIComponent(legacyToken)}`); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); await expect( page.getByPlaceholder(new RegExp(`message\\s+${escapeRegex(channelName)}`, 'i')) ).toBeVisible(); @@ -72,7 +72,7 @@ test.describe('Hash routing and conversation identity', () => { test('full-key contact hash selects the exact contact even with shared prefixes', async ({ page }) => { await page.goto(`/#contact/${contactBKey}`); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); await expect( page.getByPlaceholder(new RegExp(`message\\s+${escapeRegex(contactBName)}`, 'i')) ).toBeVisible(); @@ -84,7 +84,7 @@ test.describe('Hash routing and conversation identity', () => { test('legacy contact-name hash resolves and rewrites to stable full-key hash', async ({ page }) => { await page.goto(`/#contact/${encodeURIComponent(contactAName)}`); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); await expect( page.getByPlaceholder(new RegExp(`message\\s+${escapeRegex(contactAName)}`, 'i')) ).toBeVisible(); diff --git a/tests/e2e/specs/health.spec.ts b/tests/e2e/specs/health.spec.ts index c49d0fd..15ef663 100644 --- a/tests/e2e/specs/health.spec.ts +++ b/tests/e2e/specs/health.spec.ts @@ -4,8 +4,8 @@ test.describe('Health & UI basics', () => { test('page loads and shows connected status', async ({ page }) => { await page.goto('/'); - // Status bar shows "Connected" - await expect(page.getByText('Connected')).toBeVisible(); + // Status bar shows the connected-ready label + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Sidebar is visible with key sections await expect(page.getByRole('heading', { name: 'Conversations' })).toBeVisible(); diff --git a/tests/e2e/specs/historical-decryption.spec.ts b/tests/e2e/specs/historical-decryption.spec.ts index b9f1678..4403abe 100644 --- a/tests/e2e/specs/historical-decryption.spec.ts +++ b/tests/e2e/specs/historical-decryption.spec.ts @@ -34,7 +34,7 @@ test.describe('Historical packet decryption', () => { // Open the UI await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Open new message modal → Hashtag tab await page.getByTitle('New Message').click(); diff --git a/tests/e2e/specs/incoming-message.spec.ts b/tests/e2e/specs/incoming-message.spec.ts index d109958..4be02bc 100644 --- a/tests/e2e/specs/incoming-message.spec.ts +++ b/tests/e2e/specs/incoming-message.spec.ts @@ -59,7 +59,7 @@ test.describe('Incoming mesh messages', () => { await nudgeEchoBot(); await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Record existing message counts per channel so we can detect new ones const channels = await getChannels(); @@ -110,7 +110,7 @@ test.describe('Incoming mesh messages', () => { await nudgeEchoBot(); await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Record baselines const channels = await getChannels(); diff --git a/tests/e2e/specs/reopen-last-conversation.spec.ts b/tests/e2e/specs/reopen-last-conversation.spec.ts index 64b2a12..7ceb564 100644 --- a/tests/e2e/specs/reopen-last-conversation.spec.ts +++ b/tests/e2e/specs/reopen-last-conversation.spec.ts @@ -28,7 +28,7 @@ test.describe('Reopen last conversation (device-local)', () => { test('reopens last viewed conversation on startup when enabled', async ({ page }) => { await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); await expect.poll(() => new URL(page.url()).hash).toBe(''); await page.getByText(channelName, { exact: true }).first().click(); @@ -51,7 +51,7 @@ test.describe('Reopen last conversation (device-local)', () => { test('clears local storage and falls back to default when disabled', async ({ page }) => { await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); await page.getByText(channelName, { exact: true }).first().click(); await expect( diff --git a/tests/e2e/specs/sidebar-search.spec.ts b/tests/e2e/specs/sidebar-search.spec.ts index 5d49427..8615df0 100644 --- a/tests/e2e/specs/sidebar-search.spec.ts +++ b/tests/e2e/specs/sidebar-search.spec.ts @@ -27,7 +27,7 @@ test.describe('Sidebar search/filter', () => { test('search filters conversations by name', async ({ page }) => { await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Both channels should be visible await expect(page.getByText(nameA, { exact: true })).toBeVisible(); diff --git a/tests/e2e/specs/sidebar-sort.spec.ts b/tests/e2e/specs/sidebar-sort.spec.ts index 8d2c79b..3be6990 100644 --- a/tests/e2e/specs/sidebar-sort.spec.ts +++ b/tests/e2e/specs/sidebar-sort.spec.ts @@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test'; test.describe('Sidebar sort toggle', () => { test('toggle sort order between A-Z and recent', async ({ page }) => { await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // There are multiple sort toggles (Channels, Contacts, Repeaters sections). // Use .first() to target the Channels sort toggle. diff --git a/tests/e2e/specs/statistics.spec.ts b/tests/e2e/specs/statistics.spec.ts index 230143d..119d304 100644 --- a/tests/e2e/specs/statistics.spec.ts +++ b/tests/e2e/specs/statistics.spec.ts @@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test'; test.describe('Statistics page', () => { test('statistics section shows data', async ({ page }) => { await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Open settings await page.getByText('Settings').click(); diff --git a/tests/e2e/specs/unread-indicator.spec.ts b/tests/e2e/specs/unread-indicator.spec.ts index 9f244b5..d704601 100644 --- a/tests/e2e/specs/unread-indicator.spec.ts +++ b/tests/e2e/specs/unread-indicator.spec.ts @@ -9,7 +9,7 @@ test.describe('Unread badge/pip', () => { seedChannelUnread({ channelName: CHANNEL_NAME, unreadCount: 3 }); await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Find the channel in the sidebar const channelRow = page.getByText(CHANNEL_NAME, { exact: true }).first(); diff --git a/tests/e2e/specs/webhook.spec.ts b/tests/e2e/specs/webhook.spec.ts index fa9fa0f..3a778a3 100644 --- a/tests/e2e/specs/webhook.spec.ts +++ b/tests/e2e/specs/webhook.spec.ts @@ -33,7 +33,7 @@ test.describe('Webhook integration settings', () => { test('create webhook via UI, configure, save as enabled, verify in list', async ({ page }) => { await openFanoutSettings(page); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Open add menu and pick Webhook await page.getByRole('button', { name: 'Add Integration' }).click(); @@ -75,7 +75,7 @@ test.describe('Webhook integration settings', () => { const existingIds = new Set(existingConfigs.map((cfg) => cfg.id)); await openFanoutSettings(page); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); await page.getByRole('button', { name: 'Add Integration' }).click(); await page.getByRole('menuitem', { name: 'Webhook' }).click(); @@ -105,7 +105,7 @@ test.describe('Webhook integration settings', () => { createdWebhookId = webhook.id; await openFanoutSettings(page); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Click Edit on our webhook const row = fanoutHeader(page, 'API Webhook'); @@ -139,7 +139,7 @@ test.describe('Webhook integration settings', () => { createdWebhookId = webhook.id; await openFanoutSettings(page); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Click Edit const row = fanoutHeader(page, 'Scope Webhook'); @@ -173,7 +173,7 @@ test.describe('Webhook integration settings', () => { createdWebhookId = webhook.id; await openFanoutSettings(page); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // Click Edit const row = fanoutHeader(page, 'Delete Me Webhook'); diff --git a/tests/e2e/specs/zz-radio-settings.spec.ts b/tests/e2e/specs/zz-radio-settings.spec.ts index 068089e..aaf43f9 100644 --- a/tests/e2e/specs/zz-radio-settings.spec.ts +++ b/tests/e2e/specs/zz-radio-settings.spec.ts @@ -15,7 +15,7 @@ test.describe('Radio settings', () => { try { await page.goto('/'); - await expect(page.getByText('Connected')).toBeVisible(); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible(); // --- Step 1: Change the name via settings UI --- await page.getByText('Settings').click(); @@ -36,7 +36,9 @@ test.describe('Radio settings', () => { // --- Step 3: Verify persistence across page reload --- await page.reload(); - await expect(page.getByText('Connected')).toBeVisible({ timeout: 15_000 }); + await expect(page.getByRole('status', { name: 'Radio OK' })).toBeVisible({ + timeout: 15_000, + }); await page.getByText('Settings').click(); await expect(page.locator('#name')).toHaveValue(testName, { timeout: 10_000 });