#2026 Implemented & tests passed
gitea/salix/pipeline/head This commit looks good Details

This commit is contained in:
Juan Ferrer 2020-03-25 20:44:59 +01:00
parent 77e8bbc2ce
commit 0bd09492d1
8 changed files with 115 additions and 99 deletions

View File

@ -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});
},

View File

@ -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"]',

View File

@ -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');
});
});
});

View File

@ -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() => {

View File

@ -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');
});
});

View File

@ -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,

View File

@ -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: {

View File

@ -3,6 +3,7 @@ vn-item-descriptor {
display: block;
img[ng-src] {
min-height: 16em;
height: 100%;
width: 100%;
display: block;