diff --git a/e2e/src/feature/employee/employee.feature b/e2e/src/feature/employee/employee.feature new file mode 100644 index 0000000..a347db1 --- /dev/null +++ b/e2e/src/feature/employee/employee.feature @@ -0,0 +1,26 @@ +@Employee +Feature: Employee + As a user + I should be able to create, read, update and delete some data on the table. + +Scenario: Create an Employee + Given I am on the dashboard + When I create new employee + Then I should see the success message "Success: Data has been added!" + And I should see the employee record in the list + +Scenario: Viewing the Dashboard + Given Im at the dashboard page + When I check the table + Then I should see the existing records + +Scenario: Delete an Existing Employee + Given I am on the dashboard page + When I delete an existing employee + Then I should see the employee is deleted from the table + +Scenario: Update the info of Employee + Given Im at the dashboard to update info + When I update the selected employee + Then I should view the success message "Success: Data has been updated!" + And I should see the new info saved \ No newline at end of file diff --git a/e2e/src/feature/security/security.feature b/e2e/src/feature/security/security.feature new file mode 100644 index 0000000..80b3cbe --- /dev/null +++ b/e2e/src/feature/security/security.feature @@ -0,0 +1,13 @@ +@security +Feature: Security + As a user + I should be able to access the system with proper credentials + +Scenario: Login +Given I am on the login page +When I log in +Then I should be redirected to the dashboard + + + + diff --git a/e2e/src/hooks/generic.hooks.ts b/e2e/src/hooks/generic.hooks.ts new file mode 100644 index 0000000..4d57c45 --- /dev/null +++ b/e2e/src/hooks/generic.hooks.ts @@ -0,0 +1,9 @@ +import { BeforeAll , setDefaultTimeout } from 'cucumber'; +import { browser } from 'protractor'; + +BeforeAll( async () => { + console.log('HOOK EXECUTED'); + browser.waitForAngularEnabled(false); + setDefaultTimeout( 60 * 10000); + +}); diff --git a/e2e/src/po/dashboard.po.ts b/e2e/src/po/dashboard.po.ts new file mode 100644 index 0000000..070392d --- /dev/null +++ b/e2e/src/po/dashboard.po.ts @@ -0,0 +1,50 @@ +import { element, by, browser } from 'protractor'; +import { FormPage } from './form.po'; + +export class DashboardPage { + static get newEmployeeButton() { + return element(by.buttonText('New Employee')); + } + + static async createEmployee() { + await this.newEmployeeButton.click(); + await FormPage.fillForm(); + await FormPage.addButton.click(); + // await this.closeSuccessMessage.click(); + } + + static get table() { + return element(by.tagName('p-table')); + } + + static get tableRows() { + return this.table.all(by.tagName('tr')); + } + + static get tableNextPageButton() { + return element(by.css('span[class= "ui-paginator-icon pi pi-caret-right"')); + } + + static get tablePrevPageButton() { + return element(by.css('span[class= "ui-paginator-icon pi pi-caret-left"')); + } + static async checkTableRowForData(data: string) { + let foundData = null; + (await this.tableRows.getText() as any).forEach(trData => { + if (trData.includes('Jerrica Azupardo')) { + foundData = trData; + } + });​ + return foundData; + } + + static get closeSuccessMessage(){ + return element(by.css('i[class="pi pi-times"]')); + } + + + static async successMessage(){ + await browser.sleep(1000); + await this.closeSuccessMessage.click(); + } +}; \ No newline at end of file diff --git a/e2e/src/po/delete.po.ts b/e2e/src/po/delete.po.ts new file mode 100644 index 0000000..bb52289 --- /dev/null +++ b/e2e/src/po/delete.po.ts @@ -0,0 +1,12 @@ +import { element, by, browser } from 'protractor'; +export class DeletePage { + static get delEmployeeButton() { + + return element.all(by.buttonText('Delete')).first(); + } + + static async delEmployee() { + await this.delEmployeeButton.click(); + } + +} diff --git a/e2e/src/po/form.po.ts b/e2e/src/po/form.po.ts new file mode 100644 index 0000000..7554209 --- /dev/null +++ b/e2e/src/po/form.po.ts @@ -0,0 +1,26 @@ +import { element, by, browser } from 'protractor'; +export class FormPage { + static get form() { + return element(by.tagName('form')); + } + static getFormControlElement(formContolName: string){ + return element(by.css(`[formcontrolname=${formContolName}]`)); + } + static get addButton() { + return element(by.buttonText('Add')) + } + static async fillForm() { + await this.getFormControlElement('firstName').sendKeys('Jerrica'); + await this.getFormControlElement('lastName').sendKeys('Azupardo'); + await this.getFormControlElement('country').sendKeys('France'); + await this.getFormControlElement('nationality').sendKeys('Filipino'); + await this.getFormControlElement('company').sendKeys('Titus Global'); + await this.getFormControlElement('designation').sendKeys('idk'); + await this.getFormControlElement('workExp').sendKeys('2 years'); + await this.getFormControlElement('dataSource').click(); + await browser.sleep(1000); + await element.all(by.tagName('p-dropdownitem')).get(2).click(); + } + + +} \ No newline at end of file diff --git a/e2e/src/po/formUpdate.po.ts b/e2e/src/po/formUpdate.po.ts new file mode 100644 index 0000000..05ab4e7 --- /dev/null +++ b/e2e/src/po/formUpdate.po.ts @@ -0,0 +1,25 @@ +import { element, by, browser } from 'protractor'; +export class Updateform { + static get form() { + return element(by.tagName('form')); + } + static getFormControlElement(formContolName: string){ + return element(by.css(`[formcontrolname=${formContolName}]`)); + } + static get updateButton() { + return element(by.buttonText('Update')) + } + + static async fillForm2() { + await this.getFormControlElement('firstName').sendKeys('Ching'); + await this.getFormControlElement('lastName').sendKeys('Chong'); + await this.getFormControlElement('country').sendKeys('Wuhan, China'); + await this.getFormControlElement('nationality').sendKeys('Chinese'); + await this.getFormControlElement('company').sendKeys('Pongkwayla'); + await this.getFormControlElement('designation').sendKeys('Earth'); + await this.getFormControlElement('workExp').sendKeys('2'); + await this.getFormControlElement('dataSource').click(); + await browser.sleep(1000); + await element.all(by.tagName('p-dropdownitem')).get(2).click(); + } +} diff --git a/e2e/src/po/message.po.ts b/e2e/src/po/message.po.ts new file mode 100644 index 0000000..180eb60 --- /dev/null +++ b/e2e/src/po/message.po.ts @@ -0,0 +1,10 @@ +import { element, by } from 'protractor'; + +export class MessagePage{ + static get successMessage() { + return element(by.id('success-message')); + } + static get successUpdateMessage(){ + return element(by.id('success-message')); + } +} \ No newline at end of file diff --git a/e2e/src/po/security.po.ts b/e2e/src/po/security.po.ts new file mode 100644 index 0000000..325d408 --- /dev/null +++ b/e2e/src/po/security.po.ts @@ -0,0 +1,22 @@ +import { element, by, ElementFinder, browser} from 'protractor'; +export class SecurityPage { + static get usernameField(): ElementFinder { + return element(by.id('username-field')); + } + + static get passwordField(): ElementFinder { + return element(by.id('password-field')); + } + + static get loginButton(): ElementFinder { + return element(by.css('button[label="Login"')); + } + + static async login() { + await this.usernameField.sendKeys('asd'); + await this.passwordField.sendKeys('asd'); + await this.loginButton.click(); + + } +} + diff --git a/e2e/src/po/update.po.ts b/e2e/src/po/update.po.ts new file mode 100644 index 0000000..50360a2 --- /dev/null +++ b/e2e/src/po/update.po.ts @@ -0,0 +1,25 @@ +import { element, by, browser } from 'protractor'; +import { Updateform } from '../po/formUpdate.po' + +export class UpdatePage { + + static get updateDetail() { + return element(by.tagName('td')) + } + + static async updateEmployee(){ + await this.updateDetail.click(); + // await Updateform.clearFieldButton.click(); + await Updateform.fillForm2(); + await Updateform.updateButton.click(); + } + + static get table() { + return element(by.tagName('p-table')); + } + + static get tableRows() { + return this.table.all(by.tagName('tr')); + } + +}; \ No newline at end of file diff --git a/e2e/src/step_definition/deleteEmployee.definitions.ts b/e2e/src/step_definition/deleteEmployee.definitions.ts new file mode 100644 index 0000000..186d726 --- /dev/null +++ b/e2e/src/step_definition/deleteEmployee.definitions.ts @@ -0,0 +1,58 @@ +import { Given, When, Then } from 'cucumber'; +import { browser, element, by, ExpectedConditions} from 'protractor'; +import { DeletePage } from '../po/delete.po'; +import { Alert } from 'selenium-webdriver'; +import { DashboardPage} from '../po/dashboard.po'; + +const chai = require('chai').use(require('chai-as-promised')); +const expect = chai.expect; + + Given('I am on the dashboard page', async function () { + const currentUrl = await browser.getCurrentUrl(); + const dashboardUrl = 'http://localhost:4200/dashboard'; + + if (currentUrl !== dashboardUrl) { + await browser.get(dashboardUrl); + } + + const dashboardElemenet = element(by.tagName('app-dashboard')); + if (!(await dashboardElemenet.isPresent())) { + throw Error ('The user is not on the dashboard page'); + } + + + }); + + When('I delete an existing employee', async function () { + let rowData; + + if (!(await DashboardPage.checkTableRowForData('Jerrica Azupardo'))) { + await DashboardPage.tableNextPageButton.click(); + await browser.sleep(1000); + } + + rowData = (await DashboardPage.checkTableRowForData('Jerrica') as string); + rowData = (rowData.replace('Delete', '')).trim(); + expect('8 Jerrica Azupardo France Filipino Titus Global idk 2 years Monster Gulf').to.equal(rowData); + + await browser.sleep(1000) + await DeletePage.delEmployee(); + await browser.sleep(1000) + + const ale:Alert = browser.switchTo().alert(); + ale.accept() + await browser.sleep(1000) + }); + + Then ('I should see the employee is deleted from the table', async function () { + let rowData; + + if (!(await DashboardPage.checkTableRowForData('Jerrica Azupardo'))) { + await DashboardPage.tableNextPageButton.click(); + await browser.sleep(1000); + } + + rowData = (await DashboardPage.checkTableRowForData('Jerrica') as string); + rowData = (rowData.replace('Delete', '')).trim(); + expect('8 Jerrica Azupardo France Filipino Titus Global idk 2 years Monster Gulf').to.equal(rowData); + }); \ No newline at end of file diff --git a/e2e/src/step_definition/employee.definitions.ts b/e2e/src/step_definition/employee.definitions.ts new file mode 100644 index 0000000..21ad64c --- /dev/null +++ b/e2e/src/step_definition/employee.definitions.ts @@ -0,0 +1,58 @@ +import { Given, When, Then } from 'cucumber'; +import { browser, element, by} from 'protractor'; +import { DashboardPage } from '../po/dashboard.po'; +import { MessagePage } from '../po/message.po'; + + + +const chai = require('chai').use(require('chai-as-promised')); +const expect = chai.expect; + +Given('I am on the dashboard', async function () { + + const currentUrl = await browser.getCurrentUrl(); + const dashboardUrl = 'http://localhost:4200/dashboard'; + + if (currentUrl !== dashboardUrl) { + await browser.get(dashboardUrl); + } + + const dashboardElemenet = element(by.tagName('app-dashboard')); + if (!(await dashboardElemenet.isPresent())) { + throw Error ('The user is not on the dashboard page'); + } + + }); + +When('I create new employee', async function () { + + await DashboardPage.createEmployee(); + await browser.sleep(1000); + + }); + +Then('I should see the success message {string}', async function (expectedMessage: string) { + + const messageObject = MessagePage.successMessage; + + expect( true, 'The success message was not displayed').to.equal(await messageObject.isPresent()); + expect( await messageObject.getText(), 'The success message did not match the expected message').to.equal(expectedMessage); + + await DashboardPage.successMessage(); + + }); + + +Then('I should see the employee record in the list', async function () { + + let rowData: string; + + if (!(await DashboardPage.checkTableRowForData('Jerrica Azupardo'))) { + await DashboardPage.tableNextPageButton.click(); + await browser.sleep(1000); + } + + rowData = (await DashboardPage.checkTableRowForData('Jerrica') as string); + rowData = (rowData.replace('Delete', '')).trim(); + expect('8 Jerrica Azupardo France Filipino Titus Global idk 2 years Monster Gulf').to.equal(rowData); +}); \ No newline at end of file diff --git a/e2e/src/step_definition/read.definitions.ts b/e2e/src/step_definition/read.definitions.ts new file mode 100644 index 0000000..9329821 --- /dev/null +++ b/e2e/src/step_definition/read.definitions.ts @@ -0,0 +1,51 @@ + import { Given, When, Then } from 'cucumber' + import { browser, element, by} from 'protractor'; + import { DashboardPage } from '../po/dashboard.po' + + const chai = require('chai').use(require('chai-as-promised')); + const expect = chai.expect; + + Given('Im at the dashboard page', async function () { + + const currentUrl = await browser.getCurrentUrl(); + const dashboardUrl = 'http://localhost:4200/dashboard'; + + if (currentUrl !== dashboardUrl) { + await browser.get(dashboardUrl); + } + + const dashboardElemenet = element(by.tagName('app-dashboard')); + if (!(await dashboardElemenet.isPresent())) { + throw Error ('The user is not on the dashboard page'); + } + + }); + + When('I check the table', async function () { + + + await DashboardPage.tablePrevPageButton.click(); + browser.sleep(1000) + + const tbl = element(by.tagName('table')); + if(!(await tbl.isPresent())){ + throw Error ('The user cant see the table'); + } + + }); + + Then('I should see the existing records', async function () { + + let rowData: string; + + if (!(await DashboardPage.checkTableRowForData('Rome Joseph'))) { + await DashboardPage.tableNextPageButton.click(); + + return true; + } + + rowData = (await DashboardPage.checkTableRowForData('Rome') as string); + rowData = (rowData.replace('Delete', '')).trim(); + expect('7 Rome Joseph United States, Denver, Colorado American Titus Global Tech-Inc Sergeant-at-arms 2 Steam').to.equal(rowData); + await browser.sleep(2000) + }); \ No newline at end of file diff --git a/e2e/src/step_definition/security.definitions.ts b/e2e/src/step_definition/security.definitions.ts new file mode 100644 index 0000000..fde6fd4 --- /dev/null +++ b/e2e/src/step_definition/security.definitions.ts @@ -0,0 +1,32 @@ +import { Given, When , Then } from 'cucumber'; +import { element , browser } from 'protractor'; +import { SecurityPage } from '../po/security.po'; + + + +const chai = require('chai').use(require('chai-as-promised')); +const expect = chai.expect; + +Given ('I am on the login page', async function() { + + await browser.get('http://localhost:4200/login'); + +}); + + When('I log in', async function () { + + await SecurityPage.login(); + + }); + + Then('I should be redirected to the dashboard', async function () { + + await browser.sleep(1000); + expect(await browser.getCurrentUrl()).to.equal('http://localhost:4200/dashboard'); + + }); + + + + + diff --git a/e2e/src/step_definition/update.definitions.ts b/e2e/src/step_definition/update.definitions.ts new file mode 100644 index 0000000..75730ad --- /dev/null +++ b/e2e/src/step_definition/update.definitions.ts @@ -0,0 +1,63 @@ +import { Given, When, Then } from 'cucumber'; +import { browser, element, by} from 'protractor'; +import { UpdatePage } from '../po/update.po'; +import { MessagePage } from '../po/message.po' +import { DashboardPage } from '../po/dashboard.po'; + +const chai = require('chai').use(require('chai-as-promised')); +const expect = chai.expect; + + +Given('Im at the dashboard to update info', async function () { + await browser.sleep(1000); + + const currentUrl = await browser.getCurrentUrl(); + const dashboardUrl = 'http://localhost:4200/dashboard'; + + if (currentUrl !== dashboardUrl) { + await browser.get(dashboardUrl); + } + + const dashboardElemenet = element(by.tagName('app-dashboard')); + if (!(await dashboardElemenet.isPresent())) { + throw Error ('The user is not on the dashboard page'); + } + + }); + + + +When('I update the selected employee', async function () { + + await UpdatePage.updateEmployee(); + await browser.sleep(1000); + + +}); + +Then('I should view the success message {string}', async function(expectedMessage: string){ + + const messageObject = MessagePage.successUpdateMessage; + + expect( true, 'The success message was not displayed').to.equal(await messageObject.isPresent()); + expect( await messageObject.getText(), 'The success message did not match the expected message').to.equal(expectedMessage); + + await DashboardPage.successMessage(); + +}) + +Then('I should see the new info saved', async function () { + + let rowData: string; + + if (!(await DashboardPage.checkTableRowForData('Jerrica Azupardo'))) { + await DashboardPage.tableNextPageButton.click(); + await browser.sleep(1000); + } + + rowData = (await DashboardPage.checkTableRowForData('Jerrica') as string); + rowData = (rowData.replace('Delete', '')).trim(); + expect('8 Jerrica Azupardo France Filipino Titus Global idk 2 years Monster Gulf').to.equal(rowData); + + await browser.sleep(1000) +}); \ No newline at end of file