diff --git a/index.js b/index.js index 2ba8335..13b79df 100644 --- a/index.js +++ b/index.js @@ -13,7 +13,7 @@ import dashboardMyStandards from './tests/dashboardMyStandards.js'; import ExACT_contentPage from './tests/ExACT_contentPage.js'; import ExACT_editItem from './tests/ExACT_editItem.js'; //Align -import ExACT_alignContentPage from './tests/ExACT_alignContentPage.js'; +import alignContentPage from './tests/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'; @@ -49,7 +49,7 @@ app.get('/', (req, res) => {
Edit Item

ALIGN

-
Align Content Page
+
Align Content Page
Align - Edit Content and Align Concept
Align Standards Page
Align Concepts Page
@@ -82,7 +82,7 @@ app.get('/', (req, res) => { //Edit Item app.get('/ExACT_editItem', ExACT_editItem); //Align - app.get('/ExACT_alignContentPage', ExACT_alignContentPage); + app.get('/alignContentPage', alignContentPage); app.get('/ExACT_alignStandardsPage', ExACT_alignStandardsPage); app.get('/ExACT_editItemAddConcept', ExACT_editItemAddConcept); app.get('/ExACT_alignConceptsPage', ExACT_alignConceptsPage); diff --git a/tests/ExACT_alignContentPage.js b/tests/alignContentPage.js similarity index 91% rename from tests/ExACT_alignContentPage.js rename to tests/alignContentPage.js index 4adf7f3..6917082 100644 --- a/tests/ExACT_alignContentPage.js +++ b/tests/alignContentPage.js @@ -1,44 +1,194 @@ -import { Builder, By, Key, until } from 'selenium-webdriver'; -import fs from 'fs'; +import { Builder, By, Key, until, Select, Browser } from 'selenium-webdriver'; +import { Options as ChromeOptions } from 'selenium-webdriver/chrome.js'; +import fs, { link } from 'fs'; import XLSX from 'xlsx'; import path from 'path'; -const ExACT_alignContentPage = (req, res) => { - res.send('

ExACT Automated Test Script: Align Content Page(ExACT_alignContentPage); Initiated

'); +const alignContentPage = (req, res) => { + res.send('

ExACT Automated Test Script: Align Content Page(alignContentPage); Initiated

'); (async function example() { - let driver = await new Builder().forBrowser('chrome').build(); + let driver = await new Builder() + .forBrowser('chrome') + .setChromeOptions( + new ChromeOptions() + .addArguments('--disable-features=MediaRouter') + .addArguments('--disable-extensions') + .addArguments('--disable-background-networking') + .addArguments('--log-level=3') + ) + .build(); let testStatus = 'Failed'; let workbook; let worksheet; const startTime = new Date().toISOString(); +//CONSTANTS +//My Content Widget +const myContentItemTotals = '5038 items'; + 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: 'Navigate to ExACT Landing Page', action: async () => await driver.navigate().to('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', + //Login + { + description: 'Login', action: async () => { - return await driver.wait(until.elementLocated(By.linkText('View Details')), 10000).catch(() => false); + const multipleChecks = 'Log In'; + + console.log('------------->| ALIGN CONTENT PAGE |<-------------'); + const errors = []; + + await driver.findElement(By.css('.form-control:nth-child(2)')).sendKeys('exact_juan'); + await driver.findElement(By.css('.passfield')).sendKeys('Edgate1!'); + await driver.findElement(By.css('.login')).click(); + console.log('----->| NEXT ACTION: Entered credentials and logged in'); + + //Wait for page readyState + await driver.wait(async () => { + const readyState = await driver.executeScript('return document.readyState'); + return readyState === 'complete'; + }, 30000, 'ExACT Dashboard did not fully load within 30 seconds'); + + //Wait for the dashboard container to exist in DOM + await driver.wait( + until.elementLocated(By.css('.gap-idle-wrap > img')), + 30000, + 'Dashboard image did not appear within 30 seconds' + ); + + //Wait for it to be visible + await driver.wait(async () => { + try { + const img = await driver.findElement(By.css('.gap-idle-wrap > img')); + return await img.isDisplayed(); + } catch (e) { + return false; + } + }, 30000, 'Dashboard image did not become visible within 30 seconds'); + + //Wait for any loading spinners to disappear + await driver.wait(async () => { + try { + const spinners = await driver.findElements(By.css('.spinner-border')); + for (const spinner of spinners) { + if (await spinner.isDisplayed()) return false; + } + return true; + } catch (e) { + return true; + } + }, 30000, 'Loading spinners did not disappear within 30 seconds'); + + //Wait for the slowest resource to complete + await driver.wait(async () => { + const completed = await driver.executeScript(` + const entries = performance.getEntriesByType('resource'); + return entries.some(entry => + entry.name.includes('content_sets.php') && + entry.responseEnd > 0 + ); + `); + return completed; + }, 30000, 'My Content widget (content_sets.php) did not complete loading within 30 seconds'); + console.log('Passed: My Content widget (content_sets.php) loaded successfully - Dashboard fully loaded'); + + //Final sleep to allow any remaining dynamic content to settle + await driver.sleep(2000); + + console.log('Passed: ExACT Dashboard loaded successfully'); + + if (errors.length > 0) { + if (errors.length > 1) { + errors.unshift(`${multipleChecks} - Multiple validation checks did not pass`); + } + throw new Error(errors.join('\n')); + } } }, //Dashboard title { - description: 'Validate dashboard title', + description: 'Dashboard title text, size, and color', action: async () => { - const elementText = await driver.findElement(By.css('.e-heading')).getText(); - if (elementText !== 'Correlation Dashboard') { - throw new Error(`Expected: "Correlation Dashboard"; Actual: "${elementText}"`); + const multipleChecks = 'Dashboard title'; + + const element = await driver.findElement(By.css('.e-heading')); + + //Get text, font, size, and color + const elementText = await element.getText(); + const elementFont = await element.getCssValue('font-family'); + const elementSize = await element.getCssValue('font-size'); + const elementColor = await element.getCssValue('color'); + + //Track all errors + const errors = []; + + //text + if (elementText === 'Correlation Dashboard') { + console.log('Passed: Dashboard title text matched as expected'); + } else { + errors.push(`Expected: "Correlation Dashboard"; Actual: "${elementText}"`); } - console.log('Passed: Dashboard title matched as expected'); + + //font + if (elementFont === `"DM Serif Display", serif`) { + console.log('Passed: Dashboard title font-family matched as expected'); + } else { + errors.push(`Expected: Dashboard title font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + } + + //size + if (elementSize === '32px') { + console.log('Passed: Dashboard title text font-size matched as expected'); + } else { + errors.push(`Expected: Dashboard title text font-size "32px"; Actual: "${elementSize}"`); + } + + //color + if (elementColor === 'rgba(40, 39, 90, 1)') { + console.log('Passed: Dashboard title text color matched as expected'); + } else { + errors.push(`Expected: Dashboard title text color: "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); + } + + //Throw summary if any validation failed + if (errors.length > 0) { + //Add summary line only when multiple checks failed + if (errors.length > 1) { + errors.unshift(`${multipleChecks} - Multiple validation checks did not pass`); + } + + //Throw collected messages — catch() will prefix with "FAILED:" + throw new Error(errors.join('\n')); + } + } + }, +/* + //NEXT ACTION + { + description: 'Click Frameworks navigation link', + action: async () => { + await driver.findElement(By.linkText('Frameworks')).click(); + console.log('----->| NEXT ACTION: Clicked Frameworks navigation link'); + + //Wait for page readyState + await driver.wait(async () => { + const readyState = await driver.executeScript('return document.readyState'); + return readyState === 'complete'; + }, 30000, 'ExACT Dashboard did not fully load within 30 seconds'); + + //Wait until the element exists in the DOM + const pageTitle = await driver.wait( + until.elementLocated(By.css('h2')), + 30000 + ); + + //Wait until it becomes visible + await driver.wait( + until.elementIsVisible(pageTitle), + 30000 + ); } }, @@ -2260,19 +2410,50 @@ const steps = [ - - //LOG OUT - //NEXT ACTION - Log out - { description: 'Click Username dropdown', action: async () => await driver.findElement(By.css('#navbarDropdown > span')).click() }, - { description: 'Wait for action to complete', action: async () => await driver.sleep(2000) }, - { description: 'Click Log Out link', action: async () => await driver.findElement(By.linkText('Log Out')).click() }, - { description: 'Wait for action to complete', action: async () => await driver.sleep(2000) }, - - //Wait for login screen to load +*/ + //NEXT ACTION { - description: 'Wait for log out process to complete', + description: 'Log Out', action: async () => { - return await driver.wait(until.elementLocated(By.css('.login')), 10000).catch(() => false); + const multipleChecks = 'Log Out'; + + //Track all errors + const errors = []; + + await driver.findElement(By.css('#navbarDropdown > span')).click(); + await driver.sleep(2000); + await driver.findElement(By.linkText('Log Out')).click(); + console.log('----->| NEXT ACTION: Clicked User Profile and Logged Out'); + + //Wait until the element exists in the DOM + const exactLogo = await driver.wait( + until.elementLocated(By.css('.logo')), + 30000 + ); + + //Wait until it becomes visible + await driver.wait( + until.elementIsVisible(exactLogo), + 30000 + ); + + //Wait for page to load completely + await driver.wait(async () => { + const readyState = await driver.executeScript('return document.readyState'); + return readyState === 'complete'; + }, 30000, 'ExACT Langing page did not fully load within 30 seconds'); + console.log('Passed: ExACT Landing Page loaded successfully'); + + //Throw summary if any validation failed + if (errors.length > 0) { + //Add summary line only when multiple checks failed + if (errors.length > 1) { + errors.unshift(`${multipleChecks} - Multiple validation checks did not pass`); + } + + //Throw collected messages — catch() will prefix with "FAILED:" + throw new Error(errors.join('\n')); + } } }, ]; @@ -2360,19 +2541,23 @@ try { ); console.error(`Step ${stepIndex} FAILED: ${error.message}`); + failedSteps.push(`Step ${stepIndex}: ${step.description} - ${error.message}`); //Track failed step testStatus = 'Failed'; allStepsPassed = false; } } //Check if log out was successful - const loginButton = await driver.wait(until.elementLocated(By.css('.login')), 5000).catch(() => false); - - if (loginButton && allStepsPassed) { - console.log('PASSED: Align - Edit Content and Align Concept(ExACT_alignContentPage); All test steps completed successfully'); + + if (allStepsPassed) { + console.log('------------->| THE END |<-------------'); + console.log('PASSED: Align - Content Page(alignContentPage); All test steps completed successfully'); testStatus = 'Passed'; } else { - console.log('FAILED: Align - Edit Content and Align Concept(ExACT_alignContentPage); One or more test steps failed'); + console.log('------------->| THE END |<-------------'); + console.log('FAILED: Align - Content Page(alignContentPage); One or more test steps failed'); + console.log('FAILED STEPS:'); + failedSteps.forEach(step => console.error(` ✗ ${step}`)); testStatus = 'Failed'; } @@ -2389,4 +2574,4 @@ try { })(); } -export default ExACT_alignContentPage; +export default alignContentPage;