forked from verdnatura/salix-front
feat: refs #7220 ok FormModel
This commit is contained in:
parent
3a04fc5029
commit
e49a91255f
|
@ -4,6 +4,9 @@ const {
|
|||
} = require('@quasar/quasar-app-extension-testing-e2e-cypress/cct-dev-server');
|
||||
|
||||
module.exports = defineConfig({
|
||||
env: {
|
||||
baseUrl: 'http://localhost:9000/',
|
||||
},
|
||||
e2e: {
|
||||
baseUrl: 'http://localhost:9000/',
|
||||
experimentalStudio: true,
|
||||
|
@ -33,7 +36,10 @@ module.exports = defineConfig({
|
|||
indexHtmlFile: 'test/cypress/support/component-index.html',
|
||||
supportFile: 'test/cypress/support/component.js',
|
||||
specPattern: 'test/cypress/components/**/*.spec.js',
|
||||
devServer: injectQuasarDevServerConfig(),
|
||||
devServer: {
|
||||
framework: 'quasar',
|
||||
bundler: 'vite',
|
||||
},
|
||||
setupNodeEvents(on, config) {
|
||||
// implement node event listeners here
|
||||
on('after:spec', (results) => {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { ref } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import { ref } from 'vue';
|
||||
|
||||
export const useArrayDataStore = defineStore('arrayDataStore', () => {
|
||||
const state = ref({});
|
||||
|
||||
const defaultOpts = {
|
||||
filter: {},
|
||||
userFilter: {},
|
||||
|
@ -24,7 +25,7 @@ export const useArrayDataStore = defineStore('arrayDataStore', () => {
|
|||
}
|
||||
|
||||
function set(key) {
|
||||
state.value[key] = getDefaultState();
|
||||
state.value[key] = getDefaultState(); // Ahora asigna el estado a la clave 'key'
|
||||
}
|
||||
|
||||
function clear(key) {
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
import { setActivePinia, createPinia } from 'pinia';
|
||||
import { useArrayDataStore } from './useArrayDataStore';
|
||||
|
||||
describe('useArrayDataStore', () => {
|
||||
beforeEach(() => {
|
||||
setActivePinia(createPinia());
|
||||
});
|
||||
|
||||
it('should initialize isLoading to false', () => {
|
||||
const store = useArrayDataStore();
|
||||
store.set('testKey');
|
||||
expect(store.get('testKey').isLoading).toBe(false);
|
||||
});
|
||||
|
||||
it('should reset isLoading to false', () => {
|
||||
const store = useArrayDataStore();
|
||||
store.set('testKey');
|
||||
store.get('testKey').isLoading = true;
|
||||
store.reset('testKey', ['isLoading']);
|
||||
expect(store.get('testKey').isLoading).toBe(false);
|
||||
});
|
||||
});
|
|
@ -1,31 +1,34 @@
|
|||
import { createTestingPinia } from '@pinia/testing';
|
||||
import axios from 'axios';
|
||||
import { setActivePinia } from 'pinia';
|
||||
import { createPinia } from 'pinia';
|
||||
import CreateBankEntityForm from 'src/components/CreateBankEntityForm.vue';
|
||||
import { useArrayData } from 'src/composables/useArrayData';
|
||||
import { useArrayDataStore } from 'src/stores/useArrayDataStore';
|
||||
|
||||
// import { useRouter } from 'vue-router';
|
||||
import { useRouter } from 'vue-router';
|
||||
// import vueRouter from 'vue-router';
|
||||
describe('<CreateBankEntityForm />', () => {
|
||||
const mockApiResponse = { results: [{ id: 1, name: 'Test' }] };
|
||||
const arrayDataStore = useArrayDataStore();
|
||||
// const arrayDataStore = useArrayDataStore();
|
||||
const mockStoreData = { filter: {}, userFilter: {}, userParams: {}, url: 'mockUrl' };
|
||||
|
||||
let store, arrayData;
|
||||
before(() => {
|
||||
cy.login('developer');
|
||||
// cy.stub(arrayDataStore, 'get').callsFake(() => 'asd');
|
||||
|
||||
cy.stub(arrayDataStore, 'get')
|
||||
.callsFake((e, fn) => (e = fn))
|
||||
.as('update');
|
||||
const arrayData = useArrayData('ArrayData', { url: 'mockUrl' });
|
||||
// cy.stub(arrayDataStore, 'get')
|
||||
// .callsFake((e, fn) => (e = fn))
|
||||
// .as('update');
|
||||
// const arrayData = useArrayData('ArrayData', { url: 'mockUrl' });
|
||||
|
||||
cy.stub(arrayData).callsFake(() => ({
|
||||
userParams: {},
|
||||
userFilter: {},
|
||||
order: {},
|
||||
searchUrl: 'searchUrl',
|
||||
}));
|
||||
// cy.stub(vueRouter, 'useRouter').callsFake(() => ({
|
||||
// cy.stub(arrayData).callsFake(() => ({
|
||||
// userParams: {},
|
||||
// userFilter: {},
|
||||
// order: {},
|
||||
// searchUrl: 'searchUrl',
|
||||
// }));
|
||||
// cy.stub(vueRouter).callsFake(() => ({
|
||||
// push: () => {},
|
||||
// replace: () => {},
|
||||
// currentRoute: {
|
||||
|
@ -38,14 +41,69 @@ describe('<CreateBankEntityForm />', () => {
|
|||
// },
|
||||
// },
|
||||
// }));
|
||||
Cypress.config('defaultCommandTimeout', 500);
|
||||
|
||||
// const spy = cy.spy();
|
||||
// createTestingPinia({
|
||||
// createSpy: () => spy,
|
||||
// });
|
||||
|
||||
// // one way:
|
||||
// store = useArrayDataStore();
|
||||
|
||||
// // another way with the same error:
|
||||
// useArrayDataStore(
|
||||
// createTestingPinia({
|
||||
// createSpy: () => spy,
|
||||
// initialState: {
|
||||
// state: { ArrayData: cy.spy() },
|
||||
// },
|
||||
// })
|
||||
// );
|
||||
|
||||
// cy.stub(useArrayDataStore, 'get').callsFake(() => cy.spy());
|
||||
// cy.stub(useArrayData, 'get').callsFake(() => store);
|
||||
// arrayData = useArrayData('ArrayData', { url: 'mockUrl' });
|
||||
});
|
||||
beforeEach(() => {
|
||||
// cy._mount(CreateBankEntityForm, {
|
||||
// global: {
|
||||
// plugins: [store],
|
||||
// },
|
||||
// });
|
||||
// Stub del método get del store
|
||||
// cy.spy(useRouter(), 'replace');
|
||||
// cy.spy(useRouter(), 'push');
|
||||
});
|
||||
|
||||
it('should intercept axios.get for a specific route', () => {
|
||||
// Configura Pinia y la store
|
||||
const pinia = createPinia();
|
||||
setActivePinia(pinia);
|
||||
const arrayDataStore = useArrayDataStore();
|
||||
cy.stub(arrayDataStore, 'get').returns(mockStoreData).as('getStub');
|
||||
|
||||
cy.stub(arrayData, 'arrayDataStore').callsFake(() => store);
|
||||
cy.createWrapper(CreateBankEntityForm);
|
||||
// Obtén la instancia de la store de Pinia
|
||||
// const store = useArrayDataStore();
|
||||
// Asegúrate de que el método `set` esté disponible
|
||||
// Usar cy.stub() para espiar la función set y personalizar su comportamiento
|
||||
// cy.stub(store, 'set').callsFake(() => {
|
||||
// console.log('store.set fue llamado');
|
||||
// // Simular que set se ejecuta correctamente
|
||||
// store.get('key').data = 'Fake Data';
|
||||
// });
|
||||
// expect(store.set).to.be.a('function');
|
||||
// store.set('key'); // Inicializar el estado con `set`
|
||||
// store.get('key').data = 'Test Data'; // Simular que tenemos datos
|
||||
// // Simula que agregamos usuarios a la store
|
||||
// store.setUsers([
|
||||
// { id: 1, name: 'John Doe' },
|
||||
// { id: 2, name: 'Jane Doe' },
|
||||
// ]);
|
||||
});
|
||||
xit('should intercept axios.get for a specific route', () => {
|
||||
// Intercepta la llamada a axios.get para una ruta específica
|
||||
cy.stub(axios, 'get')
|
||||
.callsFake((url, params) => {
|
||||
|
@ -58,7 +116,11 @@ describe('<CreateBankEntityForm />', () => {
|
|||
.as('axiosStub');
|
||||
|
||||
const onFetchSpy = cy.spy().as('onFetchSpy');
|
||||
|
||||
// Configura Pinia y la store
|
||||
const pinia = createPinia();
|
||||
setActivePinia(pinia);
|
||||
const arrayDataStore = useArrayDataStore();
|
||||
cy.stub(arrayDataStore, 'get').returns(mockStoreData).as('getStub');
|
||||
cy.createWrapper(CreateBankEntityForm, {
|
||||
props: {
|
||||
showEntityField: true,
|
||||
|
|
|
@ -1,8 +1,142 @@
|
|||
import { Notify } from 'quasar';
|
||||
import FormModel from 'src/components/FormModel.vue';
|
||||
// import useNotify from 'src/composables/useNotify';
|
||||
import { useState } from 'src/composables/useState';
|
||||
import { useStateStore } from 'src/stores/useStateStore';
|
||||
|
||||
describe.skip('<FormModel />', () => {
|
||||
it('TODO: boilerplate', () => {
|
||||
// see: https://on.cypress.io/mounting-vue
|
||||
cy.createWrapper(FormModel, { props: {} });
|
||||
describe('<FormModel />', () => {
|
||||
let piniaOptions = null;
|
||||
let saveSpy, notifySpy, component, wrapper;
|
||||
beforeEach(() => {
|
||||
piniaOptions = {
|
||||
stubActions: false,
|
||||
createSpy: cy.spy, // Use Cypress spy function
|
||||
};
|
||||
const state = useState();
|
||||
const stateStore = useStateStore();
|
||||
cy.stub(stateStore, 'isSubToolbarShown').returns(true).as('isSubToolbarShown');
|
||||
state.set('testModel', { name: 'Test', age: 30 });
|
||||
const props = {
|
||||
url: '',
|
||||
model: 'testModel',
|
||||
filter: {},
|
||||
urlUpdate: '',
|
||||
urlCreate: '/api/test/create',
|
||||
defaultActions: true,
|
||||
defaultButtons: {},
|
||||
autoLoad: false,
|
||||
formInitialData: {},
|
||||
observeFormChanges: true,
|
||||
mapper: null,
|
||||
clearStoreOnUnmount: true,
|
||||
saveFn: null,
|
||||
goTo: '',
|
||||
reload: false,
|
||||
defaultTrim: true,
|
||||
};
|
||||
cy.mount(FormModel, {
|
||||
piniaOptions,
|
||||
props,
|
||||
slots: {
|
||||
form: `<template #form="{ data, validate, filter }">
|
||||
<input data-cy="name" v-model="data.name" label="name" />
|
||||
<input data-cy="age" v-model="data.age" label="age" type="number" />
|
||||
<button type="submit">Save</button>
|
||||
</template>`,
|
||||
moreActions: `<template #moreActions>
|
||||
<button @click="customAction">Custom Action</button>
|
||||
</template>`,
|
||||
},
|
||||
}).then(({ component: cmp, wrapper: wpr }) => {
|
||||
component = cmp;
|
||||
wrapper = wpr;
|
||||
saveSpy = cy.spy(component, 'save').as('saveSpy');
|
||||
notifySpy = cy.spy(Notify, 'create').as('notifySpy');
|
||||
});
|
||||
});
|
||||
it('should mount the component', () => {
|
||||
cy.get('#formModel').should('exist');
|
||||
});
|
||||
|
||||
it('should call the save method when the save button is clicked without changes', () => {
|
||||
cy.get('#formModel').should('exist');
|
||||
cy.get('button').contains('Save').click();
|
||||
cy.get('@saveSpy').should('not.have.been.called');
|
||||
cy.get('@notifySpy').should((spy) => {
|
||||
expect(spy).to.have.been.calledWith({
|
||||
message: 'No changes to save',
|
||||
type: 'negative',
|
||||
icon: 'error',
|
||||
});
|
||||
});
|
||||
});
|
||||
it('should call the save method when the save button is clicked with changes', () => {
|
||||
cy.get('#formModel').should('exist');
|
||||
cy.get('[data-cy="name"]').type('John Doe');
|
||||
cy.get('button').contains('Save').click();
|
||||
cy.get('@saveSpy').should('not.have.been.called');
|
||||
cy.get('@notifySpy').should((spy) => {
|
||||
const [args] = spy.getCall(0)?.args || [];
|
||||
expect(args.type).to.equal('negative');
|
||||
expect(args.icon).to.equal('error');
|
||||
expect(args.message).not.to.equal('No changes to save');
|
||||
});
|
||||
});
|
||||
/*
|
||||
it('should display the confirmation dialog on route leave with unsaved changes', () => {
|
||||
// Simulate form change
|
||||
cy.get('#formModel').then((form) => {
|
||||
form[0].__vue__.formData.name = 'Changed';
|
||||
});
|
||||
|
||||
// Attempt to navigate away
|
||||
cy.get('.q-dialog').should('be.visible');
|
||||
cy.get('.q-dialog .q-dialog__title').should(
|
||||
'contain',
|
||||
'globals.unsavedPopup.title'
|
||||
);
|
||||
});
|
||||
|
||||
it('should call save method on form submit', async () => {
|
||||
const saveSpy = cy.spy(formModel.value, 'save');
|
||||
await formModel.value.$refs.myForm.trigger('submit');
|
||||
expect(saveSpy).to.have.been.called;
|
||||
});
|
||||
|
||||
it('should reset the form data', async () => {
|
||||
formModel.value.formData.name = 'Changed';
|
||||
await formModel.value.reset();
|
||||
expect(formModel.value.formData.name).toBe('Test');
|
||||
});
|
||||
|
||||
it('should show loading indicator when saving', async () => {
|
||||
formModel.value.isLoading = true;
|
||||
await nextTick();
|
||||
expect(wrapper.findComponent({ name: 'QInnerLoading' }).props('showing')).toBe(true);
|
||||
});
|
||||
|
||||
it('should render form slot content', () => {
|
||||
expect(wrapper.find('input').exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('should update form data through slot inputs', async () => {
|
||||
const nameInput = wrapper.find('input[type="text"]');
|
||||
const ageInput = wrapper.find('input[type="number"]');
|
||||
|
||||
await nameInput.setValue('Updated Name');
|
||||
await ageInput.setValue(25);
|
||||
|
||||
expect(formModel.value.formData.name).toBe('Updated Name');
|
||||
expect(formModel.value.formData.age).toBe(25);
|
||||
});
|
||||
|
||||
it('should render moreActions slot content', () => {
|
||||
expect(wrapper.find('button').exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('should call custom action on button click', async () => {
|
||||
const customActionSpy = cy.spy(formModel.value, 'customAction');
|
||||
await wrapper.find('button').trigger('click');
|
||||
expect(customActionSpy).to.have.been.called;
|
||||
});*/
|
||||
});
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
import { installQuasarPlugin } from '@quasar/quasar-app-extension-testing-e2e-cypress';
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
import { mount } from 'cypress/vue';
|
||||
import { i18n } from 'src/boot/i18n';
|
||||
import { Quasar } from 'quasar';
|
||||
import { createPinia } from 'pinia';
|
||||
const pinia = createTestingPinia({ createSpy: () => {}, stubActions: false });
|
||||
|
||||
import axios from 'axios';
|
||||
installQuasarPlugin({ plugins: { Dialog, Notify } });
|
||||
// setActivePinia(pinia);
|
||||
// // Run this code before each *test*.
|
||||
// beforeEach(() => {
|
||||
// // New Pinia
|
||||
|
@ -13,10 +17,72 @@ const pinia = createTestingPinia({ createSpy: () => {}, stubActions: false });
|
|||
// setActivePinia(pinia);
|
||||
// });
|
||||
|
||||
function createWrapper(component, options) {
|
||||
// Crear un comando personalizado para montar componentes con Pinia
|
||||
// Cypress.Commands.add('mountWithPinia', (component, options = {}) => {
|
||||
// const pinia = createPinia();
|
||||
// options.global = options.global || {};
|
||||
// options.global.plugins = [Quasar, createPinia()]; // Incluye Quasar y Pinia
|
||||
// return mount(component, options);
|
||||
// });
|
||||
|
||||
// Registrar Quasar y sus componentes
|
||||
|
||||
setActivePinia(createPinia()); // Ensure Pinia is active
|
||||
axios.defaults.baseURL = Cypress.env('baseUrl');
|
||||
Cypress.Commands.add('mount', (component, options = {}) => {
|
||||
const pinia = createTestingPinia(options.piniaOptions);
|
||||
const components = options.global?.components || {};
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: [],
|
||||
});
|
||||
const defaultOptions = {
|
||||
global: {
|
||||
plugins: [Quasar, i18n, pinia],
|
||||
mocks: {
|
||||
t: (tKey) => tKey,
|
||||
$t: (tKey) => tKey,
|
||||
|
||||
$axios: axios, // Añadir axios como un mock global
|
||||
},
|
||||
plugins: [
|
||||
Quasar,
|
||||
(app) => {
|
||||
app.use(router);
|
||||
app.use(i18n);
|
||||
app.use(pinia);
|
||||
},
|
||||
], // Añade Quasar y Pinia como plugins globales
|
||||
},
|
||||
};
|
||||
const mountOptions = Object.assign({}, defaultOptions, options);
|
||||
|
||||
if (options.global) {
|
||||
mountOptions.global.plugins = defaultOptions.global.plugins;
|
||||
}
|
||||
|
||||
return mount(component, mountOptions);
|
||||
|
||||
// options.global.plugins.push({
|
||||
// install(app) {
|
||||
// app.use(i18n);
|
||||
// app.use(router);
|
||||
// // app.use(arrayDataStore);
|
||||
// },
|
||||
// });
|
||||
// const wrapper = mount(component, mountOptions);
|
||||
// const { vm } = wrapper;
|
||||
// return wrapper;
|
||||
});
|
||||
function createWrapper(component, options = {}) {
|
||||
const defaultOptions = {
|
||||
global: {
|
||||
plugins: [
|
||||
Quasar,
|
||||
i18n,
|
||||
createTestingPinia({
|
||||
createSpy: () => cy.spy(),
|
||||
}),
|
||||
],
|
||||
stubs: [
|
||||
'router-link',
|
||||
'router-view',
|
||||
|
@ -36,9 +102,13 @@ function createWrapper(component, options) {
|
|||
$t: (tKey) => tKey,
|
||||
},
|
||||
};
|
||||
|
||||
const arrayDataStore = useArrayDataStore();
|
||||
const mountOptions = Object.assign({}, defaultOptions);
|
||||
|
||||
options.global = options?.global || {};
|
||||
options.global.plugins = options.global?.plugins || [];
|
||||
// options.global.plugins.push([Quasar, {}]);
|
||||
// options.global.plugins.push([i18n]);
|
||||
// options.global.plugins.push(createTestingPinia());
|
||||
if (options instanceof Object) {
|
||||
Object.assign(mountOptions, options);
|
||||
|
||||
|
@ -57,8 +127,10 @@ function createWrapper(component, options) {
|
|||
install(app) {
|
||||
app.use(i18n);
|
||||
app.use(options.router);
|
||||
// app.use(arrayDataStore);
|
||||
},
|
||||
});
|
||||
|
||||
const wrapper = mount(component, mountOptions);
|
||||
const vm = wrapper.vm;
|
||||
|
||||
|
@ -77,8 +149,7 @@ Cypress.Commands.add('createWrapper', createWrapper);
|
|||
Cypress.Commands.add('_vnMount', (component, options = {}) => {
|
||||
const globalConfig = {
|
||||
global: {
|
||||
stubs: ['router-view', 'vue-i18n'],
|
||||
plugins: [Quasar, i18n, pinia],
|
||||
plugins: [Quasar, i18n],
|
||||
mocks: { t: (key) => key },
|
||||
},
|
||||
};
|
||||
|
@ -115,6 +186,11 @@ Cypress.Commands.add('_vnMount', (component, options = {}) => {
|
|||
import 'quasar/dist/quasar.css';
|
||||
import { createRouter } from 'vue-router';
|
||||
import { createMemoryHistory } from 'vue-router';
|
||||
import { setActivePinia } from 'pinia';
|
||||
import { useArrayDataStore } from 'src/stores/useArrayDataStore';
|
||||
import { createWebHistory } from 'vue-router';
|
||||
import { Dialog } from 'quasar';
|
||||
import { Notify } from 'quasar';
|
||||
Cypress.Commands.add('vue', () => {
|
||||
return cy.wrap(Cypress.vueWrapper);
|
||||
});
|
||||
|
@ -152,3 +228,12 @@ Cypress.Commands.add('login', (user) => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Define el comando personalizado
|
||||
Cypress.Commands.add('stubUseArrayDataStore', (stubData = {}) => {
|
||||
const arrayDataStore = useArrayDataStore();
|
||||
if (arrayDataStore.get.restore) {
|
||||
arrayDataStore.get.restore();
|
||||
}
|
||||
cy.stub(arrayDataStore, 'get').returns(stubData).as('getStub');
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue