This commit is contained in:
parent
77e8bbc2ce
commit
0bd09492d1
|
@ -65,15 +65,6 @@ let actions = {
|
||||||
},
|
},
|
||||||
|
|
||||||
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.clearInput(`vn-login vn-textfield[ng-model="$ctrl.user"]`);
|
|
||||||
await this.write(`vn-login vn-textfield[ng-model="$ctrl.user"]`, userName);
|
|
||||||
await this.clearInput(`vn-login vn-textfield[ng-model="$ctrl.password"]`);
|
|
||||||
await this.write(`vn-login vn-textfield[ng-model="$ctrl.password"]`, password);
|
|
||||||
await this.waitToClick('vn-login button[type=submit]');
|
|
||||||
},
|
|
||||||
|
|
||||||
login: async function(userName) {
|
|
||||||
let state = await this.getState();
|
let state = await this.getState();
|
||||||
|
|
||||||
if (state != 'login') {
|
if (state != 'login') {
|
||||||
|
@ -91,6 +82,16 @@ let actions = {
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.waitForState('login');
|
await this.waitForState('login');
|
||||||
|
|
||||||
|
await this.waitForSelector(`vn-login vn-textfield[ng-model="$ctrl.user"]`, {visible: true});
|
||||||
|
await this.clearInput(`vn-login vn-textfield[ng-model="$ctrl.user"]`);
|
||||||
|
await this.write(`vn-login vn-textfield[ng-model="$ctrl.user"]`, userName);
|
||||||
|
await this.clearInput(`vn-login vn-textfield[ng-model="$ctrl.password"]`);
|
||||||
|
await this.write(`vn-login vn-textfield[ng-model="$ctrl.password"]`, password);
|
||||||
|
await this.waitToClick('vn-login button[type=submit]');
|
||||||
|
},
|
||||||
|
|
||||||
|
login: async function(userName) {
|
||||||
await this.doLogin(userName);
|
await this.doLogin(userName);
|
||||||
await this.waitForState('home');
|
await this.waitForState('home');
|
||||||
},
|
},
|
||||||
|
@ -114,10 +115,11 @@ let actions = {
|
||||||
},
|
},
|
||||||
|
|
||||||
gotoState: async function(state, params) {
|
gotoState: async function(state, params) {
|
||||||
return await this.evaluate((state, params) => {
|
await this.evaluate((state, params) => {
|
||||||
let $state = angular.element(document.body).injector().get('$state');
|
let $state = angular.element(document.body).injector().get('$state');
|
||||||
return $state.go(state, params);
|
return $state.go(state, params);
|
||||||
}, state, params);
|
}, state, params);
|
||||||
|
await this.waitForSpinnerLoad();
|
||||||
},
|
},
|
||||||
|
|
||||||
waitForState: async function(state) {
|
waitForState: async function(state) {
|
||||||
|
@ -125,7 +127,7 @@ let actions = {
|
||||||
let $state = angular.element(document.body).injector().get('$state');
|
let $state = angular.element(document.body).injector().get('$state');
|
||||||
return !$state.transition && $state.is(state);
|
return !$state.transition && $state.is(state);
|
||||||
}, {}, state);
|
}, {}, state);
|
||||||
await this.waitForSpinnerLoad(state);
|
await this.waitForSpinnerLoad();
|
||||||
},
|
},
|
||||||
|
|
||||||
waitForTransition: async function() {
|
waitForTransition: async function() {
|
||||||
|
@ -181,6 +183,12 @@ let actions = {
|
||||||
}, selector, property);
|
}, selector, property);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getClassName: async function(selector) {
|
||||||
|
const element = await this.$(selector);
|
||||||
|
const handle = await element.getProperty('className');
|
||||||
|
return await handle.jsonValue();
|
||||||
|
},
|
||||||
|
|
||||||
waitPropertyLength: async function(selector, property, minLength) {
|
waitPropertyLength: async function(selector, property, minLength) {
|
||||||
await this.waitForFunction((selector, property, minLength) => {
|
await this.waitForFunction((selector, property, minLength) => {
|
||||||
const element = document.querySelector(selector);
|
const element = document.querySelector(selector);
|
||||||
|
@ -339,24 +347,42 @@ let actions = {
|
||||||
await this.waitFor(300);
|
await this.waitFor(300);
|
||||||
|
|
||||||
await this.evaluate(() => {
|
await this.evaluate(() => {
|
||||||
let hideButton = document.querySelector('#shapes .shown button');
|
let hideButton = document
|
||||||
|
.querySelector('vn-snackbar .shape.shown button');
|
||||||
if (hideButton)
|
if (hideButton)
|
||||||
return document.querySelector('#shapes .shown button').click();
|
return hideButton.click();
|
||||||
});
|
});
|
||||||
await this.waitFor('#shapes > .shape', {hidden: true});
|
await this.waitFor('vn-snackbar .shape.shown', {hidden: true});
|
||||||
|
},
|
||||||
|
|
||||||
|
waitForSnackbar: async function() {
|
||||||
|
const selector = 'vn-snackbar .shape.shown';
|
||||||
|
await this.waitForSelector(selector);
|
||||||
|
|
||||||
|
let message = await this.evaluate(selector => {
|
||||||
|
const shape = document.querySelector(selector);
|
||||||
|
const message = {
|
||||||
|
text: shape.querySelector('.text').innerText
|
||||||
|
};
|
||||||
|
|
||||||
|
const types = ['error', 'success'];
|
||||||
|
for (let type of types) {
|
||||||
|
if (shape.classList.contains(type)) {
|
||||||
|
message.type = type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}, selector);
|
||||||
|
|
||||||
|
await this.hideSnackbar();
|
||||||
|
return message;
|
||||||
},
|
},
|
||||||
|
|
||||||
waitForLastSnackbar: async function() {
|
waitForLastSnackbar: async function() {
|
||||||
const selector = 'vn-snackbar .shown .text';
|
const message = await this.waitForSnackbar();
|
||||||
|
return message.text;
|
||||||
await this.waitForSelector(selector);
|
|
||||||
let snackBarText = await this.evaluate(selector => {
|
|
||||||
const shape = document.querySelector(selector);
|
|
||||||
|
|
||||||
return shape.innerText;
|
|
||||||
}, selector);
|
|
||||||
await this.hideSnackbar();
|
|
||||||
return snackBarText;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
pickDate: async function(selector, date) {
|
pickDate: async function(selector, date) {
|
||||||
|
@ -438,7 +464,6 @@ let actions = {
|
||||||
.includes(searchValue.toLowerCase());
|
.includes(searchValue.toLowerCase());
|
||||||
}, {}, builtSelector, searchValue);
|
}, {}, builtSelector, searchValue);
|
||||||
|
|
||||||
await this.waitForMutation('.vn-drop-down', 'childList');
|
|
||||||
await this.waitFor('.vn-drop-down', {hidden: true});
|
await this.waitFor('.vn-drop-down', {hidden: true});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
export default {
|
export default {
|
||||||
globalItems: {
|
globalItems: {
|
||||||
applicationsMenuButton: '#apps',
|
applicationsMenuButton: '#apps',
|
||||||
|
userMenuButton: '#user',
|
||||||
|
logoutButton: '#logout',
|
||||||
applicationsMenuVisible: '.modules-menu',
|
applicationsMenuVisible: '.modules-menu',
|
||||||
clientsButton: '.modules-menu > li[ui-sref="client.index"]',
|
clientsButton: '.modules-menu > li[ui-sref="client.index"]',
|
||||||
itemsButton: '.modules-menu > li[ui-sref="item.index"]',
|
itemsButton: '.modules-menu > li[ui-sref="item.index"]',
|
||||||
|
@ -10,7 +12,6 @@ export default {
|
||||||
claimsButton: '.modules-menu > li[ui-sref="claim.index"]',
|
claimsButton: '.modules-menu > li[ui-sref="claim.index"]',
|
||||||
returnToModuleIndexButton: 'a[ui-sref="order.index"]',
|
returnToModuleIndexButton: 'a[ui-sref="order.index"]',
|
||||||
homeButton: 'vn-topbar > div.side.start > a',
|
homeButton: 'vn-topbar > div.side.start > a',
|
||||||
userMenuButton: '#user',
|
|
||||||
userLocalWarehouse: '.user-popover vn-autocomplete[ng-model="$ctrl.localWarehouseFk"]',
|
userLocalWarehouse: '.user-popover vn-autocomplete[ng-model="$ctrl.localWarehouseFk"]',
|
||||||
userLocalBank: '.user-popover vn-autocomplete[ng-model="$ctrl.localBankFk"]',
|
userLocalBank: '.user-popover vn-autocomplete[ng-model="$ctrl.localBankFk"]',
|
||||||
userLocalCompany: '.user-popover vn-autocomplete[ng-model="$ctrl.localCompanyFk"]',
|
userLocalCompany: '.user-popover vn-autocomplete[ng-model="$ctrl.localCompanyFk"]',
|
||||||
|
@ -338,8 +339,8 @@ export default {
|
||||||
},
|
},
|
||||||
itemDiary: {
|
itemDiary: {
|
||||||
secondTicketId: 'vn-item-diary vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(2) > span',
|
secondTicketId: 'vn-item-diary vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(2) > span',
|
||||||
|
fourthBalance: 'vn-item-diary vn-tbody > vn-tr:nth-child(4) > vn-td.balance > span',
|
||||||
firstBalance: 'vn-item-diary vn-tbody > vn-tr:nth-child(1) > vn-td.balance',
|
firstBalance: 'vn-item-diary vn-tbody > vn-tr:nth-child(1) > vn-td.balance',
|
||||||
fourthBalance: 'vn-item-diary vn-tbody > vn-tr:nth-child(4) > vn-td.balance',
|
|
||||||
warehouse: 'vn-item-diary vn-autocomplete[ng-model="$ctrl.warehouseFk"]',
|
warehouse: 'vn-item-diary vn-autocomplete[ng-model="$ctrl.warehouseFk"]',
|
||||||
},
|
},
|
||||||
itemLog: {
|
itemLog: {
|
||||||
|
@ -352,7 +353,7 @@ export default {
|
||||||
route: 'vn-ticket-summary vn-label-value[label="Route"] > section > span > span',
|
route: 'vn-ticket-summary vn-label-value[label="Route"] > section > span > span',
|
||||||
total: 'vn-ticket-summary vn-one.taxes > p:nth-child(3) > strong',
|
total: 'vn-ticket-summary vn-one.taxes > p:nth-child(3) > strong',
|
||||||
sale: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr',
|
sale: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr',
|
||||||
firstSaleItemId: 'vn-ticket-summary [name="sales"] vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > span',
|
firstSaleItemId: 'vn-ticket-summary [name="sales"] vn-table vn-tbody > :nth-child(1) > vn-td:nth-child(2) > span',
|
||||||
firstSaleDescriptorImage: '.vn-popover.shown vn-item-descriptor img',
|
firstSaleDescriptorImage: '.vn-popover.shown vn-item-descriptor img',
|
||||||
itemDescriptorPopover: '.vn-popover.shown vn-item-descriptor',
|
itemDescriptorPopover: '.vn-popover.shown vn-item-descriptor',
|
||||||
itemDescriptorPopoverItemDiaryButton: 'vn-item-descriptor a[href="#!/item/2/diary?warehouseFk=5&ticketFk=20"]',
|
itemDescriptorPopoverItemDiaryButton: 'vn-item-descriptor a[href="#!/item/2/diary?warehouseFk=5&ticketFk=20"]',
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import selectors from '../../helpers/selectors';
|
||||||
import getBrowser from '../../helpers/puppeteer';
|
import getBrowser from '../../helpers/puppeteer';
|
||||||
|
|
||||||
describe('Login path', async() => {
|
describe('Login path', async() => {
|
||||||
|
@ -13,41 +14,54 @@ describe('Login path', async() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Bad login', async() => {
|
describe('Bad login', async() => {
|
||||||
it('should receive an error when the username is incorrect', async() => {
|
it('should receive an error when the password is invalid', async() => {
|
||||||
await page.doLogin('badUser', '');
|
await page.doLogin('employee', 'badPassword');
|
||||||
const result = await page.waitForLastSnackbar();
|
const message = await page.waitForSnackbar();
|
||||||
const state = await page.getState();
|
const state = await page.getState();
|
||||||
|
|
||||||
expect(result.length).toBeGreaterThan(0);
|
expect(message.type).toBe('error');
|
||||||
|
expect(state).toBe('login');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should receive an error when the username is invalid', async() => {
|
||||||
|
await page.doLogin('badUser', '');
|
||||||
|
const message = await page.waitForSnackbar();
|
||||||
|
const state = await page.getState();
|
||||||
|
|
||||||
|
expect(message.type).toBe('error');
|
||||||
expect(state).toBe('login');
|
expect(state).toBe('login');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should receive an error when the username is blank', async() => {
|
it('should receive an error when the username is blank', async() => {
|
||||||
await page.doLogin('', '');
|
await page.doLogin('', '');
|
||||||
const result = await page.waitForLastSnackbar();
|
const message = await page.waitForSnackbar();
|
||||||
const state = await page.getState();
|
const state = await page.getState();
|
||||||
|
|
||||||
expect(result.length).toBeGreaterThan(0);
|
expect(message.type).toBe('error');
|
||||||
expect(state).toBe('login');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should receive an error when the 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');
|
expect(state).toBe('login');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Successful login', async() => {
|
describe('Successful login', async() => {
|
||||||
it('should log in', async() => {
|
it('should log in and go to home state', async() => {
|
||||||
await page.doLogin('employee', 'nightmare');
|
await page.doLogin('employee');
|
||||||
await page.waitForNavigation();
|
await page.waitFor('vn-home');
|
||||||
const state = await page.getState();
|
const state = await page.getState();
|
||||||
|
|
||||||
expect(state).toBe('home');
|
expect(state).toBe('home');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Logout', async() => {
|
||||||
|
it('should logout and return to login state', async() => {
|
||||||
|
await page.doLogin('employee');
|
||||||
|
|
||||||
|
await page.waitToClick(selectors.globalItems.userMenuButton);
|
||||||
|
await page.waitToClick(selectors.globalItems.logoutButton);
|
||||||
|
await page.waitFor('vn-login');
|
||||||
|
const state = await page.getState();
|
||||||
|
|
||||||
|
expect(state).toBe('login');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import selectors from '../../helpers/selectors';
|
import selectors from '../../helpers/selectors';
|
||||||
import getBrowser from '../../helpers/puppeteer';
|
import getBrowser from '../../helpers/puppeteer';
|
||||||
|
|
||||||
describe('Client create path', async() => {
|
describe('Client create path', () => {
|
||||||
let browser;
|
let browser;
|
||||||
let page;
|
let page;
|
||||||
|
|
||||||
beforeAll(async() => {
|
beforeAll(async() => {
|
||||||
browser = await getBrowser();
|
browser = await getBrowser();
|
||||||
page = browser.page;
|
page = browser.page;
|
||||||
|
@ -92,9 +93,9 @@ describe('Client create path', async() => {
|
||||||
await page.clearInput(selectors.createClientView.postcode);
|
await page.clearInput(selectors.createClientView.postcode);
|
||||||
await page.write(selectors.createClientView.postcode, '46000');
|
await page.write(selectors.createClientView.postcode, '46000');
|
||||||
await page.waitToClick(selectors.createClientView.createButton);
|
await page.waitToClick(selectors.createClientView.createButton);
|
||||||
const result = await page.waitForLastSnackbar();
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
expect(result).toEqual('Data saved!');
|
expect(message.type).toEqual('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should click on the Clients button of the top bar menu', async() => {
|
it('should click on the Clients button of the top bar menu', async() => {
|
||||||
|
|
|
@ -1,66 +1,30 @@
|
||||||
import selectors from '../../helpers/selectors.js';
|
import selectors from '../../helpers/selectors.js';
|
||||||
import getBrowser from '../../helpers/puppeteer';
|
import getBrowser from '../../helpers/puppeteer';
|
||||||
|
|
||||||
// #2026 Fallo en relocate de descriptor popover
|
describe('Ticket diary path', () => {
|
||||||
xdescribe('Ticket diary path', () => {
|
|
||||||
let browser;
|
|
||||||
let page;
|
let page;
|
||||||
|
|
||||||
beforeAll(async() => {
|
beforeAll(async() => {
|
||||||
browser = await getBrowser();
|
page = (await getBrowser()).page;
|
||||||
page = browser.page;
|
|
||||||
await page.loginAndModule('employee', 'ticket');
|
await page.loginAndModule('employee', 'ticket');
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async() => {
|
afterAll(async() => {
|
||||||
await browser.close();
|
await page.browser().close();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should search for a specific ticket', async() => {
|
it(`should navigate to item diary from ticket sale and check the lines`, async() => {
|
||||||
await page.write(selectors.ticketsIndex.topbarSearch, '1');
|
await page.accessToSearchResult('1');
|
||||||
await page.waitToClick(selectors.ticketsIndex.searchButton);
|
|
||||||
await page.waitForNumberOfElements(selectors.ticketsIndex.searchResult, 1);
|
|
||||||
const result = await page.countElement(selectors.ticketsIndex.searchResult);
|
|
||||||
|
|
||||||
expect(result).toEqual(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should click on the search result to access to the ticket summary`, async() => {
|
|
||||||
await page.waitForTextInElement(selectors.ticketsIndex.searchResult, 'Bat cave');
|
|
||||||
await page.waitToClick(selectors.ticketsIndex.searchResult);
|
|
||||||
let url = await page.expectURL('/summary'); // use waitForState instead
|
|
||||||
|
|
||||||
expect(url).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should navigate to the item diary from the 1st sale item id descriptor popover`, async() => {
|
|
||||||
await page.waitToClick(selectors.ticketSummary.firstSaleItemId);
|
await page.waitToClick(selectors.ticketSummary.firstSaleItemId);
|
||||||
await page.waitForTransitionEnd('.vn-popover');
|
|
||||||
await page.waitToClick(selectors.ticketSummary.popoverDiaryButton);
|
await page.waitToClick(selectors.ticketSummary.popoverDiaryButton);
|
||||||
let url = await page.expectURL('/diary'); // use waitForState instead
|
await page.waitForState('item.card.diary');
|
||||||
|
|
||||||
expect(url).toBe(true);
|
const secondIdClass = await page.getClassName(selectors.itemDiary.secondTicketId);
|
||||||
});
|
const fourthBalanceClass = await page.getClassName(selectors.itemDiary.fourthBalance);
|
||||||
|
const firstBalanceClass = await page.getClassName(selectors.itemDiary.firstBalance);
|
||||||
|
|
||||||
it(`should check the second line id is marked as message`, async() => {
|
expect(secondIdClass).toContain('message');
|
||||||
const result = await page
|
expect(fourthBalanceClass).toContain('message');
|
||||||
.waitToGetProperty(selectors.itemDiary.secondTicketId, 'className');
|
expect(firstBalanceClass).toContain('balance');
|
||||||
|
|
||||||
expect(result).toContain('message');
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should check the third line balance is marked as message`, async() => {
|
|
||||||
const result = await page
|
|
||||||
.waitToGetProperty(`${selectors.itemDiary.fourthBalance} > span`, 'className');
|
|
||||||
|
|
||||||
expect(result).toContain('message');
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should change to the warehouse two and check there are sales marked as negative balance`, async() => {
|
|
||||||
await page.autocompleteSearch(selectors.itemDiary.warehouse, 'Warehouse Two');
|
|
||||||
const result = await page
|
|
||||||
.waitToGetProperty(selectors.itemDiary.firstBalance, 'className');
|
|
||||||
|
|
||||||
expect(result).toContain('balance');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -45,8 +45,11 @@ export default class Auth {
|
||||||
}
|
}
|
||||||
|
|
||||||
login(user, password, remember) {
|
login(user, password, remember) {
|
||||||
if (!user)
|
if (!user) {
|
||||||
return this.$q.reject(new UserError('Please enter your username'));
|
let err = new UserError('Please enter your username');
|
||||||
|
err.code = 'EmptyLogin';
|
||||||
|
return this.$q.reject(err);
|
||||||
|
}
|
||||||
|
|
||||||
let params = {
|
let params = {
|
||||||
user,
|
user,
|
||||||
|
|
|
@ -181,6 +181,13 @@ function e2eSingleRun() {
|
||||||
return gulp.src(specFiles).pipe(jasmine({
|
return gulp.src(specFiles).pipe(jasmine({
|
||||||
errorOnFail: false,
|
errorOnFail: false,
|
||||||
timeout: 30000,
|
timeout: 30000,
|
||||||
|
config: {
|
||||||
|
random: false,
|
||||||
|
// TODO: Waiting for this option to be implemented
|
||||||
|
// https://github.com/jasmine/jasmine/issues/1533
|
||||||
|
stopSpecOnExpectationFailure: false
|
||||||
|
|
||||||
|
},
|
||||||
reporter: [
|
reporter: [
|
||||||
new SpecReporter({
|
new SpecReporter({
|
||||||
spec: {
|
spec: {
|
||||||
|
|
|
@ -3,6 +3,7 @@ vn-item-descriptor {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
img[ng-src] {
|
img[ng-src] {
|
||||||
|
min-height: 16em;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: block;
|
display: block;
|
||||||
|
|
Loading…
Reference in New Issue