All tests passed, but some intermittence in e2e
gitea/salix/pipeline/head This commit has test failures
Details
gitea/salix/pipeline/head This commit has test failures
Details
This commit is contained in:
parent
efbda0d5c0
commit
84bf240e71
|
@ -471,19 +471,19 @@ INSERT INTO `vn`.`invoiceOutSerial` (`code`, `description`, `isTaxed`, `taxAreaF
|
||||||
|
|
||||||
INSERT INTO `vn`.`zone` (`id`, `name`, `hour`, `agencyModeFk`, `travelingDays`, `price`, `bonus`, `m3Max`)
|
INSERT INTO `vn`.`zone` (`id`, `name`, `hour`, `agencyModeFk`, `travelingDays`, `price`, `bonus`, `m3Max`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 'Zone pickup A', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 1, 0, 0, 0, 30.50),
|
(1, 'Zone pickup A', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 1, 0, 0, 0, 30.50),
|
||||||
(2, 'Zone pickup B', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 1, 0, 0, 0, 30.50),
|
(2, 'Zone pickup B', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 1, 0, 0, 0, 30.50),
|
||||||
(3, 'Zone 247 A', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 7, 1, 2, 0, 40.50),
|
(3, 'Zone 247 A', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 7, 1, 2, 0, 40.50),
|
||||||
(4, 'Zone 247 B', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 7, 1, 2, 0, 40.50),
|
(4, 'Zone 247 B', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 7, 1, 2, 0, 40.50),
|
||||||
(5, 'Zone expensive A', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 8, 1, 1000, 0, 50.50),
|
(5, 'Zone expensive A', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 8, 1, 1000, 0, 50.50),
|
||||||
(6, 'Zone expensive B', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 8, 1, 1000, 0, 50.50),
|
(6, 'Zone expensive B', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 8, 1, 1000, 0, 50.50),
|
||||||
(7, 'Zone refund', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 23, 0, 0, 0, 60.50),
|
(7, 'Zone refund', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 23, 0, 0, 0, 60.50),
|
||||||
(8, 'Zone others', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 10, 0, 0, 0, 60.50),
|
(8, 'Zone others', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 10, 0, 0, 0, 60.50),
|
||||||
(9, 'Zone superMan', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 2, 0, 0, 0, NULL),
|
(9, 'Zone superMan', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 2, 0, 0, 0, NULL),
|
||||||
(10, 'Zone teleportation', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 3, 0, 0, 0, NULL),
|
(10, 'Zone teleportation', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 3, 0, 0, 0, NULL),
|
||||||
(11, 'Zone pickup C', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 1, 0, 0, 0, NULL),
|
(11, 'Zone pickup C', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 1, 0, 0, 0, NULL),
|
||||||
(12, 'Zone entanglement', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 4, 0, 0, 0, NULL),
|
(12, 'Zone entanglement', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 4, 0, 0, 0, NULL),
|
||||||
(13, 'Zone quantum break', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 5, 0, 0, 0, NULL);
|
(13, 'Zone quantum break', CONCAT(CURRENT_DATE(), ' ', TIME('23:59')), 5, 0, 0, 0, NULL);
|
||||||
|
|
||||||
INSERT INTO `vn`.`zoneWarehouse` (`id`, `zoneFk`, `warehouseFk`)
|
INSERT INTO `vn`.`zoneWarehouse` (`id`, `zoneFk`, `warehouseFk`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -1890,14 +1890,10 @@ INSERT INTO `vn`.`zoneEvent`(`zoneFk`, `type`, `dated`)
|
||||||
(7, 'day', DATE_ADD(CURDATE(), INTERVAL +3 DAY)),
|
(7, 'day', DATE_ADD(CURDATE(), INTERVAL +3 DAY)),
|
||||||
(7, 'day', DATE_ADD(CURDATE(), INTERVAL +4 DAY)),
|
(7, 'day', DATE_ADD(CURDATE(), INTERVAL +4 DAY)),
|
||||||
(7, 'day', DATE_ADD(CURDATE(), INTERVAL +5 DAY)),
|
(7, 'day', DATE_ADD(CURDATE(), INTERVAL +5 DAY)),
|
||||||
(7, 'day', DATE_ADD(CURDATE(), INTERVAL +6 DAY)),
|
(7, 'day', DATE_ADD(CURDATE(), INTERVAL +6 DAY));
|
||||||
(8, 'day', CURDATE()),
|
|
||||||
(8, 'day', DATE_ADD(CURDATE(), INTERVAL +1 DAY)),
|
INSERT INTO `vn`.`zoneEvent`(`zoneFk`, `type`, `weekDays`)
|
||||||
(8, 'day', DATE_ADD(CURDATE(), INTERVAL +2 DAY)),
|
VALUES (8, 'indefinitely', 'mon,tue,wed,thu,fri,sat,sun');
|
||||||
(8, 'day', DATE_ADD(CURDATE(), INTERVAL +3 DAY)),
|
|
||||||
(8, 'day', DATE_ADD(CURDATE(), INTERVAL +4 DAY)),
|
|
||||||
(8, 'day', DATE_ADD(CURDATE(), INTERVAL +5 DAY)),
|
|
||||||
(8, 'day', DATE_ADD(CURDATE(), INTERVAL +6 DAY));
|
|
||||||
|
|
||||||
INSERT INTO `vn`.`workerTimeControl`(`userFk`, `timed`, `manual`, `direction`)
|
INSERT INTO `vn`.`workerTimeControl`(`userFk`, `timed`, `manual`, `direction`)
|
||||||
VALUES
|
VALUES
|
||||||
|
|
|
@ -1,45 +1,3 @@
|
||||||
import {url as defaultURL} from './config';
|
|
||||||
|
|
||||||
function checkVisibility(selector) {
|
|
||||||
let selectorMatches = document.querySelectorAll(selector);
|
|
||||||
let element = selectorMatches[0];
|
|
||||||
|
|
||||||
if (selectorMatches.length > 1)
|
|
||||||
throw new Error(`Multiple matches of ${selector} found`);
|
|
||||||
|
|
||||||
let isVisible = false;
|
|
||||||
if (element) {
|
|
||||||
let eventHandler = event => {
|
|
||||||
event.preventDefault();
|
|
||||||
isVisible = true;
|
|
||||||
};
|
|
||||||
element.addEventListener('mouseover', eventHandler);
|
|
||||||
let rect = element.getBoundingClientRect();
|
|
||||||
let x = rect.left + rect.width / 2;
|
|
||||||
let y = rect.top + rect.height / 2;
|
|
||||||
let elementInCenter = document.elementFromPoint(x, y);
|
|
||||||
let elementInTopLeft = document.elementFromPoint(rect.left, rect.top);
|
|
||||||
let elementInBottomRight = document.elementFromPoint(rect.right, rect.bottom);
|
|
||||||
|
|
||||||
let e = new MouseEvent('mouseover', {
|
|
||||||
view: window,
|
|
||||||
bubbles: true,
|
|
||||||
cancelable: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (elementInCenter)
|
|
||||||
elementInCenter.dispatchEvent(e);
|
|
||||||
|
|
||||||
if (elementInTopLeft)
|
|
||||||
elementInTopLeft.dispatchEvent(e);
|
|
||||||
|
|
||||||
if (elementInBottomRight)
|
|
||||||
elementInBottomRight.dispatchEvent(e);
|
|
||||||
|
|
||||||
element.removeEventListener('mouseover', eventHandler);
|
|
||||||
}
|
|
||||||
return isVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
let actions = {
|
let actions = {
|
||||||
clickIfExists: async function(selector) {
|
clickIfExists: async function(selector) {
|
||||||
|
@ -65,12 +23,6 @@ let actions = {
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
waitUntilNotPresent: async function(selector) {
|
|
||||||
await this.wait(selector => {
|
|
||||||
return document.querySelector(selector) == null;
|
|
||||||
}, selector);
|
|
||||||
},
|
|
||||||
|
|
||||||
doLogin: async function(userName, password = 'nightmare') {
|
doLogin: async function(userName, password = 'nightmare') {
|
||||||
await this.waitForSelector(`vn-login vn-textfield[ng-model="$ctrl.user"]`, {visible: true});
|
await this.waitForSelector(`vn-login vn-textfield[ng-model="$ctrl.user"]`, {visible: true});
|
||||||
await this.clearInput(`vn-login vn-textfield[ng-model="$ctrl.user"]`);
|
await this.clearInput(`vn-login vn-textfield[ng-model="$ctrl.user"]`);
|
||||||
|
@ -81,27 +33,31 @@ let actions = {
|
||||||
},
|
},
|
||||||
|
|
||||||
login: async function(userName) {
|
login: async function(userName) {
|
||||||
await this.goto(`${defaultURL}/#!/login`);
|
let state = await this.getState();
|
||||||
let dialog = await this.evaluate(() => {
|
|
||||||
return document.querySelector('button[response="accept"]');
|
|
||||||
});
|
|
||||||
if (dialog)
|
|
||||||
await this.waitToClick('button[response="accept"]');
|
|
||||||
|
|
||||||
|
if (state != 'login') {
|
||||||
|
try {
|
||||||
|
await this.gotoState('login');
|
||||||
|
} catch (err) {
|
||||||
|
let dialog = await this.evaluate(
|
||||||
|
() => document.querySelector('button[response="accept"]'));
|
||||||
|
|
||||||
|
if (dialog)
|
||||||
|
await this.waitToClick('button[response="accept"]');
|
||||||
|
else
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.waitForState('login');
|
||||||
await this.doLogin(userName);
|
await this.doLogin(userName);
|
||||||
await this.waitForFunction(() => {
|
await this.waitForState('home');
|
||||||
return document.location.hash === '#!/';
|
|
||||||
}, {});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
selectModule: async function(moduleName) {
|
selectModule: async function(moduleName) {
|
||||||
let snakeName = moduleName.replace(/[\w]([A-Z])/g, m => {
|
let state = `${moduleName}.index`;
|
||||||
return m[0] + '-' + m[1];
|
await this.waitToClick(`vn-home a[ui-sref="${state}"]`);
|
||||||
}).toLowerCase();
|
await this.waitForState(state);
|
||||||
|
|
||||||
let selector = `vn-home a[ui-sref="${moduleName}.index"]`;
|
|
||||||
await this.waitToClick(selector);
|
|
||||||
await this.expectURL(snakeName);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
loginAndModule: async function(userName, moduleName) {
|
loginAndModule: async function(userName, moduleName) {
|
||||||
|
@ -109,56 +65,73 @@ let actions = {
|
||||||
await this.selectModule(moduleName);
|
await this.selectModule(moduleName);
|
||||||
},
|
},
|
||||||
|
|
||||||
datePicker: async function(selector, changeMonth, day) {
|
getState: async function() {
|
||||||
let date = new Date();
|
return await this.evaluate(() => {
|
||||||
if (changeMonth) date.setMonth(date.getMonth() + changeMonth);
|
let $state = angular.element(document.body).injector().get('$state');
|
||||||
date.setDate(day ? day : 16);
|
return $state.current.name;
|
||||||
date = date.toISOString().substr(0, 10);
|
});
|
||||||
|
|
||||||
await this.wait(selector);
|
|
||||||
await this.evaluate((selector, date) => {
|
|
||||||
let input = document.querySelector(selector).$ctrl.input;
|
|
||||||
input.value = date;
|
|
||||||
input.dispatchEvent(new Event('change'));
|
|
||||||
}, selector, date);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
pickTime: async function(selector, time) {
|
gotoState: async function(state, params) {
|
||||||
await this.wait(selector);
|
return await this.evaluate((state, params) => {
|
||||||
await this.evaluate((selector, time) => {
|
let $state = angular.element(document.body).injector().get('$state');
|
||||||
let input = document.querySelector(selector).$ctrl.input;
|
return $state.go(state, params);
|
||||||
input.value = time;
|
}, state, params);
|
||||||
input.dispatchEvent(new Event('change'));
|
|
||||||
}, selector, time);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
clearTextarea: async function(selector) {
|
waitForState: async function(state) {
|
||||||
await this.waitForSelector(selector, {visible: true});
|
await this.waitFor(state => {
|
||||||
await this.evaluate(inputSelector => {
|
let $state = angular.element(document.body).injector().get('$state');
|
||||||
return document.querySelector(`${inputSelector} textarea`).value = '';
|
return $state.is(state);
|
||||||
}, selector);
|
}, {}, state);
|
||||||
},
|
},
|
||||||
|
|
||||||
clearInput: async function(selector) {
|
waitForTransition: async function() {
|
||||||
await this.waitForSelector(selector);
|
await this.waitFor(() => {
|
||||||
|
const $state = angular.element(document.body).injector().get('$state');
|
||||||
|
return !$state.transition;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
let field = await this.evaluate(selector => {
|
accessToSection: async function(state) {
|
||||||
return document.querySelector(`${selector} input`).closest('.vn-field').$ctrl.field;
|
await this.waitForSelector('vn-left-menu');
|
||||||
}, selector);
|
let nested = await this.evaluate(state => {
|
||||||
|
return document.querySelector(`vn-left-menu li li > a[ui-sref="${state}"]`) != null;
|
||||||
|
}, state);
|
||||||
|
|
||||||
if ((field != null && field != '') || field == '0') {
|
if (nested) {
|
||||||
let coords = await this.evaluate(selector => {
|
await this.waitToClick('vn-left-menu vn-item-section > vn-icon[icon=keyboard_arrow_down]');
|
||||||
let rect = document.querySelector(selector).getBoundingClientRect();
|
await this.wait('vn-left-menu .expanded');
|
||||||
return {x: rect.x + (rect.width / 2), y: rect.y + (rect.height / 2), width: rect.width};
|
|
||||||
}, selector);
|
|
||||||
await this.mouse.move(coords.x, coords.y);
|
|
||||||
await this.waitForSelector(`${selector} [icon="clear"]`, {visible: true});
|
|
||||||
await this.waitToClick(`${selector} [icon="clear"]`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.evaluate(selector => {
|
await this.evaluate(state => {
|
||||||
return document.querySelector(`${selector} input`).closest('.vn-field').$ctrl.field == '';
|
let navButton = document.querySelector(`vn-left-menu li > a[ui-sref="${state}"]`);
|
||||||
}, selector);
|
navButton.scrollIntoViewIfNeeded();
|
||||||
|
return navButton.click();
|
||||||
|
}, state);
|
||||||
|
|
||||||
|
await this.waitForState(state);
|
||||||
|
await this.waitForContentLoaded();
|
||||||
|
},
|
||||||
|
|
||||||
|
reloadSection: async function(state) {
|
||||||
|
await this.click('vn-icon[icon="desktop_windows"]');
|
||||||
|
await this.accessToSection(state);
|
||||||
|
},
|
||||||
|
|
||||||
|
forceReloadSection: async function(sectionRoute) {
|
||||||
|
await this.waitToClick('vn-icon[icon="desktop_windows"]');
|
||||||
|
await this.waitToClick('button[response="accept"]');
|
||||||
|
await this.wait('vn-card.summary');
|
||||||
|
await this.waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`);
|
||||||
|
},
|
||||||
|
|
||||||
|
accessToSearchResult: async function(searchValue) {
|
||||||
|
await this.clearInput('vn-searchbar');
|
||||||
|
await this.write('vn-searchbar', searchValue);
|
||||||
|
await this.waitToClick('vn-searchbar vn-icon[icon="search"]');
|
||||||
|
await this.waitForTransition();
|
||||||
|
await this.waitForContentLoaded();
|
||||||
},
|
},
|
||||||
|
|
||||||
getProperty: async function(selector, property) {
|
getProperty: async function(selector, property) {
|
||||||
|
@ -216,7 +189,7 @@ let actions = {
|
||||||
|
|
||||||
waitToClick: async function(selector) {
|
waitToClick: async function(selector) {
|
||||||
await this.waitForSelector(selector);
|
await this.waitForSelector(selector);
|
||||||
await this.waitForFunction(checkVisibility, {}, selector);
|
await this.checkVisibility(selector);
|
||||||
|
|
||||||
return await this.click(selector);
|
return await this.click(selector);
|
||||||
},
|
},
|
||||||
|
@ -236,9 +209,52 @@ let actions = {
|
||||||
}, selector);
|
}, selector);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
checkVisibility: async function(selector) {
|
||||||
|
return await this.evaluate(function(selector) {
|
||||||
|
let selectorMatches = document.querySelectorAll(selector);
|
||||||
|
let element = selectorMatches[0];
|
||||||
|
|
||||||
|
if (selectorMatches.length > 1)
|
||||||
|
throw new Error(`Multiple matches of ${selector} found`);
|
||||||
|
|
||||||
|
let isVisible = false;
|
||||||
|
if (element) {
|
||||||
|
let eventHandler = event => {
|
||||||
|
event.preventDefault();
|
||||||
|
isVisible = true;
|
||||||
|
};
|
||||||
|
element.addEventListener('mouseover', eventHandler);
|
||||||
|
let rect = element.getBoundingClientRect();
|
||||||
|
let x = rect.left + rect.width / 2;
|
||||||
|
let y = rect.top + rect.height / 2;
|
||||||
|
let elementInCenter = document.elementFromPoint(x, y);
|
||||||
|
let elementInTopLeft = document.elementFromPoint(rect.left, rect.top);
|
||||||
|
let elementInBottomRight = document.elementFromPoint(rect.right, rect.bottom);
|
||||||
|
|
||||||
|
let e = new MouseEvent('mouseover', {
|
||||||
|
view: window,
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (elementInCenter)
|
||||||
|
elementInCenter.dispatchEvent(e);
|
||||||
|
|
||||||
|
if (elementInTopLeft)
|
||||||
|
elementInTopLeft.dispatchEvent(e);
|
||||||
|
|
||||||
|
if (elementInBottomRight)
|
||||||
|
elementInBottomRight.dispatchEvent(e);
|
||||||
|
|
||||||
|
element.removeEventListener('mouseover', eventHandler);
|
||||||
|
}
|
||||||
|
return isVisible;
|
||||||
|
}, selector);
|
||||||
|
},
|
||||||
|
|
||||||
isVisible: async function(selector) {
|
isVisible: async function(selector) {
|
||||||
await this.waitForSelector(selector);
|
await this.waitForSelector(selector);
|
||||||
return await this.evaluate(checkVisibility, selector);
|
return await this.checkVisibility(selector);
|
||||||
},
|
},
|
||||||
|
|
||||||
waitImgLoad: async function(selector) {
|
waitImgLoad: async function(selector) {
|
||||||
|
@ -320,12 +336,13 @@ let actions = {
|
||||||
},
|
},
|
||||||
|
|
||||||
hideSnackbar: async function() {
|
hideSnackbar: async function() {
|
||||||
await this.waitFor(750); // holds up for the snackbar to be visible for a small period of time.
|
await this.waitFor(300); // holds up for the snackbar to be visible for a small period of time.
|
||||||
await this.evaluate(() => {
|
await this.evaluate(() => {
|
||||||
let hideButton = document.querySelector('#shapes .shown button');
|
let hideButton = document.querySelector('#shapes .shown button');
|
||||||
if (hideButton)
|
if (hideButton)
|
||||||
return document.querySelector('#shapes .shown button').click();
|
return document.querySelector('#shapes .shown button').click();
|
||||||
});
|
});
|
||||||
|
await this.waitFor('#shapes > .shape', {hidden: true});
|
||||||
},
|
},
|
||||||
|
|
||||||
waitForLastSnackbar: async function() {
|
waitForLastSnackbar: async function() {
|
||||||
|
@ -341,37 +358,59 @@ let actions = {
|
||||||
return snackBarText;
|
return snackBarText;
|
||||||
},
|
},
|
||||||
|
|
||||||
accessToSearchResult: async function(searchValue) {
|
pickDate: async function(selector, date) {
|
||||||
await this.clearInput('vn-searchbar');
|
date = date || new Date();
|
||||||
await this.write('vn-searchbar', searchValue);
|
date = date.toISOString().substr(0, 10);
|
||||||
await this.waitToClick('vn-searchbar vn-icon[icon="search"]');
|
|
||||||
await this.waitForContentLoaded();
|
await this.wait(selector);
|
||||||
|
await this.evaluate((selector, date) => {
|
||||||
|
let input = document.querySelector(selector).$ctrl.input;
|
||||||
|
input.value = date;
|
||||||
|
input.dispatchEvent(new Event('change'));
|
||||||
|
}, selector, date);
|
||||||
},
|
},
|
||||||
|
|
||||||
accessToSection: async function(sectionRoute) {
|
pickTime: async function(selector, time) {
|
||||||
await this.waitForSelector('vn-left-menu');
|
await this.wait(selector);
|
||||||
let nested = await this.evaluate(sectionRoute => {
|
await this.evaluate((selector, time) => {
|
||||||
return document.querySelector(`vn-left-menu li li > a[ui-sref="${sectionRoute}"]`) != null;
|
let input = document.querySelector(selector).$ctrl.input;
|
||||||
}, sectionRoute);
|
input.value = time;
|
||||||
|
input.dispatchEvent(new Event('change'));
|
||||||
|
}, selector, time);
|
||||||
|
},
|
||||||
|
|
||||||
if (nested) {
|
clearTextarea: async function(selector) {
|
||||||
await this.waitToClick('vn-left-menu vn-item-section > vn-icon[icon=keyboard_arrow_down]');
|
await this.waitForSelector(selector, {visible: true});
|
||||||
await this.wait('vn-left-menu .expanded');
|
await this.evaluate(inputSelector => {
|
||||||
|
return document.querySelector(`${inputSelector} textarea`).value = '';
|
||||||
|
}, selector);
|
||||||
|
},
|
||||||
|
|
||||||
|
clearInput: async function(selector) {
|
||||||
|
await this.waitForSelector(selector);
|
||||||
|
|
||||||
|
let field = await this.evaluate(selector => {
|
||||||
|
return document.querySelector(`${selector} input`).closest('.vn-field').$ctrl.field;
|
||||||
|
}, selector);
|
||||||
|
|
||||||
|
if ((field != null && field != '') || field == '0') {
|
||||||
|
let coords = await this.evaluate(selector => {
|
||||||
|
let rect = document.querySelector(selector).getBoundingClientRect();
|
||||||
|
return {x: rect.x + (rect.width / 2), y: rect.y + (rect.height / 2), width: rect.width};
|
||||||
|
}, selector);
|
||||||
|
await this.mouse.move(coords.x, coords.y);
|
||||||
|
await this.waitForSelector(`${selector} [icon="clear"]`, {visible: true});
|
||||||
|
await this.waitToClick(`${selector} [icon="clear"]`);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.evaluate(sectionRoute => {
|
await this.evaluate(selector => {
|
||||||
let navButton = document.querySelector(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`);
|
return document.querySelector(`${selector} input`).closest('.vn-field').$ctrl.field == '';
|
||||||
navButton.scrollIntoViewIfNeeded();
|
}, selector);
|
||||||
return navButton.click();
|
|
||||||
}, sectionRoute);
|
|
||||||
await this.waitForNavigation({waitUntil: ['networkidle0']});
|
|
||||||
await this.waitForContentLoaded();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
autocompleteSearch: async function(selector, searchValue) {
|
autocompleteSearch: async function(selector, searchValue) {
|
||||||
let builtSelector = await this.selectorFormater(selector);
|
let builtSelector = await this.selectorFormater(selector);
|
||||||
|
|
||||||
await this.waitForContentLoaded();
|
|
||||||
await this.waitToClick(selector);
|
await this.waitToClick(selector);
|
||||||
await this.waitForSelector(selector => {
|
await this.waitForSelector(selector => {
|
||||||
document
|
document
|
||||||
|
@ -402,28 +441,7 @@ let actions = {
|
||||||
}, {}, builtSelector, searchValue);
|
}, {}, builtSelector, searchValue);
|
||||||
|
|
||||||
await this.waitForMutation('.vn-drop-down', 'childList');
|
await this.waitForMutation('.vn-drop-down', 'childList');
|
||||||
await this.waitForContentLoaded();
|
await this.waitFor('.vn-drop-down', {hidden: true});
|
||||||
},
|
|
||||||
|
|
||||||
reloadSection: async function(sectionRoute) {
|
|
||||||
await this.waitForContentLoaded();
|
|
||||||
await Promise.all([
|
|
||||||
this.waitForNavigation({waitUntil: 'networkidle0'}),
|
|
||||||
this.click('vn-icon[icon="desktop_windows"]', {}),
|
|
||||||
]);
|
|
||||||
|
|
||||||
await Promise.all([
|
|
||||||
this.waitForNavigation({waitUntil: 'networkidle0'}),
|
|
||||||
this.click(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`, {}),
|
|
||||||
]);
|
|
||||||
await this.waitForContentLoaded();
|
|
||||||
},
|
|
||||||
|
|
||||||
forceReloadSection: async function(sectionRoute) {
|
|
||||||
await this.waitToClick('vn-icon[icon="desktop_windows"]');
|
|
||||||
await this.waitToClick('button[response="accept"]');
|
|
||||||
await this.wait('vn-card.summary');
|
|
||||||
await this.waitToClick(`vn-left-menu li > a[ui-sref="${sectionRoute}"]`);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
checkboxState: async function(selector) {
|
checkboxState: async function(selector) {
|
||||||
|
@ -457,7 +475,7 @@ let actions = {
|
||||||
},
|
},
|
||||||
|
|
||||||
waitForSpinnerLoad: async function() {
|
waitForSpinnerLoad: async function() {
|
||||||
await this.waitUntilNotPresent('vn-topbar vn-spinner');
|
await this.waitFor('vn-topbar vn-spinner', {hidden: true});
|
||||||
},
|
},
|
||||||
|
|
||||||
waitForWatcherData: async function(selector) {
|
waitForWatcherData: async function(selector) {
|
||||||
|
@ -509,14 +527,10 @@ let actions = {
|
||||||
closePopup: async function(selector) {
|
closePopup: async function(selector) {
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.keyboard.press('Escape'),
|
this.keyboard.press('Escape'),
|
||||||
this.waitForSelector('.vn-popup', {hidden: true}),
|
this.waitFor('.vn-popup', {hidden: true}),
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
waitForContentLoaded: async function() {
|
|
||||||
await this.waitFor(1000);
|
|
||||||
},
|
|
||||||
|
|
||||||
respondToDialog: async function(response) {
|
respondToDialog: async function(response) {
|
||||||
await this.waitForSelector('.vn-dialog.vn-popup.shown');
|
await this.waitForSelector('.vn-dialog.vn-popup.shown');
|
||||||
const firstCount = await this.evaluate(text => {
|
const firstCount = await this.evaluate(text => {
|
||||||
|
@ -531,6 +545,10 @@ let actions = {
|
||||||
const dialogs = document.querySelectorAll('.vn-dialog.vn-popup');
|
const dialogs = document.querySelectorAll('.vn-dialog.vn-popup');
|
||||||
return dialogs.length < firstCount;
|
return dialogs.length < firstCount;
|
||||||
}, {}, firstCount);
|
}, {}, firstCount);
|
||||||
|
},
|
||||||
|
|
||||||
|
waitForContentLoaded: async function() {
|
||||||
|
await this.waitFor(250);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,8 @@ export async function getBrowser() {
|
||||||
const browser = await Puppeteer.launch({
|
const browser = await Puppeteer.launch({
|
||||||
args: [
|
args: [
|
||||||
'--no-sandbox',
|
'--no-sandbox',
|
||||||
`--window-size=${ 1920 },${ 1080 }`
|
`--window-size=${ 1920 },${ 1080 }`,
|
||||||
|
// '--auto-open-devtools-for-tabs'
|
||||||
],
|
],
|
||||||
defaultViewport: null,
|
defaultViewport: null,
|
||||||
headless: headless,
|
headless: headless,
|
||||||
|
@ -28,8 +29,8 @@ export async function getBrowser() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
page = extendPage(page);
|
page = extendPage(page);
|
||||||
page.setDefaultTimeout(10000);
|
page.setDefaultTimeout(4000);
|
||||||
await page.goto(defaultURL, {waitUntil: 'networkidle0'});
|
await page.goto(defaultURL, {waitUntil: 'load'});
|
||||||
return {page, close: browser.close.bind(browser)};
|
return {page, close: browser.close.bind(browser)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,32 +12,42 @@ describe('Login path', async() => {
|
||||||
await browser.close();
|
await browser.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should receive an error when the username is incorrect', async() => {
|
describe('Bad login', async() => {
|
||||||
await page.doLogin('badUser', '');
|
it('should receive an error when the username is incorrect', async() => {
|
||||||
const result = await page.waitForLastSnackbar();
|
await page.doLogin('badUser', '');
|
||||||
|
const result = await page.waitForLastSnackbar();
|
||||||
|
const state = await page.getState();
|
||||||
|
|
||||||
expect(result.length).toBeGreaterThan(0);
|
expect(result.length).toBeGreaterThan(0);
|
||||||
|
expect(state).toBe('login');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should receive an error when the username is blank', async() => {
|
||||||
|
await page.doLogin('', '');
|
||||||
|
const result = await page.waitForLastSnackbar();
|
||||||
|
const state = await page.getState();
|
||||||
|
|
||||||
|
expect(result.length).toBeGreaterThan(0);
|
||||||
|
expect(state).toBe('login');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should receive an error when the password is incorrect', async() => {
|
||||||
|
await page.doLogin('employee', 'badPassword');
|
||||||
|
const result = await page.waitForLastSnackbar();
|
||||||
|
const state = await page.getState();
|
||||||
|
|
||||||
|
expect(result.length).toBeGreaterThan(0);
|
||||||
|
expect(state).toBe('login');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should receive an error when the username is blank', async() => {
|
describe('Successful login', async() => {
|
||||||
await page.doLogin('', '');
|
it('should log in', async() => {
|
||||||
const result = await page.waitForLastSnackbar();
|
await page.doLogin('employee', 'nightmare');
|
||||||
|
await page.waitForNavigation();
|
||||||
|
const state = await page.getState();
|
||||||
|
|
||||||
expect(result.length).toBeGreaterThan(0);
|
expect(state).toBe('home');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should receive an error when the password is incorrect', async() => {
|
|
||||||
await page.doLogin('employee', 'badPassword');
|
|
||||||
const result = await page.waitForLastSnackbar();
|
|
||||||
|
|
||||||
expect(result.length).toBeGreaterThan(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should log in', async() => {
|
|
||||||
await page.doLogin('employee', 'nightmare');
|
|
||||||
await page.waitForNavigation();
|
|
||||||
let url = await page.expectURL('#!/');
|
|
||||||
|
|
||||||
expect(url).toBe(true);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -25,10 +25,7 @@ describe('Client create path', async() => {
|
||||||
|
|
||||||
it('should now access to the create client view by clicking the create-client floating button', async() => {
|
it('should now access to the create client view by clicking the create-client floating button', async() => {
|
||||||
await page.waitToClick(selectors.clientsIndex.createClientButton);
|
await page.waitToClick(selectors.clientsIndex.createClientButton);
|
||||||
await page.wait(selectors.createClientView.createButton);
|
await page.waitForState('client.create');
|
||||||
let url = await page.expectURL('#!/client/create');
|
|
||||||
|
|
||||||
expect(url).toBe(true);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should receive an error when clicking the create button having all the form fields empty', async() => {
|
it('should receive an error when clicking the create button having all the form fields empty', async() => {
|
||||||
|
|
|
@ -109,7 +109,7 @@ describe('Client lock verified data path', () => {
|
||||||
await page.waitToClick(selectors.clientFiscalData.saveButton);
|
await page.waitToClick(selectors.clientFiscalData.saveButton);
|
||||||
const result = await page.waitForLastSnackbar();
|
const result = await page.waitForLastSnackbar();
|
||||||
|
|
||||||
expect(result).toEqual(jasmine.arrayContaining([`You can't make changes on a client with verified data`]));
|
expect(result).toEqual(`You can't make changes on a client with verified data`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,9 @@ describe('Ticket expeditions and log path', () => {
|
||||||
|
|
||||||
it(`should delete a former expedition and confirm the remaining expedition are the expected ones`, async() => {
|
it(`should delete a former expedition and confirm the remaining expedition are the expected ones`, async() => {
|
||||||
await page.waitToClick(selectors.ticketExpedition.secondExpeditionRemoveButton);
|
await page.waitToClick(selectors.ticketExpedition.secondExpeditionRemoveButton);
|
||||||
await page.waitToClick(selectors.ticketExpedition.acceptDeleteRowButton),
|
await page.waitToClick(selectors.ticketExpedition.acceptDeleteRowButton);
|
||||||
await page.reloadSection('ticket.card.expedition');
|
await page.reloadSection('ticket.card.expedition');
|
||||||
|
|
||||||
await page.waitForSelector(selectors.ticketExpedition.expeditionRow, {});
|
await page.waitForSelector(selectors.ticketExpedition.expeditionRow, {});
|
||||||
const result = await page
|
const result = await page
|
||||||
.countElement(selectors.ticketExpedition.expeditionRow);
|
.countElement(selectors.ticketExpedition.expeditionRow);
|
||||||
|
|
|
@ -44,9 +44,6 @@ describe('Ticket services path', () => {
|
||||||
await page.loginAndModule('administrative', 'ticket');
|
await page.loginAndModule('administrative', 'ticket');
|
||||||
await page.accessToSearchResult(editableTicketId);
|
await page.accessToSearchResult(editableTicketId);
|
||||||
await page.accessToSection('ticket.card.service');
|
await page.accessToSection('ticket.card.service');
|
||||||
let url = await page.expectURL('/service');
|
|
||||||
|
|
||||||
expect(url).toBe(true);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click on the add button to prepare the form to create a new service', async() => {
|
it('should click on the add button to prepare the form to create a new service', async() => {
|
||||||
|
|
|
@ -23,9 +23,12 @@ describe('Ticket create path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should succeed to create a ticket', async() => {
|
it('should succeed to create a ticket', async() => {
|
||||||
|
const nextMonth = new Date();
|
||||||
|
nextMonth.setMonth(nextMonth.getMonth() + 1);
|
||||||
|
|
||||||
await page.autocompleteSearch(selectors.createTicketView.client, 'Tony Stark');
|
await page.autocompleteSearch(selectors.createTicketView.client, 'Tony Stark');
|
||||||
await page.autocompleteSearch(selectors.createTicketView.address, 'Tony Stark');
|
await page.autocompleteSearch(selectors.createTicketView.address, 'Tony Stark');
|
||||||
await page.datePicker(selectors.createTicketView.deliveryDate, 1, null);
|
await page.pickDate(selectors.createTicketView.deliveryDate, nextMonth);
|
||||||
await page.autocompleteSearch(selectors.createTicketView.warehouse, 'Warehouse One');
|
await page.autocompleteSearch(selectors.createTicketView.warehouse, 'Warehouse One');
|
||||||
await page.autocompleteSearch(selectors.createTicketView.agency, 'Silla247');
|
await page.autocompleteSearch(selectors.createTicketView.agency, 'Silla247');
|
||||||
await page.waitToClick(selectors.createTicketView.createButton);
|
await page.waitToClick(selectors.createTicketView.createButton);
|
||||||
|
|
|
@ -27,7 +27,7 @@ describe('Claim edit basic data path', () => {
|
||||||
await page.waitToClick(selectors.claimBasicData.saveButton);
|
await page.waitToClick(selectors.claimBasicData.saveButton);
|
||||||
const result = await page.waitForLastSnackbar();
|
const result = await page.waitForLastSnackbar();
|
||||||
|
|
||||||
expect(result).toEqual(jasmine.arrayContaining(['Data saved!']));
|
expect(result).toEqual('Data saved!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should have been redirected to the next section of claims as the role is salesAssistant`, async() => {
|
it(`should have been redirected to the next section of claims as the role is salesAssistant`, async() => {
|
||||||
|
@ -58,6 +58,6 @@ describe('Claim edit basic data path', () => {
|
||||||
await page.waitToClick(selectors.claimBasicData.saveButton);
|
await page.waitToClick(selectors.claimBasicData.saveButton);
|
||||||
const result = await page.waitForLastSnackbar();
|
const result = await page.waitForLastSnackbar();
|
||||||
|
|
||||||
expect(result).toEqual(jasmine.arrayContaining(['Data saved!']));
|
expect(result).toEqual('Data saved!');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -67,7 +67,7 @@ describe('Claim action path', () => {
|
||||||
await page.waitToClick(selectors.claimAction.isPaidWithManaCheckbox);
|
await page.waitToClick(selectors.claimAction.isPaidWithManaCheckbox);
|
||||||
const result = await page.waitForLastSnackbar();
|
const result = await page.waitForLastSnackbar();
|
||||||
|
|
||||||
expect(result).toEqual(jasmine.arrayContaining(['Data saved!']));
|
expect(result).toEqual('Data saved!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should confirm the "is paid with mana" checkbox is checked', async() => {
|
it('should confirm the "is paid with mana" checkbox is checked', async() => {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import getBrowser from '../../helpers/puppeteer';
|
||||||
describe('Order edit basic data path', () => {
|
describe('Order edit basic data path', () => {
|
||||||
let browser;
|
let browser;
|
||||||
let page;
|
let page;
|
||||||
const today = new Date().getDate();
|
|
||||||
|
|
||||||
beforeAll(async() => {
|
beforeAll(async() => {
|
||||||
browser = await getBrowser();
|
browser = await getBrowser();
|
||||||
|
@ -67,7 +66,7 @@ describe('Order edit basic data path', () => {
|
||||||
|
|
||||||
it('should now create a new one', async() => {
|
it('should now create a new one', async() => {
|
||||||
await page.autocompleteSearch(selectors.createOrderView.client, 'Jessica Jones');
|
await page.autocompleteSearch(selectors.createOrderView.client, 'Jessica Jones');
|
||||||
await page.datePicker(selectors.createOrderView.landedDatePicker, 0, today);
|
await page.pickDate(selectors.createOrderView.landedDatePicker);
|
||||||
await page.autocompleteSearch(selectors.createOrderView.agency, 'Other agency');
|
await page.autocompleteSearch(selectors.createOrderView.agency, 'Other agency');
|
||||||
await page.waitToClick(selectors.createOrderView.createButton);
|
await page.waitToClick(selectors.createOrderView.createButton);
|
||||||
let url = await page.expectURL('/catalog');
|
let url = await page.expectURL('/catalog');
|
||||||
|
|
|
@ -23,10 +23,8 @@ describe('Order catalog', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create a new order', async() => {
|
it('should create a new order', async() => {
|
||||||
let today = new Date().getDate();
|
|
||||||
|
|
||||||
await page.autocompleteSearch(selectors.createOrderView.client, 'Tony Stark');
|
await page.autocompleteSearch(selectors.createOrderView.client, 'Tony Stark');
|
||||||
await page.datePicker(selectors.createOrderView.landedDatePicker, 0, today);
|
await page.pickDate(selectors.createOrderView.landedDatePicker);
|
||||||
await page.autocompleteSearch(selectors.createOrderView.agency, 'Other agency');
|
await page.autocompleteSearch(selectors.createOrderView.agency, 'Other agency');
|
||||||
await page.waitToClick(selectors.createOrderView.createButton);
|
await page.waitToClick(selectors.createOrderView.createButton);
|
||||||
let url = await page.expectURL('/catalog');
|
let url = await page.expectURL('/catalog');
|
||||||
|
|
|
@ -18,9 +18,12 @@ describe('Route basic Data path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should edit the route basic data', async() => {
|
it('should edit the route basic data', async() => {
|
||||||
|
const nextMonth = new Date();
|
||||||
|
nextMonth.setMonth(nextMonth.getMonth() + 1);
|
||||||
|
|
||||||
await page.autocompleteSearch(selectors.routeBasicData.worker, 'adminBossNick');
|
await page.autocompleteSearch(selectors.routeBasicData.worker, 'adminBossNick');
|
||||||
await page.autocompleteSearch(selectors.routeBasicData.vehicle, '1111-IMK');
|
await page.autocompleteSearch(selectors.routeBasicData.vehicle, '1111-IMK');
|
||||||
await page.datePicker(selectors.routeBasicData.createdDate, 1, null);
|
await page.pickDate(selectors.routeBasicData.createdDate, nextMonth);
|
||||||
await page.clearInput(selectors.routeBasicData.kmStart);
|
await page.clearInput(selectors.routeBasicData.kmStart);
|
||||||
await page.write(selectors.routeBasicData.kmStart, '1');
|
await page.write(selectors.routeBasicData.kmStart, '1');
|
||||||
await page.clearInput(selectors.routeBasicData.kmEnd);
|
await page.clearInput(selectors.routeBasicData.kmEnd);
|
||||||
|
@ -37,7 +40,6 @@ describe('Route basic Data path', () => {
|
||||||
await page.reloadSection('route.card.basicData');
|
await page.reloadSection('route.card.basicData');
|
||||||
const worker = await page.waitToGetProperty(selectors.routeBasicData.worker, 'value');
|
const worker = await page.waitToGetProperty(selectors.routeBasicData.worker, 'value');
|
||||||
|
|
||||||
|
|
||||||
expect(worker).toEqual('adminBoss - adminBossNick');
|
expect(worker).toEqual('adminBoss - adminBossNick');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ describe('Route create path', () => {
|
||||||
|
|
||||||
it(`should create a new route`, async() => {
|
it(`should create a new route`, async() => {
|
||||||
await page.autocompleteSearch(selectors.createRouteView.worker, 'teamManagerNick');
|
await page.autocompleteSearch(selectors.createRouteView.worker, 'teamManagerNick');
|
||||||
await page.datePicker(selectors.createRouteView.createdDatePicker, 0, null);
|
await page.pickDate(selectors.createRouteView.createdDatePicker);
|
||||||
await page.autocompleteSearch(selectors.createRouteView.vehicleAuto, '4444-IMK');
|
await page.autocompleteSearch(selectors.createRouteView.vehicleAuto, '4444-IMK');
|
||||||
await page.autocompleteSearch(selectors.createRouteView.agency, 'Teleportation device');
|
await page.autocompleteSearch(selectors.createRouteView.agency, 'Teleportation device');
|
||||||
await page.write(selectors.createRouteView.description, 'faster faster!!');
|
await page.write(selectors.createRouteView.description, 'faster faster!!');
|
||||||
|
|
|
@ -24,7 +24,10 @@ describe('Travel basic data path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set a wrong delivery date then receive an error on submit', async() => {
|
it('should set a wrong delivery date then receive an error on submit', async() => {
|
||||||
await page.datePicker(selectors.travelBasicDada.deliveryDate, -1, null);
|
const lastMonth = new Date();
|
||||||
|
lastMonth.setMonth(lastMonth.getMonth() - 1);
|
||||||
|
|
||||||
|
await page.pickDate(selectors.travelBasicDada.deliveryDate, lastMonth);
|
||||||
await page.waitToClick(selectors.travelBasicDada.save);
|
await page.waitToClick(selectors.travelBasicDada.save);
|
||||||
const result = await page.waitForLastSnackbar();
|
const result = await page.waitForLastSnackbar();
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ describe('Zone basic data path', () => {
|
||||||
await page.clearInput(selectors.zoneBasicData.travelingDays);
|
await page.clearInput(selectors.zoneBasicData.travelingDays);
|
||||||
await page.write(selectors.zoneBasicData.travelingDays, '1');
|
await page.write(selectors.zoneBasicData.travelingDays, '1');
|
||||||
await page.clearInput(selectors.zoneBasicData.closing);
|
await page.clearInput(selectors.zoneBasicData.closing);
|
||||||
await page.type(selectors.zoneBasicData.closing, '2100');
|
await page.type(selectors.zoneBasicData.closing, '09:00PM');
|
||||||
await page.clearInput(selectors.zoneBasicData.price);
|
await page.clearInput(selectors.zoneBasicData.price);
|
||||||
await page.write(selectors.zoneBasicData.price, '999');
|
await page.write(selectors.zoneBasicData.price, '999');
|
||||||
await page.clearInput(selectors.zoneBasicData.bonus);
|
await page.clearInput(selectors.zoneBasicData.bonus);
|
||||||
|
@ -40,14 +40,13 @@ describe('Zone basic data path', () => {
|
||||||
await page.write(selectors.zoneBasicData.inflation, '200');
|
await page.write(selectors.zoneBasicData.inflation, '200');
|
||||||
await page.waitToClick(selectors.zoneBasicData.volumetric);
|
await page.waitToClick(selectors.zoneBasicData.volumetric);
|
||||||
await page.waitToClick(selectors.zoneBasicData.saveButton);
|
await page.waitToClick(selectors.zoneBasicData.saveButton);
|
||||||
await page.waitForContentLoaded();
|
const result = await page.waitForLastSnackbar();
|
||||||
|
|
||||||
|
expect(result).toEqual('Data saved!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should now reload the section', async() => {
|
it('should now reload the section', async() => {
|
||||||
await page.reloadSection('zone.card.basicData');
|
await page.reloadSection('zone.card.basicData');
|
||||||
let url = await page.expectURL('#!/zone/10/basic-data');
|
|
||||||
|
|
||||||
expect(url).toBe(true);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should confirm the name was updated', async() => {
|
it('should confirm the name was updated', async() => {
|
||||||
|
|
|
@ -6,9 +6,8 @@ import './style.scss';
|
||||||
* A simple component to show non-obstructive notifications to the user.
|
* A simple component to show non-obstructive notifications to the user.
|
||||||
*/
|
*/
|
||||||
export default class Controller extends Component {
|
export default class Controller extends Component {
|
||||||
constructor($element, $translate) {
|
constructor($element, $) {
|
||||||
super($element);
|
super($element, $);
|
||||||
this.$translate = $translate;
|
|
||||||
this.snackbar = $element[0].firstChild;
|
this.snackbar = $element[0].firstChild;
|
||||||
this.$snackbar = angular.element(this.snackbar);
|
this.$snackbar = angular.element(this.snackbar);
|
||||||
}
|
}
|
||||||
|
@ -19,38 +18,54 @@ export default class Controller extends Component {
|
||||||
* @return {Object} Created snackbar shape
|
* @return {Object} Created snackbar shape
|
||||||
*/
|
*/
|
||||||
createShape(data) {
|
createShape(data) {
|
||||||
let shape = document.createElement('div');
|
let shape = Object.assign({
|
||||||
shape.className = 'shape';
|
nMessages: 1
|
||||||
|
}, data);
|
||||||
|
|
||||||
|
let element = document.createElement('div');
|
||||||
|
element.className = 'shape';
|
||||||
|
setTimeout(() => element.classList.add('shown'), 30);
|
||||||
|
shape.element = element;
|
||||||
|
|
||||||
|
if (shape.type)
|
||||||
|
element.classList.add(shape.type);
|
||||||
|
|
||||||
let button = document.createElement('button');
|
let button = document.createElement('button');
|
||||||
|
button.addEventListener('click', () => this.onButtonClick(shape));
|
||||||
|
element.appendChild(button);
|
||||||
|
|
||||||
let buttonText = data.actionText || this.$translate.instant('Hide');
|
let buttonText = shape.actionText || this.$t('Hide');
|
||||||
buttonText = document.createTextNode(buttonText);
|
buttonText = document.createTextNode(buttonText);
|
||||||
button.appendChild(buttonText);
|
button.appendChild(buttonText);
|
||||||
|
|
||||||
button.addEventListener('click', () => {
|
|
||||||
this.onButtonClick(shape);
|
|
||||||
});
|
|
||||||
|
|
||||||
shape.appendChild(button);
|
|
||||||
|
|
||||||
let shapeText = document.createElement('div');
|
let shapeText = document.createElement('div');
|
||||||
shapeText.setAttribute('class', 'text');
|
shapeText.setAttribute('class', 'text');
|
||||||
shape.appendChild(shapeText);
|
element.appendChild(shapeText);
|
||||||
|
|
||||||
let text = document.createTextNode(data.message);
|
let text = document.createTextNode(shape.message);
|
||||||
shapeText.appendChild(text);
|
shapeText.appendChild(text);
|
||||||
|
|
||||||
if (data.shapeType)
|
let chip = document.createElement('vn-chip');
|
||||||
shape.classList.add(data.shapeType);
|
chip.className = 'warning small';
|
||||||
|
chip.style.visibility = 'hidden';
|
||||||
|
|
||||||
let parent = this.snackbar.querySelectorAll('.shape')[0];
|
let chipWrapper = document.createElement('div');
|
||||||
|
chip.append(chipWrapper);
|
||||||
|
|
||||||
|
let span = document.createElement('span');
|
||||||
|
chipWrapper.append(span);
|
||||||
|
|
||||||
|
let chipText = document.createTextNode(shape.nMessages);
|
||||||
|
span.append(chipText);
|
||||||
|
|
||||||
|
shapeText.appendChild(chip);
|
||||||
|
|
||||||
|
let parent = this.snackbar.querySelector('.shape');
|
||||||
|
|
||||||
if (parent)
|
if (parent)
|
||||||
this.snackbar.insertBefore(shape, parent);
|
this.snackbar.insertBefore(element, parent);
|
||||||
else
|
else
|
||||||
this.snackbar.appendChild(shape);
|
this.snackbar.appendChild(element);
|
||||||
|
|
||||||
|
|
||||||
return shape;
|
return shape;
|
||||||
}
|
}
|
||||||
|
@ -61,58 +76,28 @@ export default class Controller extends Component {
|
||||||
* @param {Object} data The message data
|
* @param {Object} data The message data
|
||||||
*/
|
*/
|
||||||
show(data) {
|
show(data) {
|
||||||
this.actionHandler = data.actionHandler;
|
let shape = this.lastShape;
|
||||||
|
|
||||||
let shape;
|
const isEqual = shape
|
||||||
|
&& shape.type == data.type
|
||||||
|
&& shape.message == data.message;
|
||||||
|
|
||||||
const lastShape = this.lastShape;
|
if (isEqual) {
|
||||||
const lastShapeData = lastShape && lastShape.data;
|
shape.nMessages++;
|
||||||
const isEqual = lastShape && (lastShapeData.shapeType == data.shapeType && lastShapeData.message == data.message);
|
|
||||||
|
|
||||||
if (lastShape && isEqual) {
|
const chip = shape.element.querySelector('.text vn-chip');
|
||||||
shape = lastShape.element;
|
chip.style.visibility = 'visible';
|
||||||
|
|
||||||
const shapeText = shape.querySelector('.text');
|
const span = chip.querySelector('span');
|
||||||
let chip = shapeText.querySelector('vn-chip');
|
span.innerHTML = shape.nMessages;
|
||||||
|
} else
|
||||||
if (chip) {
|
|
||||||
const text = chip.querySelector('span');
|
|
||||||
const number = parseInt(text.innerHTML);
|
|
||||||
|
|
||||||
text.innerHTML = number + 1;
|
|
||||||
} else {
|
|
||||||
chip = document.createElement('vn-chip');
|
|
||||||
chip.setAttribute('class', 'warning small');
|
|
||||||
let parent = document.createElement('div');
|
|
||||||
let span = document.createElement('span');
|
|
||||||
let text = document.createTextNode(1);
|
|
||||||
span.append(text);
|
|
||||||
parent.append(span);
|
|
||||||
chip.append(parent);
|
|
||||||
|
|
||||||
shapeText.appendChild(chip);
|
|
||||||
}
|
|
||||||
|
|
||||||
lastShape.element.classList.add('shown');
|
|
||||||
|
|
||||||
if (this.hideTimeout)
|
|
||||||
clearTimeout(this.hideTimeout);
|
|
||||||
} else {
|
|
||||||
shape = this.createShape(data);
|
shape = this.createShape(data);
|
||||||
|
|
||||||
setTimeout(() =>
|
clearTimeout(shape.hideTimeout);
|
||||||
shape.classList.add('shown'), 30);
|
shape.hideTimeout = setTimeout(
|
||||||
}
|
() => this.hide(shape), shape.timeout || 3000);
|
||||||
|
|
||||||
this.hideTimeout = setTimeout(() => {
|
this.lastShape = shape;
|
||||||
this.hide(shape);
|
|
||||||
this.lastShape = null;
|
|
||||||
}, data.timeout || 3000);
|
|
||||||
|
|
||||||
this.lastShape = {
|
|
||||||
data: data,
|
|
||||||
element: shape
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -121,8 +106,7 @@ export default class Controller extends Component {
|
||||||
* @param {Object} data The message data
|
* @param {Object} data The message data
|
||||||
*/
|
*/
|
||||||
showError(data) {
|
showError(data) {
|
||||||
data.shapeType = 'error';
|
data.type = 'error';
|
||||||
|
|
||||||
this.show(data);
|
this.show(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,8 +116,7 @@ export default class Controller extends Component {
|
||||||
* @param {Object} data The message data
|
* @param {Object} data The message data
|
||||||
*/
|
*/
|
||||||
showSuccess(data) {
|
showSuccess(data) {
|
||||||
data.shapeType = 'success';
|
data.type = 'success';
|
||||||
|
|
||||||
this.show(data);
|
this.show(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,8 +125,11 @@ export default class Controller extends Component {
|
||||||
* @param {Object} shape Snackbar element
|
* @param {Object} shape Snackbar element
|
||||||
*/
|
*/
|
||||||
hide(shape) {
|
hide(shape) {
|
||||||
setTimeout(() => shape.classList.remove('shown'), 30);
|
if (this.lastShape == shape)
|
||||||
setTimeout(() => shape.remove(), 250);
|
this.lastShape = null;
|
||||||
|
|
||||||
|
shape.element.classList.remove('shown');
|
||||||
|
setTimeout(() => shape.element.remove(), 250);
|
||||||
}
|
}
|
||||||
|
|
||||||
onSnackbarClick(event) {
|
onSnackbarClick(event) {
|
||||||
|
@ -151,13 +137,12 @@ export default class Controller extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
onButtonClick(shape) {
|
onButtonClick(shape) {
|
||||||
if (this.actionHandler)
|
if (shape.actionHandler)
|
||||||
this.actionHandler();
|
shape.actionHandler();
|
||||||
else
|
else
|
||||||
this.hide(shape);
|
this.hide(shape);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Controller.$inject = ['$element', '$translate'];
|
|
||||||
|
|
||||||
ngModule.component('vnSnackbar', {
|
ngModule.component('vnSnackbar', {
|
||||||
template: require('./snackbar.html'),
|
template: require('./snackbar.html'),
|
||||||
|
|
|
@ -2098,6 +2098,13 @@
|
||||||
"extend": "^3.0.1",
|
"extend": "^3.0.1",
|
||||||
"split-array-stream": "^2.0.0",
|
"split-array-stream": "^2.0.0",
|
||||||
"stream-events": "^1.0.4"
|
"stream-events": "^1.0.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"arrify": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@google-cloud/projectify": {
|
"@google-cloud/projectify": {
|
||||||
|
@ -2138,6 +2145,11 @@
|
||||||
"xdg-basedir": "^3.0.0"
|
"xdg-basedir": "^3.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"arrify": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0="
|
||||||
|
},
|
||||||
"mime": {
|
"mime": {
|
||||||
"version": "2.4.4",
|
"version": "2.4.4",
|
||||||
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
|
"resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
|
||||||
|
@ -3210,7 +3222,8 @@
|
||||||
"arrify": {
|
"arrify": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
|
||||||
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0="
|
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"asn1": {
|
"asn1": {
|
||||||
"version": "0.2.4",
|
"version": "0.2.4",
|
||||||
|
@ -7972,6 +7985,12 @@
|
||||||
"pinkie-promise": "^2.0.0"
|
"pinkie-promise": "^2.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"arrify": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"glob": {
|
"glob": {
|
||||||
"version": "7.1.4",
|
"version": "7.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
|
||||||
|
@ -8327,20 +8346,6 @@
|
||||||
"kind-of": "^1.1.0"
|
"kind-of": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"glob": {
|
|
||||||
"version": "7.1.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
|
|
||||||
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"jasmine": {
|
"jasmine": {
|
||||||
"version": "2.99.0",
|
"version": "2.99.0",
|
||||||
"resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.99.0.tgz",
|
"resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.99.0.tgz",
|
||||||
|
@ -8354,7 +8359,7 @@
|
||||||
},
|
},
|
||||||
"kind-of": {
|
"kind-of": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "http://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz",
|
||||||
"integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=",
|
"integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
@ -8382,9 +8387,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"xtend": {
|
"xtend": {
|
||||||
"version": "4.0.1",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||||
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
|
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9990,7 +9995,7 @@
|
||||||
},
|
},
|
||||||
"jasmine-core": {
|
"jasmine-core": {
|
||||||
"version": "2.99.1",
|
"version": "2.99.1",
|
||||||
"resolved": "http://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz",
|
"resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz",
|
||||||
"integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=",
|
"integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue