#8442 - createVehicleDms #1614
|
@ -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
|
||||
video: false,
|
||||
specPattern: 'test/cypress/integration/**/*.spec.js',
|
||||
experimentalRunAllSpecs: true,
|
||||
|
|
|
@ -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
jorgep
commented
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
jorgep
commented
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}
|
||||
|
|
|
@ -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
jorgep
commented
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
jorgep
commented
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"
|
||||
>
|
||||
|
|
|
@ -161,6 +161,9 @@ globals:
|
|||
department: Department
|
||||
noData: No data available
|
||||
vehicle: Vehicle
|
||||
jtubau marked this conversation as resolved
Outdated
jorgep
commented
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
jorgep
commented
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
jorgep
commented
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>
|
|
@ -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>
|
|
@ -18,3 +18,5 @@ vehicle:
|
|||
params:
|
||||
vehicleTypeFk: Type
|
||||
vehicleStateFk: State
|
||||
errors:
|
||||
documentIdEmpty: The document identifier can't be empty
|
||||
|
|
|
@ -18,3 +18,5 @@ vehicle:
|
|||
params:
|
||||
vehicleTypeFk: Tipo
|
||||
vehicleStateFk: Estado
|
||||
errors:
|
||||
documentIdEmpty: El número de documento no puede estar vacío
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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'),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
|
|
@ -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
jorgep
commented
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
jorgep
commented
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);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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
jorgep
commented
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
jorgep
commented
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
jorgep
commented
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,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
@alexm das el ok?
@jorgep No, diria que hay que usar este path:
test/cypress/storage/tmp/dms
esta dentro de lilium