From 371bb2024b65c57b82dffb0d849052bbb31a415c Mon Sep 17 00:00:00 2001 From: jhuerta Date: Fri, 4 Apr 2025 15:08:31 -0700 Subject: [PATCH] Added Framework Management Script --- frameworkManagementPageResults.xlsx | Bin 0 -> 26361 bytes index.js | 7 + tests/ExACT_frameworkManagementPage.js | 389 +++++++++++++++++++++++++ 3 files changed, 396 insertions(+) create mode 100644 frameworkManagementPageResults.xlsx create mode 100644 tests/ExACT_frameworkManagementPage.js diff --git a/frameworkManagementPageResults.xlsx b/frameworkManagementPageResults.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..03968328c3b134f28e7dec342ddbe30aa773487f GIT binary patch literal 26361 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 literal 0 HcmV?d00001 diff --git a/index.js b/index.js index b550cf9..04d38ea 100644 --- a/index.js +++ b/index.js @@ -12,6 +12,8 @@ import ExACT_alignContentPage from './tests/ExACT_alignContentPage.js'; import ExACT_alignStandardsPage from './tests/ExACT_alignStandardsPage.js'; import ExACT_editItemAddConcept from './tests/ExACT_editItemAddConcept.js'; import ExACT_alignConceptsPage from './tests/ExACT_alignConceptsPage.js'; +//Framework +import ExACT_frameworkManagementPage from './tests/ExACT_frameworkManagementPage.js'; const app = express(); @@ -43,6 +45,9 @@ app.get('/', (req, res) => {

+ +

FRAMEWORKS

