diff --git a/.eslintrc.js b/.eslintrc.js index 09dc09c1e..c8bdecb1a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -64,7 +64,7 @@ module.exports = { }, overrides: [ { - files: ['test/cypress/**/*.spec.{js,ts}'], + files: ['test/cypress/**/*.*'], extends: [ // Add Cypress-specific lint rules, globals and Cypress plugin // See https://github.com/cypress-io/eslint-plugin-cypress#rules diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json new file mode 100644 index 000000000..02e425437 --- /dev/null +++ b/cypress/fixtures/example.json @@ -0,0 +1,5 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" +} diff --git a/cypress/support/commands.js b/cypress/support/commands.js new file mode 100644 index 000000000..66ea16ef0 --- /dev/null +++ b/cypress/support/commands.js @@ -0,0 +1,25 @@ +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add('login', (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) \ No newline at end of file diff --git a/src/components/CrudModel.vue b/src/components/CrudModel.vue index 6b8c577a0..280282ffd 100644 --- a/src/components/CrudModel.vue +++ b/src/components/CrudModel.vue @@ -285,8 +285,8 @@ function isEmpty(obj) { - - + + (hasChanges.value = true)); @@ -82,13 +82,14 @@ async function save() { isLoading.value = true; await axios.patch($props.urlUpdate || $props.url, formData.value); - originalData.value = formData.value; + originalData.value = JSON.parse(JSON.stringify(formData.value)); hasChanges.value = false; isLoading.value = false; } function reset() { state.set($props.model, originalData.value); + watch(formData.value, () => (hasChanges.value = true)); hasChanges.value = false; } // eslint-disable-next-line vue/no-dupe-keys @@ -120,7 +121,7 @@ watch(formUrl, async () => { - +
diff --git a/src/pages/Claim/Card/ClaimCard.vue b/src/pages/Claim/Card/ClaimCard.vue index 142657ba5..d52b918e1 100644 --- a/src/pages/Claim/Card/ClaimCard.vue +++ b/src/pages/Claim/Card/ClaimCard.vue @@ -29,7 +29,6 @@ const claimSections = [ let salixUrl; onMounted(async () => { salixUrl = await getUrl(`claim/${entityId.value}`); - stateStore.setSubtoolbar(); }); diff --git a/src/stores/useStateStore.js b/src/stores/useStateStore.js index cf259a767..74b65e71f 100644 --- a/src/stores/useStateStore.js +++ b/src/stores/useStateStore.js @@ -5,7 +5,6 @@ export const useStateStore = defineStore('stateStore', () => { const isMounted = ref(false); const leftDrawer = ref(false); const rightDrawer = ref(false); - const subToolbar = ref(false); function toggleLeftDrawer() { leftDrawer.value = !leftDrawer.value; @@ -19,10 +18,6 @@ export const useStateStore = defineStore('stateStore', () => { isMounted.value = true; } - function setSubtoolbar() { - subToolbar.value = true; - } - function isHeaderMounted() { return isMounted.value; } @@ -36,7 +31,10 @@ export const useStateStore = defineStore('stateStore', () => { } function isSubToolbarShown() { - return subToolbar.value; + return ( + !!document.querySelector('#st-data') && + !!document.querySelector('#st-actions') + ); } return { @@ -48,7 +46,6 @@ export const useStateStore = defineStore('stateStore', () => { toggleRightDrawer, isLeftDrawerShown, isRightDrawerShown, - setSubtoolbar, isSubToolbarShown, }; }); diff --git a/test/cypress/integration/claimDevelopment.spec.js b/test/cypress/integration/claimDevelopment.spec.js index ec41e92a3..f05710eea 100755 --- a/test/cypress/integration/claimDevelopment.spec.js +++ b/test/cypress/integration/claimDevelopment.spec.js @@ -1,55 +1,77 @@ /// -describe('ClaimPhoto', () => { +describe('ClaimDevelopment', () => { + const claimId = 1; + beforeEach(() => { - const claimId = 1; + cy.viewport(1920, 1080); cy.login('developer'); - cy.visit(`/#/claim/${claimId}/photos`); + cy.visit(`/#/claim/${claimId}/development`); }); - it('should add new file', () => { - cy.get('label > .q-btn').click(); - cy.get('label > .q-btn input').selectFile('test/cypress/fixtures/image.jpg', { - force: true, - }); - cy.get('.q-notification__message').should('have.text', 'Data saved'); - }); - - it('should add new file with drag and drop', () => { - cy.get('.container').selectFile('test/cypress/fixtures/image.jpg', { - action: 'drag-drop', - }); - cy.get('.q-notification__message').should('have.text', 'Data saved'); - }); - - it('should open first image dialog change to second and close', () => { + it('should reset line', () => { + cy.get('tbody > :nth-child(1) > :nth-child(2)').click(); + cy.selectOption('Novato'); + cy.get('[title="Reset"]').click(); cy.get( - ':nth-child(1) > .q-card > .q-img > .q-img__container > .q-img__image' - ).click(); - cy.get('.q-carousel__slide > .q-img > .q-img__container > .q-img__image').should( - 'be.visible' - ); - - cy.get('.q-carousel__control > .q-btn > .q-btn__content > .q-icon').click(); - - cy.get( - '.q-dialog__inner > .q-toolbar > .q-btn > .q-btn__content > .q-icon' - ).click(); - cy.get('.q-carousel__slide > .q-img > .q-img__container > .q-img__image').should( - 'not.be.visible' - ); + ':nth-child(1) > :nth-child(2) > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > .q-field__native > span' + ).should('have.text', 'Prisas'); }); - it('should remove third and fourth file', () => { - cy.get( - '.multimediaParent > :nth-child(3) > .q-btn > .q-btn__content > .q-icon' - ).click(); - cy.get('.q-btn--unelevated > .q-btn__content > .block').click(); - cy.get('.q-notification__message').should('have.text', 'Data deleted'); + it('should edit line', () => { + cy.get('tbody > :nth-child(1) > :nth-child(2)').click(); + cy.selectOption('Novato'); + cy.get('[title="Save"]').click(); + cy.visit(`/#/claim/${claimId}/development`); cy.get( - '.multimediaParent > :nth-child(3) > .q-btn > .q-btn__content > .q-icon' - ).click(); - cy.get('.q-btn--unelevated > .q-btn__content > .block').click(); - cy.get('.q-notification__message').should('have.text', 'Data deleted'); + ':nth-child(1) > :nth-child(2) > .q-field > .q-field__inner > .q-field__control > .q-field__control-container > .q-field__native > span' + ).should('have.text', 'Novato'); + + //Restart data + cy.get('tbody > :nth-child(1) > :nth-child(2)'); + cy.selectOption('Prisas'); + cy.get('[title="Save"]').click(); }); + + it('should add new line', () => { + //check third if row exist + cy.get('.q-page-sticky > div > .q-btn').click(); + cy.get('tbody > :nth-child(3)').should('exist'); + + //fill in data + const rowData = ['', '', '']; + cy.fillTableRow(3, rowData); + }); + + // it('should remove last line', () => { + // cy.get( + // ':nth-child(1) > .q-card > .q-img > .q-img__container > .q-img__image' + // ).click(); + // cy.get('.q-carousel__slide > .q-img > .q-img__container > .q-img__image').should( + // 'be.visible' + // ); + + // cy.get('.q-carousel__control > .q-btn > .q-btn__content > .q-icon').click(); + + // cy.get( + // '.q-dialog__inner > .q-toolbar > .q-btn > .q-btn__content > .q-icon' + // ).click(); + // cy.get('.q-carousel__slide > .q-img > .q-img__container > .q-img__image').should( + // 'not.be.visible' + // ); + // }); + + // it('should remove third and fourth file', () => { + // cy.get( + // '.multimediaParent > :nth-child(3) > .q-btn > .q-btn__content > .q-icon' + // ).click(); + // cy.get('.q-btn--unelevated > .q-btn__content > .block').click(); + // cy.get('.q-notification__message').should('have.text', 'Data deleted'); + + // cy.get( + // '.multimediaParent > :nth-child(3) > .q-btn > .q-btn__content > .q-icon' + // ).click(); + // cy.get('.q-btn--unelevated > .q-btn__content > .block').click(); + // cy.get('.q-notification__message').should('have.text', 'Data deleted'); + // }); }); diff --git a/test/cypress/support/commands.js b/test/cypress/support/commands.js index a3a61c423..eca5f6c8c 100755 --- a/test/cypress/support/commands.js +++ b/test/cypress/support/commands.js @@ -40,4 +40,71 @@ Cypress.Commands.add('login', (user) => { window.localStorage.setItem('token', response.body.token); }); }); + +Cypress.Commands.add('selectOption', (option) => { + //cy.visit('/#/login'); + cy.get('.q-item__label').then(() => { + cy.contains('.q-item__label', option).click(); + }); +}); + +// Cypress.Commands.add('fillRow', (row, options) => { +// //cy.visit('/#/login'); +// for (let [i, option] of options.entries()) { +// i++; +// console.log(i); +// const selector = `tbody > :nth-child(${row}) > :nth-child(${i})`; +// if (cy.get(selector).should('have.class', 'q-select')) +// cy.selectOption(selector, option); +// } +// }); +Cypress.Commands.add('fillTableRow', (rowNumber, data) => { + // Obtener todas las filas de la tabla + cy.get('table tbody tr').eq(rowNumber).as('currentRow'); + + // Iterar sobre cada dato en el array 'data' + data.forEach((value, index) => { + // Basándonos en el índice, encontramos la celda correspondiente y verificamos el tipo de input + cy.get('@currentRow') + .find('td') + .eq(index) + .find('input') + .invoke('attr', 'type') + .then((type) => { + switch (type) { + case 'text': + cy.get('@currentRow') + .find('td') + .eq(index) + .find('input[type="text"]') + .clear() + .type(value); + break; + + case 'checkbox': + if (value) { + // Puede adaptar esto según cómo represente los valores booleanos en su array 'data' + cy.get('@currentRow') + .find('td') + .eq(index) + .find('input[type="checkbox"]') + .check(); + } else { + cy.get('@currentRow') + .find('td') + .eq(index) + .find('input[type="checkbox"]') + .uncheck(); + } + break; + + // ... Puede agregar más casos para otros tipos de inputs según sea necesario + + default: + // Manejar cualquier otro tipo de input o agregar lógica de error aquí si es necesario + break; + } + }); + }); +}); // registerCommands(); diff --git a/test/vitest/__tests__/components/common/CrudModel.spec.js b/test/vitest/__tests__/components/common/CrudModel.spec.js index 6547437ca..518c3ad60 100644 --- a/test/vitest/__tests__/components/common/CrudModel.spec.js +++ b/test/vitest/__tests__/components/common/CrudModel.spec.js @@ -1,13 +1,16 @@ -import { createWrapper } from 'app/test/vitest/helper'; +import { createWrapper, axios } from 'app/test/vitest/helper'; import CrudModel from 'components/CrudModel.vue'; -import { vi, afterEach, beforeAll, describe, expect, it } from 'vitest'; +import { vi, afterEach, beforeAll, beforeEach, describe, expect, it } from 'vitest'; describe.only('CrudModel', () => { let vm; beforeAll(() => { vm = createWrapper(CrudModel, { global: { - stubs: ['VnPaginate', 'useState'], + stubs: ['vnPaginate', 'useState', 'arrayData', 'useStateStore'], + mocks: { + fetch: vi.fn(), + }, }, propsData: { dataRequired: { @@ -15,6 +18,15 @@ describe.only('CrudModel', () => { name: 'name', autoLoad: true, }, + dataKey: 'crudModelKey', + model: 'crudModel', + url: 'crudModelUrl', + }, + attrs: { + url: 'crudModelUrl', + dataKey: 'CustomerList', + order: 'id DESC', + limit: 3, }, }).vm; }); @@ -24,12 +36,26 @@ describe.only('CrudModel', () => { }); describe('insert()', () => { - it('should new element in list', () => { + it('should new element in list with index 0 if formData not has data', () => { + vi.mock('src/composables/useValidator', () => ({ + default: () => {}, + fetch: () => { + vi.fn(); + }, + })); + vi.spyOn(axios, 'get').mockResolvedValue({ + data: [ + { id: 1, name: 'Tony Stark' }, + { id: 2, name: 'Jessica Jones' }, + { id: 3, name: 'Bruce Wayne' }, + ], + }); + vm.state.set('crudModel', []); vm.insert(); - expect(vm.message).toEqual( - `A minimum amount of 50€ (VAT excluded) is required for your order ${orderId} of ${shipped} to receive it without additional shipping costs.` - ); + expect(vm.formData.length).toEqual(1); + expect(vm.formData[0].id).toEqual(1); + expect(vm.formData[0].$index).toEqual(0); }); }); }); diff --git a/test/vitest/helper.js b/test/vitest/helper.js index 8a6fb1415..186f4ee3a 100644 --- a/test/vitest/helper.js +++ b/test/vitest/helper.js @@ -64,6 +64,10 @@ export function createWrapper(component, options) { global: { plugins: [i18n, pinia], }, + mocks: { + t: (tKey) => tKey, + $t: (tKey) => tKey, + }, }; const mountOptions = Object.assign({}, defaultOptions); @@ -75,6 +79,7 @@ export function createWrapper(component, options) { mountOptions.global.plugins = defaultOptions.global.plugins; } } + console.log(mountOptions); const wrapper = mount(component, mountOptions); const vm = wrapper.vm;