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