+
`); @@ -64,6 +69,8 @@ app.get('/ExACT_contentPage', ExACT_contentPage); app.get('/ExACT_alignStandardsPage', ExACT_alignStandardsPage); app.get('/ExACT_editItemAddConcept', ExACT_editItemAddConcept); app.get('/ExACT_alignConceptsPage', ExACT_alignConceptsPage); +//Framework + app.get('/ExACT_frameworkManagementPage', ExACT_frameworkManagementPage); app.listen(8000, () => { console.log('Server is running on port 8000'); diff --git a/tests/ExACT_frameworkManagementPage.js b/tests/ExACT_frameworkManagementPage.js new file mode 100644 index 0000000..ea13f67 --- /dev/null +++ b/tests/ExACT_frameworkManagementPage.js @@ -0,0 +1,389 @@ +import { Builder, By, Key, until } from 'selenium-webdriver'; +import fs from 'fs'; +import XLSX from 'xlsx'; +import path from 'path'; + +const ExACT_frameworkManagementPage = (req, res) => { + res.send('

ExACT Automated Test Script - Framework Management Page: Initiated

'); + (async function example() { + let driver = await new Builder().forBrowser('chrome').build(); + let testStatus = 'Failed'; + let workbook; + let worksheet; + const startTime = new Date().toISOString(); + +const steps = [ + { description: 'Navigate to ExACT Landing Page', action: async () => await driver.navigate().to('https://stage.edgate.com/exact/login.php') }, //PROD - https://correlation.edgate.com/exact/login.php + { description: 'Expand browser', action: async () => await driver.manage().window().maximize() }, + + //LOGIN + { description: 'Enter username', action: async () => await driver.findElement(By.css('.form-control:nth-child(2)')).sendKeys('exact_juan') }, + { description: 'Enter password', action: async () => await driver.findElement(By.css('.passfield')).sendKeys('Edgate1!') }, + { description: 'Click Login button', action: async () => await driver.findElement(By.css('.login')).click() }, + { description: 'Wait for login process to complete', action: async () => await driver.sleep(10000) }, + + //Wait for dashboard to load - Correlation Coverages View Details button + { + description: 'Wait for dashboard load to completely', + action: async () => { + return await driver.wait(until.elementLocated(By.linkText('View Details')), 10000).catch(() => false); + } + }, + + //Dashboard title + { + description: 'Validate dashboard title', + action: async () => { + const elementText = await driver.findElement(By.css('.e-heading')).getText(); + if (elementText !== 'Correlation Dashboard') { + throw new Error(`Expected: "Correlation Dashboard"; Actual: "${elementText}"`); + } + console.log('Passed: Dashboard title matched as expected'); + } + }, + + //Align icon color -gray + { + description: 'Validate Align icon color', + action: async () => { + const elementStyle = await driver.findElement(By.css('.fb-align')).getCssValue('color'); + if (elementStyle !== 'rgba(99, 99, 99, 1)') { + throw new Error(`Align icon color did not match; Actual: "${elementStyle}"`); + } + console.log('Passed: Align icon color matched as expected'); + } + }, + + //NEXT ACTION - Navigate to Framework Management page + { description: 'Click Frameworks navigation link', action: async () => await driver.findElement(By.linkText('Frameworks')).click() }, + + //Wait for page to load - Correlation Coverages View Details button + { + description: 'Wait for page to load', + action: async () => { + return await driver.wait(until.elementLocated(By.css('h2')), 10000).catch(() => false); + } + }, + + //Framework Management page title + { + description: 'Validate Framework Management page title', + action: async () => { + const elementText = await driver.findElement(By.css('h2')).getText(); + if (elementText !== 'Framework Management') { + throw new Error(`Expected: "Framework Management"; Actual: "${elementText}"`); + } + console.log('Passed: Framework Management page title matched as expected'); + } + }, + + //Framework Management page title text color -dark blue + { + description: 'Validate Framework Management page title text color', + action: async () => { + const elementStyle = await driver.findElement(By.css('h2')).getCssValue('color'); + if (elementStyle !== 'rgba(40, 39, 90, 1)') { + throw new Error(`Framework Management page title text color did not match; Actual: "${elementStyle}"`); + } + console.log('Passed: Framework Management page title text color matched as expected'); + } + }, + + //Framework Management page title text font + { + description: 'Validate Framework Management page title text font size', + action: async () => { + const elementStyle = await driver.findElement(By.css('h2')).getCssValue('font-size'); + if (elementStyle !== '32px') { + throw new Error(`Framework Management page title text font-size did not match; Actual: "${elementStyle}"`); + } + console.log('Passed: Framework Management page title text font-size matched as expected'); + } + }, + + //Publishing button icon + { + description: 'Verify Publishing buttion icon is present', + action: async () => + { const expectedIcon = await driver.wait(until.elementLocated(By.css('.btn > .fa-cloud-upload')), 5000).catch(() => false); + if (!expectedIcon) { + throw new Error('Publishing button icon not found'); + } + console.log('Passed: Publishing button icon present'); + } + }, + + //Publishing button text + { + description: 'Validate Publishing button text', + action: async () => { + const elementText = await driver.findElement(By.linkText('Publishing')).getText(); + if (elementText !== 'Publishing') { + throw new Error(`Expected: "Publishing" button text; Actual: "${elementText}"`); + } + console.log('Passed: Publsining button text matched as expected'); + } + }, + + //Publishing button color -green + { + description: 'Validate Publishing button color', + action: async () => { + const elementStyle = await driver.findElement(By.linkText('Publishing')).getCssValue('background-color'); + if (elementStyle !== 'rgba(48, 200, 172, 1)') { + throw new Error(`Publishing button color did not match; Actual: "${elementStyle}"`); + } + console.log('Passed: Publishing button color matched as expected'); + } + }, + + //Import Framework button icon + { + description: 'Verify Import Framework buttion icon is present', + action: async () => + { const expectedIcon = await driver.wait(until.elementLocated(By.css('.fa-upload')), 5000).catch(() => false); + if (!expectedIcon) { + throw new Error('Import Framework button icon not found'); + } + console.log('Passed: Import Framework button icon present'); + } + }, + + //Import Framework button text + { + description: 'Validate Import Framework button text', + action: async () => { + const elementText = await driver.findElement(By.linkText('Import Framework')).getText(); + if (elementText !== 'Import Framework') { + throw new Error(`Expected: "Import Framework" button text; Actual: "${elementText}"`); + } + console.log('Passed: Import Framework button text matched as expected'); + } + }, + + //Import Framework button color -green + { + description: 'Validate Import Framework button color', + action: async () => { + const elementStyle = await driver.findElement(By.linkText('Import Framework')).getCssValue('background-color'); + if (elementStyle !== 'rgba(48, 200, 172, 1)') { + throw new Error(`Import Framework button color did not match; Actual: "${elementStyle}"`); + } + console.log('Passed: Import Framework button color matched as expected'); + } + }, + + //Create button icon + { + description: 'Verify Create buttion icon is present', + action: async () => + { const expectedIcon = await driver.wait(until.elementLocated(By.css('.fa-plus-circle')), 5000).catch(() => false); + if (!expectedIcon) { + throw new Error('Create button icon not found'); + } + console.log('Passed: Create button icon present'); + } + }, + + //Create button text + { + description: 'Validate Create button text', + action: async () => { + const elementText = await driver.findElement(By.linkText('Create')).getText(); + if (elementText !== 'Create') { + throw new Error(`Expected: "Create" button text; Actual: "${elementText}"`); + } + console.log('Passed: Create button text matched as expected'); + } + }, + + //Create button color -green + { + description: 'Validate Create button color', + action: async () => { + const elementStyle = await driver.findElement(By.linkText('Create')).getCssValue('background-color'); + if (elementStyle !== 'rgba(48, 200, 172, 1)') { + throw new Error(`Create button color did not match; Actual: "${elementStyle}"`); + } + console.log('Passed: Create button color matched as expected'); + } + }, + + //Search textbox + { + description: 'Verify Search textbox is present', + action: async () => + { const expectedIcon = await driver.wait(until.elementLocated(By.css('#FilterOrganization')), 5000).catch(() => false); + if (!expectedIcon) { + throw new Error('Search textbox not found'); + } + console.log('Passed: Search textbox present'); + } + }, + + //Search textbox icon + { + description: 'Verify Search textbox icon is present', + action: async () => + { const expectedIcon = await driver.wait(until.elementLocated(By.css('.fa-times')), 5000).catch(() => false); + if (!expectedIcon) { + throw new Error('Search textbox icon not found'); + } + console.log('Passed: Search textbox icon present'); + } + }, + + //Advanced Search button icon + { + description: 'Verify Advanced Search buttion icon is present', + action: async () => + { const expectedIcon = await driver.wait(until.elementLocated(By.css('.fa-plus-circle')), 5000).catch(() => false); + if (!expectedIcon) { + throw new Error('Advanced Search button icon not found'); + } + console.log('Passed: Advanced Search button icon present'); + } + }, + + //Advanced Search button text + { + description: 'Validate Advanced Search button text', + action: async () => { + const elementText = await driver.findElement(By.css('.bg-green')).getText(); + if (elementText !== 'Advanced Search') { + throw new Error(`Expected: "Advanced Search" button text; Actual: "${elementText}"`); + } + console.log('Passed: Advanced Search button text matched as expected'); + } + }, + + //Advanced Search button color -green (slightly different green color) + { + description: 'Validate Advanced Search button color', + action: async () => { + const elementStyle = await driver.findElement(By.css('.bg-green')).getCssValue('background-color'); + if (elementStyle !== 'rgba(26, 187, 156, 1)') { + throw new Error(`Advanced Search button color did not match; Actual: "${elementStyle}"`); + } + console.log('Passed: Advanced Search button color matched as expected'); + } + }, + + + + + //LOG OUT + //NEXT ACTION - Log out + { description: 'Click Username dropdown', action: async () => await driver.findElement(By.css('#navbarDropdown > span')).click() }, + { description: 'Wait action to complete', action: async () => await driver.sleep(2000) }, + + //Log Out icon + { + description: 'Verify Log Out icon is present', + action: async () => + { const expectedIcon = await driver.wait(until.elementLocated(By.css('.fa-sign-out')), 5000).catch(() => false); + if (!expectedIcon) { + throw new Error('Log Out icon not found'); + } + console.log('Passed: Log Out icon present'); + } + }, + + { description: 'Click Log Out link', action: async () => await driver.findElement(By.linkText('Log Out')).click() }, + + //Wait for login screen to load + { + description: 'Wait for log out process to complete', + action: async () => { + return await driver.wait(until.elementLocated(By.css('.login')), 10000).catch(() => false); + } + }, + +]; + +const logStep = (worksheet, stepDescription, status, stepIndex, timestamp, screenshotPath) => { + const json_data = XLSX.utils.sheet_to_json(worksheet, { header: 1 }); + json_data.push([stepIndex, stepDescription, status, timestamp, screenshotPath]); + return XLSX.utils.aoa_to_sheet(json_data); +}; + +const takeScreenshot = async (driver, stepIndex, stepDescription) => { + const screenshot = await driver.takeScreenshot(); + + const dir = path.join('screenshots', 'frameworkManagementPage'); + + const screenshotFileName = `step_${stepIndex}_${stepDescription.replace(/\s+/g, '_')}.png`; + const screenshotPath = path.join(dir, screenshotFileName); + fs.writeFileSync(screenshotPath, screenshot, 'base64'); + return screenshotPath; +}; + +const clearOldResults = () => { + // Remove old screenshots + const screenshotDir = path.join('screenshots', 'frameworkManagementPage'); + if (fs.existsSync(screenshotDir)) { + fs.rmSync(screenshotDir, { recursive: true, force: true }); + } + fs.mkdirSync(screenshotDir, { recursive: true }); + + // Remove old Excel file + if (fs.existsSync('frameworkManagementPageResults.xlsx')) { + fs.unlinkSync('frameworkManagementPageResults.xlsx'); + } +}; + +try { + // Initialize workbook and worksheet + clearOldResults(); + + // Initialize workbook and worksheet + workbook = XLSX.utils.book_new(); + worksheet = XLSX.utils.aoa_to_sheet([ + ['Step Number', 'Step Description', 'Status', 'Timestamp', 'Screenshot'] + ]); + XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1'); + + // Log test start time + worksheet = logStep(worksheet, 'Test Start', 'Started', '', startTime, ''); + + for (const step of steps) { + const stepIndex = steps.indexOf(step) + 1; + const timestamp = new Date().toISOString(); + + try { + await step.action(); + const screenshotPath = await takeScreenshot(driver, stepIndex, step.description); + worksheet = logStep(worksheet, step.description, 'Passed', stepIndex, timestamp, screenshotPath); + } catch (error) { + const screenshotPath = await takeScreenshot(driver, stepIndex, `${step.description}_Failed`); + worksheet = logStep(worksheet, step.description, 'Failed', stepIndex, timestamp, screenshotPath); + console.error(`Step ${stepIndex} FAILED: ${error.message}`); + testStatus = 'Failed'; + } + } + + //Check if login was successful + const loginButton = await driver.wait(until.elementLocated(By.css('.login')), 5000).catch(() => false); + + if (loginButton) { + console.log('COMPLETED Script: frameworkManagementPage'); + testStatus = 'Passed'; + } else { + console.log('FAILED: Unable to complete frameworkManagementPage script'); + testStatus = 'Failed'; + } + + // Log test end time + const endTime = new Date().toISOString(); + worksheet = logStep(worksheet, 'Test End', testStatus, '', endTime, ''); + + // Write the updated worksheet back to the workbook and save it + workbook.Sheets['Sheet1'] = worksheet; + XLSX.writeFile(workbook, 'frameworkManagementPageResults.xlsx'); +} finally { + await driver.quit(); +} +})(); +} + +export default ExACT_frameworkManagementPage;