test: fix test

This commit is contained in:
Javier Segarra 2025-05-15 14:08:39 +02:00
parent 3940ac3c82
commit f4171d8efa
12 changed files with 119 additions and 102 deletions

View File

@ -39,7 +39,7 @@ if (process.env.CI) {
export default defineConfig({ export default defineConfig({
e2e: { e2e: {
baseUrl: `http://${urlHost}:9000`, baseUrl: `http://${urlHost}:9000`,
experimentalStudio: false, experimentalStudio: true,
trashAssetsBeforeRuns: false, trashAssetsBeforeRuns: false,
defaultBrowser: 'chromium', defaultBrowser: 'chromium',
fixturesFolder: 'test/cypress/fixtures', fixturesFolder: 'test/cypress/fixtures',

View File

@ -1,11 +1,11 @@
import axios from 'axios'; import axios from 'axios';
export default async function (data, date) { export default async function (data, landed) {
const reducedData = data.reduce((acc, item) => { const reducedData = data.reduce((acc, item) => {
const existing = acc.find(({ ticketFk }) => ticketFk === item.id); const existing = acc.find(({ ticketFk }) => ticketFk === item.id);
if (existing) { if (existing) {
existing.sales.push(item.saleFk); existing.sales.push(item.saleFk);
} else { } else {
acc.push({ ticketFk: item.ticketFk, sales: [item.saleFk], date }); acc.push({ ticketFk: item.ticketFk, sales: [item.saleFk], landed });
} }
return acc; return acc;
}, []); }, []);

View File

@ -69,6 +69,8 @@ const showItemProposal = () => {
}) })
.onOk(itemProposalEvt); .onOk(itemProposalEvt);
}; };
const isButtonDisabled = computed(() => selectedRows.value.length !== 1);
</script> </script>
<template> <template>
@ -93,11 +95,7 @@ const showItemProposal = () => {
> >
<template #top-right> <template #top-right>
<QBtnGroup push class="q-mr-lg" style="column-gap: 1px"> <QBtnGroup push class="q-mr-lg" style="column-gap: 1px">
<QBtn <QBtn data-cy="transferLines" color="primary" :disable="isButtonDisabled">
data-cy="transferLines"
color="primary"
:disable="!(selectedRows.length === 1)"
>
<template #default> <template #default>
<QIcon name="vn:splitline" /> <QIcon name="vn:splitline" />
<QIcon name="vn:ticket" /> <QIcon name="vn:ticket" />
@ -118,7 +116,7 @@ const showItemProposal = () => {
<QBtn <QBtn
color="primary" color="primary"
@click="showItemProposal" @click="showItemProposal"
:disable="!(selectedRows.length === 1)" :disable="isButtonDisabled"
data-cy="itemProposal" data-cy="itemProposal"
> >
<QIcon name="import_export" class="rotate-90" /> <QIcon name="import_export" class="rotate-90" />
@ -129,7 +127,7 @@ const showItemProposal = () => {
<VnPopupProxy <VnPopupProxy
data-cy="changeItem" data-cy="changeItem"
icon="sync" icon="sync"
:disable="!(selectedRows.length === 1)" :disable="isButtonDisabled"
:tooltip="t('negative.detail.modal.changeItem.title')" :tooltip="t('negative.detail.modal.changeItem.title')"
> >
<template #extraIcon> <QIcon name="vn:item" /> </template> <template #extraIcon> <QIcon name="vn:item" /> </template>
@ -143,7 +141,7 @@ const showItemProposal = () => {
<VnPopupProxy <VnPopupProxy
data-cy="changeState" data-cy="changeState"
icon="sync" icon="sync"
:disable="!(selectedRows.length === 1)" :disable="isButtonDisabled"
:tooltip="t('negative.detail.modal.changeState.title')" :tooltip="t('negative.detail.modal.changeState.title')"
> >
<template #extraIcon> <QIcon name="vn:eye" /> </template> <template #extraIcon> <QIcon name="vn:eye" /> </template>
@ -157,7 +155,7 @@ const showItemProposal = () => {
<VnPopupProxy <VnPopupProxy
data-cy="changeQuantity" data-cy="changeQuantity"
icon="sync" icon="sync"
:disable="!(selectedRows.length === 1)" :disable="isButtonDisabled"
:tooltip="t('negative.detail.modal.changeQuantity.title')" :tooltip="t('negative.detail.modal.changeQuantity.title')"
@click="showChangeQuantityDialog = true" @click="showChangeQuantityDialog = true"
> >

View File

@ -41,6 +41,7 @@ const updateItem = async () => {
<QCardSection class="row items-center justify-center column items-stretch"> <QCardSection class="row items-center justify-center column items-stretch">
<span>{{ $t('negative.detail.modal.changeItem.title') }}</span> <span>{{ $t('negative.detail.modal.changeItem.title') }}</span>
<VnSelect <VnSelect
data-cy="New item_select"
url="Items/WithName" url="Items/WithName"
:fields="['id', 'name']" :fields="['id', 'name']"
:sort-by="['id DESC']" :sort-by="['id DESC']"

View File

@ -18,10 +18,11 @@ const $props = defineProps({
}); });
const updateState = async () => { const updateState = async () => {
try { try {
debugger;
showChangeStateDialog.value = true; showChangeStateDialog.value = true;
const rowsToUpdate = $props.selectedRows.map(({ id }) => const rowsToUpdate = $props.selectedRows.map(({ ticketFk }) =>
axios.post(`Tickets/state`, { axios.post(`Tickets/state`, {
ticketFk: id, ticketFk,
code: newState.value, code: newState.value,
}), }),
); );
@ -49,8 +50,9 @@ const updateState = async () => {
v-model="newState" v-model="newState"
:options="editableStates" :options="editableStates"
option-label="name" option-label="name"
option-value="code" option-value="id"
autofocus autofocus
data-cy="New state_select"
/> />
</QCardSection> </QCardSection>
<QCardActions align="right"> <QCardActions align="right">

View File

@ -45,7 +45,7 @@ describe('OrderCatalog', { testIsolation: true }, () => {
).type('{enter}'); ).type('{enter}');
cy.get(':nth-child(1) > [data-cy="catalogFilterCategory"]').click(); cy.get(':nth-child(1) > [data-cy="catalogFilterCategory"]').click();
cy.dataCy('catalogFilterValueDialogBtn').last().click(); cy.dataCy('catalogFilterValueDialogBtn').last().click();
cy.selectOption("[data-cy='catalogFilterValueDialogTagSelect']", 'Tallos'); cy.selectOption('[data-cy="catalogFilterValueDialogTagSelect"]', 'Tallos');
cy.dataCy('catalogFilterValueDialogValueInput').find('input').focus(); cy.dataCy('catalogFilterValueDialogValueInput').find('input').focus();
cy.dataCy('catalogFilterValueDialogValueInput').find('input').type('2'); cy.dataCy('catalogFilterValueDialogValueInput').find('input').type('2');
cy.dataCy('catalogFilterValueDialogValueInput').find('input').type('{enter}'); cy.dataCy('catalogFilterValueDialogValueInput').find('input').type('{enter}');

View File

@ -1,8 +1,6 @@
/// <reference types="cypress" /> /// <reference types="cypress" />
const firstRow = 'tr.cursor-pointer > :nth-child(1)'; const firstRow = 'tr.cursor-pointer > :nth-child(1)';
const ticketId = 1000000; const ticketId = 1000000;
const findTr = (index) => `tbody > tr > :nth-child(${index}) > div`;
const clickNotificationAction = () => { const clickNotificationAction = () => {
const notification = '.q-notification'; const notification = '.q-notification';
cy.waitForElement(notification); cy.waitForElement(notification);
@ -10,9 +8,9 @@ const clickNotificationAction = () => {
cy.get(notification).find('.q-btn').click(); cy.get(notification).find('.q-btn').click();
cy.get(notification).should('not.be.visible'); cy.get(notification).should('not.be.visible');
}; };
describe('Ticket Lack detail', () => { describe('Ticket Lack detail', { testIsolation: true }, () => {
beforeEach(() => { beforeEach(() => {
cy.viewport(1280, 720); cy.viewport(1980, 1020);
cy.login('developer'); cy.login('developer');
cy.intercept('GET', /\/api\/Tickets\/itemLack\/88.*$/).as('getItemLack'); cy.intercept('GET', /\/api\/Tickets\/itemLack\/88.*$/).as('getItemLack');
cy.visit('/#/ticket/negative/88'); cy.visit('/#/ticket/negative/88');
@ -23,21 +21,19 @@ describe('Ticket Lack detail', () => {
expect(filter).to.have.property('where'); expect(filter).to.have.property('where');
expect(filter.where).to.have.property('alertLevelCode', 'FREE'); expect(filter.where).to.have.property('alertLevelCode', 'FREE');
}); });
cy.domContentLoad();
cy.waitForElement('.q-table');
}); });
describe('Table detail', () => { describe('Table detail', () => {
it('should open descriptors', () => { it('should open descriptors', () => {
cy.get('.q-table').should('be.visible'); cy.get('.q-table').should('be.visible');
cy.colField('zoneName').click(); cy.colField('zoneName').click();
cy.dataCy('zoneDescriptorProxy').should('be.visible'); cy.dataCy('ZoneDescriptor').should('be.visible');
cy.get('.q-item > .q-item__label').should('have.text', ' #1'); cy.get('.q-item > .q-item__label').should('have.text', ' #1');
cy.colField('ticketFk').click(); cy.colField('ticketFk').click();
cy.dataCy('ticketDescriptorProxy').should('be.visible'); cy.dataCy('TicketDescriptor').should('be.visible');
cy.get('.q-item > .q-item__label').should('have.text', ` #${ticketId}`); cy.get('.q-item > .q-item__label').should('have.text', ` #${ticketId}`);
cy.colField('nickname').find('.link').click(); cy.colField('nickname').find('.link').click();
cy.waitForElement('[data-cy="customerDescriptorProxy"]'); cy.waitForElement('[data-cy="CustomerDescriptor"]');
cy.dataCy('customerDescriptorProxy').should('be.visible'); cy.dataCy('CustomerDescriptor').should('be.visible');
cy.get('.q-item > .q-item__label').should('have.text', ' #1'); cy.get('.q-item > .q-item__label').should('have.text', ' #1');
}); });
it('should display only one row in the lack list', () => { it('should display only one row in the lack list', () => {
@ -63,60 +59,7 @@ describe('Ticket Lack detail', () => {
it('Split', () => { it('Split', () => {
cy.dataCy('ticketTransferPopup').find('.flex > .q-btn').click(); cy.dataCy('ticketTransferPopup').find('.flex > .q-btn').click();
clickNotificationAction(); cy.checkNotification('Ticket 1000000: No split');
cy.dataCy('HandleLackDialog').should('be.visible');
cy.dataCy('HandleLackDialog').find('tbody > tr > :nth-child(1) > .q-icon');
cy.dataCy('HandleLackDialog').find(findTr(2)).should('have.class', 'link');
cy.dataCy('HandleLackDialog')
.find(`${findTr(2)}.link > div > span`)
.should('have.text', `${ticketId} `);
cy.dataCy('HandleLackDialog').find(findTr(3)).should('have.text', 'noSplit');
});
});
describe('Change Item', () => {
beforeEach(() => {
cy.get(firstRow).click();
cy.dataCy('changeItem').click();
});
it('Change failed', () => {
cy.dataCy('New item_select').should('be.visible').click();
cy.get('.q-item').contains('Palito rojo').click();
cy.get('.q-btn--unelevated > .q-btn__content > .block').click();
clickNotificationAction();
cy.dataCy('HandleLackDialog').should('be.visible');
cy.dataCy('HandleLackDialog').find('tbody > tr > :nth-child(1) > .q-icon');
cy.dataCy('HandleLackDialog').find(findTr(2)).should('have.class', 'link');
cy.dataCy('HandleLackDialog')
.find(`${findTr(2)}.link > span`)
.should('have.text', `${ticketId}`);
cy.dataCy('HandleLackDialog')
.find(findTr(3))
.should('have.text', 'price retrieval failed');
});
});
describe('Change state', () => {
beforeEach(() => {
cy.get(firstRow).click();
cy.dataCy('changeState').click();
});
it('Change success', () => {
cy.dataCy('New state_select').should('be.visible').click();
cy.get('.q-item').contains('OK').click();
cy.get('.q-btn--unelevated > .q-btn__content > .block').click();
clickNotificationAction();
cy.dataCy('HandleLackDialog')
.should('be.visible')
.find('tbody > tr > :nth-child(1) > .q-icon');
cy.dataCy('HandleLackDialog').find(findTr(2)).should('have.class', 'link');
cy.dataCy('HandleLackDialog')
.find(`${findTr(2)}.link > div > span`)
.should('have.text', `${ticketId} `);
cy.dataCy('HandleLackDialog').find(findTr(3)).should('have.text', 'OK');
}); });
}); });
describe('change quantity', () => { describe('change quantity', () => {
@ -126,22 +69,60 @@ describe('Ticket Lack detail', () => {
cy.dataCy('changeQuantity').click(); cy.dataCy('changeQuantity').click();
}); });
it('Change success', () => { it('by popup', () => {
cy.dataCy('New quantity_input').type(10); cy.dataCy('New quantity_input').type(10);
cy.get('.q-btn--unelevated > .q-btn__content > .block').click(); cy.get('.q-btn--unelevated > .q-btn__content > .block').click();
clickNotificationAction(); clickNotificationAction();
});
});
describe('Change state', () => {
beforeEach(() => {
cy.get(firstRow).click();
cy.dataCy('changeState').click();
});
it('by popup', () => {
cy.dataCy('New state_select').should('be.visible');
cy.selectOption('[data-cy="New state_select"]', 'OK');
cy.get('.q-btn--unelevated > .q-btn__content > .block').click();
cy.dataCy('HandleLackDialog') clickNotificationAction();
.should('be.visible')
.find('tbody > tr > :nth-child(1) > .q-icon');
cy.dataCy('HandleLackDialog').find(findTr(2)).should('have.class', 'link');
cy.dataCy('HandleLackDialog')
.find(`${findTr(2)}.link > div > span`)
.should('have.text', `${ticketId} `);
cy.dataCy('HandleLackDialog').find(findTr(3)).should('have.text', '10');
}); });
}); });
describe('Change Item', () => {
beforeEach(() => {
cy.get(firstRow).click();
cy.dataCy('changeItem').click();
});
it('by popup', () => {
cy.dataCy('New item_select').should('be.visible');
cy.selectOption('[data-cy="New item_select"]', 'Palito rojo');
cy.get('.q-btn--unelevated > .q-btn__content > .block').click();
cy.checkNotification('Ticket 43: price retrieval failed');
cy.dataCy('changeItem').click();
cy.selectOption('[data-cy="New item_select"]', 'Ranged weapon longbow 200cm');
cy.get('.q-btn--unelevated > .q-btn__content > .block').click();
clickNotificationAction();
});
after(() => {
cy.visit('/#/ticket/1000000/sale');
const quantity = Math.floor(Math.random() * 100) + 1;
cy.dataCy('ticketSaleQuantityInput')
.find('input')
.eq(1)
.type(quantity)
.trigger('tab');
cy.get('.q-page > :nth-child(6)').click();
cy.get('[data-cy="ticketSaleQuantityInput"]')
.find('input')
.should('have.value', `${quantity}`);
});
});
describe('Item proposal', () => { describe('Item proposal', () => {
beforeEach(() => { beforeEach(() => {
cy.get(firstRow).click(); cy.get(firstRow).click();
@ -155,7 +136,7 @@ describe('Ticket Lack detail', () => {
it('item proposal cells', () => { it('item proposal cells', () => {
cy.get('[data-col-field="longName"] .link').first().click(); cy.get('[data-col-field="longName"] .link').first().click();
cy.dataCy('itemDescriptorProxy').should('be.visible'); cy.dataCy('ItemDescriptor').should('be.visible');
cy.colField('longName', 2) cy.colField('longName', 2)
.find('.no-padding > .q-td > .middle') .find('.no-padding > .q-td > .middle')

View File

@ -1,7 +1,7 @@
/// <reference types="cypress" /> /// <reference types="cypress" />
describe('Ticket Lack list', () => { describe('Ticket Lack list', () => {
beforeEach(() => { beforeEach(() => {
cy.viewport(1280, 720); cy.viewport(1980, 1020);
cy.login('developer'); cy.login('developer');
cy.visit('/#/ticket/negative'); cy.visit('/#/ticket/negative');
@ -10,7 +10,7 @@ describe('Ticket Lack list', () => {
describe('Table actions', () => { describe('Table actions', () => {
it('should display only one row in the lack list', () => { it('should display only one row in the lack list', () => {
cy.get('[data-col-field="longName"]').first().click(); cy.get('[data-col-field="longName"]').first().click();
cy.dataCy('itemDescriptorProxy').should('be.visible'); cy.dataCy('ItemDescriptor').should('be.visible');
cy.get('.q-virtual-scroll__content > :nth-child(1) > .sticky').click(); cy.get('.q-virtual-scroll__content > :nth-child(1) > .sticky').click();
cy.location('href').should('contain', '#/ticket/negative/5'); cy.location('href').should('contain', '#/ticket/negative/5');
}); });

View File

@ -22,7 +22,7 @@ describe('TicketSale', { testIsolation: true }, () => {
cy.intercept('POST', /\/api\/Sales\/\d+\/updatePrice/).as('updatePrice'); cy.intercept('POST', /\/api\/Sales\/\d+\/updatePrice/).as('updatePrice');
cy.dataCy('saveManaBtn').click(); cy.dataCy('saveManaBtn').click();
handleVnConfirm(); cy.handleVnConfirm();
cy.wait('@updatePrice').its('response.statusCode').should('eq', 200); cy.wait('@updatePrice').its('response.statusCode').should('eq', 200);
cy.get('[data-col-field="price"]') cy.get('[data-col-field="price"]')
@ -43,7 +43,7 @@ describe('TicketSale', { testIsolation: true }, () => {
); );
cy.dataCy('saveManaBtn').click(); cy.dataCy('saveManaBtn').click();
handleVnConfirm(); cy.handleVnConfirm();
cy.wait('@updateDiscount').its('response.statusCode').should('eq', 204); cy.wait('@updateDiscount').its('response.statusCode').should('eq', 204);
cy.get('[data-col-field="discount"]') cy.get('[data-col-field="discount"]')
@ -61,7 +61,7 @@ describe('TicketSale', { testIsolation: true }, () => {
.find('[data-cy="undefined_input"]') .find('[data-cy="undefined_input"]')
.type(concept) .type(concept)
.type('{enter}'); .type('{enter}');
handleVnConfirm(); cy.handleVnConfirm();
cy.get('[data-col-field="item"]').should('contain.text', `${concept}`); cy.get('[data-col-field="item"]').should('contain.text', `${concept}`);
}); });
@ -77,7 +77,7 @@ describe('TicketSale', { testIsolation: true }, () => {
.trigger('tab'); .trigger('tab');
cy.get('.q-page > :nth-child(6)').click(); cy.get('.q-page > :nth-child(6)').click();
handleVnConfirm(); cy.handleVnConfirm();
cy.get('[data-cy="ticketSaleQuantityInput"]') cy.get('[data-cy="ticketSaleQuantityInput"]')
.find('input') .find('input')
@ -210,8 +210,3 @@ function selectFirstRow() {
cy.waitForElement(firstRow); cy.waitForElement(firstRow);
cy.get(firstRow).find('.q-checkbox__inner').click(); cy.get(firstRow).find('.q-checkbox__inner').click();
} }
function handleVnConfirm() {
cy.confirmVnConfirm();
cy.checkNotification('Data saved');
}

View File

@ -1,3 +1,9 @@
Cypress.Commands.add('handleVnConfirm', () => {
cy.confirmVnConfirm();
cy.checkNotification('Data saved');
});
Cypress.Commands.add('confirmVnConfirm', () => Cypress.Commands.add('confirmVnConfirm', () =>
cy.dataCy('VnConfirm_confirm').should('exist').click(), cy.dataCy('VnConfirm_confirm').should('exist').click(),
); );

View File

@ -18,3 +18,37 @@ Cypress.Commands.add('tableActions', (n = 0, child = 1) =>
`:nth-child(${child}) > .q-table--col-auto-width > [data-cy="tableAction-${n}"] > .q-btn__content > .q-icon`, `:nth-child(${child}) > .q-table--col-auto-width > [data-cy="tableAction-${n}"] > .q-btn__content > .q-icon`,
), ),
); );
Cypress.Commands.add('validateVnTableRows', (opts = {}) => {
let { cols = [] } = opts;
const { rows = [] } = opts;
if (!Array.isArray(cols)) cols = [cols];
const rowSelector = rows.length
? rows.map((row) => `> :nth-child(${row})`).join(', ')
: '> *';
cy.get(`[data-cy="vnTable"] .q-virtual-scroll__content`).within(() => {
cy.get(`${rowSelector}`).each(($el) => {
for (const { name, type = 'string', val, operation = 'equal' } of cols) {
cy.wrap($el)
.find(`[data-cy="vnTableCell_${name}"]`)
.invoke('text')
.then((text) => {
if (type === 'string')
expect(text.trim().toLowerCase()).to[operation](
val.toLowerCase(),
);
if (type === 'number') cy.checkNumber(text, val, operation);
if (type === 'date') cy.checkDate(text, val, operation);
});
}
});
});
});
Cypress.Commands.add('colField', (name, index = null, key = 'data-col-field') => {
if (index) {
cy.get(`:nth-child(${index}) > [${key}="${name}"]`);
} else {
cy.get(`[${key}="${name}"]`);
}
});