diff --git a/.gitignore b/.gitignore index 8cb76a829..f4b1ab270 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ e2e/dms/*/ !e2e/dms/c4c !e2e/dms/c81 !e2e/dms/ecc +!e2e/dms/a87 npm-debug.log .eslintcache datasources.*.json diff --git a/back/methods/dms/downloadFile.js b/back/methods/dms/downloadFile.js index f3096aabb..1b9150053 100644 --- a/back/methods/dms/downloadFile.js +++ b/back/methods/dms/downloadFile.js @@ -1,5 +1,4 @@ const UserError = require('vn-loopback/util/user-error'); - module.exports = Self => { Self.remoteMethodCtx('downloadFile', { description: 'Download a document', @@ -34,29 +33,8 @@ module.exports = Self => { }); Self.downloadFile = async function(ctx, id) { - const storageConnector = Self.app.dataSources.storage.connector; - const models = Self.app.models; - const dms = await Self.findById(id); - - const hasReadRole = await models.DmsType.hasReadRole(ctx, dms.dmsTypeFk); - if (!hasReadRole) + if (!await Self.checkRole(ctx, id)) throw new UserError(`You don't have enough privileges`); - - const pathHash = storageConnector.getPathHash(dms.id); - try { - await models.Container.getFile(pathHash, dms.file); - } catch (e) { - if (e.code != 'ENOENT') - throw e; - - const error = new UserError(`File doesn't exists`); - error.statusCode = 404; - - throw error; - } - - const stream = models.Container.downloadStream(pathHash, dms.file); - - return [stream, dms.contentType, `filename="${dms.file}"`]; + return await Self.getFile(id); }; }; diff --git a/back/methods/dms/specs/downloadFile.spec.js b/back/methods/dms/specs/downloadFile.spec.js index 99820ed38..701a484df 100644 --- a/back/methods/dms/specs/downloadFile.spec.js +++ b/back/methods/dms/specs/downloadFile.spec.js @@ -11,7 +11,7 @@ describe('dms downloadFile()', () => { expect(result[1]).toEqual('text/plain'); }); - it(`should return an error for a user without enough privileges`, async() => { + it('should return an error for a user without enough privileges', async() => { let clientId = 101; let ctx = {req: {accessToken: {userId: clientId}}}; diff --git a/back/models/dms.js b/back/models/dms.js index 9a06928db..8be539a0f 100644 --- a/back/models/dms.js +++ b/back/models/dms.js @@ -1,6 +1,37 @@ +const UserError = require('vn-loopback/util/user-error'); + module.exports = Self => { require('../methods/dms/downloadFile')(Self); require('../methods/dms/uploadFile')(Self); require('../methods/dms/removeFile')(Self); require('../methods/dms/updateFile')(Self); + + Self.checkRole = async function(ctx, id) { + const models = Self.app.models; + const dms = await Self.findById(id); + + return await models.DmsType.hasReadRole(ctx, dms.dmsTypeFk); + }; + + Self.getFile = async function(id) { + const storageConnector = Self.app.dataSources.storage.connector; + const models = Self.app.models; + const dms = await Self.findById(id); + const pathHash = storageConnector.getPathHash(dms.id); + try { + await models.Container.getFile(pathHash, dms.file); + } catch (e) { + if (e.code != 'ENOENT') + throw e; + + const error = new UserError(`File doesn't exists`); + error.statusCode = 404; + + throw error; + } + + const stream = models.Container.downloadStream(pathHash, dms.file); + + return [stream, dms.contentType, `filename="${dms.file}"`]; + }; }; diff --git a/back/models/specs/dms.spec.js b/back/models/specs/dms.spec.js new file mode 100644 index 000000000..8e76a4956 --- /dev/null +++ b/back/models/specs/dms.spec.js @@ -0,0 +1,53 @@ +const app = require('vn-loopback/server/server'); +describe('Dms', () => { + const Dms = app.models.Dms; + + describe('getFile()', () => { + it('should return a response with text content-type', async() => { + const result = await Dms.getFile(1); + + expect(result[1]).toEqual('text/plain'); + }); + + it('should return an error for a file does not exists', async() => { + let error = {}; + try { + await Dms.getFile(6); + } catch (e) { + error = e; + } + + expect(error.statusCode).toBe(404); + }); + + it('should return an error for a record does not exists', async() => { + let error = {}; + try { + await app.models.Dms.getFile('NotExistentId'); + } catch (e) { + error = e; + } + + expect(error.statusCode).not.toBe(404); + expect(error).toEqual(jasmine.any(Error)); + }); + }); + + describe('checkRole()', () => { + const dmsId = 1; + it('should return a true for an employee with permission', async() => { + let ctx = {req: {accessToken: {userId: 107}}}; + const result = await Dms.checkRole(ctx, dmsId); + + expect(result).toBeTruthy(); + }); + + it('should return false for an employee without permission', async() => { + let ctx = {req: {accessToken: {userId: 101}}}; + const result = await Dms.checkRole(ctx, dmsId); + + expect(result).toBeFalsy(); + }); + }); +}); + diff --git a/db/changes/10161-postValentineDay/00-borrame.sql b/db/changes/10161-postValentineDay/00-borrame.sql new file mode 100644 index 000000000..22d1f5dec --- /dev/null +++ b/db/changes/10161-postValentineDay/00-borrame.sql @@ -0,0 +1,4 @@ +ALTER TABLE `vn`.`workerDocument` +ADD COLUMN `isReadableByWorker` TINYINT(1) NOT NULL DEFAULT 0 AFTER `document`; + +UPDATE `vn`.`workerDocument` SET `isReadableByWorker` = '1' WHERE (`id` = '1'); diff --git a/db/changes/10162-fallas/00-acl.sql b/db/changes/10162-fallas/00-acl.sql new file mode 100644 index 000000000..376788af1 --- /dev/null +++ b/db/changes/10162-fallas/00-acl.sql @@ -0,0 +1 @@ +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) VALUES ('WorkerLog', '*', 'READ', 'ALLOW', 'ROLE', 'hr'); diff --git a/db/changes/10162-fallas/00-workerLog.sql b/db/changes/10162-fallas/00-workerLog.sql new file mode 100644 index 000000000..730b60aa5 --- /dev/null +++ b/db/changes/10162-fallas/00-workerLog.sql @@ -0,0 +1,6 @@ +ALTER TABLE `vn`.`workerLog` + ADD COLUMN `changedModel` VARCHAR(45) NULL DEFAULT NULL AFTER `description`, + ADD COLUMN `oldInstance` text CHARACTER SET utf8 COLLATE utf8_unicode_ci, + ADD COLUMN `newInstance` text CHARACTER SET utf8 COLLATE utf8_unicode_ci, + ADD COLUMN `changedModelId` int(11) DEFAULT NULL, + ADD COLUMN `changedModelValue` varchar(45) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL; \ No newline at end of file diff --git a/db/changes/10170-NOFallas/00-aclWorkerDms.sql b/db/changes/10170-NOFallas/00-aclWorkerDms.sql new file mode 100644 index 000000000..46e56f77e --- /dev/null +++ b/db/changes/10170-NOFallas/00-aclWorkerDms.sql @@ -0,0 +1,5 @@ +INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`) +VALUES +('WorkerDms', 'filter', 'READ', 'ALLOW', 'ROLE', 'employee'), +('WorkerDms', 'downloadFile', 'READ', 'ALLOW', 'ROLE', 'employee'); +DELETE FROM `salix`.`ACL` WHERE (`id` = '205'); diff --git a/db/changes/10170-NOFallas/00-zone_getEvents.sql b/db/changes/10170-NOFallas/00-zone_getEvents.sql new file mode 100644 index 000000000..991150db7 --- /dev/null +++ b/db/changes/10170-NOFallas/00-zone_getEvents.sql @@ -0,0 +1,119 @@ +USE `vn`; +DROP procedure IF EXISTS `zone_getEvents`; + +DELIMITER $$ +USE `vn`$$ +CREATE DEFINER=`root`@`%` PROCEDURE `zone_getEvents`( + vGeoFk INT, + vAgencyModeFk INT) +BEGIN +/** + * Returns available events for the passed province/postcode and agency. + * + * @param vGeoFk The geo id + * @param vAgencyModeFk The agency mode id + */ + DECLARE vDeliveryMethodFk VARCHAR(255); + + DROP TEMPORARY TABLE IF EXISTS tZone; + CREATE TEMPORARY TABLE tZone + (id INT PRIMARY KEY) + ENGINE = MEMORY; + + SELECT dm.`code` INTO vDeliveryMethodFk + FROM agencyMode am + JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk + WHERE am.id = vAgencyModeFk; + + IF vDeliveryMethodFk = 'PICKUP' THEN + INSERT INTO tZone + SELECT id + FROM zone + WHERE agencyModeFk = vAgencyModeFk; + ELSE + CALL zone_getFromGeo(vGeoFk); + + IF vAgencyModeFk IS NOT NULL THEN + INSERT INTO tZone + SELECT t.id + FROM tmp.zone t + JOIN zone z ON z.id = t.id + WHERE z.agencyModeFk = vAgencyModeFk; + ELSE + INSERT INTO tZone + SELECT t.id + FROM tmp.zone t + JOIN zone z ON z.id = t.id + JOIN agencyMode am ON am.id = z.agencyModeFk + JOIN deliveryMethod dm ON dm.id = am.deliveryMethodFk + WHERE dm.`code` IN ('AGENCY', 'DELIVERY'); + END IF; + DROP TEMPORARY TABLE tmp.zone; + END IF; + + SELECT e.zoneFk, e.`type`, e.dated, e.`started`, e.`ended`, e.weekDays + FROM tZone t + JOIN zoneEvent e ON e.zoneFk = t.id; + + SELECT e.zoneFk, e.dated + FROM tZone t + JOIN zoneExclusion e ON e.zoneFk = t.id; + + DROP TEMPORARY TABLE tZone; +END$$ + +DELIMITER ; + +USE `vn`; +DROP procedure IF EXISTS `zone_getEvents__`; + +DELIMITER $$ +USE `vn`$$ +CREATE DEFINER=`root`@`%` PROCEDURE `zone_getEvents__`( + vProvinceFk INT, + vPostCode VARCHAR(255), + vAgencyModeFk INT) +BEGIN +/** + * Returns available events for the passed province/postcode and agency. + * + * @param vAgencyModeFk The agency mode id + * @param vProvinceFk The province id + * @param vPostCode The postcode or %NULL to use the province + */ + + DECLARE vGeoFk INT; + + IF vPostCode IS NOT NULL THEN + SELECT p.geoFk INTO vGeoFk + FROM postCode p + JOIN town t ON t.id = p.townFk + WHERE p.`code` = vPostCode + AND t.provinceFk = vProvinceFk; + ELSE + SELECT geoFk INTO vGeoFk + FROM province + WHERE id = vProvinceFk; + END IF; + + CALL zone_getFromGeo(vGeoFk); + + IF vAgencyModeFk IS NOT NULL THEN + DELETE t FROM tmp.zone t + JOIN zone z ON z.id = t.id + WHERE z.agencyModeFk != vAgencyModeFk; + END IF; + + SELECT e.zoneFk, e.`type`, e.dated, e.`started`, e.`ended`, e.weekDays + FROM tmp.zone t + JOIN zoneEvent e ON e.zoneFk = t.id; + + SELECT e.zoneFk, e.dated + FROM tmp.zone t + JOIN zoneExclusion e ON e.zoneFk = t.id; + + DROP TEMPORARY TABLE tmp.zone; +END$$ + +DELIMITER ; + diff --git a/db/changes/10170-NOFallas/00-zone_getWarehouse.sql b/db/changes/10170-NOFallas/00-zone_getWarehouse.sql new file mode 100644 index 000000000..a65643ff5 --- /dev/null +++ b/db/changes/10170-NOFallas/00-zone_getWarehouse.sql @@ -0,0 +1,87 @@ +USE `vn`; +DROP procedure IF EXISTS `zone_getWarehouse`; + +DELIMITER $$ +USE `vn`$$ +CREATE DEFINER=`root`@`%` PROCEDURE `zone_getWarehouse`(vAddress INT, vLanded DATE, vWarehouse INT) +BEGIN +/** + * Devuelve el listado de agencias disponibles para la fecha, + * dirección y almacén pasados. + * + * @param vAddress + * @param vWarehouse warehouse + * @param vLanded Fecha de recogida + * @select Listado de agencias disponibles + */ + + CALL zone_getFromGeo(address_getGeo(vAddress)); + CALL zone_getOptionsForLanding(vLanded, FALSE); + + SELECT am.id agencyModeFk, + am.name agencyMode, + am.description, + am.deliveryMethodFk, + TIMESTAMPADD(DAY, -zo.travelingDays, vLanded) shipped, + zw.warehouseFk, + z.id zoneFk + FROM tmp.zoneOption zo + JOIN zone z ON z.id = zo.zoneFk + JOIN agencyMode am ON am.id = z.agencyModeFk + JOIN zoneWarehouse zw ON zw.zoneFk = zo.zoneFk + WHERE zw.warehouseFk = vWarehouse + GROUP BY z.agencyModeFk + ORDER BY agencyMode; + + DROP TEMPORARY TABLE + tmp.zone, + tmp.zoneOption; + +END$$ + +DELIMITER ; + +USE `vn`; +DROP procedure IF EXISTS `zone_getWarehouse__`; + +DELIMITER $$ +USE `vn`$$ +CREATE DEFINER=`root`@`%` PROCEDURE `zone_getWarehouse__`(vAddress INT, vLanded DATE, vWarehouse INT) +BEGIN +/** + * Devuelve el listado de agencias disponibles para la fecha, + * dirección y almacén pasados. + * + * @param vAddress + * @param vWarehouse warehouse + * @param vLanded Fecha de recogida + * @select Listado de agencias disponibles + */ + + CALL zone_getFromGeo(address_getGeo(vAddress)); + CALL zone_getOptionsForLanding(vLanded, FALSE); + + SELECT am.id agencyModeFk, + am.name agencyMode, + am.description, + am.deliveryMethodFk, + TIMESTAMPADD(DAY, -zo.travelingDays, vLanded) shipped, + zw.warehouseFk, + z.id zoneFk + FROM tmp.zoneOption zo + JOIN zone z ON z.id = zo.zoneFk + JOIN agencyMode am ON am.id = z.agencyModeFk + JOIN zoneWarehouse zw ON zw.zoneFk = zo.zoneFk + WHERE zw.warehouseFk + GROUP BY z.agencyModeFk + ORDER BY agencyMode; + + DROP TEMPORARY TABLE + tmp.zone, + tmp.zoneOption; + +END$$ + +DELIMITER ; + + diff --git a/db/changes/10180-holyWeek/00-ticketWeekly.sql b/db/changes/10180-holyWeek/00-ticketWeekly.sql new file mode 100644 index 000000000..05d65e124 --- /dev/null +++ b/db/changes/10180-holyWeek/00-ticketWeekly.sql @@ -0,0 +1,13 @@ +ALTER TABLE `vn`.`ticketWeekly` +ADD COLUMN `agencyModeFk` INT(11) NULL DEFAULT NULL AFTER `weekDay`, +ADD INDEX `agencyModeFk_idx` (`agencyModeFk` ASC); + +ALTER TABLE `vn`.`ticketWeekly` +ADD CONSTRAINT `agencyModeFk` + FOREIGN KEY (`agencyModeFk`) + REFERENCES `vn`.`agencyMode` (`id`) + ON DELETE SET NULL + ON UPDATE CASCADE; + +ALTER TABLE `vn`.`ticketWeekly` +CHANGE COLUMN `weekDay` `weekDay` TINYINT(1) NOT NULL COMMENT 'funcion de mysql Lunes = 0, Domingo = 6' ; diff --git a/db/changes/10180-holyWeek/00-ticket_cloneWeekly.sql b/db/changes/10180-holyWeek/00-ticket_cloneWeekly.sql new file mode 100644 index 000000000..544296feb --- /dev/null +++ b/db/changes/10180-holyWeek/00-ticket_cloneWeekly.sql @@ -0,0 +1,130 @@ +DELIMITER $$ +USE `vn`$$ +CREATE DEFINER=`root`@`%` PROCEDURE `ticket_cloneWeekly`(IN vWeek INT) +BEGIN + DECLARE vIsDone BOOL; + DECLARE vLanding DATE; + DECLARE vShipment DATE; + DECLARE vWarehouse INT; + DECLARE vTicket INT; + DECLARE vWeekDay INT; + DECLARE vClient INT; + DECLARE vEmpresa INT; + DECLARE vAddressFk INT; + DECLARE vAgencyModeFk INT; + DECLARE vNewTicket INT; + DECLARE vYear INT; + + DECLARE rsTicket CURSOR FOR + SELECT tw.ticketFk, weekDay, t.clientFk, t.warehouseFk, t.companyFk, t.addressFk, tw.agencyModeFk + FROM ticketWeekly tw + JOIN ticket t ON tt.ticketFk = t.id; + + DECLARE CONTINUE HANDLER FOR NOT FOUND SET vIsDone = TRUE; + + SET vYear = YEAR(CURDATE()) + IF(vWeek < WEEK(CURDATE()),1, 0); + + OPEN rsTicket; + + myLoop: LOOP + BEGIN + DECLARE vError TEXT; + DECLARE vSalesPersonEmail VARCHAR(150); + DECLARE vMailSent BOOL; + DECLARE vSubject VARCHAR(150); + DECLARE vMessage TEXT; + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION + BEGIN + GET DIAGNOSTICS CONDITION 1 + vError = MESSAGE_TEXT; + + END; + + SET vIsDone = FALSE; + FETCH rsTicket INTO vTicket, vWeekDay, vClient, vWarehouse, vEmpresa, vAddressFk, vAgencyModeFk; + + IF vIsDone THEN + + LEAVE myLoop; + END IF; + SELECT date INTO vShipment + FROM `time` + WHERE `year` = vYear AND `week` = vWeek + AND WEEKDAY(date) = vWeekDay; + + -- busca si el ticket ya ha sido clonado + IF (SELECT COUNT(*) FROM vn.ticket tOrig + JOIN vn.sale saleOrig ON tOrig.id = saleOrig.ticketFk + JOIN vn.saleCloned sc ON sc.saleOriginalFk = saleOrig.id + JOIN vn.sale saleClon ON saleClon.id = sc.saleClonedFk + JOIN vn.ticket tClon ON tClon.id = saleClon.ticketFk + WHERE tOrig.id = vTicket AND DATE(tClon.shipped) = vShipment) > 0 + THEN + ITERATE myLoop; + END IF; + CALL vn.zone_getLanded(vShipment, vAddressFk, vAgencyModeFk, vWarehouse); + + SELECT landed INTO vLanding from tmp.zoneGetLanded LIMIT 1; + + CALL vn.ticketCreateWithoutZone(vClient, vShipment, vWarehouse, vEmpresa, vAddressFk, vAgencyModeFk, NULL, vLanding, account.userGetId(), vNewTicket); + + IF (vLanding IS NULL) THEN + + SELECT e.email INTO vSalesPersonEmail + FROM vn.client c + JOIN vn.worker sp ON sp.id = c.salesPersonFk + JOIN account.emailUser e ON e.userFk = sp.userFk + WHERE c.id = vClient; + + SET vSubject = CONCAT('Turnos - No se ha podido clonar correctamente el ticket ', vTicket, + ' para el dia: ', vShipment); + SET vMessage = CONCAT('No se ha podido clonar el ticket ', vTicket, + ' para el dia: ', vShipment, + ' porque no hay una zona de envío disponible. Se ha creado el ticket: ', vNewTicket, + ' pero ha que revisar las fechas y la agencia'); + + SELECT COUNT(*) INTO vMailSent + FROM vn.mail + WHERE sender = vSalesPersonEmail + AND subject = vSubject; + + IF NOT vMailSent THEN + INSERT INTO vn.mail (sender,`subject`,body) + VALUES (vSalesPersonEmail, vSubject, vMessage); + END IF; + CALL vn.ticketStateUpdate (vNewTicket, 'FIXING'); + END IF; + + INSERT INTO vn.sale (ticketFk, itemFk, concept, quantity, price, discount, priceFixed, isPriceFixed) + SELECT vNewTicket, saleOrig.itemFk , saleOrig.concept , saleOrig.quantity, saleOrig.price , saleOrig.discount, saleOrig.priceFixed, saleOrig.isPriceFixed + FROM vn.ticket tOrig + JOIN vn.sale saleOrig ON tOrig.id = saleOrig.ticketFk + LEFT JOIN vn.saleCloned sc ON sc.saleOriginalFk = saleOrig.id + LEFT JOIN vn.sale saleClon ON saleClon.id = sc.saleClonedFk + LEFT JOIN vn.ticket tClon ON tClon.id = saleClon.ticketFk AND DATE(tClon.shipped) = vShipment + WHERE tOrig.id = vTicket AND saleClon.id IS NULL; + + INSERT IGNORE INTO vn.saleCloned(saleOriginalFk, saleClonedFk) + SELECT saleOriginal.id, saleClon.id + FROM vn.sale saleOriginal + JOIN vn.sale saleClon ON saleOriginal.itemFk = saleClon.itemFk AND saleOriginal.quantity = saleClon.quantity + WHERE saleOriginal.ticketFk = vTicket AND saleClon.ticketFk = vNewTicket; + + INSERT INTO ticketRequest (description, ordered, shipped, salesPersonCode, buyerCode, quantity, price, + itemFk ,clientFk, response, total, buyed, saleFk) + SELECT tr.description, tr.ordered, tr.shipped, tr.salesPersonCode, tr.buyerCode, tr.quantity, tr.price, + tr.itemFk, tr.clientFk, tr.response, tr.total, tr.buyed, tr.saleFk + FROM sale s JOIN ticketRequest tr ON tr.saleFk = s.id + JOIN sale s2 ON s.concept = s2.concept AND s.quantity = s2.quantity AND m.Id_Article = m2.Id_Article + WHERE s.ticketFk = vTicket AND s2.ticketFk = vNewTicket; + + CALL vn.ticketCalculateClon(vNewTicket, vTicket); + END; + END LOOP; + + CLOSE rsTicket; + +END$$ + +DELIMITER ; + diff --git a/db/changes/10180-holyWeek/01-migrateFromTicketToTicketWeekly.sql b/db/changes/10180-holyWeek/01-migrateFromTicketToTicketWeekly.sql new file mode 100644 index 000000000..939a8e73c --- /dev/null +++ b/db/changes/10180-holyWeek/01-migrateFromTicketToTicketWeekly.sql @@ -0,0 +1,6 @@ +UPDATE vn.ticketWeekly tw + JOIN vn.ticket t ON t.id = tw.ticketFk + JOIN vn.agencyMode am ON am.id = t.agencyModeFk +SET tw.agencyModeFk = t.agencyModeFk +WHERE am.name NOT LIKE '%turno%'; + diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index fbe33159a..792787154 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -101,6 +101,16 @@ INSERT INTO `vn`.`sector`(`id`, `description`, `warehouseFk`, `isPreviousPrepare (1, 'First sector', 1, 1, 'FIRST', 999, 999), (2, 'Second sector', 2, 0, 'SECOND', 100, 150); +INSERT INTO `vn`.`parking` (`id`, `column`, `row`, `sectorFk`, `code`, `pickingOrder`) + VALUES + ('1', '700', '01', '1', '700-01', '70001'), + ('2', '700', '02', '2', '700-02', '70002'); + +INSERT INTO `vn`.`shelving` (`code`, `parkingFk`, `isPrinted`, `priority`, `parked`, `userFk`) + VALUES + ('GVC', '1', '0', '1', '0', '106'), + ('HEJ', '2', '0', '1', '0', '106'); + INSERT INTO `vn`.`warehouseAlias`(`id`, `name`) VALUES (1, 'Main Warehouse'); @@ -156,7 +166,7 @@ UPDATE `vn`.`agencyMode` SET `id` = 8 WHERE `name` = 'Silla247Expensive'; UPDATE `vn`.`agencyMode` SET `id` = 23 WHERE `name` = 'Refund'; UPDATE `vn`.`agencyMode` SET `id` = 10 WHERE `name` = 'Other agency'; -UPDATE `vn`.`agencyMode` SET `deliveryMethodFk` = 1 WHERE `id` = 1; +UPDATE `vn`.`agencyMode` SET `deliveryMethodFk` = 3 WHERE `id` = 1; UPDATE `vn`.`agencyMode` SET `deliveryMethodFk` = 1 WHERE `id` = 2; UPDATE `vn`.`agencyMode` SET `deliveryMethodFk` = 2 WHERE `id` = 3; UPDATE `vn`.`agencyMode` SET `deliveryMethodFk` = 1 WHERE `id` = 4; @@ -471,19 +481,19 @@ INSERT INTO `vn`.`invoiceOutSerial` (`code`, `description`, `isTaxed`, `taxAreaF INSERT INTO `vn`.`zone` (`id`, `name`, `hour`, `agencyModeFk`, `travelingDays`, `price`, `bonus`, `m3Max`) VALUES - (1, 'Zone pickup A', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 1, 0, 0, 0, 30.50), - (2, 'Zone pickup B', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 1, 0, 0, 0, 30.50), - (3, 'Zone 247 A', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 7, 1, 2, 0, 40.50), - (4, 'Zone 247 B', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 7, 1, 2, 0, 40.50), - (5, 'Zone expensive A', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 8, 1, 1000, 0, 50.50), - (6, 'Zone expensive B', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 8, 1, 1000, 0, 50.50), - (7, 'Zone refund', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 23, 0, 0, 0, 60.50), - (8, 'Zone others', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 10, 0, 0, 0, 60.50), - (9, 'Zone superMan', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 2, 0, 0, 0, NULL), - (10, 'Zone teleportation', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 3, 0, 0, 0, NULL), - (11, 'Zone pickup C', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 1, 0, 0, 0, NULL), - (12, 'Zone entanglement', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 4, 0, 0, 0, NULL), - (13, 'Zone quantum break', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 5, 0, 0, 0, NULL); + (1, 'Zone pickup A', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 1, 0, 0, 0, 30.50), + (2, 'Zone pickup B', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 1, 0, 0, 0, 30.50), + (3, 'Zone 247 A', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 7, 1, 2, 0, 40.50), + (4, 'Zone 247 B', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 7, 1, 2, 0, 40.50), + (5, 'Zone expensive A', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 8, 1, 1000, 0, 50.50), + (6, 'Zone expensive B', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 8, 1, 1000, 0, 50.50), + (7, 'Zone refund', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 23, 0, 0, 0, 60.50), + (8, 'Zone others', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 10, 0, 0, 0, 60.50), + (9, 'Zone superMan', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 2, 0, 0, 0, NULL), + (10, 'Zone teleportation', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 3, 0, 0, 0, NULL), + (11, 'Zone pickup C', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 1, 0, 0, 0, NULL), + (12, 'Zone entanglement', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 4, 0, 0, 0, NULL), + (13, 'Zone quantum break', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 5, 0, 0, 0, NULL); INSERT INTO `vn`.`zoneWarehouse` (`id`, `zoneFk`, `warehouseFk`) VALUES @@ -554,6 +564,10 @@ INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `des (10, 23, 4, 'Reclama ticket: 8'), (11, 24, 4, 'Reclama ticket: 7'); +-- FIX for state hours on local, inter_afterInsert +UPDATE vncontrol.inter SET odbc_date = DATE_ADD(CURDATE(), INTERVAL -10 SECOND); + + INSERT INTO `vn`.`ticketTracking`(`ticketFk`, `stateFk`, `workerFk`, `created`) VALUES (1, 16, 5 , DATE_ADD(NOW(), INTERVAL -1 MONTH)), @@ -928,6 +942,18 @@ INSERT INTO `vn`.`saleComponent`(`saleFk`, `componentFk`, `value`) (32, 36, -92.324), (32, 39, 0.994); +INSERT INTO `vn`.`itemShelving` (`id`, `itemFk`, `shelvingFk`, `shelve`, `deep`, `quantity`, `visible`, `available`, `grouping`, `packing`, `level`, `userFk`) + VALUES + ('1', '2', 'GVC', 'A', '0', '1', '1', '1', '1', '1', '1', '106'), + ('2', '4', 'HEJ', 'A', '0', '2', '1', '1', '1', '1', '1', '106'); + +INSERT INTO `vn`.`itemShelvingSale` (`itemShelvingFk`, `saleFk`, `quantity`, `created`, `userFk`) + VALUES + ('1', '1', '1', '', '106'), + ('2', '2', '5', '', '106'), + ('1', '7', '1', '', '106'), + ('2', '8', '5', '', '106'); + INSERT INTO `vncontrol`.`accion`(`accion_id`, `accion`) VALUES (3, 'ACTION ONE'), @@ -1913,14 +1939,10 @@ INSERT INTO `vn`.`zoneEvent`(`zoneFk`, `type`, `dated`) (7, 'day', DATE_ADD(CURDATE(), INTERVAL +3 DAY)), (7, 'day', DATE_ADD(CURDATE(), INTERVAL +4 DAY)), (7, 'day', DATE_ADD(CURDATE(), INTERVAL +5 DAY)), - (7, 'day', DATE_ADD(CURDATE(), INTERVAL +6 DAY)), - (8, 'day', CURDATE()), - (8, 'day', DATE_ADD(CURDATE(), INTERVAL +1 DAY)), - (8, 'day', DATE_ADD(CURDATE(), INTERVAL +2 DAY)), - (8, 'day', DATE_ADD(CURDATE(), INTERVAL +3 DAY)), - (8, 'day', DATE_ADD(CURDATE(), INTERVAL +4 DAY)), - (8, 'day', DATE_ADD(CURDATE(), INTERVAL +5 DAY)), - (8, 'day', DATE_ADD(CURDATE(), INTERVAL +6 DAY)); + (7, 'day', DATE_ADD(CURDATE(), INTERVAL +6 DAY)); + +INSERT INTO `vn`.`zoneEvent`(`zoneFk`, `type`, `weekDays`) + VALUES (8, 'indefinitely', 'mon,tue,wed,thu,fri,sat,sun'); INSERT INTO `vn`.`workerTimeControl`(`userFk`, `timed`, `manual`, `direction`) VALUES @@ -1954,11 +1976,13 @@ INSERT INTO `vn`.`dmsType`(`id`, `name`, `path`, `readRoleFk`, `writeRoleFk`, `c INSERT INTO `vn`.`dms`(`id`, `dmsTypeFk`, `file`, `contentType`, `workerFk`, `warehouseFk`, `companyFk`, `hardCopyNumber`, `hasFile`, `reference`, `description`, `created`) VALUES - (1, 14, '1.txt', 'text/plain', 5, 1, 442, NULL, FALSE, 'Ticket:11', 'Ticket:11 dms for the ticket', CURDATE()), - (2, 5, '2.txt', 'text/plain', 5, 1, 442, 1, TRUE, 'Client:104', 'Client:104 dms for the client', CURDATE()), - (3, 5, '3.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Client: 104', 'Client:104 readme', CURDATE()), - (4, 3, '4.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Worker: 106', 'Worker:106 readme', CURDATE()), - (5, 5, '5.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'travel: 1', 'dmsForThermograph', CURDATE()); + (1, 14, '1.txt', 'text/plain', 5, 1, 442, NULL, FALSE, 'Ticket:11', 'Ticket:11 dms for the ticket', CURDATE()), + (2, 5, '2.txt', 'text/plain', 5, 1, 442, 1, TRUE, 'Client:104', 'Client:104 dms for the client', CURDATE()), + (3, 5, '3.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Client: 104', 'Client:104 readme', CURDATE()), + (4, 3, '4.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'Worker: 106', 'Worker:106 readme', CURDATE()), + (5, 5, '5.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'travel: 1', 'dmsForThermograph', CURDATE()), + (6, 5, '6.txt', 'text/plain', 5, 1, 442, NULL, TRUE, 'NotExists', 'DoesNotExists', CURDATE()); + INSERT INTO `vn`.`ticketDms`(`ticketFk`, `dmsFk`) VALUES @@ -1969,9 +1993,10 @@ INSERT INTO `vn`.`clientDms`(`clientFk`, `dmsFk`) (104, 2), (104, 3); -INSERT INTO `vn`.`workerDocument`(`id`, `worker`, `document`) +INSERT INTO `vn`.`workerDocument`(`id`, `worker`, `document`,`isReadableByWorker`) VALUES - (1, 106, 4); + (1, 106, 4, TRUE), + (2, 107, 3, FALSE); INSERT INTO `vn`.`device` (`sn`, `model`, `userFk`) VALUES diff --git a/e2e/dms/a87/4.txt b/e2e/dms/a87/4.txt new file mode 100644 index 000000000..a46bfbeda --- /dev/null +++ b/e2e/dms/a87/4.txt @@ -0,0 +1 @@ +File: 4.txt. It works! \ No newline at end of file diff --git a/e2e/helpers/extensions.js b/e2e/helpers/extensions.js index 5fe362043..636819860 100644 --- a/e2e/helpers/extensions.js +++ b/e2e/helpers/extensions.js @@ -1,4 +1,3 @@ -import {url as defaultURL} from './config'; function checkVisibility(selector) { let selectorMatches = document.querySelectorAll(selector); @@ -59,19 +58,31 @@ let actions = { return document.location.hash.includes(expectedHash); }, {}, expectedHash); } catch (error) { - throw new Error(`failed to reach URL containing: ${expectedHash}`); + throw new Error(`Failed to reach URL containing: ${expectedHash}`); } - await this.waitForContentLoaded(); + await this.waitForSpinnerLoad(); return true; }, - waitUntilNotPresent: async function(selector) { - await this.wait(selector => { - return document.querySelector(selector) == null; - }, selector); - }, - doLogin: async function(userName, password = 'nightmare') { + let state = await this.getState(); + + if (state != 'login') { + try { + await this.gotoState('login'); + } catch (err) { + let dialog = await this.evaluate( + () => document.querySelector('button[response="accept"]')); + + if (dialog) + await this.waitToClick('button[response="accept"]'); + else + throw err; + } + } + + await this.waitForState('login'); + await this.waitForSelector(`vn-login vn-textfield[ng-model="$ctrl.user"]`, {visible: true}); await this.clearInput(`vn-login vn-textfield[ng-model="$ctrl.user"]`); await this.write(`vn-login vn-textfield[ng-model="$ctrl.user"]`, userName); @@ -81,27 +92,14 @@ let actions = { }, login: async function(userName) { - await this.goto(`${defaultURL}/#!/login`); - let dialog = await this.evaluate(() => { - return document.querySelector('button[response="accept"]'); - }); - if (dialog) - await this.waitToClick('button[response="accept"]'); - await this.doLogin(userName); - await this.waitForFunction(() => { - return document.location.hash === '#!/'; - }, {}); + await this.waitForState('home'); }, selectModule: async function(moduleName) { - let snakeName = moduleName.replace(/[\w]([A-Z])/g, m => { - return m[0] + '-' + m[1]; - }).toLowerCase(); - - let selector = `vn-home a[ui-sref="${moduleName}.index"]`; - await this.waitToClick(selector); - await this.expectURL(snakeName); + let state = `${moduleName}.index`; + await this.waitToClick(`vn-home a[ui-sref="${state}"]`); + await this.waitForState(state); }, loginAndModule: async function(userName, moduleName) { @@ -109,56 +107,85 @@ let actions = { await this.selectModule(moduleName); }, - datePicker: async function(selector, changeMonth, day) { - let date = new Date(); - if (changeMonth) date.setMonth(date.getMonth() + changeMonth); - date.setDate(day ? day : 16); - date = date.toISOString().substr(0, 10); - - await this.wait(selector); - await this.evaluate((selector, date) => { - let input = document.querySelector(selector).$ctrl.input; - input.value = date; - input.dispatchEvent(new Event('change')); - }, selector, date); + getState: async function() { + return await this.evaluate(() => { + let $state = angular.element(document.body).injector().get('$state'); + return $state.current.name; + }); }, - pickTime: async function(selector, time) { - await this.wait(selector); - await this.evaluate((selector, time) => { - let input = document.querySelector(selector).$ctrl.input; - input.value = time; - input.dispatchEvent(new Event('change')); - }, selector, time); + gotoState: async function(state, params) { + await this.evaluate((state, params) => { + let $state = angular.element(document.body).injector().get('$state'); + return $state.go(state, params); + }, state, params); + await this.waitForSpinnerLoad(); }, - clearTextarea: async function(selector) { - await this.waitForSelector(selector, {visible: true}); - await this.evaluate(inputSelector => { - return document.querySelector(`${inputSelector} textarea`).value = ''; - }, selector); + waitForState: async function(state) { + await this.waitFor(state => { + let $state = angular.element(document.body).injector().get('$state'); + return !$state.transition && $state.is(state); + }, {}, state); + await this.waitForSpinnerLoad(); }, - clearInput: async function(selector) { - await this.waitForSelector(selector); + waitForTransition: async function() { + await this.waitFor(() => { + const $state = angular.element(document.body).injector().get('$state'); + return !$state.transition; + }); + await this.waitForSpinnerLoad(); + }, - let field = await this.evaluate(selector => { - return document.querySelector(`${selector} input`).closest('.vn-field').$ctrl.field; - }, selector); + accessToSection: async function(state) { + await this.waitForSelector('vn-left-menu'); + let nested = await this.evaluate(state => { + return document.querySelector(`vn-left-menu li li > a[ui-sref="${state}"]`) != null; + }, state); - if ((field != null && field != '') || field == '0') { - let coords = await this.evaluate(selector => { - let rect = document.querySelector(selector).getBoundingClientRect(); - return {x: rect.x + (rect.width / 2), y: rect.y + (rect.height / 2), width: rect.width}; + if (nested) { + let selector = 'vn-left-menu vn-item-section > vn-icon[icon=keyboard_arrow_down]'; + await this.evaluate(selector => { + document.querySelector(selector).scrollIntoViewIfNeeded(); }, selector); - await this.mouse.move(coords.x, coords.y); - await this.waitForSelector(`${selector} [icon="clear"]`, {visible: true}); - await this.waitToClick(`${selector} [icon="clear"]`); + await this.waitToClick(selector); + await this.wait('vn-left-menu .expanded'); } - await this.evaluate(selector => { - return document.querySelector(`${selector} input`).closest('.vn-field').$ctrl.field == ''; - }, selector); + await this.evaluate(state => { + let navButton = document.querySelector(`vn-left-menu li > a[ui-sref="${state}"]`); + navButton.scrollIntoViewIfNeeded(); + return navButton.click(); + }, state); + + await this.waitForState(state); + }, + + reloadSection: async function(state) { + await this.click('vn-icon[icon="desktop_windows"]'); + await this.accessToSection(state); + }, + + forceReloadSection: async function(sectionRoute) { + await this.waitToClick('vn-icon[icon="desktop_windows"]'); + await this.waitToClick('button[response="accept"]'); + await this.wait('vn-card.summary'); + await this.waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`); + }, + + doSearch: async function(searchValue) { + await this.clearInput('vn-searchbar'); + if (searchValue) + await this.write('vn-searchbar', searchValue); + + await this.waitToClick('vn-searchbar vn-icon[icon="search"]'); + await this.waitForTransition(); + }, + + accessToSearchResult: async function(searchValue) { + await this.doSearch(searchValue); + await this.waitFor('.vn-descriptor'); }, getProperty: async function(selector, property) { @@ -167,6 +194,12 @@ let actions = { }, selector, property); }, + getClassName: async function(selector) { + const element = await this.$(selector); + const handle = await element.getProperty('className'); + return await handle.jsonValue(); + }, + waitPropertyLength: async function(selector, property, minLength) { await this.waitForFunction((selector, property, minLength) => { const element = document.querySelector(selector); @@ -214,6 +247,11 @@ let actions = { await this.waitForTextInField(selector, text); }, + overwrite: async function(selector, text) { + await this.clearInput(selector); + await this.write(selector, text); + }, + waitToClick: async function(selector) { await this.waitForSelector(selector); await this.waitForFunction(checkVisibility, {}, selector); @@ -320,66 +358,102 @@ let actions = { }, hideSnackbar: async function() { - await this.waitFor(750); // holds up for the snackbar to be visible for a small period of time. + // Holds up for the snackbar to be visible for a small period of time. + if (process.env.E2E_DEBUG) + await this.waitFor(300); + await this.evaluate(() => { - let hideButton = document.querySelector('#shapes .shown button'); + let hideButton = document + .querySelector('vn-snackbar .shape.shown button'); if (hideButton) - return document.querySelector('#shapes .shown button').click(); + return hideButton.click(); }); + await this.waitFor('vn-snackbar .shape.shown', {hidden: true}); }, - waitForLastSnackbar: async function() { - const selector = 'vn-snackbar .shown .text'; - + waitForSnackbar: async function() { + const selector = 'vn-snackbar .shape.shown'; await this.waitForSelector(selector); - let snackBarText = await this.evaluate(selector => { + + let message = await this.evaluate(selector => { const shape = document.querySelector(selector); + const message = { + text: shape.querySelector('.text').innerText + }; - return shape.innerText; + const types = ['error', 'success']; + for (let type of types) { + if (shape.classList.contains(type)) { + message.type = type; + break; + } + } + + return message; }, selector); + await this.hideSnackbar(); - return snackBarText; + return message; }, - accessToSearchResult: async function(searchValue) { - await this.clearInput('vn-searchbar'); - await this.write('vn-searchbar', searchValue); - await this.waitToClick('vn-searchbar vn-icon[icon="search"]'); - await this.waitForContentLoaded(); + pickDate: async function(selector, date) { + date = date || new Date(); + + const tzoffset = date.getTimezoneOffset() * 60000; + const localIso = (new Date(date.getTime() - tzoffset)) + .toISOString(); + + await this.wait(selector); + await this.evaluate((selector, localIso) => { + let input = document.querySelector(selector).$ctrl.input; + input.value = localIso.substr(0, 10); + input.dispatchEvent(new Event('change')); + }, selector, localIso); }, - accessToSection: async function(sectionRoute) { - await this.waitForSelector('vn-left-menu'); - let nested = await this.evaluate(sectionRoute => { - return document.querySelector(`vn-left-menu li li > a[ui-sref="${sectionRoute}"]`) != null; - }, sectionRoute); + pickTime: async function(selector, time) { + await this.wait(selector); + await this.evaluate((selector, time) => { + let input = document.querySelector(selector).$ctrl.input; + input.value = time; + input.dispatchEvent(new Event('change')); + }, selector, time); + }, - if (nested) { - await this.waitToClick('vn-left-menu vn-item-section > vn-icon[icon=keyboard_arrow_down]'); - await this.wait('vn-left-menu .expanded'); + clearTextarea: async function(selector) { + await this.waitForSelector(selector, {visible: true}); + await this.evaluate(inputSelector => { + return document.querySelector(`${inputSelector} textarea`).value = ''; + }, selector); + }, + + clearInput: async function(selector) { + await this.waitForSelector(selector); + + let field = await this.evaluate(selector => { + return document.querySelector(`${selector} input`).closest('.vn-field').$ctrl.field; + }, selector); + + if ((field != null && field != '') || field == '0') { + let coords = await this.evaluate(selector => { + let rect = document.querySelector(selector).getBoundingClientRect(); + return {x: rect.x + (rect.width / 2), y: rect.y + (rect.height / 2), width: rect.width}; + }, selector); + await this.mouse.move(coords.x, coords.y); + await this.waitForSelector(`${selector} [icon="clear"]`, {visible: true}); + await this.waitToClick(`${selector} [icon="clear"]`); } - await this.evaluate(sectionRoute => { - let navButton = document.querySelector(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`); - navButton.scrollIntoViewIfNeeded(); - return navButton.click(); - }, sectionRoute); - await this.waitForNavigation({waitUntil: ['networkidle0']}); - await this.waitForContentLoaded(); + await this.evaluate(selector => { + return document.querySelector(`${selector} input`).closest('.vn-field').$ctrl.field == ''; + }, selector); }, autocompleteSearch: async function(selector, searchValue) { let builtSelector = await this.selectorFormater(selector); - await this.waitForContentLoaded(); await this.waitToClick(selector); - await this.waitForSelector(selector => { - document - .querySelector(`${selector} vn-drop-down`).$ctrl.content - .querySelectorAll('li'); - }, selector); - - await this.write('.vn-drop-down.vn-popover.vn-popup.shown vn-textfield', searchValue); + await this.write('.vn-drop-down.shown vn-textfield', searchValue); try { await this.waitForFunction((selector, searchValue) => { @@ -391,7 +465,7 @@ let actions = { }, {}, selector, searchValue); } catch (error) { let inputValue = await this.evaluate(() => { - return document.querySelector('.vn-drop-down.vn-popover.vn-popup.shown vn-textfield input').value; + return document.querySelector('.vn-drop-down.shown vn-textfield input').value; }); throw new Error(`${builtSelector} value is ${inputValue}! ${error}`); } @@ -401,29 +475,7 @@ let actions = { .includes(searchValue.toLowerCase()); }, {}, builtSelector, searchValue); - await this.waitForMutation('.vn-drop-down', 'childList'); - await this.waitForContentLoaded(); - }, - - reloadSection: async function(sectionRoute) { - await this.waitForContentLoaded(); - await Promise.all([ - this.waitForNavigation({waitUntil: 'networkidle0'}), - this.click('vn-icon[icon="desktop_windows"]', {}), - ]); - - await Promise.all([ - this.waitForNavigation({waitUntil: 'networkidle0'}), - this.click(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`, {}), - ]); - await this.waitForContentLoaded(); - }, - - forceReloadSection: async function(sectionRoute) { - await this.waitToClick('vn-icon[icon="desktop_windows"]'); - await this.waitToClick('button[response="accept"]'); - await this.wait('vn-card.summary'); - await this.waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`); + await this.waitFor('.vn-drop-down', {hidden: true}); }, checkboxState: async function(selector) { @@ -457,7 +509,7 @@ let actions = { }, waitForSpinnerLoad: async function() { - await this.waitUntilNotPresent('vn-topbar vn-spinner'); + await this.waitFor('vn-topbar vn-spinner', {hidden: true}); }, waitForWatcherData: async function(selector) { @@ -509,35 +561,42 @@ let actions = { closePopup: async function(selector) { await Promise.all([ this.keyboard.press('Escape'), - this.waitForSelector('.vn-popup', {hidden: true}), + this.waitFor('.vn-popup', {hidden: true}), ]); }, - waitForContentLoaded: async function() { - await this.waitFor(1000); - }, - respondToDialog: async function(response) { - await this.waitForSelector('.vn-dialog.vn-popup.shown'); + await this.waitForSelector('.vn-dialog.shown'); const firstCount = await this.evaluate(text => { - const dialogs = document.querySelectorAll('.vn-dialog.vn-popup'); + const dialogs = document.querySelectorAll('.vn-dialog'); const dialogOnTop = dialogs[dialogs.length - 1]; const button = dialogOnTop.querySelector(`div.buttons [response="${text}"]`); button.click(); return dialogs.length; }, response); - this.waitForFunction(firstCount => { - const dialogs = document.querySelectorAll('.vn-dialog.vn-popup'); + await this.waitForFunction(firstCount => { + const dialogs = document.querySelectorAll('.vn-dialog'); return dialogs.length < firstCount; }, {}, firstCount); + }, + + waitForContentLoaded: async function() { + await this.waitForSpinnerLoad(); } }; export function extendPage(page) { for (let name in actions) { page[name] = async(...args) => { - return await actions[name].call(page, ...args); + try { + return await actions[name].apply(page, args); + } catch (err) { + let stringArgs = args + .map(i => typeof i == 'function' ? 'Function' : i) + .join(', '); + throw new Error(`.${name}(${stringArgs}): ${err.message}`); + } }; } diff --git a/e2e/helpers/puppeteer.js b/e2e/helpers/puppeteer.js index 1ca0726c0..02ef82b1b 100644 --- a/e2e/helpers/puppeteer.js +++ b/e2e/helpers/puppeteer.js @@ -4,16 +4,26 @@ import {extendPage} from './extensions'; import {url as defaultURL} from './config'; export async function getBrowser() { - let headless = !process.env.E2E_SHOW; + const args = [ + `--no-sandbox`, + `--window-size=${ 1920 },${ 1080 }` + ]; + + let env = process.env; + + if (env.E2E_DEBUG) { + args.push('--auto-open-devtools-for-tabs'); + env.E2E_SHOW = true; + } + + const headless = !env.E2E_SHOW; const browser = await Puppeteer.launch({ - args: [ - '--no-sandbox', - `--window-size=${ 1920 },${ 1080 }` - ], + args, defaultViewport: null, headless: headless, slowMo: 0, // slow down by ms }); + let page = (await browser.pages())[0]; await page.evaluateOnNewDocument(() => { Object.defineProperty(navigator, 'language', { @@ -28,8 +38,8 @@ export async function getBrowser() { }); }); page = extendPage(page); - page.setDefaultTimeout(10000); - await page.goto(defaultURL, {waitUntil: 'networkidle0'}); + page.setDefaultTimeout(4000); + await page.goto(defaultURL, {waitUntil: 'load'}); return {page, close: browser.close.bind(browser)}; } diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 0cee79405..551573836 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -2,6 +2,8 @@ export default { globalItems: { applicationsMenuButton: '#apps', + userMenuButton: '#user', + logoutButton: '#logout', applicationsMenuVisible: '.modules-menu', clientsButton: '.modules-menu > li[ui-sref="client.index"]', itemsButton: '.modules-menu > li[ui-sref="item.index"]', @@ -10,7 +12,6 @@ export default { claimsButton: '.modules-menu > li[ui-sref="claim.index"]', returnToModuleIndexButton: 'a[ui-sref="order.index"]', homeButton: 'vn-topbar > div.side.start > a', - userMenuButton: '#user', userLocalWarehouse: '.user-popover vn-autocomplete[ng-model="$ctrl.localWarehouseFk"]', userLocalBank: '.user-popover vn-autocomplete[ng-model="$ctrl.localBankFk"]', userLocalCompany: '.user-popover vn-autocomplete[ng-model="$ctrl.localCompanyFk"]', @@ -99,7 +100,6 @@ export default { receivedCoreVNLCheckbox: 'vn-client-billing-data vn-check[label="Received core VNL"]', receivedB2BVNLCheckbox: 'vn-client-billing-data vn-check[label="Received B2B VNL"]', swiftBic: 'vn-client-billing-data vn-autocomplete[ng-model="$ctrl.client.bankEntityFk"]', - clearswiftBicButton: 'vn-client-billing-data vn-autocomplete[ng-model="$ctrl.client.bankEntityFk"] .icons > vn-icon[icon=clear]', newBankEntityButton: 'vn-client-billing-data vn-icon-button[vn-tooltip="New bank entity"] > button', newBankEntityName: '.vn-dialog.shown vn-textfield[ng-model="$ctrl.newBankEntity.name"]', newBankEntityBIC: '.vn-dialog.shown vn-textfield[ng-model="$ctrl.newBankEntity.bic"]', @@ -178,12 +178,11 @@ export default { }, clientBalance: { - balanceButton: 'vn-left-menu a[ui-sref="client.card.balance.index"]', company: 'vn-client-balance-index vn-autocomplete[ng-model="$ctrl.companyId"]', newPaymentButton: `vn-float-button`, newPaymentBank: '.vn-dialog.shown vn-autocomplete[ng-model="$ctrl.receipt.bankFk"]', newPaymentAmount: '.vn-dialog.shown vn-input-number[ng-model="$ctrl.receipt.amountPaid"]', - saveButton: '.vn-dialog.shown vn-button[label="Save"]', + saveButton: '.vn-dialog.shown [response="accept"]', firstBalanceLine: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(8)' }, @@ -208,7 +207,7 @@ export default { createItemButton: `vn-float-button`, firstSearchResult: 'vn-item-index a:nth-child(1)', searchResult: 'vn-item-index a.vn-tr', - searchResultPreviewButton: 'vn-item-index .buttons > [icon="desktop_windows"]', + firstResultPreviewButton: 'vn-item-index vn-tbody > :nth-child(1) .buttons > [icon="desktop_windows"]', searchResultCloneButton: 'vn-item-index .buttons > [icon="icon-clone"]', acceptClonationAlertButton: '.vn-confirm.shown [response="accept"]', topbarSearch: 'vn-topbar', @@ -260,7 +259,6 @@ export default { secondRequestDecline: 'vn-item-request vn-tbody > vn-tr:nth-child(1) vn-icon-button[icon="thumb_down"]', declineReason: 'vn-textarea[ng-model="$ctrl.denyObservation"]', acceptDeclineReason: 'button[response="accept"]', - }, itemBasicData: { basicDataButton: 'vn-left-menu a[ui-sref="item.card.basicData"]', @@ -339,8 +337,8 @@ export default { }, itemDiary: { secondTicketId: 'vn-item-diary vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(2) > span', + fourthBalance: 'vn-item-diary vn-tbody > vn-tr:nth-child(4) > vn-td.balance > span', firstBalance: 'vn-item-diary vn-tbody > vn-tr:nth-child(1) > vn-td.balance', - fourthBalance: 'vn-item-diary vn-tbody > vn-tr:nth-child(4) > vn-td.balance', warehouse: 'vn-item-diary vn-autocomplete[ng-model="$ctrl.warehouseFk"]', }, itemLog: { @@ -353,14 +351,14 @@ export default { route: 'vn-ticket-summary vn-label-value[label="Route"] > section > span > span', total: 'vn-ticket-summary vn-one.taxes > p:nth-child(3) > strong', sale: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr', - firstSaleItemId: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > span', + firstSaleItemId: 'vn-ticket-summary [name="sales"] vn-table vn-tbody > :nth-child(1) > vn-td:nth-child(2) > span', firstSaleDescriptorImage: '.vn-popover.shown vn-item-descriptor img', itemDescriptorPopover: '.vn-popover.shown vn-item-descriptor', itemDescriptorPopoverItemDiaryButton: 'vn-item-descriptor a[href="#!/item/2/diary?warehouseFk=5&ticketFk=20"]', popoverDiaryButton: '.vn-popover.shown vn-item-descriptor vn-icon[icon="icon-transaction"]', firstSaleQuantity: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(3)', firstSaleDiscount: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(6)', - invoiceOutRef: 'vn-ticket-summary > vn-card > vn-horizontal > vn-one:nth-child(1) > vn-label-value:nth-child(6) > section > span', + invoiceOutRef: 'vn-ticket-summary > vn-card > vn-horizontal > vn-one:nth-child(1) > vn-label-value:nth-child(7) > section > span', setOk: 'vn-ticket-summary vn-button[label="SET OK"] > button' }, ticketsIndex: { @@ -368,16 +366,23 @@ export default { advancedSearchInvoiceOut: 'vn-ticket-search-panel vn-textfield[ng-model="filter.refFk"]', newTicketButton: 'vn-ticket-index a', searchResult: 'vn-ticket-index vn-card > vn-table > div > vn-tbody > a.vn-tr', + secondTicketCheckbox: 'vn-ticket-index vn-tbody > a:nth-child(2) > vn-td:nth-child(1) > vn-check', + thirdTicketCheckbox: 'vn-ticket-index vn-tbody > a:nth-child(3) > vn-td:nth-child(1) > vn-check', + sixthTicketCheckbox: 'vn-ticket-index vn-tbody > a:nth-child(6) > vn-td:nth-child(1) > vn-check', + payoutButton: 'vn-ticket-index vn-button[icon="icon-recovery"]', + payoutCompany: '.vn-dialog vn-autocomplete[ng-model="$ctrl.receipt.companyFk"]', + payoutBank: '.vn-dialog vn-autocomplete[ng-model="$ctrl.receipt.bankFk"]', + submitPayout: '.vn-dialog button[response="accept"]', searchWeeklyResult: 'vn-ticket-weekly-index vn-table vn-tbody > vn-tr', - searchResultDate: 'vn-ticket-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(5)', + searchResultDate: 'vn-ticket-summary [label=Landed] span', topbarSearch: 'vn-searchbar', advancedSearchButton: 'vn-ticket-search-panel button[type=submit]', searchButton: 'vn-searchbar vn-icon[icon="search"]', - searchWeeklyButton: 'vn-searchbar vn-icon[icon="search"]', moreMenu: 'vn-ticket-index vn-icon-menu[icon=more_vert]', sixthWeeklyTicket: 'vn-ticket-weekly-index vn-table vn-tr:nth-child(6)', weeklyTicket: 'vn-ticket-weekly-index vn-table > div > vn-tbody > vn-tr', firstWeeklyTicketDeleteIcon: 'vn-ticket-weekly-index vn-tr:nth-child(1) vn-icon-button[icon="delete"]', + firstWeeklyTicketAgency: 'vn-ticket-weekly-index vn-tr:nth-child(1) [ng-model="weekly.agencyModeFk"]', acceptDeleteTurn: '.vn-confirm.shown button[response="accept"]' }, createTicketView: { @@ -430,7 +435,6 @@ export default { firstQuantity: 'vn-ticket-package vn-horizontal:nth-child(1) vn-input-number[ng-model="package.quantity"]', firstRemovePackageButton: 'vn-icon-button[vn-tooltip="Remove package"]', addPackageButton: 'vn-icon-button[vn-tooltip="Add package"]', - clearPackageAutocompleteButton: 'vn-autocomplete[label="Package"] .icons > vn-icon[icon=clear]', savePackagesButton: `button[type=submit]` }, ticketSales: { @@ -455,7 +459,6 @@ export default { firstSaleZoomedImage: 'body > div > div > img', firstSaleQuantity: 'vn-ticket-sale [ng-model="sale.quantity"]', firstSaleQuantityCell: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td-editable:nth-child(5)', - firstSaleQuantityClearInput: 'vn-textfield[ng-model="sale.quantity"] div.suffix > i', firstSaleIdAutocomplete: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > vn-autocomplete', firstSalePrice: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(7) > span', firstSalePriceInput: '.vn-popover.shown [ng-model="$ctrl.editedPrice"]', @@ -485,7 +488,6 @@ export default { deleteSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="delete"]', transferSaleButton: 'vn-ticket-sale vn-tool-bar > vn-button[icon="call_split"]', moveToTicketInput: '.vn-popover.shown vn-textfield[ng-model="$ctrl.transfer.ticketId"]', - moveToTicketInputClearButton: '.vn-popover.shown i[title="Clear"]', moveToTicketButton: '.vn-popover.shown vn-icon[icon="arrow_forward_ios"]', moveToNewTicketButton: '.vn-popover.shown vn-button[label="New ticket"]', acceptDeleteLineButton: '.vn-confirm.shown button[response=accept]', @@ -539,8 +541,8 @@ export default { firstPrice: 'vn-ticket-service vn-horizontal:nth-child(1) vn-input-number[ng-model="service.price"]', firstVatType: 'vn-ticket-service vn-autocomplete[label="Tax class"]', fistDeleteServiceButton: 'vn-ticket-service form vn-horizontal:nth-child(1) vn-icon-button[icon="delete"]', - newServiceTypeName: '.vn-dialog.shown vn-textfield[ng-model="$ctrl.newServiceType.name"]', - newServiceTypeExpense: '.vn-dialog.shown vn-autocomplete[ng-model="$ctrl.newServiceType.expenseFk"]', + newServiceTypeName: '.vn-dialog.shown vn-textfield[ng-model="newServiceType.name"]', + newServiceTypeExpense: '.vn-dialog.shown vn-autocomplete[ng-model="newServiceType.expenseFk"]', serviceLine: 'vn-ticket-service > form > vn-card > vn-one:nth-child(2) > vn-horizontal', saveServiceButton: 'button[type=submit]', saveServiceTypeButton: '.vn-dialog.shown tpl-buttons > button' @@ -548,7 +550,6 @@ export default { createStateView: { state: 'vn-autocomplete[ng-model="$ctrl.stateFk"]', worker: 'vn-autocomplete[ng-model="$ctrl.workerFk"]', - clearStateInputButton: 'vn-autocomplete[ng-model="$ctrl.stateFk"] .icons > vn-icon[icon=clear]', saveStateButton: `button[type=submit]` }, claimsIndex: { diff --git a/e2e/paths/01-login/01_login.spec.js b/e2e/paths/01-login/01_login.spec.js index abb022011..ed507df4e 100644 --- a/e2e/paths/01-login/01_login.spec.js +++ b/e2e/paths/01-login/01_login.spec.js @@ -1,3 +1,4 @@ +import selectors from '../../helpers/selectors'; import getBrowser from '../../helpers/puppeteer'; describe('Login path', async() => { @@ -12,32 +13,55 @@ describe('Login path', async() => { await browser.close(); }); - it('should receive an error when the username is incorrect', async() => { - await page.doLogin('badUser', ''); - const result = await page.waitForLastSnackbar(); + describe('Bad login', async() => { + it('should receive an error when the password is invalid', async() => { + await page.doLogin('employee', 'badPassword'); + const message = await page.waitForSnackbar(); + const state = await page.getState(); - expect(result.length).toBeGreaterThan(0); + expect(message.type).toBe('error'); + expect(state).toBe('login'); + }); + + it('should receive an error when the username is invalid', async() => { + await page.doLogin('badUser', ''); + const message = await page.waitForSnackbar(); + const state = await page.getState(); + + expect(message.type).toBe('error'); + expect(state).toBe('login'); + }); + + it('should receive an error when the username is blank', async() => { + await page.doLogin('', ''); + const message = await page.waitForSnackbar(); + const state = await page.getState(); + + expect(message.type).toBe('error'); + expect(state).toBe('login'); + }); }); - it('should receive an error when the username is blank', async() => { - await page.doLogin('', ''); - const result = await page.waitForLastSnackbar(); + describe('Successful login', async() => { + it('should log in and go to home state', async() => { + await page.doLogin('employee'); + await page.waitFor('vn-home'); + const state = await page.getState(); - expect(result.length).toBeGreaterThan(0); + expect(state).toBe('home'); + }); }); - it('should receive an error when the password is incorrect', async() => { - await page.doLogin('employee', 'badPassword'); - const result = await page.waitForLastSnackbar(); + describe('Logout', async() => { + it('should logout and return to login state', async() => { + await page.doLogin('employee'); - expect(result.length).toBeGreaterThan(0); - }); + await page.waitToClick(selectors.globalItems.userMenuButton); + await page.waitToClick(selectors.globalItems.logoutButton); + await page.waitFor('vn-login'); + const state = await page.getState(); - it('should log in', async() => { - await page.doLogin('employee', 'nightmare'); - await page.waitForNavigation(); - let url = await page.expectURL('#!/'); - - expect(url).toBe(true); + expect(state).toBe('login'); + }); }); }); diff --git a/e2e/paths/02-client/01_create_client.spec.js b/e2e/paths/02-client/01_create_client.spec.js index 65db9e7c6..2fdc4b091 100644 --- a/e2e/paths/02-client/01_create_client.spec.js +++ b/e2e/paths/02-client/01_create_client.spec.js @@ -1,9 +1,10 @@ import selectors from '../../helpers/selectors'; import getBrowser from '../../helpers/puppeteer'; -describe('Client create path', async() => { +describe('Client create path', () => { let browser; let page; + beforeAll(async() => { browser = await getBrowser(); page = browser.page; @@ -15,9 +16,7 @@ describe('Client create path', async() => { }); it(`should search for the user Carol Danvers to confirm it isn't created yet`, async() => { - await page.write(selectors.clientsIndex.topbarSearch, 'Carol Danvers'); - await page.waitToClick(selectors.clientsIndex.searchButton); - await page.waitForNumberOfElements(selectors.clientsIndex.searchResult, 0); + await page.doSearch('Carol Danvers'); const result = await page.countElement(selectors.clientsIndex.searchResult); expect(result).toEqual(0); @@ -25,17 +24,14 @@ describe('Client create path', async() => { it('should now access to the create client view by clicking the create-client floating button', async() => { await page.waitToClick(selectors.clientsIndex.createClientButton); - await page.wait(selectors.createClientView.createButton); - let url = await page.expectURL('#!/client/create'); - - expect(url).toBe(true); + await page.waitForState('client.create'); }); it('should receive an error when clicking the create button having all the form fields empty', async() => { await page.waitToClick(selectors.createClientView.createButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Some fields are invalid'); + expect(message.text).toBe('Some fields are invalid'); }); it('should receive an error when clicking the create button having name and Business name fields empty', async() => { @@ -44,9 +40,9 @@ describe('Client create path', async() => { await page.write(selectors.createClientView.email, 'CarolDanvers@verdnatura.es'); await page.autocompleteSearch(selectors.createClientView.salesPerson, 'replenisher'); await page.waitToClick(selectors.createClientView.createButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Some fields are invalid'); + expect(message.text).toBe('Some fields are invalid'); }); it(`should attempt to create a new user with all it's data but wrong email`, async() => { @@ -60,9 +56,9 @@ describe('Client create path', async() => { await page.clearInput(selectors.createClientView.email); await page.write(selectors.createClientView.email, 'incorrect email format'); await page.waitToClick(selectors.createClientView.createButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Some fields are invalid'); + expect(message.text).toBe('Some fields are invalid'); }); it(`should attempt to create a new user with all it's data but wrong postal code`, async() => { @@ -71,9 +67,9 @@ describe('Client create path', async() => { await page.clearInput(selectors.createClientView.postcode); await page.write(selectors.createClientView.postcode, '479999'); await page.waitToClick(selectors.createClientView.createButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual(`The postcode doesn't exist. Please enter a correct one`); + expect(message.text).toBe(`The postcode doesn't exist. Please enter a correct one`); }); it(`should check for autocompleted city, province and country`, async() => { @@ -95,9 +91,9 @@ describe('Client create path', async() => { await page.clearInput(selectors.createClientView.postcode); await page.write(selectors.createClientView.postcode, '46000'); await page.waitToClick(selectors.createClientView.createButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should click on the Clients button of the top bar menu', async() => { @@ -105,15 +101,11 @@ describe('Client create path', async() => { await page.wait(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.clientsButton); await page.wait(selectors.clientsIndex.createClientButton); - let url = await page.expectURL('#!/client/index'); - - expect(url).toBe(true); + await page.waitForState('client.index'); }); it(`should search for the user Carol Danvers to confirm it exists`, async() => { await page.accessToSearchResult('Carol Danvers'); - let url = await page.expectURL('#!/client/114/summary'); - - expect(url).toBe(true); + await page.waitForState('client.card.summary'); }); }); diff --git a/e2e/paths/02-client/02_edit_basic_data.spec.js b/e2e/paths/02-client/02_edit_basic_data.spec.js index 6ae512542..2e53a6ef8 100644 --- a/e2e/paths/02-client/02_edit_basic_data.spec.js +++ b/e2e/paths/02-client/02_edit_basic_data.spec.js @@ -35,9 +35,9 @@ describe('Client Edit basicData path', () => { await page.write(selectors.clientBasicData.email, 'PWallace@verdnatura.es'); await page.autocompleteSearch(selectors.clientBasicData.channel, 'Rumors on the streets'); await page.waitToClick(selectors.clientBasicData.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the name have been edited', async() => { @@ -99,9 +99,9 @@ describe('Client Edit basicData path', () => { await page.autocompleteSearch(selectors.clientBasicData.salesPerson, 'replenisherNick'); await page.autocompleteSearch(selectors.clientBasicData.channel, 'Metropolis newspaper'); await page.waitToClick(selectors.clientBasicData.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should now confirm the name have been edited', async() => { diff --git a/e2e/paths/02-client/03_edit_fiscal_data.spec.js b/e2e/paths/02-client/03_edit_fiscal_data.spec.js index 4cd54b87d..978627a60 100644 --- a/e2e/paths/02-client/03_edit_fiscal_data.spec.js +++ b/e2e/paths/02-client/03_edit_fiscal_data.spec.js @@ -36,9 +36,7 @@ describe('Client Edit fiscalData path', () => { it(`should click on the fiscal data button`, async() => { await page.waitToClick(selectors.clientFiscalData.fiscalDataButton); - let url = await page.expectURL('fiscal-data'); - - expect(url).toBe(true); + await page.waitForState('client.card.fiscalData'); }); it('should not be able to edit the verified data checkbox', async() => { @@ -80,9 +78,9 @@ describe('Client Edit fiscalData path', () => { await page.waitToClick(selectors.clientFiscalData.verifiedDataCheckbox); await page.waitToClick(selectors.clientFiscalData.saveButton); await page.waitToClick(selectors.clientFiscalData.acceptDuplicationButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Invalid Tax number'); + expect(message.text).toBe('Invalid Tax number'); }); it(`should edit the fiscal this time with a valid fiscal id`, async() => { @@ -90,16 +88,16 @@ describe('Client Edit fiscalData path', () => { await page.write(selectors.clientFiscalData.fiscalId, '94980061C'); await page.waitToClick(selectors.clientFiscalData.saveButton); await page.waitToClick(selectors.clientFiscalData.acceptDuplicationButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should propagate the Equalization tax', async() => { await page.waitToClick(selectors.clientFiscalData.acceptPropagationButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Equivalent tax spreaded'); + expect(message.text).toBe('Equivalent tax spreaded'); }); it('should receive an error if the fiscal id contains A or B at the beginning', async() => { @@ -107,26 +105,24 @@ describe('Client Edit fiscalData path', () => { await page.clearInput(selectors.clientFiscalData.fiscalId); await page.write(selectors.clientFiscalData.fiscalId, 'A94980061C'); await page.waitToClick(selectors.clientFiscalData.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Cannot check Equalization Tax in this NIF/CIF'); + expect(message.text).toBe('Cannot check Equalization Tax in this NIF/CIF'); }); it('should finally edit the fixcal data correctly as VIES isnt checked and fiscal id is valid for EQtax', async() => { await page.clearInput(selectors.clientFiscalData.fiscalId); await page.write(selectors.clientFiscalData.fiscalId, '94980061C'); await page.waitToClick(selectors.clientFiscalData.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); // confirm all addresses have now EQtax checked step 1 it(`should click on the addresses button to access to the client's addresses`, async() => { await page.waitToClick(selectors.clientAddresses.addressesButton); - let url = await page.expectURL('/address/index'); - - expect(url).toBe(true); + await page.waitForState('client.card.address.index'); }); // confirm all addresses have now EQtax checked step 2 @@ -154,17 +150,17 @@ describe('Client Edit fiscalData path', () => { await page.waitToClick(selectors.clientFiscalData.invoiceByAddressCheckbox); await page.waitToClick(selectors.clientFiscalData.equalizationTaxCheckbox); await page.waitToClick(selectors.clientFiscalData.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should propagate the Equalization tax changes', async() => { await page.waitFor(1000); await page.waitToClick(selectors.clientFiscalData.acceptPropagationButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Equivalent tax spreaded'); + expect(message.text).toBe('Equivalent tax spreaded'); }); it('should confirm its name have been edited', async() => { @@ -261,9 +257,7 @@ describe('Client Edit fiscalData path', () => { // confirm invoice by address checkbox gets checked if the EQtax differs between addresses step 1 it(`should click on the addresses button to access to the client's addresses`, async() => { await page.waitToClick(selectors.clientAddresses.addressesButton); - let url = await page.expectURL('/address/index'); - - expect(url).toBe(true); + await page.waitForState('client.card.address.index'); }); // confirm invoice by address checkbox gets checked if the EQtax differs between addresses step 2 @@ -272,9 +266,9 @@ describe('Client Edit fiscalData path', () => { await page.waitForTextInField(selectors.clientAddresses.city, 'Silla'); await page.waitToClick(selectors.clientAddresses.equalizationTaxCheckbox); await page.waitToClick(selectors.clientAddresses.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); // confirm invoice by address checkbox gets checked if the EQtax differs between addresses step 3 diff --git a/e2e/paths/02-client/04_edit_billing_data.spec.js b/e2e/paths/02-client/04_edit_billing_data.spec.js index b757940be..394324509 100644 --- a/e2e/paths/02-client/04_edit_billing_data.spec.js +++ b/e2e/paths/02-client/04_edit_billing_data.spec.js @@ -26,25 +26,26 @@ describe('Client Edit billing data path', () => { await page.waitToClick(selectors.clientBillingData.receivedCoreVNLCheckbox); await page.waitToClick(selectors.clientBillingData.receivedB2BVNLCheckbox); await page.waitToClick(selectors.clientBillingData.saveButton); - let snackbarMessage = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(snackbarMessage).toEqual('That payment method requires an IBAN'); + expect(message.text).toBe('That payment method requires an IBAN'); }); - it(`should create a new BIC code`, async() => { + // 2215: Windows (hidden mode): Entity code doesn't get the focus, '9999' is written in entity name. + xit(`should create a new BIC code`, async() => { await page.waitToClick(selectors.clientBillingData.newBankEntityButton); await page.write(selectors.clientBillingData.newBankEntityName, 'Gotham City Bank'); await page.write(selectors.clientBillingData.newBankEntityCode, '9999'); await page.write(selectors.clientBillingData.newBankEntityBIC, 'GTHMCT'); await page.waitToClick(selectors.clientBillingData.acceptBankEntityButton); await page.waitForTextInField(selectors.clientBillingData.swiftBic, 'Gotham City Bank'); - let newcode = await page.waitToGetProperty(selectors.clientBillingData.swiftBic, 'value'); + const newcode = await page.waitToGetProperty(selectors.clientBillingData.swiftBic, 'value'); expect(newcode).toEqual('GTHMCT Gotham City Bank'); }); - it(`should confirm the IBAN pay method was sucessfully saved`, async() => { - let payMethod = await page.waitToGetProperty(selectors.clientBillingData.payMethod, 'value'); + xit(`should confirm the IBAN pay method was sucessfully saved`, async() => { + const payMethod = await page.waitToGetProperty(selectors.clientBillingData.payMethod, 'value'); expect(payMethod).toEqual('PayMethod with IBAN'); }); @@ -60,46 +61,45 @@ describe('Client Edit billing data path', () => { }); it(`should save the form with all its new data`, async() => { - await page.waitFor(3000); await page.waitForWatcherData(selectors.clientBillingData.watcher); await page.waitToClick(selectors.clientBillingData.saveButton); - let snackbarMessage = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(snackbarMessage).toEqual('Notification sent!'); + expect(message.text).toBe('Notification sent!'); }); it('should confirm the due day have been edited', async() => { - let dueDate = await page.waitToGetProperty(selectors.clientBillingData.dueDay, 'value'); + const dueDate = await page.waitToGetProperty(selectors.clientBillingData.dueDay, 'value'); expect(dueDate).toEqual('60'); }); it('should confirm the IBAN was saved', async() => { - let IBAN = await page.waitToGetProperty(selectors.clientBillingData.IBAN, 'value'); + const IBAN = await page.waitToGetProperty(selectors.clientBillingData.IBAN, 'value'); expect(IBAN).toEqual('ES9121000418450200051332'); }); it('should confirm the swift / BIC code was saved', async() => { - let code = await page.waitToGetProperty(selectors.clientBillingData.swiftBic, 'value'); + const code = await page.waitToGetProperty(selectors.clientBillingData.swiftBic, 'value'); expect(code).toEqual('CAIXESBB Caixa Bank'); }); it('should confirm Received LCR checkbox is checked', async() => { - let result = await page.checkboxState(selectors.clientBillingData.receivedCoreLCRCheckbox); + const result = await page.checkboxState(selectors.clientBillingData.receivedCoreLCRCheckbox); expect(result).toBe('checked'); }); it('should confirm Received core VNL checkbox is unchecked', async() => { - let result = await page.checkboxState(selectors.clientBillingData.receivedCoreVNLCheckbox); + const result = await page.checkboxState(selectors.clientBillingData.receivedCoreVNLCheckbox); expect(result).toBe('unchecked'); }); it('should confirm Received B2B VNL checkbox is unchecked', async() => { - let result = await page.checkboxState(selectors.clientBillingData.receivedB2BVNLCheckbox); + const result = await page.checkboxState(selectors.clientBillingData.receivedB2BVNLCheckbox); expect(result).toBe('unchecked'); }); diff --git a/e2e/paths/02-client/05_add_address.spec.js b/e2e/paths/02-client/05_add_address.spec.js index c9228e1cf..2fe238fea 100644 --- a/e2e/paths/02-client/05_add_address.spec.js +++ b/e2e/paths/02-client/05_add_address.spec.js @@ -18,9 +18,7 @@ describe('Client Add address path', () => { it(`should click on the add new address button to access to the new address form`, async() => { await page.waitToClick(selectors.clientAddresses.createAddress); - let url = await page.expectURL('address/create'); - - expect(url).toBe(true); + await page.waitForState('client.card.address.create'); }); it('should receive an error after clicking save button as consignee, street and town fields are empty', async() => { @@ -30,9 +28,9 @@ describe('Client Add address path', () => { await page.write(selectors.clientAddresses.phone, '999887744'); await page.write(selectors.clientAddresses.mobileInput, '999887744'); await page.waitToClick(selectors.clientFiscalData.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Some fields are invalid'); + expect(message.text).toBe('Some fields are invalid'); }); it('should confirm that the city and province are propertly filled', async() => { @@ -50,31 +48,29 @@ describe('Client Add address path', () => { await page.write(selectors.clientAddresses.consignee, 'Bruce Bunner'); await page.write(selectors.clientAddresses.streetAddress, '320 Park Avenue New York'); await page.waitToClick(selectors.clientAddresses.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Incoterms is required for a non UEE member'); + expect(message.text).toBe('Incoterms is required for a non UEE member'); }); it(`should receive an error after clicking save button as customsAgent is empty`, async() => { await page.autocompleteSearch(selectors.clientAddresses.incoterms, 'Free Alongside Ship'); await page.waitToClick(selectors.clientAddresses.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Customs agent is required for a non UEE member'); + expect(message.text).toBe('Customs agent is required for a non UEE member'); }); it(`should create a new address with all it's data`, async() => { await page.autocompleteSearch(selectors.clientAddresses.customsAgent, 'Agent one'); await page.waitToClick(selectors.clientAddresses.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should navigate back to the addresses index`, async() => { - let url = await page.expectURL('/address/index'); - - expect(url).toBe(true); + await page.waitForState('client.card.address.index'); }); it(`should confirm the new address exists and it's the default one`, async() => { @@ -86,9 +82,9 @@ describe('Client Add address path', () => { it('should click on the make default icon of the second address', async() => { await page.waitToClick(selectors.clientAddresses.secondMakeDefaultStar); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should confirm the default address is the expected one`, async() => { @@ -101,26 +97,22 @@ describe('Client Add address path', () => { it(`should click on the edit icon of the default address`, async() => { await page.waitForTextInElement(selectors.clientAddresses.defaultAddress, 'Somewhere in Thailand'); await page.waitToClick(selectors.clientAddresses.firstEditAddress); - let url = await page.expectURL('/edit'); - - expect(url).toBe(true); + await page.waitForState('client.card.address.edit'); }); it(`should click on the active checkbox and receive an error to save it because it is the default address`, async() => { await page.waitForWatcherData(selectors.clientAddresses.watcher); await page.waitToClick(selectors.clientAddresses.activeCheckbox); await page.waitToClick(selectors.clientAddresses.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('The default consignee can not be unchecked'); + expect(message.text).toBe('The default consignee can not be unchecked'); }); it(`should go back to the addreses section by clicking the cancel button`, async() => { await page.waitForSelector('#shapes .shown', {hidden: true}); await page.waitToClick(selectors.clientAddresses.cancelEditAddressButton); await page.waitToClick('.vn-confirm.shown button[response="accept"]'); - let url = await page.expectURL('address/index'); - - expect(url).toBe(true); + await page.waitForState('client.card.address.index'); }); }); diff --git a/e2e/paths/02-client/06_add_address_notes.spec.js b/e2e/paths/02-client/06_add_address_notes.spec.js index 58a949698..bf367f5ae 100644 --- a/e2e/paths/02-client/06_add_address_notes.spec.js +++ b/e2e/paths/02-client/06_add_address_notes.spec.js @@ -19,27 +19,25 @@ describe('Client add address notes path', () => { it(`should click on the edit icon of the default address`, async() => { await page.waitForTextInElement(selectors.clientAddresses.defaultAddress, '20 Ingram Street'); await page.waitToClick(selectors.clientAddresses.firstEditAddress); - let url = await page.expectURL('/edit'); - - expect(url).toBe(true); + await page.waitForState('client.card.address.edit'); }); it('should not save a description without observation type', async() => { await page.waitToClick(selectors.clientAddresses.addObservationButton); await page.write(selectors.clientAddresses.firstObservationDescription, 'first description'); await page.waitToClick(selectors.clientAddresses.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Some fields are invalid'); + expect(message.text).toBe('Some fields are invalid'); }); it('should not save an observation type without description', async() => { await page.clearInput(selectors.clientAddresses.firstObservationDescription); await page.autocompleteSearch(selectors.clientAddresses.firstObservationType, 'comercial'); await page.waitToClick(selectors.clientAddresses.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Some fields are invalid'); + expect(message.text).toBe('Some fields are invalid'); }); it('should create two new observations', async() => { @@ -48,8 +46,8 @@ describe('Client add address notes path', () => { await page.autocompleteSearch(selectors.clientAddresses.secondObservationType, 'observation one'); await page.write(selectors.clientAddresses.secondObservationDescription, 'second description'); await page.waitToClick(selectors.clientAddresses.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); }); diff --git a/e2e/paths/02-client/07_edit_web_access.spec.js b/e2e/paths/02-client/07_edit_web_access.spec.js index f9b023716..95886f57c 100644 --- a/e2e/paths/02-client/07_edit_web_access.spec.js +++ b/e2e/paths/02-client/07_edit_web_access.spec.js @@ -21,16 +21,14 @@ describe('Client Edit web access path', () => { await page.clearInput(selectors.clientWebAccess.userName); await page.write(selectors.clientWebAccess.userName, 'Hulk'); await page.waitToClick(selectors.clientWebAccess.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm web access is now unchecked', async() => { - await page.waitToClick(selectors.clientBasicData.basicDataButton); - await page.wait(selectors.clientBasicData.name); - await page.waitToClick(selectors.clientsIndex.othersButton); - await page.waitToClick(selectors.clientWebAccess.webAccessButton); + await page.accessToSection('client.card.basicData'); + await page.accessToSection('client.card.webAccess'); const result = await page.checkboxState(selectors.clientWebAccess.enableWebAccessCheckbox); expect(result).toBe('unchecked'); diff --git a/e2e/paths/02-client/08_add_notes.spec.js b/e2e/paths/02-client/08_add_notes.spec.js index b759cbd07..d0b117ac9 100644 --- a/e2e/paths/02-client/08_add_notes.spec.js +++ b/e2e/paths/02-client/08_add_notes.spec.js @@ -17,25 +17,21 @@ describe('Client Add notes path', () => { }); it(`should reach the notes index`, async() => { - let url = await page.expectURL('/note'); - - expect(url).toBe(true); + await page.waitForState('client.card.note.index'); }); it(`should click on the add note button`, async() => { await page.waitToClick(selectors.clientNotes.addNoteFloatButton); - let url = await page.expectURL('/note/create'); - - expect(url).toBe(true); + await page.waitForState('client.card.note.create'); }); it(`should create a note`, async() => { await page.waitFor(selectors.clientNotes.note); await page.type(`${selectors.clientNotes.note} textarea`, 'Meeting with Black Widow 21st 9am'); await page.waitToClick(selectors.clientNotes.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the note was created', async() => { diff --git a/e2e/paths/02-client/09_add_credit.spec.js b/e2e/paths/02-client/09_add_credit.spec.js index 05c50e809..8d1c9be1c 100644 --- a/e2e/paths/02-client/09_add_credit.spec.js +++ b/e2e/paths/02-client/09_add_credit.spec.js @@ -18,18 +18,16 @@ describe('Client Add credit path', () => { it(`should click on the add credit button`, async() => { await page.waitToClick(selectors.clientCredit.addCreditFloatButton); - let url = await page.expectURL('/credit/create'); - - expect(url).toBe(true); + await page.waitForState('client.card.credit.create'); }); it(`should edit the credit`, async() => { await page.clearInput(selectors.clientCredit.credit); await page.write(selectors.clientCredit.credit, '999'); await page.waitToClick(selectors.clientCredit.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the credit was updated', async() => { diff --git a/e2e/paths/02-client/10_add_greuge.spec.js b/e2e/paths/02-client/10_add_greuge.spec.js index c934a42f1..b7e130683 100644 --- a/e2e/paths/02-client/10_add_greuge.spec.js +++ b/e2e/paths/02-client/10_add_greuge.spec.js @@ -18,17 +18,15 @@ describe('Client Add greuge path', () => { it(`should click on the add greuge button`, async() => { await page.waitToClick(selectors.clientGreuge.addGreugeFloatButton); - let url = await page.expectURL('greuge/create'); - - expect(url).toBe(true); + await page.waitForState('client.card.greuge.create'); }); it(`should receive an error if all fields are empty but date and type on submit`, async() => { await page.autocompleteSearch(selectors.clientGreuge.type, 'Diff'); await page.waitToClick(selectors.clientGreuge.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Some fields are invalid'); + expect(message.text).toBe('Some fields are invalid'); }); it(`should create a new greuge with all its data`, async() => { @@ -36,9 +34,9 @@ describe('Client Add greuge path', () => { await page.waitForTextInField(selectors.clientGreuge.amount, '999'); await page.write(selectors.clientGreuge.description, 'new armor for Batman!'); await page.waitToClick(selectors.clientGreuge.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the greuge was added to the list', async() => { diff --git a/e2e/paths/02-client/12_lock_of_verified_data.spec.js b/e2e/paths/02-client/12_lock_of_verified_data.spec.js index 870ce7cb1..79a9e17ac 100644 --- a/e2e/paths/02-client/12_lock_of_verified_data.spec.js +++ b/e2e/paths/02-client/12_lock_of_verified_data.spec.js @@ -30,9 +30,9 @@ describe('Client lock verified data path', () => { await page.clearInput(selectors.clientFiscalData.socialName); await page.write(selectors.clientFiscalData.socialName, 'Captain America Civil War'); await page.waitToClick(selectors.clientFiscalData.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the social name have been edited', async() => { @@ -60,9 +60,9 @@ describe('Client lock verified data path', () => { await page.waitToClick(selectors.clientFiscalData.verifiedDataCheckbox); await page.waitToClick(selectors.clientFiscalData.saveButton); await page.waitToClick(selectors.clientFiscalData.acceptDuplicationButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm Verified data checkbox is checked', async() => { @@ -77,9 +77,9 @@ describe('Client lock verified data path', () => { await page.clearInput(selectors.clientFiscalData.socialName); await page.write(selectors.clientFiscalData.socialName, 'Ant man and the Wasp'); await page.waitToClick(selectors.clientFiscalData.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should again confirm the social name have been edited', async() => { @@ -107,9 +107,9 @@ describe('Client lock verified data path', () => { await page.clearInput(selectors.clientFiscalData.socialName); await page.write(selectors.clientFiscalData.socialName, 'This wont happen'); await page.waitToClick(selectors.clientFiscalData.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual(jasmine.arrayContaining([`You can't make changes on a client with verified data`])); + expect(message.text).toBe(`You can't make changes on a client with verified data`); }); }); @@ -131,9 +131,9 @@ describe('Client lock verified data path', () => { await page.clearInput(selectors.clientFiscalData.socialName); await page.write(selectors.clientFiscalData.socialName, 'new social name edition'); await page.waitToClick(selectors.clientFiscalData.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should now confirm the social name have been edited once and for all', async() => { diff --git a/e2e/paths/02-client/13_log.spec.js b/e2e/paths/02-client/13_log.spec.js index 462d66347..93397d301 100644 --- a/e2e/paths/02-client/13_log.spec.js +++ b/e2e/paths/02-client/13_log.spec.js @@ -20,16 +20,13 @@ describe('Client log path', () => { await page.clearInput(selectors.clientBasicData.name); await page.write(selectors.clientBasicData.name, 'this is a test'); await page.waitToClick(selectors.clientBasicData.saveButton); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should navigate to the log section', async() => { - await page.waitToClick(selectors.clientLog.logButton); - let url = await page.expectURL('log'); - - expect(url).toBe(true); + await page.accessToSection('client.card.log'); }); it('should check the previous value of the last logged change', async() => { @@ -46,7 +43,6 @@ describe('Client log path', () => { let lastModificationCurrentValue = await page. waitToGetProperty(selectors.clientLog.lastModificationCurrentValue, 'innerText'); - expect(lastModificationPreviousValue).toEqual('name: DavidCharlesHaller'); expect(lastModificationCurrentValue).toEqual('name: this is a test'); }); diff --git a/e2e/paths/02-client/14_balance.spec.js b/e2e/paths/02-client/14_balance.spec.js index ef7930c8d..108f76710 100644 --- a/e2e/paths/02-client/14_balance.spec.js +++ b/e2e/paths/02-client/14_balance.spec.js @@ -18,9 +18,9 @@ describe('Client balance path', () => { it('should now edit the local user config data', async() => { await page.waitToClick(selectors.globalItems.userMenuButton); await page.autocompleteSearch(selectors.globalItems.userLocalCompany, 'CCs'); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should access to the balance section to check the data shown matches the local settings', async() => { @@ -33,26 +33,24 @@ describe('Client balance path', () => { it('should now clear the user local settings', async() => { await page.waitToClick(selectors.globalItems.userMenuButton); await page.clearInput(selectors.globalItems.userConfigThirdAutocomplete); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toContain('Data saved!'); + expect(message.type).toBe('success'); }); it('should click the new payment button', async() => { await page.closePopup(); await page.reloadSection('client.card.balance.index'); - let url = await page.expectURL('/balance'); - - expect(url).toBe(true); + await page.waitForState('client.card.balance.index'); }); it('should create a new payment that clears the debt', async() => { await page.waitToClick(selectors.clientBalance.newPaymentButton); await page.autocompleteSearch(selectors.clientBalance.newPaymentBank, 'Pay on receipt'); await page.waitToClick(selectors.clientBalance.saveButton); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toContain('Data saved!'); + expect(message.type).toBe('success'); }); it('should check balance is now 0 and the company is now VNL becouse the user local settings were removed', async() => { @@ -69,13 +67,11 @@ describe('Client balance path', () => { it('should create a new payment that sets the balance to positive value', async() => { await page.waitToClick(selectors.clientBalance.newPaymentButton); - await page.waitFor(3000); // didn't manage to make this dynamic to allow clearInput to find the icon clear... :( - await page.clearInput(selectors.clientBalance.newPaymentAmount); - await page.write(selectors.clientBalance.newPaymentAmount, '100'); + await page.overwrite(selectors.clientBalance.newPaymentAmount, '100'); await page.waitToClick(selectors.clientBalance.saveButton); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toContain('Data saved!'); + expect(message.type).toBe('success'); }); it('should check balance is now -100', async() => { @@ -87,14 +83,11 @@ describe('Client balance path', () => { it('should create a new payment that sets the balance back to the original negative value', async() => { await page.waitToClick(selectors.clientBalance.newPaymentButton); - await page.waitFor(3000); // didn't manage to make this dynamic to allow clearInput to find the icon clear... :( - await page.waitForSelector('.vn-dialog.vn-popup.shown', {visible: true}); - await page.clearInput(selectors.clientBalance.newPaymentAmount); - await page.write(selectors.clientBalance.newPaymentAmount, '-150'); + await page.overwrite(selectors.clientBalance.newPaymentAmount, '-150'); await page.waitToClick(selectors.clientBalance.saveButton); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toContain('Data saved!'); + expect(message.type).toBe('success'); }); it('should check balance is now 50', async() => { @@ -110,17 +103,12 @@ describe('Client balance path', () => { await page.wait(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.clientsButton); await page.wait(selectors.clientsIndex.createClientButton); - let url = await page.expectURL('#!/client/index'); - - expect(url).toBe(true); + await page.waitForState('client.index'); }); it('should now search for the user Petter Parker', async() => { await page.accessToSearchResult('Petter Parker'); - await page.waitToClick(selectors.clientBalance.balanceButton); - let url = await page.expectURL('/balance'); - - expect(url).toBe(true); + await page.accessToSection('client.card.balance.index'); }); it('should not be able to click the new payment button as it isnt present', async() => { diff --git a/e2e/paths/02-client/15_user_config.spec.js b/e2e/paths/02-client/15_user_config.spec.js index 89d4e004a..28f2ef29e 100644 --- a/e2e/paths/02-client/15_user_config.spec.js +++ b/e2e/paths/02-client/15_user_config.spec.js @@ -16,7 +16,6 @@ describe('User config', () => { describe('as salesPerson', () => { it('should login', async() => { await page.login('salesPerson'); - await page.waitForContentLoaded(); }); it('should now open the user config form to check the settings', async() => { @@ -26,7 +25,6 @@ describe('User config', () => { let expectedLocalWarehouse = await page .expectPropertyValue(selectors.globalItems.userLocalWarehouse, 'value', ''); - let expectedLocalBank = await page .expectPropertyValue(selectors.globalItems.userLocalBank, 'value', ''); @@ -50,7 +48,6 @@ describe('User config', () => { describe('as employee', () => { it('should log in', async() => { await page.login('employee'); - await page.waitForContentLoaded(); }); it('should open the user config form to check the settings', async() => { @@ -59,7 +56,6 @@ describe('User config', () => { let expectedLocalWarehouse = await page .expectPropertyValue(selectors.globalItems.userLocalWarehouse, 'value', ''); - let expectedLocalBank = await page .expectPropertyValue(selectors.globalItems.userLocalBank, 'value', ''); @@ -83,16 +79,15 @@ describe('User config', () => { await page.autocompleteSearch(selectors.globalItems.userLocalWarehouse, 'Warehouse Four'); await page.autocompleteSearch(selectors.globalItems.userLocalBank, 'Pay on receipt'); await page.autocompleteSearch(selectors.globalItems.userLocalCompany, 'VNL'); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toContain('Data saved!'); + expect(message.type).toBe('success'); }); }); describe('as salesPerson 2nd run', () => { it('should log in once more', async() => { await page.login('salesPerson'); - await page.waitForContentLoaded(); }); it('should again open the user config form to check the local settings', async() => { @@ -123,9 +118,9 @@ describe('User config', () => { await page.clearInput(selectors.globalItems.userConfigFirstAutocomplete); await page.clearInput(selectors.globalItems.userConfigSecondAutocomplete); await page.clearInput(selectors.globalItems.userConfigThirdAutocomplete); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toContain('Data saved!'); + expect(message.type).toBe('success'); }); }); }); diff --git a/e2e/paths/02-client/17_dms.spec.js b/e2e/paths/02-client/17_dms.spec.js index 95b37093a..32cca05f3 100644 --- a/e2e/paths/02-client/17_dms.spec.js +++ b/e2e/paths/02-client/17_dms.spec.js @@ -20,9 +20,9 @@ describe('Client DMS', () => { it('should delete de first file', async() => { await page.waitToClick(selectors.dms.deleteFileButton); await page.respondToDialog('accept'); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should click on the first document line worker name making the descriptor visible`, async() => { diff --git a/e2e/paths/02-client/18_contacts.spec.js b/e2e/paths/02-client/18_contacts.spec.js index fd8b68283..87e75a975 100644 --- a/e2e/paths/02-client/18_contacts.spec.js +++ b/e2e/paths/02-client/18_contacts.spec.js @@ -22,17 +22,17 @@ describe('Client contacts', () => { await page.write(selectors.clientContacts.name, 'Ansible'); await page.write(selectors.clientContacts.phone, 'FTL comms'); await page.waitToClick(selectors.clientContacts.saveButton); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should delete de contact', async() => { await page.waitFor(3000); await page.waitToClick(selectors.clientContacts.deleteFirstPhone); await page.waitToClick(selectors.clientContacts.saveButton); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toContain('Data saved!'); + expect(message.type).toBe('success'); }); }); diff --git a/e2e/paths/02-client/19_summary.spec.js b/e2e/paths/02-client/19_summary.spec.js index 11b5a298e..ab39154cf 100644 --- a/e2e/paths/02-client/19_summary.spec.js +++ b/e2e/paths/02-client/19_summary.spec.js @@ -17,9 +17,7 @@ describe('Client summary path', () => { }); it('should reach the first route summary section', async() => { - let url = await page.expectURL('#!/client/102/summary'); - - expect(url).toBe(true); + await page.waitForState('client.card.summary'); }); it('should display details from the client on the header', async() => { diff --git a/e2e/paths/03-worker/01_summary.spec.js b/e2e/paths/03-worker/01_summary.spec.js index 86a95eee3..4ea87481a 100644 --- a/e2e/paths/03-worker/01_summary.spec.js +++ b/e2e/paths/03-worker/01_summary.spec.js @@ -16,9 +16,7 @@ describe('Worker summary path', () => { }); it('should reach the employee summary section', async() => { - const url = await page.expectURL('#!/worker/3/summary'); - - expect(url).toBe(true); + await page.waitForState('worker.card.summary'); }); it('should check the summary contains the name and userName on the header', async() => { diff --git a/e2e/paths/03-worker/02_basicData.spec.js b/e2e/paths/03-worker/02_basicData.spec.js index 21443c517..a24ffd033 100644 --- a/e2e/paths/03-worker/02_basicData.spec.js +++ b/e2e/paths/03-worker/02_basicData.spec.js @@ -24,9 +24,9 @@ describe('Worker basic data path', () => { await page.clearInput(selectors.workerBasicData.phone); await page.write(selectors.workerBasicData.phone, '444332211'); await page.waitToClick(selectors.workerBasicData.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should reload the section then check the name was edited', async() => { diff --git a/e2e/paths/03-worker/03_pbx.spec.js b/e2e/paths/03-worker/03_pbx.spec.js index 83849a5dd..f2a567af2 100644 --- a/e2e/paths/03-worker/03_pbx.spec.js +++ b/e2e/paths/03-worker/03_pbx.spec.js @@ -19,17 +19,17 @@ describe('Worker pbx path', () => { it('should receive an error when the extension exceeds 4 characters', async() => { await page.write(selectors.workerPbx.extension, '55555'); await page.waitToClick(selectors.workerPbx.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Extension format is invalid'); + expect(message.text).toBe('Extension format is invalid'); }); it('should sucessfully save the changes', async() => { await page.clearInput(selectors.workerPbx.extension); await page.write(selectors.workerPbx.extension, '4444'); await page.waitToClick(selectors.workerPbx.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved! User must access web'); + expect(message.text).toBe('Data saved! User must access web'); }); }); diff --git a/e2e/paths/03-worker/04_time_control.spec.js b/e2e/paths/03-worker/04_time_control.spec.js index 36aaca61e..c94137e2f 100644 --- a/e2e/paths/03-worker/04_time_control.spec.js +++ b/e2e/paths/03-worker/04_time_control.spec.js @@ -57,9 +57,9 @@ describe('Worker time control path', () => { await page.waitForTextInElement(selectors.workerTimeControl.thirdEntryOfMonday, wrongScanTime); await page.waitToClick(selectors.workerTimeControl.thirdEntryOfMondayDelete); await page.respondToDialog('accept'); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Entry removed'); + expect(message.text).toBe('Entry removed'); }); it(`should scan out Hank Pym to leave early`, async() => { @@ -316,16 +316,12 @@ describe('Worker time control path', () => { it('should search for a worker and access to its summary', async() => { await page.accessToSearchResult('HankPym'); - let url = await page.expectURL('/summary'); - - expect(url).toBe(true); + await page.waitForState('worker.card.summary'); }); it('should access to the time control section', async() => { await page.accessToSection('worker.card.timeControl'); - let url = await page.expectURL('/time-control'); - - expect(url).toBe(true); + await page.waitForState('worker.card.timeControl'); }); it('should lovingly scan in Hank Pym', async() => { diff --git a/e2e/paths/04-item/01_summary.spec.js b/e2e/paths/04-item/01_summary.spec.js index 01e730668..7658cb752 100644 --- a/e2e/paths/04-item/01_summary.spec.js +++ b/e2e/paths/04-item/01_summary.spec.js @@ -15,14 +15,14 @@ describe('Item summary path', () => { }); it('should search for an item', async() => { - await page.clearInput(selectors.itemsIndex.topbarSearch); - await page.write(selectors.itemsIndex.topbarSearch, 'Ranged weapon'); - await page.waitToClick(selectors.itemsIndex.searchButton); - await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 3); - await page.waitForTextInElement(selectors.itemsIndex.searchResult, 'Ranged weapon longbow 2m'); - await page.waitToClick(selectors.itemsIndex.searchResultPreviewButton); + await page.doSearch('Ranged weapon'); + const nResults = await page.countElement(selectors.itemsIndex.searchResult); + + await page.waitForTextInElement(selectors.itemsIndex.searchResult, 'Ranged weapon'); + await page.waitToClick(selectors.itemsIndex.firstResultPreviewButton); const isVisible = await page.isVisible(selectors.itemSummary.basicData); + expect(nResults).toBe(3); expect(isVisible).toBeTruthy(); }); @@ -67,13 +67,13 @@ describe('Item summary path', () => { }); it('should search for other item', async() => { - await page.clearInput('vn-searchbar'); - await page.waitToClick(selectors.itemsIndex.searchButton); - await page.write(selectors.itemsIndex.topbarSearch, 'Melee Reinforced'); - await page.waitToClick(selectors.itemsIndex.searchButton); - await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 2); - await page.waitToClick(selectors.itemsIndex.searchResultPreviewButton); + await page.doSearch('Melee Reinforced'); + const nResults = await page.countElement(selectors.itemsIndex.searchResult); + + await page.waitToClick(selectors.itemsIndex.firstResultPreviewButton); await page.waitForSelector(selectors.itemSummary.basicData, {visible: true}); + + expect(nResults).toBe(2); }); it(`should now check the item summary preview shows fields from basic data`, async() => { @@ -104,9 +104,7 @@ describe('Item summary path', () => { it(`should navigate to the one of the items detailed section`, async() => { await page.accessToSearchResult('Melee weapon combat fist 15cm'); - let url = await page.expectURL('summary'); - - expect(url).toBe(true); + await page.waitForState('item.card.summary'); }); it(`should check the descritor edit button is not visible for employee`, async() => { diff --git a/e2e/paths/04-item/02_basic_data.spec.js b/e2e/paths/04-item/02_basic_data.spec.js index ce56b9a5c..7a9b9a1e7 100644 --- a/e2e/paths/04-item/02_basic_data.spec.js +++ b/e2e/paths/04-item/02_basic_data.spec.js @@ -34,9 +34,9 @@ describe('Item Edit basic data path', () => { await page.waitToClick(selectors.itemBasicData.isActiveCheckbox); await page.waitToClick(selectors.itemBasicData.priceInKgCheckbox); await page.waitToClick(selectors.itemBasicData.submitBasicDataButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should create a new intrastat`, async() => { @@ -53,9 +53,9 @@ describe('Item Edit basic data path', () => { it('should save with the new intrastat', async() => { await page.waitToClick(selectors.itemBasicData.submitBasicDataButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should confirm the item name was edited`, async() => { diff --git a/e2e/paths/04-item/03_tax.spec.js b/e2e/paths/04-item/03_tax.spec.js index ef2d68096..b05dcb286 100644 --- a/e2e/paths/04-item/03_tax.spec.js +++ b/e2e/paths/04-item/03_tax.spec.js @@ -21,9 +21,9 @@ describe('Item edit tax path', () => { await page.autocompleteSearch(selectors.itemTax.secondClass, 'General VAT'); await page.autocompleteSearch(selectors.itemTax.thirdClass, 'General VAT'); await page.waitToClick(selectors.itemTax.submitTaxButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should confirm the first item tax class was edited`, async() => { diff --git a/e2e/paths/04-item/04_tags.spec.js b/e2e/paths/04-item/04_tags.spec.js index 098ac75eb..f53ff3582 100644 --- a/e2e/paths/04-item/04_tags.spec.js +++ b/e2e/paths/04-item/04_tags.spec.js @@ -24,9 +24,9 @@ describe('Item create tags path', () => { await page.clearInput(selectors.itemTags.seventhRelevancy); await page.write(selectors.itemTags.seventhRelevancy, '4'); await page.waitToClick(selectors.itemTags.submitItemTagsButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should confirm the fourth row data is the expected one`, async() => { diff --git a/e2e/paths/04-item/05_niche.spec.js b/e2e/paths/04-item/05_niche.spec.js index 4da8ed5fe..4ad0398c2 100644 --- a/e2e/paths/04-item/05_niche.spec.js +++ b/e2e/paths/04-item/05_niche.spec.js @@ -23,9 +23,9 @@ describe('Item create niche path', () => { await page.autocompleteSearch(selectors.itemNiches.thirdWarehouse, 'Warehouse Two'); await page.write(selectors.itemNiches.thirdCode, 'A4'); await page.waitToClick(selectors.itemNiches.submitNichesButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should confirm the first niche is the expected one`, async() => { diff --git a/e2e/paths/04-item/06_botanical.spec.js b/e2e/paths/04-item/06_botanical.spec.js index edcc94f28..84a144f1d 100644 --- a/e2e/paths/04-item/06_botanical.spec.js +++ b/e2e/paths/04-item/06_botanical.spec.js @@ -21,9 +21,9 @@ describe('Item Create botanical path', () => { await page.autocompleteSearch(selectors.itemBotanical.genus, 'Abelia'); await page.autocompleteSearch(selectors.itemBotanical.species, 'dealbata'); await page.waitToClick(selectors.itemBotanical.submitBotanicalButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should confirm the botanical for the item was created`, async() => { @@ -56,9 +56,9 @@ describe('Item Create botanical path', () => { await page.autocompleteSearch(selectors.itemBotanical.genus, 'Abies'); await page.autocompleteSearch(selectors.itemBotanical.species, 'decurrens'); await page.waitToClick(selectors.itemBotanical.submitBotanicalButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should confirm the botanical for the item was edited`, async() => { diff --git a/e2e/paths/04-item/07_barcode.spec.js b/e2e/paths/04-item/07_barcode.spec.js index 7750b4b6d..0220b3a9d 100644 --- a/e2e/paths/04-item/07_barcode.spec.js +++ b/e2e/paths/04-item/07_barcode.spec.js @@ -21,9 +21,9 @@ describe('Item Create barcodes path', () => { await page.waitToClick(selectors.itemBarcodes.addBarcodeButton); await page.write(selectors.itemBarcodes.thirdCode, '5'); await page.waitToClick(selectors.itemBarcodes.submitBarcodesButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should confirm the barcode 5 is created and it is now the third barcode as the first was deleted`, async() => { diff --git a/e2e/paths/04-item/08_create_and_clone.spec.js b/e2e/paths/04-item/08_create_and_clone.spec.js index d06ef4682..4d035a4c3 100644 --- a/e2e/paths/04-item/08_create_and_clone.spec.js +++ b/e2e/paths/04-item/08_create_and_clone.spec.js @@ -16,34 +16,25 @@ describe('Item Create/Clone path', () => { describe('create', () => { it(`should search for the item Infinity Gauntlet to confirm it isn't created yet`, async() => { - await page.clearInput(selectors.itemsIndex.topbarSearch); - await page.write(selectors.itemsIndex.topbarSearch, 'Infinity Gauntlet'); - await page.waitToClick(selectors.itemsIndex.searchButton); - await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 0); - const result = await page.countElement(selectors.itemsIndex.searchResult); + await page.doSearch('Infinity Gauntlet'); + const nResults = await page.countElement(selectors.itemsIndex.searchResult); - expect(result).toEqual(0); + expect(nResults).toEqual(0); }); it('should access to the create item view by clicking the create floating button', async() => { await page.waitToClick(selectors.itemsIndex.createItemButton); - let url = await page.expectURL('#!/item/create'); - - expect(url).toBe(true); + await page.waitForState('item.create'); }); it('should return to the item index by clickig the cancel button', async() => { await page.waitToClick(selectors.itemCreateView.cancelButton); - let url = await page.expectURL('#!/item/index'); - - expect(url).toBe(true); + await page.waitForState('item.index'); }); it('should now access to the create item view by clicking the create floating button', async() => { await page.waitToClick(selectors.itemsIndex.createItemButton); - let url = await page.expectURL('#!/item/create'); - - expect(url).toBe(true); + await page.waitForState('item.create'); }); it('should create the Infinity Gauntlet item', async() => { @@ -52,9 +43,9 @@ describe('Item Create/Clone path', () => { await page.autocompleteSearch(selectors.itemCreateView.intrastat, 'Coral y materiales similares'); await page.autocompleteSearch(selectors.itemCreateView.origin, 'Holand'); await page.waitToClick(selectors.itemCreateView.createButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm Infinity Gauntlet item was created', async() => { @@ -87,39 +78,28 @@ describe('Item Create/Clone path', () => { it('should return to the items index by clicking the return to items button', async() => { await page.waitToClick(selectors.itemBasicData.goToItemIndexButton); await page.wait(selectors.itemsIndex.createItemButton); - let url = await page.expectURL('#!/item/index'); - - expect(url).toBe(true); + await page.waitForState('item.index'); }); it(`should search for the item Infinity Gauntlet`, async() => { - await page.clearInput(selectors.itemsIndex.topbarSearch); - await page.write(selectors.itemsIndex.topbarSearch, 'Infinity Gauntlet'); - await page.waitToClick(selectors.itemsIndex.searchButton); - await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 1); - const result = await page.countElement(selectors.itemsIndex.searchResult); + await page.doSearch('Infinity Gauntlet'); + const nResults = await page.countElement(selectors.itemsIndex.searchResult); - expect(result).toEqual(1); + expect(nResults).toEqual(1); }); it(`should clone the Infinity Gauntlet`, async() => { await page.waitForTextInElement(selectors.itemsIndex.searchResult, 'Infinity Gauntlet'); await page.waitToClick(selectors.itemsIndex.searchResultCloneButton); await page.waitToClick(selectors.itemsIndex.acceptClonationAlertButton); - let url = await page.expectURL('tags'); - - expect(url).toBe(true); + await page.waitForState('item.tags'); }); it('should search for the item Infinity Gauntlet and find two', async() => { - await page.waitToClick(selectors.itemTags.goToItemIndexButton); - await page.clearInput(selectors.itemsIndex.topbarSearch); - await page.write(selectors.itemsIndex.topbarSearch, 'Infinity Gauntlet'); - await page.waitToClick(selectors.itemsIndex.searchButton); - await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 2); - const result = await page.countElement(selectors.itemsIndex.searchResult); + await page.doSearch('Infinity Gauntlet'); + const nResults = await page.countElement(selectors.itemsIndex.searchResult); - expect(result).toEqual(2); + expect(nResults).toEqual(2); }); }); }); diff --git a/e2e/paths/04-item/09_regularize.spec.js b/e2e/paths/04-item/09_regularize.spec.js index 838b24cf0..6de995515 100644 --- a/e2e/paths/04-item/09_regularize.spec.js +++ b/e2e/paths/04-item/09_regularize.spec.js @@ -18,9 +18,9 @@ describe('Item regularize path', () => { await page.waitForSpinnerLoad(); await page.waitToClick(selectors.globalItems.userMenuButton); await page.autocompleteSearch(selectors.globalItems.userLocalWarehouse, 'Warehouse Four'); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should check the local settings were saved', async() => { @@ -34,9 +34,7 @@ describe('Item regularize path', () => { it('should search for an specific item', async() => { await page.accessToSearchResult('Ranged weapon pistol 9mm'); - let url = await page.expectURL('/summary'); - - expect(url).toBe(true); + await page.waitForState('item.card.summary'); }); it('should open the regularize dialog and check the warehouse matches the local user settings', async() => { @@ -51,9 +49,9 @@ describe('Item regularize path', () => { await page.write(selectors.itemDescriptor.regularizeQuantity, '100'); await page.autocompleteSearch(selectors.itemDescriptor.regularizeWarehouse, 'Warehouse One'); await page.waitToClick(selectors.itemDescriptor.regularizeSaveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should click on the Tickets button of the top bar menu', async() => { @@ -63,27 +61,22 @@ describe('Item regularize path', () => { page.waitForNavigation({waitUntil: ['load', 'networkidle0', 'domcontentloaded']}), page.waitToClick(selectors.globalItems.ticketsButton) ]); - let url = await page.expectURL('#!/ticket/index'); - - expect(url).toBe(true); + await page.waitForState('ticket.index'); }); it('should clear the user local settings now', async() => { - await page.waitForContentLoaded(); await page.waitToClick(selectors.globalItems.userMenuButton); + await page.waitForContentLoaded(); await page.clearInput(selectors.globalItems.userConfigFirstAutocomplete); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should search for the ticket with alias missing', async() => { - await page.accessToSearchResult('Carol Danvers'); await page.keyboard.press('Escape'); await page.accessToSearchResult('missing'); - let url = await page.expectURL('/summary'); - - expect(url).toBe(true); + await page.waitForState('ticket.card.summary'); }); it(`should check the ticket sale quantity is showing a negative value`, async() => { @@ -105,16 +98,12 @@ describe('Item regularize path', () => { await page.waitToClick(selectors.globalItems.applicationsMenuButton); await page.wait(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.itemsButton); - let url = await page.expectURL('#!/item/index'); - - expect(url).toBe(true); + await page.waitForState('item.index'); }); it('should search for the item once again', async() => { await page.accessToSearchResult('Ranged weapon pistol 9mm'); - let url = await page.expectURL('/summary'); - - expect(url).toBe(true); + await page.waitForState('item.card.summary'); }); it('should regularize the item once more', async() => { @@ -123,9 +112,9 @@ describe('Item regularize path', () => { await page.write(selectors.itemDescriptor.regularizeQuantity, '100'); await page.autocompleteSearch(selectors.itemDescriptor.regularizeWarehouse, 'Warehouse One'); await page.waitToClick(selectors.itemDescriptor.regularizeSaveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should again click on the Tickets button of the top bar menu', async() => { @@ -136,16 +125,12 @@ describe('Item regularize path', () => { page.waitToClick(selectors.globalItems.ticketsButton) ]); await page.waitForTransitionEnd('vn-searchbar'); - let url = await page.expectURL('#!/ticket/index'); - - expect(url).toBe(true); + await page.waitForState('ticket.index'); }); it('should search for the ticket with id 25 once again', async() => { await page.accessToSearchResult('25'); - let url = await page.expectURL('/summary'); - - expect(url).toBe(true); + await page.waitForState('ticket.card.summary'); }); it(`should check the ticket contains now two sales`, async() => { diff --git a/e2e/paths/04-item/10_index.spec.js b/e2e/paths/04-item/10_index.spec.js index e15469283..b4c4b636e 100644 --- a/e2e/paths/04-item/10_index.spec.js +++ b/e2e/paths/04-item/10_index.spec.js @@ -34,9 +34,9 @@ describe('Item index path', () => { await page.waitToClick(selectors.itemsIndex.buyerCheckbox); await page.waitToClick(selectors.itemsIndex.destinyCheckbox); await page.waitToClick(selectors.itemsIndex.saveFieldsButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should navigate forth and back to see the images column is still visible', async() => { @@ -68,9 +68,9 @@ describe('Item index path', () => { await page.waitToClick(selectors.itemsIndex.buyerCheckbox); await page.waitToClick(selectors.itemsIndex.destinyCheckbox); await page.waitToClick(selectors.itemsIndex.saveFieldsButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should now navigate forth and back to see the ids column is now visible', async() => { diff --git a/e2e/paths/04-item/11_item_log.spec.js b/e2e/paths/04-item/11_item_log.spec.js index 213365c12..7ea679f4a 100644 --- a/e2e/paths/04-item/11_item_log.spec.js +++ b/e2e/paths/04-item/11_item_log.spec.js @@ -15,19 +15,15 @@ describe('Item log path', () => { }); it(`should search for the Knowledge artifact to confirm it isn't created yet`, async() => { - await page.write(selectors.itemsIndex.topbarSearch, 'Knowledge artifact'); - await page.waitToClick(selectors.itemsIndex.searchButton); - await page.waitForNumberOfElements(selectors.itemsIndex.searchResult, 0); - const result = await page.countElement(selectors.itemsIndex.searchResult); + await page.doSearch('Knowledge artifact'); + const nResults = await page.countElement(selectors.itemsIndex.searchResult); - expect(result).toEqual(0); + expect(nResults).toEqual(0); }); it('should access to the create item view by clicking the create floating button', async() => { await page.waitToClick(selectors.itemsIndex.createItemButton); - let url = await page.expectURL('#!/item/create'); - - expect(url).toBe(true); + await page.waitForState('item.create'); }); it('should create the Knowledge artifact item', async() => { @@ -36,25 +32,21 @@ describe('Item log path', () => { await page.autocompleteSearch(selectors.itemCreateView.intrastat, 'Coral y materiales similares'); await page.autocompleteSearch(selectors.itemCreateView.origin, 'Holand'); await page.waitToClick(selectors.itemCreateView.createButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should return to the items index by clicking the return to items button', async() => { await page.waitToClick(selectors.itemBasicData.goToItemIndexButton); await page.wait(selectors.itemsIndex.createItemButton); - let url = await page.expectURL('#!/item/index'); - - expect(url).toBe(true); + await page.waitForState('item.index'); }); it(`should search for the created item and navigate to it's log section`, async() => { await page.accessToSearchResult('Knowledge artifact'); await page.accessToSection('item.card.log'); - let url = await page.expectURL('/log'); - - expect(url).toBe(true); + await page.waitForState('item.card.log'); }); it(`should confirm the log is showing 5 entries`, async() => { diff --git a/e2e/paths/04-item/12_descriptor.spec.js b/e2e/paths/04-item/12_descriptor.spec.js index 84614cf30..35be1135e 100644 --- a/e2e/paths/04-item/12_descriptor.spec.js +++ b/e2e/paths/04-item/12_descriptor.spec.js @@ -19,7 +19,7 @@ describe('Item descriptor path', () => { it('should check the descriptor inactive icon is dark as the item is active', async() => { await page.wait(selectors.itemDescriptor.inactiveIcon); await page.waitForClassNotPresent(selectors.itemDescriptor.inactiveIcon, 'bright'); - let darkIcon = await page.isVisible(selectors.itemDescriptor.inactiveIcon); + const darkIcon = await page.isVisible(selectors.itemDescriptor.inactiveIcon); expect(darkIcon).toBeTruthy(); }); @@ -27,15 +27,15 @@ describe('Item descriptor path', () => { it('should set the item to inactive', async() => { await page.waitToClick(selectors.itemBasicData.isActiveCheckbox); await page.waitToClick(selectors.itemBasicData.submitBasicDataButton); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should reload the section and check the inactive icon is bright', async() => { await page.reloadSection('item.card.basicData'); await page.waitForClassPresent(selectors.itemDescriptor.inactiveIcon, 'bright'); - let brightIcon = await page.isVisible(selectors.itemDescriptor.inactiveIcon); + const brightIcon = await page.isVisible(selectors.itemDescriptor.inactiveIcon); expect(brightIcon).toBeTruthy(); }); @@ -43,8 +43,8 @@ describe('Item descriptor path', () => { it('should set the item back to active', async() => { await page.waitToClick(selectors.itemBasicData.isActiveCheckbox); await page.waitToClick(selectors.itemBasicData.submitBasicDataButton); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); }); diff --git a/e2e/paths/04-item/13_request.spec.js b/e2e/paths/04-item/13_request.spec.js index d6aecbb48..ab48e0c37 100644 --- a/e2e/paths/04-item/13_request.spec.js +++ b/e2e/paths/04-item/13_request.spec.js @@ -16,9 +16,7 @@ describe('Item request path', () => { }); it('should reach the item request section', async() => { - const result = await page.expectURL('/item/request'); - - expect(result).toBe(true); + await page.waitForState('item.request'); }); it('should fill the id and quantity then check the concept was updated', async() => { @@ -38,9 +36,8 @@ describe('Item request path', () => { it('should now click on the second declain request icon then type the reason', async() => { await page.waitToClick(selectors.itemRequest.secondRequestDecline); - await page.write(selectors.itemRequest.declineReason, 'not quite as expected'); - await page.waitToClick(selectors.itemRequest.acceptDeclineReason); - await page.waitForContentLoaded(); + await page.write(selectors.itemRequest.declineReason, 'Not quite as expected'); + await page.respondToDialog('accept'); let status = await page.waitToGetProperty(selectors.itemRequest.firstRequestStatus, 'innerText'); expect(status).toContain('Denegada'); diff --git a/e2e/paths/05-ticket/01-sale/01_list_sales.spec.js b/e2e/paths/05-ticket/01-sale/01_list_sales.spec.js index a6d34a473..e8b0ad8e7 100644 --- a/e2e/paths/05-ticket/01-sale/01_list_sales.spec.js +++ b/e2e/paths/05-ticket/01-sale/01_list_sales.spec.js @@ -74,9 +74,9 @@ describe('Ticket List sale path', () => { await page.keyboard.press('Enter'); await page.write(selectors.ticketSales.secondSaleQuantity, '1'); await page.keyboard.press('Enter'); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); // #1865 @@ -84,9 +84,9 @@ describe('Ticket List sale path', () => { await page.focusElement(selectors.ticketSales.secondSaleConceptCell); await page.write(selectors.ticketSales.secondSaleConceptInput, 'Aegis of Valor'); await page.keyboard.press('Enter'); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should add a third empty item to the sale list', async() => { @@ -102,9 +102,9 @@ describe('Ticket List sale path', () => { await page.waitToClick(selectors.ticketSales.thirdSaleCheckbox); await page.waitToClick(selectors.ticketSales.deleteSaleButton); await page.waitToClick(selectors.ticketSales.acceptDeleteLineButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should verify there's only 1 single line remaining`, async() => { 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 f2265797c..a22b0e022 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 @@ -19,245 +19,218 @@ xdescribe('Ticket Edit sale path', () => { }); it(`should click on the first sale claim icon to navigate over there`, async() => { - const url = await nightmare - .waitToClick(selectors.ticketSales.firstSaleClaimIcon) - .wait(selectors.claimBasicData.claimState) - .parsedUrl(); + 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'); }); it('should navigate to the tickets index', async() => { - const url = await nightmare - .waitToClick(selectors.globalItems.applicationsMenuButton) - .wait(selectors.globalItems.applicationsMenuVisible) - .waitToClick(selectors.globalItems.ticketsButton) - .wait(selectors.ticketsIndex.topbarSearch) - .parsedUrl(); + 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'); }); it(`should search for a ticket and then navigate to it's sales`, async() => { - const url = await nightmare - .accessToSearchResult(16) - .accessToSection('ticket.card.sale') - .waitForURL('/sale') - .parsedUrl(); + 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 check the zoomed image isn't present`, async() => { - const result = await nightmare - .countElement(selectors.ticketSales.firstSaleZoomedImage); + const result = await page.countElement(selectors.ticketSales.firstSaleZoomedImage); expect(result).toEqual(0); }); it(`should click on the thumbnail image of the 1st sale and see the zoomed image`, async() => { - const result = await nightmare - .clickIfVisible(selectors.ticketSales.firstSaleThumbnailImage) - .countElement(selectors.ticketSales.firstSaleZoomedImage); + await page.clickIfVisible(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() => { - const result = await nightmare - .clickIfVisible(selectors.ticketSales.firstSaleZoomedImage) - .countElement(selectors.ticketSales.firstSaleZoomedImage); + await page.clickIfVisible(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 nightmare - .isVisible(selectors.ticketSales.saleDescriptorPopover); + 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() => { - const visible = await nightmare - .waitToClick(selectors.ticketSales.firstSaleId) - .waitImgLoad(selectors.ticketSales.firstSaleDescriptorImage) - .isVisible(selectors.ticketSales.saleDescriptorPopover); + await page.waitToClick(selectors.ticketSales.firstSaleId); + await page.waitImgLoad(selectors.ticketSales.firstSaleDescriptorImage); + const visible = await page.isVisible(selectors.ticketSales.saleDescriptorPopover); expect(visible).toBeTruthy(); }); it(`should click on the descriptor image of the 1st sale and see the zoomed image`, async() => { - const result = await nightmare - .clickIfVisible('vn-item-descriptor img') - .countElement(selectors.ticketSales.firstSaleZoomedImage); + await page.clickIfVisible('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() => { - const result = await nightmare - .clickIfVisible(selectors.ticketSales.firstSaleZoomedImage) - .countElement(selectors.ticketSales.firstSaleZoomedImage); + await page.clickIfVisible(selectors.ticketSales.firstSaleZoomedImage); + const result = await page.countElement(selectors.ticketSales.firstSaleZoomedImage); expect(result).toEqual(0); }); it(`should click on the summary icon of the item-descriptor to access to the item summary`, async() => { - const url = await nightmare - .waitToClick(selectors.ticketSales.saleDescriptorPopoverSummaryButton) - .waitForURL('/summary') - .parsedUrl(); + await page.waitToClick(selectors.ticketSales.saleDescriptorPopoverSummaryButton); + await page.waitForURL('/summary'); + const url = await page.parsedUrl(); expect(url.hash).toContain('/summary'); }); it('should return to ticket sales section', async() => { - const url = await nightmare - .waitToClick(selectors.globalItems.applicationsMenuButton) - .wait(selectors.globalItems.applicationsMenuVisible) - .waitToClick(selectors.globalItems.ticketsButton) - .accessToSearchResult(16) - .accessToSection('ticket.card.sale') - .waitForURL('/sale') - .parsedUrl(); + await page.waitToClick(selectors.globalItems.applicationsMenuButton); + await page.wait(selectors.globalItems.applicationsMenuVisible); + await page.waitToClick(selectors.globalItems.ticketsButton); + 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() => { - const result = await nightmare - .focusElement(selectors.ticketSales.firstSaleQuantityCell) - .write(selectors.ticketSales.firstSaleQuantity, '11\u000d') - .waitForLastSnackbar(); + await page.focusElement(selectors.ticketSales.firstSaleQuantityCell); + await page.write(selectors.ticketSales.firstSaleQuantity, '11\u000d'); + const message = await page.waitForSnackbar(); - expect(result).toEqual('The new quantity should be smaller than the old one'); + expect(message.text).toBe('The new quantity should be smaller than the old one'); }); it('should remove 1 from the first sale quantity', async() => { - const result = await nightmare - .focusElement(selectors.ticketSales.firstSaleQuantityCell) - .write(selectors.ticketSales.firstSaleQuantity, '9\u000d') - .waitForLastSnackbar(); + await page.focusElement(selectors.ticketSales.firstSaleQuantityCell); + await page.write(selectors.ticketSales.firstSaleQuantity, '9\u000d'); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should update the price', async() => { - const result = await nightmare - .waitToClick(`${selectors.ticketSales.firstSalePrice} > span`) - .write(selectors.ticketSales.firstSalePriceInput, '5\u000d') - .waitForLastSnackbar(); + await page.waitToClick(`${selectors.ticketSales.firstSalePrice} > span`); + await page.write(selectors.ticketSales.firstSalePriceInput, '5\u000d'); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the price have been updated', async() => { - const result = await nightmare - .waitToGetProperty(`${selectors.ticketSales.firstSalePrice} span`, 'innerText'); + const result = await page.waitToGetProperty(`${selectors.ticketSales.firstSalePrice} span`, 'innerText'); expect(result).toContain('5.00'); }); it('should confirm the total price for that item have been updated', async() => { - const result = await nightmare - .waitToGetProperty(selectors.ticketSales.firstSaleImport, 'innerText'); + const result = await page.waitToGetProperty(selectors.ticketSales.firstSaleImport, 'innerText'); expect(result).toContain('45.00'); }); it('should update the discount', async() => { - const result = await nightmare - .waitToClick(`${selectors.ticketSales.firstSaleDiscount} > span`) - .write(selectors.ticketSales.firstSaleDiscountInput, '50\u000d') - .waitForLastSnackbar(); + await page.waitToClick(`${selectors.ticketSales.firstSaleDiscount} > span`); + await page.write(selectors.ticketSales.firstSaleDiscountInput, '50\u000d'); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the discount have been updated', async() => { - const result = await nightmare - .waitForTextInElement(`${selectors.ticketSales.firstSaleDiscount} > span`, '50.00%') - .waitToGetProperty(`${selectors.ticketSales.firstSaleDiscount} > span`, 'innerText'); + await page.waitForTextInElement(`${selectors.ticketSales.firstSaleDiscount} > span`, '50.00%'); + const result = await page.waitToGetProperty(`${selectors.ticketSales.firstSaleDiscount} > span`, 'innerText'); expect(result).toContain('50.00%'); }); it('should confirm the total import for that item have been updated', async() => { - const result = await nightmare - .waitForTextInElement(selectors.ticketSales.firstSaleImport, '22.50') - .waitToGetProperty(selectors.ticketSales.firstSaleImport, 'innerText'); + await page.waitForTextInElement(selectors.ticketSales.firstSaleImport, '22.50'); + const result = await page.waitToGetProperty(selectors.ticketSales.firstSaleImport, 'innerText'); expect(result).toContain('22.50'); }); it('should select the third sale and create a claim of it', async() => { - const url = await nightmare - .waitToClick(selectors.ticketSales.thirdSaleCheckbox) - .waitToClick(selectors.ticketSales.moreMenu) - .waitToClick(selectors.ticketSales.moreMenuCreateClaim) - .wait(selectors.claimBasicData.claimState) - .parsedUrl(); + 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'); }); it('should click on the Claims button of the top bar menu', async() => { - const url = await nightmare - .waitToClick(selectors.globalItems.applicationsMenuButton) - .wait(selectors.globalItems.applicationsMenuVisible) - .waitToClick(selectors.globalItems.claimsButton) - .wait(selectors.claimsIndex.searchClaimInput) - .parsedUrl(); + 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'); }); it('should search for the claim with id 4', async() => { - const result = await nightmare - .write(selectors.claimsIndex.searchClaimInput, 4) - .waitToClick(selectors.claimsIndex.searchButton) - .waitForNumberOfElements(selectors.claimsIndex.searchResult, 1) - .countElement(selectors.claimsIndex.searchResult); + 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); }); it('should click the Tickets button of the top bar menu', async() => { - const url = await nightmare - .waitToClick(selectors.globalItems.applicationsMenuButton) - .wait(selectors.globalItems.applicationsMenuVisible) - .waitToClick(selectors.globalItems.ticketsButton) - .wait(selectors.ticketsIndex.topbarSearch) - .parsedUrl(); + 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'); }); it('should search for a ticket then access to the sales section', async() => { - const url = await nightmare - .accessToSearchResult(16) - .accessToSection('ticket.card.sale') - .waitForURL('/sale') - .parsedUrl(); + 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() => { - const result = await nightmare - .waitToClick(selectors.ticketSales.thirdSaleCheckbox) - .waitToClick(selectors.ticketSales.deleteSaleButton) - .waitToClick(selectors.ticketSales.acceptDeleteLineButton) - .waitForSpinnerLoad() - .waitForLastSnackbar(); + await page.waitToClick(selectors.ticketSales.thirdSaleCheckbox); + await page.waitToClick(selectors.ticketSales.deleteSaleButton); + await page.waitToClick(selectors.ticketSales.acceptDeleteLineButton); + await page.waitForSpinnerLoad(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should confirm the third sale was deleted`, async() => { - const result = await nightmare - .countElement(selectors.ticketSales.saleLine); + const result = await page.countElement(selectors.ticketSales.saleLine); expect(result).toEqual(3); }); @@ -265,67 +238,60 @@ xdescribe('Ticket Edit sale path', () => { it('should select the second sale and transfer it to a valid ticket', async() => { const targetTicketId = 12; - const result = await nightmare - .waitToClick(selectors.ticketSales.secondSaleCheckbox) - .waitToClick(selectors.ticketSales.transferSaleButton) - .focusElement(selectors.ticketSales.transferQuantityCell) - .write(selectors.ticketSales.transferQuantityInput, '10\u000d') - .write(selectors.ticketSales.moveToTicketInput, targetTicketId) - .waitToClick(selectors.ticketSales.moveToTicketButton) - .waitForURL(`ticket/${targetTicketId}/sale`) - .parsedUrl(); + 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.moveToTicketButton); + await page.waitForURL(`ticket/${targetTicketId}/sale`); + const result = await page.parsedUrl(); expect(result.hash).toContain(`ticket/${targetTicketId}/sale`); }); it('should confirm the transfered line is the correct one', async() => { - const result = await nightmare - .wait(selectors.ticketSales.secondSaleText) - .waitToGetProperty(selectors.ticketSales.secondSaleText, 'innerText'); + await page.wait(selectors.ticketSales.secondSaleText); + const result = await page.waitToGetProperty(selectors.ticketSales.secondSaleText, 'innerText'); expect(result).toContain(`Melee weapon heavy shield`); }); it('should confirm the transfered quantity is the correct one', async() => { - const result = await nightmare - .waitToGetProperty(selectors.ticketSales.secondSaleQuantityCell, 'innerText'); + const result = await page.waitToGetProperty(selectors.ticketSales.secondSaleQuantityCell, 'innerText'); expect(result).toContain('10'); }); it('should go back to the original ticket sales section', async() => { - const url = await nightmare - .waitToClick(selectors.ticketDescriptor.goBackToModuleIndexButton) - .accessToSearchResult(16) - .accessToSection('ticket.card.sale') - .waitForURL('/sale') - .parsedUrl(); + await page.waitToClick(selectors.ticketDescriptor.goBackToModuleIndexButton); + 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() => { - const result = await nightmare - .wait(selectors.ticketSales.saleLine) - .countElement(selectors.ticketSales.saleLine); + await page.wait(selectors.ticketSales.saleLine); + const result = await page.countElement(selectors.ticketSales.saleLine); expect(result).toEqual(3); }); it(`should confirm the second sale quantity is now half of it's original value after the transfer`, async() => { - const result = await nightmare - .waitToGetProperty(selectors.ticketSales.secondSaleQuantityCell, 'innerText'); + const result = await page.waitToGetProperty(selectors.ticketSales.secondSaleQuantityCell, 'innerText'); expect(result).toContain('10'); }); it('should go back to the receiver ticket sales section', async() => { - const url = await nightmare - .waitToClick(selectors.ticketDescriptor.goBackToModuleIndexButton) - .accessToSearchResult(12) - .accessToSection('ticket.card.sale') - .waitForURL('/sale') - .parsedUrl(); + await page.waitToClick(selectors.ticketDescriptor.goBackToModuleIndexButton); + await page.accessToSearchResult(12); + await page.accessToSection('ticket.card.sale'); + await page.waitForURL('/sale'); + const url = await page.parsedUrl(); expect(url.hash).toContain('/sale'); }); @@ -333,44 +299,40 @@ xdescribe('Ticket Edit sale path', () => { it('should transfer the sale back to the original ticket', async() => { const targetTicketId = 16; - const result = await nightmare - .waitToClick(selectors.ticketSales.secondSaleCheckbox) - .waitToClick(selectors.ticketSales.transferSaleButton) - .write(selectors.ticketSales.moveToTicketInput, targetTicketId) - .waitToClick(selectors.ticketSales.moveToTicketButton) - .waitForURL(`ticket/${targetTicketId}/sale`) - .parsedUrl(); + await page.waitToClick(selectors.ticketSales.secondSaleCheckbox); + await page.waitToClick(selectors.ticketSales.transferSaleButton); + await page.write(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`); }); it('should confirm the original ticket received the line', async() => { const expectedLines = 4; - const result = await nightmare - .waitForNumberOfElements(selectors.ticketSales.saleLine, expectedLines) - .countElement(selectors.ticketSales.saleLine); + await page.waitForNumberOfElements(selectors.ticketSales.saleLine, expectedLines); + const result = await page.countElement(selectors.ticketSales.saleLine); expect(result).toEqual(expectedLines); }); it(`should throw an error when attempting to create a ticket for an inactive client`, async() => { - const result = await nightmare - .waitToClick(selectors.ticketSales.firstSaleCheckbox) - .waitToClick(selectors.ticketSales.transferSaleButton) - .waitToClick(selectors.ticketSales.moveToNewTicketButton) - .waitToClick(selectors.ticketSales.acceptDeleteTicketButton) - .waitForLastSnackbar(); + 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(result).toEqual(`You can't create a ticket for a inactive client`); + expect(message.text).toBe(`You can't create a ticket for a inactive client`); }); it('should go now to the ticket sales section of an active, not frozen client', async() => { - const url = await nightmare - .waitToClick(selectors.ticketDescriptor.goBackToModuleIndexButton) - .accessToSearchResult(13) - .accessToSection('ticket.card.sale') - .waitForURL('/sale') - .parsedUrl(); + await page.waitToClick(selectors.ticketDescriptor.goBackToModuleIndexButton); + await page.accessToSearchResult(13); + await page.accessToSection('ticket.card.sale'); + await page.waitForURL('/sale'); + const url = await page.parsedUrl(); expect(url.hash).toContain('/sale'); }); @@ -378,118 +340,106 @@ xdescribe('Ticket Edit sale path', () => { 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 url = await nightmare - .waitToClick(selectors.ticketSales.selectAllSalesCheckbox) - .waitToClick(selectors.ticketSales.transferSaleButton) - .waitToClick(selectors.ticketSales.moveToNewTicketButton) - .waitToClick(selectors.ticketSales.acceptDeleteTicketButton) - .wait((selector, ticketId) => { - return document.querySelector(selector).innerText.toLowerCase().indexOf(`${ticketId}`) == -1; - }, selectors.ticketDescriptor.idLabelValue, senderTicketId) - .parsedUrl(); + 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'); }); it('should confirm the new ticket received the line', async() => { - const result = await nightmare - .countElement(selectors.ticketSales.saleLine); + const result = await page.countElement(selectors.ticketSales.saleLine); expect(result).toEqual(1); }); it('should check the first sale reserved icon isnt visible', async() => { - const result = await nightmare - .isVisible(selectors.ticketSales.firstSaleReservedIcon); + const result = await page.isVisible(selectors.ticketSales.firstSaleReservedIcon); expect(result).toBeFalsy(); }); it('should mark the first sale as reserved', async() => { - const result = await nightmare - .waitToClick(selectors.ticketSales.firstSaleCheckbox) - .waitToClick(selectors.ticketSales.moreMenu) - .waitToClick(selectors.ticketSales.moreMenuReserve) - .waitForClassNotPresent(selectors.ticketSales.firstSaleReservedIcon, 'ng-hide') - .isVisible(selectors.ticketSales.firstSaleReservedIcon); + await page.waitToClick(selectors.ticketSales.firstSaleCheckbox); + await page.waitToClick(selectors.ticketSales.moreMenu); + await page.waitToClick(selectors.ticketSales.moreMenuReserve); + await page.waitForClassNotPresent(selectors.ticketSales.firstSaleReservedIcon, 'ng-hide'); + const result = await page.isVisible(selectors.ticketSales.firstSaleReservedIcon); expect(result).toBeTruthy(); }); it('should unmark the first sale as reserved', async() => { - const result = await nightmare - .waitToClick(selectors.ticketSales.moreMenu) - .waitToClick(selectors.ticketSales.moreMenuUnmarkReseved) - .waitForClassPresent(selectors.ticketSales.firstSaleReservedIcon, 'ng-hide') - .isVisible(selectors.ticketSales.firstSaleReservedIcon); + await page.waitToClick(selectors.ticketSales.moreMenu); + await page.waitToClick(selectors.ticketSales.moreMenuUnmarkReseved); + await page.waitForClassPresent(selectors.ticketSales.firstSaleReservedIcon, 'ng-hide'); + const result = await page.isVisible(selectors.ticketSales.firstSaleReservedIcon); expect(result).toBeFalsy(); }); it('should update all sales discount', async() => { - const result = await nightmare - .waitToClick(selectors.ticketSales.moreMenu) - .waitToClick(selectors.ticketSales.moreMenuUpdateDiscount) - // .write(selectors.ticketSales.moreMenuUpdateDiscountInput, 100) can't find the selector on app (deleted the selector), menu option was removed? - .write('body', '\u000d') - .waitForTextInElement(selectors.ticketSales.totalImport, '0.00') - .waitToGetProperty(selectors.ticketSales.totalImport, 'innerText'); + 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.waitForTextInElement(selectors.ticketSales.totalImport, '0.00'); + const result = await page.waitToGetProperty(selectors.ticketSales.totalImport, 'innerText'); expect(result).toContain('0.00'); }); it('should log in as Production role and go to a target ticket summary', async() => { - const url = await nightmare - .loginAndModule('production', 'ticket') - .accessToSearchResult(13) - .waitForURL('/summary') - .parsedUrl(); + await page.loginAndModule('production', 'ticket'); + await page.accessToSearchResult(13); + await page.waitForURL('/summary'); + const url = await page.parsedUrl(); expect(url.hash).toContain('/summary'); }); it(`should check it's state is deleted`, async() => { - const result = await nightmare - .waitToGetProperty(selectors.ticketDescriptor.stateLabelValue, 'innerText'); + 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() => { - const result = await nightmare - .waitToClick(selectors.ticketDescriptor.goBackToModuleIndexButton) - .accessToSearchResult(8) - .accessToSection('ticket.card.sale') - .waitToClick(selectors.ticketSales.firstSalePrice) - .exists(selectors.ticketSales.firstSalePriceInput); + 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() => { - const result = await nightmare - .waitToClick(selectors.ticketSales.firstSaleDiscount) - .exists(selectors.ticketSales.firstSaleDiscountInput); + 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() => { - const result = await nightmare - .waitToClick(selectors.ticketSales.stateMenuButton) - .exists(selectors.ticketSales.stateMenuOptions); + 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() => { - const url = await nightmare - .loginAndModule('salesPerson', 'ticket') - .accessToSearchResult(8) - .accessToSection('ticket.card.sale') - .waitForURL('/sale') - .parsedUrl(); + 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'); }); @@ -497,25 +447,22 @@ xdescribe('Ticket Edit sale path', () => { describe('when state is preparation and loged as salesPerson', () => { it(`shouldn't be able to edit the sale price`, async() => { - const result = await nightmare - .waitToClick(selectors.ticketSales.firstSalePrice) - .exists(selectors.ticketSales.firstSalePriceInput); + 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() => { - const result = await nightmare - .waitToClick(selectors.ticketSales.firstSaleDiscount) - .exists(selectors.ticketSales.firstSaleDiscountInput); + 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() => { - const result = await nightmare - .waitToClick(selectors.ticketSales.stateMenuButton) - .exists(selectors.ticketSales.stateMenuOptions); + await page.waitToClick(selectors.ticketSales.stateMenuButton); + const result = await page.exists(selectors.ticketSales.stateMenuOptions); expect(result).toBeFalsy(); }); diff --git a/e2e/paths/05-ticket/01_observations.spec.js b/e2e/paths/05-ticket/01_observations.spec.js index cccfa8b67..d919b8ed3 100644 --- a/e2e/paths/05-ticket/01_observations.spec.js +++ b/e2e/paths/05-ticket/01_observations.spec.js @@ -22,9 +22,9 @@ describe('Ticket Create notes path', () => { await page.autocompleteSearch(selectors.ticketNotes.firstNoteType, 'observation one'); await page.write(selectors.ticketNotes.firstDescription, 'description'); await page.waitToClick(selectors.ticketNotes.submitNotesButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the note is the expected one', async() => { @@ -43,8 +43,8 @@ describe('Ticket Create notes path', () => { it('should delete the note', async() => { await page.waitToClick(selectors.ticketNotes.firstNoteRemoveButton); await page.waitToClick(selectors.ticketNotes.submitNotesButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); }); diff --git a/e2e/paths/05-ticket/02_expeditions_and_log.spec.js b/e2e/paths/05-ticket/02_expeditions_and_log.spec.js index 94fad9b69..2d046e3a9 100644 --- a/e2e/paths/05-ticket/02_expeditions_and_log.spec.js +++ b/e2e/paths/05-ticket/02_expeditions_and_log.spec.js @@ -19,8 +19,9 @@ describe('Ticket expeditions and log path', () => { it(`should delete a former expedition and confirm the remaining expedition are the expected ones`, async() => { await page.waitToClick(selectors.ticketExpedition.secondExpeditionRemoveButton); - await page.waitToClick(selectors.ticketExpedition.acceptDeleteRowButton), + await page.waitToClick(selectors.ticketExpedition.acceptDeleteRowButton); await page.reloadSection('ticket.card.expedition'); + await page.waitForSelector(selectors.ticketExpedition.expeditionRow, {}); const result = await page .countElement(selectors.ticketExpedition.expeditionRow); @@ -29,7 +30,7 @@ describe('Ticket expeditions and log path', () => { }); it(`should confirm the expedition deleted is shown now in the ticket log`, async() => { - await page.waitToClick(selectors.ticketLog.logButton); + await page.accessToSection('ticket.card.log'); const changedBy = await page .waitToGetProperty(selectors.ticketLog.changedBy, 'innerText'); diff --git a/e2e/paths/05-ticket/04_packages.spec.js b/e2e/paths/05-ticket/04_packages.spec.js index fd2945877..3db53587c 100644 --- a/e2e/paths/05-ticket/04_packages.spec.js +++ b/e2e/paths/05-ticket/04_packages.spec.js @@ -22,18 +22,18 @@ describe('Ticket Create packages path', () => { await page.waitToClick(selectors.ticketPackages.addPackageButton); await page.write(selectors.ticketPackages.firstQuantity, '99'); await page.waitToClick(selectors.ticketPackages.savePackagesButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Package cannot be blank'); + expect(message.text).toBe('Package cannot be blank'); }); it(`should delete the first package and receive and error to save a new one with blank quantity`, async() => { await page.clearInput(selectors.ticketPackages.firstQuantity); await page.autocompleteSearch(selectors.ticketPackages.firstPackage, 'Container medical box 1m'); await page.waitToClick(selectors.ticketPackages.savePackagesButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Some fields are invalid'); + expect(message.text).toBe('Some fields are invalid'); }); it(`should confirm the quantity input isn't invalid yet`, async() => { @@ -49,9 +49,9 @@ describe('Ticket Create packages path', () => { await page.clearInput(selectors.ticketPackages.firstQuantity); await page.write(selectors.ticketPackages.firstQuantity, '-99'); await page.waitToClick(selectors.ticketPackages.savePackagesButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should confirm the first select is the expected one`, async() => { diff --git a/e2e/paths/05-ticket/05_tracking_state.spec.js b/e2e/paths/05-ticket/05_tracking_state.spec.js index 108e8776f..34f3c4d44 100644 --- a/e2e/paths/05-ticket/05_tracking_state.spec.js +++ b/e2e/paths/05-ticket/05_tracking_state.spec.js @@ -21,24 +21,22 @@ describe('Ticket Create new tracking state path', () => { it('should access to the create state view by clicking the create floating button', async() => { await page.waitToClick(selectors.ticketTracking.createStateButton); await page.waitForSelector(selectors.createStateView.state, {visible: true}); - let url = await page.expectURL('tracking/edit'); - - expect(url).toBe(true); + await page.waitForState('ticket.card.tracking.edit'); }); it(`should attempt create a new state but receive an error if state is empty`, async() => { await page.waitToClick(selectors.createStateView.saveStateButton); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('State cannot be blank'); + expect(message.text).toBe('State cannot be blank'); }); it(`should create a new state`, async() => { await page.autocompleteSearch(selectors.createStateView.state, '¿Fecha?'); await page.waitToClick(selectors.createStateView.saveStateButton); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); }); @@ -51,23 +49,21 @@ describe('Ticket Create new tracking state path', () => { it('should now access to the create state view by clicking the create floating button', async() => { await page.waitToClick(selectors.ticketTracking.createStateButton); - let url = await page.expectURL('tracking/edit'); - - expect(url).toBe(true); + await page.waitForState('ticket.card.tracking.edit'); }); it(`should attemp to create an state for which salesPerson doesn't have permissions`, async() => { await page.waitFor(1500); await page.autocompleteSearch(selectors.createStateView.state, 'Encajado'); await page.waitToClick(selectors.createStateView.saveStateButton); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual(`You don't have enough privileges`); + expect(message.text).toBe(`You don't have enough privileges`); }); it(`should make sure the worker gets autocomplete uppon selecting the assigned state`, async() => { await page.autocompleteSearch(selectors.createStateView.state, 'asignado'); - let result = await page + const result = await page .waitToGetProperty(selectors.createStateView.worker, 'value'); expect(result).toEqual('salesPersonNick'); @@ -75,9 +71,9 @@ describe('Ticket Create new tracking state path', () => { it(`should succesfully create a valid state`, async() => { await page.waitToClick(selectors.createStateView.saveStateButton); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); }); }); diff --git a/e2e/paths/05-ticket/06_basic_data_steps.spec.js b/e2e/paths/05-ticket/06_basic_data_steps.spec.js index de78b9fa7..3191673a5 100644 --- a/e2e/paths/05-ticket/06_basic_data_steps.spec.js +++ b/e2e/paths/05-ticket/06_basic_data_steps.spec.js @@ -68,9 +68,7 @@ describe('Ticket Edit basic data path', () => { it(`should click next`, async() => { await page.waitToClick(selectors.ticketBasicData.nextStepButton); - let url = await page.expectURL('data/step-two'); - - expect(url).toBe(true); + await page.waitForState('ticket.card.basicData.stepTwo'); }); it(`should have a price diference`, async() => { @@ -83,8 +81,6 @@ describe('Ticket Edit basic data path', () => { it(`should select a new reason for the changes made then click on finalize`, async() => { await page.waitToClick(selectors.ticketBasicData.chargesReason); await page.waitToClick(selectors.ticketBasicData.finalizeButton); - let url = await page.expectURL('summary'); - - expect(url).toBe(true); + await page.waitForState('ticket.card.summary'); }); }); diff --git a/e2e/paths/05-ticket/09_weekly.spec.js b/e2e/paths/05-ticket/09_weekly.spec.js index 3e791dc18..79722d2f7 100644 --- a/e2e/paths/05-ticket/09_weekly.spec.js +++ b/e2e/paths/05-ticket/09_weekly.spec.js @@ -17,7 +17,6 @@ describe('Ticket descriptor path', () => { }); it('should count the amount of tickets in the turns section', async() => { - await page.waitForNumberOfElements(selectors.ticketsIndex.weeklyTicket, 5); const result = await page.countElement(selectors.ticketsIndex.weeklyTicket); expect(result).toEqual(5); @@ -32,18 +31,16 @@ describe('Ticket descriptor path', () => { await page.waitToClick(selectors.ticketDescriptor.moreMenu); await page.waitToClick(selectors.ticketDescriptor.moreMenuAddToTurn); await page.waitToClick(selectors.ticketDescriptor.thursdayButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should again click on 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); - let url = await page.expectURL('#!/ticket/index'); - - expect(url).toBe(true); + await page.waitForState('ticket.index'); }); it('should confirm the ticket 11 was added to thursday', async() => { @@ -57,43 +54,28 @@ describe('Ticket descriptor path', () => { await page.waitToClick(selectors.globalItems.applicationsMenuButton); await page.wait(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.ticketsButton); - let url = await page.expectURL('#!/ticket/index'); - - expect(url).toBe(true); + await page.waitForState('ticket.index'); }); it('should now search for the ticket 11', async() => { - await page.write(selectors.ticketsIndex.topbarSearch, '11'); - await page.waitToClick(selectors.ticketsIndex.searchButton); - await page.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1); - const result = await page.countElement(selectors.ticketsIndex.searchResult); - - expect(result).toEqual(1); - }); - - it(`should click on the search result to access to the ticket`, async() => { - await page.waitToClick(selectors.ticketsIndex.searchResult); - let url = await page.expectURL('/summary'); - - expect(url).toBe(true); + await page.accessToSearchResult('11'); + await page.waitForState('ticket.card.summary'); }); it('should add the ticket to saturday turn using the descriptor more menu', async() => { await page.waitToClick(selectors.ticketDescriptor.moreMenu); await page.waitToClick(selectors.ticketDescriptor.moreMenuAddToTurn); await page.waitToClick(selectors.ticketDescriptor.saturdayButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should click on the Tickets button of the top bar menu once again', async() => { await page.waitToClick(selectors.globalItems.applicationsMenuButton); await page.wait(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.ticketsButton); - let url = await page.expectURL('#!/ticket/index'); - - expect(url).toBe(true); + await page.waitForState('ticket.index'); }); it('should confirm the ticket 11 was added on saturday', async() => { @@ -104,29 +86,36 @@ describe('Ticket descriptor path', () => { }); it('should now search for the weekly ticket 11', async() => { - await page.write(selectors.ticketsIndex.topbarSearch, '11'); - await page.waitToClick(selectors.ticketsIndex.searchButton); - await page.waitForNumberOfElements(selectors.ticketsIndex.searchWeeklyResult, 1); - const result = await page.countElement(selectors.ticketsIndex.searchWeeklyResult); + await page.doSearch('11'); + const nResults = await page.countElement(selectors.ticketsIndex.searchWeeklyResult); - expect(result).toEqual(1); + expect(nResults).toEqual(1); }); it('should delete the weekly ticket 11', async() => { await page.waitToClick(selectors.ticketsIndex.firstWeeklyTicketDeleteIcon); await page.waitToClick(selectors.ticketsIndex.acceptDeleteTurn); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the sixth weekly ticket was deleted', async() => { - await page.waitForContentLoaded(); - await page.clearInput('vn-searchbar'); - await page.waitToClick(selectors.ticketsIndex.searchWeeklyButton); - await page.waitForNumberOfElements(selectors.ticketsIndex.searchWeeklyResult, 5); - const result = await page.countElement(selectors.ticketsIndex.searchWeeklyResult); + await page.doSearch(); + const nResults = await page.countElement(selectors.ticketsIndex.searchWeeklyResult); - expect(result).toEqual(5); + expect(nResults).toEqual(5); + }); + + it('should update the agency then remove it afterwards', async() => { + await page.autocompleteSearch(selectors.ticketsIndex.firstWeeklyTicketAgency, 'Silla247'); + let message = await page.waitForSnackbar(); + + expect(message.type).toBe('success'); + + await page.clearInput(selectors.ticketsIndex.firstWeeklyTicketAgency); + message = await page.waitForSnackbar(); + + expect(message.type).toBe('success'); }); }); diff --git a/e2e/paths/05-ticket/10_request.spec.js b/e2e/paths/05-ticket/10_request.spec.js index 737d69048..334b8ba5e 100644 --- a/e2e/paths/05-ticket/10_request.spec.js +++ b/e2e/paths/05-ticket/10_request.spec.js @@ -24,24 +24,21 @@ describe('Ticket purchase request path', () => { await page.autocompleteSearch(selectors.ticketRequests.atender, 'buyerNick'); await page.write(selectors.ticketRequests.price, '999'); await page.waitToClick(selectors.ticketRequests.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should have been redirected to the request index', async() => { - let url = await page.expectURL('/request'); - - expect(url).toBe(true); + await page.waitForState('ticket.card.request.index'); }); it(`should edit the third request quantity as it's state is still new`, async() => { - await page.waitFor(2000); // looks like it needs more than a single second some times to load await page.write(selectors.ticketRequests.thirdRequestQuantity, '9'); await page.keyboard.press('Enter'); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the new request was added', async() => { @@ -67,9 +64,9 @@ describe('Ticket purchase request path', () => { it('should delete the added request', async() => { await page.waitToClick(selectors.ticketRequests.thirdRemoveRequestButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the request was deleted', async() => { diff --git a/e2e/paths/05-ticket/11_diary.spec.js b/e2e/paths/05-ticket/11_diary.spec.js index b529ee1ff..a75e1ae24 100644 --- a/e2e/paths/05-ticket/11_diary.spec.js +++ b/e2e/paths/05-ticket/11_diary.spec.js @@ -1,66 +1,31 @@ import selectors from '../../helpers/selectors.js'; import getBrowser from '../../helpers/puppeteer'; -// #2026 Fallo en relocate de descriptor popover +// #2221 Local MySQL8 crashes when rest method Items/getDiary is called xdescribe('Ticket diary path', () => { - let browser; let page; beforeAll(async() => { - browser = await getBrowser(); - page = browser.page; + page = (await getBrowser()).page; await page.loginAndModule('employee', 'ticket'); }); afterAll(async() => { - await browser.close(); + await page.browser().close(); }); - it('should search for a specific ticket', async() => { - await page.write(selectors.ticketsIndex.topbarSearch, '1'); - await page.waitToClick(selectors.ticketsIndex.searchButton); - await page.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1); - const result = await page.countElement(selectors.ticketsIndex.searchResult); - - expect(result).toEqual(1); - }); - - it(`should click on the search result to access to the ticket summary`, async() => { - await page.waitForTextInElement(selectors.ticketsIndex.searchResult, 'Bat cave'); - await page.waitToClick(selectors.ticketsIndex.searchResult); - let url = await page.expectURL('/summary'); - - expect(url).toBe(true); - }); - - it(`should navigate to the item diary from the 1st sale item id descriptor popover`, async() => { + it(`should navigate to item diary from ticket sale and check the lines`, async() => { + await page.accessToSearchResult('1'); await page.waitToClick(selectors.ticketSummary.firstSaleItemId); - await page.waitForTransitionEnd('.vn-popover'); await page.waitToClick(selectors.ticketSummary.popoverDiaryButton); - let url = await page.expectURL('/diary'); + await page.waitForState('item.card.diary'); - expect(url).toBe(true); - }); + const secondIdClass = await page.getClassName(selectors.itemDiary.secondTicketId); + const fourthBalanceClass = await page.getClassName(selectors.itemDiary.fourthBalance); + const firstBalanceClass = await page.getClassName(selectors.itemDiary.firstBalance); - it(`should check the second line id is marked as message`, async() => { - const result = await page - .waitToGetProperty(selectors.itemDiary.secondTicketId, 'className'); - - expect(result).toContain('message'); - }); - - it(`should check the third line balance is marked as message`, async() => { - const result = await page - .waitToGetProperty(`${selectors.itemDiary.fourthBalance} > span`, 'className'); - - expect(result).toContain('message'); - }); - - it(`should change to the warehouse two and check there are sales marked as negative balance`, async() => { - await page.autocompleteSearch(selectors.itemDiary.warehouse, 'Warehouse Two'); - const result = await page - .waitToGetProperty(selectors.itemDiary.firstBalance, 'className'); - - expect(result).toContain('balance'); + expect(secondIdClass).toContain('message'); + expect(fourthBalanceClass).toContain('message'); + expect(firstBalanceClass).toContain('balance'); }); }); diff --git a/e2e/paths/05-ticket/12_descriptor.spec.js b/e2e/paths/05-ticket/12_descriptor.spec.js index 59691d380..87990bcc5 100644 --- a/e2e/paths/05-ticket/12_descriptor.spec.js +++ b/e2e/paths/05-ticket/12_descriptor.spec.js @@ -18,9 +18,7 @@ describe('Ticket descriptor path', () => { describe('Delete ticket', () => { it('should search for an specific ticket', async() => { await page.accessToSearchResult('18'); - let url = await page.expectURL('/summary'); - - expect(url).toBe(true); + await page.waitForState('ticket.card.summary'); }); it(`should update the shipped hour using the descriptor menu`, async() => { @@ -28,9 +26,9 @@ describe('Ticket descriptor path', () => { await page.waitToClick(selectors.ticketDescriptor.moreMenuChangeShippedHour); await page.pickTime(selectors.ticketDescriptor.changeShippedHour, '08:15'); await page.waitToClick(selectors.ticketDescriptor.acceptChangeHourButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Shipped hour updated'); + expect(message.text).toBe('Shipped hour updated'); }); it(`should confirm the ticket descriptor shows the correct shipping hour`, async() => { @@ -44,22 +42,19 @@ describe('Ticket descriptor path', () => { await page.waitToClick(selectors.ticketDescriptor.moreMenu); await page.waitToClick(selectors.ticketDescriptor.moreMenuDeleteTicket); await page.waitToClick(selectors.ticketDescriptor.acceptDeleteButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Ticket deleted'); + expect(message.text).toBe('Ticket deleted'); }); it('should have been relocated to the ticket index', async() => { - let url = await page.expectURL('#!/ticket/index'); - - expect(url).toBe(true); + await page.waitForState('ticket.index'); }); it(`should search for the deleted ticket and check it's date`, async() => { await page.write(selectors.ticketsIndex.topbarSearch, '18'); await page.waitToClick(selectors.ticketsIndex.searchButton); - await page.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1); - await page.wait(selectors.ticketsIndex.searchResultDate); + await page.waitForState('ticket.card.summary'); const result = await page.waitToGetProperty(selectors.ticketsIndex.searchResultDate, 'innerText'); expect(result).toContain(2000); @@ -69,9 +64,7 @@ describe('Ticket descriptor path', () => { describe('add stowaway', () => { it('should search for a ticket', async() => { await page.accessToSearchResult('16'); - let url = await page.expectURL('/summary'); - - expect(url).toBe(true); + await page.waitForState('ticket.card.summary'); }); it('should open the add stowaway dialog', async() => { @@ -89,9 +82,9 @@ describe('Ticket descriptor path', () => { it('should add a ticket as stowaway', async() => { await page.waitToClick(selectors.ticketDescriptor.addStowawayDialogFirstTicket); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should check the state of the stowaway ticket is embarked`, async() => { @@ -102,19 +95,17 @@ describe('Ticket descriptor path', () => { it(`should navigate back to the added ticket using the descriptors ship button`, async() => { await page.waitToClick(selectors.ticketDescriptor.shipButton); - let url = await page.expectURL('#!/ticket/17/summary'); - - expect(url).toBe(true); + await page.waitForState('ticket.card.summary'); }); it('should delete the stowaway', async() => { - await page.waitForContentLoaded(); await page.waitToClick(selectors.ticketDescriptor.moreMenu); + await page.waitForContentLoaded(); await page.waitToClick(selectors.ticketDescriptor.moreMenuDeleteStowawayButton); await page.waitToClick(selectors.ticketDescriptor.acceptDeleteStowawayButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should confirm the ship buton doesn't exisist any more`, async() => { @@ -128,9 +119,7 @@ describe('Ticket descriptor path', () => { await page.loginAndModule('adminBoss', 'ticket'); await page.accessToSearchResult(invoiceableTicketId); - let url = await page.expectURL(`ticket/${invoiceableTicketId}/summary`); - - expect(url).toBe(true); + await page.waitForState('ticket.card.summary'); }); it(`should make sure the ticket doesn't have an invoiceOutFk yet`, async() => { @@ -141,13 +130,13 @@ describe('Ticket descriptor path', () => { }); it('should invoice the ticket using the descriptor more menu', async() => { - await page.waitForContentLoaded(); await page.waitToClick(selectors.ticketDescriptor.moreMenu); + await page.waitForContentLoaded(); await page.waitToClick(selectors.ticketDescriptor.moreMenuMakeInvoice); await page.waitToClick(selectors.ticketDescriptor.acceptInvoiceOutButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Ticket invoiced'); + expect(message.text).toBe('Ticket invoiced'); }); it(`should make sure the ticket summary have an invoiceOutFk`, async() => { diff --git a/e2e/paths/05-ticket/13_services.spec.js b/e2e/paths/05-ticket/13_services.spec.js index 07a0a5768..08b9219a5 100644 --- a/e2e/paths/05-ticket/13_services.spec.js +++ b/e2e/paths/05-ticket/13_services.spec.js @@ -32,9 +32,9 @@ describe('Ticket services path', () => { await page.clearInput(selectors.ticketService.firstPrice); await page.write(selectors.ticketService.firstPrice, '999'); await page.waitToClick(selectors.ticketService.saveServiceButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual(`The current ticket can't be modified`); + expect(message.text).toBe(`The current ticket can't be modified`); }); }); @@ -44,9 +44,6 @@ describe('Ticket services path', () => { await page.loginAndModule('administrative', 'ticket'); await page.accessToSearchResult(editableTicketId); await page.accessToSection('ticket.card.service'); - let url = await page.expectURL('/service'); - - expect(url).toBe(true); }); it('should click on the add button to prepare the form to create a new service', async() => { @@ -59,9 +56,9 @@ describe('Ticket services path', () => { it('should receive an error if you attempt to save it with empty fields', async() => { await page.waitToClick(selectors.ticketService.saveServiceButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual(`can't be blank`); + expect(message.text).toBe(`can't be blank`); }); it('should click on the add new service type to open the dialog', async() => { @@ -74,9 +71,9 @@ describe('Ticket services path', () => { it('should receive an error if service type is empty on submit', async() => { await page.waitToClick(selectors.ticketService.saveServiceTypeButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual(`Name can't be empty`); + expect(message.text).toBe(`Name can't be empty`); }); it('should create a new service type then add price then create the service', async() => { @@ -84,11 +81,10 @@ describe('Ticket services path', () => { await page.autocompleteSearch(selectors.ticketService.newServiceTypeExpense, 'Retencion'); await page.waitToClick(selectors.ticketService.saveServiceTypeButton); await page.write(selectors.ticketService.firstPrice, '999'); - await page.waitFor(1000); // time needed for the button to be clickable await page.waitToClick(selectors.ticketService.saveServiceButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the service description was created correctly', async() => { @@ -123,19 +119,17 @@ describe('Ticket services path', () => { it('should delete the service', async() => { await page.waitToClick(selectors.ticketService.fistDeleteServiceButton); await page.waitForNumberOfElements(selectors.ticketService.serviceLine, 0); - await page.waitFor(1000); // without this wait it fails to click the save button await page.waitToClick(selectors.ticketService.saveServiceButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should confirm the service was removed`, async() => { await page.reloadSection('ticket.card.service'); - await page.waitForNumberOfElements(selectors.ticketService.serviceLine, 0); - const result = await page.countElement(selectors.ticketService.serviceLine); + const nResults = await page.countElement(selectors.ticketService.serviceLine); - expect(result).toEqual(0); + expect(nResults).toEqual(0); }); }); }); diff --git a/e2e/paths/05-ticket/14_create_ticket.spec.js b/e2e/paths/05-ticket/14_create_ticket.spec.js index e501ea0ef..4ce2e5156 100644 --- a/e2e/paths/05-ticket/14_create_ticket.spec.js +++ b/e2e/paths/05-ticket/14_create_ticket.spec.js @@ -17,26 +17,25 @@ describe('Ticket create path', () => { it('should open the new ticket form', async() => { await page.waitToClick(selectors.ticketsIndex.newTicketButton); - let url = await page.expectURL('#!/ticket/create'); - - expect(url).toBe(true); + await page.waitForState('ticket.create'); }); it('should succeed to create a ticket', async() => { + const nextMonth = new Date(); + nextMonth.setMonth(nextMonth.getMonth() + 1); + await page.autocompleteSearch(selectors.createTicketView.client, 'Tony Stark'); await page.autocompleteSearch(selectors.createTicketView.address, 'Tony Stark'); - await page.datePicker(selectors.createTicketView.deliveryDate, 1, null); + await page.pickDate(selectors.createTicketView.deliveryDate, nextMonth); await page.autocompleteSearch(selectors.createTicketView.warehouse, 'Warehouse One'); await page.autocompleteSearch(selectors.createTicketView.agency, 'Silla247'); await page.waitToClick(selectors.createTicketView.createButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should check the url is now the summary of the ticket', async() => { - let url = await page.expectURL('/summary'); - - expect(url).toBe(true); + await page.waitForState('ticket.card.summary'); }); }); diff --git a/e2e/paths/05-ticket/15_create_ticket_from_client.spec.js b/e2e/paths/05-ticket/15_create_ticket_from_client.spec.js index 28c11de3a..a68ce894e 100644 --- a/e2e/paths/05-ticket/15_create_ticket_from_client.spec.js +++ b/e2e/paths/05-ticket/15_create_ticket_from_client.spec.js @@ -19,9 +19,7 @@ describe('Ticket create from client path', () => { it('should click the create simple ticket on the descriptor menu', async() => { await page.waitToClick(selectors.clientDescriptor.moreMenu); await page.waitToClick(selectors.clientDescriptor.simpleTicketButton); - let url = await page.expectURL('clientFk=102'); - - expect(url).toBe(true); + await page.waitForState('ticket.create'); }); it('should check if the client details are the expected ones', async() => { @@ -31,7 +29,6 @@ describe('Ticket create from client path', () => { const address = await page .waitToGetProperty(selectors.createTicketView.address, 'value'); - expect(client).toContain('Petter Parker'); expect(address).toContain('20 Ingram Street'); }); diff --git a/e2e/paths/05-ticket/16_summary.spec.js b/e2e/paths/05-ticket/16_summary.spec.js index e7c6507d7..f6808651e 100644 --- a/e2e/paths/05-ticket/16_summary.spec.js +++ b/e2e/paths/05-ticket/16_summary.spec.js @@ -18,9 +18,7 @@ describe('Ticket Summary path', () => { it('should navigate to the target ticket summary section', async() => { await page.loginAndModule('employee', 'ticket'); await page.accessToSearchResult(ticketId); - let url = await page.expectURL('/summary'); - - expect(url).toBe(true); + await page.waitForState('ticket.card.summary'); }); it(`should display details from the ticket and it's client on the top of the header`, async() => { @@ -75,21 +73,19 @@ describe('Ticket Summary path', () => { it('should log in as production then navigate to the summary of the same ticket', async() => { await page.loginAndModule('production', 'ticket'); await page.accessToSearchResult(ticketId); - let url = await page.expectURL('/summary'); - - expect(url).toBe(true); + await page.waitForState('ticket.card.summary'); }); it('should click on the SET OK button', async() => { await page.waitToClick(selectors.ticketSummary.setOk); - let result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the ticket state was updated', async() => { await page.waitForSpinnerLoad(); - let result = await page.waitToGetProperty(selectors.ticketSummary.state, 'innerText'); + const result = await page.waitToGetProperty(selectors.ticketSummary.state, 'innerText'); expect(result).toContain('OK'); }); diff --git a/e2e/paths/05-ticket/17_log.spec.js b/e2e/paths/05-ticket/17_log.spec.js index 2008d022e..97e121460 100644 --- a/e2e/paths/05-ticket/17_log.spec.js +++ b/e2e/paths/05-ticket/17_log.spec.js @@ -19,9 +19,7 @@ describe('Ticket log path', () => { await page.loginAndModule('employee', 'ticket'); await page.accessToSearchResult(ticketId); await page.accessToSection('ticket.card.observation'); - let url = await page.expectURL('/observation'); - - expect(url).toBe(true); + await page.waitForState('ticket.card.observation'); }); it('should create a new note for the test', async() => { @@ -29,16 +27,13 @@ describe('Ticket log path', () => { await page.autocompleteSearch(selectors.ticketNotes.firstNoteType, 'observation one'); await page.write(selectors.ticketNotes.firstDescription, 'description'); await page.waitToClick(selectors.ticketNotes.submitNotesButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should navigate to the log section', async() => { await page.accessToSection('ticket.card.log'); - let url = await page.expectURL('/log'); - - expect(url).toBe(true); }); it('should set the viewport width to 1920 to see the table full width', async() => { diff --git a/e2e/paths/05-ticket/18_index_payout.spec.js b/e2e/paths/05-ticket/18_index_payout.spec.js new file mode 100644 index 000000000..b1dc06e51 --- /dev/null +++ b/e2e/paths/05-ticket/18_index_payout.spec.js @@ -0,0 +1,58 @@ +import selectors from '../../helpers/selectors.js'; +import getBrowser from '../../helpers/puppeteer'; + +describe('Ticket index payout path', () => { + let browser; + let page; + + beforeAll(async() => { + browser = await getBrowser(); + page = browser.page; + }); + + afterAll(async() => { + await browser.close(); + }); + + it('should navigate to the ticket index', async() => { + await page.loginAndModule('administrative', 'ticket'); + await page.waitForState('ticket.index'); + }); + + it('should check three tickets 2 of a clinet and 1 of another', async() => { + await page.keyboard.press('Enter'); + await page.waitToClick(selectors.ticketsIndex.secondTicketCheckbox); + await page.waitToClick(selectors.ticketsIndex.sixthTicketCheckbox); + await page.waitToClick(selectors.ticketsIndex.payoutButton); + const message = await page.waitForSnackbar(); + + expect(message.text).toBe('You cannot make a payment on account from multiple clients'); + }); + + it('should uncheck the sixth ticket result and check the third which is from the same client then open the payout form', async() => { + await page.waitToClick(selectors.ticketsIndex.sixthTicketCheckbox); + await page.waitToClick(selectors.ticketsIndex.thirdTicketCheckbox); + await page.waitToClick(selectors.ticketsIndex.payoutButton); + + await page.waitForSelector(selectors.ticketsIndex.payoutCompany); + }); + + it('should fill the company and bank to perform a payout', async() => { + await page.autocompleteSearch(selectors.ticketsIndex.payoutBank, 'cash'); + await page.waitToClick(selectors.ticketsIndex.submitPayout); + const message = await page.waitForSnackbar(); + + expect(message.type).toBe('success'); + }); + + it('should navigate to the client balance section and check a new balance line was entered', async() => { + await page.waitToClick(selectors.globalItems.homeButton); + await page.selectModule('client'); + await page.accessToSearchResult('101'); + await page.accessToSection('client.card.balance.index'); + await page.waitForSelector('vn-client-balance-index vn-tbody > vn-tr'); + let result = await page.countElement('vn-client-balance-index vn-tbody > vn-tr'); + + expect(result).toEqual(4); + }); +}); diff --git a/e2e/paths/06-claim/01_basic_data.spec.js b/e2e/paths/06-claim/01_basic_data.spec.js index 9718fb583..a255188e2 100644 --- a/e2e/paths/06-claim/01_basic_data.spec.js +++ b/e2e/paths/06-claim/01_basic_data.spec.js @@ -25,15 +25,13 @@ describe('Claim edit basic data path', () => { await page.clearTextarea(selectors.claimBasicData.observation); await page.write(selectors.claimBasicData.observation, 'edited observation'); await page.waitToClick(selectors.claimBasicData.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual(jasmine.arrayContaining(['Data saved!'])); + expect(message.type).toBe('success'); }); it(`should have been redirected to the next section of claims as the role is salesAssistant`, async() => { - let url = await page.expectURL('/detail'); - - expect(url).toBe(true); + await page.waitForState('claim.card.detail'); }); it('should confirm the claim state was edited', async() => { @@ -56,8 +54,8 @@ describe('Claim edit basic data path', () => { await page.clearTextarea(selectors.claimBasicData.observation); await page.write(selectors.claimBasicData.observation, 'Observation one'); await page.waitToClick(selectors.claimBasicData.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual(jasmine.arrayContaining(['Data saved!'])); + expect(message.type).toBe('success'); }); }); diff --git a/e2e/paths/06-claim/02_development.spec.js b/e2e/paths/06-claim/02_development.spec.js index 346f88581..8efae48d4 100644 --- a/e2e/paths/06-claim/02_development.spec.js +++ b/e2e/paths/06-claim/02_development.spec.js @@ -26,15 +26,13 @@ describe('Claim development', () => { await page.autocompleteSearch(selectors.claimDevelopment.secondClaimWorker, 'deliveryNick'); await page.autocompleteSearch(selectors.claimDevelopment.secondClaimRedelivery, 'Reparto'); await page.waitToClick(selectors.claimDevelopment.saveDevelopmentButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should redirect to the next section of claims as the role is salesAssistant`, async() => { - let url = await page.expectURL('/action'); - - expect(url).toBe(true); + await page.waitForState('claim.card.action'); }); it('should edit a development', async() => { @@ -45,9 +43,9 @@ describe('Claim development', () => { await page.autocompleteSearch(selectors.claimDevelopment.firstClaimWorker, 'adminAssistantNick'); await page.autocompleteSearch(selectors.claimDevelopment.firstClaimRedelivery, 'Cliente'); await page.waitToClick(selectors.claimDevelopment.saveDevelopmentButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the first development is the expected one', async() => { diff --git a/e2e/paths/06-claim/03_detail.spec.js b/e2e/paths/06-claim/03_detail.spec.js index cf758919e..9d1f6eee1 100644 --- a/e2e/paths/06-claim/03_detail.spec.js +++ b/e2e/paths/06-claim/03_detail.spec.js @@ -21,9 +21,9 @@ xdescribe('Claim detail', () => { it('should add the first claimable item from ticket to the claim', async() => { await page.waitToClick(selectors.claimDetail.addItemButton); await page.waitToClick(selectors.claimDetail.firstClaimableSaleFromTicket); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the claim contains now two items', async() => { @@ -36,9 +36,9 @@ xdescribe('Claim detail', () => { await page.clearInput(selectors.claimDetail.firstItemQuantityInput); // selector deleted, find new upon fixes await page.write(selectors.claimDetail.firstItemQuantityInput, '4'); // selector deleted, find new upon fixes await page.keyboard.press('Enter'); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the first item quantity, and the claimed total were correctly edited', async() => { @@ -56,7 +56,7 @@ xdescribe('Claim detail', () => { await page.loginAndModule('salesAssistant', 'claim'); await page.accessToSearchResult('1'); await page.accessToSection('claim.card.detail'); - let url = await page.expectURL('/detail'); + let url = await page.expectURL('/detail'); // replace with waitForState expect(url).toBe(true); }); @@ -65,9 +65,9 @@ xdescribe('Claim detail', () => { await page.waitToClick(selectors.claimDetail.secondItemDiscount); await page.write(selectors.claimDetail.discount, '100'); await page.keyboard.press('Enter'); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should check the mana is the expected one', async() => { @@ -79,9 +79,9 @@ xdescribe('Claim detail', () => { it('should delete the second item from the claim', async() => { await page.waitToClick(selectors.claimDetail.secondItemDeleteButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the claim contains now one item', async() => { @@ -93,13 +93,13 @@ xdescribe('Claim detail', () => { it('should add the deleted ticket from to the claim', async() => { await page.waitToClick(selectors.claimDetail.addItemButton); await page.waitToClick(selectors.claimDetail.firstClaimableSaleFromTicket); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should have been redirected to the next section in claims`, async() => { - let url = await page.expectURL('development'); + let url = await page.expectURL('development'); // replace with waitForState expect(url).toBe(true); }); diff --git a/e2e/paths/06-claim/04_claim_action.spec.js b/e2e/paths/06-claim/04_claim_action.spec.js index 1db3938d5..9897a3ef3 100644 --- a/e2e/paths/06-claim/04_claim_action.spec.js +++ b/e2e/paths/06-claim/04_claim_action.spec.js @@ -19,33 +19,36 @@ describe('Claim action path', () => { it('should import the claim', async() => { await page.waitToClick(selectors.claimAction.importClaimButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should import the second importable ticket', async() => { - await page.waitFor(3000); // the animation adding the header element for the claimed total obscures somehow other elements for about 2 seconds + // the animation adding the header element for the claimed total + // obscures somehow other elements for about 2 seconds + await page.waitFor(3000); + await page.waitToClick(selectors.claimAction.importTicketButton); await page.waitToClick(selectors.claimAction.secondImportableTicket); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should edit the second line destination field', async() => { await page.waitForContentLoaded(); await page.autocompleteSearch(selectors.claimAction.secondLineDestination, 'Bueno'); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should delete the first line', async() => { await page.waitToClick(selectors.claimAction.firstDeleteLine); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toContain('Data saved!'); + expect(message.type).toBe('success'); }); it('should refresh the view to check the remaining line is the expected one', async() => { @@ -57,17 +60,17 @@ describe('Claim action path', () => { it('should delete the current first line', async() => { await page.waitToClick(selectors.claimAction.firstDeleteLine); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should check the "is paid with mana" checkbox', async() => { page.waitFor(3000); // can't use waitForNavigation here and needs more time than a single second to get the section ready... await page.waitToClick(selectors.claimAction.isPaidWithManaCheckbox); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual(jasmine.arrayContaining(['Data saved!'])); + expect(message.type).toBe('success'); }); it('should confirm the "is paid with mana" checkbox is checked', async() => { diff --git a/e2e/paths/06-claim/05_summary.spec.js b/e2e/paths/06-claim/05_summary.spec.js index 9dab65954..c63e686cb 100644 --- a/e2e/paths/06-claim/05_summary.spec.js +++ b/e2e/paths/06-claim/05_summary.spec.js @@ -18,9 +18,7 @@ describe('claim Summary path', () => { it('should navigate to the target claim summary section', async() => { await page.loginAndModule('employee', 'claim'); await page.accessToSearchResult(claimId); - let url = await page.expectURL('/summary'); - - expect(url).toBe(true); + await page.waitForState('claim.card.summary'); }); it(`should display details from the claim and it's client on the top of the header`, async() => { diff --git a/e2e/paths/06-claim/06_descriptor.spec.js b/e2e/paths/06-claim/06_descriptor.spec.js index 104f63945..43d046d62 100644 --- a/e2e/paths/06-claim/06_descriptor.spec.js +++ b/e2e/paths/06-claim/06_descriptor.spec.js @@ -18,9 +18,7 @@ describe('claim Descriptor path', () => { it('should now navigate to the target claim summary section', async() => { await page.loginAndModule('employee', 'claim'); await page.accessToSearchResult(claimId); - let url = await page.expectURL('/summary'); - - expect(url).toBe(true); + await page.waitForState('claim.card.summary'); }); it(`should not be able to see the delete claim button of the descriptor more menu`, async() => { @@ -31,9 +29,7 @@ describe('claim Descriptor path', () => { it(`should log in as salesAssistant and navigate to the target claim`, async() => { await page.loginAndModule('salesAssistant', 'claim'); await page.accessToSearchResult(claimId); - let url = await page.expectURL('/summary'); - - expect(url).toBe(true); + await page.waitForState('claim.card.summary'); }); it(`should be able to see the delete claim button of the descriptor more menu`, async() => { @@ -44,23 +40,19 @@ describe('claim Descriptor path', () => { it(`should delete the claim`, async() => { await page.waitToClick(selectors.claimDescriptor.moreMenuDeleteClaim); await page.waitToClick(selectors.claimDescriptor.acceptDeleteClaim); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Claim deleted!'); + expect(message.text).toBe('Claim deleted!'); }); it(`should have been relocated to the claim index`, async() => { - let url = await page.expectURL('/claim/index'); - - expect(url).toBe(true); + await page.waitForState('claim.index'); }); it(`should search for the deleted claim to find no results`, async() => { - await page.write(selectors.claimsIndex.searchClaimInput, claimId); - await page.waitToClick(selectors.claimsIndex.searchButton); - await page.waitForNumberOfElements(selectors.claimsIndex.searchResult, 0); - const result = await page.countElement(selectors.claimsIndex.searchResult); + await page.doSearch(claimId); + const nResults = await page.countElement(selectors.claimsIndex.searchResult); - expect(result).toEqual(0); + expect(nResults).toEqual(0); }); }); diff --git a/e2e/paths/07-order/01_summary.spec.js b/e2e/paths/07-order/01_summary.spec.js index cba56bf70..f4bc44827 100644 --- a/e2e/paths/07-order/01_summary.spec.js +++ b/e2e/paths/07-order/01_summary.spec.js @@ -16,9 +16,7 @@ describe('Order summary path', () => { }); it('should reach the order summary section', async() => { - const url = await page.expectURL('#!/order/16/summary'); - - expect(url).toBe(true); + await page.waitForState('order.card.summary'); }); it('should check the summary contains the order id', async() => { diff --git a/e2e/paths/07-order/02_basic_data.spec.js b/e2e/paths/07-order/02_basic_data.spec.js index 768985628..38d6619e0 100644 --- a/e2e/paths/07-order/02_basic_data.spec.js +++ b/e2e/paths/07-order/02_basic_data.spec.js @@ -4,7 +4,6 @@ import getBrowser from '../../helpers/puppeteer'; describe('Order edit basic data path', () => { let browser; let page; - const today = new Date().getDate(); beforeAll(async() => { browser = await getBrowser(); @@ -24,9 +23,9 @@ describe('Order edit basic data path', () => { await page.autocompleteSearch(selectors.orderBasicData.client, 'Tony Stark'); await page.autocompleteSearch(selectors.orderBasicData.address, 'Tony Stark'); await page.waitToClick(selectors.orderBasicData.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual(`You can't make changes on the basic data of an confirmed order or with rows`); + expect(message.text).toBe(`You can't make changes on the basic data of an confirmed order or with rows`); }); }); @@ -40,17 +39,15 @@ describe('Order edit basic data path', () => { await page.accessToSearchResult(orderId); await page.accessToSection('order.card.basicData'); await page.waitForSelector(selectors.orderBasicData.observation, {visible: true}); - let url = await page.expectURL(`#!/order/${orderId}/basic-data`); - - expect(url).toBe(true); + await page.waitForState('order.card.basicData'); }); it('should not be able to change anything', async() => { await page.write(selectors.orderBasicData.observation, 'observation'); await page.waitToClick(selectors.orderBasicData.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual(`You can't make changes on the basic data of an confirmed order or with rows`); + expect(message.text).toBe(`You can't make changes on the basic data of an confirmed order or with rows`); }); }); @@ -60,26 +57,20 @@ describe('Order edit basic data path', () => { await page.waitToClick(selectors.orderBasicData.acceptButton); await page.waitForContentLoaded(); await page.waitToClick(selectors.ordersIndex.createOrderButton); - let url = await page.expectURL('#!/order/create'); - - expect(url).toBe(true); + await page.waitForState('order.create'); }); it('should now create a new one', async() => { await page.autocompleteSearch(selectors.createOrderView.client, 'Jessica Jones'); - await page.datePicker(selectors.createOrderView.landedDatePicker, 0, today); + await page.pickDate(selectors.createOrderView.landedDatePicker); await page.autocompleteSearch(selectors.createOrderView.agency, 'Other agency'); await page.waitToClick(selectors.createOrderView.createButton); - let url = await page.expectURL('/catalog'); - - expect(url).toBe(true); + await page.waitForState('order.card.catalog'); }); it('should navigate to the basic data section of the new order', async() => { await page.accessToSection('order.card.basicData'); - let url = await page.expectURL('/basic-data'); - - expect(url).toBe(true); + await page.waitForState('order.card.basicData'); }); it('should be able to modify all the properties', async() => { @@ -88,9 +79,9 @@ describe('Order edit basic data path', () => { await page.autocompleteSearch(selectors.orderBasicData.agency, 'Silla247'); await page.write(selectors.orderBasicData.observation, 'my observation'); await page.waitToClick(selectors.orderBasicData.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should now confirm the client have been edited', async() => { diff --git a/e2e/paths/07-order/03_lines.spec.js b/e2e/paths/07-order/03_lines.spec.js index 21fceac44..6f87b45f0 100644 --- a/e2e/paths/07-order/03_lines.spec.js +++ b/e2e/paths/07-order/03_lines.spec.js @@ -26,9 +26,9 @@ describe('Order lines', () => { it('should delete the first line in the order', async() => { await page.waitToClick(selectors.orderLine.firstLineDeleteButton); await page.waitToClick(selectors.orderLine.confirmButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the order subtotal has changed', async() => { @@ -41,10 +41,7 @@ describe('Order lines', () => { it('should confirm the whole order and redirect to ticket index filtered by clientFk', async() => { await page.waitToClick(selectors.orderLine.confirmOrder); - let hashPartOne = await page.expectURL('ticket/index'); - let hashPartTwo = await page.expectURL('clientFk'); - - expect(hashPartOne).toBe(true); - expect(hashPartTwo).toBe(true); + await page.expectURL('ticket/index'); + await page.expectURL('clientFk'); }); }); diff --git a/e2e/paths/07-order/04_catalog.spec.js b/e2e/paths/07-order/04_catalog.spec.js index ca6489779..34fdbbec0 100644 --- a/e2e/paths/07-order/04_catalog.spec.js +++ b/e2e/paths/07-order/04_catalog.spec.js @@ -17,21 +17,15 @@ describe('Order catalog', () => { it('should open the create new order form', async() => { await page.waitToClick(selectors.ordersIndex.createOrderButton); - let url = await page.expectURL('order/create'); - - expect(url).toBe(true); + await page.waitForState('order.create'); }); it('should create a new order', async() => { - let today = new Date().getDate(); - await page.autocompleteSearch(selectors.createOrderView.client, 'Tony Stark'); - await page.datePicker(selectors.createOrderView.landedDatePicker, 0, today); + await page.pickDate(selectors.createOrderView.landedDatePicker); await page.autocompleteSearch(selectors.createOrderView.agency, 'Other agency'); await page.waitToClick(selectors.createOrderView.createButton); - let url = await page.expectURL('/catalog'); - - expect(url).toBe(true); + await page.waitForState('order.card.catalog'); }); it('should add the realm and type filters and obtain results', async() => { @@ -75,8 +69,7 @@ describe('Order catalog', () => { }); it('should search for an item by id', async() => { - await page.write(selectors.orderCatalog.itemId, '2'); - await page.keyboard.press('Enter'); + await page.accessToSearchResult('2'); await page.waitForNumberOfElements('section.product', 1); const result = await page.countElement('section.product'); diff --git a/e2e/paths/08-route/01_summary.spec.js b/e2e/paths/08-route/01_summary.spec.js index c062b9b08..02cc71f2f 100644 --- a/e2e/paths/08-route/01_summary.spec.js +++ b/e2e/paths/08-route/01_summary.spec.js @@ -17,9 +17,7 @@ describe('Route summary path', () => { }); it('should reach the first route summary section', async() => { - let url = await page.expectURL('#!/route/1/summary'); - - expect(url).toBe(true); + await page.waitForState('route.card.summary'); }); it(`should display details from the route on the header`, async() => { diff --git a/e2e/paths/08-route/02_basic_data.spec.js b/e2e/paths/08-route/02_basic_data.spec.js index 91688b3ff..10edbcd8a 100644 --- a/e2e/paths/08-route/02_basic_data.spec.js +++ b/e2e/paths/08-route/02_basic_data.spec.js @@ -18,9 +18,12 @@ describe('Route basic Data path', () => { }); it('should edit the route basic data', async() => { + const nextMonth = new Date(); + nextMonth.setMonth(nextMonth.getMonth() + 1); + await page.autocompleteSearch(selectors.routeBasicData.worker, 'adminBossNick'); await page.autocompleteSearch(selectors.routeBasicData.vehicle, '1111-IMK'); - await page.datePicker(selectors.routeBasicData.createdDate, 1, null); + await page.pickDate(selectors.routeBasicData.createdDate, nextMonth); await page.clearInput(selectors.routeBasicData.kmStart); await page.write(selectors.routeBasicData.kmStart, '1'); await page.clearInput(selectors.routeBasicData.kmEnd); @@ -28,16 +31,15 @@ describe('Route basic Data path', () => { await page.type(`${selectors.routeBasicData.startedHour} input`, '0800'); await page.type(`${selectors.routeBasicData.finishedHour} input`, '1230'); await page.waitToClick(selectors.routeBasicData.saveButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the worker was edited', async() => { await page.reloadSection('route.card.basicData'); const worker = await page.waitToGetProperty(selectors.routeBasicData.worker, 'value'); - expect(worker).toEqual('adminBoss - adminBossNick'); }); diff --git a/e2e/paths/08-route/03_create.spec.js b/e2e/paths/08-route/03_create.spec.js index 11ffd500b..80c0071b6 100644 --- a/e2e/paths/08-route/03_create.spec.js +++ b/e2e/paths/08-route/03_create.spec.js @@ -17,19 +17,16 @@ describe('Route create path', () => { describe('as employee', () => { it('should click on the add new route button and open the creation form', async() => { - await page.waitForContentLoaded(); await page.waitToClick(selectors.routeIndex.addNewRouteButton); - let url = await page.expectURL('#!/route/create'); - - expect(url).toBe(true); + await page.waitForState('route.create'); }); it(`should attempt to create a new route but fail since employee has no access rights`, async() => { await page.write(selectors.createRouteView.description, 'faster faster!!'); await page.waitToClick(selectors.createRouteView.submitButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Access denied'); + expect(message.text).toBe('Access denied'); }); }); @@ -41,27 +38,23 @@ describe('Route create path', () => { it('should again click on the add new route button and open the creation form', async() => { await page.waitToClick(selectors.routeIndex.addNewRouteButton); - let url = await page.expectURL('#!/route/create'); - - expect(url).toBe(true); + await page.waitForState('route.create'); }); it(`should create a new route`, async() => { await page.autocompleteSearch(selectors.createRouteView.worker, 'teamManagerNick'); - await page.datePicker(selectors.createRouteView.createdDatePicker, 0, null); + await page.pickDate(selectors.createRouteView.createdDatePicker); await page.autocompleteSearch(selectors.createRouteView.vehicleAuto, '4444-IMK'); await page.autocompleteSearch(selectors.createRouteView.agency, 'Teleportation device'); await page.write(selectors.createRouteView.description, 'faster faster!!'); await page.waitToClick(selectors.createRouteView.submitButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it(`should confirm the redirection to the created route summary`, async() => { - let url = await page.expectURL('/summary'); - - expect(url).toBe(true); + await page.waitForState('route.card.summary'); }); }); }); diff --git a/e2e/paths/08-route/04_tickets.spec.js b/e2e/paths/08-route/04_tickets.spec.js index 53b8f56c8..938c98574 100644 --- a/e2e/paths/08-route/04_tickets.spec.js +++ b/e2e/paths/08-route/04_tickets.spec.js @@ -19,17 +19,15 @@ xdescribe('Route basic Data path', () => { }); it('should modify the first ticket priority', async() => { - const result = await nightmare; await page.write(selectors.routeTickets.firstTicketPriority, '2'); await page.keyboard.press('Enter'); - await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should confirm the buscamanButton is disabled', async() => { - const result = await nightmare; - await page.evaluate(selector => { + const result = await page.evaluate(selector => { return document.querySelector(selector); }, `${selectors.routeTickets.buscamanButton} :disabled`); @@ -37,9 +35,8 @@ xdescribe('Route basic Data path', () => { }); it('should check the first ticket checkbox and confirm the buscamanButton button is no longer disabled', async() => { - const result = await nightmare; await page.waitToClick(selectors.routeTickets.firstTicketCheckbox); - await page.evaluate(selector => { + const result = await page.evaluate(selector => { return document.querySelector(selector); }, `${selectors.routeTickets.buscamanButton} :disabled`); @@ -47,47 +44,41 @@ xdescribe('Route basic Data path', () => { }); it('should check the route volume on the descriptor', async() => { - const result = await nightmare; - await page.waitToGetProperty(selectors.routeDescriptor.volume, 'innerText'); + const result = await page.waitToGetProperty(selectors.routeDescriptor.volume, 'innerText'); expect(result).toEqual('1.1 / 18 m³'); }); it('should count how many tickets are in route', async() => { - const result = await nightmare; - await page.countElement('vn-route-tickets vn-textfield[ng-model="ticket.priority"]'); + const result = await page.countElement('vn-route-tickets vn-textfield[ng-model="ticket.priority"]'); expect(result).toEqual(11); }); it('should delete the first ticket in route', async() => { - const result = await nightmare; await page.waitToClick(selectors.routeTickets.firstTicketDeleteButton); await page.waitToClick(selectors.routeTickets.confirmButton); - await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Ticket removed from route'); + expect(message.text).toBe('Ticket removed from route'); }); it('should again delete the first ticket in route', async() => { - const result = await nightmare; await page.waitToClick(selectors.routeTickets.firstTicketDeleteButton); await page.waitToClick(selectors.routeTickets.confirmButton); - await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Ticket removed from route'); + expect(message.text).toBe('Ticket removed from route'); }); it('should now count how many tickets are in route to find one less', async() => { - const result = await nightmare; - await page.countElement('vn-route-tickets vn-textfield[ng-model="ticket.priority"]'); + const result = await page.countElement('vn-route-tickets vn-textfield[ng-model="ticket.priority"]'); expect(result).toEqual(9); }); it('should confirm the route volume on the descriptor has been updated by the changes made', async() => { - const result = await nightmare; - await page.waitToGetProperty(selectors.routeDescriptor.volume, 'innerText'); + const result = await page.waitToGetProperty(selectors.routeDescriptor.volume, 'innerText'); expect(result).toEqual('0.9 / 18 m³'); }); diff --git a/e2e/paths/09-invoice-out/01_summary.spec.js b/e2e/paths/09-invoice-out/01_summary.spec.js index 126c745d3..728f0130a 100644 --- a/e2e/paths/09-invoice-out/01_summary.spec.js +++ b/e2e/paths/09-invoice-out/01_summary.spec.js @@ -17,9 +17,7 @@ describe('InvoiceOut summary path', () => { }); it('should reach the summary section', async() => { - const result = await page.expectURL('/summary'); - - expect(result).toBe(true); + await page.waitForState('invoiceOut.card.summary'); }); it('should contain the company from which the invoice is emited', async() => { diff --git a/e2e/paths/09-invoice-out/02_descriptor.spec.js b/e2e/paths/09-invoice-out/02_descriptor.spec.js index e70c39ded..ade121a8b 100644 --- a/e2e/paths/09-invoice-out/02_descriptor.spec.js +++ b/e2e/paths/09-invoice-out/02_descriptor.spec.js @@ -20,10 +20,7 @@ describe('InvoiceOut descriptor path', () => { await page.waitToClick(selectors.ticketsIndex.openAdvancedSearchButton); await page.write(selectors.ticketsIndex.advancedSearchInvoiceOut, 'T2222222'); await page.waitToClick(selectors.ticketsIndex.advancedSearchButton); - await page.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1); - const result = await page.countElement(selectors.ticketsIndex.searchResult); - - expect(result).toEqual(1); + await page.waitForState('ticket.card.summary'); }); it('should navigate to the invoiceOut index', async() => { @@ -31,86 +28,58 @@ describe('InvoiceOut descriptor path', () => { await page.wait(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.invoiceOutButton); await page.wait(selectors.invoiceOutIndex.topbarSearch); - let url = await page.expectURL('#!/invoice-out/index'); - - expect(url).toBe(true); - }); - - it('should search for the target invoiceOut', async() => { - await page.write(selectors.invoiceOutIndex.topbarSearch, 'T2222222'); - await page.waitToClick(selectors.invoiceOutIndex.searchButton); - await page.waitForNumberOfElements(selectors.invoiceOutIndex.searchResult, 1); - const result = await page.countElement(selectors.invoiceOutIndex.searchResult); - - expect(result).toEqual(1); + await page.waitForState('invoiceOut.index'); }); it(`should click on the search result to access to the invoiceOut summary`, async() => { await page.accessToSearchResult('T2222222'); - let url = await page.expectURL('/summary'); - - expect(url).toBe(true); + await page.waitForState('invoiceOut.card.summary'); }); it('should delete the invoiceOut using the descriptor more menu', async() => { await page.waitToClick(selectors.invoiceOutDescriptor.moreMenu); await page.waitToClick(selectors.invoiceOutDescriptor.moreMenuDeleteInvoiceOut); await page.waitToClick(selectors.invoiceOutDescriptor.acceptDeleteButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('InvoiceOut deleted'); + expect(message.text).toBe('InvoiceOut deleted'); }); it('should have been relocated to the invoiceOut index', async() => { - let url = await page.expectURL('#!/invoice-out/index'); - - expect(url).toBe(true); + await page.waitForState('invoiceOut.index'); }); it(`should search for the deleted invouceOut to find no results`, async() => { - await page.write(selectors.invoiceOutIndex.topbarSearch, 'T2222222'); - await page.waitToClick(selectors.invoiceOutIndex.searchButton); - await page.waitForNumberOfElements(selectors.invoiceOutIndex.searchResult, 0); - const result = await page.countElement(selectors.invoiceOutIndex.searchResult); + await page.doSearch('T2222222'); + const nResults = await page.countElement(selectors.invoiceOutIndex.searchResult); - expect(result).toEqual(0); + expect(nResults).toEqual(0); }); it('should navigate to the ticket index', async() => { await page.waitToClick(selectors.globalItems.applicationsMenuButton); await page.wait(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.ticketsButton); - let url = await page.expectURL('#!/ticket/index'); - - expect(url).toBe(true); + await page.waitForState('ticket.index'); }); it('should search for tickets with an specific invoiceOut to find no results', async() => { - await page.waitFor(2000); - await page.waitToClick(selectors.ticketsIndex.openAdvancedSearchButton); - await page.write(selectors.ticketsIndex.advancedSearchInvoiceOut, 'T2222222'); - await page.waitToClick(selectors.ticketsIndex.advancedSearchButton); - await page.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 0); - const result = await page.countElement(selectors.ticketsIndex.searchResult); + await page.doSearch('T2222222'); + const nResults = await page.countElement(selectors.ticketsIndex.searchResult); - expect(result).toEqual(0); + expect(nResults).toEqual(0); }); it('should now navigate to the invoiceOut index', async() => { - await page.waitForContentLoaded(); await page.waitToClick(selectors.globalItems.applicationsMenuButton); await page.wait(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.invoiceOutButton); - let url = await page.expectURL('#!/invoice-out/index'); - - expect(url).toBe(true); + await page.waitForState('invoiceOut.index'); }); it(`should search and access to the invoiceOut summary`, async() => { await page.accessToSearchResult('T1111111'); - let url = await page.expectURL('/summary'); - - expect(url).toBe(true); + await page.waitForState('invoiceOut.card.summary'); }); it(`should check the invoiceOut is booked in the summary data`, async() => { @@ -124,9 +93,9 @@ describe('InvoiceOut descriptor path', () => { await page.waitToClick(selectors.invoiceOutDescriptor.moreMenu); await page.waitToClick(selectors.invoiceOutDescriptor.moreMenuBookInvoiceOut); await page.waitToClick(selectors.invoiceOutDescriptor.acceptBookingButton); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('InvoiceOut booked'); + expect(message.text).toBe('InvoiceOut booked'); }); it(`should check the invoiceOut booked in the summary data`, async() => { diff --git a/e2e/paths/10-travel/01_thermograph.spec.js b/e2e/paths/10-travel/01_thermograph.spec.js index efa2295a6..67a62381a 100644 --- a/e2e/paths/10-travel/01_thermograph.spec.js +++ b/e2e/paths/10-travel/01_thermograph.spec.js @@ -18,16 +18,12 @@ describe('Travel thermograph path', () => { }); it('should reach the thermograph section', async() => { - const result = await page.expectURL('/thermograph/index'); - - expect(result).toBe(true); + await page.waitForState('travel.card.thermograph.index'); }); it('should click the add thermograph floating button', async() => { await page.waitToClick(selectors.travelThermograph.add); - const result = await page.expectURL('/thermograph/create'); - - expect(result).toBe(true); + await page.waitForState('travel.card.thermograph.create'); }); it('should select the thermograph and then the file to upload', async() => { diff --git a/e2e/paths/10-travel/02_basic_data_and_log.spec.js b/e2e/paths/10-travel/02_basic_data_and_log.spec.js index a835df2a2..c631e7131 100644 --- a/e2e/paths/10-travel/02_basic_data_and_log.spec.js +++ b/e2e/paths/10-travel/02_basic_data_and_log.spec.js @@ -18,25 +18,26 @@ describe('Travel basic data path', () => { }); it('should reach the thermograph section', async() => { - const result = await page.expectURL('/basic-data'); - - expect(result).toBe(true); + await page.waitForState('travel.card.basicData'); }); it('should set a wrong delivery date then receive an error on submit', async() => { - await page.datePicker(selectors.travelBasicDada.deliveryDate, -1, null); - await page.waitToClick(selectors.travelBasicDada.save); - const result = await page.waitForLastSnackbar(); + const lastMonth = new Date(); + lastMonth.setMonth(lastMonth.getMonth() - 1); - expect(result).toEqual('Landing cannot be lesser than shipment'); + await page.pickDate(selectors.travelBasicDada.deliveryDate, lastMonth); + await page.waitToClick(selectors.travelBasicDada.save); + const message = await page.waitForSnackbar(); + + expect(message.text).toBe('Landing cannot be lesser than shipment'); }); it('should undo the changes', async() => { await page.waitToClick(selectors.travelBasicDada.undoChanges); await page.waitToClick(selectors.travelBasicDada.save); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('No changes to save'); + expect(message.text).toBe('No changes to save'); }); it('should now edit the whole form then save', async() => { @@ -49,9 +50,9 @@ describe('Travel basic data path', () => { await page.waitToClick(selectors.travelBasicDada.delivered); await page.waitToClick(selectors.travelBasicDada.received); await page.waitToClick(selectors.travelBasicDada.save); - const result = await page.waitForLastSnackbar(); + const message = await page.waitForSnackbar(); - expect(result).toEqual('Data saved!'); + expect(message.type).toBe('success'); }); it('should reload the section and check the reference was saved', async() => { @@ -89,9 +90,7 @@ describe('Travel basic data path', () => { it('should navigate to the travel logs', async() => { await page.accessToSection('travel.card.log'); - const result = await page.expectURL('/log'); - - expect(result).toBe(true); + await page.waitForState('travel.card.log'); }); it('should check the 1st log contains details from the changes made', async() => { diff --git a/e2e/paths/11-zone/01_basic-data.spec.js b/e2e/paths/11-zone/01_basic-data.spec.js index c63bb8321..f28be5194 100644 --- a/e2e/paths/11-zone/01_basic-data.spec.js +++ b/e2e/paths/11-zone/01_basic-data.spec.js @@ -18,9 +18,7 @@ describe('Zone basic data path', () => { }); it('should reach the basic data section', async() => { - let url = await page.expectURL('#!/zone/10/basic-data'); - - expect(url).toBe(true); + await page.waitForState('zone.card.basicData'); }); it('should edit de form and then save', async() => { @@ -31,7 +29,7 @@ describe('Zone basic data path', () => { await page.clearInput(selectors.zoneBasicData.travelingDays); await page.write(selectors.zoneBasicData.travelingDays, '1'); await page.clearInput(selectors.zoneBasicData.closing); - await page.type(selectors.zoneBasicData.closing, '2100'); + await page.pickTime(selectors.zoneBasicData.closing, '21:00'); await page.clearInput(selectors.zoneBasicData.price); await page.write(selectors.zoneBasicData.price, '999'); await page.clearInput(selectors.zoneBasicData.bonus); @@ -40,14 +38,13 @@ describe('Zone basic data path', () => { await page.write(selectors.zoneBasicData.inflation, '200'); await page.waitToClick(selectors.zoneBasicData.volumetric); await page.waitToClick(selectors.zoneBasicData.saveButton); - await page.waitForContentLoaded(); + const message = await page.waitForSnackbar(); + + expect(message.type).toBe('success'); }); it('should now reload the section', async() => { await page.reloadSection('zone.card.basicData'); - let url = await page.expectURL('#!/zone/10/basic-data'); - - expect(url).toBe(true); }); it('should confirm the name was updated', async() => { diff --git a/e2e/paths/12-entry/01_summary.spec.js b/e2e/paths/12-entry/01_summary.spec.js index 39b12b840..e57654f94 100644 --- a/e2e/paths/12-entry/01_summary.spec.js +++ b/e2e/paths/12-entry/01_summary.spec.js @@ -17,9 +17,7 @@ describe('Entry summary path', () => { }); it('should reach the second entry summary section', async() => { - let url = await page.expectURL('#!/entry/2/summary'); - - expect(url).toBe(true); + await page.waitForState('entry.card.summary'); }); it(`should display details from the entry on the header`, async() => { diff --git a/e2e/paths/12-entry/02_descriptor.spec.js b/e2e/paths/12-entry/02_descriptor.spec.js index 8fa0d2a4f..699d00517 100644 --- a/e2e/paths/12-entry/02_descriptor.spec.js +++ b/e2e/paths/12-entry/02_descriptor.spec.js @@ -17,9 +17,7 @@ describe('Entry descriptor path', () => { }); it('should reach the second entry summary section', async() => { - let url = await page.expectURL('#!/entry/2/summary'); - - expect(url).toBe(true); + await page.waitForState('entry.card.summary'); }); it('should show some entry information', async() => { @@ -30,32 +28,22 @@ describe('Entry descriptor path', () => { it('should click the travels button to be redirected to the travels index filtered by the current agency', async() => { await page.waitToClick(selectors.entryDescriptor.travelsQuicklink); - const url = await page.expectURL('/travel/index'); - const filter = await page.expectURL('agencyFk'); - - expect(url).toBe(true); - expect(filter).toBe(true); + await page.expectURL('/travel/index'); + await page.expectURL('agencyFk'); }); it('should go back to the entry summary', async() => { await page.waitToClick(selectors.globalItems.homeButton); await page.selectModule('entry'); await page.accessToSearchResult('2'); - let url = await page.expectURL('#!/entry/2/summary'); - - expect(url).toBe(true); + await page.waitForState('entry.card.summary'); }); it('should click the entries button to be redirected to the entries index filtered by the current supplier', async() => { await page.waitToClick(selectors.entryDescriptor.entriesQuicklink); - const url = await page.expectURL('/entry/index'); - const supplierFilter = await page.expectURL('supplierFk'); - const toFilter = await page.expectURL('to'); - const fromFilter = await page.expectURL('from'); - - expect(url).toBe(true); - expect(supplierFilter).toBe(true); - expect(toFilter).toBe(true); - expect(fromFilter).toBe(true); + await page.expectURL('/entry/index'); + await page.expectURL('supplierFk'); + await page.expectURL('to'); + await page.expectURL('from'); }); }); diff --git a/front/core/components/autocomplete/index.html b/front/core/components/autocomplete/index.html index 725d38977..feaa47bdb 100755 --- a/front/core/components/autocomplete/index.html +++ b/front/core/components/autocomplete/index.html @@ -1,5 +1,6 @@