diff --git a/CHANGELOG.md b/CHANGELOG.md index ef959871ba..1098d6d003 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ### Changed - [#7614](https://github.com/apache/trafficcontrol/pull/7614) *Traffic Ops* The database upgrade process no longer overwrites changes users may have made to the initially seeded data. - [#7832](https://github.com/apache/trafficcontrol/pull/7832) *t3c* Removed perl dependency +- Updated the CacheGroups Traffic Portal page to use a more performant AG-Grid-based table. ## [8.0.0] - 2023-09-20 ### Added diff --git a/traffic_ops/traffic_ops_golang/cachegroup/cachegroups.go b/traffic_ops/traffic_ops_golang/cachegroup/cachegroups.go index 2a729bbbc0..f96ba19ff8 100644 --- a/traffic_ops/traffic_ops_golang/cachegroup/cachegroups.go +++ b/traffic_ops/traffic_ops_golang/cachegroup/cachegroups.go @@ -1405,8 +1405,7 @@ func DeleteCacheGroup(w http.ResponseWriter, r *http.Request) { return } - alertMessage := fmt.Sprintf("%s was deleted.", ID) - alerts := tc.CreateAlerts(tc.SuccessLevel, alertMessage) + alerts := tc.CreateAlerts(tc.SuccessLevel, "cache group was deleted.") api.WriteAlerts(w, r, http.StatusOK, alerts) return } diff --git a/traffic_portal/app/src/common/modules/table/cacheGroups/TableCacheGroupsController.js b/traffic_portal/app/src/common/modules/table/cacheGroups/TableCacheGroupsController.js index 10ccff279f..473605a093 100644 --- a/traffic_portal/app/src/common/modules/table/cacheGroups/TableCacheGroupsController.js +++ b/traffic_portal/app/src/common/modules/table/cacheGroups/TableCacheGroupsController.js @@ -18,206 +18,249 @@ */ /** - * @param {*} cacheGroups + * @typedef CacheGroup + * @property {number} id + * @property {string} name + * @property {number} shortName + * @property {number} latitude + * @property {number} longitude + * @property {string} parentCachegroupName + * @property {string} secondaryParentCachegroupName + * @property {string} typeName + * @property {string} lastUpdated + */ + +/** + * @param {CacheGroup} cacheGroup + * @returns {string} + */ +const getHref = (cacheGroup) => `#!/cache-groups/${cacheGroup.id}`; + +/** + * @param {CacheGroup[]} cacheGroups * @param {*} $scope * @param {*} $state * @param {import("../../../service/utils/angular.ui.bootstrap").IModalService} $uibModal - * @param {import("angular").IWindowService} $window * @param {import("../../../service/utils/LocationUtils")} locationUtils * @param {import("../../../api/CacheGroupService")} cacheGroupService * @param {import("../../../models/MessageModel")} messageModel */ -var TableCacheGroupsController = function(cacheGroups, $scope, $state, $uibModal, $window, locationUtils, cacheGroupService, messageModel) { - - let cacheGroupsTable; +var TableCacheGroupsController = function ( + cacheGroups, + $scope, + $state, + $uibModal, + locationUtils, + cacheGroupService, + messageModel +) { + /**** Constants, scope data, etc. ****/ - var queueServerUpdates = function(cacheGroup, cdnId) { - cacheGroupService.queueServerUpdates(cacheGroup.id, cdnId); - }; + /** The columns of the ag-grid table */ + $scope.columns = [ + { + headerName: "Name", + field: "name", + hide: false, + }, + { + headerName: "Short Name", + field: "shortName", + hide: false, + }, + { + headerName: "Type", + field: "typeName", + hide: false, + }, + { + headerName: "1st Parent", + field: "parentCachegroupName", + hide: false, + }, + { + headerName: "2nd Parent", + field: "secondaryParentCachegroupName", + hide: false, + }, + { + headerName: "Latitude", + field: "latitude", + hide: false, + }, + { + headerName: "Longitude", + field: "longitude", + hide: false, + }, + { + headerName: "ID", + field: "id", + filter: "agNumberColumnFilter", + hide: true, + }, + { + headerName: "Last Updated", + field: "lastUpdated", + hide: true, + filter: "agDateColumnFilter", + }, + ]; - var clearServerUpdates = function(cacheGroup, cdnId) { - cacheGroupService.clearServerUpdates(cacheGroup.id, cdnId); - }; + /** @type {import("../agGrid/CommonGridController").CGC.DropDownOption[]} */ + $scope.dropDownOptions = [ + { + name: "createCacheGroupMenuItem", + href: "#!/cache-groups/new", + text: "Create New Cache Group", + type: 2, + }, + ]; - var deleteCacheGroup = function(cacheGroup) { - cacheGroupService.deleteCacheGroup(cacheGroup.id) - .then(function(result) { - messageModel.setMessages(result.alerts, false); - $scope.refresh(); - }); + /** Reloads all resolved data for the view. */ + $scope.refresh = () => { + $state.reload(); }; - var confirmQueueServerUpdates = function(cacheGroup) { - var params = { - title: 'Queue Server Updates: ' + cacheGroup.name, - message: "Please select a CDN" + /** + * Deletes a Cache Group if confirmation is given. + * @param {CacheGroup} cacheGroup + */ + function confirmDelete(cacheGroup) { + const params = { + title: `Delete Cache Group: ${cacheGroup.name}`, + key: cacheGroup.name, }; - var modalInstance = $uibModal.open({ - templateUrl: 'common/modules/dialog/select/dialog.select.tpl.html', - controller: 'DialogSelectController', - size: 'md', - resolve: { - params: function () { - return params; - }, - collection: function(cdnService) { - return cdnService.getCDNs(); - } - } - }); - modalInstance.result.then(function(cdn) { - queueServerUpdates(cacheGroup, cdn.id); - }, function () { - // do nothing + const modalInstance = $uibModal.open({ + templateUrl: "common/modules/dialog/delete/dialog.delete.tpl.html", + controller: "DialogDeleteController", + size: "md", + resolve: { params }, }); - }; + modalInstance.result + .then(() => { + cacheGroupService + .deleteCacheGroup(cacheGroup.id) + .then((result) => { + messageModel.setMessages(result.alerts, false); + $scope.refresh(); + }); + }) + .catch((e) => console.error("failed to delete Cache Group:", e)); + } - var confirmClearServerUpdates = function(cacheGroup) { - var params = { - title: 'Clear Server Updates: ' + cacheGroup.name, - message: "Please select a CDN" + /** + * Queues servers updates on a Cache Group if CDN is selected + * @param {CacheGroup} cacheGroup + */ + function confirmQueueServerUpdates(cacheGroup) { + const params = { + title: `Queue Server Updates: ${cacheGroup.name}`, + message: "Please select a CDN", }; - var modalInstance = $uibModal.open({ - templateUrl: 'common/modules/dialog/select/dialog.select.tpl.html', - controller: 'DialogSelectController', - size: 'md', + const modalInstance = $uibModal.open({ + templateUrl: "common/modules/dialog/select/dialog.select.tpl.html", + controller: "DialogSelectController", + size: "md", resolve: { - params: function () { - return params; - }, - collection: function(cdnService) { - return cdnService.getCDNs(); - } - } - }); - modalInstance.result.then(function(cdn) { - clearServerUpdates(cacheGroup, cdn.id); - }, function () { - // do nothing + params, + collection: (cdnService) => cdnService.getCDNs(), + }, }); - }; + modalInstance.result.then((cdn) => + cacheGroupService.queueServerUpdates(cacheGroup.id, cdn.id) + ); + } - var confirmDelete = function(cacheGroup) { - var params = { - title: 'Delete Cache Group: ' + cacheGroup.name, - key: cacheGroup.name + /** + * Clears servers updates on a Cache Group if confirmation is given. + * @param {CacheGroup} cacheGroup + */ + function confirmClearServerUpdates(cacheGroup) { + const params = { + title: `Clear Server Updates: ${cacheGroup.name}`, + message: "Please select a CDN", }; - var modalInstance = $uibModal.open({ - templateUrl: 'common/modules/dialog/delete/dialog.delete.tpl.html', - controller: 'DialogDeleteController', - size: 'md', + const modalInstance = $uibModal.open({ + templateUrl: "common/modules/dialog/select/dialog.select.tpl.html", + controller: "DialogSelectController", + size: "md", resolve: { - params: function () { - return params; - } - } + params, + collection: (cdnService) => cdnService.getCDNs(), + }, }); - modalInstance.result.then(function() { - deleteCacheGroup(cacheGroup); - }, function () { - // do nothing + modalInstance.result.then((cdn) => { + cacheGroupService.clearServerUpdates(cacheGroup.id, cdn.id); }); - }; - - - $scope.cacheGroups = cacheGroups; - - $scope.navigateToPath = (path, unsavedChanges) => locationUtils.navigateToPath(path, unsavedChanges); + } - $scope.columns = [ - { "name": "Name", "visible": true, "searchable": true }, - { "name": "Short Name", "visible": true, "searchable": true }, - { "name": "Type", "visible": true, "searchable": true }, - { "name": "1st Parent", "visible": true, "searchable": true }, - { "name": "2nd Parent", "visible": true, "searchable": true }, - { "name": "Latitude", "visible": true, "searchable": true }, - { "name": "Longitude", "visible": true, "searchable": true } - ]; - - $scope.contextMenuItems = [ + /** @type {import("../agGrid/CommonGridController").CGC.ContextMenuOption[]} */ + $scope.contextMenuOptions = [ { - text: 'Open in New Tab', - click: function ($itemScope) { - $window.open('/#!/cache-groups/' + $itemScope.cg.id, '_blank'); - } + getHref, + getText: (cacheGroup) => `Open ${cacheGroup.name} in a new tab`, + newTab: true, + type: 2, }, - null, // Dividier + { type: 0 }, { - text: 'Edit', - click: function ($itemScope) { - $scope.editCacheGroup($itemScope.cg.id); - } + getHref, + text: "Edit", + type: 2, }, { - text: 'Delete', - click: function ($itemScope) { - confirmDelete($itemScope.cg); - } + onClick: (cacheGroup) => confirmDelete(cacheGroup), + text: "Delete", + type: 1, }, - null, // Dividier + { type: 0 }, { - text: 'Queue Server Updates', - click: function ($itemScope) { - confirmQueueServerUpdates($itemScope.cg); - } + onClick: (cacheGroup) => confirmQueueServerUpdates(cacheGroup), + text: "Queue Server Updates", + type: 1, }, { - text: 'Clear Server Updates', - click: function ($itemScope) { - confirmClearServerUpdates($itemScope.cg); - } + onClick: (cacheGroup) => confirmClearServerUpdates(cacheGroup), + text: "Clear Server Updates", + type: 1, }, - null, // Dividier + { type: 0 }, { - text: 'Manage ASNs', - click: function ($itemScope) { - locationUtils.navigateToPath('/cache-groups/' + $itemScope.cg.id + '/asns'); - } + getHref: (cacheGroup) => `#!/cache-groups/${cacheGroup.id}/asns`, + text: "Manage ASNs", + type: 2, }, { - text: 'Manage Servers', - click: function ($itemScope) { - locationUtils.navigateToPath('/cache-groups/' + $itemScope.cg.id + '/servers'); - } - } + getHref: (cacheGroup) => `#!/cache-groups/${cacheGroup.id}/servers`, + text: "Manage Servers", + type: 2, + }, ]; - $scope.editCacheGroup = function(id) { - locationUtils.navigateToPath('/cache-groups/' + id); - }; - - $scope.createCacheGroup = function() { - locationUtils.navigateToPath('/cache-groups/new'); - }; - - $scope.refresh = function() { - $state.reload(); // reloads all the resolves for the view - }; - - $scope.toggleVisibility = function(colName) { - const col = cacheGroupsTable.column(colName + ':name'); - col.visible(!col.visible()); - cacheGroupsTable.rows().invalidate().draw(); + /** Options, configuration, data and callbacks for the ag-grid table. */ + /** @type {import("../agGrid/CommonGridController").CGC.GridSettings} */ + $scope.gridOptions = { + onRowClick: function (row) { + locationUtils.navigateToPath(`/cache-groups/${row.data.id}`); + }, }; - angular.element(document).ready(function () { - cacheGroupsTable = $('#cacheGroupsTable').DataTable({ - "aLengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]], - "iDisplayLength": 25, - "aaSorting": [], - "columns": $scope.columns, - "initComplete": function(settings, json) { - try { - // need to create the show/hide column checkboxes and bind to the current visibility - $scope.columns = JSON.parse(localStorage.getItem('DataTables_cacheGroupsTable_/')).columns; - } catch (e) { - console.error("Failure to retrieve required column info from localStorage (key=DataTables_cacheGroupsTable_/):", e); - } - } - }); - }); - + $scope.cacheGroups = cacheGroups.map((cacheGroup) => ({ + ...cacheGroup, + lastUpdated: new Date( + cacheGroup.lastUpdated.replace(" ", "T").replace("+00", "Z") + ), + })); }; -TableCacheGroupsController.$inject = ['cacheGroups', '$scope', '$state', '$uibModal', '$window', 'locationUtils', 'cacheGroupService', 'messageModel']; +TableCacheGroupsController.$inject = [ + "cacheGroups", + "$scope", + "$state", + "$uibModal", + "locationUtils", + "cacheGroupService", + "messageModel", +]; module.exports = TableCacheGroupsController; diff --git a/traffic_portal/app/src/common/modules/table/cacheGroups/table.cacheGroups.tpl.html b/traffic_portal/app/src/common/modules/table/cacheGroups/table.cacheGroups.tpl.html index a2d5726824..44ef006cbb 100644 --- a/traffic_portal/app/src/common/modules/table/cacheGroups/table.cacheGroups.tpl.html +++ b/traffic_portal/app/src/common/modules/table/cacheGroups/table.cacheGroups.tpl.html @@ -18,54 +18,14 @@ -->
-
- -
- - -
- - -
  • -
    - -
    -
  • -
    -
    -
    -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - -
    NameShort NameType1st Parent2nd ParentLatitudeLongitude
    {{::cg.name}}{{::cg.shortName}}{{::cg.typeName}}{{::cg.parentCachegroupName}}{{::cg.secondaryParentCachegroupName}}{{::cg.latitude}}{{::cg.longitude}}
    -
    + +
    diff --git a/traffic_portal/test/integration/Data/cachegroup.ts b/traffic_portal/test/integration/Data/cachegroup.ts index 92500b97fc..4a72d7c26d 100644 --- a/traffic_portal/test/integration/Data/cachegroup.ts +++ b/traffic_portal/test/integration/Data/cachegroup.ts @@ -27,22 +27,6 @@ export const cachegroups = { "password": "pa$$word" } ], - toggle:[ - { - description: "hide first table column", - Name: "1st Parent" - }, - { - description: "redisplay first table column", - Name: "1st Parent" - } - ], - check: [ - { - description: "check CSV link from CacheGroup page", - Name: "Export as CSV" - } - ], create: [ { Description: "create a EDGE_LOC cachegroup with FailOver CacheGroup Field", @@ -111,12 +95,12 @@ export const cachegroups = { { Description: "delete a cachegroup", Name: "TP_Cache1", - validationMessage: "was deleted" + validationMessage: "cache group was deleted." }, { Description: "delete a cachegroup", Name: "TP_Cache3", - validationMessage: "was deleted" + validationMessage: "cache group was deleted." } ] }, @@ -128,22 +112,6 @@ export const cachegroups = { "password": "pa$$word" } ], - toggle:[ - { - description: "hide first table column", - Name: "1st Parent" - }, - { - description: "display first table column", - Name: "1st Parent" - } - ], - check: [ - { - description: "check CSV link from CacheGroup page", - Name: "Export as CSV" - } - ], create: [ { Description: "create a CacheGroup", @@ -182,22 +150,6 @@ export const cachegroups = { "password": "pa$$word" } ], - toggle:[ - { - description: "hide first table column", - Name: "1st Parent" - }, - { - description: "display first table column", - Name: "1st Parent" - } - ], - check: [ - { - description: "check CSV link from CacheGroup page", - Name: "Export as CSV" - } - ], create: [ { Description: "create a EDGE_LOC cachegroup with FailOver CacheGroup Field", @@ -266,22 +218,22 @@ export const cachegroups = { { Description: "delete a cachegroup", Name: "TP_Cache2", - validationMessage: "was deleted" + validationMessage: "cache group was deleted." }, { Description: "delete a cachegroup", Name: "TP_Cache4", - validationMessage: "was deleted" + validationMessage: "cache group was deleted." }, { Description: "delete a cachegroup", Name: "TP_Cache5", - validationMessage: "was deleted" + validationMessage: "cache group was deleted." }, { Description: "delete a cachegroup", Name: "TP_Cache6", - validationMessage: "was deleted" + validationMessage: "cache group was deleted." } ] } diff --git a/traffic_portal/test/integration/PageObjects/CacheGroup.po.ts b/traffic_portal/test/integration/PageObjects/CacheGroup.po.ts index d4ebeb0e06..578e18503a 100644 --- a/traffic_portal/test/integration/PageObjects/CacheGroup.po.ts +++ b/traffic_portal/test/integration/PageObjects/CacheGroup.po.ts @@ -16,11 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -import { browser, by, element } from 'protractor'; +import { browser, by, element } from "protractor"; +import { SideNavigationPage } from "./SideNavigationPage.po"; import { randomize } from "../config"; -import { BasePage } from './BasePage.po'; -import { SideNavigationPage } from '../PageObjects/SideNavigationPage.po'; interface CreateCacheGroup { Type: string; @@ -37,133 +36,144 @@ interface UpdateCacheGroup { Type: string; FailoverCG?: string; } -export class CacheGroupPage extends BasePage { - private btnCreateCacheGroups = element(by.name('createCacheGroupButton')); - private txtName = element(by.name("name")) - private txtShortName = element(by.name("shortName")); - private txtType = element(by.name("type")); - private txtLatitude = element(by.name("latitude")); - private txtLongtitude = element(by.name("longitude")); - private txtParentCacheGroup = element(by.name("parentCacheGroup")); - private txtSecondaryParentCG = element(by.name("secondaryParentCacheGroup")); - private txtFailoverCG = element(by.name("fallbackOptions")); - private txtSearch = element(by.id('cacheGroupsTable_filter')).element(by.css('label input')); - private txtConfirmCacheGroupName = element(by.name("confirmWithNameInput")); - private btnDelete = element(by.buttonText('Delete')); - private randomize = randomize; - private btnTableColumn = element(by.className("caret")) + +export class CacheGroupPage extends SideNavigationPage { + private txtName = element(by.name("name")); + async OpenTopologyMenu() { - let snp = new SideNavigationPage(); - await snp.ClickTopologyMenu(); + await this.ClickTopologyMenu(); } + + /** + * Navigates the browser to the Cache Groups table page. + */ async OpenCacheGroupsPage() { - let snp = new SideNavigationPage(); - await snp.NavigateToCacheGroupsPage(); + await this.NavigateToCacheGroupsPage(); } - public async CreateCacheGroups(cachegroup: CreateCacheGroup, outputMessage: string): Promise { - let result = false - let basePage = new BasePage(); - if (cachegroup.Type == "EDGE_LOC") { - if (cachegroup.FailoverCG === undefined) { - throw new Error(`cachegroups with Type 'EDGE_LOC' must have FailoverCG`); - } - await this.btnCreateCacheGroups.click(); - await this.txtName.sendKeys(cachegroup.Name + this.randomize); - await this.txtShortName.sendKeys(cachegroup.ShortName + this.randomize); - await this.txtType.sendKeys(cachegroup.Type); - await this.txtLatitude.sendKeys(cachegroup.Latitude); - await this.txtLongtitude.sendKeys(cachegroup.Longitude); - await this.txtParentCacheGroup.sendKeys(cachegroup.ParentCacheGroup); - await this.txtSecondaryParentCG.sendKeys(cachegroup.SecondaryParentCG); - await this.txtFailoverCG.sendKeys(cachegroup.FailoverCG); - } else { - await this.btnCreateCacheGroups.click(); - await this.txtName.sendKeys(cachegroup.Name + this.randomize); - await this.txtShortName.sendKeys(cachegroup.ShortName + this.randomize); - await this.txtType.sendKeys(cachegroup.Type); - await this.txtLatitude.sendKeys(cachegroup.Latitude); - await this.txtLongtitude.sendKeys(cachegroup.Longitude); - await this.txtParentCacheGroup.sendKeys(cachegroup.ParentCacheGroup); - await this.txtSecondaryParentCG.sendKeys(cachegroup.SecondaryParentCG); + /** + * Creates a given Cache Group. + * + * @param cachegroup The CacheGroup to create. + * @param outputMessage The expected output message + * @returns Whether or not creation succeeded, which is judged by comparing + * the displayed Alert message to outputMessage - they must match + * *exactly*! + */ + public async CreateCacheGroups( + cachegroup: CreateCacheGroup, + outputMessage: string + ): Promise { + await this.OpenCacheGroupsPage(); + await element(by.buttonText("More")).click(); + await element(by.linkText("Create New Cache Group")).click(); + + if ( + cachegroup.Type == "EDGE_LOC" && + cachegroup.FailoverCG === undefined + ) { + throw new Error( + `cachegroups with Type 'EDGE_LOC' must have FailoverCG` + ); } - await basePage.ClickCreate(); - await basePage.GetOutputMessage().then(function (value) { - if (outputMessage == value) { - result = true; - } else { - result = false; - } - }) - return result; - } - public async SearchCacheGroups(nameCG: string): Promise { - let name = nameCG + this.randomize; - await this.txtSearch.clear(); - await this.txtSearch.sendKeys(name); - if (await browser.isElementPresent(element(by.xpath("//td[@data-search='^" + name + "$']"))) === true) { - await element(by.xpath("//td[@data-search='^" + name + "$']")).click(); - return true; + const actions = [ + this.txtName.sendKeys(cachegroup.Name + randomize), + element(by.name("shortName")).sendKeys(cachegroup.ShortName), + element(by.name("type")).sendKeys(cachegroup.Type), + element(by.name("latitude")).sendKeys(cachegroup.Latitude), + element(by.name("longitude")).sendKeys(cachegroup.Longitude), + element(by.name("parentCacheGroup")).sendKeys( + cachegroup.ParentCacheGroup + ), + element(by.name("secondaryParentCacheGroup")).sendKeys( + cachegroup.SecondaryParentCG + ), + ]; + + if (cachegroup.Type == "EDGE_LOC" && cachegroup.FailoverCG) { + actions.push( + element(by.name("fallbackOptions")).sendKeys( + cachegroup.FailoverCG + ) + ); } - return false; + + await Promise.all(actions); + await this.ClickCreate(); + return this.GetOutputMessage().then((v) => outputMessage === v); + } + + /** + * Searches the Cache Groups table for a specific Cache Group, and navigates to its details + * page. + * + * @param nameCG The Name of the Cache Group for which to search. + */ + public async SearchCacheGroups(nameCG: string): Promise { + nameCG += randomize; + await this.OpenCacheGroupsPage(); + const searchInput = element(by.id("quickSearch")); + await searchInput.clear(); + await searchInput.sendKeys(nameCG); + await element(by.cssContainingText("span", nameCG)).click(); } - public async UpdateCacheGroups(cachegroup: UpdateCacheGroup, outputMessage: string | undefined): Promise { + /** + * Updates a Cache Group's Name. + * + * @param cachegroup A definition of the CacheGroup renaming. + * @param outputMessage The expected output message + * @returns Whether or not renaming succeeded. + */ + public async UpdateCacheGroups( + cachegroup: UpdateCacheGroup, + outputMessage: string | undefined + ): Promise { let result: boolean | undefined = false; - let basePage = new BasePage(); - let snp = new SideNavigationPage(); if (cachegroup.Type == "EDGE_LOC") { - const name = cachegroup.FailoverCG + this.randomize; - await this.txtFailoverCG.click(); - if (await browser.isElementPresent(element(by.css(`select[name="fallbackOptions"] > option[label="${name}"]`)))) { - await element(by.css(`select[name="fallbackOptions"] > option[label="${name}"]`)).click(); + const name = cachegroup.FailoverCG + randomize; + await element(by.name("fallbackOptions")).click(); + if ( + await browser.isElementPresent( + element( + by.css( + `select[name="fallbackOptions"] > option[label="${name}"]` + ) + ) + ) + ) { + await element( + by.css( + `select[name="fallbackOptions"] > option[label="${name}"]` + ) + ).click(); } else { result = undefined; } } - await this.txtType.sendKeys(cachegroup.Type); - await snp.ClickUpdate(); + await element(by.name("type")).sendKeys(cachegroup.Type); + await this.ClickUpdate(); if (result !== undefined) { - await basePage.GetOutputMessage().then(function (value) { - if (outputMessage === value) { - result = true; - } else { - result = false; - } - }) + return (await this.GetOutputMessage()) === outputMessage; } - return result; } - public async DeleteCacheGroups(nameCG: string, outputMessage: string) { - let result = false; - let basePage = new BasePage(); - let snp = new SideNavigationPage(); - let name = nameCG + this.randomize; - await this.btnDelete.click(); - await this.txtConfirmCacheGroupName.sendKeys(name); - if (await basePage.ClickDeletePermanently() == true) { - result = await basePage.GetOutputMessage().then(function (value) { - if (value.indexOf(outputMessage) > -1) { - return true - } else { - return false; - } - }) - } else { - await basePage.ClickCancel(); - } - await snp.NavigateToCacheGroupsPage(); - return result; - } - public async CheckCSV(name: string): Promise { - return element(by.cssContainingText("span", name)).isPresent(); - } - public async ToggleTableColumn(name: string): Promise { - await this.btnTableColumn.click(); - const result = await element(by.cssContainingText("th", name)).isPresent(); - await element(by.cssContainingText("label", name)).click(); - await this.btnTableColumn.click(); - return !result; + + /** + * Deletes a Cache Group. + * + * @param nameCG The Name of the Cache Group to be deleted. + * @param outputMessage The expected output message + * @returns Whether or not the deletion succeeded. + */ + public async DeleteCacheGroups( + nameCG: string, + outputMessage: string + ): Promise { + nameCG += randomize; + await element(by.buttonText("Delete")).click(); + await element(by.name("confirmWithNameInput")).sendKeys(nameCG); + await this.ClickDeletePermanently(); + return (await this.GetOutputMessage()) === outputMessage; } } diff --git a/traffic_portal/test/integration/specs/CacheGroup.spec.ts b/traffic_portal/test/integration/specs/CacheGroup.spec.ts index b5e9ec9618..57aaddb654 100644 --- a/traffic_portal/test/integration/specs/CacheGroup.spec.ts +++ b/traffic_portal/test/integration/specs/CacheGroup.spec.ts @@ -16,80 +16,77 @@ * specific language governing permissions and limitations * under the License. */ -import { browser } from 'protractor'; +import { browser } from "protractor"; -import { LoginPage } from '../PageObjects/LoginPage.po' -import { CacheGroupPage } from '../PageObjects/CacheGroup.po'; -import { TopNavigationPage } from '../PageObjects/TopNavigationPage.po'; +import { LoginPage } from "../PageObjects/LoginPage.po"; +import { CacheGroupPage } from "../PageObjects/CacheGroup.po"; +import { TopNavigationPage } from "../PageObjects/TopNavigationPage.po"; import { cachegroups } from "../Data"; - - let loginPage = new LoginPage(); let topNavigation = new TopNavigationPage(); let cacheGroupPage = new CacheGroupPage(); -cachegroups.tests.forEach(cacheGroupData => { - describe(`Traffic Portal - CacheGroup - ${cacheGroupData.testName}`, () => { - cacheGroupData.logins.forEach(login => { - it('can login', async function () { +cachegroups.tests.forEach((cacheGroupData) => { + for (const login of cacheGroupData.logins) { + describe(`Traffic Portal - CacheGroup - ${cacheGroupData.testName}`, () => { + beforeAll(async () => { browser.get(browser.params.baseUrl); await loginPage.Login(login); expect(await loginPage.CheckUserName(login)).toBeTruthy(); - }) - it('can open cache group page', async function () { await cacheGroupPage.OpenTopologyMenu(); await cacheGroupPage.OpenCacheGroupsPage(); - }) - cacheGroupData.check.forEach(check => { - it(check.description, async () => { - expect(await cacheGroupPage.CheckCSV(check.Name)).toBe(true); - await cacheGroupPage.OpenCacheGroupsPage(); - }); }); - cacheGroupData.toggle.forEach(toggle => { - it(toggle.description, async () => { - if(toggle.description.includes('hide')){ - expect(await cacheGroupPage.ToggleTableColumn(toggle.Name)).toBe(false); - await cacheGroupPage.OpenCacheGroupsPage(); - }else{ - expect(await cacheGroupPage.ToggleTableColumn(toggle.Name)).toBe(true); - await cacheGroupPage.OpenCacheGroupsPage(); - } - + afterAll(async () => { + expect(await topNavigation.Logout()).toBeTruthy(); + }); + afterEach(async () => { + await cacheGroupPage.OpenCacheGroupsPage(); + }); + for (const create of cacheGroupData.create) { + it(create.Description, async () => { + expect( + await cacheGroupPage.CreateCacheGroups( + create, + create.validationMessage + ) + ).toBeTruthy(); }); - }) - cacheGroupData.create.forEach(create => { - it(create.Description, async function () { - expect(await cacheGroupPage.CreateCacheGroups(create, create.validationMessage)).toBeTruthy(); - await cacheGroupPage.OpenCacheGroupsPage(); - }) - }) - cacheGroupData.update.forEach(update => { + } + for (const update of cacheGroupData.update) { if (update.Description.includes("cannot")) { - it(update.Description, async function () { - await cacheGroupPage.SearchCacheGroups(update.Name) - expect(await cacheGroupPage.UpdateCacheGroups(update, update.validationMessage)).toBeUndefined(); - await cacheGroupPage.OpenCacheGroupsPage(); - }) + it(update.Description, async () => { + await cacheGroupPage.SearchCacheGroups(update.Name); + expect( + await cacheGroupPage.UpdateCacheGroups( + update, + update.validationMessage + ) + ).toBeUndefined(); + }); } else { - it(update.Description, async function () { - await cacheGroupPage.SearchCacheGroups(update.Name) - expect(await cacheGroupPage.UpdateCacheGroups(update, update.validationMessage)).toBeTruthy(); - await cacheGroupPage.OpenCacheGroupsPage(); - }) + it(update.Description, async () => { + await cacheGroupPage.SearchCacheGroups(update.Name); + expect( + await cacheGroupPage.UpdateCacheGroups( + update, + update.validationMessage + ) + ).toBeTruthy(); + }); } - - }) - cacheGroupData.remove.forEach(remove => { - it(remove.Description, async function () { - await cacheGroupPage.SearchCacheGroups(remove.Name) - expect(await cacheGroupPage.DeleteCacheGroups(remove.Name, remove.validationMessage)).toBeTruthy(); - }) - }) - it('can logout', async function () { - expect(await topNavigation.Logout()).toBeTruthy(); - }) - }) - }) -}) + } + for (const remove of cacheGroupData.remove) { + it(remove.Description, async () => { + await cacheGroupPage.SearchCacheGroups(remove.Name); + expect( + await cacheGroupPage.DeleteCacheGroups( + remove.Name, + remove.validationMessage + ) + ).toBeTruthy(); + }); + } + }); + } +});