import { test, expect } from '@playwright/test'; async function navigateToTransactions(page: any, path: string = '/transaction2') { await page.setExtraHTTPHeaders({ 'x-clients': '"mine"' }); await page.goto(path); await page.waitForSelector('table tbody tr'); } async function setAmountFilter(page: any, gte: string, lte: string) { const amountGte = page.locator('input[name="amount-gte"]').first(); const amountLte = page.locator('input[name="amount-lte"]').first(); await amountGte.fill(gte); await amountLte.fill(lte); // Trigger the filter form submission via change event await amountLte.dispatchEvent('change'); // Wait for HTMX to update the table and push URL await page.waitForTimeout(1000); } async function getTableRowCount(page: any): Promise { const rows = page.locator('table tbody tr'); return await rows.count(); } async function clickTransactionNavLink(page: any, linkText: string) { const link = page.locator(`a:has-text("${linkText}")`).first(); await link.click({ force: true }); // Wait for navigation and table to load await page.waitForTimeout(1000); await page.waitForSelector('table tbody tr', { timeout: 10000 }); } test.describe('Transaction Navigation - Amount Filter Persistence', () => { test('should persist amount filter when navigating from All to Unapproved', async ({ page }) => { // Step 1: Navigate to All transactions page await navigateToTransactions(page, '/transaction2'); // Step 2: Set amount filter await setAmountFilter(page, '250', ''); // Step 3: Verify the URL updated with the filter await page.waitForURL(url => url.search.includes('amount-gte=250'), { timeout: 5000 }); // Step 4: Click the Unapproved nav link await clickTransactionNavLink(page, 'Unapproved'); // Step 5: Verify amount filter is preserved in URL after navigation const unapprovedUrl = page.url(); expect(unapprovedUrl).toContain('amount-gte=250'); // Step 6: Verify filter still applies (only 1 row - the 300 transaction) const filteredCount = await getTableRowCount(page); expect(filteredCount).toBe(1); }); test('should persist amount filter when navigating from Unapproved to All', async ({ page }) => { // Step 1: Navigate to Unapproved page with amount filter already in URL await navigateToTransactions(page, '/transaction2/unapproved?amount-gte=200'); // Step 2: Click All nav link await clickTransactionNavLink(page, 'All'); // Step 3: Verify amount filter is preserved const allUrl = page.url(); expect(allUrl).toContain('amount-gte=200'); }); test('should persist amount filter when navigating to Client Review', async ({ page }) => { // Step 1: Navigate to All page and set amount filter await navigateToTransactions(page, '/transaction2'); await setAmountFilter(page, '', '250'); // Step 2: Wait for URL to update await page.waitForURL(url => url.search.includes('amount-lte=250'), { timeout: 5000 }); // Step 3: Click Client Review nav link await clickTransactionNavLink(page, 'Client Review'); // Step 4: Verify filter persisted const feedbackUrl = page.url(); expect(feedbackUrl).toContain('amount-lte=250'); }); }); test.describe('Transaction Navigation - Date Filter Persistence', () => { test('should persist date-range preset when navigating between pages', async ({ page }) => { // Step 1: Navigate with date-range=all (includes 2022 test data) await navigateToTransactions(page, '/transaction2?date-range=all'); // Step 2: Click Unapproved nav link await clickTransactionNavLink(page, 'Unapproved'); // Step 3: Verify date-range persisted const unapprovedUrl = page.url(); expect(unapprovedUrl).toContain('date-range=all'); }); }); test.describe('Transaction Sort - Default Newest First', () => { test('should show transactions sorted by date descending by default', async ({ page }) => { await navigateToTransactions(page, '/transaction2'); // Verify no explicit sort in URL initially expect(page.url()).not.toContain('sort='); // The default sort should be newest first (descending by date) // We can verify this by checking that clicking Date header toggles to asc const dateHeader = page.locator('th').filter({ hasText: 'Date' }).first(); await dateHeader.click(); // Wait for HTMX to update await page.waitForTimeout(800); // The URL should now have an explicit sort parameter (ascending because we toggled from default desc) const currentUrl = page.url(); expect(currentUrl).toContain('sort=date%3Aasc'); // Click again to toggle to descending await dateHeader.click(); await page.waitForTimeout(800); const toggledUrl = page.url(); expect(toggledUrl).toContain('sort=date%3Adesc'); }); });