diff --git a/features/TRIAL_BALANCE_FEATURE.md b/features/TRIAL_BALANCE_FEATURE.md
deleted file mode 100644
index 9aa9f69..0000000
--- a/features/TRIAL_BALANCE_FEATURE.md
+++ /dev/null
@@ -1,587 +0,0 @@
-# Feature: Balanță de Verificare Sintetică (Trial Balance)
-
-**Branch**: `feature/trial-balance`
-**Status**: 📋 Planning
-**Created**: 2025-11-20
-**Assigned to**: Claude Code
-
----
-
-## 📋 Overview
-
-Implementare pagină nouă în frontend pentru afișarea balanței de verificare sintetice simplificate din tabelul Oracle `VBAL`, cu filtrare dinamică și integrare completă în aplicație.
-
----
-
-## 🎯 Business Requirements
-
-### Functional Requirements
-1. **Afișare Date Balanță de Verificare**:
- - Solduri precedente (debit/credit)
- - Rulaje lunare (debit/credit)
- - Solduri finale (debit/credit)
- - Cont contabil (cod)
- - Denumire cont
-
-2. **Filtrare și Căutare**:
- - Filtrare după **număr cont** (ex: "512", "4111")
- - Filtrare după **denumire cont** (căutare parțială, case-insensitive)
- - Filtrare combinată (și după cont și după denumire)
- - Clear filters option
-
-3. **Navigare și UX**:
- - Adăugare în meniul hamburger (secțiune Rapoarte / Reports)
- - Ordonare pe coloane (ascendent/descendent)
- - Paginare pentru volume mari de date
- - Loading states și error handling
- - Responsive design (mobile-friendly)
-
-4. **Date Contextualizate**:
- - Afișare pentru compania activă curentă
- - Afișare pentru luna/anul curent (sau filtru de perioadă - opțional faza 2)
-
-### Non-Functional Requirements
-- **Performance**: Răspuns API < 2s pentru 10,000 înregistrări
-- **Security**: Autentificare JWT obligatorie
-- **Accessibility**: Conform design system existent
-- **CSS**: Respectare strictă a arhitecturii CSS (ONBOARDING_CSS.md, CSS_PATTERNS.md)
-
----
-
-## 🏗️ Technical Architecture
-
-### Database Schema (Oracle `VBAL` table)
-```sql
--- Structura tabelului VBAL (să fie verificată în Oracle)
-SELECT
- CONT, -- Număr cont contabil
- DCONT, -- Denumire cont
- SD_PREC, -- Sold precedent debit
- SC_PREC, -- Sold precedent credit
- RD_LUNA, -- Rulaj lunar debit
- RC_LUNA, -- Rulaj lunar credit
- SD_FINAL, -- Sold final debit
- SC_FINAL, -- Sold final credit
- COD_FIRMA, -- Cod firmă (pentru filtering)
- LUNA, -- Luna (1-12)
- AN -- An
-FROM VBAL
-WHERE COD_FIRMA = :cod_firma
- AND AN = :an
- AND LUNA = :luna
- AND (CONT LIKE :cont_filter OR DCONT LIKE :denumire_filter)
-ORDER BY CONT
-```
-
-### Backend API Endpoint
-
-**Endpoint**: `GET /api/trial-balance`
-
-**Request Parameters**:
-```json
-{
- "cod_firma": "string (required, from JWT)",
- "luna": "integer (1-12, optional, default: current month)",
- "an": "integer (optional, default: current year)",
- "cont_filter": "string (optional, partial match)",
- "denumire_filter": "string (optional, partial match, case-insensitive)",
- "sort_by": "string (optional, default: 'CONT')",
- "sort_order": "string (optional, 'asc' | 'desc', default: 'asc')",
- "page": "integer (optional, default: 1)",
- "page_size": "integer (optional, default: 50)"
-}
-```
-
-**Response**:
-```json
-{
- "success": true,
- "data": {
- "items": [
- {
- "cont": "4111",
- "dcont": "Furnizori interni",
- "sold_precedent_debit": 0.00,
- "sold_precedent_credit": 15000.00,
- "rulaj_lunar_debit": 5000.00,
- "rulaj_lunar_credit": 8000.00,
- "sold_final_debit": 0.00,
- "sold_final_credit": 18000.00
- }
- ],
- "pagination": {
- "total_items": 150,
- "total_pages": 3,
- "current_page": 1,
- "page_size": 50
- },
- "filters_applied": {
- "luna": 11,
- "an": 2025,
- "cont_filter": null,
- "denumire_filter": "furnizori"
- }
- }
-}
-```
-
-**Error Responses**:
-- `401 Unauthorized`: Missing/invalid JWT token
-- `403 Forbidden`: User doesn't have access to company
-- `500 Internal Server Error`: Database connection/query error
-
----
-
-### Frontend Architecture
-
-**Location**: `reports-app/frontend/src/views/TrialBalanceView.vue`
-
-**Store**: `reports-app/frontend/src/stores/trialBalanceStore.js`
-
-**Route**: `/trial-balance` (added to `router/index.js`)
-
-**Menu Integration**:
-- Add to hamburger menu in `src/components/layout/HamburgerMenu.vue`
-- Section: "Rapoarte" / "Reports"
-- Icon: Calculator/Table icon (PrimeVue icon)
-- Label: "Balanță de Verificare"
-
-**Component Structure**:
-```vue
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-```
-
-**CSS Patterns to Use**:
-- `.roa-page-header` - Page header (CSS_PATTERNS.md)
-- `.roa-card` - Card container (CSS_PATTERNS.md)
-- `.roa-filters-card` - Filters section (CSS_PATTERNS.md)
-- Design tokens from DESIGN_TOKENS.md (colors, spacing)
-- **NO `:deep()`** - Use `src/assets/css/vendor/primevue/datatable.css` for PrimeVue overrides
-
-**State Management** (Pinia store):
-```javascript
-// src/stores/trialBalanceStore.js
-export const useTrialBalanceStore = defineStore('trialBalance', {
- state: () => ({
- trialBalanceData: [],
- loading: false,
- error: null,
- filters: {
- cont: '',
- denumire: '',
- luna: new Date().getMonth() + 1,
- an: new Date().getFullYear()
- },
- pagination: {
- totalItems: 0,
- currentPage: 1,
- pageSize: 50
- }
- }),
-
- actions: {
- async fetchTrialBalance() { /* ... */ },
- async applyFilters(filters) { /* ... */ },
- clearFilters() { /* ... */ }
- }
-})
-```
-
----
-
-## 📝 Implementation Plan (Phases)
-
-### ✅ Phase 0: Preparation & Branch Setup
-**Status**: 🔲 Not Started
-
-**Tasks**:
-- [ ] Create feature branch `feature/trial-balance` from `main`
-- [ ] Verify Oracle `VBAL` table structure and test queries
-- [ ] Review existing code patterns (InvoicesView, DashboardView)
-- [ ] Read CSS documentation (ONBOARDING_CSS.md, CSS_PATTERNS.md)
-
-**Estimated Time**: 30 minutes
-
----
-
-### ✅ Phase 1: Backend API Implementation
-**Status**: 🔲 Not Started
-
-**Tasks**:
-- [ ] Create Pydantic schema: `backend/app/schemas/trial_balance.py`
- - `TrialBalanceItem` model
- - `TrialBalanceRequest` model
- - `TrialBalanceResponse` model
-- [ ] Create router: `backend/app/routers/trial_balance.py`
- - `GET /api/trial-balance` endpoint
- - Query parameters validation
- - Oracle stored procedure/query execution
- - Pagination logic
- - Filtering logic (cont, denumire)
- - Sorting logic
-- [ ] Register router in `backend/app/main.py`
-- [ ] Test endpoint manually with Postman/curl
- - Test with valid JWT token
- - Test filtering by cont
- - Test filtering by denumire
- - Test pagination
- - Test sorting
- - Test error cases (invalid token, DB errors)
-
-**Files to Create/Modify**:
-- `reports-app/backend/app/schemas/trial_balance.py` (NEW)
-- `reports-app/backend/app/routers/trial_balance.py` (NEW)
-- `reports-app/backend/app/main.py` (MODIFY)
-
-**Acceptance Criteria**:
-- ✅ API returns correct data from `VBAL` table
-- ✅ Filtering works for cont and denumire
-- ✅ Pagination returns correct page counts
-- ✅ Sorting works for all columns
-- ✅ Proper error handling and status codes
-
-**Estimated Time**: 2-3 hours
-
----
-
-### ✅ Phase 2: Frontend Store Implementation
-**Status**: 🔲 Not Started
-
-**Tasks**:
-- [ ] Create Pinia store: `frontend/src/stores/trialBalanceStore.js`
- - State definition (data, loading, error, filters, pagination)
- - `fetchTrialBalance()` action with Axios
- - `applyFilters()` action
- - `clearFilters()` action
- - Getters for computed values
-- [ ] Add API service: `frontend/src/services/trialBalanceService.js` (optional)
-- [ ] Test store in browser DevTools
-
-**Files to Create**:
-- `reports-app/frontend/src/stores/trialBalanceStore.js` (NEW)
-- `reports-app/frontend/src/services/trialBalanceService.js` (NEW, optional)
-
-**Acceptance Criteria**:
-- ✅ Store successfully fetches data from API
-- ✅ Filters update correctly
-- ✅ Loading states work properly
-- ✅ Error handling displays user-friendly messages
-
-**Estimated Time**: 1-2 hours
-
----
-
-### ✅ Phase 3: Frontend View Component
-**Status**: 🔲 Not Started
-
-**Tasks**:
-- [ ] Create Vue component: `frontend/src/views/TrialBalanceView.vue`
- - Page header with title and period info
- - Filters card (cont input, denumire input, clear button)
- - PrimeVue DataTable with columns:
- - Cont
- - Denumire Cont
- - Sold Precedent (Debit/Credit)
- - Rulaj Lunar (Debit/Credit)
- - Sold Final (Debit/Credit)
- - Loading spinner
- - Empty state (no data)
- - Error state
-- [ ] Use **existing CSS patterns** (NO new custom CSS unless necessary)
- - `.roa-page-header`
- - `.roa-card`
- - `.roa-filters-card`
- - Design tokens (spacing, colors)
-- [ ] Implement responsive design (mobile breakpoints)
-- [ ] Add number formatting (Romanian locale, 2 decimals)
-
-**Files to Create**:
-- `reports-app/frontend/src/views/TrialBalanceView.vue` (NEW)
-
-**Acceptance Criteria**:
-- ✅ Page displays correctly with data
-- ✅ Filters work and update table
-- ✅ Sorting on columns works
-- ✅ Pagination works
-- ✅ Loading/error states display correctly
-- ✅ CSS follows design system (NO `:deep()`, NO custom colors)
-- ✅ Responsive on mobile devices
-
-**Estimated Time**: 3-4 hours
-
----
-
-### ✅ Phase 4: Routing & Navigation
-**Status**: 🔲 Not Started
-
-**Tasks**:
-- [ ] Add route in `frontend/src/router/index.js`:
- ```javascript
- {
- path: '/trial-balance',
- name: 'TrialBalance',
- component: () => import('@/views/TrialBalanceView.vue'),
- meta: { requiresAuth: true }
- }
- ```
-- [ ] Add menu item in `frontend/src/components/layout/HamburgerMenu.vue`:
- - Section: "Rapoarte"
- - Icon: `pi-calculator` or `pi-table`
- - Label: "Balanță de Verificare"
- - Route: `/trial-balance`
-- [ ] Test navigation from menu
-
-**Files to Modify**:
-- `reports-app/frontend/src/router/index.js` (MODIFY)
-- `reports-app/frontend/src/components/layout/HamburgerMenu.vue` (MODIFY)
-
-**Acceptance Criteria**:
-- ✅ Route is accessible at `/trial-balance`
-- ✅ Menu item appears in hamburger menu
-- ✅ Clicking menu item navigates to page
-- ✅ Auth guard prevents unauthorized access
-
-**Estimated Time**: 30 minutes
-
----
-
-### ✅ Phase 5: Testing & Refinement
-**Status**: 🔲 Not Started
-
-**Tasks**:
-- [ ] Manual testing:
- - Test with different companies
- - Test with different date ranges
- - Test filtering edge cases (empty results, special characters)
- - Test sorting on all columns
- - Test pagination with large datasets
- - Test on mobile devices (responsive)
- - Test error scenarios (API down, invalid token)
-- [ ] Add Playwright E2E tests (optional, recommended):
- - `frontend/tests/e2e/trial-balance/trial-balance.spec.js`
- - Test navigation
- - Test filtering
- - Test data display
-- [ ] Code review & refinement:
- - Check CSS adherence (no `:deep()`, use patterns)
- - Check error handling
- - Check loading states
- - Check accessibility (keyboard navigation, screen readers)
-- [ ] Performance testing:
- - Test with 10,000+ rows
- - Check API response time
- - Check frontend rendering performance
-
-**Files to Create** (optional):
-- `reports-app/frontend/tests/e2e/trial-balance/trial-balance.spec.js` (NEW)
-
-**Acceptance Criteria**:
-- ✅ All manual tests pass
-- ✅ E2E tests pass (if implemented)
-- ✅ Performance benchmarks met (API < 2s)
-- ✅ Code follows project conventions
-- ✅ CSS follows design system strictly
-
-**Estimated Time**: 2-3 hours
-
----
-
-### ✅ Phase 6: Documentation & PR
-**Status**: 🔲 Not Started
-
-**Tasks**:
-- [ ] Update `README.md` - add Trial Balance to features list
-- [ ] Update `CLAUDE.md` - add Trial Balance to documentation index (if needed)
-- [ ] Add API documentation in backend README
-- [ ] Create PR from `feature/trial-balance` to `main`:
- - Title: "feat: Add Trial Balance (Balanță de Verificare) page"
- - Description: Link to this feature file, list phases completed
- - Screenshots of UI
- - API endpoint documentation
-- [ ] Request code review
-- [ ] Address review comments
-- [ ] Merge to `main`
-
-**Acceptance Criteria**:
-- ✅ All documentation updated
-- ✅ PR created with complete description
-- ✅ Code review approved
-- ✅ Branch merged successfully
-
-**Estimated Time**: 1 hour
-
----
-
-## 📊 Progress Tracking
-
-### Overall Progress
-- **Phase 0**: 🔲 Not Started (0%)
-- **Phase 1**: 🔲 Not Started (0%)
-- **Phase 2**: 🔲 Not Started (0%)
-- **Phase 3**: 🔲 Not Started (0%)
-- **Phase 4**: 🔲 Not Started (0%)
-- **Phase 5**: 🔲 Not Started (0%)
-- **Phase 6**: 🔲 Not Started (0%)
-
-**Total Progress**: 0% Complete
-
-### Status Legend
-- 🔲 Not Started
-- 🔄 In Progress
-- ✅ Completed
-- ⚠️ Blocked
-- ❌ Cancelled
-
----
-
-## 🚀 Getting Started
-
-### Prerequisites
-1. SSH tunnel running (`./ssh_tunnel.sh status`)
-2. Backend running (`cd reports-app/backend && uvicorn app.main:app --reload --port 8001`)
-3. Frontend running (`cd reports-app/frontend && npm run dev`)
-4. Valid JWT token for testing API
-
-### Starting Development
-```bash
-# 1. Create feature branch
-git checkout main
-git pull origin main
-git checkout -b feature/trial-balance
-
-# 2. Verify Oracle VBAL table
-# Connect to Oracle and run:
-# SELECT * FROM VBAL WHERE ROWNUM <= 10;
-
-# 3. Start backend (Phase 1)
-cd reports-app/backend
-# Create schemas/trial_balance.py
-# Create routers/trial_balance.py
-# Test with curl/Postman
-
-# 4. Start frontend (Phases 2-4)
-cd reports-app/frontend
-# Create stores/trialBalanceStore.js
-# Create views/TrialBalanceView.vue
-# Update router and menu
-
-# 5. Test and refine (Phase 5)
-# Manual testing
-# E2E tests (optional)
-
-# 6. Create PR (Phase 6)
-git add .
-git commit -m "feat: Add Trial Balance page with filtering and pagination"
-git push origin feature/trial-balance
-# Create PR on GitHub/GitLab
-```
-
----
-
-## 📚 Reference Documentation
-
-**MUST READ before coding**:
-- `docs/ONBOARDING_CSS.md` - CSS quick start (5 min read)
-- `docs/CSS_PATTERNS.md` - All available CSS patterns
-- `docs/DESIGN_TOKENS.md` - Colors, spacing, typography
-- `reports-app/frontend/README.md` - Frontend architecture
-- `reports-app/backend/README.md` - Backend architecture
-
-**Similar implementations to reference**:
-- `reports-app/frontend/src/views/InvoicesView.vue` - Table + filters pattern
-- `reports-app/frontend/src/views/DashboardView.vue` - Cards + data display
-- `reports-app/backend/app/routers/invoices.py` - API with filtering/pagination
-
----
-
-## ⚠️ Important Notes
-
-### CSS Architecture Compliance
-**CRITICAL**: This feature MUST follow the established CSS architecture:
-
-✅ **DO**:
-- Use existing `.roa-*` patterns from `CSS_PATTERNS.md`
-- Use design tokens (`var(--color-primary)`, `var(--spacing-4)`)
-- Use vendor overrides in `src/assets/css/vendor/primevue/` for PrimeVue
-- Keep component styles minimal and semantic
-- Follow BEM naming if creating new components
-
-❌ **DON'T**:
-- Use `:deep()` in Vue components
-- Hardcode colors or spacing values
-- Duplicate existing patterns
-- Create custom CSS without checking patterns first
-- Override PrimeVue styles in component `
diff --git a/reports-app/frontend/tests/e2e/invoices/invoices.spec.js b/reports-app/frontend/tests/e2e/invoices/invoices.spec.js
index 8736227..fdbf6bc 100644
--- a/reports-app/frontend/tests/e2e/invoices/invoices.spec.js
+++ b/reports-app/frontend/tests/e2e/invoices/invoices.spec.js
@@ -36,12 +36,29 @@ test.describe('Invoices View', () => {
});
});
- // Mock invoices endpoint
- await page.route('**/api/invoices/COMP1', async route => {
+ // Mock invoices endpoint - FIX: Use query parameters instead of path parameter
+ await page.route('**/api/invoices**', async route => {
+ const url = route.request().url();
+ const urlParams = new URL(url).searchParams;
+ const partnerType = urlParams.get('partner_type') || 'CLIENTI';
+
+ // Return different data based on partner_type
+ const invoicesData = partnerType === 'CLIENTI'
+ ? mockInvoices.filter(inv => inv.type === 'client')
+ : mockInvoices.filter(inv => inv.type === 'supplier');
+
await route.fulfill({
status: 200,
contentType: 'application/json',
- body: JSON.stringify(mockInvoices),
+ body: JSON.stringify({
+ invoices: invoicesData,
+ total_count: invoicesData.length,
+ filtered_count: invoicesData.length,
+ total_amount: invoicesData.reduce((sum, inv) => sum + inv.totctva, 0),
+ page: parseInt(urlParams.get('page') || '1'),
+ page_size: parseInt(urlParams.get('page_size') || '50'),
+ has_more: false
+ }),
});
});
@@ -203,12 +220,225 @@ test.describe('Invoices View', () => {
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);
});
+
+ // NEW TESTS for fixed issues
+
+ test('should filter by invoice type (CLIENTI/FURNIZORI)', async ({ page }) => {
+ let capturedPartnerType = null;
+
+ // Intercept API requests to verify partner_type parameter
+ await page.route('**/api/invoices**', async route => {
+ const url = route.request().url();
+ const urlParams = new URL(url).searchParams;
+ capturedPartnerType = urlParams.get('partner_type');
+
+ await route.fulfill({
+ status: 200,
+ contentType: 'application/json',
+ body: JSON.stringify({
+ invoices: [],
+ total_count: 0,
+ filtered_count: 0,
+ total_amount: 0,
+ page: 1,
+ page_size: 50,
+ has_more: false
+ }),
+ });
+ });
+
+ await invoicesPage.waitForPageLoad();
+ await invoicesPage.selectCompany('Compania Test 1');
+ await page.waitForSelector(invoicesPage.invoicesTable);
+
+ // Select FURNIZORI from dropdown
+ await page.locator('[placeholder="Tip factură"]').click();
+ await page.locator('.p-dropdown-item').filter({ hasText: 'Furnizori' }).click();
+ await page.waitForTimeout(1000); // Wait for API call
+
+ // Verify partner_type parameter was sent correctly
+ expect(capturedPartnerType).toBe('FURNIZORI');
+ });
+
+ test('should filter by cont (account number)', async ({ page }) => {
+ let capturedCont = null;
+
+ // Intercept API requests to verify cont parameter
+ await page.route('**/api/invoices**', async route => {
+ const url = route.request().url();
+ const urlParams = new URL(url).searchParams;
+ capturedCont = urlParams.get('cont');
+
+ await route.fulfill({
+ status: 200,
+ contentType: 'application/json',
+ body: JSON.stringify({
+ invoices: [],
+ total_count: 0,
+ filtered_count: 0,
+ total_amount: 0,
+ page: 1,
+ page_size: 50,
+ has_more: false
+ }),
+ });
+ });
+
+ await invoicesPage.waitForPageLoad();
+ await invoicesPage.selectCompany('Compania Test 1');
+ await page.waitForSelector(invoicesPage.invoicesTable);
+
+ // Enter cont filter
+ await page.locator('[placeholder="Filtru cont (ex: 4111)"]').fill('4111');
+ await page.waitForTimeout(1000); // Wait for debounced API call
+
+ // Verify cont parameter was sent correctly
+ expect(capturedCont).toBe('4111');
+ });
+
+ test('should use partner_name parameter for search', async ({ page }) => {
+ let capturedPartnerName = null;
+ let capturedSearchParam = null;
+
+ // Intercept API requests to verify correct parameter name
+ await page.route('**/api/invoices**', async route => {
+ const url = route.request().url();
+ const urlParams = new URL(url).searchParams;
+ capturedPartnerName = urlParams.get('partner_name');
+ capturedSearchParam = urlParams.get('search');
+
+ await route.fulfill({
+ status: 200,
+ contentType: 'application/json',
+ body: JSON.stringify({
+ invoices: [],
+ total_count: 0,
+ filtered_count: 0,
+ total_amount: 0,
+ page: 1,
+ page_size: 50,
+ has_more: false
+ }),
+ });
+ });
+
+ await invoicesPage.waitForPageLoad();
+ await invoicesPage.selectCompany('Compania Test 1');
+ await page.waitForSelector(invoicesPage.invoicesTable);
+
+ // Search for partner name
+ await page.locator('[placeholder="Căutați după număr, partener..."]').fill('Test Partner');
+ await page.waitForTimeout(1000); // Wait for debounced API call
+
+ // Verify partner_name parameter was sent (not search)
+ expect(capturedPartnerName).toBe('Test Partner');
+ expect(capturedSearchParam).toBeNull();
+ });
+
+ test('should export XLSX with all filters applied', async ({ page }) => {
+ let exportRequestParams = null;
+
+ // Intercept export API request
+ await page.route('**/api/invoices**', async route => {
+ const url = route.request().url();
+ const urlParams = new URL(url).searchParams;
+
+ // Capture params if it's the export request (page_size = 999999)
+ if (urlParams.get('page_size') === '999999') {
+ exportRequestParams = {
+ partner_type: urlParams.get('partner_type'),
+ partner_name: urlParams.get('partner_name'),
+ cont: urlParams.get('cont'),
+ page_size: urlParams.get('page_size')
+ };
+ }
+
+ await route.fulfill({
+ status: 200,
+ contentType: 'application/json',
+ body: JSON.stringify({
+ invoices: [
+ {
+ cont: '4111',
+ nract: 'INV001',
+ dataact: '2024-01-01',
+ datascad: '2024-02-01',
+ nume: 'Test Client',
+ totctva: 1000,
+ achitat: 500,
+ soldfinal: 500
+ }
+ ],
+ total_count: 1,
+ filtered_count: 1,
+ total_amount: 1000,
+ page: 1,
+ page_size: 999999,
+ has_more: false
+ }),
+ });
+ });
+
+ await invoicesPage.waitForPageLoad();
+ await invoicesPage.selectCompany('Compania Test 1');
+ await page.waitForSelector(invoicesPage.invoicesTable);
+
+ // Apply filters before export
+ await page.locator('[placeholder="Tip factură"]').click();
+ await page.locator('.p-dropdown-item').filter({ hasText: 'Furnizori' }).click();
+ await page.locator('[placeholder="Filtru cont (ex: 4111)"]').fill('4111');
+ await page.waitForTimeout(500);
+
+ // Click Excel export
+ const downloadPromise = page.waitForEvent('download', { timeout: 10000 }).catch(() => null);
+ await page.locator('button:has-text("Export Excel")').click();
+ await page.waitForTimeout(2000); // Wait for export to complete
+
+ // Verify export request included all filters
+ expect(exportRequestParams).toBeTruthy();
+ expect(exportRequestParams.partner_type).toBe('FURNIZORI');
+ expect(exportRequestParams.cont).toBe('4111');
+ expect(exportRequestParams.page_size).toBe('999999');
+
+ // Download may or may not occur due to mock, but we verified the API call
+ await downloadPromise;
+ });
+
+ test('should have hover effect on table rows', async ({ page }) => {
+ await invoicesPage.waitForPageLoad();
+ await invoicesPage.selectCompany('Compania Test 1');
+ await page.waitForSelector(invoicesPage.invoicesTable);
+
+ // Wait for table rows to load
+ const firstRow = page.locator('.p-datatable-tbody tr').first();
+ await firstRow.waitFor();
+
+ // Get initial background color
+ const initialBgColor = await firstRow.evaluate(el =>
+ window.getComputedStyle(el).backgroundColor
+ );
+
+ // Hover over the row
+ await firstRow.hover();
+ await page.waitForTimeout(300); // Wait for transition
+
+ // Get background color after hover
+ const hoverBgColor = await firstRow.evaluate(el =>
+ window.getComputedStyle(el).backgroundColor
+ );
+
+ // Background color should change on hover
+ expect(hoverBgColor).not.toBe(initialBgColor);
+
+ // Verify hover color is the expected blue (#e3f2fd = rgb(227, 242, 253))
+ expect(hoverBgColor).toBe('rgb(227, 242, 253)');
+ });
});
\ No newline at end of file