From 8f0a4da245a4db78dba939ee19d40cda91898d38 Mon Sep 17 00:00:00 2001 From: jtubau Date: Tue, 11 Feb 2025 13:58:14 +0100 Subject: [PATCH 01/27] feat: refs #8422 add Vehicle DMS import functionality and routing --- .../Vehicle/Card/VehicleDmsImportForm.vue | 76 +++++++++++++++++++ src/pages/Route/Vehicle/VehicleDms.vue | 46 +++++++++++ src/router/modules/route.js | 14 +++- 3 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue create mode 100644 src/pages/Route/Vehicle/VehicleDms.vue diff --git a/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue b/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue new file mode 100644 index 0000000000..1d17a38dc0 --- /dev/null +++ b/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue @@ -0,0 +1,76 @@ + + + + + +es: + Select document id: Introduzca id de gestion documental + Document: Documento + The document indentifier can't be empty: El número de documento no puede estar vacío + diff --git a/src/pages/Route/Vehicle/VehicleDms.vue b/src/pages/Route/Vehicle/VehicleDms.vue new file mode 100644 index 0000000000..f105752472 --- /dev/null +++ b/src/pages/Route/Vehicle/VehicleDms.vue @@ -0,0 +1,46 @@ + + + + +es: + Import from existing: Importar desde existente + diff --git a/src/router/modules/route.js b/src/router/modules/route.js index 835324d20b..e8e6c1f315 100644 --- a/src/router/modules/route.js +++ b/src/router/modules/route.js @@ -166,7 +166,10 @@ const vehicleCard = { component: () => import('src/pages/Route/Vehicle/Card/VehicleCard.vue'), redirect: { name: 'VehicleSummary' }, meta: { - menu: ['VehicleBasicData'], + menu: [ + 'VehicleBasicData', + 'VehicleDms', + ], }, children: [ { @@ -187,6 +190,15 @@ const vehicleCard = { }, component: () => import('src/pages/Route/Vehicle/Card/VehicleBasicData.vue'), }, + { + name: 'VehicleDms', + path: 'dms', + meta: { + title: 'dms', + icon: 'cloud_upload', + }, + component: () => import('src/pages/Route/Vehicle/VehicleDms.vue'), + }, ], }; From c5284e54c78bebd06f87544c640bce76b0f8de0f Mon Sep 17 00:00:00 2001 From: jtubau Date: Wed, 5 Mar 2025 11:13:45 +0100 Subject: [PATCH 02/27] refactor: refs #8422 enhance DMS import functionality and improve localization --- src/components/common/VnDmsList.vue | 6 ++---- .../Route/Vehicle/Card/VehicleDmsImportForm.vue | 13 +++---------- src/pages/Route/Vehicle/VehicleDms.vue | 10 +++------- src/pages/Route/Vehicle/locale/en.yml | 6 ++++++ src/pages/Route/Vehicle/locale/es.yml | 6 ++++++ 5 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/components/common/VnDmsList.vue b/src/components/common/VnDmsList.vue index 424781a269..facb667ba4 100644 --- a/src/components/common/VnDmsList.vue +++ b/src/components/common/VnDmsList.vue @@ -389,10 +389,7 @@ defineExpose({ -
+
{{ t('No data to display') }}
@@ -416,6 +413,7 @@ defineExpose({ v-shortcut @click="showFormDialog()" class="fill-icon" + data-cy="addDmsBtn" > {{ t('Upload file') }} diff --git a/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue b/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue index 1d17a38dc0..5b27977403 100644 --- a/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue +++ b/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue @@ -22,7 +22,7 @@ const dmsId = ref(null); const importDms = async () => { try { - if (!dmsId.value) throw new Error(t(`The document identifier can't be empty`)); + if (!dmsId.value) throw new Error(t(`vehicle.error.documentIdEmpty`)); const data = { vehicleFk: route.params.id, @@ -49,14 +49,14 @@ const importDms = async () => { - - -es: - Select document id: Introduzca id de gestion documental - Document: Documento - The document indentifier can't be empty: El número de documento no puede estar vacío - diff --git a/src/pages/Route/Vehicle/VehicleDms.vue b/src/pages/Route/Vehicle/VehicleDms.vue index f105752472..c871877c27 100644 --- a/src/pages/Route/Vehicle/VehicleDms.vue +++ b/src/pages/Route/Vehicle/VehicleDms.vue @@ -20,7 +20,7 @@ const onDataSaved = () => dmsListRef.value.dmsRef.fetch(); delete-model="VehicleDms" download-model="dms" default-dms-code="vehicles" - filter="vehicleFk" + filter="vehicleFk" /> @@ -32,15 +32,11 @@ const onDataSaved = () => dmsListRef.value.dmsRef.fetch(); icon="file_copy" @click="showImportDialog = true" class="fill-icon" + data-cy="importBtn" > - {{ t('Import from existing') }} + {{ t('vehicle.dms.import') }} - - -es: - Import from existing: Importar desde existente - diff --git a/src/pages/Route/Vehicle/locale/en.yml b/src/pages/Route/Vehicle/locale/en.yml index c92022f9d2..00ef5eae96 100644 --- a/src/pages/Route/Vehicle/locale/en.yml +++ b/src/pages/Route/Vehicle/locale/en.yml @@ -18,3 +18,9 @@ vehicle: params: vehicleTypeFk: Type vehicleStateFk: State + dms: + import: Import from existing + selectDocId: Select document id + document: Document + error: + documentIdEmpty: The document identifier can't be empty diff --git a/src/pages/Route/Vehicle/locale/es.yml b/src/pages/Route/Vehicle/locale/es.yml index c878f97ac5..ea7ff47184 100644 --- a/src/pages/Route/Vehicle/locale/es.yml +++ b/src/pages/Route/Vehicle/locale/es.yml @@ -18,3 +18,9 @@ vehicle: params: vehicleTypeFk: Tipo vehicleStateFk: Estado + dms: + import: Importar desde existente + selectDocId: Introduzca id de gestion documental + document: Documento + error: + documentIdEmpty: El número de documento no puede estar vacío From b259988f907939b1025fae349fc106769c3a5045 Mon Sep 17 00:00:00 2001 From: jtubau Date: Wed, 5 Mar 2025 11:14:20 +0100 Subject: [PATCH 03/27] test: refs #8422 add test for vehicleDms --- .../route/vehicle/vehicleDms.spec.js | 103 ++++++++++++++++++ test/cypress/support/commands.js | 2 +- 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 test/cypress/integration/route/vehicle/vehicleDms.spec.js diff --git a/test/cypress/integration/route/vehicle/vehicleDms.spec.js b/test/cypress/integration/route/vehicle/vehicleDms.spec.js new file mode 100644 index 0000000000..2362dd28fe --- /dev/null +++ b/test/cypress/integration/route/vehicle/vehicleDms.spec.js @@ -0,0 +1,103 @@ +describe('Vehicle DMS', () => { + const getSelector = (btnPosition) => + `tr:last-child > .text-right > .no-wrap > :nth-child(${btnPosition}) > .q-btn > .q-btn__content > .q-icon`; + + const selectors = { + lastRowDownloadBtn: getSelector(1), + lastRowEditBtn: getSelector(2), + lastRowDeleteBtn: getSelector(3), + lastRowReference: 'tr:last-child > :nth-child(5) > .q-tr > :nth-child(1) > span', + firstRowReference: + 'tr:first-child > :nth-child(5) > .q-tr > :nth-child(1) > span', + referenceInput: 'Reference_input', + companySelect: 'Company_select', + warehouseSelect: 'Warehouse_select', + typeSelect: 'Type_select', + fileInput: 'VnDms_inputFile', + importBtn: 'importBtn', + addBtn: 'addDmsBtn', + saveFormBtn: 'FormModelPopup_save', + }; + + const data = { + Reference: { val: 'Vehicle:1234-ABC' }, + Company: { val: 'VNL', type: 'select' }, + Warehouse: { val: 'Warehouse One', type: 'select' }, + Type: { val: 'Vehiculos', type: 'select' }, + }; + + const updateData = { + Reference: { val: 'Vehicle:5678-DEF' }, + Company: { val: 'CCs', type: 'select' }, + Warehouse: { val: 'Warehouse Two', type: 'select' }, + Type: { val: 'Facturas Recibidas', type: 'select' }, + }; + + beforeEach(() => { + cy.viewport(1920, 1080); + cy.login('developer'); + cy.visit(`/#/route/vehicle/1/dms`); + }); + + it('should display vehicle DMS', () => { + cy.get('.q-table') + .children() + .should('be.visible') + .should('have.length.greaterThan', 0); + }); + + xit('Should create new DMS', () => { + const filePath = '11.jpg'; + + cy.dataCy(selectors.addBtn).click(); + cy.dataCy(selectors.referenceInput).type(data.Reference.val); + cy.dataCy(selectors.fileInput).type(filePath); + cy.dataCy(selectors.saveFormBtn).click(); + }); + + it('Should import DMS', () => { + const data = { + Document: { val: '1', type: 'select' }, + }; + cy.dataCy(selectors.importBtn).click(); + cy.fillInForm(data); + cy.dataCy(selectors.saveFormBtn).click(); + cy.validateContent(selectors.lastRowReference, 'Ticket:11'); + }); + + it('Should edit DMS', () => { + cy.get(selectors.lastRowEditBtn).click(); + cy.fillInForm(updateData); + cy.dataCy(selectors.saveFormBtn).click(); + cy.validateContent(selectors.lastRowReference, updateData.Reference.val); + }); + + it('Should download DMS', () => { + const downloadsFolder = Cypress.config('downloadsFolder'); + cy.get(selectors.lastRowDownloadBtn).click(); + cy.wait(3000); + + const fileName = '1.txt'; + cy.readFile(`${downloadsFolder}/${fileName}`).should('exist'); + }); + + it('Should delete DMS', () => { + cy.get(selectors.lastRowDeleteBtn).click(); + cy.clickConfirm(); + cy.validateContent(selectors.firstRowReference, 'Vehicle:3333-BAT'); + }); + + it('Should redirect to worker summary from worker descriptor pop-up', () => { + cy.get(':nth-child(1) > :nth-child(8) > .q-tr > .link').click(); + cy.get( + '.q-menu > .descriptor > .body > .q-list > .q-item__label--header > .title > span', + ).should('have.text', 'administrativeNick'); + cy.get( + '[href="#/worker/5/summary"] > .q-btn > .q-btn__content > .q-icon', + ).click(); + cy.get('.summaryHeader > div').should( + 'have.text', + '5 - administrative administrative', + ); + }); +}); diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index dfec341cd2..f72a3c6705 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -172,7 +172,7 @@ Cypress.Commands.add('fillInForm', (obj, form = '.q-form > .q-card') => { cy.get('.q-time .q-time__link').contains(val.x).click(); break; default: - cy.wrap(el).type(val); + cy.wrap(el).clear().type(val); break; } }); From f4b72c5d75c9fba98ab3ee512af532946d7dc6be Mon Sep 17 00:00:00 2001 From: jtubau Date: Tue, 11 Mar 2025 13:02:20 +0100 Subject: [PATCH 04/27] refactor: refs #8422 add notifications for data save and delete actions --- src/components/common/VnDms.vue | 3 +++ src/components/common/VnDmsList.vue | 3 +++ .../Vehicle/Card/VehicleDmsImportForm.vue | 22 +++++++------------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/components/common/VnDms.vue b/src/components/common/VnDms.vue index 35308c2c43..f66be963d8 100644 --- a/src/components/common/VnDms.vue +++ b/src/components/common/VnDms.vue @@ -4,6 +4,7 @@ import { useRoute } from 'vue-router'; import { useI18n } from 'vue-i18n'; import axios from 'axios'; +import useNotify from 'src/composables/useNotify.js'; import FetchData from 'components/FetchData.vue'; import VnRow from 'components/ui/VnRow.vue'; import VnSelect from 'src/components/common/VnSelect.vue'; @@ -12,6 +13,7 @@ import FormModelPopup from 'components/FormModelPopup.vue'; const route = useRoute(); const { t } = useI18n(); +const { notify } = useNotify(); const emit = defineEmits(['onDataSaved']); const $props = defineProps({ @@ -82,6 +84,7 @@ async function save() { const body = mapperDms(dms.value); const response = await axios.post(getUrl(), body[0], body[1]); emit('onDataSaved', body[1].params, response); + notify(t('globals.dataSaved'), 'positive'); delete dms.value.files; return response; } diff --git a/src/components/common/VnDmsList.vue b/src/components/common/VnDmsList.vue index facb667ba4..eec60d8a63 100644 --- a/src/components/common/VnDmsList.vue +++ b/src/components/common/VnDmsList.vue @@ -13,10 +13,12 @@ import VnDms from 'src/components/common/VnDms.vue'; import VnConfirm from 'components/ui/VnConfirm.vue'; import VnInputDate from 'components/common/VnInputDate.vue'; import { useSession } from 'src/composables/useSession'; +import useNotify from 'src/composables/useNotify.js'; const route = useRoute(); const quasar = useQuasar(); const { t } = useI18n(); +const { notify } = useNotify(); const rows = ref([]); const dmsRef = ref(); const formDialog = ref({}); @@ -261,6 +263,7 @@ function deleteDms(dmsFk) { await axios.post(`${$props.deleteModel ?? $props.model}/${dmsFk}/removeFile`); const index = rows.value.findIndex((row) => row.id == dmsFk); rows.value.splice(index, 1); + notify(t('globals.dataDeleted'), 'positive'); }); } diff --git a/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue b/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue index 5b27977403..b700fff06c 100644 --- a/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue +++ b/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue @@ -4,17 +4,14 @@ import { useI18n } from 'vue-i18n'; import { useRoute } from 'vue-router'; import VnSelect from 'src/components/common/VnSelect.vue'; -import VnRow from 'components/ui/VnRow.vue'; import FormModelPopup from 'components/FormModelPopup.vue'; import FetchData from 'components/FetchData.vue'; -import useNotify from 'src/composables/useNotify.js'; import axios from 'axios'; const emit = defineEmits(['onDataSaved']); const { t } = useI18n(); -const { notify } = useNotify(); const route = useRoute(); const dmsOptions = ref([]); @@ -30,7 +27,6 @@ const importDms = async () => { }; await axios.post('vehicleDms', data); - notify(t('globals.dataSaved'), 'positive'); dmsId.value = null; emit('onDataSaved'); } catch (e) { @@ -54,16 +50,14 @@ const importDms = async () => { :save-fn="importDms" > From 21196fcc3b2140d8b134994541aa6293d6c71d90 Mon Sep 17 00:00:00 2001 From: jtubau Date: Wed, 12 Mar 2025 08:30:02 +0100 Subject: [PATCH 05/27] test: refs #8422 add temporary upload folder configuration --- cypress.config.js | 1 + .../route/vehicle/vehicleDms.spec.js | 45 +++++++++++-------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/cypress.config.js b/cypress.config.js index d9cdbe7284..cf9289fdc1 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -44,6 +44,7 @@ export default defineConfig({ supportFile: 'test/cypress/support/index.js', videosFolder: 'test/cypress/videos', downloadsFolder: 'test/cypress/downloads', + tmpUploadFolder: '../salix/storage/tmp/dms', video: false, specPattern: 'test/cypress/integration/**/*.spec.js', experimentalRunAllSpecs: true, diff --git a/test/cypress/integration/route/vehicle/vehicleDms.spec.js b/test/cypress/integration/route/vehicle/vehicleDms.spec.js index 2362dd28fe..1a567efbdc 100644 --- a/test/cypress/integration/route/vehicle/vehicleDms.spec.js +++ b/test/cypress/integration/route/vehicle/vehicleDms.spec.js @@ -9,6 +9,13 @@ describe('Vehicle DMS', () => { lastRowReference: 'tr:last-child > :nth-child(5) > .q-tr > :nth-child(1) > span', firstRowReference: 'tr:first-child > :nth-child(5) > .q-tr > :nth-child(1) > span', + firstRowId: 'tr:first-child > :nth-child(2) > .q-tr > :nth-child(1) > span', + lastRowWorkerLink: 'tr:last-child > :nth-child(8) > .q-tr > .link', + workerDescriptorPopupTitle: + '.q-menu > .descriptor > .body > .q-list > .q-item__label--header > .title > span', + workerDescriptorGoToSummary: + '[href="#/worker/5/summary"] > .q-btn > .q-btn__content > .q-icon', + summaryTitle: '.summaryHeader > div', referenceInput: 'Reference_input', companySelect: 'Company_select', warehouseSelect: 'Warehouse_select', @@ -46,29 +53,35 @@ describe('Vehicle DMS', () => { .should('have.length.greaterThan', 0); }); - xit('Should create new DMS', () => { - const filePath = '11.jpg'; - + it('Should create new DMS', () => { + const uploadFolder = Cypress.config('tmpUploadFolder'); cy.dataCy(selectors.addBtn).click(); - cy.dataCy(selectors.referenceInput).type(data.Reference.val); - cy.dataCy(selectors.fileInput).type(filePath); + cy.dataCy(selectors.referenceInput).type(`{selectall}${data.Reference.val}`); + cy.dataCy(selectors.fileInput).selectFile('test/cypress/fixtures/image.jpg', { + force: true, + }); cy.dataCy(selectors.saveFormBtn).click(); + const fileName = 'image.jpg'; + cy.readFile(`${uploadFolder}/${fileName}`).should('exist'); + cy.checkNotification('Data saved'); }); it('Should import DMS', () => { const data = { - Document: { val: '1', type: 'select' }, + Document: { val: '10', type: 'select' }, }; cy.dataCy(selectors.importBtn).click(); cy.fillInForm(data); cy.dataCy(selectors.saveFormBtn).click(); - cy.validateContent(selectors.lastRowReference, 'Ticket:11'); + cy.checkNotification('Data created'); + cy.validateContent(selectors.lastRowReference, 'Vehicle:5678-DEF'); }); it('Should edit DMS', () => { cy.get(selectors.lastRowEditBtn).click(); cy.fillInForm(updateData); cy.dataCy(selectors.saveFormBtn).click(); + cy.checkNotification('Data saved'); cy.validateContent(selectors.lastRowReference, updateData.Reference.val); }); @@ -84,20 +97,14 @@ describe('Vehicle DMS', () => { it('Should delete DMS', () => { cy.get(selectors.lastRowDeleteBtn).click(); cy.clickConfirm(); - cy.validateContent(selectors.firstRowReference, 'Vehicle:3333-BAT'); + cy.checkNotification('Data deleted'); + cy.validateContent(selectors.lastRowReference, 'Vehicle:3333-BAT'); }); it('Should redirect to worker summary from worker descriptor pop-up', () => { - cy.get(':nth-child(1) > :nth-child(8) > .q-tr > .link').click(); - cy.get( - '.q-menu > .descriptor > .body > .q-list > .q-item__label--header > .title > span', - ).should('have.text', 'administrativeNick'); - cy.get( - '[href="#/worker/5/summary"] > .q-btn > .q-btn__content > .q-icon', - ).click(); - cy.get('.summaryHeader > div').should( - 'have.text', - '5 - administrative administrative', - ); + cy.get(selectors.lastRowWorkerLink).click(); + cy.get(selectors.workerDescriptorPopupTitle).should('contain', 'administrative'); + cy.get(selectors.workerDescriptorGoToSummary).click(); + cy.get(selectors.summaryTitle).should('contain', 'administrative'); }); }); From 7ab2e28dc71367cd3a9c4dddfaff51c2c41131cc Mon Sep 17 00:00:00 2001 From: jtubau Date: Wed, 12 Mar 2025 08:30:14 +0100 Subject: [PATCH 06/27] fix: refs #8422 update filter structure in VnDmsList component --- src/components/common/VnDmsList.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/common/VnDmsList.vue b/src/components/common/VnDmsList.vue index eec60d8a63..56cfdea824 100644 --- a/src/components/common/VnDmsList.vue +++ b/src/components/common/VnDmsList.vue @@ -90,7 +90,6 @@ const dmsFilter = { ], }, }, - where: { [$props.filter]: route.params.id }, }; const columns = computed(() => [ @@ -302,6 +301,7 @@ defineExpose({ :url="$props.model" :user-filter="dmsFilter" :order="['dmsFk DESC']" + :filter="{ where: { [$props.filter]: route.params.id } }" auto-load @on-fetch="setData" > From ca6c0cff29bee8f8cb1b80cc75df7a9ff958d28e Mon Sep 17 00:00:00 2001 From: jtubau Date: Wed, 12 Mar 2025 08:32:45 +0100 Subject: [PATCH 07/27] refactor: refs #8422 update form input handling to select all text before typing --- test/cypress/support/commands.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index 4c28aa1cae..a3ac82739a 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -179,7 +179,7 @@ Cypress.Commands.add('fillInForm', (obj, form = '.q-form > .q-card') => { cy.get('.q-time .q-time__link').contains(val.x).click(); break; default: - cy.wrap(el).clear().type(val); + cy.wrap(el).type(`{selectall}${val}`); break; } }); From 5d356428d3bfdfd03d4c5ddaf0f98d5fdbf19a7d Mon Sep 17 00:00:00 2001 From: jtubau Date: Tue, 18 Mar 2025 15:54:47 +0100 Subject: [PATCH 08/27] refactor: refs #8422 enhance error handling in save function and update selectors in tests --- src/components/common/VnDms.vue | 16 ++++++++++------ .../Route/Vehicle/Card/VehicleDmsImportForm.vue | 1 - .../integration/route/vehicle/vehicleDms.spec.js | 16 +++++++--------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/components/common/VnDms.vue b/src/components/common/VnDms.vue index c844b63d0f..8553a92b6b 100644 --- a/src/components/common/VnDms.vue +++ b/src/components/common/VnDms.vue @@ -81,12 +81,16 @@ function getUrl() { } async function save() { - const body = mapperDms(dms.value); - const response = await axios.post(getUrl(), body[0], body[1]); - emit('onDataSaved', body[1].params, response); - notify(t('globals.dataSaved'), 'positive'); - delete dms.value.files; - return response; + try { + const body = mapperDms(dms.value); + const response = await axios.post(getUrl(), body[0], body[1]); + emit('onDataSaved', body[1].params, response); + notify(t('globals.dataSaved'), 'positive'); + delete dms.value.files; + return response; + } catch (e) { + throw new Error(e.message); + } } function defaultData() { diff --git a/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue b/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue index b700fff06c..2708cd07be 100644 --- a/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue +++ b/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue @@ -43,7 +43,6 @@ const importDms = async () => { @on-fetch="(data) => (dmsOptions = data)" /> { 'tr:first-child > :nth-child(5) > .q-tr > :nth-child(1) > span', firstRowId: 'tr:first-child > :nth-child(2) > .q-tr > :nth-child(1) > span', lastRowWorkerLink: 'tr:last-child > :nth-child(8) > .q-tr > .link', - workerDescriptorPopupTitle: - '.q-menu > .descriptor > .body > .q-list > .q-item__label--header > .title > span', - workerDescriptorGoToSummary: - '[href="#/worker/5/summary"] > .q-btn > .q-btn__content > .q-icon', - summaryTitle: '.summaryHeader > div', + descriptorTitle: '.descriptor .title', + descriptorGoToSummaryBtn: '.descriptor [data-cy="goToSummaryBtn"]', + summaryTitle: '.summaryHeader', referenceInput: 'Reference_input', companySelect: 'Company_select', warehouseSelect: 'Warehouse_select', typeSelect: 'Type_select', fileInput: 'VnDms_inputFile', importBtn: 'importBtn', - addBtn: 'addDmsBtn', + addBtn: 'addButton', saveFormBtn: 'FormModelPopup_save', }; @@ -103,8 +101,8 @@ describe('Vehicle DMS', () => { it('Should redirect to worker summary from worker descriptor pop-up', () => { cy.get(selectors.lastRowWorkerLink).click(); - cy.get(selectors.workerDescriptorPopupTitle).should('contain', 'administrative'); - cy.get(selectors.workerDescriptorGoToSummary).click(); - cy.get(selectors.summaryTitle).should('contain', 'administrative'); + cy.get(selectors.descriptorTitle).should('contain', 'administrative'); + cy.get(selectors.descriptorGoToSummaryBtn).click(); + cy.containContent(selectors.summaryTitle, 'administrative'); }); }); From cb99c50f3339c21ef5f6655f58fee8d17f6e9c59 Mon Sep 17 00:00:00 2001 From: jtubau Date: Thu, 20 Mar 2025 13:34:14 +0100 Subject: [PATCH 09/27] fix: refs #8422 vehicleDms tests --- .../route/vehicle/vehicleDms.spec.js | 19 +++++++++---------- test/cypress/support/commands.js | 9 +++++++++ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/test/cypress/integration/route/vehicle/vehicleDms.spec.js b/test/cypress/integration/route/vehicle/vehicleDms.spec.js index 5e22e3507a..92c1ddd186 100644 --- a/test/cypress/integration/route/vehicle/vehicleDms.spec.js +++ b/test/cypress/integration/route/vehicle/vehicleDms.spec.js @@ -12,7 +12,7 @@ describe('Vehicle DMS', () => { firstRowId: 'tr:first-child > :nth-child(2) > .q-tr > :nth-child(1) > span', lastRowWorkerLink: 'tr:last-child > :nth-child(8) > .q-tr > .link', descriptorTitle: '.descriptor .title', - descriptorGoToSummaryBtn: '.descriptor [data-cy="goToSummaryBtn"]', + descriptorGoToSummaryBtn: '.q-menu .descriptor [data-cy="goToSummaryBtn"]', summaryTitle: '.summaryHeader', referenceInput: 'Reference_input', companySelect: 'Company_select', @@ -71,8 +71,7 @@ describe('Vehicle DMS', () => { cy.dataCy(selectors.importBtn).click(); cy.fillInForm(data); cy.dataCy(selectors.saveFormBtn).click(); - cy.checkNotification('Data created'); - cy.validateContent(selectors.lastRowReference, 'Vehicle:5678-DEF'); + cy.validateContent(selectors.lastRowReference, '1'); }); it('Should edit DMS', () => { @@ -83,6 +82,13 @@ describe('Vehicle DMS', () => { cy.validateContent(selectors.lastRowReference, updateData.Reference.val); }); + it('Should delete DMS', () => { + cy.get(selectors.lastRowDeleteBtn).click(); + cy.clickConfirm(); + cy.checkNotification('Data deleted'); + cy.validateContent(selectors.lastRowReference, 'Vehicle:3333-BAT'); + }); + it('Should download DMS', () => { const downloadsFolder = Cypress.config('downloadsFolder'); cy.get(selectors.lastRowDownloadBtn).click(); @@ -92,13 +98,6 @@ describe('Vehicle DMS', () => { cy.readFile(`${downloadsFolder}/${fileName}`).should('exist'); }); - it('Should delete DMS', () => { - cy.get(selectors.lastRowDeleteBtn).click(); - cy.clickConfirm(); - cy.checkNotification('Data deleted'); - cy.validateContent(selectors.lastRowReference, 'Vehicle:3333-BAT'); - }); - it('Should redirect to worker summary from worker descriptor pop-up', () => { cy.get(selectors.lastRowWorkerLink).click(); cy.get(selectors.descriptorTitle).should('contain', 'administrative'); diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index 45e17654e0..2fadaece9f 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -322,6 +322,15 @@ Cypress.Commands.add('validateContent', (selector, expectedValue) => { cy.get(selector).should('have.text', expectedValue); }); +Cypress.Commands.add('containContent', (selector, expectedValue) => { + cy.get(selector) + .should('be.visible') + .invoke('text') + .then((text) => { + expect(text).to.include(expectedValue); + }); +}); + Cypress.Commands.add('openActionDescriptor', (opt) => { cy.openActionsDescriptor(); const listItem = '[role="menu"] .q-list .q-item'; From f07ce9a0a1e8226b1aa821c33001f0b414c3dc6a Mon Sep 17 00:00:00 2001 From: jtubau Date: Thu, 27 Mar 2025 15:10:16 +0100 Subject: [PATCH 10/27] chore: refs #8422 update localizations --- src/i18n/locale/en.yml | 1 + src/i18n/locale/es.yml | 1 + src/pages/Route/Vehicle/locale/en.yml | 3 ++- src/pages/Route/Vehicle/locale/es.yml | 5 +++-- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index 7374cda68d..1a8419ce22 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -160,6 +160,7 @@ globals: department: Department noData: No data available vehicle: Vehicle + selectDocumentId: Select document id pageTitles: logIn: Login addressEdit: Update address diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index f0ce53e37b..5a99ece91b 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -164,6 +164,7 @@ globals: noData: Datos no disponibles department: Departamento vehicle: Vehículo + selectDocumentId: Introduzca id de gestión documental pageTitles: logIn: Inicio de sesión addressEdit: Modificar consignatario diff --git a/src/pages/Route/Vehicle/locale/en.yml b/src/pages/Route/Vehicle/locale/en.yml index 00ef5eae96..884066b6ba 100644 --- a/src/pages/Route/Vehicle/locale/en.yml +++ b/src/pages/Route/Vehicle/locale/en.yml @@ -22,5 +22,6 @@ vehicle: import: Import from existing selectDocId: Select document id document: Document - error: + errors: documentIdEmpty: The document identifier can't be empty + dmsImported: Error occurred while importing the document diff --git a/src/pages/Route/Vehicle/locale/es.yml b/src/pages/Route/Vehicle/locale/es.yml index ea7ff47184..5df286b950 100644 --- a/src/pages/Route/Vehicle/locale/es.yml +++ b/src/pages/Route/Vehicle/locale/es.yml @@ -20,7 +20,8 @@ vehicle: vehicleStateFk: Estado dms: import: Importar desde existente - selectDocId: Introduzca id de gestion documental + selectDocId: Introduzca id de gestión documental document: Documento - error: + errors: documentIdEmpty: El número de documento no puede estar vacío + dmsImported: Se ha producido un error al importar el documento From 96ed69acd2724ab02987f691a2ef8f0aae68f2f9 Mon Sep 17 00:00:00 2001 From: jtubau Date: Thu, 27 Mar 2025 15:10:31 +0100 Subject: [PATCH 11/27] refactor: refs #8422 update document ID error messages and improve notifications in DMS forms --- src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue | 9 ++++++--- src/pages/Ticket/Card/TicketDmsImportForm.vue | 3 +-- .../cypress/integration/route/vehicle/vehicleDms.spec.js | 1 + 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue b/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue index 2708cd07be..dd716bd974 100644 --- a/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue +++ b/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue @@ -6,12 +6,14 @@ import { useRoute } from 'vue-router'; import VnSelect from 'src/components/common/VnSelect.vue'; import FormModelPopup from 'components/FormModelPopup.vue'; import FetchData from 'components/FetchData.vue'; +import useNotify from 'src/composables/useNotify.js'; import axios from 'axios'; const emit = defineEmits(['onDataSaved']); const { t } = useI18n(); +const { notify } = useNotify(); const route = useRoute(); const dmsOptions = ref([]); @@ -19,7 +21,7 @@ const dmsId = ref(null); const importDms = async () => { try { - if (!dmsId.value) throw new Error(t(`vehicle.error.documentIdEmpty`)); + if (!dmsId.value) throw new Error(t(`vehicle.errors.documentIdEmpty`)); const data = { vehicleFk: route.params.id, @@ -27,10 +29,11 @@ const importDms = async () => { }; await axios.post('vehicleDms', data); + notify(t('globals.dataSaved'), 'positive'); dmsId.value = null; emit('onDataSaved'); } catch (e) { - throw new Error(e.message); + notify('vehicle.errors.dmsImported', 'negative'); } }; @@ -44,7 +47,7 @@ const importDms = async () => { /> diff --git a/src/pages/Ticket/Card/TicketDmsImportForm.vue b/src/pages/Ticket/Card/TicketDmsImportForm.vue index 4b6b9c6cd7..4ced5b6816 100644 --- a/src/pages/Ticket/Card/TicketDmsImportForm.vue +++ b/src/pages/Ticket/Card/TicketDmsImportForm.vue @@ -49,7 +49,7 @@ const importDms = async () => { @@ -70,7 +70,6 @@ const importDms = async () => { es: - Select document id: Introduzca id de gestion documental Document: Documento The document indentifier can't be empty: El número de documento no puede estar vacío diff --git a/test/cypress/integration/route/vehicle/vehicleDms.spec.js b/test/cypress/integration/route/vehicle/vehicleDms.spec.js index 92c1ddd186..7400941994 100644 --- a/test/cypress/integration/route/vehicle/vehicleDms.spec.js +++ b/test/cypress/integration/route/vehicle/vehicleDms.spec.js @@ -71,6 +71,7 @@ describe('Vehicle DMS', () => { cy.dataCy(selectors.importBtn).click(); cy.fillInForm(data); cy.dataCy(selectors.saveFormBtn).click(); + cy.checkNotification('Data saved'); cy.validateContent(selectors.lastRowReference, '1'); }); From dbdccc477437506ad4b1ad39fa3b3ba0a1e4dc00 Mon Sep 17 00:00:00 2001 From: jtubau Date: Fri, 28 Mar 2025 08:56:26 +0100 Subject: [PATCH 12/27] refactor: refs #8422 improve error handling and notifications in DMS components --- cypress.config.js | 2 +- src/components/common/VnDms.vue | 6 ++++-- src/components/common/VnDmsList.vue | 14 ++++++++++---- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/cypress.config.js b/cypress.config.js index cf9289fdc1..7458c0b05b 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -44,7 +44,7 @@ export default defineConfig({ supportFile: 'test/cypress/support/index.js', videosFolder: 'test/cypress/videos', downloadsFolder: 'test/cypress/downloads', - tmpUploadFolder: '../salix/storage/tmp/dms', + tmpUploadFolder: 'test/cypress/storage/tmp/dms', video: false, specPattern: 'test/cypress/integration/**/*.spec.js', experimentalRunAllSpecs: true, diff --git a/src/components/common/VnDms.vue b/src/components/common/VnDms.vue index 8553a92b6b..76a0c19563 100644 --- a/src/components/common/VnDms.vue +++ b/src/components/common/VnDms.vue @@ -89,7 +89,7 @@ async function save() { delete dms.value.files; return response; } catch (e) { - throw new Error(e.message); + notify(t('errorDmsSave'), 'negative'); } } @@ -210,12 +210,14 @@ function addDefaultData(data) { } -en: +en: + errorDmsSave: Error saving the dms contentTypesInfo: Allowed file types {allowedContentTypes} EntryDmsDescription: Reference {reference} WorkersDescription: Working of employee id {reference} SupplierDmsDescription: Reference {reference} es: + errorDmsSave: Error al guardar el dms Generate identifier for original file: Generar identificador para archivo original contentTypesInfo: Tipos de archivo permitidos {allowedContentTypes} EntryDmsDescription: Referencia {reference} diff --git a/src/components/common/VnDmsList.vue b/src/components/common/VnDmsList.vue index d1d40ac51c..2d0b1f7336 100644 --- a/src/components/common/VnDmsList.vue +++ b/src/components/common/VnDmsList.vue @@ -259,10 +259,14 @@ function deleteDms(dmsFk) { }, }) .onOk(async () => { - await axios.post(`${$props.deleteModel ?? $props.model}/${dmsFk}/removeFile`); - const index = rows.value.findIndex((row) => row.id == dmsFk); - rows.value.splice(index, 1); - notify(t('globals.dataDeleted'), 'positive'); + try{ + await axios.post(`${$props.deleteModel ?? $props.model}/${dmsFk}/removeFile`); + const index = rows.value.findIndex((row) => row.id == dmsFk); + rows.value.splice(index, 1); + notify(t('globals.dataDeleted'), 'positive'); + } catch (e) { + notify(t('errorDmsDelete'), 'negative'); + } }); } @@ -431,9 +435,11 @@ defineExpose({ en: + errorDmsDelete: Error deleting the dms contentTypesInfo: Allowed file types {allowedContentTypes} The documentation is available in paper form: The documentation is available in paper form es: + errorDmsSave: Error al eliminar el dms contentTypesInfo: Tipos de archivo permitidos {allowedContentTypes} Generate identifier for original file: Generar identificador para archivo original Upload file: Subir fichero From f0ef9b42c954f0a53b5ed7ccd0a7e8cc48f12889 Mon Sep 17 00:00:00 2001 From: jtubau Date: Tue, 1 Apr 2025 06:56:02 +0200 Subject: [PATCH 13/27] refactor: refs #8422 removed error-related changes --- src/components/common/VnDms.vue | 4 +--- src/components/common/VnDmsList.vue | 10 +++++----- src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue | 2 +- src/pages/Route/Vehicle/locale/en.yml | 1 - src/pages/Route/Vehicle/locale/es.yml | 1 - 5 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/components/common/VnDms.vue b/src/components/common/VnDms.vue index 76a0c19563..56c6695482 100644 --- a/src/components/common/VnDms.vue +++ b/src/components/common/VnDms.vue @@ -89,7 +89,7 @@ async function save() { delete dms.value.files; return response; } catch (e) { - notify(t('errorDmsSave'), 'negative'); + throw new Error(e.message); } } @@ -211,13 +211,11 @@ function addDefaultData(data) { en: - errorDmsSave: Error saving the dms contentTypesInfo: Allowed file types {allowedContentTypes} EntryDmsDescription: Reference {reference} WorkersDescription: Working of employee id {reference} SupplierDmsDescription: Reference {reference} es: - errorDmsSave: Error al guardar el dms Generate identifier for original file: Generar identificador para archivo original contentTypesInfo: Tipos de archivo permitidos {allowedContentTypes} EntryDmsDescription: Referencia {reference} diff --git a/src/components/common/VnDmsList.vue b/src/components/common/VnDmsList.vue index 2d0b1f7336..05d8370326 100644 --- a/src/components/common/VnDmsList.vue +++ b/src/components/common/VnDmsList.vue @@ -259,13 +259,15 @@ function deleteDms(dmsFk) { }, }) .onOk(async () => { - try{ - await axios.post(`${$props.deleteModel ?? $props.model}/${dmsFk}/removeFile`); + try { + await axios.post( + `${$props.deleteModel ?? $props.model}/${dmsFk}/removeFile`, + ); const index = rows.value.findIndex((row) => row.id == dmsFk); rows.value.splice(index, 1); notify(t('globals.dataDeleted'), 'positive'); } catch (e) { - notify(t('errorDmsDelete'), 'negative'); + throw new Error(e.message); } }); } @@ -435,11 +437,9 @@ defineExpose({ en: - errorDmsDelete: Error deleting the dms contentTypesInfo: Allowed file types {allowedContentTypes} The documentation is available in paper form: The documentation is available in paper form es: - errorDmsSave: Error al eliminar el dms contentTypesInfo: Tipos de archivo permitidos {allowedContentTypes} Generate identifier for original file: Generar identificador para archivo original Upload file: Subir fichero diff --git a/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue b/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue index dd716bd974..2be7f01e0d 100644 --- a/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue +++ b/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue @@ -33,7 +33,7 @@ const importDms = async () => { dmsId.value = null; emit('onDataSaved'); } catch (e) { - notify('vehicle.errors.dmsImported', 'negative'); + throw new Error(e.message); } }; diff --git a/src/pages/Route/Vehicle/locale/en.yml b/src/pages/Route/Vehicle/locale/en.yml index 884066b6ba..abd8b6799c 100644 --- a/src/pages/Route/Vehicle/locale/en.yml +++ b/src/pages/Route/Vehicle/locale/en.yml @@ -24,4 +24,3 @@ vehicle: document: Document errors: documentIdEmpty: The document identifier can't be empty - dmsImported: Error occurred while importing the document diff --git a/src/pages/Route/Vehicle/locale/es.yml b/src/pages/Route/Vehicle/locale/es.yml index 5df286b950..25a06274a4 100644 --- a/src/pages/Route/Vehicle/locale/es.yml +++ b/src/pages/Route/Vehicle/locale/es.yml @@ -24,4 +24,3 @@ vehicle: document: Documento errors: documentIdEmpty: El número de documento no puede estar vacío - dmsImported: Se ha producido un error al importar el documento From 0d056d3ed6408b514536412e17df3187bff426f2 Mon Sep 17 00:00:00 2001 From: jtubau Date: Wed, 2 Apr 2025 13:52:49 +0200 Subject: [PATCH 14/27] fix: refs #8422 router/module/route.js --- src/router/modules/route.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/router/modules/route.js b/src/router/modules/route.js index 95d3279f01..d71ad795d6 100644 --- a/src/router/modules/route.js +++ b/src/router/modules/route.js @@ -199,7 +199,7 @@ const vehicleCard = { icon: 'vn:notes', }, component: () => import('src/pages/Route/Vehicle/Card/VehicleNotes.vue'), - } + }, { name: 'VehicleDms', path: 'dms', From 070def57bb54f3ce75bd168c26ee2f2a55e10324 Mon Sep 17 00:00:00 2001 From: jtubau Date: Thu, 3 Apr 2025 10:28:40 +0200 Subject: [PATCH 15/27] refactor: refs #8422 update vehicle DMS tests and add download verification --- .../route/vehicle/vehicleDms.spec.js | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/test/cypress/integration/route/vehicle/vehicleDms.spec.js b/test/cypress/integration/route/vehicle/vehicleDms.spec.js index 7400941994..ebf65308c5 100644 --- a/test/cypress/integration/route/vehicle/vehicleDms.spec.js +++ b/test/cypress/integration/route/vehicle/vehicleDms.spec.js @@ -32,12 +32,14 @@ describe('Vehicle DMS', () => { }; const updateData = { - Reference: { val: 'Vehicle:5678-DEF' }, + Reference: { val: 'Vehicle:4598-FGH' }, Company: { val: 'CCs', type: 'select' }, Warehouse: { val: 'Warehouse Two', type: 'select' }, Type: { val: 'Facturas Recibidas', type: 'select' }, }; + const workerSummaryUrlRegex = /worker\/\d+\/summary/; + beforeEach(() => { cy.viewport(1920, 1080); cy.login('developer'); @@ -51,16 +53,22 @@ describe('Vehicle DMS', () => { .should('have.length.greaterThan', 0); }); + it('Should download DMS', () => { + cy.get(selectors.lastRowDownloadBtn).click(); + cy.wait(2000); + + const downloadsFolder = Cypress.config('downloadsFolder'); + const fileName = '11.jpg'; + cy.readFile(`${downloadsFolder}/${fileName}`).should('exist'); + }); + it('Should create new DMS', () => { - const uploadFolder = Cypress.config('tmpUploadFolder'); cy.dataCy(selectors.addBtn).click(); cy.dataCy(selectors.referenceInput).type(`{selectall}${data.Reference.val}`); cy.dataCy(selectors.fileInput).selectFile('test/cypress/fixtures/image.jpg', { force: true, }); cy.dataCy(selectors.saveFormBtn).click(); - const fileName = 'image.jpg'; - cy.readFile(`${uploadFolder}/${fileName}`).should('exist'); cy.checkNotification('Data saved'); }); @@ -87,22 +95,18 @@ describe('Vehicle DMS', () => { cy.get(selectors.lastRowDeleteBtn).click(); cy.clickConfirm(); cy.checkNotification('Data deleted'); - cy.validateContent(selectors.lastRowReference, 'Vehicle:3333-BAT'); - }); - - it('Should download DMS', () => { - const downloadsFolder = Cypress.config('downloadsFolder'); - cy.get(selectors.lastRowDownloadBtn).click(); - cy.wait(3000); - - const fileName = '1.txt'; - cy.readFile(`${downloadsFolder}/${fileName}`).should('exist'); + cy.containContent(selectors.lastRowReference, 'Vehicle:3333-BAT'); }); it('Should redirect to worker summary from worker descriptor pop-up', () => { - cy.get(selectors.lastRowWorkerLink).click(); - cy.get(selectors.descriptorTitle).should('contain', 'administrative'); - cy.get(selectors.descriptorGoToSummaryBtn).click(); - cy.containContent(selectors.summaryTitle, 'administrative'); + cy.get(selectors.lastRowWorkerLink) + .click() + .invoke('text') + .then((workerName) => { + workerName = workerName.trim(); + cy.get(selectors.descriptorGoToSummaryBtn).click(); + cy.url().should('match', workerSummaryUrlRegex); + cy.containContent(selectors.descriptorTitle, workerName); + }); }); }); From 7aeb75d4e135123aacf0a5401405fd40baf474f7 Mon Sep 17 00:00:00 2001 From: jtubau Date: Thu, 3 Apr 2025 13:02:15 +0200 Subject: [PATCH 16/27] refactor: refs #8422 simplify DMS creation test by using fillInForm utility --- test/cypress/integration/route/vehicle/vehicleDms.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cypress/integration/route/vehicle/vehicleDms.spec.js b/test/cypress/integration/route/vehicle/vehicleDms.spec.js index ebf65308c5..f8b54d5242 100644 --- a/test/cypress/integration/route/vehicle/vehicleDms.spec.js +++ b/test/cypress/integration/route/vehicle/vehicleDms.spec.js @@ -64,7 +64,7 @@ describe('Vehicle DMS', () => { it('Should create new DMS', () => { cy.dataCy(selectors.addBtn).click(); - cy.dataCy(selectors.referenceInput).type(`{selectall}${data.Reference.val}`); + cy.fillInForm(data); cy.dataCy(selectors.fileInput).selectFile('test/cypress/fixtures/image.jpg', { force: true, }); From a1e21d156b393073581e95eb4570562be22f378b Mon Sep 17 00:00:00 2001 From: jtubau Date: Thu, 3 Apr 2025 15:06:50 +0200 Subject: [PATCH 17/27] refactor: refs #8422 update RouteAutonomous tests to improve readability and maintainability --- .../integration/route/routeAutonomous.spec.js | 208 +++++++++++++----- 1 file changed, 156 insertions(+), 52 deletions(-) diff --git a/test/cypress/integration/route/routeAutonomous.spec.js b/test/cypress/integration/route/routeAutonomous.spec.js index d77584c04e..4bf9178d59 100644 --- a/test/cypress/integration/route/routeAutonomous.spec.js +++ b/test/cypress/integration/route/routeAutonomous.spec.js @@ -1,11 +1,12 @@ -describe.skip('RouteAutonomous', () => { - const getLinkSelector = (colField) => - `tr:first-child > [data-col-field="${colField}"] > .no-padding > .link`; +describe('RouteAutonomous', () => { + const getLinkSelector = (colField, link = true) => + `tr:first-child > [data-col-field="${colField}"] > .no-padding${link ? ' > .link' : ''}`; const selectors = { - reference: 'Reference_input', - date: 'tr:first-child > [data-col-field="dated"]', total: '.value > .text-h6', + routeId: getLinkSelector('routeFk', false), + agencyRoute: getLinkSelector('agencyModeName'), + agencyAgreement: getLinkSelector('agencyAgreement'), received: getLinkSelector('invoiceInFk'), autonomous: getLinkSelector('supplierName'), firstRowCheckbox: '.q-virtual-scroll__content tr:first-child .q-checkbox__bg', @@ -13,22 +14,30 @@ describe.skip('RouteAutonomous', () => { createInvoiceBtn: '.q-card > .q-btn', saveFormBtn: 'FormModelPopup_save', summaryIcon: 'tableAction-0', - summaryPopupBtn: '.header > :nth-child(2) > .q-btn__content > .q-icon', - summaryHeader: '.summaryHeader > :nth-child(2)', - descriptorHeader: '.summaryHeader > div', - descriptorTitle: '.q-item__label--header > .title > span', - summaryGoToSummaryBtn: '.header > .q-icon', - descriptorGoToSummaryBtn: '.descriptor > .header > a[href] > .q-btn', + descriptorRouteSubtitle: '[data-cy="vnDescriptor_subtitle"]', + descriptorAgencyAndSupplierTitle: '[data-cy="vnDescriptor_description"]', + descriptorInvoiceInTitle: '[data-cy="vnDescriptor_title"]', + descriptorOpenSummaryBtn: '.q-menu > .descriptor [data-cy="openSummaryBtn"]', + descriptorGoToSummaryBtn: '.q-menu > .descriptor [data-cy="goToSummaryBtn"]', + summaryGoToSummaryBtn: '.summaryHeader [data-cy="goToSummaryBtn"]', }; - const data = { - reference: 'Test invoice', - total: '€206.40', - supplier: 'PLANTS SL', - route: 'first route', + const newInvoice = { + Reference: { val: 'Test invoice' }, + Company: { val: 'VNL', type: 'select' }, + Warehouse: { val: 'Warehouse One', type: 'select' }, + Type: { val: 'Vehiculos', type: 'select' }, + Description: { val: 'Test description' }, }; - const summaryUrl = '/summary'; + const total = '€206.40'; + + const urls = { + summaryAgencyUrlRegex: /agency\/\d+\/summary/, + summaryInvoiceInUrlRegex: /invoice-in\/\d+\/summary/, + summarySupplierUrlRegex: /supplier\/\d+\/summary/, + summaryRouteUrlRegex: /route\/\d+\/summary/, + }; const dataSaved = 'Data saved'; beforeEach(() => { @@ -48,7 +57,7 @@ describe.skip('RouteAutonomous', () => { it('Should create invoice in to selected route', () => { cy.get(selectors.firstRowCheckbox).click(); cy.get(selectors.createInvoiceBtn).click(); - cy.dataCy(selectors.reference).type(data.reference); + cy.fillInForm(newInvoice); cy.dataCy('attachFile').click(); cy.get('.q-file').selectFile('test/cypress/fixtures/image.jpg', { force: true, @@ -60,62 +69,157 @@ describe.skip('RouteAutonomous', () => { it('Should display the total price of the selected rows', () => { cy.get(selectors.firstRowCheckbox).click(); cy.get(selectors.secondRowCheckbox).click(); - cy.validateContent(selectors.total, data.total); + cy.validateContent(selectors.total, total); }); it('Should redirect to the summary when clicking a route', () => { - cy.get(selectors.date).click(); - cy.get(selectors.summaryHeader).should('contain', data.route); - cy.url().should('include', summaryUrl); + cy.get(selectors.routeId) + .click() + .invoke('text') + .then((routeId) => { + routeId = routeId.trim(); + cy.url().should('match', urls.summaryRouteUrlRegex); + cy.containContent(selectors.descriptorRouteSubtitle, routeId); + }); + }); + + describe('Agency route pop-ups', () => { + it('Should redirect to the agency route summary from the agency route descriptor pop-up', () => { + cy.get(selectors.agencyRoute) + .click() + .invoke('text') + .then((agencyName) => { + agencyName = agencyName.trim(); + cy.get(selectors.descriptorGoToSummaryBtn).click(); + cy.url().should('match', urls.summaryAgencyUrlRegex); + cy.containContent( + selectors.descriptorAgencyAndSupplierTitle, + agencyName, + ); + }); + }); + + it('Should redirect to the agency route summary from summary pop-up from the agency route descriptor pop-up', () => { + cy.get(selectors.agencyRoute) + .click() + .invoke('text') + .then((agencyName) => { + agencyName = agencyName.trim(); + cy.get(selectors.descriptorOpenSummaryBtn).click(); + cy.get(selectors.summaryGoToSummaryBtn).click(); + cy.url().should('match', urls.summaryAgencyUrlRegex); + cy.containContent( + selectors.descriptorAgencyAndSupplierTitle, + agencyName, + ); + }); + }); + }); + + describe('Agency route pop-ups', () => { + it('Should redirect to the agency agreement summary from the agency agreement descriptor pop-up', () => { + cy.get(selectors.agencyAgreement) + .click() + .invoke('text') + .then((agencyName) => { + agencyName = agencyName.trim(); + cy.get(selectors.descriptorGoToSummaryBtn).click(); + cy.url().should('match', urls.summaryAgencyUrlRegex); + cy.containContent( + selectors.descriptorAgencyAndSupplierTitle, + agencyName, + ); + }); + }); + + it('Should redirect to the agency agreement summary from summary pop-up from the agency agreement descriptor pop-up', () => { + cy.get(selectors.agencyAgreement) + .click() + .invoke('text') + .then((agencyName) => { + agencyName = agencyName.trim(); + cy.get(selectors.descriptorOpenSummaryBtn).click(); + cy.get(selectors.summaryGoToSummaryBtn).click(); + cy.url().should('match', urls.summaryAgencyUrlRegex); + cy.containContent( + selectors.descriptorAgencyAndSupplierTitle, + agencyName, + ); + }); + }); }); describe('Received pop-ups', () => { - it('Should redirect to invoice in summary from the received descriptor pop-up', () => { - cy.get(selectors.received).click(); - cy.validateContent(selectors.descriptorTitle, data.reference); - cy.get(selectors.descriptorGoToSummaryBtn).click(); - cy.get(selectors.descriptorHeader).should('contain', data.supplier); - cy.url().should('include', summaryUrl); + it('Should redirect to the invoice in summary from the received descriptor pop-up', () => { + cy.get(selectors.received) + .click() + .invoke('text') + .then((invoice) => { + invoice = invoice.trim(); + cy.get(selectors.descriptorGoToSummaryBtn).click(); + cy.url().should('match', urls.summaryInvoiceInUrlRegex); + cy.containContent(selectors.descriptorInvoiceInTitle, invoice); + }); }); it('Should redirect to the invoiceIn summary from summary pop-up from the received descriptor pop-up', () => { - cy.get(selectors.received).click(); - cy.validateContent(selectors.descriptorTitle, data.reference); - cy.get(selectors.summaryPopupBtn).click(); - cy.get(selectors.descriptorHeader).should('contain', data.supplier); - cy.get(selectors.summaryGoToSummaryBtn).click(); - cy.get(selectors.descriptorHeader).should('contain', data.supplier); - cy.url().should('include', summaryUrl); + cy.get(selectors.received) + .click() + .invoke('text') + .then((invoice) => { + invoice = invoice.trim(); + cy.get(selectors.descriptorOpenSummaryBtn).click(); + cy.get(selectors.summaryGoToSummaryBtn).click(); + cy.url().should('match', urls.summaryInvoiceInUrlRegex); + cy.containContent(selectors.descriptorInvoiceInTitle, invoice); + }); }); }); describe('Autonomous pop-ups', () => { it('Should redirect to the supplier summary from the received descriptor pop-up', () => { - cy.get(selectors.autonomous).click(); - cy.validateContent(selectors.descriptorTitle, data.supplier); - cy.get(selectors.descriptorGoToSummaryBtn).click(); - cy.get(selectors.summaryHeader).should('contain', data.supplier); - cy.url().should('include', summaryUrl); + cy.get(selectors.autonomous) + .click() + .invoke('text') + .then((supplier) => { + supplier = supplier.trim(); + cy.get(selectors.descriptorGoToSummaryBtn).click(); + cy.url().should('match', urls.summarySupplierUrlRegex); + cy.containContent( + selectors.descriptorAgencyAndSupplierTitle, + supplier, + ); + }); }); it('Should redirect to the supplier summary from summary pop-up from the autonomous descriptor pop-up', () => { - cy.get(selectors.autonomous).click(); - cy.get(selectors.descriptorTitle).should('contain', data.supplier); - cy.get(selectors.summaryPopupBtn).click(); - cy.get(selectors.summaryHeader).should('contain', data.supplier); - cy.get(selectors.summaryGoToSummaryBtn).click(); - cy.get(selectors.summaryHeader).should('contain', data.supplier); - cy.url().should('include', summaryUrl); + cy.get(selectors.autonomous) + .click() + .invoke('text') + .then((supplier) => { + supplier = supplier.trim(); + cy.get(selectors.descriptorOpenSummaryBtn).click(); + cy.get(selectors.summaryGoToSummaryBtn).click(); + cy.url().should('match', urls.summarySupplierUrlRegex); + cy.containContent( + selectors.descriptorAgencyAndSupplierTitle, + supplier, + ); + }); }); }); describe('Route pop-ups', () => { it('Should redirect to the summary from the route summary pop-up', () => { - cy.dataCy(selectors.summaryIcon).first().click(); - cy.get(selectors.summaryHeader).should('contain', data.route); - cy.get(selectors.summaryGoToSummaryBtn).click(); - cy.get(selectors.summaryHeader).should('contain', data.route); - cy.url().should('include', summaryUrl); + cy.get(selectors.routeId) + .invoke('text') + .then((routeId) => { + routeId = routeId.trim(); + cy.dataCy(selectors.summaryIcon).first().click(); + cy.get(selectors.summaryGoToSummaryBtn).click(); + cy.url().should('match', urls.summaryRouteUrlRegex); + cy.containContent(selectors.descriptorRouteSubtitle, routeId); + }); }); }); }); From 2715502aba9987d4a9b32a01b01904d11c0a01f9 Mon Sep 17 00:00:00 2001 From: jtubau Date: Mon, 7 Apr 2025 09:25:16 +0200 Subject: [PATCH 18/27] fix: refs #8422 ensure checkbox state toggles correctly in route extended list tests --- test/cypress/integration/route/routeExtendedList.spec.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/cypress/integration/route/routeExtendedList.spec.js b/test/cypress/integration/route/routeExtendedList.spec.js index e6c873d5e4..c7db8dc7be 100644 --- a/test/cypress/integration/route/routeExtendedList.spec.js +++ b/test/cypress/integration/route/routeExtendedList.spec.js @@ -69,7 +69,8 @@ describe('Route extended list', () => { .type(`{selectall}{backspace}${value}`); break; case 'checkbox': - cy.get(selector).should('be.visible').click().click(); + cy.get(selector).should('be.visible').click() + cy.get(selector).click(); break; } } From 9a0211787a922e8733095ff5f390778ee04e6c64 Mon Sep 17 00:00:00 2001 From: jtubau Date: Fri, 11 Apr 2025 09:01:47 +0200 Subject: [PATCH 19/27] refactor: refs #8422 implement checkRedirectionFromPopup command and refactor tests for improved readability --- src/components/common/VnDms.vue | 2 +- src/components/common/VnDmsList.vue | 2 +- .../Vehicle/Card/VehicleDmsImportForm.vue | 2 +- src/pages/Ticket/Card/TicketDmsImportForm.vue | 2 +- .../integration/route/routeAutonomous.spec.js | 167 +++++++----------- .../route/vehicle/vehicleDms.spec.js | 31 +++- test/cypress/support/commands.js | 19 ++ 7 files changed, 110 insertions(+), 115 deletions(-) diff --git a/src/components/common/VnDms.vue b/src/components/common/VnDms.vue index f5391c0411..e264909337 100644 --- a/src/components/common/VnDms.vue +++ b/src/components/common/VnDms.vue @@ -93,7 +93,7 @@ async function save() { delete dms.value.files; return response; } catch (e) { - throw new Error(e.message); + throw e; } } diff --git a/src/components/common/VnDmsList.vue b/src/components/common/VnDmsList.vue index 05d8370326..a5834d0675 100644 --- a/src/components/common/VnDmsList.vue +++ b/src/components/common/VnDmsList.vue @@ -267,7 +267,7 @@ function deleteDms(dmsFk) { rows.value.splice(index, 1); notify(t('globals.dataDeleted'), 'positive'); } catch (e) { - throw new Error(e.message); + throw e; } }); } diff --git a/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue b/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue index 2be7f01e0d..28c0aa45ef 100644 --- a/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue +++ b/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue @@ -33,7 +33,7 @@ const importDms = async () => { dmsId.value = null; emit('onDataSaved'); } catch (e) { - throw new Error(e.message); + throw e; } }; diff --git a/src/pages/Ticket/Card/TicketDmsImportForm.vue b/src/pages/Ticket/Card/TicketDmsImportForm.vue index 4ced5b6816..04cb3d75ec 100644 --- a/src/pages/Ticket/Card/TicketDmsImportForm.vue +++ b/src/pages/Ticket/Card/TicketDmsImportForm.vue @@ -34,7 +34,7 @@ const importDms = async () => { dmsId.value = null; emit('onDataSaved'); } catch (e) { - throw new Error(e.message); + throw e; } }; diff --git a/test/cypress/integration/route/routeAutonomous.spec.js b/test/cypress/integration/route/routeAutonomous.spec.js index 4bf9178d59..f7abb50a5a 100644 --- a/test/cypress/integration/route/routeAutonomous.spec.js +++ b/test/cypress/integration/route/routeAutonomous.spec.js @@ -73,139 +73,102 @@ describe('RouteAutonomous', () => { }); it('Should redirect to the summary when clicking a route', () => { - cy.get(selectors.routeId) - .click() - .invoke('text') - .then((routeId) => { - routeId = routeId.trim(); - cy.url().should('match', urls.summaryRouteUrlRegex); - cy.containContent(selectors.descriptorRouteSubtitle, routeId); - }); + cy.checkRedirectionFromPopUp({ + selectorToClick: selectors.routeId, + expectedUrlRegex: urls.summaryRouteUrlRegex, + expectedTextSelector: selectors.descriptorRouteSubtitle, + }); }); describe('Agency route pop-ups', () => { it('Should redirect to the agency route summary from the agency route descriptor pop-up', () => { - cy.get(selectors.agencyRoute) - .click() - .invoke('text') - .then((agencyName) => { - agencyName = agencyName.trim(); - cy.get(selectors.descriptorGoToSummaryBtn).click(); - cy.url().should('match', urls.summaryAgencyUrlRegex); - cy.containContent( - selectors.descriptorAgencyAndSupplierTitle, - agencyName, - ); - }); + cy.checkRedirectionFromPopUp({ + selectorToClick: selectors.agencyRoute, + steps: [selectors.descriptorGoToSummaryBtn], + expectedUrlRegex: urls.summaryAgencyUrlRegex, + expectedTextSelector: selectors.descriptorAgencyAndSupplierTitle, + }); }); it('Should redirect to the agency route summary from summary pop-up from the agency route descriptor pop-up', () => { - cy.get(selectors.agencyRoute) - .click() - .invoke('text') - .then((agencyName) => { - agencyName = agencyName.trim(); - cy.get(selectors.descriptorOpenSummaryBtn).click(); - cy.get(selectors.summaryGoToSummaryBtn).click(); - cy.url().should('match', urls.summaryAgencyUrlRegex); - cy.containContent( - selectors.descriptorAgencyAndSupplierTitle, - agencyName, - ); - }); + cy.checkRedirectionFromPopUp({ + selectorToClick: selectors.agencyRoute, + steps: [ + selectors.descriptorOpenSummaryBtn, + selectors.summaryGoToSummaryBtn, + ], + expectedUrlRegex: urls.summaryAgencyUrlRegex, + expectedTextSelector: selectors.descriptorAgencyAndSupplierTitle, + }); }); }); describe('Agency route pop-ups', () => { it('Should redirect to the agency agreement summary from the agency agreement descriptor pop-up', () => { - cy.get(selectors.agencyAgreement) - .click() - .invoke('text') - .then((agencyName) => { - agencyName = agencyName.trim(); - cy.get(selectors.descriptorGoToSummaryBtn).click(); - cy.url().should('match', urls.summaryAgencyUrlRegex); - cy.containContent( - selectors.descriptorAgencyAndSupplierTitle, - agencyName, - ); - }); + cy.checkRedirectionFromPopUp({ + selectorToClick: selectors.agencyAgreement, + steps: [selectors.descriptorGoToSummaryBtn], + expectedUrlRegex: urls.summaryAgencyUrlRegex, + expectedTextSelector: selectors.descriptorAgencyAndSupplierTitle, + }); }); it('Should redirect to the agency agreement summary from summary pop-up from the agency agreement descriptor pop-up', () => { - cy.get(selectors.agencyAgreement) - .click() - .invoke('text') - .then((agencyName) => { - agencyName = agencyName.trim(); - cy.get(selectors.descriptorOpenSummaryBtn).click(); - cy.get(selectors.summaryGoToSummaryBtn).click(); - cy.url().should('match', urls.summaryAgencyUrlRegex); - cy.containContent( - selectors.descriptorAgencyAndSupplierTitle, - agencyName, - ); - }); + cy.checkRedirectionFromPopUp({ + selectorToClick: selectors.agencyAgreement, + steps: [ + selectors.descriptorOpenSummaryBtn, + selectors.summaryGoToSummaryBtn, + ], + expectedUrlRegex: urls.summaryAgencyUrlRegex, + expectedTextSelector: selectors.descriptorAgencyAndSupplierTitle, + }); }); }); describe('Received pop-ups', () => { it('Should redirect to the invoice in summary from the received descriptor pop-up', () => { - cy.get(selectors.received) - .click() - .invoke('text') - .then((invoice) => { - invoice = invoice.trim(); - cy.get(selectors.descriptorGoToSummaryBtn).click(); - cy.url().should('match', urls.summaryInvoiceInUrlRegex); - cy.containContent(selectors.descriptorInvoiceInTitle, invoice); - }); + cy.checkRedirectionFromPopUp({ + selectorToClick: selectors.received, + steps: [selectors.descriptorGoToSummaryBtn], + expectedUrlRegex: urls.summaryInvoiceInUrlRegex, + expectedTextSelector: selectors.descriptorInvoiceInTitle, + }); }); it('Should redirect to the invoiceIn summary from summary pop-up from the received descriptor pop-up', () => { - cy.get(selectors.received) - .click() - .invoke('text') - .then((invoice) => { - invoice = invoice.trim(); - cy.get(selectors.descriptorOpenSummaryBtn).click(); - cy.get(selectors.summaryGoToSummaryBtn).click(); - cy.url().should('match', urls.summaryInvoiceInUrlRegex); - cy.containContent(selectors.descriptorInvoiceInTitle, invoice); - }); + cy.checkRedirectionFromPopUp({ + selectorToClick: selectors.received, + steps: [ + selectors.descriptorOpenSummaryBtn, + selectors.summaryGoToSummaryBtn, + ], + expectedUrlRegex: urls.summaryInvoiceInUrlRegex, + expectedTextSelector: selectors.descriptorInvoiceInTitle, + }); }); }); describe('Autonomous pop-ups', () => { it('Should redirect to the supplier summary from the received descriptor pop-up', () => { - cy.get(selectors.autonomous) - .click() - .invoke('text') - .then((supplier) => { - supplier = supplier.trim(); - cy.get(selectors.descriptorGoToSummaryBtn).click(); - cy.url().should('match', urls.summarySupplierUrlRegex); - cy.containContent( - selectors.descriptorAgencyAndSupplierTitle, - supplier, - ); - }); + cy.checkRedirectionFromPopUp({ + selectorToClick: selectors.autonomous, + steps: [selectors.descriptorGoToSummaryBtn], + expectedUrlRegex: urls.summarySupplierUrlRegex, + expectedTextSelector: selectors.descriptorAgencyAndSupplierTitle, + }); }); it('Should redirect to the supplier summary from summary pop-up from the autonomous descriptor pop-up', () => { - cy.get(selectors.autonomous) - .click() - .invoke('text') - .then((supplier) => { - supplier = supplier.trim(); - cy.get(selectors.descriptorOpenSummaryBtn).click(); - cy.get(selectors.summaryGoToSummaryBtn).click(); - cy.url().should('match', urls.summarySupplierUrlRegex); - cy.containContent( - selectors.descriptorAgencyAndSupplierTitle, - supplier, - ); - }); + cy.checkRedirectionFromPopUp({ + selectorToClick: selectors.autonomous, + steps: [ + selectors.descriptorOpenSummaryBtn, + selectors.summaryGoToSummaryBtn, + ], + expectedUrlRegex: urls.summarySupplierUrlRegex, + expectedTextSelector: selectors.descriptorAgencyAndSupplierTitle, + }); }); }); diff --git a/test/cypress/integration/route/vehicle/vehicleDms.spec.js b/test/cypress/integration/route/vehicle/vehicleDms.spec.js index f8b54d5242..89b36ec9f9 100644 --- a/test/cypress/integration/route/vehicle/vehicleDms.spec.js +++ b/test/cypress/integration/route/vehicle/vehicleDms.spec.js @@ -12,7 +12,9 @@ describe('Vehicle DMS', () => { firstRowId: 'tr:first-child > :nth-child(2) > .q-tr > :nth-child(1) > span', lastRowWorkerLink: 'tr:last-child > :nth-child(8) > .q-tr > .link', descriptorTitle: '.descriptor .title', + descriptorOpenSummaryBtn: '.q-menu .descriptor [data-cy="openSummaryBtn"]', descriptorGoToSummaryBtn: '.q-menu .descriptor [data-cy="goToSummaryBtn"]', + summaryGoToSummaryBtn: '.summaryHeader [data-cy="goToSummaryBtn"]', summaryTitle: '.summaryHeader', referenceInput: 'Reference_input', companySelect: 'Company_select', @@ -98,15 +100,26 @@ describe('Vehicle DMS', () => { cy.containContent(selectors.lastRowReference, 'Vehicle:3333-BAT'); }); - it('Should redirect to worker summary from worker descriptor pop-up', () => { - cy.get(selectors.lastRowWorkerLink) - .click() - .invoke('text') - .then((workerName) => { - workerName = workerName.trim(); - cy.get(selectors.descriptorGoToSummaryBtn).click(); - cy.url().should('match', workerSummaryUrlRegex); - cy.containContent(selectors.descriptorTitle, workerName); + describe('Worker pop-ups', () => { + it('Should redirect to worker summary from worker descriptor pop-up', () => { + cy.checkRedirectionFromPopUp({ + selectorToClick: selectors.lastRowWorkerLink, + steps: [selectors.descriptorGoToSummaryBtn], + expectedUrlRegex: workerSummaryUrlRegex, + expectedTextSelector: selectors.descriptorTitle, }); + }); + + it('Should redirect to worker summary from summary pop-up from worker descriptor pop-up', () => { + cy.checkRedirectionFromPopUp({ + selectorToClick: selectors.lastRowWorkerLink, + steps: [ + selectors.descriptorOpenSummaryBtn, + selectors.summaryGoToSummaryBtn, + ], + expectedUrlRegex: workerSummaryUrlRegex, + expectedTextSelector: selectors.descriptorTitle, + }); + }); }); }); diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index 41f91e8553..ed699ac46c 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -619,3 +619,22 @@ Cypress.Commands.add('validateScrollContent', (validations) => { ); }); }); + +Cypress.Commands.add( + 'checkRedirectionFromPopup', + ({ selectorToClick, steps = [], expectedUrlRegex, expectedTextSelector }) => { + cy.get(selectorToClick) + .click() + .invoke('text') + .then((label) => { + label = label.trim(); + + steps.forEach((stepSelector) => { + cy.get(stepSelector).should('be.visible').click(); + }); + + cy.location().should('match', expectedUrlRegex); + cy.containContent(expectedTextSelector, label); + }); + }, +); From 6dddad95c9a78c684c2a32b8b0073b30ee89333d Mon Sep 17 00:00:00 2001 From: jtubau Date: Fri, 11 Apr 2025 10:43:49 +0200 Subject: [PATCH 20/27] fix: refs #8422 correct spelling of 'PopUp' in checkRedirectionFromPopup command --- test/cypress/support/commands.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index ed699ac46c..9a7801ea07 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -621,7 +621,7 @@ Cypress.Commands.add('validateScrollContent', (validations) => { }); Cypress.Commands.add( - 'checkRedirectionFromPopup', + 'checkRedirectionFromPopUp', ({ selectorToClick, steps = [], expectedUrlRegex, expectedTextSelector }) => { cy.get(selectorToClick) .click() From 800e5e18d448ec8d2b313ffc0aa10cb0dbe54487 Mon Sep 17 00:00:00 2001 From: jtubau Date: Fri, 11 Apr 2025 12:20:01 +0200 Subject: [PATCH 21/27] test: refs #8422 update download DMS test to verify file download response --- .../integration/route/vehicle/vehicleDms.spec.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/test/cypress/integration/route/vehicle/vehicleDms.spec.js b/test/cypress/integration/route/vehicle/vehicleDms.spec.js index 89b36ec9f9..94ea8ccaad 100644 --- a/test/cypress/integration/route/vehicle/vehicleDms.spec.js +++ b/test/cypress/integration/route/vehicle/vehicleDms.spec.js @@ -55,13 +55,16 @@ describe('Vehicle DMS', () => { .should('have.length.greaterThan', 0); }); - it('Should download DMS', () => { - cy.get(selectors.lastRowDownloadBtn).click(); - cy.wait(2000); - - const downloadsFolder = Cypress.config('downloadsFolder'); + it.only('Should download DMS', () => { const fileName = '11.jpg'; - cy.readFile(`${downloadsFolder}/${fileName}`).should('exist'); + cy.intercept('GET', /\/api\/dms\/11\/downloadFile/).as('download'); + cy.get(selectors.lastRowDownloadBtn).click(); + + cy.wait('@download').then((interception) => { + cy.log('RESPUESTA: ', JSON.stringify(interception.response)); + expect(interception.response.statusCode).to.equal(200); + expect(interception.response.headers['content-disposition']).to.contain(fileName); + }); }); it('Should create new DMS', () => { From b45c97e3c1c0db194d356c970799925d771459d5 Mon Sep 17 00:00:00 2001 From: jtubau Date: Fri, 11 Apr 2025 14:01:05 +0200 Subject: [PATCH 22/27] test: refs #8422 remove 'only' from download DMS test to ensure all tests run --- test/cypress/integration/route/vehicle/vehicleDms.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cypress/integration/route/vehicle/vehicleDms.spec.js b/test/cypress/integration/route/vehicle/vehicleDms.spec.js index 94ea8ccaad..d0c493c4d5 100644 --- a/test/cypress/integration/route/vehicle/vehicleDms.spec.js +++ b/test/cypress/integration/route/vehicle/vehicleDms.spec.js @@ -55,7 +55,7 @@ describe('Vehicle DMS', () => { .should('have.length.greaterThan', 0); }); - it.only('Should download DMS', () => { + it('Should download DMS', () => { const fileName = '11.jpg'; cy.intercept('GET', /\/api\/dms\/11\/downloadFile/).as('download'); cy.get(selectors.lastRowDownloadBtn).click(); From be877fa2b8cdf1a352676094f6f5c9abe704cb0e Mon Sep 17 00:00:00 2001 From: jtubau Date: Mon, 14 Apr 2025 12:07:58 +0200 Subject: [PATCH 23/27] refactor: refs #8422 add testDmsAction command for streamlined DMS operations in Cypress tests --- src/components/common/VnDmsList.vue | 1 + .../route/vehicle/vehicleDms.spec.js | 69 ++++++++++++------- test/cypress/support/commands.js | 13 ++++ 3 files changed, 58 insertions(+), 25 deletions(-) diff --git a/src/components/common/VnDmsList.vue b/src/components/common/VnDmsList.vue index a5834d0675..345870aa46 100644 --- a/src/components/common/VnDmsList.vue +++ b/src/components/common/VnDmsList.vue @@ -306,6 +306,7 @@ defineExpose({ :data-key="$props.model" :url="$props.model" :user-filter="dmsFilter" + search-url="dmsFilter" :order="['dmsFk DESC']" :filter="{ where: { [$props.filter]: route.params.id } }" auto-load diff --git a/test/cypress/integration/route/vehicle/vehicleDms.spec.js b/test/cypress/integration/route/vehicle/vehicleDms.spec.js index d0c493c4d5..a793743170 100644 --- a/test/cypress/integration/route/vehicle/vehicleDms.spec.js +++ b/test/cypress/integration/route/vehicle/vehicleDms.spec.js @@ -21,8 +21,8 @@ describe('Vehicle DMS', () => { warehouseSelect: 'Warehouse_select', typeSelect: 'Type_select', fileInput: 'VnDms_inputFile', - importBtn: 'importBtn', - addBtn: 'addButton', + importBtn: '[data-cy="importBtn"]', + addBtn: '[data-cy="addButton"]', saveFormBtn: 'FormModelPopup_save', }; @@ -61,46 +61,65 @@ describe('Vehicle DMS', () => { cy.get(selectors.lastRowDownloadBtn).click(); cy.wait('@download').then((interception) => { - cy.log('RESPUESTA: ', JSON.stringify(interception.response)); expect(interception.response.statusCode).to.equal(200); - expect(interception.response.headers['content-disposition']).to.contain(fileName); + expect(interception.response.headers['content-disposition']).to.contain( + fileName, + ); }); }); it('Should create new DMS', () => { - cy.dataCy(selectors.addBtn).click(); - cy.fillInForm(data); - cy.dataCy(selectors.fileInput).selectFile('test/cypress/fixtures/image.jpg', { - force: true, - }); - cy.dataCy(selectors.saveFormBtn).click(); - cy.checkNotification('Data saved'); + const formSelectors = { + actionBtn: selectors.addBtn, + fileInput: selectors.fileInput, + saveFormBtn: selectors.saveFormBtn, + }; + + cy.testDmsAction('create', formSelectors, data, 'Data saved'); }); it('Should import DMS', () => { const data = { Document: { val: '10', type: 'select' }, }; - cy.dataCy(selectors.importBtn).click(); - cy.fillInForm(data); - cy.dataCy(selectors.saveFormBtn).click(); - cy.checkNotification('Data saved'); - cy.validateContent(selectors.lastRowReference, '1'); + const formSelectors = { + actionBtn: selectors.importBtn, + selectorContentToCheck: selectors.lastRowReference, + saveFormBtn: selectors.saveFormBtn, + }; + + cy.testDmsAction('import', formSelectors, data, 'Data saved', '1'); }); it('Should edit DMS', () => { - cy.get(selectors.lastRowEditBtn).click(); - cy.fillInForm(updateData); - cy.dataCy(selectors.saveFormBtn).click(); - cy.checkNotification('Data saved'); - cy.validateContent(selectors.lastRowReference, updateData.Reference.val); + const formSelectors = { + actionBtn: selectors.lastRowEditBtn, + selectorContentToCheck: selectors.lastRowReference, + saveFormBtn: selectors.saveFormBtn, + }; + + cy.testDmsAction( + 'edit', + formSelectors, + updateData, + 'Data saved', + updateData.Reference.val, + ); }); it('Should delete DMS', () => { - cy.get(selectors.lastRowDeleteBtn).click(); - cy.clickConfirm(); - cy.checkNotification('Data deleted'); - cy.containContent(selectors.lastRowReference, 'Vehicle:3333-BAT'); + const formSelectors = { + actionBtn: selectors.lastRowDeleteBtn, + selectorContentToCheck: selectors.lastRowReference, + }; + + cy.testDmsAction( + 'delete', + formSelectors, + null, + 'Data deleted', + 'Vehicle:3333-BAT', + ); }); describe('Worker pop-ups', () => { diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index 9a7801ea07..9bf379debd 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -638,3 +638,16 @@ Cypress.Commands.add( }); }, ); + +Cypress.Commands.add('testDmsAction', (action, selectors, data, message, content) => { + cy.get(selectors.actionBtn).click(); + if (action !== 'delete') cy.fillInForm(data); + if (action === 'create') + cy.dataCy(selectors.fileInput).selectFile('test/cypress/fixtures/image.jpg', { + force: true, + }); + if (action === 'delete') cy.clickConfirm(); + if (action !== 'delete') cy.dataCy(selectors.saveFormBtn).click(); + cy.checkNotification(message); + if (action !== 'create') cy.containContent(selectors.selectorContentToCheck, content); +}); From b26be0bf6d6c6bf2a0470e481433742314d63f85 Mon Sep 17 00:00:00 2001 From: jtubau Date: Mon, 14 Apr 2025 12:27:15 +0200 Subject: [PATCH 24/27] feat: refs #8422 add testDmsAction command to handle create and delete actions with improved logic --- test/cypress/support/commands.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index 9bf379debd..8b9a3d3e96 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -641,13 +641,19 @@ Cypress.Commands.add( Cypress.Commands.add('testDmsAction', (action, selectors, data, message, content) => { cy.get(selectors.actionBtn).click(); - if (action !== 'delete') cy.fillInForm(data); - if (action === 'create') + + if (action === 'create') { cy.dataCy(selectors.fileInput).selectFile('test/cypress/fixtures/image.jpg', { force: true, }); - if (action === 'delete') cy.clickConfirm(); - if (action !== 'delete') cy.dataCy(selectors.saveFormBtn).click(); + } + + if (action !== 'delete') { + cy.fillInForm(data); + cy.dataCy(selectors.saveFormBtn).click(); + } else cy.clickConfirm(); + cy.checkNotification(message); + if (action !== 'create') cy.containContent(selectors.selectorContentToCheck, content); }); From 46c0e4bc74329e954fb05a0e9e610448ad3ca0f7 Mon Sep 17 00:00:00 2001 From: jtubau Date: Mon, 14 Apr 2025 13:43:52 +0200 Subject: [PATCH 25/27] test: refs #8422 skip download DMS test to prevent execution during current test run --- test/cypress/integration/route/vehicle/vehicleDms.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cypress/integration/route/vehicle/vehicleDms.spec.js b/test/cypress/integration/route/vehicle/vehicleDms.spec.js index a793743170..4d9250e0f7 100644 --- a/test/cypress/integration/route/vehicle/vehicleDms.spec.js +++ b/test/cypress/integration/route/vehicle/vehicleDms.spec.js @@ -55,7 +55,7 @@ describe('Vehicle DMS', () => { .should('have.length.greaterThan', 0); }); - it('Should download DMS', () => { + it.skip('Should download DMS', () => { const fileName = '11.jpg'; cy.intercept('GET', /\/api\/dms\/11\/downloadFile/).as('download'); cy.get(selectors.lastRowDownloadBtn).click(); From 76c6bd3048099a60de4c87d59bdb9461a15c99ec Mon Sep 17 00:00:00 2001 From: jtubau Date: Tue, 15 Apr 2025 08:22:31 +0200 Subject: [PATCH 26/27] refactor: refs #8422 update document ID prompt for clarity in Spanish and English locales --- src/i18n/locale/es.yml | 2 +- src/pages/Route/Vehicle/locale/en.yml | 1 - src/pages/Route/Vehicle/locale/es.yml | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index 6d760555c6..b8f0e10468 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -164,7 +164,7 @@ globals: noData: Datos no disponibles department: Departamento vehicle: Vehículo - selectDocumentId: Introduzca id de gestión documental + selectDocumentId: Seleccione el id de gestión documental pageTitles: logIn: Inicio de sesión addressEdit: Modificar consignatario diff --git a/src/pages/Route/Vehicle/locale/en.yml b/src/pages/Route/Vehicle/locale/en.yml index abd8b6799c..ca3cee31ba 100644 --- a/src/pages/Route/Vehicle/locale/en.yml +++ b/src/pages/Route/Vehicle/locale/en.yml @@ -20,7 +20,6 @@ vehicle: vehicleStateFk: State dms: import: Import from existing - selectDocId: Select document id document: Document errors: documentIdEmpty: The document identifier can't be empty diff --git a/src/pages/Route/Vehicle/locale/es.yml b/src/pages/Route/Vehicle/locale/es.yml index 25a06274a4..c6eef2b6e9 100644 --- a/src/pages/Route/Vehicle/locale/es.yml +++ b/src/pages/Route/Vehicle/locale/es.yml @@ -20,7 +20,6 @@ vehicle: vehicleStateFk: Estado dms: import: Importar desde existente - selectDocId: Introduzca id de gestión documental document: Documento errors: documentIdEmpty: El número de documento no puede estar vacío From db06227b14355cfc71abdb39730c6c2214d4e0e1 Mon Sep 17 00:00:00 2001 From: jtubau Date: Tue, 15 Apr 2025 10:39:33 +0200 Subject: [PATCH 27/27] refactor: refs #8422 add document and import translations for DMS in global locales --- src/i18n/locale/en.yml | 2 ++ src/i18n/locale/es.yml | 2 ++ src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue | 2 +- src/pages/Route/Vehicle/VehicleDms.vue | 2 +- src/pages/Route/Vehicle/locale/en.yml | 3 --- src/pages/Route/Vehicle/locale/es.yml | 3 --- 6 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/i18n/locale/en.yml b/src/i18n/locale/en.yml index ad3c3fa2fe..e45640017a 100644 --- a/src/i18n/locale/en.yml +++ b/src/i18n/locale/en.yml @@ -161,6 +161,8 @@ globals: noData: No data available vehicle: Vehicle selectDocumentId: Select document id + document: Document + import: Import from existing pageTitles: logIn: Login addressEdit: Update address diff --git a/src/i18n/locale/es.yml b/src/i18n/locale/es.yml index b8f0e10468..6f9efc6c27 100644 --- a/src/i18n/locale/es.yml +++ b/src/i18n/locale/es.yml @@ -165,6 +165,8 @@ globals: department: Departamento vehicle: Vehículo selectDocumentId: Seleccione el id de gestión documental + document: Documento + import: Importar desde existente pageTitles: logIn: Inicio de sesión addressEdit: Modificar consignatario diff --git a/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue b/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue index 28c0aa45ef..ade3e6dc5b 100644 --- a/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue +++ b/src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue @@ -53,7 +53,7 @@ const importDms = async () => { >