diff --git a/e2e/src/feature/employee/employee.feature b/e2e/src/feature/employee/employee.feature new file mode 100644 index 0000000..adfdcb8 --- /dev/null +++ b/e2e/src/feature/employee/employee.feature @@ -0,0 +1,21 @@ +@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: Delete an Existing Employee + Given I am on the dashboard page + When I delete an existing employee + Then I should see if the deleted record was not in the table anymore + +Scenario: Update an Existing Employee + Given I am on the dashboard for update + When I update an existing employee + Then I should see the success message in update "Success: Data has been updated!" + And I should see the updated employee record in the list \ 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..0748206 --- /dev/null +++ b/e2e/src/po/dashboard.po.ts @@ -0,0 +1,36 @@ +import { element, by, ElementFinder } 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.removexxbut.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 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 removexxbut(){ + return element(by.css('li')); +}} diff --git a/e2e/src/po/delete.po.ts b/e2e/src/po/delete.po.ts new file mode 100644 index 0000000..aee2ba7 --- /dev/null +++ b/e2e/src/po/delete.po.ts @@ -0,0 +1,17 @@ +import { element, by } 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..390531d --- /dev/null +++ b/e2e/src/po/form.po.ts @@ -0,0 +1,30 @@ +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('5 years'); + + await this.getFormControlElement('dataSource').click(); + // may need to wait for the list + await browser.sleep(1000); + await element.all(by.tagName('p-dropdownitem')).get(3).click(); +} + +} diff --git a/e2e/src/po/formupdate.po.ts b/e2e/src/po/formupdate.po.ts new file mode 100644 index 0000000..fefcfbf --- /dev/null +++ b/e2e/src/po/formupdate.po.ts @@ -0,0 +1,30 @@ +import { element, by, browser } from 'protractor'; + + +export class UpdateFormPage { + +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 fillForm() { + await this.getFormControlElement('firstName').sendKeys('asddasd'); + await this.getFormControlElement('lastName').sendKeys('Azusdads'); + await this.getFormControlElement('country').sendKeys('Paridsadss'); + await this.getFormControlElement('nationality').sendKeys('Fildasdipino'); + await this.getFormControlElement('company').sendKeys('Titus Global'); + await this.getFormControlElement('designation').sendKeys('iddsdk'); + await this.getFormControlElement('workExp').sendKeys('2 yeadsadrs'); + + await this.getFormControlElement('dataSource').click(); + // may need to wait for the list + 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..13bfef0 --- /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 successMessageUpdate() { + // return element(by.css('span [class="ui-messages-detail ng-tns-c3-2 ng-star-inserted"]')); + // } +} \ 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..9b9957e --- /dev/null +++ b/e2e/src/po/security.po.ts @@ -0,0 +1,24 @@ +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..ee4ff58 --- /dev/null +++ b/e2e/src/po/update.po.ts @@ -0,0 +1,29 @@ +import { element, by} from 'protractor'; +import { UpdateFormPage } from './formupdate.po'; + + + +export class UpdatePage{ + +static get updateinfo() { + return element(by.tagName('tbody')); +} + +static get table() { + return element(by.tagName('p-table')); +} +static get tableRows() { + return this.table.all(by.tagName('tr')); +} +static async updateEmployee() { + await this.updateinfo.click(); + await UpdateFormPage.fillForm(); + await UpdateFormPage.updateButton.click(); + await this.removexbut.click(); + +} +static get removexbut(){ + return element(by.css('i')); +} + +} \ No newline at end of file diff --git a/e2e/src/step_definition/delete.definitions.ts b/e2e/src/step_definition/delete.definitions.ts new file mode 100644 index 0000000..a87ccf2 --- /dev/null +++ b/e2e/src/step_definition/delete.definitions.ts @@ -0,0 +1,58 @@ +import { Given, When, Then} from 'cucumber'; +import { element, by, browser, } 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 () { + // Write code here that turns the phrase above into concrete actions + let rowData; + + if (!(await DashboardPage.checkTableRowForData('Jerrica Azupardo'))) { + await DashboardPage.tableNextPageButton.click(); + await browser.sleep(5000); + } + rowData = (await DashboardPage.checkTableRowForData('Jerrica Azupardo') as string); + // rowData = (rowData.replace('Delete', '')).trim(); + // expect('8 Jerrica Azupardo France Filipino Titus Global idk 5 years JobsDB').to.equal(rowData); + + + await DeletePage.delEmployee(); + const ale: Alert = browser.switchTo().alert(); + ale.accept(); + await browser.sleep(5000); + + }); +Then('I should see if the deleted record was not in the table anymore', async function () { + // Write code here that turns the phrase above into concrete actions + let rowData; + + if (!(await DashboardPage.checkTableRowForData('Jerrica Azupardo'))) { + await DashboardPage.tableNextPageButton.click(); + await browser.sleep(1000); + } + + rowData = (await DashboardPage.checkTableRowForData('Jerrica Azupardo') as string); + rowData = (rowData.replace('Delete', '')).trim(); + expect('8 Jerrica Azupardo France Filipino Titus Global idk 5 years JobsDB').to.equal(rowData); + }); diff --git a/e2e/src/step_definition/employee.definitions.ts b/e2e/src/step_definition/employee.definitions.ts new file mode 100644 index 0000000..dc863b1 --- /dev/null +++ b/e2e/src/step_definition/employee.definitions.ts @@ -0,0 +1,53 @@ +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) { + // Write code here that turns the phrase above into concrete actions +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); + }); + +Then('I should see the employee record in the list', async function () { + // Write code here that turns the phrase above into concrete actions +let rowData; + +if (!(await DashboardPage.checkTableRowForData('Jerrica Azupardo'))) { + await DashboardPage.tableNextPageButton.click(); + await browser.sleep(1000); +} + + +rowData = (await DashboardPage.checkTableRowForData('Ivan Mercado') as string); +rowData = (rowData.replace('Delete', '')).trim(); +expect('8 Jerrica Azupardo France Filipino Titus Global idk 5 years JobsDB').to.equal(rowData); +}); \ 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..c5e3906 --- /dev/null +++ b/e2e/src/step_definition/security.definitions.ts @@ -0,0 +1,37 @@ +import { Given, When , Then } from 'cucumber'; +import { element , browser, 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'); + // Write code here that turns the phrase above into concrete actions + }); +When('I log in', async function () { +await SecurityPage.login(); + +// // type uaername +// const usernameField = element(by.id('username-field')); +// await usernameField.sendKeys('asd'); +// // type password +// const passwordField = element(by.id('username-field')); +// await passwordField.sendKeys('asd'); +// // click the log in button +// const loginButton = element(by.css('button[label="Login"]')); +// await loginButton.click(); + // Write code here that turns the phrase above into concrete actions + }); +Then('I should be redirected to the dashboard', async function () { +await browser.sleep(3000); +expect(await browser.getCurrentUrl()).to.equal('http://localhost:4200/dashboard'); + // Write code here that turns the phrase above into concrete actions + }); + + + + + diff --git a/e2e/src/step_definition/update.definitions.ts b/e2e/src/step_definition/update.definitions.ts new file mode 100644 index 0000000..c43150f --- /dev/null +++ b/e2e/src/step_definition/update.definitions.ts @@ -0,0 +1,53 @@ +import { Given, When, Then} from 'cucumber'; +import { element, by, browser} from 'protractor'; +import { MessagePage } from '../po/message.po'; +import { UpdatePage } from '../po/update.po'; +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 for update', 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 update an existing employee', async function () { + + await UpdatePage.updateEmployee(); + await browser.sleep(5000); + + }); + + +Then('I should see the success message in update {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); + }); + +Then('I should see the updated employee record in the list', async function () { + let rowData; + + if (!(await DashboardPage.checkTableRowForData('Jerrica Azupardo'))) { + await DashboardPage.tableNextPageButton.click(); + await browser.sleep(1000); + } + + + rowData = (await DashboardPage.checkTableRowForData('Ivan Mercado') as string); + rowData = (rowData.replace('Delete', '')).trim(); + expect('8 Jerrica Azupardo France Filipino Titus Global idk 5 years JobsDB').to.equal(rowData); + }); \ No newline at end of file