#8442 - createVehicleDms #1614

Open
jtubau wants to merge 44 commits from 8422-createVehicleDms into dev
15 changed files with 468 additions and 68 deletions

View File

@ -44,6 +44,7 @@ export default defineConfig({
supportFile: 'test/cypress/support/index.js',
videosFolder: 'test/cypress/videos',
downloadsFolder: 'test/cypress/downloads',
tmpUploadFolder: 'test/cypress/storage/tmp/dms',
jtubau marked this conversation as resolved Outdated

@alexm das el ok?

@alexm das el ok?
Outdated
Review

@jorgep No, diria que hay que usar este path: test/cypress/storage/tmp/dms esta dentro de lilium

@jorgep No, diria que hay que usar este path: `test/cypress/storage/tmp/dms` esta dentro de lilium
video: false,
specPattern: 'test/cypress/integration/**/*.spec.js',
experimentalRunAllSpecs: true,

View File

@ -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({
@ -83,11 +85,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);
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');
jtubau marked this conversation as resolved Outdated

Muestra notificación al usuario correctamente no?

Muestra notificación al usuario correctamente no?
delete dms.value.files;
return response;
} catch (e) {
throw e;
jtubau marked this conversation as resolved Outdated

No puedes usar throw e y ya está?

No puedes usar throw e y ya está?
}
}
function defaultData() {
@ -208,7 +215,7 @@ function addDefaultData(data) {
}
</style>
<i18n>
en:
en:
contentTypesInfo: Allowed file types {allowedContentTypes}
EntryDmsDescription: Reference {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 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({});
@ -88,7 +90,6 @@ const dmsFilter = {
],
},
},
where: { [$props.filter]: route.params.id },
};
const columns = computed(() => [
@ -258,9 +259,16 @@ 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);
try {
jtubau marked this conversation as resolved Outdated

Si falla el post, mostrarás la notificación igualmente, trycatch para no mostrar la notificación si falla.

Si falla el post, mostrarás la notificación igualmente, trycatch para no mostrar la notificación si falla.
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) {
throw e;
jtubau marked this conversation as resolved Outdated

throw e?

throw e?
}
});
}
@ -298,7 +306,9 @@ 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
@on-fetch="setData"
>

View File

@ -161,6 +161,9 @@ globals:
department: Department
noData: No data available
vehicle: Vehicle
jtubau marked this conversation as resolved Outdated

Seguro que es la traducción más correcta? Lo digo porque en español estás diciendo "introduzca"

Seguro que es la traducción más correcta? Lo digo porque en español estás diciendo "introduzca"
selectDocumentId: Select document id
document: Document
import: Import from existing
pageTitles:
logIn: Login
addressEdit: Update address

View File

@ -165,6 +165,9 @@ globals:
noData: Datos no disponibles
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

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;
jtubau marked this conversation as resolved Outdated

throw 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:
vehicleTypeFk: Type
vehicleStateFk: State
errors:
documentIdEmpty: The document identifier can't be empty

View File

@ -18,3 +18,5 @@ vehicle:
params:
vehicleTypeFk: Tipo
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;
emit('onDataSaved');
} catch (e) {
throw new Error(e.message);
throw e;
}
};
</script>
@ -49,7 +49,7 @@ const importDms = async () => {
<FormModelPopup
url-create="genera"
model="DmsImport"
:title="t('Select document id')"
:title="t('globals.selectDocumentId')"
:form-initial-data="{}"
:save-fn="importDms"
>
@ -70,7 +70,6 @@ const importDms = async () => {
<i18n>
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
</i18n>

View File

@ -166,7 +166,11 @@ const vehicleCard = {
component: () => import('src/pages/Route/Vehicle/Card/VehicleCard.vue'),
redirect: { name: 'VehicleSummary' },
meta: {
menu: ['VehicleBasicData', 'VehicleNotes'],
menu: [
'VehicleBasicData',
'VehicleNotes',
'VehicleDms',
],
},
children: [
{
@ -195,7 +199,16 @@ const vehicleCard = {
icon: 'vn:notes',
},
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.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"]',
jtubau marked this conversation as resolved
Review

Si vas directo al dataCy no funciona?

Si vas directo al dataCy no funciona?
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(() => {
@ -47,7 +56,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,
@ -59,62 +68,120 @@ 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.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.checkRedirectionFromPopUp({
selectorToClick: selectors.agencyRoute,
steps: [selectors.descriptorGoToSummaryBtn],
jtubau marked this conversation as resolved Outdated

Veo mucha duplicidad en los tests de los popups, crea una fn que puedas reutilizar

Veo mucha duplicidad en los tests de los popups, crea una fn que puedas reutilizar
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.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 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.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();
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.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();
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.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();
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.checkRedirectionFromPopUp({
selectorToClick: selectors.autonomous,
steps: [
selectors.descriptorOpenSummaryBtn,
selectors.summaryGoToSummaryBtn,
],
expectedUrlRegex: urls.summarySupplierUrlRegex,
expectedTextSelector: selectors.descriptorAgencyAndSupplierTitle,
});
});
});
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);
});
});
});
});

View File

@ -69,7 +69,8 @@ describe.skip('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();
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;
}
}

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,
jtubau marked this conversation as resolved Outdated

Create, import, edit y delete son casi iguales, crea una fn para no duplicar código

Create, import, edit y delete son casi iguales, crea una fn para no duplicar código
};
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(
jtubau marked this conversation as resolved Outdated

Lo mismo que los popup del otro archivo de tests

Lo mismo que los popup del otro archivo de tests
'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

@ -619,3 +619,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);
});