@openveo/test
Version:
Test API for OpenVeo unit tests
1,873 lines (1,596 loc) • 69.2 kB
JavaScript
'use strict';
/**
* @module e2e/pages/TablePage
*/
var util = require('util');
var browserExt = process.requireTest('lib/e2e/browser.js');
var BackEndPage = process.requireTest('lib/e2e/pages/BackEndPage.js');
/**
* Defines a TablePage representing a back end page with a table and form to add an entity.
*
* Do not use this directly but extend it.
*
* @example
* var TablePage = require('@openveo/test').e2e.pages.TablePage;
*
* function MyTablePage() {
* MyTablePage.super_.call(this);
* this.path = 'be/myTablePage';
* }
*
* module.exports = MyTablePage;
* util.inherits(MyTablePage, TablePage);
*
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load().then(function() {
* console.log('Page fully loaded in the first language');
* });
*
* @class TablePage
* @extends module:e2e/pages/BackEndPage~BackEndPage
* @constructor
* @param {Object} provider Provider to interact directly with the database
*/
function TablePage(provider) {
TablePage.super_.call(this);
var tableSelector = '.datatable div[tasty-table] > table';
var addFormElement = element(by.css('.add-form'));
var addLinkElement = element(by.css('.add-element'));
var tableElement = element(by.css(tableSelector));
var dialogElement = element(by.css('.modal-dialog'));
var paginationElement = element(by.css('.pagination'));
var paginationLinkElements = paginationElement.all(by.css('li'));
Object.defineProperties(this,
/** @lends module:e2e/pages/TablePage~TablePage */
{
/**
* The entity provider.
*
* @type {Object}
* @instance
* @readonly
*/
provider: {value: provider},
/**
* Form element to add a new entity.
*
* @type {Object}
* @instance
* @readonly
*/
addFormElement: {value: addFormElement},
/**
* Link to open / close form element to add a new entity.
*
* @type {Object}
* @instance
* @readonly
*/
addLinkElement: {value: addLinkElement},
/**
* Wrapper of the add form element.
*
* This element will be displayed when add form is displayed and hidden when add form is closed.
*
* @type {Object}
* @instance
* @readonly
*/
addFormWrapperElement: {
value: addLinkElement.element(by.xpath('..')).all(by.css('div[uib-collapse="isCollapsed"]')).first()
},
/**
* Submit button of the form to add a new entity.
*
* @type {Object}
* @instance
* @readonly
*/
addButtonElement: {value: addFormElement.element(by.css('button'))},
/**
* Table element.
*
* @type {Object}
* @instance
* @readonly
*/
tableElement: {value: tableElement},
/**
* Table row elements.
*
* @type {Object}
* @instance
* @readonly
*/
rowElements: {value: element.all(by.css(tableSelector + ' > tbody > tr'))},
/**
* Table header elements.
*
* @type {Object}
* @instance
* @readonly
*/
headerElements: {value: element.all(by.css(tableSelector + ' > thead th'))},
/**
* Opened line detail containing information about the opened line.
*
* @type {Object}
* @instance
* @readonly
*/
lineDetailElement: {value: element(by.css(tableSelector + ' > tbody > tr.detail'))},
/**
* Checkbox to select all line.
*
* @type {Object}
* @instance
* @readonly
*/
selectAllElement: {value: element(by.css('.allactions input[type="checkbox"]'))},
/**
* Main action button element to perform actions on all selected lines.
*
* @type {Object}
* @instance
* @readonly
*/
actionsButtonElement: {value: element(by.css('.allactions button'))},
/**
* Element holding the list of actions under main action button.
*
* @type {Object}
* @instance
* @readonly
*/
actionsElement: {value: element(by.css('.allactions ul'))},
/**
* Dialog box.
*
* @type {Object}
* @instance
* @readonly
*/
dialogElement: {value: dialogElement},
/**
* Dialog box confirmation button.
*
* @type {Object}
* @instance
* @readonly
*/
dialogConfirmActionButtonElement: {value: dialogElement.element(by.css('.btn-primary'))},
/**
* Dialog box cancel button.
*
* @type {Object}
* @instance
* @readonly
*/
dialogCancelActionButtonElement: {value: dialogElement.element(by.css('.btn-warning'))},
/**
* Search engine form to filter lines in the table.
*
* @type {Object}
* @instance
* @readonly
*/
searchFormElement: {value: element(by.css('.search-fields'))},
/**
* Link to open / close search engine.
*
* @type {Object}
* @instance
* @readonly
*/
searchLinkElement: {value: element(by.css('.search-title'))},
/**
* Element holding the current table page (pagination).
*
* @type {Object}
* @instance
* @readonly
*/
currentPageElement: {value: element(by.exactBinding('pagination.page'))},
/**
* Element holding the total number of table pages (pagination).
*
* @type {Object}
* @instance
* @readonly
*/
totalPagesElement: {value: element(by.exactBinding('pagination.pages'))},
/**
* Element holding the total number of lines in all table pages (pagination).
*
* @type {Object}
* @instance
* @readonly
*/
totalLinesElement: {value: element(by.exactBinding('pagination.size'))},
/**
* Pagination links wrapper.
*
* @type {Object}
* @instance
* @readonly
*/
paginationElement: {value: element(by.css('.pagination'))},
/**
* List of pagination links, including the previous and next range buttons.
*
* @type {Object}
* @instance
* @readonly
*/
paginationLinkElements: {value: paginationLinkElements},
/**
* List of pagination links, excluding the previous and next range buttons.
*
* @type {Object}
* @instance
* @readonly
*/
paginationPageLinkElements: {value: paginationElement.all(by.repeater('numPage in rangePage')).all(by.css('a'))},
/**
* Pagination previous range link.
*
* @type {Object}
* @instance
* @readonly
*/
paginationPreviousRangeElement: {value: paginationLinkElements.first()},
/**
* Pagination next range link.
*
* @type {Object}
* @instance
* @readonly
*/
paginationNextRangeElement: {value: paginationLinkElements.last()},
/**
* List of per page links to select the number of elements to display per table page.
*
* @type {Object}
* @instance
* @readonly
*/
itemsPerPageLinkElements: {value: element.all(by.repeater('count in listItemsPerPageShow'))}
}
);
}
module.exports = TablePage;
util.inherits(TablePage, BackEndPage);
/**
* Finds a line.
*
* Iterate through the given list of lines to look for the expected one.
*
* @private
* @method getLineByIndex
* @memberof module:e2e/pages/TablePage~TablePage
* @this module:e2e/pages/TablePage~TablePage
* @param {Array} lines The list of line elements (tr elements) to look into
* @param {String} name The name of the line to look for (this value will be compared to the value of each cell)
* @param {Number} [index] The index in lines to start from
* @return {Promise} Promise resolving with the tr element
*/
function getLineByIndex(lines, name, index) {
index = index || 0;
var deferred = protractor.promise.defer();
var self = this;
if (index < lines.length && lines.length) {
var line = lines[index];
self.lineCellContain(line, name).then(function(contain) {
if (contain) {
// Line found
deferred.fulfill(line);
} else {
// Line not found
// Try next line
getLineByIndex.call(self, lines, name, ++index).then(function(elements) {
deferred.fulfill(elements);
}, function(error) {
deferred.reject(error);
});
}
});
} else
deferred.reject(new Error('No lines corresponding to ' + name));
return deferred.promise;
}
/**
* Finds a line by page.
*
* Iterate through all lines of all pages to look for the expected line.
* It starts at current page.
*
* @private
* @method getLineByPage
* @memberof module:e2e/pages/TablePage~TablePage
* @this module:e2e/pages/TablePage~TablePage
* @param {String} name The name of the line to look for (this value will be compared to the value of each cell)
* @param {Number} totalPages The total number of pages
* @return {Promise} Promise resolving with the searched line (tr element)
*/
function getLineByPage(name, totalPages) {
var self = this;
var deferred = protractor.promise.defer();
this.getLineInPage(name).then(function(line) {
// Line find in current page
deferred.fulfill(line);
}, function(error) {
// Line not found in current page
self.getCurrentPage().then(function(currentPage) {
if ((currentPage + 1) <= totalPages) {
// Got more pages
// Select next page
return self.selectPage(currentPage + 1).then(function() {
// Get line in page
return getLineByPage.call(self, name, totalPages);
});
} else {
// No more page, line has not been found
return protractor.promise.rejected(new Error('No lines corresponding to ' + name));
}
}).then(function(line) {
deferred.fulfill(line);
}, function(error) {
deferred.reject(error);
});
});
return deferred.promise;
}
/**
* Selects a page.
*
* Look for page link in pagination links, if page link is not in the pagination actual range, it will search for
* the page link in the other pagination ranges.
*
* @private
* @method selectPageByRange
* @memberof module:e2e/pages/TablePage~TablePage
* @this module:e2e/pages/TablePage~TablePage
* @param {String} page The page to select (starting at 1 instead of 0)
* @return {Promise} Promise resolving when the page is selected
*/
function selectPageByRange(page) {
var self = this;
var deferred = protractor.promise.defer();
// Filter the list of pagination links to get the link corresponding to the page
this.paginationPageLinkElements.filter(function(element, index) {
return element.all(by.css('span')).first().getText().then(function(text) {
return text.replace(/ ?\(current\)/, '') == page;
});
}).then(function(links) {
if (links.length) {
// Page link found
// Click on it
browserExt.click(links[0]).then(function() {
deferred.fulfill();
});
} else {
// Page link not found
self.isNextRangeLinkEnabled().then(function(isEnabled) {
if (isEnabled) {
// There is a next range
// Select next range
self.selectNextPageRange();
// Try to find the page in the next range
return selectPageByRange.call(self, page);
} else {
// Already in last range
// Page link not found
return protractor.promise.rejected(new Error('No page ' + page + ' found'));
}
}).then(function() {
deferred.fulfill();
}, function(error) {
deferred.reject(error);
});
}
});
return deferred.promise;
}
/**
* Gets the index of a table column in the list of columns.
*
* @private
* @method getHeaderIndex
* @memberof module:e2e/pages/TablePage~TablePage
* @this module:e2e/pages/TablePage~TablePage
* @param {String} name The name of the header to look for
* @return {Promise} Promise resolving with the index of the column
*/
function getHeaderIndex(name) {
var self = this;
return browser.waitForAngular().then(function() {
var deferred = protractor.promise.defer();
var headerIndex = -1;
self.headerElements.each(function(thElement, index) {
thElement.getText().then(function(text) {
if (text === name)
headerIndex = index;
});
}).then(function() {
if (headerIndex >= 0)
deferred.fulfill(headerIndex);
else
deferred.reject(new Error('Table header "' + name + '" not found'));
});
return deferred.promise;
});
}
/**
* Gets column value for a list of lines.
*
* Iterates through the given list of lines and find its value in the given column.
*
* @private
* @method getLineValuesByIndex
* @memberof module:e2e/pages/TablePage~TablePage
* @this module:e2e/pages/TablePage~TablePage
* @param {Array} lines The lines in the page (tr elements)
* @param {Number} headerIndex The index of the column to read
* @param {Number} [index=0] Current line index being inspected
* @return {Promise} Promise resolving with lines values
*/
function getLineValuesByIndex(lines, headerIndex, index) {
index = index || 0;
var self = this;
var deferred = protractor.promise.defer();
var values = [];
var line = lines[index];
self.getLineCellValue(line, headerIndex).then(function(text) {
values.push(text);
if ((index + 1) < lines.length) {
return getLineValuesByIndex.call(self, lines, headerIndex, ++index);
} else {
deferred.fulfill(values);
return protractor.promise.rejected(new Error('No more lines'));
}
}).then(function(newValues) {
values = values.concat(newValues);
deferred.fulfill(values);
}).then(null, function(error) {
// Nothing to do, promise is rejected but it's not an error
});
return deferred.promise;
}
/**
* Gets column and field values for a list of lines.
*
* Iterates through the given list of lines and get all information (column values and field values) for each line.
*
* @private
* @method getAllLineDetailsByIndex
* @memberof module:e2e/pages/TablePage~TablePage
* @this module:e2e/pages/TablePage~TablePage
* @param {Array} lines The lines in the page (tr elements)
* @param {Number} [index=0] Current line index being inspected
* @return {Promise} Promise resolving with values
*/
function getAllLineDetailsByIndex(lines, index) {
index = index || 0;
var self = this;
var deferred = protractor.promise.defer();
var datas = [];
var line = lines[index];
this.getLineDetails(line).then(function(details) {
datas.push(details);
if ((index + 1) < lines.length) {
// Got more lines
// Go to next line
return getAllLineDetailsByIndex.call(self, lines, ++index);
} else {
// No more lines
return protractor.promise.fulfilled();
}
}).then(function(newDatas) {
if (newDatas) datas = datas.concat(newDatas);
deferred.fulfill(datas);
});
return deferred.promise;
}
/**
* Gets line column values in all pages.
*
* Iterate through all lines of all pages and get column value for each line.
* It starts at current page.
*
* @private
* @method getLineValuesByPage
* @memberof module:e2e/pages/TablePage~TablePage
* @this module:e2e/pages/TablePage~TablePage
* @param {Number} headerIndex The index of the column to read
* @param {Number} totalPages The total number of pages
* @return {Promise} Promise resolving with column values
*/
function getLineValuesByPage(headerIndex, totalPages) {
var self = this;
var values = [];
var deferred = protractor.promise.defer();
this.getLinesInPage().then(function(lines) {
if (lines.length) {
// Found lines in the page
return getLineValuesByIndex.call(self, lines, headerIndex);
} else {
// No lines in the page
return deferred.reject(new Error('No lines'));
}
}).then(function(lineValuesInPage) {
// Got line values in the page
values = values.concat(lineValuesInPage);
return self.getCurrentPage();
}).then(function(currentPage) {
if ((currentPage + 1) <= totalPages) {
// Got more pages
// Select next page
return self.selectPage(currentPage + 1);
} else {
// No more pages
deferred.fulfill(values);
return protractor.promise.rejected(new Error('No more pages'));
}
}).then(function() {
// Next page selected
// Get all values in the page
return getLineValuesByPage.call(self, headerIndex, totalPages);
}).then(function(lineValuesInPage) {
values = values.concat(lineValuesInPage);
deferred.fulfill(values);
}).then(null, function(error) {
// Nothing to do, promise is rejected but it's not an error
});
return deferred.promise;
}
/**
* Gets line fields values in all pages.
*
* Iterate through all lines of all pages and get columns / fields values for each line.
* It starts at current page.
*
* @private
* @method getAllLineDetailsByPage
* @memberof module:e2e/pages/TablePage~TablePage
* @this module:e2e/pages/TablePage~TablePage
* @param {Number} totalPages The total number of pages
* @return {Promise} Promise resolving with values
*/
function getAllLineDetailsByPage(totalPages) {
var self = this;
var datas = [];
var deferred = protractor.promise.defer();
// Get all lines in the page
this.getLinesInPage().then(function(lines) {
if (lines.length) {
// Found lines in the page
// Get all information about each line
return getAllLineDetailsByIndex.call(self, lines);
} else {
// No lines in the page
return deferred.reject(new Error('No lines'));
}
}).then(function(datasInPage) {
// Got field datas in the page
datas = datas.concat(datasInPage);
return self.getCurrentPage();
}).then(function(currentPage) {
if ((currentPage + 1) <= totalPages) {
// Got more pages
// Select next page
return self.selectPage(currentPage + 1);
} else {
// No more pages
return protractor.promise.rejected(new Error('No more pages'));
}
}).then(function() {
// Next page selected
// Get all datas in the page
return getAllLineDetailsByPage.call(self, totalPages);
}).then(function(datasInPage) {
datas = datas.concat(datasInPage);
deferred.fulfill(datas);
}).then(null, function(error) {
if (error.message !== 'No more pages' && error.message !== 'No lines')
deferred.reject(error);
else
deferred.fulfill(datas);
});
return deferred.promise;
}
/**
* Gets all lines in the table page except the opened one.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.getLinesInPage().then(function(lines) {
* console.log(lines);
* });
*
* @return {Promise} Promise resolving with the list of lines elements in the page (tr elements)
*/
TablePage.prototype.getLinesInPage = function() {
var self = this;
return browser.waitForAngular().then(function() {
var deferred = protractor.promise.defer();
self.rowElements.filter(function(rowElement, index) {
return rowElement.getAttribute('class').then(function(classes) {
classes = classes.split(' ');
return classes.indexOf('detail') < 0;
});
}).then(function(lines) {
deferred.fulfill(lines);
}, function(error) {
deferred.reject(error);
});
return deferred.promise;
});
};
/**
* Gets a line within the current page.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.getLineInPage('My line').then(function(line) {
* console.log(line);
* });
*
* @param {String} name The name of the line to look for (each column will be compared to this value)
* @return {Promise} Promise resolving with the line (tr element)
*/
TablePage.prototype.getLineInPage = function(name) {
var self = this;
// Get all lines except opened ones
return this.getLinesInPage().then(function(lines) {
// Got all lines except opened lines
return getLineByIndex.call(self, lines, name);
});
};
/**
* Gets the number of lines in the current page.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.getLinesInPageNumber().then(function(linesNumber) {
* console.log('This page contains ' + linesNumber + ' lines');
* });
*
* @return {Promise} Promise resolving with the number of lines in the page
*/
TablePage.prototype.getLinesInPageNumber = function() {
return this.getLinesInPage().then(function(lines) {
return protractor.promise.fulfilled(lines.length);
});
};
/**
* Opens add form.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.openAddForm().then(function() {
* console.log('Add form opened');
* });
*
* @return {Promise} Promise resolving when add form is opened
*/
TablePage.prototype.openAddForm = function() {
var self = this;
return this.addFormWrapperElement.isDisplayed().then(function(isDisplayed) {
if (!isDisplayed) {
// Open add form
browserExt.click(self.addLinkElement);
return browser.wait(self.EC.visibilityOf(self.addFormWrapperElement), 1000, 'Missing add form');
} else {
// Add form is already displayed
return protractor.promise.fulfilled();
}
}).then(function() {
return protractor.promise.fulfilled();
});
};
/**
* Closes formular to add an item.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.openAddForm();
* page.closeAddForm().then(function() {
* console.log('Add form closed');
* });
*
* @return {Promise} Promise resolving when add form is closed
*/
TablePage.prototype.closeAddForm = function() {
var self = this;
return this.addFormWrapperElement.isDisplayed().then(function(isDisplayed) {
if (isDisplayed) {
// Close add form
browserExt.click(self.addLinkElement);
// Wait for the menu to be invisible
return browser.wait(self.EC.invisibilityOf(self.addFormWrapperElement), 1000, 'Add form still visible');
} else {
// Add form is already closed
return protractor.promise.fulfilled();
}
}).then(function() {
return protractor.promise.fulfilled();
});
};
/**
* Submit formular to add an item.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.submitAddForm().then(function() {
* console.log('Add form submitted');
* });
*
* @return {Promise} Promise resolving when add form submit button has been clicked
*/
TablePage.prototype.submitAddForm = function() {
return browserExt.click(this.addButtonElement);
};
/**
* Gets a line.
*
* Looks for a line in all pages.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.getLine('My line').then(function(line) {
* console.log(line);
* });
*
* @param {(String|Object)} lineFinder The name of the line (each column will be compared to this value) or
* the line element
* @return {Promise} Promise resolving with the line (tr element)
*/
TablePage.prototype.getLine = function(lineFinder) {
var self = this;
if (typeof lineFinder !== 'string')
return protractor.promise.fulfilled(lineFinder);
return browser.waitForAngular().then(function() {
var promises = [self.getCurrentPage(), self.getTotalPages()];
return protractor.promise.all(promises).then(function(values) {
var currentPage = values[0];
var totalPages = values[1];
if (totalPages) {
if (currentPage != 1)
self.selectPage(1);
return getLineByPage.call(self, lineFinder, totalPages);
} else {
return protractor.promise.rejected(new Error('No lines'));
}
});
});
};
/**
* Gets values of a column for all lines in all pages.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.getLineValues('Name').then(function(values) {
* console.log(values);
* });
*
* @param {String} headerTitle Title of the column to extract values from
* @return {Promise} Promise resolving with the list of values
*/
TablePage.prototype.getLineValues = function(headerTitle) {
var self = this;
return browser.waitForAngular().then(function() {
var currentPage;
var totalPages;
var promises = [self.getCurrentPage(), self.getTotalPages()];
return protractor.promise.all(promises).then(function(values) {
currentPage = values[0];
totalPages = values[1];
if (totalPages) {
if (currentPage != 1)
self.selectPage(1);
return getHeaderIndex.call(self, headerTitle);
} else {
return protractor.promise.rejected(new Error('No lines'));
}
}).then(function(headerIndex) {
return getLineValuesByPage.call(self, headerIndex, totalPages);
});
});
};
/**
* Gets values of a column for all lines in current page.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.getLineInPageValues('Name').then(function(values) {
* console.log(values);
* });
*
* @param {String} headerTitle Title of the column to extract values from
* @return {Promise} Promise resolving with the list of values
*/
TablePage.prototype.getLineInPageValues = function(headerTitle) {
var self = this;
return getHeaderIndex.call(this, headerTitle).then(function(headerIndex) {
return self.getLinesInPage().then(function(lines) {
if (lines.length) {
// Found lines in the page
return getLineValuesByIndex.call(self, lines, headerIndex);
} else {
// No lines in the page
return protractor.promise.rejected(new Error('No lines'));
}
});
});
};
/**
* Gets all column / fields values for all lines in all pages.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.getAllLineDetails().then(function(data) {
* console.log(data);
* });
*
* @return {Promise} Promise resolving with the list of line details
*/
TablePage.prototype.getAllLineDetails = function() {
var self = this;
return browser.waitForAngular().then(function() {
var promises = [self.getCurrentPage(), self.getTotalPages()];
var currentPage;
var totalPages;
return protractor.promise.all(promises).then(function(values) {
currentPage = values[0];
totalPages = values[1];
if (totalPages) {
if (currentPage != 1)
self.selectPage(1);
return getAllLineDetailsByPage.call(self, totalPages);
} else {
return protractor.promise.rejected(new Error('No lines'));
}
});
});
};
/**
* Gets all column / field values of a line.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.getLineDetails('My line').then(function(data) {
* console.log(data);
* });
*
* @param {(String|Object)} lineFinder The name of the line (each column will be compared to this value) or
* the line element
* @return {Promise} Promise resolving with the line details
*/
TablePage.prototype.getLineDetails = function(lineFinder) {
var self = this;
return browser.waitForAngular().then(function() {
var promises = [self.getLineCellValues(lineFinder), self.getLineFieldValues(lineFinder)];
return protractor.promise.all(promises);
}).then(function(values) {
return protractor.promise.fulfilled({
cells: values[0],
fields: values[1]
});
});
};
/**
* Gets all column values for a line.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.getLineCells('My line').then(function(data) {
* console.log(data);
* });
*
* @param {(String|Object)} lineFinder The name of the line (each column will be compared to this value) or
* the line element
* @return {Promise} Promise resolving with the line column values
*/
TablePage.prototype.getLineCells = function(lineFinder) {
var self = this;
return this.getLine(lineFinder).then(function(line) {
// Get all cell values
return self.getLineCellValues(line);
});
};
/**
* Gets all fields values for a line.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.getLineFieldValues('My line').then(function(data) {
* console.log(data);
* });
*
* @param {(String|Object)} lineFinder The name of the line (each column will be compared to this value) or
* the line element
* @return {Promise} Promise resolving with the line fields values
*/
TablePage.prototype.getLineFieldValues = function(lineFinder) {
var self = this;
var fieldValues = {};
var getFieldText = function(field, fieldName) {
return field.getText().then(function(text) {
fieldValues[fieldName] = text;
}, function(error) {
// Field couldn't be found, maybe it is hidden
fieldValues[fieldName] = null;
});
};
return this.getLine(lineFinder).then(function(line) {
var promises = [];
// Close any opened line
self.closeLine();
// Open line
self.openLine(line);
// Get all field values
var fields = self.getEditFormFields(self.lineDetailElement);
for (var fieldId in fields)
promises.push(getFieldText(fields[fieldId], fieldId));
return protractor.promise.all(promises);
}).then(function() {
return protractor.promise.fulfilled(fieldValues);
});
};
/**
* Opens a line.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.openLine('My line').then(function() {
* console.log('My line opened');
* });
*
* @param {(String|Object)} lineFinder The name of the line (each column will be compared to this value) or
* the line element
* @return {Promise} Promise resolving when line is opened
*/
TablePage.prototype.openLine = function(lineFinder) {
var self = this;
return this.getLine(lineFinder).then(function(line) {
// Click on the line to open it
browserExt.click(line.all(by.css('td')).get(1));
// Wait for the detail line
return browser.wait(self.EC.presenceOf(self.lineDetailElement), 5000, 'Missing opened line');
});
};
/**
* Closes opened line.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.closeLine('My line').then(function() {
* console.log('My line closed');
* });
*
* @return {Promise} Promise resolving when line is closed
*/
TablePage.prototype.closeLine = function() {
var self = this;
return browser.waitForAngular().then(function() {
var deferred = protractor.promise.defer();
var openedLineElement;
// Iterate on each line to find if one is an opened line
self.rowElements.each(function(rowElement, index) {
rowElement.getAttribute('class').then(function(classes) {
classes = classes.split(' ');
if (classes.indexOf('detail') >= 0) {
// Found an opened line
// Line is on the previous line because the detail is displayed in a new line
openedLineElement = self.rowElements.get(--index);
}
});
}).then(function() {
if (openedLineElement) {
// Close opened line
browserExt.click(openedLineElement.all(by.css('td')).get(1));
// Wait for the detail line to be closed
browser.wait(self.EC.stalenessOf(self.lineDetailElement), 5000, 'Line still opened').then(function() {
deferred.fulfill();
}, function(error) {
deferred.reject(error);
});
} else {
deferred.fulfill();
}
});
return deferred.promise;
});
};
/**
* Tests if a line is opened.
*
* As only one line can be opened at a time, no name is required.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.isOpenedLine().then(function(isOpened) {
* console.log('Is a line opened ? ' + isOpened);
* });
*
* @return {Promise} Promise resolving with a boolean indicating if a line is opened or not
*/
TablePage.prototype.isOpenedLine = function() {
var self = this;
return browser.waitForAngular().then(function() {
var deferred = protractor.promise.defer();
var isOpened = false;
// Iterate on each line to find if one is an opened line
self.rowElements.each(function(rowElement, index) {
rowElement.getAttribute('class').then(function(classes) {
classes = classes.split(' ');
if (classes.indexOf('detail') >= 0)
isOpened = true;
});
}).then(function() {
deferred.fulfill(isOpened);
});
return deferred.promise;
});
};
/**
* Tests if a line is selected.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.isSelectedLine('my line name').then(function(isSelected) {
* console.log('Is line selected ? ' + isSelected);
* });
*
* @param {(String|Object)} lineFinder The name of the line (each column will be compared to this value) or
* the line element
* @return {Promise} Promise resolving with a boolean indicating if line is selected or not
*/
TablePage.prototype.isSelectedLine = function(lineFinder) {
return this.getLine(lineFinder).then(function(line) {
// Check if line is selected
return browserExt.getProperty(line.element(by.css('input[type="checkbox"]')), 'checked');
});
};
/**
* Selects a line by checking the line checkbox.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.selectLine('My line').then(function() {
* console.log('My line is selected');
* });
*
* @param {(String|Object)} lineFinder The name of the line (each column will be compared to this value) or
* the line element
* @return {Promise} Promise resolving when line is selected
*/
TablePage.prototype.selectLine = function(lineFinder) {
var self = this;
return this.isSelectedLine(lineFinder).then(function(isSelected) {
if (isSelected) return protractor.promise.fulfilled();
return self.getLine(lineFinder).then(function(line) {
// Click on line checkbox
return browserExt.click(line.element(by.css('input[type="checkbox"]')));
});
});
};
/**
* Deselects a line by clicking on the line checkbox.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.deselectLine('My line').then(function() {
* console.log('My line is deselected');
* });
*
* @param {(String|Object)} lineFinder The name of the line (each column will be compared to this value) or
* the line element
* @return {Promise} Promise resolving when line is deselected
*/
TablePage.prototype.deselectLine = function(lineFinder) {
var self = this;
return this.isSelectedLine(lineFinder).then(function(isSelected) {
if (!isSelected) return protractor.promise.fulfilled();
return self.getLine(lineFinder).then(function(line) {
// Click on line checkbox
return browserExt.click(line.element(by.css('input[type="checkbox"]')));
});
});
};
/**
* Selects all lines.
*
* At least, one line must be in the table.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.selectAllLines().then(function() {
* console.log('All lines selected');
* });
*
* @return {Promise} Promise resolving when all lines are selected
*/
TablePage.prototype.selectAllLines = function() {
var self = this;
return browserExt.getProperty(this.selectAllElement, 'checked').then(function(isChecked) {
if (isChecked) return protractor.promise.fulfilled();
browserExt.click(self.selectAllElement);
return browser.wait(self.EC.visibilityOf(self.actionsButtonElement), 1000, 'Missing the global action button');
});
};
/**
* Sorts lines.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.sortBy('Name', true).then(function() {
* console.log('Lines sorted by Name');
* });
*
* @param {String} name The value of the column to act on, each column will be compared to this value
* @param {Boolean} asc true to sort in ascendant order, false to sort in descendant order
* @return {Promise} Promise resolving when column is clicked
*/
TablePage.prototype.sortBy = function(name, asc) {
var self = this;
return browser.waitForAngular().then(function() {
var deferred = protractor.promise.defer();
self.headerElements.filter(function(thElement, index) {
return thElement.getText().then(function(text) {
return text === name;
});
}).then(function(thElements) {
if (thElements.length) {
var thElement = thElements[0];
// Header found
thElement.element(by.className('glyphicon-triangle-bottom')).isPresent().then(function(isPresent) {
if ((isPresent && asc) || (!isPresent && !asc)) {
deferred.fulfill();
} else {
browserExt.click(thElement).then(function() {
deferred.fulfill();
}, function(error) {
deferred.reject(error);
});
}
});
} else {
deferred.reject(new Error('No header corresponding to ' + name));
}
});
return deferred.promise;
});
};
/**
* Performs an action on a single line.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.performAction('My line', 'Remove').then(function() {
* console.log('Action "Remove" has been performed on line "My line", confirmation dialog is opened');
* });
*
* mple
*
* page.performAction('My line', 'Remove', true).then(function() {
* console.log('"My line" removed');
* });
*
* @param {(String|Object)} lineFinder The name of the line (each column will be compared to this value) or
* the line element
* @param {String} action The translated name of the action to perform
* @param {Boolean} [confirm=false] true to confirm the action, false otherwise
* @return {Promise} Promise resolving when action is performed
*/
TablePage.prototype.performAction = function(lineFinder, action, confirm) {
var self = this;
return this.getLine(lineFinder).then(function(line) {
var actionTd = line.all(by.css('td')).last();
var actionButton = actionTd.element(by.css('button'));
var actionElement = actionTd.element(by.cssContainingText('a', action));
return actionElement.isDisplayed().then(function(isDisplayed) {
// Click on action button
if (!isDisplayed)
browserExt.click(actionButton);
// Click on the desired action
browserExt.click(actionElement);
if (confirm) {
browser.wait(self.EC.visibilityOf(self.dialogElement), 5000, 'Missing confirmation dialog');
return self.confirmAction();
} else
return protractor.promise.fulfilled();
});
});
};
/**
* Performs a grouped action.
*
* At least one line must be selected.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.selectAllLines();
* page.performMultipleAction('Remove').then(function() {
* console.log('Action "Remove" performed on all selected lines, confirmation dialog is opened');
* });
*
* mple
*
* page.performMultipleAction('Remove', true).then(function() {
* console.log('All lines removed');
* });
*
* @param {String} action The translated name of the action to perform
* @param {Boolean} [confirm=false] true to confirm the action, false otherwise
* @return {Promise} Promise resolving when the action is performed
*/
TablePage.prototype.performMultipleAction = function(action, confirm) {
var self = this;
return browserExt.click(this.actionsButtonElement).then(function() {
browser.wait(self.EC.visibilityOf(self.actionsElement), 1000, 'Missing the list of actions');
browserExt.click(self.actionsElement.element(by.cssContainingText('a', action)));
if (confirm) {
browser.wait(self.EC.visibilityOf(self.dialogElement), 5000, 'Missing confirmation dialog');
return self.confirmAction();
} else
return protractor.promise.fulfilled();
});
};
/**
* Accepts the confirmation dialog.
*
* Confirmation dialog must be displayed.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.selectAllLines();
* page.performMultipleAction('Remove');
* page.confirmAction().then(function() {
* console.Log('Dialog confirmed, thus all selected lines are removed');
* });
*
* @return {Promise} Promise resolving when confirmation dialog has been accepted
*/
TablePage.prototype.confirmAction = function() {
var self = this;
return browserExt.click(this.dialogConfirmActionButtonElement).then(function() {
return browser.wait(self.EC.stalenessOf(self.dialogElement), 5000, 'Dialog still visible');
}).then(function() {
return protractor.promise.fulfilled();
});
};
/**
* Cancels the confirmation dialog.
*
* Confirmation dialog must be displayed.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.selectAllLines();
* page.performMultipleAction('Remove');
* page.cancelAction().then(function() {
* console.Log('Remoe action canceled');
* });
*
* @return {Promise} Promise resolving when confirmation dialog has been canceled
*/
TablePage.prototype.cancelAction = function() {
var self = this;
return browserExt.click(this.dialogCancelActionButtonElement).then(function() {
return browser.wait(self.EC.stalenessOf(self.dialogElement), 1000, 'Dialog still visible');
}).then(function() {
return protractor.promise.fulfilled();
});
};
/**
* Gets the list of available actions for a line.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.getLineActions('My line').then(function(actions) {
* console.log(actions);
* });
*
* @param {(String|Object)} lineFinder The name of the line (each column will be compared to this value) or
* the line element
* @return {Promise} Promise resolving whith the list of actions
*/
TablePage.prototype.getLineActions = function(lineFinder) {
return this.getLine(lineFinder).then(function(line) {
var deferred = protractor.promise.defer();
var actions = [];
var actionElements;
var actionTd = line.all(by.css('td')).last();
var actionButton = actionTd.element(by.css('button'));
actionElements = actionTd.all(by.css('a'));
// Click on action button
browserExt.click(actionButton);
// Get action names
actionElements.each(function(actionElement, index) {
actionElement.getText().then(function(actionName) {
actions.push(actionName);
});
}).then(function() {
browserExt.click(actionButton);
}).then(function() {
deferred.fulfill(actions);
});
return deferred.promise;
});
};
/**
* Gets the list of global actions available.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.getGlobalActions().then(function(actions) {
* console.log(actions);
* });
*
* @return {Promise} Promise resolving whith the list of global actions
*/
TablePage.prototype.getGlobalActions = function() {
var self = this;
return this.selectAllLines().then(function() {
var deferred = protractor.promise.defer();
var actions = [];
var actionElements = self.actionsElement.all(by.css('a'));
browserExt.click(self.actionsButtonElement);
browser.wait(self.EC.visibilityOf(self.actionsElement), 1000, 'Missing the list of actions').then(function() {
// Get action names
actionElements.each(function(actionElement, index) {
actionElement.getText().then(function(actionName) {
actions.push(actionName);
});
}).then(function() {
deferred.fulfill(actions);
});
});
return deferred.promise;
});
};
/**
* Searches in the list of lines using search engine.
*
* Fills search fields.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
*
* var searchFieldsValues = {
* myField: 'Value'
* };
*
* page.search(searchFieldsValues).then(function() {
* console.Log('Search done');
* });
*
* @param {Object} fields List of values for fields returned by method getSearchFields
* @return {Promise} Promise resolving when search is done
*/
TablePage.prototype.search = function(values) {
var self = this;
return this.openSearchEngine().then(function() {
var promises = [];
var fields = self.getSearchFields(self.searchFormElement);
for (var fieldId in values)
promises.push(fields[fieldId].setValue(values[fieldId]));
return protractor.promise.all(promises);
});
};
/**
* Clears search fields.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.clearSearch().then(function() {
* console.Log('Search engine cleared');
* });
*
* @return {Promise} Promise resolving when fields are cleared
*/
TablePage.prototype.clearSearch = function() {
var self = this;
return this.openSearchEngine().then(function() {
var promises = [];
var fields = self.getSearchFields(self.searchFormElement);
for (var fieldId in fields)
promises.push(fields[fieldId].setValue());
return protractor.promise.all(promises);
});
};
/**
* Opens search engine.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.openSearchEngine().then(function() {
* console.log('Search engine opened');
* });
*
* @return {Promise} Promise resolving when search engine is opened
*/
TablePage.prototype.openSearchEngine = function() {
var self = this;
return this.searchFormElement.isDisplayed().then(function(isDisplayed) {
if (!isDisplayed) {
// Open search engine
browserExt.click(self.searchLinkElement);
return browser.wait(self.EC.visibilityOf(self.searchFormElement), 1000, 'Missing search form');
} else {
// Search engine is already displayed
return protractor.promise.fulfilled();
}
}).then(function() {
return protractor.promise.fulfilled();
});
};
/**
* Closes search engine.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.closeSearchEngine().then(function() {
* console.log('Search engine closed');
* });
*
* @return {Promise} Promise resolving when search engine is closed
*/
TablePage.prototype.closeSearchEngine = function() {
var self = this;
return this.searchFormElement.isDisplayed().then(function(isDisplayed) {
if (isDisplayed) {
// Close search engine
browserExt.click(self.searchLinkElement);
// Wait for the search engine to be invisible
return browser.wait(self.EC.invisibilityOf(self.searchFormElement), 1000, 'Search engine still visible');
} else {
// Search engine is already closed
return protractor.promise.fulfilled();
}
}).then(function() {
return protractor.promise.fulfilled();
});
};
/**
* Gets current page number.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.getCurrentPage().then(function(currentPage) {
* console.log('Current page is ' + currentPage);
* });
*
* @return {Promise} Promise resolving with the current page (starting at 1)
*/
TablePage.prototype.getCurrentPage = function() {
return this.currentPageElement.getText().then(function(currentPage) {
return protractor.promise.fulfilled(parseInt(currentPage));
});
};
/**
* Gets total number of pages.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.getTotalPages().then(function(totalPages) {
* console.log('There are ' + totalPages + ' pages');
* });
*
* @return {Promise} Promise resolving with the total number of pages
*/
TablePage.prototype.getTotalPages = function() {
return this.totalPagesElement.getText().then(function(totalPages) {
return protractor.promise.fulfilled(parseInt(totalPages));
});
};
/**
* Gets total number of lines.
*
* @example
* // With MyTablePage extending TablePage
* var page = new MyTablePage();
* page.logAsAdmin();
* page.load();
* page.getTotalLines()