You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by oc...@apache.org on 2021/05/20 14:54:46 UTC
[trafficcontrol] branch master updated: Migrate user tests from E2E
to integration (#5870)
This is an automated email from the ASF dual-hosted git repository.
ocket8888 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
The following commit(s) were added to refs/heads/master by this push:
new dde7f69 Migrate user tests from E2E to integration (#5870)
dde7f69 is described below
commit dde7f69d49a056843e7c179bef44a36ba839be02
Author: Rima Shah <22...@users.noreply.github.com>
AuthorDate: Thu May 20 08:54:36 2021 -0600
Migrate user tests from E2E to integration (#5870)
* Added ts files for user and users.spec and update UserPage
* Added tests for create/update user, search csv
* Added toggle and register user tests
* Added update registered user
* Edited update register user tests
* used right comparison sign
* Changes made per review comments.
* Changed string manipulation to template string and removed undefined return in update()
* Added return type
---
traffic_portal/test/integration/Data/users.ts | 89 +++++++++++++
.../test/integration/PageObjects/BasePage.po.ts | 21 ++-
.../test/integration/PageObjects/UsersPage.po.ts | 148 +++++++++++++++++++--
.../test/integration/specs/Users.spec.ts | 91 +++++++++++++
4 files changed, 329 insertions(+), 20 deletions(-)
diff --git a/traffic_portal/test/integration/Data/users.ts b/traffic_portal/test/integration/Data/users.ts
new file mode 100644
index 0000000..7d907de
--- /dev/null
+++ b/traffic_portal/test/integration/Data/users.ts
@@ -0,0 +1,89 @@
+/*
+ * 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 {randomize} from "../config";
+
+export const users = {
+ tests: [
+ {
+ logins: [
+ {
+ description: "Admin Role",
+ username: "TPAdmin",
+ password: "pa$$word"
+ }
+ ],
+ check: [
+ {
+ description: "check CSV link from CDN page",
+ Name: "Export as CSV"
+ }
+ ],
+ toggle: [
+ {
+ description: "hide first table column",
+ Name: "Email"
+ },
+ {
+ description: "redisplay first table column",
+ Name: "Email"
+ }
+ ],
+ add: [
+ {
+ description: "create a new User",
+ FullName: "TPCreateUser1",
+ Username: "User1",
+ Email: "test@cdn.tc.com",
+ Role: "admin",
+ Tenant: "- tenantSame",
+ Password: "qwe@123#rty",
+ ConfirmPassword: "qwe@123#rty",
+ PublicSSHKey: "",
+ validationMessage: "User created"
+ },
+ ],
+ register: [
+ {
+ description: "create a registered User",
+ Email: "test2@cdn.tc.com",
+ Role: "admin",
+ Tenant: "- tenantSame",
+ validationMessage: `Sent user registration to {{ test2@cdn.tc.com${randomize}}} with the following permissions [ role: admin | tenant: tenantSame${randomize} ]`
+ }
+ ],
+ update: [
+ {
+ description: "update user's fullname",
+ Username: "User1",
+ NewFullName: "TPUpdatedUser1",
+ validationMessage: "user was updated."
+ },
+ ],
+ updateRegisterUser: [
+ {
+ description: "update registered user's fullname",
+ Email: "test2@cdn.tc.com",
+ NewFullName: "TPRegisterUser1",
+ validationMessage: "user was updated."
+ }
+ ],
+ },
+ ]
+};
diff --git a/traffic_portal/test/integration/PageObjects/BasePage.po.ts b/traffic_portal/test/integration/PageObjects/BasePage.po.ts
index 8983a1a..17a5c0d 100644
--- a/traffic_portal/test/integration/PageObjects/BasePage.po.ts
+++ b/traffic_portal/test/integration/PageObjects/BasePage.po.ts
@@ -34,11 +34,12 @@ export class BasePage {
private lbOutputWarning = element(by.xpath("(//div[contains(@class,'alert alert-dismissable alert-warning')]//div)[1]"));
private lbBlankError = element(by.xpath("//small[text()='Required']"));
private lbSyntaxError = element(by.xpath("//small[text()='Must be alphamumeric with no spaces. Dashes and underscores also allowed.']"));
- private btnCreate= element(by.xpath("//button[text()='Create']"));
+ private btnCreate= element(by.buttonText('Create'));
private btnDeletePermanently = element(by.buttonText('Delete Permanently'));
private btnCancel = element(by.className('close')).element(by.xpath("//span[text()='×']"));
- private btnUpdate = element(by.xpath("//button[text()='Update']"))
+ private btnUpdate = element(by.buttonText('Update'));
private btnSubmit = element(by.xpath("//button[text()='Submit']"));
+ private btnRegister = element(by.buttonText('Send Registration'));
private btnNo = element(by.xpath("//button[text()='No']"));
async ClickNo(){
@@ -53,8 +54,8 @@ export class BasePage {
}
}
- async ClickUpdate(){
- if(await this.btnUpdate.isEnabled() == true){
+ public async ClickUpdate(): Promise<boolean>{
+ if(await this.btnUpdate.isEnabled()){
await this.btnUpdate.click();
return true;
}else{
@@ -69,14 +70,22 @@ export class BasePage {
return false;
}
}
- async ClickCreate(){
- if(await this.btnCreate.isEnabled() == true){
+ public async ClickCreate(): Promise<boolean> {
+ if(await this.btnCreate.isEnabled()){
await this.btnCreate.click();
return true;
}else{
return false;
}
}
+ public async ClickRegister(): Promise<boolean> {
+ if(await this.btnRegister.isEnabled()){
+ await this.btnRegister.click();
+ return true;
+ }else{
+ return false;
+ }
+ }
async ClickCancel(){
await this.btnCancel.click();
}
diff --git a/traffic_portal/test/integration/PageObjects/UsersPage.po.ts b/traffic_portal/test/integration/PageObjects/UsersPage.po.ts
index 3260a71..9788488 100644
--- a/traffic_portal/test/integration/PageObjects/UsersPage.po.ts
+++ b/traffic_portal/test/integration/PageObjects/UsersPage.po.ts
@@ -16,10 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { by, element } from 'protractor';
+import { by, element } from 'protractor';
import { BasePage } from './BasePage.po';
-import {SideNavigationPage} from '../PageObjects/SideNavigationPage.po';
+import { SideNavigationPage } from './SideNavigationPage.po';
import { randomize } from '../config';
interface User {
@@ -35,9 +35,31 @@ interface User {
validationMessage?: string;
}
-export class UsersPage extends BasePage {
+interface UpdateUser {
+ description: string;
+ Username: string;
+ NewFullName: string;
+ validationMessage?: string;
+}
+
+interface RegisterUser {
+ Email: string;
+ Role: string;
+ Tenant: string;
+ existsMessage?: string;
+ validationMessage?: string;
+}
+
+interface UpdateRegisterUser {
+ description: string;
+ Email: string;
+ NewFullName: string;
+ validationMessage?: string;
+}
- private btnCreateNewUser = element(by.css('[title="Create New User"]'));
+export class UsersPage extends BasePage {
+ private btnCreateNewUser = element(by.name('createUserButton'));
+ private btnRegisterNewUser = element(by.name('createRegisterUserButton'));
private txtFullName = element(by.name('fullName'));
private txtUserName = element(by.name('uName'));
private txtEmail = element(by.name('email'));
@@ -46,32 +68,58 @@ export class UsersPage extends BasePage {
private txtPassword = element(by.name('uPass'));
private txtConfirmPassword = element(by.name('confirmPassword'));
private txtPublicSSHKey = element(by.name('publicSshKey'));
+ private txtSearch = element(by.id('usersTable_filter')).element(by.css('label input'));
+ private btnTableColumn = element(by.css('[title="Select Table Columns"]'));
private randomize = randomize;
- async OpenUserPage(){
- let snp = new SideNavigationPage();
- await snp.ClickUserAdminMenu();
- await snp.NavigateToUsersPage();
- }
+ public async OpenUserPage(): Promise<void> {
+ const snp = new SideNavigationPage();
+ await snp.NavigateToUsersPage();
+ }
+
+ public async OpenUserMenu(): Promise<void> {
+ const snp = new SideNavigationPage();
+ await snp.ClickUserAdminMenu();
+ }
+
+ public async CheckCSV(name: string): Promise<boolean> {
+ return element(by.cssContainingText("span", name)).isPresent();
+ }
+
+ public async CheckToggle(name: string): Promise<boolean> {
+ let result = false;
+ await this.btnTableColumn.click();
+ //if the box is already checked, uncheck it and return false
+ if (await element(by.cssContainingText("th", name)).isPresent()) {
+ await element(by.cssContainingText("label", name)).click();
+ result = false;
+ } else {
+ //if the box is unchecked, then check it and return true
+ await element(by.cssContainingText("label", name)).click();
+ result = true;
+ }
+ await this.btnTableColumn.click();
+ return result;
+ }
public async CreateUser(user: User): Promise<boolean> {
let result = false;
- let basePage = new BasePage();
- let snp = new SideNavigationPage();
+ const basePage = new BasePage();
+ const snp = new SideNavigationPage();
await this.btnCreateNewUser.click();
await this.txtFullName.sendKeys(user.FullName + this.randomize);
await this.txtUserName.sendKeys(user.Username + this.randomize);
- await this.txtEmail.sendKeys(user.FullName + this.randomize + user.Email);
+ await this.txtEmail.sendKeys(user.Email + this.randomize);
await this.txtRole.sendKeys(user.Role);
await this.txtTenant.sendKeys(user.Tenant+this.randomize);
await this.txtPassword.sendKeys(user.Password);
await this.txtConfirmPassword.sendKeys(user.ConfirmPassword);
await this.txtPublicSSHKey.sendKeys(user.PublicSSHKey);
await basePage.ClickCreate();
- if(await basePage.GetOutputMessage() == user.existsMessage){
+ if(await basePage.GetOutputMessage() === user.existsMessage){
await snp.NavigateToUsersPage();
result = true;
- }else if(await basePage.GetOutputMessage() == user.validationMessage){
+ }else if(await basePage.GetOutputMessage() === user.validationMessage){
result = true;
}else{
result = false;
@@ -79,4 +127,76 @@ export class UsersPage extends BasePage {
return result;
}
+ public async SearchUser(nameUser: string): Promise<void> {
+ const snp = new SideNavigationPage();
+ const name = nameUser + this.randomize;
+ await snp.NavigateToUsersPage();
+ await this.txtSearch.clear();
+ await this.txtSearch.sendKeys(name);
+ await element.all(by.repeater('u in ::users')).filter(function (row) {
+ return row.element(by.name('username')).getText().then(function (val) {
+ return val === name;
+ });
+ }).first().click();
+ }
+
+ public async SearchEmailUser(nameEmail: string): Promise<void> {
+ const snp = new SideNavigationPage();
+ const name = nameEmail + this.randomize;
+ await snp.NavigateToUsersPage();
+ await this.txtSearch.clear();
+ await this.txtSearch.sendKeys(name);
+ await element.all(by.repeater('u in ::users')).filter(function (row) {
+ return row.element(by.name('email')).getText().then(function (val) {
+ return val === name;
+ });
+ }).first().click();
+ }
+
+ public async UpdateUser(user: UpdateUser): Promise<boolean> {
+ const basePage = new BasePage();
+ switch (user.description) {
+ case "update user's fullname":
+ await this.txtFullName.clear();
+ await this.txtFullName.sendKeys(user.NewFullName);
+ await basePage.ClickUpdate();
+ break;
+ default:
+ return false;
+ }
+ return basePage.GetOutputMessage().then(value => user.validationMessage === value);
+ }
+
+ public async RegisterUser(user: RegisterUser): Promise<boolean> {
+ let result = false;
+ const basePage = new BasePage();
+ const snp = new SideNavigationPage();
+ await this.btnRegisterNewUser.click();
+ await this.txtEmail.sendKeys(user.Email + this.randomize);
+ await this.txtRole.sendKeys(user.Role);
+ await this.txtTenant.sendKeys(user.Tenant + this.randomize);
+ await basePage.ClickRegister();
+ if (await basePage.GetOutputMessage() === user.existsMessage) {
+ await snp.NavigateToUsersPage();
+ result = true;
+ } else if (await basePage.GetOutputMessage() === user.validationMessage) {
+ result = true;
+ } else {
+ result = false;
+ }
+ return result;
+ }
+
+ public async UpdateRegisterUser(user: UpdateRegisterUser): Promise<boolean> {
+ const basePage = new BasePage();
+ switch (user.description) {
+ case "update registered user's fullname":
+ await this.txtFullName.sendKeys(user.NewFullName);
+ await basePage.ClickUpdate();
+ break;
+ default:
+ return false;
+ }
+ return basePage.GetOutputMessage().then(value => user.validationMessage === value);
+ }
}
diff --git a/traffic_portal/test/integration/specs/Users.spec.ts b/traffic_portal/test/integration/specs/Users.spec.ts
new file mode 100644
index 0000000..b1a52a5
--- /dev/null
+++ b/traffic_portal/test/integration/specs/Users.spec.ts
@@ -0,0 +1,91 @@
+/*
+ * 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 { UsersPage } from '../PageObjects/UsersPage.po';
+import { TopNavigationPage } from '../PageObjects/TopNavigationPage.po';
+import { users } from "../Data/users";
+
+const loginPage = new LoginPage();
+const topNavigation = new TopNavigationPage();
+const usersPage = new UsersPage();
+
+users.tests.forEach(async usersData =>{
+ usersData.logins.forEach(login => {
+ describe('Traffic Portal - Users - ' + login.description, function(){
+ it('can login', async () => {
+ browser.get(browser.params.baseUrl);
+ await loginPage.Login(login);
+ expect(await loginPage.CheckUserName(login)).toBeTruthy();
+ });
+ it('can open users page', async () => {
+ await usersPage.OpenUserMenu()
+ await usersPage.OpenUserPage();
+ });
+ usersData.check.forEach(check => {
+ it(check.description, async () => {
+ expect(await usersPage.CheckCSV(check.Name)).toBe(true);
+ await usersPage.OpenUserPage();
+ });
+ });
+ usersData.toggle.forEach(toggle => {
+ it(toggle.description, async () => {
+ if(toggle.description.includes('hide')){
+ expect(await usersPage.CheckToggle(toggle.Name)).toBe(false);
+ await usersPage.OpenUserPage();
+ }else{
+ expect(await usersPage.CheckToggle(toggle.Name)).toBe(true);
+ await usersPage.OpenUserPage();
+ }
+ });
+ })
+ usersData.add.forEach(add => {
+ it(add.description, async () => {
+ expect(await usersPage.CreateUser(add)).toBeTruthy();
+ await usersPage.OpenUserPage();
+ });
+ });
+ usersData.update.forEach(update => {
+ it(update.description, async () => {
+ await usersPage.SearchUser(update.Username);
+ expect(await usersPage.UpdateUser(update)).toBe(true);
+ await usersPage.OpenUserPage();
+ });
+ });
+ usersData.register.forEach(register => {
+ it(register.description, async () => {
+ expect(await usersPage.RegisterUser(register)).toBeTruthy();
+ await usersPage.OpenUserPage();
+ });
+ });
+ usersData.updateRegisterUser.forEach(updateRegisterUser => {
+ it(updateRegisterUser.description, async () => {
+ await usersPage.SearchEmailUser(updateRegisterUser.Email);
+ expect(await usersPage.UpdateRegisterUser(updateRegisterUser)).toBe(true);
+ await usersPage.OpenUserPage();
+ });
+ });
+ it('can logout', async () => {
+ expect(await topNavigation.Logout()).toBeTruthy();
+ });
+ });
+ });
+});