diff --git a/Jenkinsfile b/Jenkinsfile index e5f668581a..d87695cc42 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -65,7 +65,7 @@ pipeline { stage('Frontend') { steps { nodejs('node-lts') { - sh 'jest --ci --reporters=default --reporters=jest-junit --maxWorkers=1' + sh 'jest --ci --reporters=default --reporters=jest-junit --maxWorkers=2' } } } diff --git a/back/model-config.json b/back/model-config.json index f0032edab6..adb67eaed4 100644 --- a/back/model-config.json +++ b/back/model-config.json @@ -20,6 +20,9 @@ "Container": { "dataSource": "storage" }, + "Continent": { + "dataSource": "vn" + }, "Collection": { "dataSource": "vn" }, diff --git a/back/models/continent.json b/back/models/continent.json new file mode 100644 index 0000000000..090bada09a --- /dev/null +++ b/back/models/continent.json @@ -0,0 +1,27 @@ +{ + "name": "Continent", + "base": "VnModel", + "options": { + "mysql": { + "table": "continent" + } + }, + "properties": { + "id": { + "type": "number" + }, + "name": { + "type": "string" + }, + "code": { + "id": true, + "type": "string" + } + }, + "acls": [{ + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + }] +} \ No newline at end of file diff --git a/db/changes/10250-curfew/03-continent.sql b/db/changes/10250-curfew/03-continent.sql new file mode 100644 index 0000000000..279a736691 --- /dev/null +++ b/db/changes/10250-curfew/03-continent.sql @@ -0,0 +1,20 @@ +CREATE TABLE `vn`.continent +( + id TINYINT(4) AUTO_INCREMENT, + name VARCHAR(50) NOT NULL, + code VARCHAR(2) NOT NULL COLLATE utf8_general_ci, + CONSTRAINT continent_pk + PRIMARY KEY (id) +) + COMMENT 'World continents'; + +CREATE UNIQUE INDEX continent_name_uindex + ON `vn`.continent (name); + +INSERT IGNORE INTO `vn`.continent (`name`, `code`) + VALUES + ('Asia', 'AS'), + ('América', 'AM'), + ('África', 'AF'), + ('Europa', 'EU'), + ('Oceanía', 'OC'); \ No newline at end of file diff --git a/db/changes/10250-curfew/04-country.sql b/db/changes/10250-curfew/04-country.sql new file mode 100644 index 0000000000..e7ffbc67ff --- /dev/null +++ b/db/changes/10250-curfew/04-country.sql @@ -0,0 +1,13 @@ +ALTER TABLE `vn`.`country` + ADD COLUMN `continentFk` TINYINT(4) NULL AFTER `ibanLength`, + ADD INDEX `continent_id_fk_idx` (`continentFk` ASC); + +ALTER TABLE `vn`.`country` +ADD CONSTRAINT `continent_id_fk` + FOREIGN KEY (`continentFk`) + REFERENCES `vn`.`continent` (`id`) + ON DELETE NO ACTION + ON UPDATE CASCADE; + +UPDATE `vn`.`country` SET `continentFk` = '2' WHERE (`id` = '11'); +UPDATE `vn`.`country` SET `continentFk` = '2' WHERE (`id` = '13'); diff --git a/db/config.ini b/db/config.ini index 7800cadfd4..2caf3c2b93 100644 --- a/db/config.ini +++ b/db/config.ini @@ -3,3 +3,4 @@ host = localhost port = 3306 user = root password = root +default-character-set=utf8 diff --git a/db/dump/fixtures.sql b/db/dump/fixtures.sql index ad8474e38e..bf3b4f92f0 100644 --- a/db/dump/fixtures.sql +++ b/db/dump/fixtures.sql @@ -92,17 +92,17 @@ INSERT INTO `vn`.`worker`(`id`, `code`, `firstName`, `lastName`, `userFk`,`bossF (109, 'HLK', 'Bruce' , 'Banner', 109, 19, 432978109), (110, 'JJJ', 'Jessica' , 'Jones' , 110, 19, 432978110); -INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`, `ibanLength`) +INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`, `ibanLength`, `continentFk`) VALUES - (1, 'España', 1, 'ES', 1, 24), - (2, 'Italia', 1, 'IT', 1, 27), - (3, 'Alemania', 1, 'DE', 1, 22), - (4, 'Rumania', 1, 'RO', 1, 24), - (5, 'Holanda', 1, 'NL', 1, 18), - (8, 'Portugal', 1, 'PT', 1, 27), - (13,'Ecuador', 0, 'EC', 1, 24), - (19,'Francia', 1, 'FR', 1, 27), - (30,'Canarias', 1, 'IC', 1, 24); + (1, 'España', 1, 'ES', 1, 24, 4), + (2, 'Italia', 1, 'IT', 1, 27, 4), + (3, 'Alemania', 1, 'DE', 1, 22, 4), + (4, 'Rumania', 1, 'RO', 1, 24, 4), + (5, 'Holanda', 1, 'NL', 1, 18, 4), + (8, 'Portugal', 1, 'PT', 1, 27, 4), + (13,'Ecuador', 0, 'EC', 1, 24, 2), + (19,'Francia', 1, 'FR', 1, 27, 4), + (30,'Canarias', 1, 'IC', 1, 24, 4); INSERT INTO `hedera`.`language` (`code`, `name`, `orgName`, `isActive`) VALUES @@ -118,13 +118,13 @@ INSERT INTO `vn`.`warehouseAlias`(`id`, `name`) (1, 'Main Warehouse'), (2, 'Silla'); -INSERT INTO `vn`.`warehouse`(`id`, `name`, `isComparative`, `isInventory`, `hasAvailable`, `isManaged`, `hasStowaway`, `hasDms`, `hasComission`, `aliasFk`) +INSERT INTO `vn`.`warehouse`(`id`, `name`, `isComparative`, `isInventory`, `hasAvailable`, `isManaged`, `hasStowaway`, `hasDms`, `hasComission`, `aliasFk`, `countryFk`) VALUES - (1, 'Warehouse One', 1, 1, 1, 1, 1, 1, 1, 2), - (2, 'Warehouse Two', 1, 1, 1, 1, 0, 0, 1, 2), - (3, 'Warehouse Three', 1, 1, 1, 1, 0, 0, 0, 2), - (4, 'Warehouse Four', 1, 1, 1, 1, 0, 0, 0, 2), - (5, 'Warehouse Five', 1, 1, 1, 1, 0, 0, 0, 2); + (1, 'Warehouse One', 1, 1, 1, 1, 1, 1, 1, 2, 1), + (2, 'Warehouse Two', 1, 1, 1, 1, 0, 0, 1, 2, 13), + (3, 'Warehouse Three', 1, 1, 1, 1, 0, 0, 0, 2, 1), + (4, 'Warehouse Four', 1, 1, 1, 1, 0, 0, 0, 2, 1), + (5, 'Warehouse Five', 1, 1, 1, 1, 0, 0, 0, 2, 1); INSERT INTO `vn`.`sector`(`id`, `description`, `warehouseFk`, `isPreviousPreparedByPacking`, `code`, `pickingPlacement`, `path`) VALUES @@ -1250,11 +1250,11 @@ INSERT INTO `vn`.`travel`(`id`,`shipped`, `landed`, `warehouseInFk`, `warehouseO (1, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 1, 2, 1, 100.00, 1000, 'first travel', 1, 1), (2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 150, 2000, 'second travel', 2, 2), (3, CURDATE(), CURDATE(), 1, 2, 1, 0.00, 0.00, 'third travel', 1, 1), - (4, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 50.00, 500, 'fourth travel', 0, 2), - (5, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 3, 2, 1, 50.00, 500, 'fifth travel', 1, 1), - (6, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 2, 1, 50.00, 500, 'sixth travel', 1, 2), - (7, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 2, 1, 50.00, 500, 'seventh travel', 2, 1), - (8, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 2, 1, 50.00, 500, 'eight travel', 1, 2); + (4, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 3, 1, 50.00, 500, 'fourth travel', 0, 2), + (5, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 3, 3, 1, 50.00, 500, 'fifth travel', 1, 1), + (6, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 4, 1, 50.00, 500, 'sixth travel', 1, 2), + (7, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 4, 1, 50.00, 500, 'seventh travel', 2, 1), + (8, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 1, 1, 50.00, 500, 'eight travel', 1, 2); INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `isConfirmed`, `companyFk`, `ref`,`isInventory`, `isRaid`, `notes`, `evaNotes`) VALUES diff --git a/e2e/helpers/extensions.js b/e2e/helpers/extensions.js index 2a73bc7f3f..b38b3f7184 100644 --- a/e2e/helpers/extensions.js +++ b/e2e/helpers/extensions.js @@ -155,7 +155,7 @@ let actions = { document.querySelector(selector).scrollIntoViewIfNeeded(); }, selector); await this.waitToClick(selector); - await this.wait('vn-left-menu .expanded'); + await this.waitForSelector('vn-left-menu .expanded'); } await this.evaluate(state => { @@ -175,7 +175,7 @@ let actions = { forceReloadSection: async function(sectionRoute) { await this.waitToClick('vn-icon[icon="preview"]'); await this.waitToClick('button[response="accept"]'); - await this.wait('vn-card.summary'); + await this.waitForSelector('vn-card.summary'); await this.waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`); }, @@ -190,7 +190,7 @@ let actions = { accessToSearchResult: async function(searchValue) { await this.doSearch(searchValue); - await this.waitFor('.vn-descriptor'); + await this.waitForSelector('.vn-descriptor'); }, getProperty: async function(selector, property) { @@ -267,12 +267,13 @@ let actions = { writeOnEditableTD: async function(selector, text) { let builtSelector = await this.selectorFormater(selector); await this.waitToClick(selector); + await this.waitForSelector(builtSelector, {visible: true}); await this.type(builtSelector, text); await this.keyboard.press('Enter'); }, focusElement: async function(selector) { - await this.wait(selector); + await this.waitForSelector(selector); return await this.evaluate(selector => { let element = document.querySelector(selector); element.focus(); @@ -285,8 +286,8 @@ let actions = { }, waitImgLoad: async function(selector) { - await this.wait(selector); - return await this.wait(selector => { + await this.waitForSelector(selector); + return await this.waitForFunction(selector => { const imageReady = document.querySelector(selector).complete; return imageReady; }, {}, selector); @@ -305,16 +306,16 @@ let actions = { }, waitForClassNotPresent: async function(selector, className) { - await this.wait(selector); - return await this.wait((selector, className) => { + await this.waitForSelector(selector); + return await this.waitForFunction((selector, className) => { if (!document.querySelector(selector).classList.contains(className)) return true; }, {}, selector, className); }, waitForClassPresent: async function(selector, className) { - await this.wait(selector); - return await this.wait((elementSelector, targetClass) => { + await this.waitForSelector(selector); + return await this.waitForFunction((elementSelector, targetClass) => { if (document.querySelector(elementSelector).classList.contains(targetClass)) return true; }, {}, selector, className); @@ -387,7 +388,7 @@ let actions = { }, waitForEmptyInnerText: async function(selector) { - return await this.wait(selector => { + return await this.waitFunction(selector => { return document.querySelector(selector).innerText == ''; }, selector); }, @@ -395,7 +396,7 @@ let actions = { hideSnackbar: async function() { // 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.waitForTimeout(300); await this.evaluate(() => { let hideButton = document @@ -403,7 +404,7 @@ let actions = { if (hideButton) return hideButton.click(); }); - await this.waitFor('vn-snackbar .shape.shown', {hidden: true}); + await this.waitForSelector('vn-snackbar .shape.shown', {hidden: true}); }, waitForSnackbar: async function() { @@ -438,7 +439,7 @@ let actions = { const localDate = (new Date(date.getTime() - timeZoneOffset)) .toISOString().substr(0, 10); - await this.wait(selector); + await this.waitForSelector(selector); await this.evaluate((selector, localDate) => { let input = document.querySelector(selector).$ctrl.input; input.value = localDate; @@ -447,7 +448,7 @@ let actions = { }, pickTime: async function(selector, time) { - await this.wait(selector); + await this.waitForSelector(selector); await this.evaluate((selector, time) => { let input = document.querySelector(selector).$ctrl.input; input.value = time; @@ -510,11 +511,11 @@ let actions = { .includes(searchValue.toLowerCase()); }, {}, builtSelector, searchValue); - await this.waitFor('.vn-drop-down', {hidden: true}); + await this.waitForSelector('.vn-drop-down', {hidden: true}); }, checkboxState: async function(selector) { - await this.wait(selector); + await this.waitForSelector(selector); return await this.evaluate(selector => { let checkbox = document.querySelector(selector); switch (checkbox.$ctrl.field) { @@ -537,7 +538,7 @@ let actions = { }, waitForStylePresent: async function(selector, property, value) { - return await this.wait((selector, property, value) => { + return await this.waitForFunction((selector, property, value) => { const element = document.querySelector(selector); return element.style[property] == value; }, {}, selector, property, value); @@ -548,8 +549,8 @@ let actions = { }, waitForWatcherData: async function(selector) { - await this.wait(selector); - await this.wait(selector => { + await this.waitForSelector(selector); + await this.waitForFunction(selector => { let watcher = document.querySelector(selector); let orgData = watcher.$ctrl.orgData; return !angular.equals({}, orgData) && orgData != null; @@ -596,7 +597,7 @@ let actions = { closePopup: async function() { await Promise.all([ this.keyboard.press('Escape'), - this.waitFor('.vn-popup', {hidden: true}), + this.waitForSelector('.vn-popup', {hidden: true}), ]); }, diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 2471cf2001..eeaaf2702c 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -823,6 +823,10 @@ export default { anySearchResult: 'vn-travel-index vn-tbody > a', firstSearchResult: 'vn-travel-index vn-tbody > a:nth-child(1)' }, + travelExtraCommunity: { + firstTravelReference: 'vn-travel-extra-community > vn-data-viewer div > vn-tbody > vn-tr > vn-td-editable', + removeContinentFilter: 'vn-searchbar > form > vn-textfield > div.container > div.prepend > prepend > div > span:nth-child(3) > vn-icon > i' + }, travelBasicDada: { reference: 'vn-travel-basic-data vn-textfield[ng-model="$ctrl.travel.ref"]', agency: 'vn-travel-basic-data vn-autocomplete[ng-model="$ctrl.travel.agencyModeFk"]', diff --git a/e2e/paths/01-login/01_login.spec.js b/e2e/paths/01-login/01_login.spec.js index 35bebcff1d..7414856daa 100644 --- a/e2e/paths/01-login/01_login.spec.js +++ b/e2e/paths/01-login/01_login.spec.js @@ -45,7 +45,7 @@ describe('Login path', async() => { describe('Successful login', async() => { it('should log in and go to home state', async() => { await page.doLogin('employee'); - await page.waitFor('vn-home'); + await page.waitForSelector('vn-home'); const state = await page.getState(); expect(state).toBe('home'); @@ -58,7 +58,7 @@ describe('Login path', async() => { await page.waitToClick(selectors.globalItems.userMenuButton); await page.waitToClick(selectors.globalItems.logoutButton); - await page.waitFor('vn-login'); + await page.waitForSelector('vn-login'); const state = await page.getState(); 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 8bdc755563..9029910a7a 100644 --- a/e2e/paths/02-client/01_create_client.spec.js +++ b/e2e/paths/02-client/01_create_client.spec.js @@ -124,9 +124,9 @@ describe('Client create path', () => { it('should click on the Clients button of the top bar menu', async() => { await page.waitToClick(selectors.globalItems.applicationsMenuButton); - await page.wait(selectors.globalItems.applicationsMenuVisible); + await page.waitForSelector(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.clientsButton); - await page.wait(selectors.clientsIndex.createClientButton); + await page.waitForSelector(selectors.clientsIndex.createClientButton); await page.waitForState('client.index'); }); 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 8cb39520f3..6f331fb237 100644 --- a/e2e/paths/02-client/02_edit_basic_data.spec.js +++ b/e2e/paths/02-client/02_edit_basic_data.spec.js @@ -18,7 +18,7 @@ describe('Client Edit basicData path', () => { describe('as employee', () => { it('should not be able to change the salesPerson', async() => { - await page.wait(selectors.clientBasicData.name); + await page.waitForSelector(selectors.clientBasicData.name); const result = await page.evaluate(selector => { return document.querySelector(selector).disabled; }, `${selectors.clientBasicData.salesPerson} input`); 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 a7bf49eb6f..da04c813aa 100644 --- a/e2e/paths/02-client/03_edit_fiscal_data.spec.js +++ b/e2e/paths/02-client/03_edit_fiscal_data.spec.js @@ -40,7 +40,7 @@ describe('Client Edit fiscalData path', () => { }); it('should not be able to edit the verified data checkbox', async() => { - await page.wait(selectors.clientFiscalData.verifiedDataCheckbox); + await page.waitForSelector(selectors.clientFiscalData.verifiedDataCheckbox); const result = await page.isDisabled(selectors.clientFiscalData.verifiedDataCheckbox); expect(result).toBeTruthy(); @@ -55,7 +55,7 @@ describe('Client Edit fiscalData path', () => { }); it(`should edit the fiscal data but fail as the fiscal id ain't valid`, async() => { - await page.wait(selectors.clientFiscalData.socialName); + await page.waitForSelector(selectors.clientFiscalData.socialName); await page.clearInput(selectors.clientFiscalData.socialName); await page.write(selectors.clientFiscalData.socialName, 'SMASH'); await page.clearInput(selectors.clientFiscalData.fiscalId); @@ -159,7 +159,7 @@ describe('Client Edit fiscalData path', () => { }); it('should propagate the Equalization tax changes', async() => { - await page.waitFor(1000); + await page.waitForTimeout(1000); await page.waitToClick(selectors.globalItems.acceptButton); const message = await page.waitForSnackbar(); diff --git a/e2e/paths/02-client/05_add_address.spec.js b/e2e/paths/02-client/05_add_address.spec.js index f2a7050fe3..90cbc15a56 100644 --- a/e2e/paths/02-client/05_add_address.spec.js +++ b/e2e/paths/02-client/05_add_address.spec.js @@ -17,7 +17,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.waitFor(500); + await page.waitForTimeout(500); await page.waitToClick(selectors.clientAddresses.createAddress); await page.waitForState('client.card.address.create'); }); @@ -81,7 +81,7 @@ describe('Client Add address path', () => { }); it(`should confirm the new address exists and it's the default one`, async() => { - await page.waitFor(2000); // needs more than a single second to load the section + await page.waitForTimeout(2000); // needs more than a single second to load the section const result = await page.waitToGetProperty(selectors.clientAddresses.defaultAddress, 'innerText'); expect(result).toContain('320 Park Avenue New York'); diff --git a/e2e/paths/02-client/08_add_notes.spec.js b/e2e/paths/02-client/08_add_notes.spec.js index 82bc14d0b6..d0c483a114 100644 --- a/e2e/paths/02-client/08_add_notes.spec.js +++ b/e2e/paths/02-client/08_add_notes.spec.js @@ -26,7 +26,7 @@ describe('Client Add notes path', () => { }); it(`should create a note`, async() => { - await page.waitFor(selectors.clientNotes.note); + await page.waitForSelector(selectors.clientNotes.note); await page.type(`${selectors.clientNotes.note} textarea`, 'Meeting with Black Widow 21st 9am'); await page.waitToClick(selectors.clientNotes.saveButton); const message = await page.waitForSnackbar(); 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 817ba72384..701531c765 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 @@ -18,15 +18,15 @@ describe('Client lock verified data path', () => { describe('as salesPerson', () => { it('should confirm verified data button is disabled for salesPerson', async() => { - await page.wait(200); - await page.wait(selectors.clientFiscalData.verifiedDataCheckbox); + await page.waitForTimeout(200); + await page.waitForSelector(selectors.clientFiscalData.verifiedDataCheckbox); const result = await page.isDisabled(selectors.clientFiscalData.verifiedDataCheckbox); expect(result).toBeTruthy(); }); it('should edit the social name', async() => { - await page.wait(selectors.clientFiscalData.socialName); + await page.waitForSelector(selectors.clientFiscalData.socialName); await page.clearInput(selectors.clientFiscalData.socialName); await page.write(selectors.clientFiscalData.socialName, 'Captain America Civil War'); await page.waitToClick(selectors.clientFiscalData.saveButton); @@ -75,7 +75,7 @@ describe('Client lock verified data path', () => { }); it('should again edit the social name', async() => { - await page.wait(selectors.clientFiscalData.socialName); + await page.waitForSelector(selectors.clientFiscalData.socialName); await page.clearInput(selectors.clientFiscalData.socialName); await page.write(selectors.clientFiscalData.socialName, 'Ant man and the Wasp'); await page.waitToClick(selectors.clientFiscalData.saveButton); @@ -161,7 +161,7 @@ describe('Client lock verified data path', () => { }); it('should confirm the form is enabled for salesPerson', async() => { - await page.wait(selectors.clientFiscalData.socialName); + await page.waitForSelector(selectors.clientFiscalData.socialName); const result = await page.evaluate(selector => { return document.querySelector(selector).disabled; }, 'vn-textfield[ng-model="$ctrl.client.socialName"] > div'); diff --git a/e2e/paths/02-client/14_balance.spec.js b/e2e/paths/02-client/14_balance.spec.js index bd00af58ea..b069a4cfb8 100644 --- a/e2e/paths/02-client/14_balance.spec.js +++ b/e2e/paths/02-client/14_balance.spec.js @@ -113,9 +113,9 @@ describe('Client balance path', () => { it('should now click on the Clients button of the top bar menu', async() => { await page.login('employee'); await page.waitToClick(selectors.globalItems.applicationsMenuButton); - await page.wait(selectors.globalItems.applicationsMenuVisible); + await page.waitForSelector(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.clientsButton); - await page.wait(selectors.clientsIndex.createClientButton); + await page.waitForSelector(selectors.clientsIndex.createClientButton); await page.waitForState('client.index'); }); @@ -125,6 +125,6 @@ describe('Client balance path', () => { }); it('should not be able to click the new payment button as it isnt present', async() => { - await page.waitFor(selectors.clientBalance.newPaymentButton, {hidden: true}); + await page.waitForSelector(selectors.clientBalance.newPaymentButton, {hidden: true}); }); }); diff --git a/e2e/paths/02-client/15_user_config.spec.js b/e2e/paths/02-client/15_user_config.spec.js index 28f2ef29ee..0e18c07add 100644 --- a/e2e/paths/02-client/15_user_config.spec.js +++ b/e2e/paths/02-client/15_user_config.spec.js @@ -52,7 +52,7 @@ describe('User config', () => { it('should open the user config form to check the settings', async() => { await page.waitToClick(selectors.globalItems.userMenuButton); - await page.waitFor(1000); + await page.waitForTimeout(1000); let expectedLocalWarehouse = await page .expectPropertyValue(selectors.globalItems.userLocalWarehouse, 'value', ''); diff --git a/e2e/paths/02-client/16_web_payment.spec.js b/e2e/paths/02-client/16_web_payment.spec.js index 3a4f50e769..24d802e3ef 100644 --- a/e2e/paths/02-client/16_web_payment.spec.js +++ b/e2e/paths/02-client/16_web_payment.spec.js @@ -18,7 +18,7 @@ describe('Client web Payment', () => { describe('as employee', () => { it('should not be able to confirm payments', async() => { - await page.waitFor(selectors.webPayment.confirmFirstPaymentButton, {hidden: true}); + await page.waitForSelector(selectors.webPayment.confirmFirstPaymentButton, {hidden: true}); }); }); @@ -31,7 +31,7 @@ describe('Client web Payment', () => { it('should be able to confirm payments', async() => { await page.waitToClick(selectors.webPayment.confirmFirstPaymentButton); - await page.waitFor(selectors.webPayment.firstPaymentConfirmed, {hidden: true}); + await page.waitForSelector(selectors.webPayment.firstPaymentConfirmed, {hidden: true}); }); }); }); diff --git a/e2e/paths/02-client/18_contacts.spec.js b/e2e/paths/02-client/18_contacts.spec.js index c6dd4e4066..49d9304352 100644 --- a/e2e/paths/02-client/18_contacts.spec.js +++ b/e2e/paths/02-client/18_contacts.spec.js @@ -28,7 +28,7 @@ describe('Client contacts', () => { }); it('should delete de contact', async() => { - await page.waitFor(3000); + await page.waitForTimeout(3000); await page.waitToClick(selectors.clientContacts.deleteFirstPhone); await page.waitToClick(selectors.clientContacts.saveButton); const message = await page.waitForSnackbar(); diff --git a/e2e/paths/03-worker/05_calendar.spec.js b/e2e/paths/03-worker/05_calendar.spec.js index 7ebc3badb3..e82006b3c0 100644 --- a/e2e/paths/03-worker/05_calendar.spec.js +++ b/e2e/paths/03-worker/05_calendar.spec.js @@ -26,33 +26,33 @@ describe('Worker calendar path', () => { it('should set two days as holidays on the calendar and check the total holidays increased by 1.5', async() => { await page.waitToClick(selectors.workerCalendar.holidays); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.januaryThirtyFirst); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.absence); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.marchTwentyThird); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.halfHoliday); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.mayFourth); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.furlough); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.mayTwelfth); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.mayThirteenth); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.mayFourteenth); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.halfFurlough); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.mayEighth); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText'); @@ -68,33 +68,33 @@ describe('Worker calendar path', () => { }); it('should undo what was done here', async() => { - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.holidays); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.januaryThirtyFirst); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.absence); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.marchTwentyThird); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.halfHoliday); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.mayFourth); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.furlough); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.mayTwelfth); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.mayThirteenth); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.mayFourteenth); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.halfFurlough); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.mayEighth); }); @@ -113,9 +113,9 @@ describe('Worker calendar path', () => { }); it('should make a futile attempt to add holidays', async() => { - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.holidays); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); await page.waitToClick(selectors.workerCalendar.januaryThirtyFirst); }); @@ -131,7 +131,7 @@ describe('Worker calendar path', () => { await page.autocompleteSearch(selectors.workerCalendar.year, lastYear); - await page.waitFor(reasonableTimeBetweenClicks); + await page.waitForTimeout(reasonableTimeBetweenClicks); const result = await page.waitToGetProperty(selectors.workerCalendar.totalHolidaysUsed, 'innerText'); expect(result).toContain(' 0 '); diff --git a/e2e/paths/04-item/02_basic_data.spec.js b/e2e/paths/04-item/02_basic_data.spec.js index 6f664cf9b0..a728ac7174 100644 --- a/e2e/paths/04-item/02_basic_data.spec.js +++ b/e2e/paths/04-item/02_basic_data.spec.js @@ -46,7 +46,7 @@ describe('Item Edit basic data path', () => { await page.write(selectors.itemBasicData.newIntrastatId, '588420239'); await page.write(selectors.itemBasicData.newIntrastatDescription, 'Tropical Flowers'); await page.waitToClick(selectors.itemBasicData.acceptIntrastatButton); // this popover obscures the rest of the form for aprox 2 seconds - await page.waitFor(2000); + await page.waitForTimeout(2000); await page.waitForTextInField(selectors.itemBasicData.intrastat, 'Tropical Flowers'); let newcode = await page.waitToGetProperty(selectors.itemBasicData.intrastat, 'value'); diff --git a/e2e/paths/04-item/04_tags.spec.js b/e2e/paths/04-item/04_tags.spec.js index 39d49cd1ee..9f2a8e2952 100644 --- a/e2e/paths/04-item/04_tags.spec.js +++ b/e2e/paths/04-item/04_tags.spec.js @@ -31,7 +31,7 @@ describe('Item create tags path', () => { it(`should confirm the fourth row data is the expected one`, async() => { await page.reloadSection('item.card.tags'); - await page.wait('vn-item-tags'); + await page.waitForSelector('vn-item-tags'); let result = await page.waitToGetProperty(selectors.itemTags.fourthTag, 'value'); expect(result).toEqual('Ancho de la base'); 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 ac667d1238..938f15e3f9 100644 --- a/e2e/paths/04-item/08_create_and_clone.spec.js +++ b/e2e/paths/04-item/08_create_and_clone.spec.js @@ -77,7 +77,7 @@ describe('Item Create/Clone path', () => { xdescribe('clone', () => { 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); + await page.waitForSelector(selectors.itemsIndex.createItemButton); await page.waitForState('item.index'); }); diff --git a/e2e/paths/04-item/09_regularize.spec.js b/e2e/paths/04-item/09_regularize.spec.js index 0bc2c3acfe..97c45643f1 100644 --- a/e2e/paths/04-item/09_regularize.spec.js +++ b/e2e/paths/04-item/09_regularize.spec.js @@ -56,7 +56,7 @@ describe('Item regularize path', () => { it('should 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.waitForSelector(selectors.globalItems.applicationsMenuVisible); await Promise.all([ page.waitForNavigation({waitUntil: ['load', 'networkidle0', 'domcontentloaded']}), page.waitToClick(selectors.globalItems.ticketsButton) @@ -96,7 +96,7 @@ describe('Item regularize path', () => { it('should now click on the Items button of the top bar menu', async() => { await page.waitToClick(selectors.globalItems.applicationsMenuButton); - await page.wait(selectors.globalItems.applicationsMenuVisible); + await page.waitForSelector(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.itemsButton); await page.waitForState('item.index'); }); @@ -119,7 +119,7 @@ describe('Item regularize path', () => { 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.waitForSelector(selectors.globalItems.applicationsMenuVisible); await Promise.all([ page.waitForNavigation({waitUntil: ['load', 'networkidle0', 'domcontentloaded']}), page.waitToClick(selectors.globalItems.ticketsButton) diff --git a/e2e/paths/04-item/10_index.spec.js b/e2e/paths/04-item/10_index.spec.js index fb4efb5c87..40c567cacb 100644 --- a/e2e/paths/04-item/10_index.spec.js +++ b/e2e/paths/04-item/10_index.spec.js @@ -43,7 +43,7 @@ describe('Item index path', () => { await page.waitToClick(selectors.itemsIndex.firstSearchResult); await page.waitToClick(selectors.itemDescriptor.goBackToModuleIndexButton); await page.waitToClick(selectors.globalItems.searchButton); - await page.wait(selectors.itemsIndex.searchResult); + await page.waitForSelector(selectors.itemsIndex.searchResult); await page.waitImgLoad(selectors.itemsIndex.firstItemImage); const imageVisible = await page.isVisible(selectors.itemsIndex.firstItemImageTd); @@ -55,7 +55,7 @@ describe('Item index path', () => { }); it('should mark all unchecked boxes to leave the index as it was', async() => { - await page.waitFor(500); // otherwise the snackbar doesnt appear some times. + await page.waitForTimeout(500); // otherwise the snackbar doesnt appear some times. await page.waitToClick(selectors.itemsIndex.fieldsToShowButton); await page.waitToClick(selectors.itemsIndex.idCheckbox); await page.waitToClick(selectors.itemsIndex.stemsCheckbox); @@ -77,7 +77,7 @@ describe('Item index path', () => { await page.waitToClick(selectors.itemsIndex.firstSearchResult); await page.waitToClick(selectors.itemDescriptor.goBackToModuleIndexButton); await page.waitToClick(selectors.globalItems.searchButton); - await page.wait(selectors.itemsIndex.searchResult); + await page.waitForSelector(selectors.itemsIndex.searchResult); const idVisible = await page.isVisible(selectors.itemsIndex.firstItemId); expect(idVisible).toBeTruthy(); diff --git a/e2e/paths/04-item/11_item_log.spec.js b/e2e/paths/04-item/11_item_log.spec.js index c0a0470515..2a885fe6f6 100644 --- a/e2e/paths/04-item/11_item_log.spec.js +++ b/e2e/paths/04-item/11_item_log.spec.js @@ -39,7 +39,7 @@ describe('Item log 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); + await page.waitForSelector(selectors.itemsIndex.createItemButton); await page.waitForState('item.index'); }); @@ -49,7 +49,7 @@ describe('Item log path', () => { }); it(`should confirm the log is showing 5 entries`, async() => { - await page.wait(selectors.itemLog.anyLineCreated); + await page.waitForSelector(selectors.itemLog.anyLineCreated); const anyLineCreatedCount = await page.countElement(selectors.itemLog.anyLineCreated); expect(anyLineCreatedCount).toEqual(5); diff --git a/e2e/paths/04-item/12_descriptor.spec.js b/e2e/paths/04-item/12_descriptor.spec.js index 9e0de84797..7c6fa074c8 100644 --- a/e2e/paths/04-item/12_descriptor.spec.js +++ b/e2e/paths/04-item/12_descriptor.spec.js @@ -17,7 +17,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.waitForSelector(selectors.itemDescriptor.inactiveIcon); await page.waitForClassNotPresent(selectors.itemDescriptor.inactiveIcon, 'bright'); const darkIcon = await page.isVisible(selectors.itemDescriptor.inactiveIcon); 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 c3403b3710..248f38927a 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 @@ -24,7 +24,7 @@ describe('Ticket Edit sale path', () => { it('should navigate to the tickets index', async() => { await page.waitToClick(selectors.globalItems.applicationsMenuButton); - await page.wait(selectors.globalItems.applicationsMenuVisible); + await page.waitForSelector(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.ticketsButton); await page.waitForState('ticket.index'); }); @@ -128,7 +128,7 @@ describe('Ticket Edit sale path', () => { it('should return to ticket sales section', async() => { await page.waitToClick(selectors.globalItems.applicationsMenuButton); - await page.wait(selectors.globalItems.applicationsMenuVisible); + await page.waitForSelector(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.ticketsButton); await page.accessToSearchResult('16'); await page.accessToSection('ticket.card.sale'); @@ -143,9 +143,9 @@ describe('Ticket Edit sale path', () => { }); it('should remove 1 from the first sale quantity', async() => { - await page.waitFor(500); + await page.waitForTimeout(500); await page.waitToClick(selectors.ticketSales.firstSaleQuantityCell); - await page.waitFor(selectors.ticketSales.firstSaleQuantity); + await page.waitForSelector(selectors.ticketSales.firstSaleQuantity); await page.type(selectors.ticketSales.firstSaleQuantity, '9\u000d'); const message = await page.waitForSnackbar(); @@ -154,7 +154,7 @@ describe('Ticket Edit sale path', () => { it('should update the price', async() => { await page.waitToClick(selectors.ticketSales.firstSalePrice); - await page.waitFor(selectors.ticketSales.firstSalePriceInput); + await page.waitForSelector(selectors.ticketSales.firstSalePriceInput); await page.type(selectors.ticketSales.firstSalePriceInput, '5\u000d'); const message = await page.waitForSnackbar(); @@ -175,7 +175,7 @@ describe('Ticket Edit sale path', () => { it('should update the discount', async() => { await page.waitToClick(selectors.ticketSales.firstSaleDiscount); - await page.waitFor(selectors.ticketSales.firstSaleDiscountInput); + await page.waitForSelector(selectors.ticketSales.firstSaleDiscountInput); await page.type(selectors.ticketSales.firstSaleDiscountInput, '50\u000d'); const message = await page.waitForSnackbar(); @@ -205,7 +205,7 @@ describe('Ticket Edit sale path', () => { it('should click on the Claims button of the top bar menu', async() => { await page.waitToClick(selectors.globalItems.applicationsMenuButton); - await page.wait(selectors.globalItems.applicationsMenuVisible); + await page.waitForSelector(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.claimsButton); await page.waitForState('claim.index'); }); @@ -217,7 +217,7 @@ describe('Ticket Edit sale path', () => { it('should click the Tickets button of the top bar menu', async() => { await page.waitToClick(selectors.globalItems.applicationsMenuButton); - await page.wait(selectors.globalItems.applicationsMenuVisible); + await page.waitForSelector(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.ticketsButton); await page.waitForState('ticket.index'); }); @@ -225,16 +225,16 @@ describe('Ticket Edit sale path', () => { it('should search for a ticket then access to the sales section', async() => { await page.accessToSearchResult('16'); await page.accessToSection('ticket.card.sale'); - await page.wait(2000); + await page.waitForTimeout(2000); }); it('should select the third sale and delete it', async() => { await page.waitToClick(selectors.ticketSales.thirdSaleCheckbox); - await page.wait(2000); + await page.waitForTimeout(2000); await page.waitToClick(selectors.ticketSales.deleteSaleButton); - await page.wait(2000); + await page.waitForTimeout(2000); await page.waitToClick(selectors.globalItems.acceptButton); - await page.wait(2000); + await page.waitForTimeout(2000); await page.waitForSpinnerLoad(); const message = await page.waitForSnackbar(); @@ -260,7 +260,7 @@ describe('Ticket Edit sale path', () => { }); it('should confirm the transfered line is the correct one', async() => { - await page.wait(selectors.ticketSales.secondSaleText); + await page.waitForSelector(selectors.ticketSales.secondSaleText); const result = await page.waitToGetProperty(selectors.ticketSales.secondSaleText, 'innerText'); expect(result).toContain(`Melee weapon heavy shield`); @@ -279,7 +279,7 @@ describe('Ticket Edit sale path', () => { }); it(`should confirm the original ticket has still three lines`, async() => { - await page.wait(selectors.ticketSales.saleLine); + await page.waitForSelector(selectors.ticketSales.saleLine); const result = await page.countElement(selectors.ticketSales.saleLine); expect(result).toEqual(3); diff --git a/e2e/paths/05-ticket/05_tracking_state.spec.js b/e2e/paths/05-ticket/05_tracking_state.spec.js index 1db0144e5e..9c8e6d4922 100644 --- a/e2e/paths/05-ticket/05_tracking_state.spec.js +++ b/e2e/paths/05-ticket/05_tracking_state.spec.js @@ -48,13 +48,13 @@ 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.waitFor('.vn-popup', {hidden: true}); + await page.waitForSelector('.vn-popup', {hidden: true}); await page.waitToClick(selectors.ticketTracking.createStateButton); 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.waitForTimeout(1500); await page.autocompleteSearch(selectors.createStateView.state, 'Encajado'); await page.waitToClick(selectors.createStateView.saveStateButton); const message = await page.waitForSnackbar(); 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 f6660ae391..fff6c12646 100644 --- a/e2e/paths/05-ticket/06_basic_data_steps.spec.js +++ b/e2e/paths/05-ticket/06_basic_data_steps.spec.js @@ -34,7 +34,7 @@ describe('Ticket Edit basic data path', () => { it(`should confirm the zone autocomplete is enabled for the role productionBoss`, async() => { await page.waitForSpinnerLoad(); - await page.wait(selectors.ticketBasicData.zone); + await page.waitForSelector(selectors.ticketBasicData.zone); const disabled = await page.evaluate(selector => { return document.querySelector(selector).disabled; }, `${selectors.ticketBasicData.zone} input`); @@ -51,7 +51,7 @@ describe('Ticket Edit basic data path', () => { it(`should edit the ticket agency then check there are no zones for it`, async() => { await page.autocompleteSearch(selectors.ticketBasicData.agency, 'Super-Man delivery'); - await page.waitFor(1000); + await page.waitForTimeout(1000); let emptyZone = await page .expectPropertyValue(selectors.ticketBasicData.zone, 'value', ''); diff --git a/e2e/paths/05-ticket/09_weekly.spec.js b/e2e/paths/05-ticket/09_weekly.spec.js index e1d54e7a4c..2392de28ff 100644 --- a/e2e/paths/05-ticket/09_weekly.spec.js +++ b/e2e/paths/05-ticket/09_weekly.spec.js @@ -38,7 +38,7 @@ describe('Ticket descriptor path', () => { 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.waitForSelector(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.ticketsButton); await page.waitForState('ticket.index'); }); @@ -52,7 +52,7 @@ describe('Ticket descriptor path', () => { it('should click on the Tickets button of the top bar menu once more', async() => { await page.waitToClick(selectors.globalItems.applicationsMenuButton); - await page.wait(selectors.globalItems.applicationsMenuVisible); + await page.waitForSelector(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.ticketsButton); await page.waitForState('ticket.index'); }); @@ -73,7 +73,7 @@ describe('Ticket descriptor path', () => { 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.waitForSelector(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.ticketsButton); await page.waitForState('ticket.index'); }); diff --git a/e2e/paths/05-ticket/10_request.spec.js b/e2e/paths/05-ticket/10_request.spec.js index 8d9dc6aaae..af73d7081d 100644 --- a/e2e/paths/05-ticket/10_request.spec.js +++ b/e2e/paths/05-ticket/10_request.spec.js @@ -18,7 +18,7 @@ describe('Ticket purchase request path', () => { }); it('should add a new request', async() => { - await page.waitFor(500); + await page.waitForTimeout(500); await page.waitToClick(selectors.ticketRequests.addRequestButton); await page.write(selectors.ticketRequests.descriptionInput, 'New stuff'); await page.write(selectors.ticketRequests.quantity, '9'); @@ -72,7 +72,7 @@ describe('Ticket purchase request path', () => { it('should check the request was deleted', async() => { await page.reloadSection('ticket.card.request.index'); - await page.wait(selectors.ticketRequests.addRequestButton); + await page.waitForSelector(selectors.ticketRequests.addRequestButton); await page.waitForSelector(selectors.ticketRequests.thirdDescription, {hidden: true}); }); }); diff --git a/e2e/paths/05-ticket/12_descriptor.spec.js b/e2e/paths/05-ticket/12_descriptor.spec.js index c1258f9738..c426f7d7f3 100644 --- a/e2e/paths/05-ticket/12_descriptor.spec.js +++ b/e2e/paths/05-ticket/12_descriptor.spec.js @@ -92,7 +92,7 @@ describe('Ticket descriptor path', () => { }); await page.waitToClick(selectors.ticketDescriptor.moreMenu); await page.waitToClick(selectors.ticketDescriptor.moreMenuAddStowaway); - await page.wait(selectors.ticketDescriptor.addStowawayDialogFirstTicket); + await page.waitForSelector(selectors.ticketDescriptor.addStowawayDialogFirstTicket); const isVisible = await page.isVisible(selectors.ticketDescriptor.addStowawayDialogFirstTicket); expect(isVisible).toBeTruthy(); diff --git a/e2e/paths/05-ticket/13_services.spec.js b/e2e/paths/05-ticket/13_services.spec.js index 9108f64e40..03e57b5887 100644 --- a/e2e/paths/05-ticket/13_services.spec.js +++ b/e2e/paths/05-ticket/13_services.spec.js @@ -22,7 +22,7 @@ describe('Ticket services path', () => { it('should find the add descripton button disabled for this user role', async() => { await page.waitForClassPresent(selectors.ticketService.firstAddServiceTypeButton, 'disabled'); await page.waitToClick(selectors.ticketService.addServiceButton); - await page.wait(selectors.ticketService.firstAddServiceTypeButton); + await page.waitForSelector(selectors.ticketService.firstAddServiceTypeButton); const result = await page.isDisabled(selectors.ticketService.firstAddServiceTypeButton); expect(result).toBe(true); @@ -63,7 +63,7 @@ describe('Ticket services path', () => { it('should click on the add new service type to open the dialog', async() => { await page.waitToClick(selectors.ticketService.firstAddServiceTypeButton); - await page.wait('.vn-dialog.shown'); + await page.waitForSelector('.vn-dialog.shown'); const result = await page.isVisible(selectors.ticketService.newServiceTypeName); expect(result).toBeTruthy(); diff --git a/e2e/paths/05-ticket/14_create_ticket.spec.js b/e2e/paths/05-ticket/14_create_ticket.spec.js index 6923544729..4e7d954932 100644 --- a/e2e/paths/05-ticket/14_create_ticket.spec.js +++ b/e2e/paths/05-ticket/14_create_ticket.spec.js @@ -42,7 +42,7 @@ describe('Ticket create path', () => { it('should again open the new ticket form', async() => { await page.waitToClick(selectors.globalItems.returnToModuleIndexButton); - await page.waitFor(500); + await page.waitForTimeout(500); await page.waitToClick(selectors.ticketsIndex.newTicketButton); await page.waitForState('ticket.create'); }); diff --git a/e2e/paths/06-claim/01_basic_data.spec.js b/e2e/paths/06-claim/01_basic_data.spec.js index efbfd03055..5dfd54c4ee 100644 --- a/e2e/paths/06-claim/01_basic_data.spec.js +++ b/e2e/paths/06-claim/01_basic_data.spec.js @@ -45,7 +45,7 @@ describe('Claim edit basic data path', () => { it('should confirm the claim state was edited', async() => { await page.reloadSection('claim.card.basicData'); - await page.wait(selectors.claimBasicData.claimState); + await page.waitForSelector(selectors.claimBasicData.claimState); const result = await page.waitToGetProperty(selectors.claimBasicData.claimState, 'value'); expect(result).toEqual('Gestionado'); diff --git a/e2e/paths/06-claim/03_detail.spec.js b/e2e/paths/06-claim/03_detail.spec.js index 9649d19052..ddcfd9302d 100644 --- a/e2e/paths/06-claim/03_detail.spec.js +++ b/e2e/paths/06-claim/03_detail.spec.js @@ -106,7 +106,7 @@ xdescribe('Claim detail', () => { it('should navigate back to claim.detail to confirm the claim contains now two items', async() => { await page.accessToSection('claim.card.detail'); - await page.wait(selectors.claimDetail.claimDetailLine); + await page.waitForSelector(selectors.claimDetail.claimDetailLine); const result = await page.countElement(selectors.claimDetail.claimDetailLine); expect(result).toEqual(2); diff --git a/e2e/paths/06-claim/04_claim_action.spec.js b/e2e/paths/06-claim/04_claim_action.spec.js index c22fe57044..b3fedc9c8b 100644 --- a/e2e/paths/06-claim/04_claim_action.spec.js +++ b/e2e/paths/06-claim/04_claim_action.spec.js @@ -27,7 +27,7 @@ describe('Claim action path', () => { it('should import the second importable ticket', async() => { // the animation adding the header element for the claimed total // obscures somehow other elements for about 2 seconds - await page.waitFor(3000); + await page.waitForTimeout(3000); await page.waitToClick(selectors.claimAction.importTicketButton); await page.waitToClick(selectors.claimAction.secondImportableTicket); diff --git a/e2e/paths/07-order/01_summary.spec.js b/e2e/paths/07-order/01_summary.spec.js index f21015c52c..1b47768265 100644 --- a/e2e/paths/07-order/01_summary.spec.js +++ b/e2e/paths/07-order/01_summary.spec.js @@ -8,7 +8,7 @@ describe('Order summary path', () => { browser = await getBrowser(); page = browser.page; await page.loginAndModule('employee', 'order'); - await page.waitFor(2000); + await page.waitForTimeout(2000); await page.accessToSearchResult('16'); }); diff --git a/e2e/paths/08-route/03_create.spec.js b/e2e/paths/08-route/03_create.spec.js index ad6fb39913..670f7e17b9 100644 --- a/e2e/paths/08-route/03_create.spec.js +++ b/e2e/paths/08-route/03_create.spec.js @@ -17,7 +17,7 @@ describe('Route create path', () => { describe('as employee', () => { it('should click on the add new route button and open the creation form', async() => { - await page.waitFor(500); + await page.waitForTimeout(500); await page.waitToClick(selectors.routeIndex.addNewRouteButton); await page.waitForState('route.create'); }); diff --git a/e2e/paths/09-invoice-out/02_descriptor.spec.js b/e2e/paths/09-invoice-out/02_descriptor.spec.js index aff35ac33c..8d403e0839 100644 --- a/e2e/paths/09-invoice-out/02_descriptor.spec.js +++ b/e2e/paths/09-invoice-out/02_descriptor.spec.js @@ -26,9 +26,9 @@ describe('InvoiceOut descriptor path', () => { it('should navigate to the invoiceOut index', async() => { await page.waitToClick(selectors.globalItems.applicationsMenuButton); - await page.wait(selectors.globalItems.applicationsMenuVisible); + await page.waitForSelector(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.invoiceOutButton); - await page.wait(selectors.invoiceOutIndex.topbarSearch); + await page.waitForSelector(selectors.invoiceOutIndex.topbarSearch); await page.waitForState('invoiceOut.index'); }); @@ -59,7 +59,7 @@ describe('InvoiceOut descriptor path', () => { it('should navigate to the ticket index', async() => { await page.waitToClick(selectors.globalItems.applicationsMenuButton); - await page.wait(selectors.globalItems.applicationsMenuVisible); + await page.waitForSelector(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.ticketsButton); await page.waitForState('ticket.index'); }); @@ -73,7 +73,7 @@ describe('InvoiceOut descriptor path', () => { it('should now navigate to the invoiceOut index', async() => { await page.waitToClick(selectors.globalItems.applicationsMenuButton); - await page.wait(selectors.globalItems.applicationsMenuVisible); + await page.waitForSelector(selectors.globalItems.applicationsMenuVisible); await page.waitToClick(selectors.globalItems.invoiceOutButton); await page.waitForState('invoiceOut.index'); }); @@ -126,7 +126,7 @@ describe('InvoiceOut descriptor path', () => { it(`should check the salesPerson role doens't see the book option in the more menu`, async() => { await page.waitToClick(selectors.invoiceOutDescriptor.moreMenu); - await page.wait(selectors.invoiceOutDescriptor.moreMenuShowInvoiceOutPdf); + await page.waitForSelector(selectors.invoiceOutDescriptor.moreMenuShowInvoiceOutPdf); await page.waitForSelector(selectors.invoiceOutDescriptor.moreMenuBookInvoiceOut, {hidden: true}); }); 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 f1253cdd74..9c81e6f638 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 @@ -43,7 +43,7 @@ describe('Travel basic data path', () => { it('should now edit the whole form then save', async() => { await page.clearInput(selectors.travelBasicDada.reference); await page.write(selectors.travelBasicDada.reference, 'new reference!'); - await page.waitFor(2000); + await page.waitForTimeout(2000); await page.autocompleteSearch(selectors.travelBasicDada.agency, 'Entanglement'); await page.autocompleteSearch(selectors.travelBasicDada.outputWarehouse, 'Warehouse Three'); await page.autocompleteSearch(selectors.travelBasicDada.inputWarehouse, 'Warehouse Four'); diff --git a/e2e/paths/10-travel/04_extra_community.spec.js b/e2e/paths/10-travel/04_extra_community.spec.js new file mode 100644 index 0000000000..bc81c086c8 --- /dev/null +++ b/e2e/paths/10-travel/04_extra_community.spec.js @@ -0,0 +1,33 @@ +import selectors from '../../helpers/selectors.js'; +import getBrowser from '../../helpers/puppeteer'; + +describe('Travel extra community path', () => { + let browser; + let page; + + beforeAll(async() => { + browser = await getBrowser(); + page = browser.page; + await page.loginAndModule('buyer', 'travel'); + await page.accessToSection('travel.extraCommunity'); + }); + + afterAll(async() => { + await browser.close(); + }); + + it('should edit the travel reference', async() => { + await page.waitToClick(selectors.travelExtraCommunity.removeContinentFilter); + await page.writeOnEditableTD(selectors.travelExtraCommunity.firstTravelReference, 'edited reference'); + }); + + it('should reload the index and confirm the reference was edited', async() => { + await page.accessToSection('travel.index'); + await page.accessToSection('travel.extraCommunity'); + await page.waitToClick(selectors.travelExtraCommunity.removeContinentFilter); + await page.waitForTextInElement(selectors.travelExtraCommunity.firstTravelReference, 'edited reference'); + const reference = await page.getProperty(selectors.travelExtraCommunity.firstTravelReference, 'innerText'); + + expect(reference).toContain('edited reference'); + }); +}); diff --git a/e2e/paths/12-entry/03_latestBuys.spec.js b/e2e/paths/12-entry/03_latestBuys.spec.js index 33acdb3187..8e9de8158f 100644 --- a/e2e/paths/12-entry/03_latestBuys.spec.js +++ b/e2e/paths/12-entry/03_latestBuys.spec.js @@ -17,7 +17,7 @@ describe('Entry lastest buys path', () => { it('should access the latest buys seccion and search not seeing the edit buys button yet', async() => { await page.waitToClick(selectors.entryLatestBuys.latestBuysSectionButton); - await page.waitFor(250); + await page.waitForTimeout(250); await page.waitToClick(selectors.globalItems.searchButton); await page.waitForSelector(selectors.entryLatestBuys.editBuysButton, {visible: false}); }); diff --git a/front/core/components/table/style.scss b/front/core/components/table/style.scss index 7dd69d89f3..8d35c374c9 100644 --- a/front/core/components/table/style.scss +++ b/front/core/components/table/style.scss @@ -22,28 +22,7 @@ vn-table { & > * > vn-th[field] { position: relative; overflow: visible; - cursor: pointer; - - &.active > :after { - color: $color-font; - opacity: 1; - } - &.desc > :after { - content: 'arrow_drop_down'; - } - &.asc > :after { - content: 'arrow_drop_up'; - } - & > :after { - font-family: 'Material Icons'; - content: 'arrow_drop_down'; - position: absolute; - color: $color-spacer; - opacity: 0; - } - &:hover > :after { - opacity: 1; - } + cursor: pointer } } & > vn-tbody, diff --git a/front/core/components/th/index.js b/front/core/components/th/index.js index b8260bd748..f815056f6e 100644 --- a/front/core/components/th/index.js +++ b/front/core/components/th/index.js @@ -54,7 +54,6 @@ export default class Th { else this.table.setOrder(this.field, this.order); - this.updateArrow(); this.table.applyOrder(this.field, this.order); diff --git a/front/core/components/th/style.scss b/front/core/components/th/style.scss new file mode 100644 index 0000000000..4982f8f897 --- /dev/null +++ b/front/core/components/th/style.scss @@ -0,0 +1,33 @@ +@import "effects"; +@import "variables"; + +vn-th { + font-weight: normal; +} + +vn-th[field] { + &.active > :after { + color: $color-font; + opacity: 1; + } + &.desc > :after { + content: 'arrow_drop_down'; + } + &.asc > :after { + content: 'arrow_drop_up'; + } + + & > :after { + font-family: 'Material Icons'; + content: 'arrow_drop_down'; + position: absolute; + color: $color-spacer; + font-size: 1.5em; + margin-top: -2px; + opacity: 0 + + } + &:hover > :after { + opacity: 1; + } +} \ No newline at end of file diff --git a/front/salix/components/descriptor/index.html b/front/salix/components/descriptor/index.html index f888432ed3..c786ebb931 100644 --- a/front/salix/components/descriptor/index.html +++ b/front/salix/components/descriptor/index.html @@ -17,7 +17,7 @@ ui-sref="{{::$ctrl.summaryState}}({id: $ctrl.descriptor.id})"> - diff --git a/loopback/server/connectors/vn-mysql.js b/loopback/server/connectors/vn-mysql.js index 5c625be85b..4e1345cd69 100644 --- a/loopback/server/connectors/vn-mysql.js +++ b/loopback/server/connectors/vn-mysql.js @@ -84,6 +84,32 @@ class VnMySQL extends MySQL { return wrappedConnector.buildWhere(null, where); } + /** + * Constructs SQL GROUP BY clause from Loopback filter. + * + * @param {Object} group The group by definition + * @return {String} Built SQL group by + */ + makeGroupBy(group) { + if (!group) + return ''; + if (typeof group === 'string') + group = [group]; + + let clauses = []; + + for (let clause of group) { + let sqlGroup = ''; + let t = clause.split(/[\s,]+/); + + sqlGroup += this.escapeName(t[0]); + + clauses.push(sqlGroup); + } + + return `GROUP BY ${clauses.join(', ')}`; + } + /** * Constructs SQL order clause from Loopback filter. * diff --git a/modules/entry/back/models/buy.json b/modules/entry/back/models/buy.json index 56f1eef4f3..65bf15fa49 100644 --- a/modules/entry/back/models/buy.json +++ b/modules/entry/back/models/buy.json @@ -34,9 +34,6 @@ "stickers": { "type": "number" }, - "packageFk": { - "type": "number" - }, "groupingMode": { "type": "number" }, @@ -68,6 +65,11 @@ "model": "Item", "foreignKey": "itemFk", "required": true - } + }, + "package": { + "type": "belongsTo", + "model": "Packaging", + "foreignKey": "packageFk" + } } } \ No newline at end of file diff --git a/modules/item/back/methods/item/specs/getDiary.spec.js b/modules/item/back/methods/item/specs/getDiary.spec.js index cf9ed93204..2903fc426e 100644 --- a/modules/item/back/methods/item/specs/getDiary.spec.js +++ b/modules/item/back/methods/item/specs/getDiary.spec.js @@ -5,10 +5,8 @@ describe('item getBalance()', () => { let params = {where: {itemFk: 1, warehouseFk: 2}}; let result = await app.models.Item.getBalance(params); - expect(result.length).toBe(4); + expect(result.length).toBe(2); expect(result[0].balance).toBe(-100); - expect(result[1].balance).toBe(-110); - expect(result[2].balance).toBe(-110); - expect(result[3].balance).toBe(-210); + expect(result[1].balance).toBe(-200); }); }); diff --git a/modules/travel/back/methods/travel/extraCommunityFilter.js b/modules/travel/back/methods/travel/extraCommunityFilter.js new file mode 100644 index 0000000000..4a49b44015 --- /dev/null +++ b/modules/travel/back/methods/travel/extraCommunityFilter.js @@ -0,0 +1,213 @@ + +const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; +const buildFilter = require('vn-loopback/util/filter').buildFilter; +const mergeFilters = require('vn-loopback/util/filter').mergeFilters; + +module.exports = Self => { + Self.remoteMethodCtx('extraCommunityFilter', { + description: 'Find all instances of the model matched by filter from the data source.', + accessType: 'READ', + accepts: [ + { + arg: 'filter', + type: 'Object', + description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string', + http: {source: 'query'} + }, { + arg: 'search', + type: 'String', + description: 'Searchs the travel by id', + http: {source: 'query'} + }, { + arg: 'id', + type: 'Integer', + description: 'The travel id', + http: {source: 'query'} + }, { + arg: 'shippedFrom', + type: 'Date', + description: 'The shipped from date filter', + http: {source: 'query'} + }, { + arg: 'shippedTo', + type: 'Date', + description: 'The shipped to date filter', + http: {source: 'query'} + }, { + arg: 'landedFrom', + type: 'Date', + description: 'The landed from date filter', + http: {source: 'query'} + }, { + arg: 'landedTo', + type: 'Date', + description: 'The landed to date filter', + http: {source: 'query'} + }, { + arg: 'agencyFk', + type: 'Number', + description: 'The agencyModeFk id', + http: {source: 'query'} + }, { + arg: 'warehouseOutFk', + type: 'Number', + description: 'The warehouseOutFk filter', + http: {source: 'query'} + }, { + arg: 'warehouseInFk', + type: 'Number', + description: 'The warehouseInFk filter', + http: {source: 'query'} + }, { + arg: 'totalEntries', + type: 'Number', + description: 'The totalEntries filter', + http: {source: 'query'} + }, { + arg: 'ref', + type: 'string', + description: 'The reference' + }, { + arg: 'continent', + type: 'string', + description: 'The continent code' + } + ], + returns: { + type: ['Object'], + root: true + }, + http: { + path: `/extraCommunityFilter`, + verb: 'GET' + } + }); + + Self.extraCommunityFilter = async(ctx, filter) => { + let conn = Self.dataSource.connector; + let where = buildFilter(ctx.args, (param, value) => { + switch (param) { + case 'search': + return /^\d+$/.test(value) + ? {'t.id': value} + : {'t.ref': {like: `%${value}%`}}; + case 'ref': + return {'t.ref': {like: `%${value}%`}}; + case 'shippedFrom': + return {'t.shipped': {gte: value}}; + case 'shippedTo': + return {'t.shipped': {lte: value}}; + case 'landedFrom': + return {'t.landed': {gte: value}}; + case 'landedTo': + return {'t.landed': {lte: value}}; + case 'continent': + return {'cnt.code': value}; + case 'id': + case 'agencyFk': + case 'warehouseOutFk': + case 'warehouseInFk': + case 'totalEntries': + param = `t.${param}`; + return {[param]: value}; + } + }); + + filter = mergeFilters(filter, {where}); + + let stmts = []; + let stmt; + stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.travel'); + stmt = new ParameterizedSQL( + `CREATE TEMPORARY TABLE tmp.travel + (INDEX (id)) + ENGINE = MEMORY + SELECT + t.id, + t.ref, + t.shipped, + t.landed, + t.kg, + am.id AS agencyModeFk, + am.name AS agencyModeName, + wo.id AS warehouseOutFk, + wo.name AS warehouseOutName, + w.name AS warehouseInFk, + w.name AS warehouseInName, + SUM(b.stickers) AS stickers, + s.id AS supplierFk, + s.nickname AS cargoSupplierNickname, + CAST(SUM(i.density * b.stickers * IF(pkg.volume, pkg.volume, pkg.width * pkg.depth * pkg.height) / 1000000 ) as DECIMAL(10,0)) as loadedKg, + CAST(SUM(167.5 * b.stickers * IF(pkg.volume, pkg.volume, pkg.width * pkg.depth * pkg.height) / 1000000 ) as DECIMAL(10,0)) as volumeKg + FROM travel t + LEFT JOIN supplier s ON s.id = t.cargoSupplierFk + LEFT JOIN entry e ON e.travelFk = t.id + LEFT JOIN buy b ON b.entryFk = e.id + LEFT JOIN packaging pkg ON pkg.id = b.packageFk + LEFT JOIN item i ON i.id = b.itemFk + LEFT JOIN itemType it ON it.id = i.typeFk + JOIN warehouse w ON w.id = t.warehouseInFk + JOIN warehouse wo ON wo.id = t.warehouseOutFk + JOIN country c ON c.id = wo.countryFk + LEFT JOIN continent cnt ON cnt.id = c.continentFk + JOIN agencyMode am ON am.id = t.agencyFk` + ); + + stmt.merge(conn.makeWhere(filter.where)); + stmt.merge(conn.makeGroupBy('t.id')); + stmt.merge(conn.makeLimit(filter)); + stmts.push(stmt); + + const travelsIndex = stmts.push('SELECT * FROM tmp.travel') - 1; + + stmt = new ParameterizedSQL( + `SELECT + e.id, + e.travelFk, + e.ref, + e.loadPriority, + s.name AS supplierName, + SUM(b.stickers) AS stickers, + e.evaNotes, + e.notes, + CAST(SUM(i.density * b.stickers * IF(pkg.volume, pkg.volume, pkg.width * pkg.depth * pkg.height) / 1000000 ) as DECIMAL(10,0)) as loadedkg, + CAST(SUM(167.5 * b.stickers * IF(pkg.volume, pkg.volume, pkg.width * pkg.depth * pkg.height) / 1000000 ) as DECIMAL(10,0)) as volumeKg + FROM entry e + JOIN tmp.travel tr ON tr.id = e.travelFk + JOIN buy b ON b.entryFk = e.id + JOIN packaging pkg ON pkg.id = b.packageFk + JOIN item i ON i.id = b.itemFk + JOIN itemType it ON it.id = i.typeFk + JOIN supplier s ON s.id = e.supplierFk` + ); + + stmt.merge(conn.makeGroupBy('e.id')); + stmt.merge(conn.makeOrderBy(filter.order)); + const entriesIndex = stmts.push(stmt) - 1; + + stmts.push(`DROP TEMPORARY TABLE tmp.travel`); + + const sql = ParameterizedSQL.join(stmts, ';'); + const result = await conn.executeStmt(sql); + + const travels = result[travelsIndex]; + const entries = result[entriesIndex]; + + const travelsMap = new Map(); + for (let travel of travels) + travelsMap.set(travel.id, travel); + + for (let entry of entries) { + const travel = travelsMap.get(entry.travelFk); + + if (travel) { + if (!travel.entries) travel.entries = []; + + travel.entries.push(entry); + } + } + + return travels; + }; +}; + diff --git a/modules/travel/back/methods/travel/specs/extraCommunityFilter.spec.js b/modules/travel/back/methods/travel/specs/extraCommunityFilter.spec.js new file mode 100644 index 0000000000..7f42eb5f06 --- /dev/null +++ b/modules/travel/back/methods/travel/specs/extraCommunityFilter.spec.js @@ -0,0 +1,66 @@ +const app = require('vn-loopback/server/server'); + +describe('Travel extraCommunityFilter()', () => { + const filter = { + order: 'landed ASC, shipped ASC, travelFk, loadPriority, agencyModeFk, evaNotes', + }; + it('should return the travel matching "search"', async() => { + const ctx = { + args: { + search: 2 + } + }; + + const result = await app.models.Travel.extraCommunityFilter(ctx, filter); + const firstRow = result[0]; + const entries = firstRow.entries; + + expect(result.length).toEqual(1); + expect(firstRow.id).toEqual(2); + expect(entries.length).toEqual(2); + }); + + it('should return the travel matching "search" by ref', async() => { + const ctx = { + args: { + search: 'third' + } + }; + + const result = await app.models.Travel.extraCommunityFilter(ctx, filter); + const firstRow = result[0]; + + expect(result.length).toEqual(1); + expect(firstRow.id).toEqual(3); + }); + + it('should return the travel matching "warehouse out"', async() => { + const ctx = { + args: { + warehouseOutFk: 2 + } + }; + + const result = await app.models.Travel.extraCommunityFilter(ctx, filter); + + expect(result.length).toEqual(3); + }); + + it('should return the routes matching "landed from" and "landed to"', async() => { + const from = new Date(); + const to = new Date(); + from.setHours(0, 0, 0, 0); + to.setHours(23, 59, 59, 999); + to.setDate(to.getDate() + 14); + const ctx = { + args: { + landedFrom: from, + landedTo: to + } + }; + + const result = await app.models.Travel.extraCommunityFilter(ctx, filter); + + expect(result.length).toEqual(1); + }); +}); diff --git a/modules/travel/back/methods/travel/specs/filter.spec.js b/modules/travel/back/methods/travel/specs/filter.spec.js index d04b0f0931..ababe961e6 100644 --- a/modules/travel/back/methods/travel/specs/filter.spec.js +++ b/modules/travel/back/methods/travel/specs/filter.spec.js @@ -38,7 +38,7 @@ describe('Travel filter()', () => { const result = await app.models.Travel.filter(ctx); - expect(result.length).toEqual(8); + expect(result.length).toEqual(3); }); it('should return the travel matching "total entries"', async() => { diff --git a/modules/travel/back/models/travel.js b/modules/travel/back/models/travel.js index b47742c263..b8a1a24b36 100644 --- a/modules/travel/back/models/travel.js +++ b/modules/travel/back/models/travel.js @@ -7,6 +7,7 @@ module.exports = Self => { require('../methods/travel/createThermograph')(Self); require('../methods/travel/deleteThermograph')(Self); require('../methods/travel/updateThermograph')(Self); + require('../methods/travel/extraCommunityFilter')(Self); Self.rewriteDbError(function(err) { if (err.code === 'ER_DUP_ENTRY') diff --git a/modules/travel/front/descriptor/locale/es.yml b/modules/travel/front/descriptor/locale/es.yml index 0ae18fdbf9..3e6d627353 100644 --- a/modules/travel/front/descriptor/locale/es.yml +++ b/modules/travel/front/descriptor/locale/es.yml @@ -1,6 +1,6 @@ Reference: Referencia -Wh. In: Almacén entrada -Wh. Out: Almacén salida +Wh. In: Alm. entrada +Wh. Out: Alm. salida Shipped: F. envío Landed: F. entrega Total entries: Entradas totales \ No newline at end of file diff --git a/modules/travel/front/extra-community-search-panel/index.html b/modules/travel/front/extra-community-search-panel/index.html new file mode 100644 index 0000000000..85a30907a3 --- /dev/null +++ b/modules/travel/front/extra-community-search-panel/index.html @@ -0,0 +1,91 @@ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
\ No newline at end of file diff --git a/modules/travel/front/extra-community-search-panel/index.js b/modules/travel/front/extra-community-search-panel/index.js new file mode 100644 index 0000000000..63d404b4b1 --- /dev/null +++ b/modules/travel/front/extra-community-search-panel/index.js @@ -0,0 +1,7 @@ +import ngModule from '../module'; +import SearchPanel from 'core/components/searchbar/search-panel'; + +ngModule.vnComponent('vnExtraCommunitySearchPanel', { + template: require('./index.html'), + controller: SearchPanel +}); diff --git a/modules/travel/front/extra-community/index.html b/modules/travel/front/extra-community/index.html new file mode 100644 index 0000000000..84e6fcb854 --- /dev/null +++ b/modules/travel/front/extra-community/index.html @@ -0,0 +1,111 @@ + + + + + + + + +
+ + + + Id + Supplier + Freighter + Reference + Packages + Bl. KG + Phy. KG + Vol. KG + + Wh. Out + + Shipped + + Wh. In + + Landed + + + + + + + {{::travel.id}} + + + {{::travel.agencyModeName}} + {{::travel.cargoSupplierNickname}} + + {{travel.ref}} + + + + + + {{::travel.stickers}} + {{::travel.kg}} + {{::travel.loadedKg}} + {{::travel.volumeKg}} + {{::travel.warehouseOutName}} + {{::travel.shipped | date: 'dd/MM/yyyy'}} + {{::travel.warehouseInName}} + {{::travel.landed | date: 'dd/MM/yyyy'}} + + + + + {{::entry.id}} + + + {{::entry.supplierName}} + + {{::entry.ref}} + {{::entry.stickers}} + + {{::entry.loadedkg}} + {{::entry.volumeKg}} + + + {{::entry.notes}} + + + + + {{::entry.evaNotes}} + + + + + + + +
+
+
+ + + + + diff --git a/modules/travel/front/extra-community/index.js b/modules/travel/front/extra-community/index.js new file mode 100644 index 0000000000..221d6cb0d0 --- /dev/null +++ b/modules/travel/front/extra-community/index.js @@ -0,0 +1,91 @@ +import ngModule from '../module'; +import Section from 'salix/components/section'; +import './style.scss'; + +class Controller extends Section { + constructor($element, $) { + super($element, $); + + const draggable = this.element.querySelector('.travel-list'); + draggable.addEventListener('dragstart', + event => this.dragStart(event)); + draggable.addEventListener('dragend', + event => this.dragEnd(event)); + + this.draggableElement = 'a[draggable]'; + this.droppableElement = 'vn-table[vn-droppable]'; + + const scopeDays = 14; + const landedFrom = new Date(); + landedFrom.setHours(0, 0, 0, 0); + + const landedTo = new Date(); + landedTo.setDate(landedTo.getDate() + scopeDays); + landedTo.setHours(23, 59, 59, 59); + + this.defaultFilter = { + landedFrom: landedFrom, + landedTo: landedTo, + continent: 'AM' + }; + } + + findDraggable($event) { + const target = $event.target; + const draggable = target.closest(this.draggableElement); + + return draggable; + } + + findDroppable($event) { + const target = $event.target; + const droppable = target.closest(this.droppableElement); + + return droppable; + } + + dragStart($event) { + const draggable = this.findDraggable($event); + draggable.classList.add('dragging'); + + const id = parseInt(draggable.id); + this.entryId = id; + this.entry = draggable; + } + + dragEnd($event) { + const draggable = this.findDraggable($event); + draggable.classList.remove('dragging'); + this.entryId = null; + this.entry = null; + } + + onDrop($event) { + const model = this.$.model; + const droppable = this.findDroppable($event); + const travelId = parseInt(droppable.id); + + const currentDroppable = this.entry.closest(this.droppableElement); + + if (currentDroppable == droppable) return; + + if (this.entryId && travelId) { + const path = `Entries/${this.entryId}`; + this.$http.patch(path, {travelFk: travelId}) + .then(() => model.refresh()) + .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))); + } + } + + changeReference(travel) { + const params = {ref: travel.ref}; + const endpoint = `Travels/${travel.id}`; + this.$http.patch(endpoint, params) + .then(() => this.vnApp.showSuccess(this.$t('Data saved!'))); + } +} + +ngModule.vnComponent('vnTravelExtraCommunity', { + template: require('./index.html'), + controller: Controller +}); diff --git a/modules/travel/front/extra-community/index.spec.js b/modules/travel/front/extra-community/index.spec.js new file mode 100644 index 0000000000..2f510f22fc --- /dev/null +++ b/modules/travel/front/extra-community/index.spec.js @@ -0,0 +1,127 @@ +import './index.js'; + +describe('Travel Component vnTravelExtraCommunity', () => { + let controller; + let $httpBackend; + + beforeEach(ngModule('travel')); + + beforeEach(inject(($componentController, _$httpBackend_) => { + $httpBackend = _$httpBackend_; + const $element = angular.element('
'); + controller = $componentController('vnTravelExtraCommunity', {$element}); + controller.$.model = {}; + controller.$.model.refresh = jest.fn(); + })); + + describe('changeReference()', () => { + it('should make an HTTP query', () => { + jest.spyOn(controller.vnApp, 'showSuccess'); + + const travel = {id: 1, ref: 'New reference'}; + const expectedData = {ref: 'New reference'}; + $httpBackend.expect('PATCH', `Travels/${travel.id}`, expectedData).respond(200); + controller.changeReference(travel); + $httpBackend.flush(); + + expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!'); + }); + }); + + describe('findDraggable()', () => { + it('should find the draggable element', () => { + const draggable = document.createElement('a'); + draggable.setAttribute('draggable', true); + + const $event = new Event('dragstart'); + const target = document.createElement('div'); + draggable.appendChild(target); + target.dispatchEvent($event); + + const result = controller.findDraggable($event); + + expect(result).toEqual(draggable); + }); + }); + + describe('findDroppable()', () => { + it('should find the droppable element', () => { + const droppable = document.createElement('vn-table'); + droppable.setAttribute('vn-droppable', true); + + const $event = new Event('drop'); + const target = document.createElement('div'); + droppable.appendChild(target); + target.dispatchEvent($event); + + const result = controller.findDroppable($event); + + expect(result).toEqual(droppable); + }); + }); + + describe('dragStart()', () => { + it(`should add the class "dragging" to the draggable element + and then set the entryId controller property`, () => { + const draggable = document.createElement('a'); + draggable.setAttribute('draggable', true); + draggable.setAttribute('id', 3); + + jest.spyOn(controller, 'findDraggable').mockReturnValue(draggable); + + const $event = new Event('dragStart'); + controller.dragStart($event); + + const firstClass = draggable.classList[0]; + + expect(firstClass).toEqual('dragging'); + expect(controller.entryId).toEqual(3); + expect(controller.entry).toEqual(draggable); + }); + }); + + describe('dragEnd()', () => { + it(`should remove the class "dragging" from the draggable element + and then set the entryId controller property to null`, () => { + const draggable = document.createElement('a'); + draggable.setAttribute('draggable', true); + draggable.setAttribute('id', 3); + draggable.classList.add('dragging'); + + jest.spyOn(controller, 'findDraggable').mockReturnValue(draggable); + + const $event = new Event('dragStart'); + controller.dragEnd($event); + + const classList = draggable.classList; + + expect(classList.length).toEqual(0); + expect(controller.entryId).toBeNull(); + expect(controller.entry).toBeNull(); + }); + }); + + describe('onDrop()', () => { + it('should make an HTTP patch query', () => { + const droppable = document.createElement('vn-table'); + droppable.setAttribute('vn-droppable', true); + droppable.setAttribute('id', 1); + + jest.spyOn(controller, 'findDroppable').mockReturnValue(droppable); + + const oldDroppable = document.createElement('vn-table'); + oldDroppable.setAttribute('vn-droppable', true); + const entry = document.createElement('div'); + oldDroppable.appendChild(entry); + + controller.entryId = 3; + controller.entry = entry; + + const $event = new Event('drop'); + const expectedData = {travelFk: 1}; + $httpBackend.expect('PATCH', `Entries/3`, expectedData).respond(200); + controller.onDrop($event); + $httpBackend.flush(); + }); + }); +}); diff --git a/modules/travel/front/extra-community/locale/es.yml b/modules/travel/front/extra-community/locale/es.yml new file mode 100644 index 0000000000..e377a10111 --- /dev/null +++ b/modules/travel/front/extra-community/locale/es.yml @@ -0,0 +1,8 @@ +Family: Familia +Extra community: Extra comunitarios +Freighter: Transitario +Bl. KG: KG Bloq. +Phy. KG: KG físico +Vol. KG: KG Vol. +Search by travel id or reference: Buscar por id travel o referencia +Continent Out: Continente salida \ No newline at end of file diff --git a/modules/travel/front/extra-community/style.scss b/modules/travel/front/extra-community/style.scss new file mode 100644 index 0000000000..e7265781dd --- /dev/null +++ b/modules/travel/front/extra-community/style.scss @@ -0,0 +1,55 @@ +@import "variables"; + +vn-travel-extra-community { + .header { + margin-bottom: 16px; + font-size: 1.25rem; + line-height: 1; + padding: 7px; + padding-bottom: 7px; + padding-bottom: 4px; + font-weight: lighter; + background-color: #fde6ca; + color: $color-font-light; + border-bottom: 1px solid #f7931e; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + vn-td-editable text { + background-color: transparent; + padding: 0; + border: 0; + border-bottom: 1px dashed $color-active; + border-radius: 0; + color: $color-active + } + + vn-td-editable text:after { + font-family: 'Material Icons'; + content: 'edit'; + position: absolute; + margin-left: 5px; + color: $color-spacer + } + + vn-table[vn-droppable] { + border-radius: 0; + } + + a[draggable] { + transition: all .5s; + cursor: move; + outline: 0; + } + + a[draggable]:hover { + background-color: $color-hover-cd + } + + a[draggable].dragging { + background-color: $color-success-light; + font-weight:bold + } +} \ No newline at end of file diff --git a/modules/travel/front/index.js b/modules/travel/front/index.js index 52a09af30c..e4375c59da 100644 --- a/modules/travel/front/index.js +++ b/modules/travel/front/index.js @@ -14,3 +14,5 @@ import './thermograph/create/'; import './thermograph/edit/'; import './descriptor-popover'; import './descriptor-menu'; +import './extra-community'; +import './extra-community-search-panel'; diff --git a/modules/travel/front/routes.json b/modules/travel/front/routes.json index 5fa43fd1d3..b2e438c6d1 100644 --- a/modules/travel/front/routes.json +++ b/modules/travel/front/routes.json @@ -6,7 +6,8 @@ "dependencies": ["worker", "entry"], "menus": { "main": [ - {"state": "travel.index", "icon": "local_airport"} + {"state": "travel.index", "icon": "local_airport"}, + {"state": "travel.extraCommunity", "icon": "directions_boat"} ], "card": [ {"state": "travel.card.basicData", "icon": "settings"}, @@ -90,6 +91,16 @@ "travel": "$ctrl.travel" }, "acl": ["buyer"] + }, + { + "url": "/extra-community?q", + "state": "travel.extraCommunity", + "component": "vn-travel-extra-community", + "description": "Extra community", + "acl": ["buyer"], + "params": { + "travel": "$ctrl.travel" + } } ] } \ No newline at end of file diff --git a/modules/travel/front/summary/locale/es.yml b/modules/travel/front/summary/locale/es.yml index 09e5a19634..aa002fad05 100644 --- a/modules/travel/front/summary/locale/es.yml +++ b/modules/travel/front/summary/locale/es.yml @@ -1,6 +1,6 @@ Reference: Referencia -Warehouse In: Almacen entrada -Warehouse Out: Almacen salida +Warehouse In: Almacén entrada +Warehouse Out: Almacén salida Shipped: F. envío Landed: F. entrega Total entries: Entradas totales diff --git a/package-lock.json b/package-lock.json index 2fcd0e4403..99e20a441d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5264,6 +5264,16 @@ "integrity": "sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg==", "dev": true }, + "@types/yauzl": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", + "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==", + "dev": true, + "optional": true, + "requires": { + "@types/node": "*" + } + }, "@webassemblyjs/ast": { "version": "1.8.5", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", @@ -8546,6 +8556,12 @@ "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", "dev": true }, + "devtools-protocol": { + "version": "0.0.818844", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.818844.tgz", + "integrity": "sha512-AD1hi7iVJ8OD0aMLQU5VK0XH9LDlA1+BcPIgrAxPfaibx2DbWucuyOhc4oyQCbnvDDO68nN6/LcKfqTP343Jjg==", + "dev": true + }, "diff": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", @@ -9857,47 +9873,40 @@ } }, "extract-zip": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", - "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, "requires": { - "concat-stream": "^1.6.2", - "debug": "^2.6.9", - "mkdirp": "^0.5.4", + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", "yauzl": "^2.10.0" }, "dependencies": { - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "ms": "2.1.2" } }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { - "pend": "~1.2.0" + "pump": "^3.0.0" } }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -9981,6 +9990,15 @@ "bser": "^2.0.0" } }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, "feature-policy": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/feature-policy/-/feature-policy-0.3.0.tgz", @@ -21828,9 +21846,9 @@ } }, "proxy-from-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", - "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "dev": true }, "prr": { @@ -21914,70 +21932,68 @@ } }, "puppeteer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-2.0.0.tgz", - "integrity": "sha512-t3MmTWzQxPRP71teU6l0jX47PHXlc4Z52sQv4LJQSZLq1ttkKS2yGM3gaI57uQwZkNaoGd0+HPPMELZkcyhlqA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-5.5.0.tgz", + "integrity": "sha512-OM8ZvTXAhfgFA7wBIIGlPQzvyEETzDjeRa4mZRCRHxYL+GNH5WAuYUQdja3rpWZvkX/JKqmuVgbsxDNsDFjMEg==", "dev": true, "requires": { "debug": "^4.1.0", - "extract-zip": "^1.6.6", - "https-proxy-agent": "^3.0.0", - "mime": "^2.0.3", + "devtools-protocol": "0.0.818844", + "extract-zip": "^2.0.0", + "https-proxy-agent": "^4.0.0", + "node-fetch": "^2.6.1", + "pkg-dir": "^4.2.0", "progress": "^2.0.1", "proxy-from-env": "^1.0.0", - "rimraf": "^2.6.1", - "ws": "^6.1.0" + "rimraf": "^3.0.2", + "tar-fs": "^2.0.0", + "unbzip2-stream": "^1.3.3", + "ws": "^7.2.3" }, "dependencies": { + "agent-base": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", + "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", + "dev": true + }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, "https-proxy-agent": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz", - "integrity": "sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", + "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", "dev": true, "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } + "agent-base": "5", + "debug": "4" } }, - "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", - "dev": true + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } }, "ms": { "version": "2.1.2", @@ -21985,14 +22001,44 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" } + }, + "ws": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.0.tgz", + "integrity": "sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ==", + "dev": true } } }, @@ -25143,6 +25189,40 @@ "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=" }, + "unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "requires": { + "buffer": "^5.2.1", + "through": "^2.3.8" + }, + "dependencies": { + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + } + } + }, "unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", @@ -26908,6 +26988,16 @@ "dev": true } } + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } } } } diff --git a/package.json b/package.json index c594514669..1a301afb0f 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,7 @@ "node-sass": "^4.14.1", "nodemon": "^1.19.4", "plugin-error": "^1.0.1", - "puppeteer": "^2.0.0", + "puppeteer": "^5.5.0", "raw-loader": "^1.0.0", "sass-loader": "^7.3.1", "style-loader": "^0.23.1",