diff --git a/app/Console/Commands/CypressResetCommand.php b/app/Console/Commands/CypressResetCommand.php new file mode 100644 index 00000000..4f2dafea --- /dev/null +++ b/app/Console/Commands/CypressResetCommand.php @@ -0,0 +1,25 @@ +info('Resetting Cypress test data...'); + + $this->call('db:seed', [ + '--class' => 'Database\\Seeders\\CypressSeeder', + ]); + + $this->info('Cypress test data reset successfully.'); + + return self::SUCCESS; + } +} diff --git a/cypress/e2e/efomento/noticePage/notice.cy.js b/cypress/e2e/efomento/noticePage/notice.cy.js index 16b93cff..e2ff7bf2 100644 --- a/cypress/e2e/efomento/noticePage/notice.cy.js +++ b/cypress/e2e/efomento/noticePage/notice.cy.js @@ -1,177 +1,268 @@ -import Login from '../../../pages/auth'; +import NoticeWorkflow from '../../../support/workflows/NoticeWorkflow'; import Notice from '../../../pages/notice/NoticePage'; describe('Notice Page - E2E Tests', () => { - beforeEach(() => { + beforeEach(function () { + cy.resetCypressData(); + cy.fixture('users').as('user'); - cy.fixture('notices').as('notice'); - cy.get('@user').then((user) => { - Login.accessLoginPage(); - Login.successLogin(user.valid_email, user.password, user.name); + cy.fixture('notices').then((notices) => { + this.notice = notices.notice; + this.noticeIdentificationForm = notices.noticeIdentificationForm; }); - Notice.visitPage(); - Notice.verifyPageLoaded(); + cy.fixture('noticeUpdate').as('noticeUdate'); }); - describe('Page Access and Navigation', () => { - it('should access the notice list page', function () { - cy.url().should('include', '/editais'); - }); + describe('Dashboard', () => { + it('should display the notice dashboard metrics', function () { + // Arrange + cy.loginByRole('fomentation'); - it('should display the notice list table', function () { - cy.get('[data-cy=table-notice-list]').should('be.visible'); - }); - }); + // Act + NoticeWorkflow.gotToNoticePage(); - describe('Dashboard Visibility', () => { - it('should display all dashboard cards', function () { + // Assert Notice.verifyDashboardCardsAreVisible(); }); it('should display all dashboard metric cards', function () { - Notice.verifyAllDashboardMetrics(); - }); - }); + // Arrange + cy.loginByRole('fomentation'); - describe('User Information Display', () => { - it('should display logged user name in header avatar', function () { - Notice.verifyLoggedUserDisplayedInHeader(this.user.name); - }); + // Act + NoticeWorkflow.gotToNoticePage(); - it('should display welcome message with user name', function () { - Notice.verifyWelcomeMessageDisplaysUsername(this.user.name); + // Assert + Notice.verifyAllDashboardMetrics(); }); }); - describe('Identification Data Form', () => { + describe('Identification Data', () => { it('should open the identification data form', function () { - Notice.openIdentificationDataForm(); - cy.get('[data-cy=notice-nup-identification-data-form]').should('be.visible'); + // Arrange + cy.loginByRole('fomentation'); + NoticeWorkflow.gotToNoticePage(); + + // Act + NoticeWorkflow.openIdentificationDataForm(); + + // Assert + NoticeWorkflow.validateIdentificationDataFormIsVisible(); }); it('should fill and submit the identification data form', function () { - Notice.openIdentificationDataForm(); + // Arrange + const notice = this.noticeIdentificationForm; + + cy.loginByRole('fomentation'); - const notice = this.notice[0]; - const formData = { - noticeNup: notice.noticeNup, - instrumentType: notice.noticeInstrumentType, - totalAmount: notice.noticeTotalValue, - noticeManager: notice.noticeAccompanimentManager, - managerEmail: notice.noticeManagerEmail, - quotaNumber: notice.quotaNumber, - }; - - Notice.fillIdentificationDataForm(formData); + NoticeWorkflow.gotToNoticePage(); + + Notice.searchNoticeByTitle(notice.title); + + // Act + NoticeWorkflow.fillNoticeIdentificationData(notice); + Notice.submitIdentificationDataForm(); + + // Assert Notice.verifySuccessMessageIdentificationDataForm(); }); }); describe('Search Functionality', () => { it('should find a notice by title', function () { - const notice = this.notice[0]; + // Arrange + const notice = this.notice; + cy.loginByRole('fomentation'); + // Act + NoticeWorkflow.gotToNoticePage(); Notice.searchNoticeByTitle(notice.title); + + // Assert + Notice.validateResultSearchByTitle(notice.title); }); - it('should find a notice by NUP number', function () { - const notice = this.notice[0]; + it('should find a notice by NUP', function () { + // Arrange + const notice = this.notice; + cy.loginByRole('fomentation'); + // Act + NoticeWorkflow.gotToNoticePage(); Notice.searchNoticeByNup(notice.noticeNup); + + // Assert + Notice.validateResultSearchByNup(notice.noticeNup); }); it('should clear search and display all notices', function () { - const notice = this.notice[0]; + // Arrange + const notice = this.notice; + cy.loginByRole('fomentation'); - Notice.searchNoticeByNup(notice.noticeNup); - cy.get('[data-cy=find-specific-notice] input').clear(); - cy.get('[data-cy=table-notice-list] tbody tr').should('have.length.greaterThan', 1); + NoticeWorkflow.gotToNoticePage(); + + Notice.getTotalNotices().then((initialTotal) => { + Notice.searchNoticeByNup(notice.noticeNup); + + // Act + Notice.clearNoticeSearch(); + + // Assert + Notice.validateNoticeListAfterClearingSearch(initialTotal); + }); }); }); describe('Filtering', () => { it('should filter notices by process status', function () { - const notice = this.notice[0]; + // Arrange + const notice = this.notice; + cy.loginByRole('fomentation'); - Notice.filterByProcessStatus(notice.processsStatus); + NoticeWorkflow.gotToNoticePage(); + + // Act + Notice.filterByProcessStatus(notice.processStatus); + + // Assert + Notice.validateNoticesByStatus(notice.processStatus); }); it('should filter notices by instrument type', function () { - const notice = this.notice[0]; + // Arrange + const notice = this.notice; + cy.loginByRole('fomentation'); + + NoticeWorkflow.gotToNoticePage(); - Notice.filterByInstrumentType(notice.noticeInstrumentType); + // Act + Notice.filterByInstrumentType(notice.instrumentType); + + // Assert + Notice.validateNoticesByInstrumentType(notice.instrumentType); }); }); describe('Notice Details View', () => { it('should open notice details page', function () { - const notice = this.notice[0]; + // Arrange + const notice = this.notice; + cy.loginByRole('fomentation'); + + NoticeWorkflow.gotToNoticePage(); + // Act Notice.searchNoticeByNup(notice.noticeNup); Notice.goToNoticeDetailsPage(notice.noticeNup); - cy.url().should('match', /\/editais\/\d+\/projetos$/); + + // Assert + NoticeWorkflow.validateNoticeDetailsPageUrl(); }); it('should display all information in detail view', function () { - const notice = this.notice[0]; + // Arrange + const notice = this.notice; + cy.loginByRole('fomentation'); + NoticeWorkflow.gotToNoticePage(); + // Act Notice.searchNoticeByNup(notice.noticeNup); Notice.goToNoticeDetailsPage(notice.noticeNup); Notice.clickShowAllInformationButton(); - Notice.verifyDetailViewElements(); - }); - it('should display correct NUP in detail view', function () { - const notice = this.notice[0]; - Notice.searchNoticeByNup(notice.noticeNup); - Notice.goToNoticeDetailsPage(notice.noticeNup); - Notice.displayCorrectNupInDetailView(notice.noticeNup); + // Assert + Notice.verifyDetailViewElements(); + Notice.verifyIdentificationData(notice); }); }); describe('Pagination', () => { it('should change the number of items displayed per page', function () { - const itemsPerPage = this.notice[0].quantityPerPage; - Notice.changeItemsPerPage(itemsPerPage); + // Arrange + const noticesPerPage = this.notice.noticesPerPage; + cy.loginByRole('fomentation'); + NoticeWorkflow.gotToNoticePage(); + + // Act + Notice.changeItemsPerPage(noticesPerPage); + + // Assert + Notice.validateNoticesPerPage(noticesPerPage); }); it('should navigate to next page and highlight current page number', function () { - Notice.goToPage(2); - cy.get('[data-cy=pagination-number-notice-list]') - .contains('2') - .parent() - .should('have.css', 'background-color', 'rgb(255, 193, 7)'); + // Arrange + const pageNumber = '1'; + cy.loginByRole('fomentation'); + + NoticeWorkflow.gotToNoticePage(); + + // Act + Notice.goToPage(pageNumber); + + // Assert + Notice.verifyPageIsActive(pageNumber); }); }); describe('Form Error Handling', () => { it('should display error when submitting form with invalid data', function () { + // Arrange + cy.loginByRole('fomentation'); + + NoticeWorkflow.gotToNoticePage(); + Notice.openIdentificationDataForm(); - // Try to submit with empty required fields - cy.get('[data-cy=add-data-identification-data-form-button]').click(); + // Act + Notice.submitIdentificationDataForm(); - // Expect validation error - cy.get('[data-cy=notice-nup-identification-data-form]') - .closest('.v-input') - .contains('Campo obrigatório') - .should('be.visible'); + // Assert + Notice.verifyNoticeNupRequiredFieldError(); }); }); describe('Update Notice Data', () => { it('should update data about notice and save', function () { - const currentNoticeData = this.notice[0]; - const newNoticeData = this.notice[1]; + // Arrange + const currentNotice = this.notice; + const noticeUpdate = this.noticeUdate; + + cy.loginByRole('fomentation'); - Notice.goToNoticeDetailsPage(currentNoticeData.noticeNup); + NoticeWorkflow.gotToNoticePage(); + + Notice.searchNoticeByNup(currentNotice.noticeNup); + Notice.goToNoticeDetailsPage(currentNotice.noticeNup); Notice.clickShowAllInformationButton(); - Notice.verifyDetailViewElements(); - Notice.updateDataAboutProcess(newNoticeData.noticeInstrumentType, newNoticeData.noticeManagerEmail); - Notice.verifySuccessMessageUpdateNoiceData(); - Notice.verifyUpdatedDataAboutProcess(newNoticeData.noticeInstrumentType, newNoticeData.noticeManagerEmail); + + // Act + Notice.updateDataAboutProcess(noticeUpdate.accompanimentManager, noticeUpdate.managerEmail); + + // Assert + Notice.verifySuccessMessageUpdateNoticeData(); + Notice.verifyUpdatedDataAboutProcess(noticeUpdate.accompanimentManager, noticeUpdate.managerEmail); + }); + }); + + describe('Upload Payment Report', () => { + beforeEach(() => { + cy.resetCypressData(); + }); + + it('should upload payments report', function () { + // Arrange + cy.loginByRole('financial'); + + // Act + NoticeWorkflow.uploadPaymentsReportFile(); + + // Assert + NoticeWorkflow.validatePaymentReportUpload(); }); }); }); diff --git a/cypress/fixtures/documents/payments-report.csv b/cypress/fixtures/documents/payments-report.csv new file mode 100644 index 00000000..8912bc93 --- /dev/null +++ b/cypress/fixtures/documents/payments-report.csv @@ -0,0 +1,3 @@ +270401 - FUNDO ESTADUAL DE CULTURA,,,,,,,,,,,,,"98571495,02","98223904,68","91271532,56",, +Unidade Gestora / Data NE,Nota de Empenho,Data NL,Nota de Liquidação,Data OB,Ordem Bancária,Fonte Completa,Natureza Despesa,Processo,Credor,Nome do Credor,Credor da Retenção,Domicílio Bancário Origem (OB),Empenhado,Liquidado,Pago,, +26/02/2025,2025NE000002 – CYPRESS TESTE,26/02/2025,2025NL000005,27/02/2025,2026OB000025,1234567890,123456,27001.501234/5678-90,12345678901,CREDOR CYPRESS,07950123456789 - SECRETARIA DA CULTURA DO EST DO CEARA,123 - 1234 – 1234567021122,"30,08","30,08","30,08",,NUP diff --git a/cypress/fixtures/noticeUpdate.json b/cypress/fixtures/noticeUpdate.json new file mode 100644 index 00000000..1d7a5046 --- /dev/null +++ b/cypress/fixtures/noticeUpdate.json @@ -0,0 +1,5 @@ +{ + "accompanimentManager": "Cypress Notice Manager", + "managerEmail": "cypress.update@example.com", + "totalAmount": 14258 +} diff --git a/cypress/fixtures/notices.json b/cypress/fixtures/notices.json index 04d6d0e4..a25a850a 100644 --- a/cypress/fixtures/notices.json +++ b/cypress/fixtures/notices.json @@ -1,13 +1,26 @@ { - "id": 54, - "title": "SINCRONISMO DO MAPA CULTURAL COM O EFOMENTO", - "processStatus": "Processos em andamento", - "noticeNup": "27001123456789012", - "processInstrumentType": "CONVÊNIO", - "noticeTotalValue": 13500000, - "noticeAccompanimentManager": "Saulo Furtado", - "noticeManagerEmail": "saulo.furtado@example.com", - "quotaNumber": 5, - "installmentAmount": 1500000, - "quantityPerPage": 25 + "notice": { + "title": "EDITAL CYPRESS - EFOMENTO", + "processStatus": "Processos em andamento", + "noticeNup": "27001123456789012", + "instrumentType": "CONVÊNIO", + "totalAmount": 13500000, + "accompanimentManager": "Cypress Notice Manager", + "managerEmail": "cypress.manager@example.com", + "quotaNumber": 3, + "installmentAmount": 1500000, + "noticesPerPage": 25 + }, + "noticeIdentificationForm": { + "title": "EDITAL CYPRESS - PREENCHIMENTO", + "processStatus": "Processos em andamento", + "noticeNup": "27001123456789013", + "instrumentType": "CONVÊNIO", + "totalAmount": 23800000, + "accompanimentManager": "Cypress Notice Manager", + "managerEmail": "cypress.manager@example.com", + "quotaNumber": 3, + "installmentAmount": 780000, + "noticesPerPage": 50 + } } diff --git a/cypress/fixtures/projects.json b/cypress/fixtures/projects.json index b32a7759..ab23c000 100644 --- a/cypress/fixtures/projects.json +++ b/cypress/fixtures/projects.json @@ -1,4 +1,42 @@ { - "title": "Projects", - "projectNup": "12345678901234569" + "opening": { + "registrationId": "CYPRESS-PROJECT_OPENNING", + "phase": "opening", + "title": "Projeto Cypress - Abertura", + "nup": "27001101234567890" + }, + "legal_analisys": { + "registrationId": "CYPRESS-LEGAL_ANALISYS_", + "phase": "legal_analisys", + "title": "Projeto Cypress - Análise Jurídica", + "nup": "27001201234567890" + }, + "formalization": { + "registrationId": "CYPRESS-PROJECT-FORMALIZATION", + "phase": "formalization", + "title": "Projeto Cypress - Formalização", + "nup": "27001301234567890" + }, + "budgetary": { + "registrationId": "CYPRESS-PROJECT_BUDGETARY", + "phase": "budgetary", + "title": "Projeto Cypress - Orçamento", + "nup": "27001401234567890" + }, + "payment": { + "registrationId": "CYPRESS-PROJECT-PAYMENT", + "phase": "payment", + "title": "Projeto Cypress - Pagamento", + "nup": "27001501234567890", + "installment": { + "number": 1, + "amount": 30.08 + } + }, + "monitoring": { + "registrationId": "CYPRESS-PROJECT-MONITORING", + "phase": "monitoring", + "title": "Projeto Cypress - Monitoramento", + "nup": "27001601234567890" + } } diff --git a/cypress/fixtures/users.json b/cypress/fixtures/users.json index 2c0d920d..c8f583c5 100644 --- a/cypress/fixtures/users.json +++ b/cypress/fixtures/users.json @@ -48,5 +48,15 @@ "updated_name": "User Updated", "updated_email": "user.updated@example.com", "new_password": "newpassword" + }, + "financial": { + "name": "Claudia Moreira", + "valid_email": "claudia.moreira@secult.ce.gov.br", + "password": "password", + "invalid_email": "test", + "incorrect_password": "123456", + "updated_name": "User Updated", + "updated_email": "user.updated@example.com", + "new_password": "newpassword" } } diff --git a/cypress/pages/notice/NoticePage.js b/cypress/pages/notice/NoticePage.js index 01de4a86..1bc51e80 100644 --- a/cypress/pages/notice/NoticePage.js +++ b/cypress/pages/notice/NoticePage.js @@ -1,7 +1,6 @@ import { elements as el } from './elements'; class Notice { - // Navigation and Page Access visitPage() { cy.visit('/editais'); } @@ -10,14 +9,13 @@ class Notice { cy.get(el.noticeListTable, { timeout: 10000 }).should('be.visible'); } - // Dashboard verifyDashboardCardsAreVisible() { cy.get(el.dashboardCard).should('have.length.at.least', 1); } verifyAllDashboardMetrics() { const expectedMetrics = [ - 'Editais Pendentes para abertura de processo', + 'Editais pendentes para abertura de processo', 'Editais com processos em andamento', 'Processos Formalizados', ]; @@ -27,7 +25,6 @@ class Notice { }); } - // User Info verifyLoggedUserDisplayedInHeader(username) { cy.get(el.userAvatarButton).should('be.visible').and('contain', username); } @@ -36,47 +33,46 @@ class Notice { cy.get(el.welcomeMessage).should('be.visible').and('contain', username); } - // Form Navigation + verifyIdentificationDataFormIsVisible() { + cy.get(el.noticeNupInput).should('be.visible'); + cy.get(el.instrumentTypeSelect).should('be.visible'); + cy.get(el.totalAmountInput).should('be.visible'); + cy.get(el.noticeManagerInput).should('be.visible'); + cy.get(el.managerEmailInput).should('be.visible'); + cy.get(el.quotaNumberInput).should('be.visible'); + cy.get(el.publicPolicySelect).should('be.visible'); + cy.get(el.budgeAllocationNupInput).should('be.visible'); + cy.get(el.budgetAllocationRequestDateInput).should('be.visible'); + cy.get(el.creditorRegistrationNup).should('be.visible'); + cy.get(el.creditorRegistratioRequestDate).should('be.visible'); + cy.get(el.closeIdentificationDataButton).should('be.visible'); + cy.get(el.submitFormButton).should('be.visible'); + } + openIdentificationDataForm() { cy.get(el.identificationDataFormButton).should('be.visible').first().click(); } - // Form Filling fillIdentificationDataForm(formData) { - const { noticeNup, instrumentType, totalAmount, noticeManager, managerEmail, quotaNumber, publicPolicy } = - formData; + const { noticeNup, instrumentType, totalAmount, accompanimentManager, managerEmail, quotaNumber } = formData; - // Fill NUP field cy.get(el.noticeNupInput).should('be.visible').type(noticeNup); - - // Select instrument type - cy.get(el.instrumentTypeSelect).should('be.visible').click(); - - cy.contains('.v-list-item', instrumentType).should('be.visible').click(); - - // Fill amount + this.selectDropdownOption(el.instrumentTypeSelect, instrumentType); cy.get(el.totalAmountInput).should('be.visible').type(totalAmount); - - // Fill manager name - cy.get(el.noticeManagerInput).should('be.visible').type(noticeManager); - - // Fill email + cy.get(el.noticeManagerInput).should('be.visible').type(accompanimentManager); cy.get(el.managerEmailInput).should('be.visible').type(managerEmail); - - // Fill quota number cy.get(el.quotaNumberInput).should('be.visible').type(quotaNumber); + } - this.selectDropdownOption( - '[data-cy=monitoring-report-request-deadline-identification-data-form-select]', - publicPolicy - ); - - // Submit form + submitIdentificationDataForm() { cy.get(el.submitFormButton).should('be.visible').click(); } + verifyNoticeNupRequiredFieldError() { + cy.get(el.noticeNupInput).closest('.v-input').contains('Campo obrigatório').should('be.visible'); + } + verifySuccessMessageIdentificationDataForm() { - // Verify success message cy.get(el.successAlert, { timeout: 20000 }) .contains('Número do processo salvo com sucesso') .should('be.visible'); @@ -94,10 +90,11 @@ class Notice { cy.contains('.v-list-item', valueStr).should('be.visible').click(); } - // Search and Filtering searchNoticeByTitle(title) { cy.get(el.findSpecificNoticeInput).should('be.visible').type(title); + } + verifyNoticeWithTitleIsDisplayed(title) { cy.get(el.noticeListTable).within(() => { cy.get(el.noticeTitleNoticesList).contains(title).should('be.visible'); }); @@ -107,48 +104,77 @@ class Notice { const expectedNup = this.normalizeNup(nup); cy.get(el.findSpecificNoticeInput).should('be.visible').type(expectedNup); + } + + validateResultSearchByNup(nup) { + const expectedNup = this.normalizeNup(nup); cy.get(el.noticeListTable).within(() => { cy.get(el.noticeNupNoticesList) .invoke('text') .then((text) => { - const formattedNup = text.replace(/\D/g, ''); + const formattedNup = this.normalizeNup(text); + expect(formattedNup).to.equal(expectedNup); }); }); } + validateResultSearchByTitle(noticeTitle) { + cy.get(el.noticeListTable).within(() => { + cy.get(el.noticeTitleNoticesList).contains(noticeTitle).should('be.visible'); + }); + } + + clearNoticeSearch() { + cy.get(`${el.findSpecificNoticeInput} input`).clear(); + } + + getTotalNotices() { + return cy + .get(el.noticeTotalCount) + .invoke('text') + .then((text) => Number(text.trim())); + } + + validateNoticeListAfterClearingSearch(expectedTotal, expectedRows = 10) { + this.getTotalNotices().should('eq', expectedTotal); + + cy.get(`${el.noticeListTable} tbody tr`).should('have.length', expectedRows); + } + filterByProcessStatus(status) { this.selectDropdownOption(el.filterProcessStatusSelect, status); + } - // Verify the table shows items matching the selected status + verifyNoticesAreFilteredByStatus(status) { cy.get(el.noticeListTable).should('be.visible').and('contain', status); } filterByInstrumentType(instrumentType) { this.selectDropdownOption(el.filterInstrumentTypeSelect, instrumentType); + } - // Verify the table lists the expected instrument type - // cy.get(el.noticeListTable).should('be.visible').and('contain', instrumentType); + verifyNoticesAreFilteredByInstrumentType(instrumentType) { + cy.get(el.noticeListTable).should('be.visible').and('contain', instrumentType); } - // Detail View goToNoticeDetailsPage(nup) { const expectedNup = this.normalizeNup(nup); - cy.get(el.noticeNupNoticesList).each(($element) => { - const currentNup = this.normalizeNup($element.text()); + cy.get(el.noticeTableRow) + .filter((_, row) => { + const currentNup = this.normalizeNup(Cypress.$(row).find(el.noticeNupNoticesList).text()); - if (currentNup === expectedNup) { - cy.wrap($element).closest('tr').find(el.accessNoticeInformationButton).click(); - } - }); - - cy.url({ timeout: 10000 }).should('match', /\/editais\/\d+\/projetos$/); + return currentNup === expectedNup; + }) + .first() + .find(el.accessNoticeInformationButton) + .click(); } - clickShowAllInformationButton() { - cy.get(el.showAllInformationButton).should('be.visible').click(); + verifyNoticeDetailsPageIsDisplayed() { + cy.url({ timeout: 10000 }).should('match', /\/editais\/\d+\/projetos$/); } verifyDetailViewElements() { @@ -156,7 +182,7 @@ class Notice { el.noticeTitleDetail, el.noticeNupDetail, el.instrumentTypeDetail, - el.noticeManagerDetail, + el.accompanimentManagerDetail, el.budgetAllocationRequestDateDetail, el.totalAmountDetail, el.valueInFullDetail, @@ -172,23 +198,40 @@ class Notice { }); } + verifyIdentificationData(notice) { + cy.get(el.noticeTitleDetail).should('contain', notice.title); + + cy.get(el.noticeNupDetail) + .invoke('text') + .then((displayedNup) => { + expect(this.normalizeNup(displayedNup)).to.equal(this.normalizeNup(notice.noticeNup)); + }); + + cy.get(el.instrumentTypeDetail).should('contain', notice.instrumentType); + } + displayCorrectNupInDetailView(nup) { const formatedNup = this.normalizeNup(nup); cy.get('[data-cy=notice-nup-show-all-information]').should('be.visible').and('contain', formatedNup); } - // Pagination changeItemsPerPage(quantity) { const quantityStr = quantity.toString(); this.selectDropdownOption(el.quantityPerPageSelect, quantityStr); + } - cy.get(`${el.noticeListTable} tbody tr`, { timeout: 5000 }).should('have.length', quantity); + validateNoticesPerPage(noticesPerPage) { + cy.get(`${el.noticeListTable} tbody tr`, { timeout: 5000 }).should('have.length', noticesPerPage); } goToPage(pageNumber) { const pageStr = pageNumber.toString(); cy.get(el.paginationNumber).contains(pageStr).should('be.visible').click(); + } + + verifyPageIsActive(pageNumber) { + const pageStr = pageNumber.toString(); cy.get(el.paginationNumber) .contains(pageStr) @@ -200,38 +243,39 @@ class Notice { return String(value).replace(/\D/g, ''); } - updateDataAboutProcess(newInstrumentType, newManagerEmail) { - const instrumentType = newInstrumentType.toString(); + updateDataAboutProcess(newAccompanimentManager, newManagerEmail) { + const newNoticeManager = String(newAccompanimentManager); + + cy.get(el.accompanimentManagerDetail).should('be.visible').children().eq(1).click(); + + cy.get(el.noticeEditTextField).find('input').should('be.visible').clear(); - // Update Instrument Type - cy.get(el.instrumentTypeDetail).children().eq(1).click(); - this.selectDropdownOption(el.instrumentTypeDetail, instrumentType); + cy.get(el.noticeEditTextField).find('input').should('be.visible').type(newNoticeManager); - // Update Manager Email cy.get(el.managerEmailDetail).children().eq(1).click(); + cy.get(el.noticeEditTextField).find('input').should('be.visible').clear(); + cy.get(el.noticeEditTextField).find('input').should('be.visible').type(newManagerEmail); - // Click in Update Button cy.get(el.updateDataButton).click({ force: true }); } - verifySuccessMessageUpdateNoiceData() { - // Verify success message + verifySuccessMessageUpdateNoticeData() { cy.get(el.successAlert, { timeout: 20000 }).contains('Dados atualizados com sucesso').should('be.visible'); } - verifyUpdatedDataAboutProcess(newInstrumentType, newManagerEmail) { + verifyUpdatedDataAboutProcess(newaccompanimentManager, newManagerEmail) { cy.reload(); this.clickShowAllInformationButton(); - cy.get(el.instrumentTypeDetail) + cy.get(el.accompanimentManagerDetail) .children() .eq(1) .invoke('text') .then((text) => { - expect(text.trim()).to.eq(newInstrumentType); + expect(text.trim()).to.eq(newaccompanimentManager); }); cy.get(el.managerEmailDetail) @@ -242,6 +286,46 @@ class Notice { expect(text.trim()).to.eq(newManagerEmail); }); } + + validateNoticesByStatus(status) { + cy.get(`${el.noticeListTable} tbody tr`).each(($row) => { + cy.wrap($row).should('contain.text', status); + }); + } + + validateNoticesByInstrumentType(instrumentType) { + cy.get(`${el.noticeListTable} tbody tr`).each(($row) => { + cy.wrap($row).should('contain.text', instrumentType); + }); + } + + clickUploadPaymentsReportButton() { + cy.get(el.uploadBPaymentsReportButton) + .should('be.visible') + .and('not.be.disabled') + .contains('Subir relatório de pagamentos') + .click(); + } + + clickShowAllInformationButton() { + cy.get(el.showAllInformationButton).should('be.visible').click(); + } + + uploadPaymentsReport() { + cy.intercept('POST', '/editais/projetos/pagamento/import').as('importPayments'); + + cy.get(el.paymentsReportFileInput).selectFile('cypress/fixtures/documents/payments-report.csv', { + force: true, + }); + } + + displaySuccessMessagePaymentReportUploaded() { + cy.wait('@importPayments'); + + cy.get(el.successAlert) + .contains('Importação concluída. 1 projeto(s) tiveram parcela(s) atualizada(s) com sucesso.') + .should('be.visible'); + } } export default new Notice(); diff --git a/cypress/pages/notice/elements.js b/cypress/pages/notice/elements.js index bc60e43d..9dcde1d3 100644 --- a/cypress/pages/notice/elements.js +++ b/cypress/pages/notice/elements.js @@ -1,5 +1,3 @@ -import project from '../project/ProjectPage'; - export const elements = { // appContainer: '#app', @@ -10,6 +8,7 @@ export const elements = { userAvatarButton: '[data-cy=btnUserAvatar]', // Tables + noticeTotalCount: '[data-cy=notice-total-count]', noticeListTable: '[data-cy=table-notice-list]', noticeTableRow: '[data-cy=row-table-notice-list]', noticeNupNoticesList: '[data-cy=notice-nup-notices-list]', @@ -27,13 +26,21 @@ export const elements = { paginationNumber: '[data-cy=pagination-number-notice-list]', // Identification Data Form + identificationDataForm: '[data-cy=identification-data-form]', identificationDataFormButton: '[data-cy=access-identification-data-form-button]', noticeNupInput: '[data-cy=notice-nup-identification-data-form]', instrumentTypeSelect: '[data-cy=instrument-type-identification-data-form-select]', totalAmountInput: '[data-cy=total-amount-notice-identification-data-form]', + amountInFullIdentificationData: '[data-cy=amount-in-full-information-data]', noticeManagerInput: '[data-cy=notice-manager-accompaniment-identification-data-form]', managerEmailInput: '[data-cy=manager-email-identification-data-form]', quotaNumberInput: '[data-cy=quota-number-identification-data-form]', + publicPolicySelect: '[data-cy=public-policy-identification-data-form-select]', + budgeAllocationNupInput: '[data-cy="budget-allocation-nup"]', + budgetAllocationRequestDateInput: '[data-cy="budget-allocation-request-date"]', + creditorRegistrationNup: '[data-cy="creditor-retistration-nup"]', + creditorRegistratioRequestDate: '[data-cy="creditor-registration-request-date"]', + closeIdentificationDataButton: '[data-cy="close-idetification-data-button"]', submitFormButton: '[data-cy=add-data-identification-data-form-button]', // List actions @@ -45,7 +52,7 @@ export const elements = { noticeNupDetail: '[data-cy=notice-nup-show-all-information]', instrumentTypeDetail: '[data-cy=instrument-type-show-all-information]', allInformationSelect: 'data-cy=all-information-select', - noticeManagerDetail: '[data-cy=notice-manager-show-all-information]', + accompanimentManagerDetail: '[data-cy=accompaniment-manager-show-all-information]', budgetAllocationRequestDateDetail: '[data-cy=budget-allocation-request-date-show-all-information]', totalAmountDetail: '[data-cy=total-amount-show-all-information]', valueInFullDetail: '[data-cy=value-in-full-show-all-information]', @@ -59,6 +66,8 @@ export const elements = { noticeEditTextField: '[data-cy=notice-edit-textfield]', noticeEditTextArea: '[data-cy=notice-edit-textarea]', noticeEditTextSelect: '[data-cy=notice-edit-select]', + paymentsReportFileInput: '[data-cy=payments-report-file-input]', + uploadBPaymentsReportButton: '[data-cy=upload-payments-report-button]', // Alerts successAlert: '.v-snackbar', diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 2e53171c..fb6ae3a3 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -65,3 +65,7 @@ Cypress.Commands.add('loginByRole', (role) => { ); }); }); + +Cypress.Commands.add('resetCypressData', () => { + return cy.exec('docker compose exec -T app php artisan cypress:reset'); +}); diff --git a/cypress/support/workflows/NoticeWorkflow.js b/cypress/support/workflows/NoticeWorkflow.js new file mode 100644 index 00000000..a42ee62d --- /dev/null +++ b/cypress/support/workflows/NoticeWorkflow.js @@ -0,0 +1,103 @@ +import '../commands.js'; +import Notice from '../../pages/notice/NoticePage.js'; + +class NoticeWorkflow { + gotToNoticePage() { + Notice.visitPage(); + Notice.verifyPageLoaded(); + } + + validateDashboardCardsAreVisible() { + Notice.verifyDashboardCardsAreVisible(); + } + + validateAllDashBoardMetrics() { + Notice.verifyAllDashboardMetrics(); + } + + accessNoticeDetails(nup) { + Notice.searchNoticeByNup(nup); + Notice.findNoticeByNup(nup); + + cy.url().should('match', /\/editais\/\d+\/projetos$/); + } + + fillRequiredNoticeIdentificationData(notice) { + Notice.openIdentificationDataForm(); + + Notice.fillRequiredIdentificationDataFields({ + noticeNup: notice.noticeNup, + instrumentType: notice.instrumentType, + totalAmount: notice.totalAmount, + quotaNumber: notice.quotaNumber, + }); + } + + fillNoticeIdentificationData(notice) { + this.gotToNoticePage(); + + Notice.searchNoticeByTitle(notice.title); + Notice.openIdentificationDataForm(); + + Notice.fillIdentificationDataForm({ + noticeNup: notice.noticeNup, + instrumentType: notice.instrumentType, + totalAmount: notice.totalAmount, + accompanimentManager: notice.accompanimentManager, + managerEmail: notice.managerEmail, + quotaNumber: notice.quotaNumber, + }); + } + + updateNoticeData(currentNotice, newNotice) { + this.accessNoticeDetails(currentNotice.noticeNup); + + Notice.clickShowAllInformationButton(); + Notice.verifyDetailViewElements(); + + Notice.updateDataAboutProcess(newNotice.noticeInstrumentType, newNotice.noticeManagerEmail); + + Notice.verifySuccessMessageUpdateNoticeData(); + + Notice.verifyUpdatedDataAboutProcess(newNotice.noticeInstrumentType, newNotice.noticeManagerEmail); + } + + uploadPaymentsReportFile() { + this.gotToNoticePage(); + + Notice.clickUploadPaymentsReportButton(); + + Notice.uploadPaymentsReport(); + } + + getInitialNoticeTotal() { + return Notice.getTotalNotices(); + } + + openIdentificationDataForm() { + Notice.openIdentificationDataForm(); + } + + validatePaymentReportUpload() { + Notice.displaySuccessMessagePaymentReportUploaded(); + } + + validateIdentificationDataFormIsVisible() { + Notice.verifyIdentificationDataFormIsVisible(); + } + + validateAllNoticesAreDisplayed(notice) { + Notice.getTotalNotices().then((totalNotices) => { + Notice.searchNoticeByNup(notice.noticeNup); + Notice.clearNoticeSearch(); + + Notice.validateAllNoticesAreDisplayed(totalNotices); + }); + } + + validateNoticeDetailsPageUrl() { + cy.url().should('match', /\/editais\/\d+\/projetos$/); + } +} + +export default new NoticeWorkflow(); diff --git a/database/seeders/CypressNoticeSeeder.php b/database/seeders/CypressNoticeSeeder.php new file mode 100644 index 00000000..5bd3dd7c --- /dev/null +++ b/database/seeders/CypressNoticeSeeder.php @@ -0,0 +1,94 @@ +where('external_id', 'cypress-notice-efomento') + ->first(); + + if ($notice) { + if ($notice->trashed()) { + $notice->restore(); + } + + $notice->update([ + 'nup' => '27001123456789012', + 'name' => 'EDITAL CYPRESS - EFOMENTO', + 'instrument_type' => 'CONVÊNIO', + 'total_notice_amount' => 13500000, + 'process_manager' => 'Cypress Notice Manager', + 'process_manager_email' => 'cypress.manager@example.com', + 'installments' => 3, + ]); + } else { + $notice = Notice::withTrashed() + ->where('nup', '27001123456789012') + ->first(); + + if ($notice) { + if ($notice->trashed()) { + $notice->restore(); + } + + $notice->update([ + 'external_id' => 'cypress-notice-efomento', + 'name' => 'EDITAL CYPRESS - EFOMENTO', + 'instrument_type' => 'CONVÊNIO', + 'total_notice_amount' => 13500000, + 'process_manager' => 'Cypress Notice Manager', + 'process_manager_email' => 'cypress.manager@example.com', + 'installments' => 3, + ]); + } else { + Notice::create([ + 'external_id' => 'cypress-notice-efomento', + 'nup' => '27001123456789012', + 'name' => 'EDITAL CYPRESS - EFOMENTO', + 'instrument_type' => 'CONVÊNIO', + 'total_notice_amount' => 13500000, + 'process_manager' => 'Cypress Notice Manager', + 'process_manager_email' => 'cypress.manager@example.com', + 'installments' => 3, + ]); + } + } + + $notice = Notice::withTrashed() + ->where('external_id', 'cypress-notice-identification-form') + ->first(); + + if ($notice) { + if ($notice->trashed()) { + $notice->restore(); + } + + $notice->update([ + 'nup' => null, + 'name' => 'EDITAL CYPRESS - PREENCHIMENTO', + 'instrument_type' => null, + 'total_notice_amount' => null, + 'process_manager' => null, + 'process_manager_email' => null, + 'installments' => null, + ]); + } else { + Notice::create([ + 'external_id' => 'cypress-notice-identification-form', + 'nup' => null, + 'name' => 'EDITAL CYPRESS - PREENCHIMENTO', + 'instrument_type' => null, + 'total_notice_amount' => null, + 'process_manager' => null, + 'process_manager_email' => null, + 'installments' => null, + ]); + } + } +} diff --git a/database/seeders/CypressProjectSeeder.php b/database/seeders/CypressProjectSeeder.php new file mode 100644 index 00000000..a5e10ee3 --- /dev/null +++ b/database/seeders/CypressProjectSeeder.php @@ -0,0 +1,394 @@ +firstOrFail(); + + $user = User::where( + 'email', + 'lara.pimentel@secult.ce.gov.br' + )->firstOrFail(); + + $agent = Agent::factory()->create(); + + $category = Category::factory()->create(); + + /* + * Project used by tests that start in the Opening phase. + */ + $openingProjectData = $projects['opening']; + + $openingAgent = Agent::factory()->create(); + + $openingProject = $this->createProject( + registrationId: $openingProjectData['registrationId'], + number: 'CYPRESS-001', + title: $openingProjectData['title'], + notice: $notice, + user: $user, + agent: $openingAgent, + category: $category, + ); + + $this->createOpening( + project: $openingProject, + user: $user, + nup: $openingProjectData['nup'], + ); + + $this->setProjectStage( + project: $openingProject, + currentStage: ProjectStageSlug::ABERTURA, + ); + + /* + * Project used by tests that start in the Legal Analysis phase. + */ + $legalAnalysisProjectData = $projects['legal_analisys']; + + $legalAnalisysAgent = Agent::factory()->create(); + + $legalAnalysisProject = $this->createProject( + registrationId: $legalAnalysisProjectData['registrationId'], + number: 'CYPRESS-002', + title: $legalAnalysisProjectData['title'], + notice: $notice, + user: $user, + agent: $legalAnalisysAgent, + category: $category, + ); + + $this->createOpening( + project: $legalAnalysisProject, + user: $user, + nup: $legalAnalysisProjectData['nup'], + ); + + $this->setProjectStage( + project: $legalAnalysisProject, + currentStage: ProjectStageSlug::ANALISE_JURIDICA, + ); + + $this->createLegalAnalysisFiles( + project: $legalAnalysisProject, + ); + + /* + * Project used by tests that start in the Formalization phase. + */ + $formalizationProjectData = $projects['formalization']; + + $formalizationAgent = Agent::factory()->create(); + + $formalizationProject = $this->createProject( + registrationId: $formalizationProjectData['registrationId'], + number: 'CYPRESS-003', + title: $formalizationProjectData['title'], + notice: $notice, + user: $user, + agent: $formalizationAgent, + category: $category, + ); + + $this->createOpening( + project: $formalizationProject, + user: $user, + nup: $formalizationProjectData['nup'], + ); + + $this->setProjectStage( + project: $formalizationProject, + currentStage: ProjectStageSlug::FORMALIZACAO, + ); + + $this->createLegalAnalysisFiles( + project: $formalizationProject, + ); + + /* + * Project used by tests that start in the Budgetary phase. + */ + $budgetaryProjectData = $projects['budgetary']; + + $budgetaryAgent = Agent::factory()->create(); + + $budgetaryProject = $this->createProject( + registrationId: $budgetaryProjectData['registrationId'], + number: 'CYPRESS-004', + title: $budgetaryProjectData['title'], + notice: $notice, + user: $user, + agent: $budgetaryAgent, + category: $category, + ); + + $this->createOpening( + project: $budgetaryProject, + user: $user, + nup: $budgetaryProjectData['nup'], + ); + + $this->setProjectStage( + project: $budgetaryProject, + currentStage: ProjectStageSlug::ORCAMENTO, + ); + + $this->createLegalAnalysisFiles( + project: $budgetaryProject, + ); + + /* + * Project used by tests that start in the Payment phase. + */ + $paymentProjectData = $projects['payment']; + + $paymentAgent = Agent::factory()->create(); + + $paymentProject = $this->createProject( + registrationId: $paymentProjectData['registrationId'], + number: 'CYPRESS-005', + title: $paymentProjectData['title'], + notice: $notice, + user: $user, + agent: $paymentAgent, + category: $category, + ); + + $this->createOpening( + project: $paymentProject, + user: $user, + nup: $paymentProjectData['nup'], + ); + + $this->createBudgetInstallment( + project: $paymentProject, + user: $user, + installment: $paymentProjectData['installment'], + ); + + $this->setProjectStage( + project: $paymentProject, + currentStage: ProjectStageSlug::PAGAMENTO, + ); + + /* + * Project used by tests that start in the Monitoring phase. + */ + $monitoringProjectData = $projects['monitoring']; + + $monitoringAgent = Agent::factory()->create(); + + $monitoringProject = $this->createProject( + registrationId: $monitoringProjectData['registrationId'], + number: 'CYPRESS-006', + title: $monitoringProjectData['title'], + notice: $notice, + user: $user, + agent: $monitoringAgent, + category: $category, + ); + + $this->createOpening( + project: $monitoringProject, + user: $user, + nup: $monitoringProjectData['nup'], + ); + + $this->setProjectStage( + project: $monitoringProject, + currentStage: ProjectStageSlug::MONITORAMENTO, + ); + } + + private function createProject( + string $registrationId, + string $number, + string $title, + Notice $notice, + User $user, + Agent $agent, + Category $category, + ): Project { + return Project::updateOrCreate( + [ + 'registration_id' => $registrationId, + ], + [ + 'number' => $number, + 'category_id' => $category->id, + 'agent_id' => $agent->id, + 'notice_id' => $notice->id, + 'current_installment_cycle' => 1, + 'created_by' => $user->id, + 'title_project' => $title, + ] + ); + } + + private function createOpening( + Project $project, + User $user, + string $nup + ): void { + Opening::updateOrCreate( + [ + 'project_id' => $project->id, + ], + [ + 'opening_nup' => $nup, + 'opening_date' => now(), + 'user_id' => $user->id, + 'created_by' => $user->id, + 'status' => OpeningStatus::EM_ANDAMENTO, + 'is_draft' => false, + ] + ); + } + + private function setProjectStage( + Project $project, + ProjectStageSlug $currentStage + ): void { + $stages = [ + ProjectStageSlug::ABERTURA->value => 1, + ProjectStageSlug::ANALISE_JURIDICA->value => 2, + ProjectStageSlug::FORMALIZACAO->value => 3, + ProjectStageSlug::ORCAMENTO->value => 4, + ProjectStageSlug::PAGAMENTO->value => 5, + ProjectStageSlug::MONITORAMENTO->value => 6, + ProjectStageSlug::PRESTACAO_DE_CONTAS->value => 7, + ]; + + $currentOrder = $stages[$currentStage->value]; + + foreach ($stages as $slug => $order) { + if ($order < $currentOrder) { + $status = ProjectStageStatus::APROVADO; + } elseif ($order === $currentOrder) { + $status = ProjectStageStatus::EM_ANDAMENTO; + } else { + $status = ProjectStageStatus::PENDENTE; + } + + ProjectStage::updateOrCreate( + [ + 'project_id' => $project->id, + 'slug' => $slug, + ], + [ + 'order' => $order, + 'status' => $status, + 'started_at' => $order <= $currentOrder + ? now() + : null, + 'concluded_at' => $order < $currentOrder + ? now() + : null, + ] + ); + } + } + + private function createLegalAnalysisFiles( + Project $project + ): void { + $files = [ + [ + 'external_id' => 'CYPRESS-LEGAL-FILE-001', + 'name' => 'Documento Cypress 001.pdf', + 'title' => 'Documento Cypress 001', + ], + [ + 'external_id' => 'CYPRESS-LEGAL-FILE-002', + 'name' => 'Documento Cypress 002.pdf', + 'title' => 'Documento Cypress 002', + ], + [ + 'external_id' => 'CYPRESS-LEGAL-FILE-003', + 'name' => 'Documento Cypress 003.pdf', + 'title' => 'Documento Cypress 003', + ], + ]; + + foreach ($files as $file) { + File::updateOrCreate( + [ + 'object_type' => 'project', + 'object_id' => $project->id, + 'source' => 'cypress', + 'external_id' => $file['external_id'], + ], + [ + 'mime_type' => 'application/pdf', + 'name' => $file['name'], + 'grp' => 'cypress', + 'title' => $file['title'], + 'description' => 'Documento utilizado nos testes automatizados do Cypress.', + 'path' => null, + 'private' => true, + ] + ); + } + } + + private function createBudgetInstallment( + Project $project, + User $user, + array $installment, + ): void { + $budget = Budget::updateOrCreate( + [ + 'project_id' => $project->id, + ], + [ + 'created_by' => $user->id, + 'processing_date_for_codip' => null, + 'processing_date_for_coafi' => null, + ] + ); + + $budget->installments()->updateOrCreate( + [ + 'installment_number' => $project->current_installment_cycle, + ], + [ + 'notice_installment_number' => $installment['number'], + 'amount' => $installment['amount'], + 'request_date' => now(), + 'created_by' => $user->id, + + 'committed_amount' => null, + 'settlement_amount' => null, + 'payment_order_number' => null, + 'payment_amount' => null, + 'payment_date' => null, + ] + ); + } +} diff --git a/database/seeders/CypressRoleSeeder.php b/database/seeders/CypressRoleSeeder.php new file mode 100644 index 00000000..a18331c2 --- /dev/null +++ b/database/seeders/CypressRoleSeeder.php @@ -0,0 +1,27 @@ + Role::FOMENTATION->value, + 'glaucivane.portela@secult.ce.gov.br' => Role::LEGAL_ANALYSIS->value, + 'jferreira@secult.ce.gov.br' => Role::BUDGETARY->value, + 'claudia.moreira@secult.ce.gov.br' => Role::FINANCIAL->value, + 'cicero.gondim@secult.ce.gov.br' => Role::COORD_MONITORING->value, + ]; + + foreach ($users as $email => $role) { + $user = User::where('email', $email)->firstOrFail(); + + $user->syncRoles([$role]); + } + } +} diff --git a/database/seeders/CypressSeeder.php b/database/seeders/CypressSeeder.php new file mode 100644 index 00000000..5e47aeb4 --- /dev/null +++ b/database/seeders/CypressSeeder.php @@ -0,0 +1,18 @@ +call([ + CypressUserSeeder::class, + CypressRoleSeeder::class, + CypressNoticeSeeder::class, + CypressProjectSeeder::class, + ]); + } +} diff --git a/database/seeders/CypressUserSeeder.php b/database/seeders/CypressUserSeeder.php new file mode 100644 index 00000000..f8bf8330 --- /dev/null +++ b/database/seeders/CypressUserSeeder.php @@ -0,0 +1,48 @@ + 'Lara Pimentel', + 'email' => 'lara.pimentel@secult.ce.gov.br', + ], + [ + 'name' => 'Glaucivane Portela', + 'email' => 'glaucivane.portela@secult.ce.gov.br', + ], + [ + 'name' => 'J Ferreira', + 'email' => 'jferreira@secult.ce.gov.br', + ], + [ + 'name' => 'Claudia Moreira', + 'email' => 'claudia.moreira@secult.ce.gov.br', + ], + [ + 'name' => 'Cicero Gondim', + 'email' => 'cicero.gondim@secult.ce.gov.br', + ], + ]; + + foreach ($users as $userData) { + User::updateOrCreate( + [ + 'email' => $userData['email'], + ], + [ + 'name' => $userData['name'], + 'password' => Hash::make('password'), + ] + ); + } + } +} diff --git a/reset-fomento.sh b/reset-fomento.sh index ba639028..b50df088 100755 --- a/reset-fomento.sh +++ b/reset-fomento.sh @@ -8,3 +8,9 @@ docker compose up -d ## Rodar migrations e seeders docker compose exec app php artisan migrate:fresh --seed + +## Rodar migrations do Cypress +docker compose exec app php artisan db:seed --class="Database\Seeders\CypressSeeder" + +## Rodar sincronismo do Edital do Mapa Cultural +docker compose exec app php artisan tinker --execute="SyncNoticesJob::dispatch()" diff --git a/resources/js/Pages/Notices/NoticesListPage.vue b/resources/js/Pages/Notices/NoticesListPage.vue index 51bed823..d7f3078d 100644 --- a/resources/js/Pages/Notices/NoticesListPage.vue +++ b/resources/js/Pages/Notices/NoticesListPage.vue @@ -246,7 +246,7 @@ async function handleFileUpload(event) {

Total de editais encontrados: - {{ total }} + {{ total }}

@@ -259,6 +259,7 @@ async function handleFileUpload(event) { type="file" accept=".xlsx,.xls,.csv" class="hidden" + data-cy="payments-report-file-input" @change="handleFileUpload" /> {