import { test, expect } from '@playwright/test'; import { LoginPage } from '../../page-objects/LoginPage.js'; import { InvoicesPage } from '../../page-objects/InvoicesPage.js'; import { testCredentials } from '../../fixtures/auth.js'; import { mockInvoices } from '../../fixtures/invoices.js'; test.describe('Invoices View', () => { let loginPage; let invoicesPage; test.beforeEach(async ({ page }) => { loginPage = new LoginPage(page); invoicesPage = new InvoicesPage(page); // Mock authentication await page.route('**/api/auth/login', async route => { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ access_token: 'mock_access_token', refresh_token: 'mock_refresh_token', user: { id: 1, username: 'testuser', full_name: 'Test User' } }), }); }); // Mock companies await page.route('**/api/companies', async route => { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify([ { code: 'COMP1', name: 'Compania Test 1' } ]), }); }); // Mock invoices endpoint await page.route('**/api/invoices/COMP1', async route => { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(mockInvoices), }); }); // Login and navigate to invoices await loginPage.navigate(); await loginPage.login(testCredentials.valid.username, testCredentials.valid.password); await page.waitForURL('/dashboard'); await invoicesPage.navigate(); }); test('should display invoices page correctly', async ({ page: _page }) => { expect(await invoicesPage.isOnInvoicesPage()).toBe(true); const title = await invoicesPage.getPageTitle(); expect(title).toContain('Facturi'); }); test('should show company selection when no company selected', async ({ page: _page }) => { await invoicesPage.waitForPageLoad(); expect(await invoicesPage.isCompanySelectionVisible()).toBe(true); expect(await invoicesPage.isInvoicesTableVisible()).toBe(false); }); test('should display invoices table after company selection', async ({ page }) => { await invoicesPage.waitForPageLoad(); await invoicesPage.selectCompany('Compania Test 1'); await page.waitForSelector(invoicesPage.invoicesTable, { timeout: 10000 }); expect(await invoicesPage.isInvoicesTableVisible()).toBe(true); }); test('should filter invoices by search term', async ({ page }) => { await invoicesPage.waitForPageLoad(); await invoicesPage.selectCompany('Compania Test 1'); await page.waitForSelector(invoicesPage.invoicesTable); // Search for specific invoice await invoicesPage.searchInvoices('INV001'); await invoicesPage.waitForLoadingToFinish(); const visibleRows = await invoicesPage.getVisibleInvoicesCount(); expect(visibleRows).toBeGreaterThan(0); // Check that displayed invoices contain search term const firstRowData = await invoicesPage.getFirstInvoiceData(); expect(firstRowData.number).toContain('INV001'); }); test('should filter invoices by status', async ({ page }) => { await invoicesPage.waitForPageLoad(); await invoicesPage.selectCompany('Compania Test 1'); await page.waitForSelector(invoicesPage.invoicesTable); // Filter by paid status await invoicesPage.filterByStatus('paid'); await invoicesPage.waitForLoadingToFinish(); const visibleRows = await invoicesPage.getVisibleInvoicesCount(); expect(visibleRows).toBeGreaterThan(0); }); test('should sort invoices by date', async ({ page }) => { await invoicesPage.waitForPageLoad(); await invoicesPage.selectCompany('Compania Test 1'); await page.waitForSelector(invoicesPage.invoicesTable); // Click date column header to sort await invoicesPage.sortByColumn('date'); await invoicesPage.waitForLoadingToFinish(); // Verify sorting worked const firstRowDate = await invoicesPage.getFirstInvoiceData(); expect(firstRowDate.date).toBeTruthy(); }); test('should display invoice details when clicking on row', async ({ page }) => { await invoicesPage.waitForPageLoad(); await invoicesPage.selectCompany('Compania Test 1'); await page.waitForSelector(invoicesPage.invoicesTable); // Click on first invoice row await invoicesPage.clickFirstInvoiceRow(); // Check if details panel or modal appears expect(await invoicesPage.isInvoiceDetailsVisible()).toBe(true); }); test('should export invoices data', async ({ page }) => { await invoicesPage.waitForPageLoad(); await invoicesPage.selectCompany('Compania Test 1'); await page.waitForSelector(invoicesPage.invoicesTable); // Set up download handler const downloadPromise = page.waitForEvent('download'); await invoicesPage.clickExportButton(); const download = await downloadPromise; expect(download.suggestedFilename()).toContain('facturi'); }); test('should handle pagination correctly', async ({ page }) => { // Mock large dataset await page.route('**/api/invoices/COMP1*', async route => { const url = route.request().url(); const urlParams = new URL(url).searchParams; const page_num = parseInt(urlParams.get('page') || '1'); await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ items: mockInvoices.slice((page_num - 1) * 10, page_num * 10), total: 25, page: page_num, size: 10, pages: 3 }), }); }); await invoicesPage.waitForPageLoad(); await invoicesPage.selectCompany('Compania Test 1'); await page.waitForSelector(invoicesPage.invoicesTable); // Check pagination controls appear expect(await invoicesPage.isPaginationVisible()).toBe(true); // Navigate to next page await invoicesPage.goToNextPage(); await invoicesPage.waitForLoadingToFinish(); // Verify page changed const currentPage = await invoicesPage.getCurrentPage(); expect(currentPage).toBe(2); }); test('should handle API errors gracefully', async ({ page }) => { // Mock API error await page.route('**/api/invoices/COMP1', async route => { await route.fulfill({ status: 500, contentType: 'application/json', body: JSON.stringify({ detail: 'Internal server error' }), }); }); await invoicesPage.waitForPageLoad(); await invoicesPage.selectCompany('Compania Test 1'); // Should show error message const errorToast = page.locator('.p-toast-message-error'); if (await errorToast.isVisible()) { const errorText = await errorToast.textContent(); expect(errorText.toLowerCase()).toContain('eroare'); } }); test('should refresh data when refresh button clicked', async ({ page }) => { await invoicesPage.waitForPageLoad(); await invoicesPage.selectCompany('Compania Test 1'); await page.waitForSelector(invoicesPage.invoicesTable); // Click refresh button await invoicesPage.clickRefreshButton(); await invoicesPage.waitForLoadingToFinish(); // Table should still be visible after refresh expect(await invoicesPage.isInvoicesTableVisible()).toBe(true); }); });