From 4359ae846995025877c14f5a46640fa791b80ebe Mon Sep 17 00:00:00 2001 From: jubnl Date: Wed, 27 May 2026 18:18:08 +0200 Subject: [PATCH] chore: fix client tests --- client/src/pages/DashboardPage.test.tsx | 132 ++++++++---------------- 1 file changed, 44 insertions(+), 88 deletions(-) diff --git a/client/src/pages/DashboardPage.test.tsx b/client/src/pages/DashboardPage.test.tsx index 9e26acaf..a8c802b8 100644 --- a/client/src/pages/DashboardPage.test.tsx +++ b/client/src/pages/DashboardPage.test.tsx @@ -1,5 +1,5 @@ import { describe, it, expect, beforeEach, vi } from 'vitest'; -import { render, screen, waitFor } from '../../tests/helpers/render'; +import { render, screen, waitFor, within } from '../../tests/helpers/render'; import userEvent from '@testing-library/user-event'; import { http, HttpResponse } from 'msw'; import { server } from '../../tests/helpers/msw/server'; @@ -75,7 +75,7 @@ describe('DashboardPage', () => { render(); await waitFor(() => { - expect(screen.getByText(/no trips yet/i)).toBeInTheDocument(); + expect(screen.queryAllByRole('article').length).toBe(0); }); }); }); @@ -230,13 +230,8 @@ describe('DashboardPage', () => { const archiveButtons = screen.getAllByRole('button', { name: /archive/i }); await user.click(archiveButtons[0]); - // Wait for archived section toggle to appear - await waitFor(() => { - expect(screen.getByRole('button', { name: /archived/i })).toBeInTheDocument(); - }); - - // Click "Archived" toggle to show archived trips - await user.click(screen.getByRole('button', { name: /archived/i })); + // Click the Archive filter tab to show archived trips + await user.click(screen.getByText('Archive')); await waitFor(() => { expect(screen.getAllByText('Paris Adventure')[0]).toBeInTheDocument(); @@ -272,8 +267,8 @@ describe('DashboardPage', () => { expect(screen.getAllByText('Paris Adventure')[0]).toBeInTheDocument(); }); - // Find the view mode toggle button (shows List icon when in grid mode, title "List view") - const viewToggle = screen.getByTitle(/list view/i); + // Find the view mode toggle button (aria-label "Toggle view") + const viewToggle = screen.getByRole('button', { name: /toggle view/i }); await user.click(viewToggle); // localStorage should be updated to 'list' @@ -302,13 +297,8 @@ describe('DashboardPage', () => { expect(screen.getAllByText('Paris Adventure')[0]).toBeInTheDocument(); }); - // Archived section toggle should be present - await waitFor(() => { - expect(screen.getByRole('button', { name: /archived/i })).toBeInTheDocument(); - }); - - // Click to expand - await user.click(screen.getByRole('button', { name: /archived/i })); + // Click the Archive filter tab to show archived trips + await user.click(screen.getByText('Archive')); await waitFor(() => { expect(screen.getByText('Old Rome Trip')).toBeInTheDocument(); @@ -343,7 +333,7 @@ describe('DashboardPage', () => { }); // Switch to list view - const viewToggle = screen.getByTitle(/list view/i); + const viewToggle = screen.getByRole('button', { name: /toggle view/i }); await user.click(viewToggle); // Non-spotlight trips should be visible in list view @@ -367,7 +357,7 @@ describe('DashboardPage', () => { }); // Switch to list view - const viewToggle = screen.getByTitle(/list view/i); + const viewToggle = screen.getByRole('button', { name: /toggle view/i }); await user.click(viewToggle); // Non-spotlight trips render in list view @@ -397,8 +387,8 @@ describe('DashboardPage', () => { expect(screen.getAllByText('Paris Adventure')[0]).toBeInTheDocument(); }); - // Find copy buttons - const copyButtons = screen.getAllByRole('button', { name: /copy/i }); + // Find duplicate buttons (aria-label="Duplicate") + const copyButtons = screen.getAllByRole('button', { name: /duplicate/i }); await user.click(copyButtons[0]); // Confirm the copy dialog @@ -420,19 +410,9 @@ describe('DashboardPage', () => { expect(screen.getAllByText('Paris Adventure').length).toBeGreaterThan(0); }); - // Find settings button — the gear icon button (icon-only, no visible label) - const allBtns = screen.getAllByRole('button'); - const settingsButton = allBtns.find(btn => - btn.querySelector('.lucide-settings') && !btn.textContent?.trim() - ); - - expect(settingsButton).toBeDefined(); - if (settingsButton) { - await user.click(settingsButton); - await waitFor(() => { - expect(screen.getByText('Widgets:')).toBeInTheDocument(); - }); - } + // Currency and timezone widgets are always visible in the sidebar + expect(screen.getAllByText(/currency/i).length).toBeGreaterThan(0); + expect(screen.getAllByText(/timezone/i).length).toBeGreaterThan(0); }); }); @@ -462,24 +442,21 @@ describe('DashboardPage', () => { const user = userEvent.setup(); render(); - await waitFor(() => { - expect(screen.getByRole('button', { name: /archived/i })).toBeInTheDocument(); - }); - - // Expand archived section - await user.click(screen.getByRole('button', { name: /archived/i })); + // Click the Archive filter tab to show archived trips + await user.click(screen.getByText('Archive')); await waitFor(() => { expect(screen.getByText('Old Rome Trip')).toBeInTheDocument(); }); - // Click restore button - const restoreBtn = screen.getByRole('button', { name: /restore/i }); + // The Archive action button on an archived trip triggers restore (unarchive) + const tripArticles = screen.getAllByRole('article'); + const restoreBtn = within(tripArticles[0]).getByRole('button', { name: /archive/i }); await user.click(restoreBtn); - // After restore, archived section should disappear (no more archived trips) + // After restore, the archived trip is no longer visible await waitFor(() => { - expect(screen.queryByRole('button', { name: /archived/i })).not.toBeInTheDocument(); + expect(screen.queryByText('Old Rome Trip')).not.toBeInTheDocument(); }); }); }); @@ -577,8 +554,8 @@ describe('DashboardPage', () => { expect(screen.getAllByText(/live now/i).length).toBeGreaterThan(0); }); - // Progress bar label "Trip progress" appears - expect(screen.getAllByText(/trip progress/i).length).toBeGreaterThan(0); + // Ring completion percentage appears + expect(screen.getAllByText(/%/i).length).toBeGreaterThan(0); // "days left" label appears inside the progress section expect(screen.getAllByText(/days left/i).length).toBeGreaterThan(0); @@ -645,25 +622,9 @@ describe('DashboardPage', () => { expect(screen.getAllByText('Paris Adventure').length).toBeGreaterThan(0); }); - // Open widget settings — gear icon button (icon-only, no visible label) - const allBtns = screen.getAllByRole('button'); - const settingsButton = allBtns.find(btn => - btn.querySelector('.lucide-settings') && !btn.textContent?.trim() - ); - - expect(settingsButton).toBeDefined(); - if (settingsButton) { - await user.click(settingsButton); - - await waitFor(() => { - expect(screen.getByText('Widgets:')).toBeInTheDocument(); - }); - - // Both currency and timezone toggle labels should be visible - // Use getAllByText because labels may appear in both widget settings and quick actions - expect(screen.getAllByText(/currency/i).length).toBeGreaterThan(0); - expect(screen.getAllByText(/timezone/i).length).toBeGreaterThan(0); - } + // Currency and timezone widgets are always visible in the sidebar + expect(screen.getAllByText(/currency/i).length).toBeGreaterThan(0); + expect(screen.getAllByText(/timezone/i).length).toBeGreaterThan(0); }); }); @@ -685,18 +646,14 @@ describe('DashboardPage', () => { const user = userEvent.setup(); render(); - await waitFor(() => { - expect(screen.getByRole('button', { name: /archived/i })).toBeInTheDocument(); - }); - - // Expand - await user.click(screen.getByRole('button', { name: /archived/i })); + // Click the Archive filter tab to show archived trips + await user.click(screen.getByText('Archive')); await waitFor(() => { expect(screen.getByText('Old Archived Trip')).toBeInTheDocument(); }); - // Collapse - await user.click(screen.getByRole('button', { name: /archived/i })); + // Switch back to Planned tab to hide archived trips + await user.click(screen.getByText('Planned')); await waitFor(() => { expect(screen.queryByText('Old Archived Trip')).not.toBeInTheDocument(); }); @@ -729,22 +686,21 @@ describe('DashboardPage', () => { const user = userEvent.setup(); render(); - await waitFor(() => { - expect(screen.getByRole('button', { name: /archived/i })).toBeInTheDocument(); - }); - - await user.click(screen.getByRole('button', { name: /archived/i })); + // Click the Archive filter tab to show archived trips + await user.click(screen.getByText('Archive')); await waitFor(() => { expect(screen.getByText('Restored Trip')).toBeInTheDocument(); }); - const restoreBtn = screen.getByRole('button', { name: /restore/i }); + // The Archive action button on an archived trip triggers restore (unarchive) + const tripArticles = screen.getAllByRole('article'); + const restoreBtn = within(tripArticles[0]).getByRole('button', { name: /archive/i }); await user.click(restoreBtn); - // After restore, the archived section should disappear (no archived trips left) + // After restore, the archived trip is no longer in the list await waitFor(() => { - expect(screen.queryByRole('button', { name: /archived/i })).not.toBeInTheDocument(); + expect(screen.queryByText('Restored Trip')).not.toBeInTheDocument(); }); }); }); @@ -765,8 +721,8 @@ describe('DashboardPage', () => { expect(screen.getAllByText('Paris Adventure')[0]).toBeInTheDocument(); }); - // Find copy buttons (may appear in mobile + desktop) - const copyButtons = screen.getAllByRole('button', { name: /copy/i }); + // Find duplicate buttons (aria-label="Duplicate") + const copyButtons = screen.getAllByRole('button', { name: /duplicate/i }); expect(copyButtons.length).toBeGreaterThan(0); await user.click(copyButtons[0]); @@ -791,10 +747,10 @@ describe('DashboardPage', () => { render(); await waitFor(() => { - expect(screen.getByText(/no trips yet/i)).toBeInTheDocument(); + expect(screen.queryAllByRole('article').length).toBe(0); }); - // Empty state should show a descriptive text and a create button + // Empty state should show a create button const createButtons = screen.getAllByRole('button'); const createBtn = createButtons.find(btn => btn.textContent?.toLowerCase().includes('trip')); expect(createBtn).toBeDefined(); @@ -828,10 +784,10 @@ describe('DashboardPage', () => { expect(screen.getAllByText('Live Adventure').length).toBeGreaterThan(0); }); - // Stats section: places count "5" and buddies count "2" appear + // Stats section: countdown-days "5" and travelers label appear await waitFor(() => { expect(screen.getAllByText('5').length).toBeGreaterThan(0); - expect(screen.getAllByText('2').length).toBeGreaterThan(0); + expect(screen.getAllByText(/travelers/i).length).toBeGreaterThan(0); }); // Days stat label