ocket8888 commented on a change in pull request #5700:
URL: https://github.com/apache/trafficcontrol/pull/5700#discussion_r605989292



##########
File path: traffic_portal/test/integration/PageObjects/TopologiesPage.po.ts
##########
@@ -0,0 +1,192 @@
+import { browser, by, element } from 'protractor'

Review comment:
       missing license header

##########
File path: traffic_portal/test/integration/PageObjects/TopologiesPage.po.ts
##########
@@ -0,0 +1,192 @@
+import { browser, by, element } from 'protractor'
+import { BasePage } from './BasePage.po';
+import { SideNavigationPage } from './SideNavigationPage.po';
+
+interface TopologiesData {
+    description: string;
+    Name:string;
+    DescriptionData: string;
+    Type: string;
+    CacheGroup: string;
+    validationMessage: string;
+}
+export class TopologiesPage extends BasePage {
+    private btnCreateNewTopologies = element(by.xpath("//button[@title='Create 
Topology']"));
+    private txtCacheGroupType = element(by.name('selectFormDropdown'));
+    private txtSearch = 
element(by.id('topologiesTable_filter')).element(by.css('label input'));
+    private txtName = element(by.name('name'));
+    private txtDescription = element(by.id('description'));
+    private btnAddCacheGroup = element(by.xpath("//a[@title='Add child cache 
groups to TOPOLOGY']"));
+    private txtSearchCacheGroup = 
element(by.id('availableCacheGroupsTable_filter')).element(by.css('label 
input'));
+    private btnDelete = element(by.xpath("//button[text()='Delete']"));
+    private txtConfirmName = element(by.name('confirmWithNameInput'));
+    private config = require('../config');
+    private randomize = this.config.randomize;
+    async OpenTopologiesPage(){
+        let snp = new SideNavigationPage();
+        await snp.NavigateToTopologiesPage();
+    }
+    async OpenTopologyMenu(){
+        let snp = new SideNavigationPage();
+        await snp.ClickTopologyMenu();
+    }
+    async CreateTopologies(topologies:TopologiesData){
+        let result = false;
+        let basePage = new BasePage();
+        let snp = new SideNavigationPage();
+        await snp.NavigateToTopologiesPage();
+        //click '+'
+        await this.btnCreateNewTopologies.click();
+        await this.txtName.sendKeys(topologies.Name + this.randomize)
+        await this.txtDescription.sendKeys(topologies.DescriptionData + 
this.randomize)
+        //click add cache group +
+        await this.btnAddCacheGroup.click();
+        //choose type
+        await this.txtCacheGroupType.sendKeys(topologies.Type);
+        await basePage.ClickSubmit();
+        //choose Cachegroup
+        await this.txtSearchCacheGroup.sendKeys(topologies.CacheGroup + 
this.randomize)
+        if(await browser.isElementPresent(by.xpath("//td[@data-search='^" + 
topologies.CacheGroup + this.randomize + "$']")) === true){
+            await element(by.xpath("//td[@data-search='^" + 
topologies.CacheGroup + this.randomize + "$']")).click();
+        }
+        if(await basePage.ClickSubmit() == false){
+            result = undefined;
+            await snp.NavigateToTopologiesPage();
+            throw new Error('Test '+topologies.description+' Failed because 
cannot click on Submit button');
+        }
+        if(result != undefined){
+            if(await basePage.ClickCreate() == false){
+                result = undefined;
+                await snp.NavigateToTopologiesPage();
+                throw new Error('Test '+topologies.description+' Failed 
because cannot click on Create button');
+            }else{
+                result = await basePage.GetOutputMessage().then(value => value 
=== topologies.validationMessage);
+                if (topologies.description == 'create a Topologies with empty 
cachegroup (no server)'){
+                    result = await basePage.GetOutputMessage().then(value => 
value.includes(topologies.validationMessage));
+                }
+            }
+            return result;
+        }
+    }
+       
+    async SearchTopologies(nameTopologies:string){
+        let name = nameTopologies + this.randomize;
+        let result = false;
+        let snp = new SideNavigationPage();
+        await snp.NavigateToTopologiesPage();
+        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();
+            result = true;
+        } else {
+            result = undefined;
+        }
+        return result;
+    }
+    async UpdateTopologies(topologies){

Review comment:
       Do we know the type of this argument?

##########
File path: traffic_portal/test/integration/specs/Topologies.spec.ts
##########
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { browser } from 'protractor';
+import { LoginPage } from '../PageObjects/LoginPage.po';
+import { TopologiesPage } from '../PageObjects/TopologiesPage.po';
+import { TopNavigationPage } from '../PageObjects/TopNavigationPage.po';
+import  * as using  from "jasmine-data-provider";
+import { readFileSync } from "fs"
+import { API } from '../CommonUtils/API';
+
+const api = new API();
+const testFile = 'Data/Topologies/TestCases.json';
+const setupFile = 'Data/Topologies/Setup.json';
+const cleanupFile = 'Data/Topologies/Cleanup.json';
+const testData = JSON.parse(readFileSync(testFile,'utf-8'));
+const loginPage = new LoginPage();
+const topologiesPage = new TopologiesPage();
+const topNavigation = new TopNavigationPage();
+
+describe('Setup prereq for Topologies Test', function(){
+    it('Setup', async function(){
+        let setupData = JSON.parse(readFileSync(setupFile,'utf-8'));
+        let output = await api.UseAPI(setupData);
+        expect(output).toBeNull();
+    })
+})
+
+using(testData.Topologies, async function(topologiesData){
+    using(topologiesData.Login, function(login){
+        describe('Traffic Portal - Topologies - ' + login.description, 
function(){
+            it('can login', async function(){
+                browser.get(browser.params.baseUrl);
+                await loginPage.Login(login);
+                expect(await loginPage.CheckUserName(login)).toBeTruthy();
+            })
+            it('can open topologies page', async function(){
+                await topologiesPage.OpenTopologyMenu();
+                await topologiesPage.OpenTopologiesPage();
+            })
+            using(topologiesData.Add, function (add) {
+                it(add.description, async function () {
+                    expect(await 
topologiesPage.CreateTopologies(add)).toBeTruthy();
+                    await topologiesPage.OpenTopologiesPage();
+                })
+            })
+            it('can logout', async function(){
+                expect(await topNavigation.Logout()).toBeTruthy();
+            })
+        
+        })
+    })
+})
+
+describe('Clean up prereq and test data for Topologies Test', function () {
+    it('Cleanup', async function () {
+        let cleanupData = JSON.parse(readFileSync(cleanupFile,'utf-8'));
+        let output = await api.UseAPI(cleanupData);
+        expect(output).toBeNull();
+    })
+})

Review comment:
       missing newline at EOF

##########
File path: traffic_portal/test/integration/PageObjects/TopologiesPage.po.ts
##########
@@ -0,0 +1,192 @@
+import { browser, by, element } from 'protractor'
+import { BasePage } from './BasePage.po';
+import { SideNavigationPage } from './SideNavigationPage.po';
+
+interface TopologiesData {
+    description: string;
+    Name:string;
+    DescriptionData: string;
+    Type: string;
+    CacheGroup: string;
+    validationMessage: string;
+}
+export class TopologiesPage extends BasePage {
+    private btnCreateNewTopologies = element(by.xpath("//button[@title='Create 
Topology']"));
+    private txtCacheGroupType = element(by.name('selectFormDropdown'));
+    private txtSearch = 
element(by.id('topologiesTable_filter')).element(by.css('label input'));
+    private txtName = element(by.name('name'));
+    private txtDescription = element(by.id('description'));
+    private btnAddCacheGroup = element(by.xpath("//a[@title='Add child cache 
groups to TOPOLOGY']"));
+    private txtSearchCacheGroup = 
element(by.id('availableCacheGroupsTable_filter')).element(by.css('label 
input'));
+    private btnDelete = element(by.xpath("//button[text()='Delete']"));
+    private txtConfirmName = element(by.name('confirmWithNameInput'));
+    private config = require('../config');
+    private randomize = this.config.randomize;
+    async OpenTopologiesPage(){
+        let snp = new SideNavigationPage();
+        await snp.NavigateToTopologiesPage();
+    }
+    async OpenTopologyMenu(){
+        let snp = new SideNavigationPage();
+        await snp.ClickTopologyMenu();
+    }
+    async CreateTopologies(topologies:TopologiesData){
+        let result = false;
+        let basePage = new BasePage();
+        let snp = new SideNavigationPage();
+        await snp.NavigateToTopologiesPage();
+        //click '+'
+        await this.btnCreateNewTopologies.click();
+        await this.txtName.sendKeys(topologies.Name + this.randomize)
+        await this.txtDescription.sendKeys(topologies.DescriptionData + 
this.randomize)
+        //click add cache group +
+        await this.btnAddCacheGroup.click();
+        //choose type
+        await this.txtCacheGroupType.sendKeys(topologies.Type);
+        await basePage.ClickSubmit();
+        //choose Cachegroup
+        await this.txtSearchCacheGroup.sendKeys(topologies.CacheGroup + 
this.randomize)
+        if(await browser.isElementPresent(by.xpath("//td[@data-search='^" + 
topologies.CacheGroup + this.randomize + "$']")) === true){
+            await element(by.xpath("//td[@data-search='^" + 
topologies.CacheGroup + this.randomize + "$']")).click();
+        }
+        if(await basePage.ClickSubmit() == false){
+            result = undefined;
+            await snp.NavigateToTopologiesPage();
+            throw new Error('Test '+topologies.description+' Failed because 
cannot click on Submit button');
+        }
+        if(result != undefined){
+            if(await basePage.ClickCreate() == false){
+                result = undefined;
+                await snp.NavigateToTopologiesPage();
+                throw new Error('Test '+topologies.description+' Failed 
because cannot click on Create button');
+            }else{
+                result = await basePage.GetOutputMessage().then(value => value 
=== topologies.validationMessage);
+                if (topologies.description == 'create a Topologies with empty 
cachegroup (no server)'){
+                    result = await basePage.GetOutputMessage().then(value => 
value.includes(topologies.validationMessage));
+                }
+            }
+            return result;
+        }
+    }
+       
+    async SearchTopologies(nameTopologies:string){
+        let name = nameTopologies + this.randomize;
+        let result = false;
+        let snp = new SideNavigationPage();
+        await snp.NavigateToTopologiesPage();
+        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();
+            result = true;
+        } else {
+            result = undefined;
+        }
+        return result;
+    }
+    async UpdateTopologies(topologies){
+        let result = false;
+        let basePage = new BasePage();
+        let snp = new SideNavigationPage();
+        if(topologies.Type != undefined){
+             //click add cache group +
+            await this.btnAddCacheGroup.click();
+            //choose type
+            await this.txtCacheGroupType.sendKeys(topologies.Type);
+            await basePage.ClickSubmit();
+            await this.txtSearchCacheGroup.sendKeys(topologies.CacheGroup + 
this.randomize)
+            await element(by.xpath("//td[@data-search='^" + 
topologies.CacheGroup + this.randomize + "$']")).click();
+            if(await basePage.ClickSubmit() == false){
+                result = undefined;
+            }
+        }
+        //if TypeChild is not empty
+        if(topologies.TypeChild != undefined){
+            //add cachegroup child to cachegroup
+            await element(by.xpath("//a[@title='Add child cache groups to " + 
topologies.CacheGroup + this.randomize + "']//i[1]")).click();
+            //choose type
+            await this.txtCacheGroupType.sendKeys(topologies.TypeChild);
+            //if cannot click submit return undefined
+            if(await basePage.ClickSubmit() == false ){
+                result = undefined;
+            }else{
+                //search and send in cachegroup child then click submit
+                await 
this.txtSearchCacheGroup.sendKeys(topologies.CacheGroupChild + this.randomize)
+                await element(by.xpath("//td[@data-search='^" + 
topologies.CacheGroupChild + this.randomize + "$']")).click();
+                await basePage.ClickSubmit(); 
+                if(topologies.TypeGrandChild != undefined){
+                    //add grandchild to cachegroup
+                    await element(by.xpath("//a[@title='Add child cache groups 
to " + topologies.CacheGroupChild + this.randomize + "']//i[1]")).click();
+                    //choose type
+                    await 
this.txtCacheGroupType.sendKeys(topologies.TypeGrandChild);
+                      //if cannot click submit return undefined
+                    if(await basePage.ClickSubmit() == false ){
+                        result = undefined;
+                    }else{
+                        //search and send in cachegroup grandchild then click 
submit
+                        await 
this.txtSearchCacheGroup.sendKeys(topologies.CacheGroupGrandChild + 
this.randomize)
+                        await element(by.xpath("//td[@data-search='^" + 
topologies.CacheGroupGrandChild + this.randomize + "$']")).click();
+                        await basePage.ClickSubmit(); 
+                        await basePage.ClickNo();
+                    }
+                }
+            }
+        }
+        if(topologies.CacheGroupNeedSP != undefined){
+            if(await element(by.xpath("//a[@title='Set Secondary Parent Cache 
Group for " + topologies.CacheGroupNeedSP + this.randomize + 
"']")).isDisplayed() == true){
+                await element(by.xpath("//a[@title='Set Secondary Parent Cache 
Group for " + topologies.CacheGroupNeedSP + this.randomize + "']")).click();
+                await 
this.txtCacheGroupType.sendKeys(topologies.SecondaryParent + this.randomize );
+                if(await basePage.ClickSubmit() == false){
+                    result = undefined;
+                }
+            }else{
+                result = undefined;
+            }
+        }
+         //message check
+        //if result in the beginning is not undefined
+        if(result != undefined){
+            if(await basePage.ClickUpdate() == false){
+                result = undefined;
+                await snp.NavigateToTopologiesPage();
+            }else{
+                result = await basePage.GetOutputMessage().then(function 
(value) {
+                    if (topologies.validationMessage == value) {
+                        return true;
+                    } else {
+                        return false;
+                    }
+                })
+                if(topologies.validationWarning == true){
+                    let warningMessage = ""+topologies.Type+"-typed cachegroup 
"+topologies.CacheGroup+this.randomize+" is a parent of 
"+topologies.CacheGroupChild+this.randomize+", unexpected behavior may result"
+                    result = await basePage.GetOutputWarning().then(function 
(value) {
+                        if ( warningMessage == value) {
+                            return true;
+                        } else {
+                            return false;
+                        }
+                    })
+
+                }
+            }
+            return result;
+        }
+        
+    }
+    async DeleteTopologies(topologies){

Review comment:
       same as above RE typing

##########
File path: traffic_portal/test/integration/PageObjects/TopologiesPage.po.ts
##########
@@ -0,0 +1,192 @@
+import { browser, by, element } from 'protractor'
+import { BasePage } from './BasePage.po';
+import { SideNavigationPage } from './SideNavigationPage.po';
+
+interface TopologiesData {
+    description: string;
+    Name:string;
+    DescriptionData: string;
+    Type: string;
+    CacheGroup: string;
+    validationMessage: string;
+}
+export class TopologiesPage extends BasePage {
+    private btnCreateNewTopologies = element(by.xpath("//button[@title='Create 
Topology']"));
+    private txtCacheGroupType = element(by.name('selectFormDropdown'));
+    private txtSearch = 
element(by.id('topologiesTable_filter')).element(by.css('label input'));
+    private txtName = element(by.name('name'));
+    private txtDescription = element(by.id('description'));
+    private btnAddCacheGroup = element(by.xpath("//a[@title='Add child cache 
groups to TOPOLOGY']"));
+    private txtSearchCacheGroup = 
element(by.id('availableCacheGroupsTable_filter')).element(by.css('label 
input'));
+    private btnDelete = element(by.xpath("//button[text()='Delete']"));
+    private txtConfirmName = element(by.name('confirmWithNameInput'));
+    private config = require('../config');
+    private randomize = this.config.randomize;
+    async OpenTopologiesPage(){
+        let snp = new SideNavigationPage();
+        await snp.NavigateToTopologiesPage();
+    }
+    async OpenTopologyMenu(){
+        let snp = new SideNavigationPage();
+        await snp.ClickTopologyMenu();
+    }
+    async CreateTopologies(topologies:TopologiesData){
+        let result = false;
+        let basePage = new BasePage();
+        let snp = new SideNavigationPage();
+        await snp.NavigateToTopologiesPage();
+        //click '+'
+        await this.btnCreateNewTopologies.click();
+        await this.txtName.sendKeys(topologies.Name + this.randomize)
+        await this.txtDescription.sendKeys(topologies.DescriptionData + 
this.randomize)
+        //click add cache group +
+        await this.btnAddCacheGroup.click();
+        //choose type
+        await this.txtCacheGroupType.sendKeys(topologies.Type);
+        await basePage.ClickSubmit();
+        //choose Cachegroup
+        await this.txtSearchCacheGroup.sendKeys(topologies.CacheGroup + 
this.randomize)
+        if(await browser.isElementPresent(by.xpath("//td[@data-search='^" + 
topologies.CacheGroup + this.randomize + "$']")) === true){
+            await element(by.xpath("//td[@data-search='^" + 
topologies.CacheGroup + this.randomize + "$']")).click();
+        }
+        if(await basePage.ClickSubmit() == false){
+            result = undefined;
+            await snp.NavigateToTopologiesPage();
+            throw new Error('Test '+topologies.description+' Failed because 
cannot click on Submit button');
+        }
+        if(result != undefined){
+            if(await basePage.ClickCreate() == false){
+                result = undefined;
+                await snp.NavigateToTopologiesPage();
+                throw new Error('Test '+topologies.description+' Failed 
because cannot click on Create button');
+            }else{
+                result = await basePage.GetOutputMessage().then(value => value 
=== topologies.validationMessage);
+                if (topologies.description == 'create a Topologies with empty 
cachegroup (no server)'){
+                    result = await basePage.GetOutputMessage().then(value => 
value.includes(topologies.validationMessage));
+                }
+            }
+            return result;
+        }
+    }
+       
+    async SearchTopologies(nameTopologies:string){
+        let name = nameTopologies + this.randomize;
+        let result = false;
+        let snp = new SideNavigationPage();
+        await snp.NavigateToTopologiesPage();
+        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();
+            result = true;
+        } else {
+            result = undefined;
+        }
+        return result;
+    }
+    async UpdateTopologies(topologies){
+        let result = false;
+        let basePage = new BasePage();
+        let snp = new SideNavigationPage();
+        if(topologies.Type != undefined){
+             //click add cache group +
+            await this.btnAddCacheGroup.click();
+            //choose type
+            await this.txtCacheGroupType.sendKeys(topologies.Type);
+            await basePage.ClickSubmit();
+            await this.txtSearchCacheGroup.sendKeys(topologies.CacheGroup + 
this.randomize)
+            await element(by.xpath("//td[@data-search='^" + 
topologies.CacheGroup + this.randomize + "$']")).click();
+            if(await basePage.ClickSubmit() == false){
+                result = undefined;
+            }
+        }
+        //if TypeChild is not empty
+        if(topologies.TypeChild != undefined){
+            //add cachegroup child to cachegroup
+            await element(by.xpath("//a[@title='Add child cache groups to " + 
topologies.CacheGroup + this.randomize + "']//i[1]")).click();
+            //choose type
+            await this.txtCacheGroupType.sendKeys(topologies.TypeChild);
+            //if cannot click submit return undefined
+            if(await basePage.ClickSubmit() == false ){
+                result = undefined;
+            }else{
+                //search and send in cachegroup child then click submit
+                await 
this.txtSearchCacheGroup.sendKeys(topologies.CacheGroupChild + this.randomize)
+                await element(by.xpath("//td[@data-search='^" + 
topologies.CacheGroupChild + this.randomize + "$']")).click();
+                await basePage.ClickSubmit(); 
+                if(topologies.TypeGrandChild != undefined){
+                    //add grandchild to cachegroup
+                    await element(by.xpath("//a[@title='Add child cache groups 
to " + topologies.CacheGroupChild + this.randomize + "']//i[1]")).click();
+                    //choose type
+                    await 
this.txtCacheGroupType.sendKeys(topologies.TypeGrandChild);
+                      //if cannot click submit return undefined
+                    if(await basePage.ClickSubmit() == false ){
+                        result = undefined;
+                    }else{
+                        //search and send in cachegroup grandchild then click 
submit
+                        await 
this.txtSearchCacheGroup.sendKeys(topologies.CacheGroupGrandChild + 
this.randomize)
+                        await element(by.xpath("//td[@data-search='^" + 
topologies.CacheGroupGrandChild + this.randomize + "$']")).click();
+                        await basePage.ClickSubmit(); 
+                        await basePage.ClickNo();
+                    }
+                }
+            }
+        }
+        if(topologies.CacheGroupNeedSP != undefined){
+            if(await element(by.xpath("//a[@title='Set Secondary Parent Cache 
Group for " + topologies.CacheGroupNeedSP + this.randomize + 
"']")).isDisplayed() == true){
+                await element(by.xpath("//a[@title='Set Secondary Parent Cache 
Group for " + topologies.CacheGroupNeedSP + this.randomize + "']")).click();
+                await 
this.txtCacheGroupType.sendKeys(topologies.SecondaryParent + this.randomize );
+                if(await basePage.ClickSubmit() == false){
+                    result = undefined;
+                }
+            }else{
+                result = undefined;
+            }
+        }
+         //message check
+        //if result in the beginning is not undefined
+        if(result != undefined){
+            if(await basePage.ClickUpdate() == false){
+                result = undefined;
+                await snp.NavigateToTopologiesPage();
+            }else{
+                result = await basePage.GetOutputMessage().then(function 
(value) {
+                    if (topologies.validationMessage == value) {
+                        return true;
+                    } else {
+                        return false;
+                    }
+                })
+                if(topologies.validationWarning == true){
+                    let warningMessage = ""+topologies.Type+"-typed cachegroup 
"+topologies.CacheGroup+this.randomize+" is a parent of 
"+topologies.CacheGroupChild+this.randomize+", unexpected behavior may result"
+                    result = await basePage.GetOutputWarning().then(function 
(value) {
+                        if ( warningMessage == value) {
+                            return true;
+                        } else {
+                            return false;
+                        }
+                    })
+
+                }
+            }
+            return result;
+        }
+        
+    }
+    async DeleteTopologies(topologies){
+        let name = topologies.Name + this.randomize;
+        let result = false;
+        let basePage = new BasePage();
+        await this.btnDelete.click();
+        await this.txtConfirmName.sendKeys(name);
+        await basePage.ClickDeletePermanently();
+        result = await basePage.GetOutputMessage().then(function (value) {
+            if (topologies.validationMessage == value) {
+                return true;
+            } else {
+                return false;
+            }
+        })
+        return result;
+    }
+}

Review comment:
       Missing newline at EOF

##########
File path: traffic_portal/test/integration/PageObjects/TopologiesPage.po.ts
##########
@@ -0,0 +1,192 @@
+import { browser, by, element } from 'protractor'
+import { BasePage } from './BasePage.po';
+import { SideNavigationPage } from './SideNavigationPage.po';
+
+interface TopologiesData {
+    description: string;
+    Name:string;
+    DescriptionData: string;
+    Type: string;
+    CacheGroup: string;
+    validationMessage: string;
+}
+export class TopologiesPage extends BasePage {
+    private btnCreateNewTopologies = element(by.xpath("//button[@title='Create 
Topology']"));
+    private txtCacheGroupType = element(by.name('selectFormDropdown'));
+    private txtSearch = 
element(by.id('topologiesTable_filter')).element(by.css('label input'));
+    private txtName = element(by.name('name'));
+    private txtDescription = element(by.id('description'));
+    private btnAddCacheGroup = element(by.xpath("//a[@title='Add child cache 
groups to TOPOLOGY']"));
+    private txtSearchCacheGroup = 
element(by.id('availableCacheGroupsTable_filter')).element(by.css('label 
input'));
+    private btnDelete = element(by.xpath("//button[text()='Delete']"));
+    private txtConfirmName = element(by.name('confirmWithNameInput'));
+    private config = require('../config');
+    private randomize = this.config.randomize;
+    async OpenTopologiesPage(){
+        let snp = new SideNavigationPage();
+        await snp.NavigateToTopologiesPage();
+    }
+    async OpenTopologyMenu(){
+        let snp = new SideNavigationPage();
+        await snp.ClickTopologyMenu();
+    }
+    async CreateTopologies(topologies:TopologiesData){
+        let result = false;
+        let basePage = new BasePage();
+        let snp = new SideNavigationPage();
+        await snp.NavigateToTopologiesPage();
+        //click '+'
+        await this.btnCreateNewTopologies.click();
+        await this.txtName.sendKeys(topologies.Name + this.randomize)
+        await this.txtDescription.sendKeys(topologies.DescriptionData + 
this.randomize)
+        //click add cache group +
+        await this.btnAddCacheGroup.click();
+        //choose type
+        await this.txtCacheGroupType.sendKeys(topologies.Type);
+        await basePage.ClickSubmit();
+        //choose Cachegroup
+        await this.txtSearchCacheGroup.sendKeys(topologies.CacheGroup + 
this.randomize)
+        if(await browser.isElementPresent(by.xpath("//td[@data-search='^" + 
topologies.CacheGroup + this.randomize + "$']")) === true){
+            await element(by.xpath("//td[@data-search='^" + 
topologies.CacheGroup + this.randomize + "$']")).click();
+        }
+        if(await basePage.ClickSubmit() == false){
+            result = undefined;
+            await snp.NavigateToTopologiesPage();
+            throw new Error('Test '+topologies.description+' Failed because 
cannot click on Submit button');
+        }
+        if(result != undefined){
+            if(await basePage.ClickCreate() == false){
+                result = undefined;
+                await snp.NavigateToTopologiesPage();
+                throw new Error('Test '+topologies.description+' Failed 
because cannot click on Create button');
+            }else{
+                result = await basePage.GetOutputMessage().then(value => value 
=== topologies.validationMessage);
+                if (topologies.description == 'create a Topologies with empty 
cachegroup (no server)'){
+                    result = await basePage.GetOutputMessage().then(value => 
value.includes(topologies.validationMessage));
+                }
+            }
+            return result;
+        }
+    }
+       
+    async SearchTopologies(nameTopologies:string){
+        let name = nameTopologies + this.randomize;
+        let result = false;
+        let snp = new SideNavigationPage();
+        await snp.NavigateToTopologiesPage();
+        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();
+            result = true;
+        } else {
+            result = undefined;
+        }
+        return result;
+    }
+    async UpdateTopologies(topologies){
+        let result = false;
+        let basePage = new BasePage();
+        let snp = new SideNavigationPage();
+        if(topologies.Type != undefined){
+             //click add cache group +
+            await this.btnAddCacheGroup.click();
+            //choose type
+            await this.txtCacheGroupType.sendKeys(topologies.Type);
+            await basePage.ClickSubmit();
+            await this.txtSearchCacheGroup.sendKeys(topologies.CacheGroup + 
this.randomize)
+            await element(by.xpath("//td[@data-search='^" + 
topologies.CacheGroup + this.randomize + "$']")).click();
+            if(await basePage.ClickSubmit() == false){
+                result = undefined;
+            }
+        }
+        //if TypeChild is not empty
+        if(topologies.TypeChild != undefined){
+            //add cachegroup child to cachegroup
+            await element(by.xpath("//a[@title='Add child cache groups to " + 
topologies.CacheGroup + this.randomize + "']//i[1]")).click();
+            //choose type
+            await this.txtCacheGroupType.sendKeys(topologies.TypeChild);
+            //if cannot click submit return undefined
+            if(await basePage.ClickSubmit() == false ){
+                result = undefined;
+            }else{
+                //search and send in cachegroup child then click submit
+                await 
this.txtSearchCacheGroup.sendKeys(topologies.CacheGroupChild + this.randomize)
+                await element(by.xpath("//td[@data-search='^" + 
topologies.CacheGroupChild + this.randomize + "$']")).click();
+                await basePage.ClickSubmit(); 
+                if(topologies.TypeGrandChild != undefined){
+                    //add grandchild to cachegroup
+                    await element(by.xpath("//a[@title='Add child cache groups 
to " + topologies.CacheGroupChild + this.randomize + "']//i[1]")).click();
+                    //choose type
+                    await 
this.txtCacheGroupType.sendKeys(topologies.TypeGrandChild);
+                      //if cannot click submit return undefined
+                    if(await basePage.ClickSubmit() == false ){
+                        result = undefined;
+                    }else{
+                        //search and send in cachegroup grandchild then click 
submit
+                        await 
this.txtSearchCacheGroup.sendKeys(topologies.CacheGroupGrandChild + 
this.randomize)
+                        await element(by.xpath("//td[@data-search='^" + 
topologies.CacheGroupGrandChild + this.randomize + "$']")).click();
+                        await basePage.ClickSubmit(); 
+                        await basePage.ClickNo();
+                    }
+                }
+            }
+        }
+        if(topologies.CacheGroupNeedSP != undefined){
+            if(await element(by.xpath("//a[@title='Set Secondary Parent Cache 
Group for " + topologies.CacheGroupNeedSP + this.randomize + 
"']")).isDisplayed() == true){
+                await element(by.xpath("//a[@title='Set Secondary Parent Cache 
Group for " + topologies.CacheGroupNeedSP + this.randomize + "']")).click();
+                await 
this.txtCacheGroupType.sendKeys(topologies.SecondaryParent + this.randomize );
+                if(await basePage.ClickSubmit() == false){
+                    result = undefined;
+                }
+            }else{
+                result = undefined;
+            }
+        }
+         //message check
+        //if result in the beginning is not undefined
+        if(result != undefined){
+            if(await basePage.ClickUpdate() == false){
+                result = undefined;
+                await snp.NavigateToTopologiesPage();
+            }else{
+                result = await basePage.GetOutputMessage().then(function 
(value) {
+                    if (topologies.validationMessage == value) {
+                        return true;
+                    } else {
+                        return false;
+                    }
+                })
+                if(topologies.validationWarning == true){
+                    let warningMessage = ""+topologies.Type+"-typed cachegroup 
"+topologies.CacheGroup+this.randomize+" is a parent of 
"+topologies.CacheGroupChild+this.randomize+", unexpected behavior may result"
+                    result = await basePage.GetOutputWarning().then(function 
(value) {
+                        if ( warningMessage == value) {
+                            return true;
+                        } else {
+                            return false;
+                        }
+                    })
+
+                }
+            }
+            return result;
+        }
+        
+    }
+    async DeleteTopologies(topologies){
+        let name = topologies.Name + this.randomize;
+        let result = false;
+        let basePage = new BasePage();
+        await this.btnDelete.click();
+        await this.txtConfirmName.sendKeys(name);
+        await basePage.ClickDeletePermanently();
+        result = await basePage.GetOutputMessage().then(function (value) {
+            if (topologies.validationMessage == value) {

Review comment:
       comparison should use `===` - but also it looks like you're just 
returning the result of this comparison, so I think you could do it more 
succinctly like:
   ```typescript
   result = await 
basePage.GetOutputMessage().then(v=>v===topologies.validationMessage);
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to