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 @@
-->
-
-
- - Cache Groups
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Name |
- Short Name |
- Type |
- 1st Parent |
- 2nd Parent |
- Latitude |
- Longitude |
-
-
-
-
- {{::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();
+ });
+ }
+ });
+ }
+});