diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 413060d23..f9a84ac65 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -403,6 +403,7 @@ export default { ticketDescriptor: { id: 'vn-descriptor-content div.top > div', stateLabelValue: 'vn-ticket-descriptor vn-label-value[label="State"]', + isDeletedIcon: 'vn-ticket-descriptor vn-icon[icon="icon-deletedTicket"]', goBackToModuleIndexButton: 'vn-ticket-descriptor a[ui-sref="ticket.index"]', moreMenu: 'vn-ticket-descriptor vn-icon-button[icon=more_vert]', moreMenuAddStowaway: '.vn-menu [name="addStowaway"]', @@ -445,6 +446,7 @@ export default { savePackagesButton: `button[type=submit]` }, ticketSales: { + setOk: 'vn-ticket-sale vn-tool-bar > vn-button[label="Ok"] > button', saleButton: 'vn-left-menu a[ui-sref="ticket.card.sale"]', saleLine: 'vn-table div > vn-tbody > vn-tr', saleDescriptorPopover: '.vn-popover.shown vn-item-descriptor', @@ -502,7 +504,8 @@ export default { moveToNewTicketButton: '.vn-popover.shown vn-button[label="New ticket"]', acceptDeleteLineButton: '.vn-confirm.shown button[response=accept]', acceptDeleteTicketButton: '.vn-confirm.shown button[response=accept]', - stateMenuButton: 'vn-ticket-sale vn-tool-bar > vn-button-menu[label="State"]' + stateMenuButton: 'vn-ticket-sale vn-tool-bar > vn-button-menu[label="State"]', + stateMenuFixOption: '' }, ticketTracking: { trackingButton: 'vn-left-menu a[ui-sref="ticket.card.tracking.index"]', diff --git a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js index a22b0e022..a7b24e4a3 100644 --- a/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js +++ b/e2e/paths/05-ticket/01-sale/02_edit_sale.spec.js @@ -1,8 +1,7 @@ import selectors from '../../../helpers/selectors.js'; import getBrowser from '../../../helpers/puppeteer'; -// #1632 [e2e] ticket.sale - Transferir lĂ­neas -xdescribe('Ticket Edit sale path', () => { +describe('Ticket Edit sale path', () => { let browser; let page; @@ -10,7 +9,7 @@ xdescribe('Ticket Edit sale path', () => { browser = await getBrowser(); page = browser.page; await page.loginAndModule('salesPerson', 'ticket'); - await page.accessToSearchResult(16); + await page.accessToSearchResult('16'); await page.accessToSection('ticket.card.sale'); }); @@ -20,29 +19,50 @@ xdescribe('Ticket Edit sale path', () => { it(`should click on the first sale claim icon to navigate over there`, async() => { await page.waitToClick(selectors.ticketSales.firstSaleClaimIcon); - await page.wait(selectors.claimBasicData.claimState); - const url = await page.parsedUrl(); - - expect(url.hash).toEqual('#!/claim/2/basic-data'); + await page.waitForState('claim.card.basicData'); }); it('should navigate to the tickets index', async() => { await page.waitToClick(selectors.globalItems.applicationsMenuButton); await page.wait(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.ticketsButton); - await page.wait(selectors.ticketsIndex.topbarSearch); - const url = await page.parsedUrl(); - - expect(url.hash).toEqual('#!/ticket/index'); + await page.waitForState('ticket.index'); }); it(`should search for a ticket and then navigate to it's sales`, async() => { - await page.accessToSearchResult(16); + await page.accessToSearchResult('16'); await page.accessToSection('ticket.card.sale'); - await page.waitForURL('/sale'); - const url = await page.parsedUrl(); + }); - expect(url.hash).toContain('/sale'); + it(`should set the ticket as libre`, async() => { + await page.waitToClick(selectors.ticketSales.stateMenuButton); + await page.write('body > div > div > div.content > div.filter.ng-scope > vn-textfield', 'libre'); + await page.waitFor(500); + await page.keyboard.press('Enter'); + const message = await page.waitForSnackbar(); + + expect(message.type).toBe('success'); + }); + + it(`should check it's state is libre now`, async() => { + await page.waitForTextInElement(selectors.ticketDescriptor.stateLabelValue, 'Libre'); + const result = await page.waitToGetProperty(selectors.ticketDescriptor.stateLabelValue, 'innerText'); + + expect(result).toEqual('State Libre'); + }); + + it(`should set the ticket as OK`, async() => { + await page.waitToClick(selectors.ticketSales.setOk); + const message = await page.waitForSnackbar(); + + expect(message.type).toBe('success'); + }); + + it(`should check it's state is OK now`, async() => { + await page.waitForTextInElement(selectors.ticketDescriptor.stateLabelValue, 'OK'); + const result = await page.waitToGetProperty(selectors.ticketDescriptor.stateLabelValue, 'innerText'); + + expect(result).toEqual('State OK'); }); it(`should check the zoomed image isn't present`, async() => { @@ -52,26 +72,20 @@ xdescribe('Ticket Edit sale path', () => { }); it(`should click on the thumbnail image of the 1st sale and see the zoomed image`, async() => { - await page.clickIfVisible(selectors.ticketSales.firstSaleThumbnailImage); + await page.waitToClick(selectors.ticketSales.firstSaleThumbnailImage); const result = await page.countElement(selectors.ticketSales.firstSaleZoomedImage); expect(result).toEqual(1); }); it(`should click on the zoomed image to close it`, async() => { - await page.clickIfVisible(selectors.ticketSales.firstSaleZoomedImage); + await page.waitToClick(selectors.ticketSales.firstSaleZoomedImage); const result = await page.countElement(selectors.ticketSales.firstSaleZoomedImage); expect(result).toEqual(0); }); - it(`should confirm the item descriptor insnt visible yet`, async() => { - const visible = await page.isVisible(selectors.ticketSales.saleDescriptorPopover); - - expect(visible).toBeFalsy(); - }); - - it(`should click on the first sale ID making the item descriptor visible`, async() => { + it(`should click on the first sale ID making now the item descriptor visible`, async() => { await page.waitToClick(selectors.ticketSales.firstSaleId); await page.waitImgLoad(selectors.ticketSales.firstSaleDescriptorImage); const visible = await page.isVisible(selectors.ticketSales.saleDescriptorPopover); @@ -80,14 +94,14 @@ xdescribe('Ticket Edit sale path', () => { }); it(`should click on the descriptor image of the 1st sale and see the zoomed image`, async() => { - await page.clickIfVisible('vn-item-descriptor img'); + await page.waitToClick('vn-item-descriptor img'); const result = await page.countElement(selectors.ticketSales.firstSaleZoomedImage); expect(result).toEqual(1); }); it(`should now click on the zoomed image to close it`, async() => { - await page.clickIfVisible(selectors.ticketSales.firstSaleZoomedImage); + await page.waitToClick(selectors.ticketSales.firstSaleZoomedImage); const result = await page.countElement(selectors.ticketSales.firstSaleZoomedImage); expect(result).toEqual(0); @@ -95,50 +109,46 @@ xdescribe('Ticket Edit sale path', () => { it(`should click on the summary icon of the item-descriptor to access to the item summary`, async() => { await page.waitToClick(selectors.ticketSales.saleDescriptorPopoverSummaryButton); - await page.waitForURL('/summary'); - const url = await page.parsedUrl(); - - expect(url.hash).toContain('/summary'); + await page.waitForState('item.card.summary'); }); it('should return to ticket sales section', async() => { await page.waitToClick(selectors.globalItems.applicationsMenuButton); await page.wait(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.ticketsButton); - await page.accessToSearchResult(16); + await page.accessToSearchResult('16'); await page.accessToSection('ticket.card.sale'); - await page.waitForURL('/sale'); - const url = await page.parsedUrl(); - - expect(url.hash).toContain('/sale'); }); it('should try to add a higher quantity value and then receive an error', async() => { - await page.focusElement(selectors.ticketSales.firstSaleQuantityCell); - await page.write(selectors.ticketSales.firstSaleQuantity, '11\u000d'); + await page.waitToClick(selectors.ticketSales.firstSaleQuantityCell); + await page.type(selectors.ticketSales.firstSaleQuantity, '11\u000d'); const message = await page.waitForSnackbar(); expect(message.text).toBe('The new quantity should be smaller than the old one'); }); it('should remove 1 from the first sale quantity', async() => { - await page.focusElement(selectors.ticketSales.firstSaleQuantityCell); - await page.write(selectors.ticketSales.firstSaleQuantity, '9\u000d'); + await page.waitFor(500); + await page.waitToClick(selectors.ticketSales.firstSaleQuantityCell); + await page.waitFor(selectors.ticketSales.firstSaleQuantity); + await page.type(selectors.ticketSales.firstSaleQuantity, '9\u000d'); const message = await page.waitForSnackbar(); expect(message.type).toBe('success'); }); it('should update the price', async() => { - await page.waitToClick(`${selectors.ticketSales.firstSalePrice} > span`); - await page.write(selectors.ticketSales.firstSalePriceInput, '5\u000d'); + await page.waitToClick(selectors.ticketSales.firstSalePrice); + await page.waitFor(selectors.ticketSales.firstSalePriceInput); + await page.type(selectors.ticketSales.firstSalePriceInput, '5\u000d'); const message = await page.waitForSnackbar(); expect(message.type).toBe('success'); }); it('should confirm the price have been updated', async() => { - const result = await page.waitToGetProperty(`${selectors.ticketSales.firstSalePrice} span`, 'innerText'); + const result = await page.waitToGetProperty(selectors.ticketSales.firstSalePrice, 'innerText'); expect(result).toContain('5.00'); }); @@ -150,16 +160,17 @@ xdescribe('Ticket Edit sale path', () => { }); it('should update the discount', async() => { - await page.waitToClick(`${selectors.ticketSales.firstSaleDiscount} > span`); - await page.write(selectors.ticketSales.firstSaleDiscountInput, '50\u000d'); + await page.waitToClick(selectors.ticketSales.firstSaleDiscount); + await page.waitFor(selectors.ticketSales.firstSaleDiscountInput); + await page.type(selectors.ticketSales.firstSaleDiscountInput, '50\u000d'); const message = await page.waitForSnackbar(); expect(message.type).toBe('success'); }); it('should confirm the discount have been updated', async() => { - await page.waitForTextInElement(`${selectors.ticketSales.firstSaleDiscount} > span`, '50.00%'); - const result = await page.waitToGetProperty(`${selectors.ticketSales.firstSaleDiscount} > span`, 'innerText'); + await page.waitForTextInElement(selectors.ticketSales.firstSaleDiscount, '50.00%'); + const result = await page.waitToGetProperty(selectors.ticketSales.firstSaleDiscount, 'innerText'); expect(result).toContain('50.00%'); }); @@ -175,48 +186,31 @@ xdescribe('Ticket Edit sale path', () => { await page.waitToClick(selectors.ticketSales.thirdSaleCheckbox); await page.waitToClick(selectors.ticketSales.moreMenu); await page.waitToClick(selectors.ticketSales.moreMenuCreateClaim); - await page.wait(selectors.claimBasicData.claimState); - const url = await page.parsedUrl(); - - expect(url.hash).toContain('basic-data'); + await page.waitForState('claim.card.basicData'); }); it('should click on the Claims button of the top bar menu', async() => { await page.waitToClick(selectors.globalItems.applicationsMenuButton); await page.wait(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.claimsButton); - await page.wait(selectors.claimsIndex.searchClaimInput); - const url = await page.parsedUrl(); - - expect(url.hash).toEqual('#!/claim/index'); + await page.waitForState('claim.index'); }); it('should search for the claim with id 4', async() => { - await page.write(selectors.claimsIndex.searchClaimInput, 4); - await page.waitToClick(selectors.claimsIndex.searchButton); - await page.waitForNumberOfElements(selectors.claimsIndex.searchResult, 1); - const result = await page.countElement(selectors.claimsIndex.searchResult); - - expect(result).toEqual(1); + await page.accessToSearchResult('4'); + await page.waitForState('claim.card.summary'); }); it('should click the Tickets button of the top bar menu', async() => { await page.waitToClick(selectors.globalItems.applicationsMenuButton); await page.wait(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.ticketsButton); - await page.wait(selectors.ticketsIndex.topbarSearch); - const url = await page.parsedUrl(); - - expect(url.hash).toEqual('#!/ticket/index'); + await page.waitForState('ticket.index'); }); it('should search for a ticket then access to the sales section', async() => { - await page.accessToSearchResult(16); + await page.accessToSearchResult('16'); await page.accessToSection('ticket.card.sale'); - await page.waitForURL('/sale'); - const url = await page.parsedUrl(); - - expect(url.hash).toContain('/sale'); }); it('should select the third sale and delete it', async() => { @@ -236,18 +230,15 @@ xdescribe('Ticket Edit sale path', () => { }); it('should select the second sale and transfer it to a valid ticket', async() => { - const targetTicketId = 12; + const targetTicketId = '12'; await page.waitToClick(selectors.ticketSales.secondSaleCheckbox); await page.waitToClick(selectors.ticketSales.transferSaleButton); - await page.focusElement(selectors.ticketSales.transferQuantityCell); - await page.write(selectors.ticketSales.transferQuantityInput, '10\u000d'); - await page.write(selectors.ticketSales.moveToTicketInput, targetTicketId); + await page.waitToClick(selectors.ticketSales.transferQuantityCell); + await page.type(selectors.ticketSales.transferQuantityInput, '10\u000d'); + await page.type(selectors.ticketSales.moveToTicketInput, targetTicketId); await page.waitToClick(selectors.ticketSales.moveToTicketButton); - await page.waitForURL(`ticket/${targetTicketId}/sale`); - const result = await page.parsedUrl(); - - expect(result.hash).toContain(`ticket/${targetTicketId}/sale`); + await page.expectURL(`ticket/${targetTicketId}/sale`); }); it('should confirm the transfered line is the correct one', async() => { @@ -265,12 +256,8 @@ xdescribe('Ticket Edit sale path', () => { it('should go back to the original ticket sales section', async() => { await page.waitToClick(selectors.ticketDescriptor.goBackToModuleIndexButton); - await page.accessToSearchResult(16); + await page.accessToSearchResult('16'); await page.accessToSection('ticket.card.sale'); - await page.waitForURL('/sale'); - const url = await page.parsedUrl(); - - expect(url.hash).toContain('/sale'); }); it(`should confirm the original ticket has still three lines`, async() => { @@ -288,25 +275,18 @@ xdescribe('Ticket Edit sale path', () => { it('should go back to the receiver ticket sales section', async() => { await page.waitToClick(selectors.ticketDescriptor.goBackToModuleIndexButton); - await page.accessToSearchResult(12); + await page.accessToSearchResult('12'); await page.accessToSection('ticket.card.sale'); - await page.waitForURL('/sale'); - const url = await page.parsedUrl(); - - expect(url.hash).toContain('/sale'); }); it('should transfer the sale back to the original ticket', async() => { - const targetTicketId = 16; + const targetTicketId = '16'; await page.waitToClick(selectors.ticketSales.secondSaleCheckbox); await page.waitToClick(selectors.ticketSales.transferSaleButton); - await page.write(selectors.ticketSales.moveToTicketInput, targetTicketId); + await page.type(selectors.ticketSales.moveToTicketInput, targetTicketId); await page.waitToClick(selectors.ticketSales.moveToTicketButton); - await page.waitForURL(`ticket/${targetTicketId}/sale`); - const result = await page.parsedUrl(); - - expect(result.hash).toContain(`ticket/${targetTicketId}/sale`); + await page.expectURL(`ticket/${targetTicketId}/sale`); }); it('should confirm the original ticket received the line', async() => { @@ -321,35 +301,29 @@ xdescribe('Ticket Edit sale path', () => { await page.waitToClick(selectors.ticketSales.firstSaleCheckbox); await page.waitToClick(selectors.ticketSales.transferSaleButton); await page.waitToClick(selectors.ticketSales.moveToNewTicketButton); - await page.waitToClick(selectors.ticketSales.acceptDeleteTicketButton); const message = await page.waitForSnackbar(); expect(message.text).toBe(`You can't create a ticket for a inactive client`); + + await page.closePopup(); }); it('should go now to the ticket sales section of an active, not frozen client', async() => { await page.waitToClick(selectors.ticketDescriptor.goBackToModuleIndexButton); - await page.accessToSearchResult(13); + await page.accessToSearchResult('13'); await page.accessToSection('ticket.card.sale'); - await page.waitForURL('/sale'); - const url = await page.parsedUrl(); - - expect(url.hash).toContain('/sale'); }); it(`should select all sales, tranfer them to a new ticket and delete the sender ticket as it would've been left empty`, async() => { - const senderTicketId = 13; + const senderTicketId = '13'; await page.waitToClick(selectors.ticketSales.selectAllSalesCheckbox); await page.waitToClick(selectors.ticketSales.transferSaleButton); await page.waitToClick(selectors.ticketSales.moveToNewTicketButton); - await page.waitToClick(selectors.ticketSales.acceptDeleteTicketButton); - await page.wait((selector, ticketId) => { - return document.querySelector(selector).innerText.toLowerCase().indexOf(`${ticketId}`) == -1; - }, selectors.ticketDescriptor.idLabelValue, senderTicketId); - const url = await page.parsedUrl(); - - expect(url.hash).toContain('/sale'); + await page.evaluate((selector, ticketId) => { + return document.querySelector(selector).innerText.toLowerCase().indexOf(`#${ticketId}`) == -1; + }, selectors.ticketDescriptor.id, senderTicketId); + await page.waitForState('ticket.card.sale'); }); it('should confirm the new ticket received the line', async() => { @@ -368,6 +342,7 @@ xdescribe('Ticket Edit sale path', () => { await page.waitToClick(selectors.ticketSales.firstSaleCheckbox); await page.waitToClick(selectors.ticketSales.moreMenu); await page.waitToClick(selectors.ticketSales.moreMenuReserve); + await page.closePopup(); await page.waitForClassNotPresent(selectors.ticketSales.firstSaleReservedIcon, 'ng-hide'); const result = await page.isVisible(selectors.ticketSales.firstSaleReservedIcon); @@ -384,10 +359,12 @@ xdescribe('Ticket Edit sale path', () => { }); it('should update all sales discount', async() => { + await page.closePopup(); await page.waitToClick(selectors.ticketSales.moreMenu); await page.waitToClick(selectors.ticketSales.moreMenuUpdateDiscount); - // .write(selectors.ticketSales.moreMenuUpdateDiscountInput, 100) can't find the selector on app (deleted the selector), menu option was removed? - await page.write('body', '\u000d'); + await page.waitForSelector(selectors.ticketSales.moreMenuUpdateDiscountInput); + await page.type(selectors.ticketSales.moreMenuUpdateDiscountInput, '100'); + await page.keyboard.press('Enter'); await page.waitForTextInElement(selectors.ticketSales.totalImport, '0.00'); const result = await page.waitToGetProperty(selectors.ticketSales.totalImport, 'innerText'); @@ -396,75 +373,12 @@ xdescribe('Ticket Edit sale path', () => { it('should log in as Production role and go to a target ticket summary', async() => { await page.loginAndModule('production', 'ticket'); - await page.accessToSearchResult(13); - await page.waitForURL('/summary'); - const url = await page.parsedUrl(); - - expect(url.hash).toContain('/summary'); + await page.accessToSearchResult('13'); + await page.waitForState('ticket.card.summary'); }); - it(`should check it's state is deleted`, async() => { - const result = await page.waitToGetProperty(selectors.ticketDescriptor.stateLabelValue, 'innerText'); - - expect(result).toEqual('State Eliminado'); - }); - - describe('when state is preparation and loged as Production', () => { - it(`should not be able to edit the sale price`, async() => { - await page.waitToClick(selectors.ticketDescriptor.goBackToModuleIndexButton); - await page.accessToSearchResult(8); - await page.accessToSection('ticket.card.sale'); - await page.waitToClick(selectors.ticketSales.firstSalePrice); - const result = await page.exists(selectors.ticketSales.firstSalePriceInput); - - expect(result).toBeFalsy(); - }); - - it(`should not be able to edit the sale discount`, async() => { - await page.waitToClick(selectors.ticketSales.firstSaleDiscount); - const result = await page.exists(selectors.ticketSales.firstSaleDiscountInput); - - expect(result).toBeFalsy(); - }); - - it(`should not be able to edit the sale state`, async() => { - await page.waitToClick(selectors.ticketSales.stateMenuButton); - const result = await page.exists(selectors.ticketSales.stateMenuOptions); - - expect(result).toBeFalsy(); - }); - - it('should log in as salesPerson then go to the sales of a target ticket', async() => { - await page.loginAndModule('salesPerson', 'ticket'); - await page.accessToSearchResult(8); - await page.accessToSection('ticket.card.sale'); - await page.waitForURL('/sale'); - const url = await page.parsedUrl(); - - expect(url.hash).toContain('/sale'); - }); - }); - - describe('when state is preparation and loged as salesPerson', () => { - it(`shouldn't be able to edit the sale price`, async() => { - await page.waitToClick(selectors.ticketSales.firstSalePrice); - const result = await page.exists(selectors.ticketSales.firstSalePriceInput); - - expect(result).toBeFalsy(); - }); - - it(`should be able to edit the sale discount`, async() => { - await page.waitToClick(selectors.ticketSales.firstSaleDiscount); - const result = await page.exists(selectors.ticketSales.firstSaleDiscountInput); - - expect(result).toBeFalsy(); - }); - - it(`should not be able to edit the sale state`, async() => { - await page.waitToClick(selectors.ticketSales.stateMenuButton); - const result = await page.exists(selectors.ticketSales.stateMenuOptions); - - expect(result).toBeFalsy(); - }); + it(`should check the ticket is deleted`, async() => { + await page.waitForSelector(selectors.ticketDescriptor.isDeletedIcon); + await page.waitForClassPresent(selectors.ticketDescriptor.isDeletedIcon, 'bright'); }); }); diff --git a/modules/client/back/methods/client/specs/canCreateTicket.spec.js b/modules/client/back/methods/client/specs/canCreateTicket.spec.js new file mode 100644 index 000000000..9eb1db334 --- /dev/null +++ b/modules/client/back/methods/client/specs/canCreateTicket.spec.js @@ -0,0 +1,17 @@ +const app = require('vn-loopback/server/server'); + +describe('Client canCreateTicket', () => { + it('should receive true if the client is active', async() => { + let id = 105; + let canCreateTicket = await app.models.Client.canCreateTicket(id); + + expect(canCreateTicket).toBeTruthy(); + }); + + it(`should receive false if the client isn't active`, async() => { + let id = 106; + let canCreateTicket = await app.models.Client.canCreateTicket(id); + + expect(canCreateTicket).toBe(false); + }); +});