#8442 - createVehicleDms #1614

Merged
jtubau merged 47 commits from 8422-createVehicleDms into dev 2025-04-16 14:20:24 +00:00
15 changed files with 468 additions and 68 deletions

View File

@ -44,6 +44,7 @@ export default defineConfig({
supportFile: 'test/cypress/support/index.js', supportFile: 'test/cypress/support/index.js',
videosFolder: 'test/cypress/videos', videosFolder: 'test/cypress/videos',
downloadsFolder: 'test/cypress/downloads', downloadsFolder: 'test/cypress/downloads',
tmpUploadFolder: 'test/cypress/storage/tmp/dms',
video: false, video: false,
specPattern: 'test/cypress/integration/**/*.spec.js', specPattern: 'test/cypress/integration/**/*.spec.js',
experimentalRunAllSpecs: true, experimentalRunAllSpecs: true,

View File

@ -4,6 +4,7 @@ import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import axios from 'axios'; import axios from 'axios';
import useNotify from 'src/composables/useNotify.js';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
import VnRow from 'components/ui/VnRow.vue'; import VnRow from 'components/ui/VnRow.vue';
import VnSelect from 'src/components/common/VnSelect.vue'; import VnSelect from 'src/components/common/VnSelect.vue';
@ -12,6 +13,7 @@ import FormModelPopup from 'components/FormModelPopup.vue';
const route = useRoute(); const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();
const { notify } = useNotify();
const emit = defineEmits(['onDataSaved']); const emit = defineEmits(['onDataSaved']);
const $props = defineProps({ const $props = defineProps({
@ -86,11 +88,16 @@ function getUrl() {
} }
async function save() { async function save() {
const body = mapperDms(dms.value); try {
const response = await axios.post(getUrl(), body[0], body[1]); const body = mapperDms(dms.value);
emit('onDataSaved', body[1].params, response); const response = await axios.post(getUrl(), body[0], body[1]);
delete dms.value.files; emit('onDataSaved', body[1].params, response);
return response; notify(t('globals.dataSaved'), 'positive');
delete dms.value.files;
return response;
} catch (e) {
throw e;
}
} }
function defaultData() { function defaultData() {
@ -211,7 +218,7 @@ function addDefaultData(data) {
} }
</style> </style>
<i18n> <i18n>
en: en:
contentTypesInfo: Allowed file types {allowedContentTypes} contentTypesInfo: Allowed file types {allowedContentTypes}
EntryDmsDescription: Reference {reference} EntryDmsDescription: Reference {reference}
WorkersDescription: Working of employee id {reference} WorkersDescription: Working of employee id {reference}

View File

@ -13,10 +13,12 @@ import VnDms from 'src/components/common/VnDms.vue';
import VnConfirm from 'components/ui/VnConfirm.vue'; import VnConfirm from 'components/ui/VnConfirm.vue';
import VnInputDate from 'components/common/VnInputDate.vue'; import VnInputDate from 'components/common/VnInputDate.vue';
import { useSession } from 'src/composables/useSession'; import { useSession } from 'src/composables/useSession';
import useNotify from 'src/composables/useNotify.js';
const route = useRoute(); const route = useRoute();
const quasar = useQuasar(); const quasar = useQuasar();
const { t } = useI18n(); const { t } = useI18n();
const { notify } = useNotify();
const rows = ref([]); const rows = ref([]);
const dmsRef = ref(); const dmsRef = ref();
const formDialog = ref({}); const formDialog = ref({});
@ -88,7 +90,6 @@ const dmsFilter = {
], ],
}, },
}, },
where: { [$props.filter]: route.params.id },
}; };
const columns = computed(() => [ const columns = computed(() => [
@ -258,9 +259,16 @@ function deleteDms(dmsFk) {
}, },
}) })
.onOk(async () => { .onOk(async () => {
await axios.post(`${$props.deleteModel ?? $props.model}/${dmsFk}/removeFile`); try {
const index = rows.value.findIndex((row) => row.id == dmsFk); await axios.post(
rows.value.splice(index, 1); `${$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) {
throw e;
}
}); });
} }
@ -298,7 +306,9 @@ defineExpose({
:data-key="$props.model" :data-key="$props.model"
:url="$props.model" :url="$props.model"
:user-filter="dmsFilter" :user-filter="dmsFilter"
search-url="dmsFilter"
:order="['dmsFk DESC']" :order="['dmsFk DESC']"
:filter="{ where: { [$props.filter]: route.params.id } }"
auto-load auto-load
@on-fetch="setData" @on-fetch="setData"
> >

View File

@ -162,6 +162,9 @@ globals:
department: Department department: Department
noData: No data available noData: No data available
vehicle: Vehicle vehicle: Vehicle
selectDocumentId: Select document id
document: Document
import: Import from existing
pageTitles: pageTitles:
logIn: Login logIn: Login
addressEdit: Update address addressEdit: Update address

View File

@ -166,6 +166,9 @@ globals:
noData: Datos no disponibles noData: Datos no disponibles
department: Departamento department: Departamento
vehicle: Vehículo vehicle: Vehículo
selectDocumentId: Seleccione el id de gestión documental
document: Documento
import: Importar desde existente
pageTitles: pageTitles:
logIn: Inicio de sesión logIn: Inicio de sesión
addressEdit: Modificar consignatario addressEdit: Modificar consignatario

View File

@ -0,0 +1,65 @@
<script setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
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([]);
const dmsId = ref(null);
const importDms = async () => {
try {
if (!dmsId.value) throw new Error(t(`vehicle.errors.documentIdEmpty`));
const data = {
vehicleFk: route.params.id,
dmsFk: dmsId.value,
};
await axios.post('vehicleDms', data);
notify(t('globals.dataSaved'), 'positive');
dmsId.value = null;
jtubau marked this conversation as resolved
Review

Revisar si se muestra el el error al usuario

Revisar si se muestra el el error al usuario
emit('onDataSaved');
} catch (e) {
throw e;
}
};
</script>
<template>
<FetchData
url="Dms"
:filter="{ fields: ['id'], order: 'id ASC' }"
auto-load
@on-fetch="(data) => (dmsOptions = data)"
/>
<FormModelPopup
model="DmsImport"
:title="t('globals.selectDocumentId')"
:form-initial-data="{}"
:save-fn="importDms"
>
<template #form-inputs>
<VnSelect
:label="t('globals.document')"
:options="dmsOptions"
hide-selected
option-label="id"
option-value="id"
v-model="dmsId"
/>
</template>
</FormModelPopup>
</template>

View File

@ -0,0 +1,42 @@
<script setup>
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import VnDmsList from 'src/components/common/VnDmsList.vue';
import VehicleDmsImportForm from 'src/pages/Route/Vehicle/Card/VehicleDmsImportForm.vue';
const { t } = useI18n();
const dmsListRef = ref(null);
const showImportDialog = ref(false);
const onDataSaved = () => dmsListRef.value.dmsRef.fetch();
</script>
<template>
<VnDmsList
ref="dmsListRef"
model="VehicleDms"
update-model="vehicles"
delete-model="VehicleDms"
download-model="dms"
default-dms-code="vehicles"
filter="vehicleFk"
/>
<QDialog v-model="showImportDialog">
<VehicleDmsImportForm @on-data-saved="onDataSaved()" />
</QDialog>
<QPageSticky position="bottom-right" :offset="[25, 90]">
<QBtn
fab
color="primary"
icon="file_copy"
@click="showImportDialog = true"
class="fill-icon"
data-cy="importBtn"
>
<QTooltip>
{{ t('globals.import') }}
</QTooltip>
</QBtn>
</QPageSticky>
</template>

View File

@ -18,3 +18,5 @@ vehicle:
params: params:
vehicleTypeFk: Type vehicleTypeFk: Type
vehicleStateFk: State vehicleStateFk: State
errors:
documentIdEmpty: The document identifier can't be empty

View File

@ -18,3 +18,5 @@ vehicle:
params: params:
vehicleTypeFk: Tipo vehicleTypeFk: Tipo
vehicleStateFk: Estado vehicleStateFk: Estado
errors:
documentIdEmpty: El número de documento no puede estar vacío

View File

@ -34,7 +34,7 @@ const importDms = async () => {
dmsId.value = null; dmsId.value = null;
emit('onDataSaved'); emit('onDataSaved');
} catch (e) { } catch (e) {
throw new Error(e.message); throw e;
} }
}; };
</script> </script>
@ -49,7 +49,7 @@ const importDms = async () => {
<FormModelPopup <FormModelPopup
url-create="genera" url-create="genera"
model="DmsImport" model="DmsImport"
:title="t('Select document id')" :title="t('globals.selectDocumentId')"
:form-initial-data="{}" :form-initial-data="{}"
:save-fn="importDms" :save-fn="importDms"
> >
@ -70,7 +70,6 @@ const importDms = async () => {
<i18n> <i18n>
es: es:
Select document id: Introduzca id de gestion documental
Document: Documento Document: Documento
The document indentifier can't be empty: El número de documento no puede estar vacío The document indentifier can't be empty: El número de documento no puede estar vacío
</i18n> </i18n>

View File

@ -166,7 +166,11 @@ const vehicleCard = {
component: () => import('src/pages/Route/Vehicle/Card/VehicleCard.vue'), component: () => import('src/pages/Route/Vehicle/Card/VehicleCard.vue'),
redirect: { name: 'VehicleSummary' }, redirect: { name: 'VehicleSummary' },
meta: { meta: {
menu: ['VehicleBasicData', 'VehicleNotes'], menu: [
'VehicleBasicData',
'VehicleNotes',
'VehicleDms',
],
}, },
children: [ children: [
{ {
@ -195,7 +199,16 @@ const vehicleCard = {
icon: 'vn:notes', icon: 'vn:notes',
}, },
component: () => import('src/pages/Route/Vehicle/Card/VehicleNotes.vue'), component: () => import('src/pages/Route/Vehicle/Card/VehicleNotes.vue'),
} },
{
name: 'VehicleDms',
path: 'dms',
meta: {
title: 'dms',
icon: 'cloud_upload',
},
component: () => import('src/pages/Route/Vehicle/VehicleDms.vue'),
},
], ],
}; };

View File

@ -1,11 +1,12 @@
describe('RouteAutonomous', () => { describe('RouteAutonomous', () => {
const getLinkSelector = (colField) => const getLinkSelector = (colField, link = true) =>
`tr:first-child > [data-col-field="${colField}"] > .no-padding > .link`; `tr:first-child > [data-col-field="${colField}"] > .no-padding${link ? ' > .link' : ''}`;
const selectors = { const selectors = {
reference: 'Reference_input',
date: 'tr:first-child > [data-col-field="dated"]',
total: '.value > .text-h6', total: '.value > .text-h6',
routeId: getLinkSelector('routeFk', false),
agencyRoute: getLinkSelector('agencyModeName'),
agencyAgreement: getLinkSelector('agencyAgreement'),
received: getLinkSelector('invoiceInFk'), received: getLinkSelector('invoiceInFk'),
autonomous: getLinkSelector('supplierName'), autonomous: getLinkSelector('supplierName'),
firstRowCheckbox: '.q-virtual-scroll__content tr:first-child .q-checkbox__bg', firstRowCheckbox: '.q-virtual-scroll__content tr:first-child .q-checkbox__bg',
@ -13,22 +14,30 @@ describe('RouteAutonomous', () => {
createInvoiceBtn: '.q-card > .q-btn', createInvoiceBtn: '.q-card > .q-btn',
saveFormBtn: 'FormModelPopup_save', saveFormBtn: 'FormModelPopup_save',
summaryIcon: 'tableAction-0', summaryIcon: 'tableAction-0',
summaryPopupBtn: '.header > :nth-child(2) > .q-btn__content > .q-icon', descriptorRouteSubtitle: '[data-cy="vnDescriptor_subtitle"]',
summaryHeader: '.summaryHeader > :nth-child(2)', descriptorAgencyAndSupplierTitle: '[data-cy="vnDescriptor_description"]',
descriptorHeader: '.summaryHeader > div', descriptorInvoiceInTitle: '[data-cy="vnDescriptor_title"]',
descriptorTitle: '.q-item__label--header > .title > span', descriptorOpenSummaryBtn: '.q-menu > .descriptor [data-cy="openSummaryBtn"]',
jtubau marked this conversation as resolved
Review

Si vas directo al dataCy no funciona?

Si vas directo al dataCy no funciona?
summaryGoToSummaryBtn: '.header > .q-icon', descriptorGoToSummaryBtn: '.q-menu > .descriptor [data-cy="goToSummaryBtn"]',
descriptorGoToSummaryBtn: '.descriptor > .header > a[href] > .q-btn', summaryGoToSummaryBtn: '.summaryHeader [data-cy="goToSummaryBtn"]',
}; };
const data = { const newInvoice = {
reference: 'Test invoice', Reference: { val: 'Test invoice' },
total: '€206.40', Company: { val: 'VNL', type: 'select' },
supplier: 'PLANTS SL', Warehouse: { val: 'Warehouse One', type: 'select' },
route: 'first route', 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'; const dataSaved = 'Data saved';
beforeEach(() => { beforeEach(() => {
@ -47,7 +56,7 @@ describe('RouteAutonomous', () => {
it.skip('Should create invoice in to selected route', () => { it.skip('Should create invoice in to selected route', () => {
cy.get(selectors.firstRowCheckbox).click(); cy.get(selectors.firstRowCheckbox).click();
cy.get(selectors.createInvoiceBtn).click(); cy.get(selectors.createInvoiceBtn).click();
cy.dataCy(selectors.reference).type(data.reference); cy.fillInForm(newInvoice);
cy.dataCy('attachFile').click(); cy.dataCy('attachFile').click();
cy.get('.q-file').selectFile('test/cypress/fixtures/image.jpg', { cy.get('.q-file').selectFile('test/cypress/fixtures/image.jpg', {
force: true, force: true,
@ -59,62 +68,120 @@ describe('RouteAutonomous', () => {
it('Should display the total price of the selected rows', () => { it('Should display the total price of the selected rows', () => {
cy.get(selectors.firstRowCheckbox).click(); cy.get(selectors.firstRowCheckbox).click();
cy.get(selectors.secondRowCheckbox).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', () => { it('Should redirect to the summary when clicking a route', () => {
cy.get(selectors.date).click(); cy.checkRedirectionFromPopUp({
cy.get(selectors.summaryHeader).should('contain', data.route); selectorToClick: selectors.routeId,
cy.url().should('include', summaryUrl); expectedUrlRegex: urls.summaryRouteUrlRegex,
expectedTextSelector: selectors.descriptorRouteSubtitle,
});
}); });
describe.skip('Received pop-ups', () => { describe('Agency route pop-ups', () => {
it('Should redirect to invoice in summary from the received descriptor pop-up', () => { it('Should redirect to the agency route summary from the agency route descriptor pop-up', () => {
cy.get(selectors.received).click(); cy.checkRedirectionFromPopUp({
cy.validateContent(selectors.descriptorTitle, data.reference); selectorToClick: selectors.agencyRoute,
cy.get(selectors.descriptorGoToSummaryBtn).click(); steps: [selectors.descriptorGoToSummaryBtn],
cy.get(selectors.descriptorHeader).should('contain', data.supplier); expectedUrlRegex: urls.summaryAgencyUrlRegex,
cy.url().should('include', summaryUrl); expectedTextSelector: selectors.descriptorAgencyAndSupplierTitle,
});
});
it('Should redirect to the agency route summary from summary pop-up from the agency route descriptor pop-up', () => {
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.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.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.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', () => { it('Should redirect to the invoiceIn summary from summary pop-up from the received descriptor pop-up', () => {
cy.get(selectors.received).click(); cy.checkRedirectionFromPopUp({
cy.validateContent(selectors.descriptorTitle, data.reference); selectorToClick: selectors.received,
cy.get(selectors.summaryPopupBtn).click(); steps: [
cy.get(selectors.descriptorHeader).should('contain', data.supplier); selectors.descriptorOpenSummaryBtn,
cy.get(selectors.summaryGoToSummaryBtn).click(); selectors.summaryGoToSummaryBtn,
cy.get(selectors.descriptorHeader).should('contain', data.supplier); ],
cy.url().should('include', summaryUrl); expectedUrlRegex: urls.summaryInvoiceInUrlRegex,
expectedTextSelector: selectors.descriptorInvoiceInTitle,
});
}); });
}); });
describe('Autonomous pop-ups', () => { describe('Autonomous pop-ups', () => {
it('Should redirect to the supplier summary from the received descriptor pop-up', () => { it('Should redirect to the supplier summary from the received descriptor pop-up', () => {
cy.get(selectors.autonomous).click(); cy.checkRedirectionFromPopUp({
cy.validateContent(selectors.descriptorTitle, data.supplier); selectorToClick: selectors.autonomous,
cy.get(selectors.descriptorGoToSummaryBtn).click(); steps: [selectors.descriptorGoToSummaryBtn],
cy.get(selectors.summaryHeader).should('contain', data.supplier); expectedUrlRegex: urls.summarySupplierUrlRegex,
cy.url().should('include', summaryUrl); expectedTextSelector: selectors.descriptorAgencyAndSupplierTitle,
});
}); });
it('Should redirect to the supplier summary from summary pop-up from the autonomous descriptor pop-up', () => { it('Should redirect to the supplier summary from summary pop-up from the autonomous descriptor pop-up', () => {
cy.get(selectors.autonomous).click(); cy.checkRedirectionFromPopUp({
cy.get(selectors.descriptorTitle).should('contain', data.supplier); selectorToClick: selectors.autonomous,
cy.get(selectors.summaryPopupBtn).click(); steps: [
cy.get(selectors.summaryHeader).should('contain', data.supplier); selectors.descriptorOpenSummaryBtn,
cy.get(selectors.summaryGoToSummaryBtn).click(); selectors.summaryGoToSummaryBtn,
cy.get(selectors.summaryHeader).should('contain', data.supplier); ],
cy.url().should('include', summaryUrl); expectedUrlRegex: urls.summarySupplierUrlRegex,
expectedTextSelector: selectors.descriptorAgencyAndSupplierTitle,
});
}); });
}); });
describe('Route pop-ups', () => { describe('Route pop-ups', () => {
it('Should redirect to the summary from the route summary pop-up', () => { it('Should redirect to the summary from the route summary pop-up', () => {
cy.dataCy(selectors.summaryIcon).first().click(); cy.get(selectors.routeId)
cy.get(selectors.summaryHeader).should('contain', data.route); .invoke('text')
cy.get(selectors.summaryGoToSummaryBtn).click(); .then((routeId) => {
cy.get(selectors.summaryHeader).should('contain', data.route); routeId = routeId.trim();
cy.url().should('include', summaryUrl); cy.dataCy(selectors.summaryIcon).first().click();
cy.get(selectors.summaryGoToSummaryBtn).click();
cy.url().should('match', urls.summaryRouteUrlRegex);
cy.containContent(selectors.descriptorRouteSubtitle, routeId);
});
}); });
}); });
}); });

View File

@ -69,7 +69,8 @@ describe.skip('Route extended list', () => {
.type(`{selectall}{backspace}${value}`); .type(`{selectall}{backspace}${value}`);
break; break;
case 'checkbox': case 'checkbox':
cy.get(selector).should('be.visible').click().click(); cy.get(selector).should('be.visible').click()
cy.get(selector).click();
jtubau marked this conversation as resolved
Review

Esto porque? Tampoco lo veía bien antes pero porque haces click 2 veces? para marcar y desmarcar??

Esto porque? Tampoco lo veía bien antes pero porque haces click 2 veces? para marcar y desmarcar??
break; break;
} }
} }

View File

@ -0,0 +1,147 @@
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',
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',
warehouseSelect: 'Warehouse_select',
typeSelect: 'Type_select',
fileInput: 'VnDms_inputFile',
importBtn: '[data-cy="importBtn"]',
addBtn: '[data-cy="addButton"]',
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: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');
cy.visit(`/#/route/vehicle/1/dms`);
});
it('should display vehicle DMS', () => {
cy.get('.q-table')
.children()
.should('be.visible')
.should('have.length.greaterThan', 0);
});
it.skip('Should download DMS', () => {
const fileName = '11.jpg';
cy.intercept('GET', /\/api\/dms\/11\/downloadFile/).as('download');
cy.get(selectors.lastRowDownloadBtn).click();
cy.wait('@download').then((interception) => {
expect(interception.response.statusCode).to.equal(200);
expect(interception.response.headers['content-disposition']).to.contain(
fileName,
);
});
});
it('Should create new DMS', () => {
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' },
};
const formSelectors = {
actionBtn: selectors.importBtn,
selectorContentToCheck: selectors.lastRowReference,
saveFormBtn: selectors.saveFormBtn,
};
cy.testDmsAction('import', formSelectors, data, 'Data saved', '1');
});
it('Should edit DMS', () => {
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', () => {
const formSelectors = {
actionBtn: selectors.lastRowDeleteBtn,
selectorContentToCheck: selectors.lastRowReference,
};
cy.testDmsAction(
'delete',
formSelectors,
null,
'Data deleted',
'Vehicle:3333-BAT',
);
});
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,
});
});
});
});

View File

@ -635,3 +635,41 @@ 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);
});
},
);
Cypress.Commands.add('testDmsAction', (action, selectors, data, message, content) => {
cy.get(selectors.actionBtn).click();
if (action === 'create') {
cy.dataCy(selectors.fileInput).selectFile('test/cypress/fixtures/image.jpg', {
force: true,
});
}
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);
});