import { BasePage } from './BasePage.js'; export class InvoicesPage extends BasePage { constructor(page) { super(page); // Page selectors this.pageTitle = '.page-title'; this.pageSubtitle = '.page-subtitle'; // Company selection this.companySelectionCard = '.company-selection-card'; this.companyDropdown = '.company-selection .p-dropdown'; this.companyDropdownTrigger = '.company-selection .p-dropdown-trigger'; this.companyOptions = '.p-dropdown-item'; // Search and filters this.searchInput = '.search-input input'; this.statusFilter = '.status-filter .p-dropdown'; this.statusFilterTrigger = '.status-filter .p-dropdown-trigger'; this.refreshButton = '.refresh-button'; this.exportButton = '.export-button'; // Table selectors this.invoicesTable = '.invoices-table'; this.tableRows = '.invoices-table tbody tr'; this.tableHeaders = '.invoices-table thead th'; this.loadingSpinner = '.p-datatable-loading'; // Pagination this.pagination = '.p-paginator'; this.nextPageButton = '.p-paginator-next'; this.prevPageButton = '.p-paginator-prev'; this.currentPageSpan = '.p-paginator-current'; // Invoice details this.invoiceDetailsModal = '.invoice-details-modal'; this.invoiceDetailsPanel = '.invoice-details-panel'; // Specific table columns (adjust based on actual implementation) this.numberColumn = 'td:nth-child(1)'; this.dateColumn = 'td:nth-child(2)'; this.clientColumn = 'td:nth-child(3)'; this.amountColumn = 'td:nth-child(4)'; this.statusColumn = 'td:nth-child(5)'; } async navigate() { await this.page.goto('/invoices'); await this.page.waitForSelector(this.pageTitle); } async isOnInvoicesPage() { return await this.page.locator(this.pageTitle).isVisible(); } async getPageTitle() { return await this.page.locator(this.pageTitle).textContent(); } async isCompanySelectionVisible() { return await this.page.locator(this.companySelectionCard).isVisible(); } async isInvoicesTableVisible() { return await this.page.locator(this.invoicesTable).isVisible(); } async selectCompany(companyName) { await this.page.click(this.companyDropdownTrigger); await this.page.waitForSelector(this.companyOptions); await this.page.click(`${this.companyOptions}:has-text("${companyName}")`); await this.waitForLoadingToFinish(); } async searchInvoices(searchTerm) { await this.page.fill(this.searchInput, searchTerm); await this.page.press(this.searchInput, 'Enter'); } async filterByStatus(status) { await this.page.click(this.statusFilterTrigger); await this.page.waitForSelector(this.companyOptions); // Map status to Romanian text (adjust based on actual implementation) const statusMap = { 'paid': 'Plătit', 'unpaid': 'Neplătit', 'overdue': 'Întârziat' }; const statusText = statusMap[status] || status; await this.page.click(`${this.companyOptions}:has-text("${statusText}")`); } async sortByColumn(columnName) { // Map column names to actual header text const columnMap = { 'number': 'Număr', 'date': 'Data', 'client': 'Client', 'amount': 'Sumă', 'status': 'Status' }; const headerText = columnMap[columnName] || columnName; await this.page.click(`${this.tableHeaders}:has-text("${headerText}")`); } async getVisibleInvoicesCount() { return await this.page.locator(this.tableRows).count(); } async getFirstInvoiceData() { const firstRow = this.page.locator(this.tableRows).first(); return { number: await firstRow.locator(this.numberColumn).textContent(), date: await firstRow.locator(this.dateColumn).textContent(), client: await firstRow.locator(this.clientColumn).textContent(), amount: await firstRow.locator(this.amountColumn).textContent(), status: await firstRow.locator(this.statusColumn).textContent() }; } async clickFirstInvoiceRow() { await this.page.locator(this.tableRows).first().click(); } async isInvoiceDetailsVisible() { const modalVisible = await this.page.locator(this.invoiceDetailsModal).isVisible(); const panelVisible = await this.page.locator(this.invoiceDetailsPanel).isVisible(); return modalVisible || panelVisible; } async clickExportButton() { await this.page.click(this.exportButton); } async clickRefreshButton() { await this.page.click(this.refreshButton); } async isPaginationVisible() { return await this.page.locator(this.pagination).isVisible(); } async goToNextPage() { await this.page.click(this.nextPageButton); } async goToPrevPage() { await this.page.click(this.prevPageButton); } async getCurrentPage() { const pageText = await this.page.locator(this.currentPageSpan).textContent(); // Extract page number from text like "Page 2 of 5" const match = pageText.match(/(\d+)/); return match ? parseInt(match[1]) : 1; } async waitForPageLoad() { await Promise.race([ this.page.waitForSelector(this.companySelectionCard, { timeout: 10000 }), this.page.waitForSelector(this.invoicesTable, { timeout: 10000 }) ]); } async waitForTableLoad() { await this.page.waitForSelector(this.invoicesTable, { timeout: 10000 }); await this.waitForLoadingToFinish(); } async getInvoiceByNumber(invoiceNumber) { const rows = this.page.locator(this.tableRows); const rowCount = await rows.count(); for (let i = 0; i < rowCount; i++) { const row = rows.nth(i); const number = await row.locator(this.numberColumn).textContent(); if (number.trim() === invoiceNumber) { return row; } } return null; } async clickInvoiceByNumber(invoiceNumber) { const row = await this.getInvoiceByNumber(invoiceNumber); if (row) { await row.click(); } } }