import { Builder, By, Key, until, Select } from 'selenium-webdriver'; import { Options as ChromeOptions } from 'selenium-webdriver/chrome.js'; import fs from 'fs'; import XLSX from 'xlsx'; import path from 'path'; import { error } from 'console'; const exactLandingPage = (req, res) => { res.send('

ExACT Automated Test Script: ExACT Landing Page(exactLandingPage) | Initiated

'); (async function example() { 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(); const steps = [ { 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() }, //Loadig page { description: 'Loading Page', action: async () => { console.log('------------->| ExACT LANDING PAGE |<-------------'); //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'); } }, //Left Panel //Header Title { description: 'Left Panel - Header title text, color, and size', action: async () => { const multipleChecks = 'Page title'; const element = await driver.findElement(By.css('h2:nth-child(1)')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Empowering publishers with the ability to correlate their unique content to standards.') { console.log('Passed: Title text matched as expected'); } else { errors.push(`Expected: "Empowering publishers with the ability to correlate their unique content to standards."; Actual: "${elementText}"`); } //font-family if (elementFont === `"DM Serif Display", serif`) { console.log('Passed: Title font matched as expected'); } else { errors.push(`Expected: Title font "DM Serif Display", serif; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(255, 255, 255, 1)') { console.log('Passed: Title text color matched as expected'); } else { errors.push(`Expected: Title text color "rgba(255, 255, 255, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '32px') { console.log('Passed: Title text font-size matched as expected'); } else { errors.push(`Expected: Title text font-size "32px"; Actual: "${elementSize}"`); } //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')); } } }, //Descriptive text 1 { description: 'Validate Landing page descriptive text 1', action: async () => { const multipleChecks = 'Landing page descriptive text 1'; const element = await driver.findElement(By.css('.content-inner > p:nth-child(2)')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'The ExACT platform is the education industry’s most trusted source to globally correlate content to standards and produce content alignment reports.') { console.log('Passed: Descriptive text 1 matched as expected'); } else { errors.push(`Expected: "The ExACT platform is the education industry’s most trusted source to globally correlate content to standards and produce content alignment reports."; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Descriptive text 1 text font matched as expected'); } else { errors.push(`Expected: Descriptive text 1 text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(255, 255, 255, 1)') { console.log('Passed: Descriptive text 1 text color matched as expected'); } else { errors.push(`Expected: Descriptive text 1 text color "rgba(255, 255, 255, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Descriptive text 1 text font-size matched as expected'); } else { errors.push(`Expected: Descriptive text 1 text font-size "14px"; Actual: "${elementSize}"`); } //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')); } } }, //Descriptive text 2 { description: 'Validate Landing page descriptive text 2', action: async () => { const multipleChecks = 'Landing page descriptive text 2'; const element = await driver.findElement(By.css('p:nth-child(3)')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'With access to over five million learning outcomes, ExACT’s robust toolset allows end users to discover new markets for their content, find gaps, and adjust alignments for specific opportunities.') { console.log('Passed: Descriptive text 2 matched as expected'); } else { errors.push(`Expected: "With access to over five million learning outcomes, ExACT’s robust toolset allows end users to discover new markets for their content, find gaps, and adjust alignments for specific opportunities."; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Descriptive text 2 text font matched as expected'); } else { errors.push(`Expected: Descriptive text 2 text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(255, 255, 255, 1)') { console.log('Passed: Descriptive text 2 text color matched as expected'); } else { errors.push(`Expected: Descriptive text 2 text color "rgba(255, 255, 255, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Descriptive text 2 text font-size matched as expected'); } else { errors.push(`Expected: Descriptive text 2 text font-size "14px"; Actual: "${elementSize}"`); } //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')); } } }, //Sign Up text { description: 'Validate sign up text', action: async () => { const multipleChecks = 'Sign Up text'; const element = await driver.findElement(By.css('h4')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Sign Up For A 30 Day Free Trial') { console.log('Passed: Sign up text matched as expected'); } else { errors.push(`Expected: "Sign Up For A 30 Day Free Trial"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Sign up text font matched as expected'); } else { errors.push(`Expected: Sign up text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(255, 255, 255, 1)') { console.log('Passed: Sign up text color matched as expected'); } else { errors.push(`Expected: Sign up text color "rgba(255, 255, 255, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '20px') { console.log('Passed: Sign up text font-size matched as expected'); } else { errors.push(`Expected: Sign up text text font-size "20px"; Actual: "${elementSize}"`); } //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')); } } }, //Free trial link (START WITH) { description: 'Validate free trial link', action: async () => { const multipleChecks = '30 Day Free Trial link'; const element = await driver.findElement(By.linkText('30 Day Free Trial')); //Get href, text, color, and size const linkHref = await element.getAttribute('href'); const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //href if (linkHref.startsWith('https://correlation.edgate.com/exact/trial-registration.php')) { console.log('Passed: 30 Day Free Trail link URL matched as expected'); } else { errors.push(`Expected: "https://correlation.edgate.com/exact/trial-registration.php"; Actual: "${linkHref}"`); } //text if (elementText === '30 Day Free Trial') { console.log('Passed: Free trial link text matched as expected'); } else { errors.push(`Expected: "30 Day Free Trial"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Free trial link text font matched as expected'); } else { errors.push(`Expected: Free trial link text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(255, 111, 97, 1)') { console.log('Passed: Free trial link text color matched as expected'); } else { errors.push(`Expected: Free trial link text color "rgba(255, 111, 97, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '20px') { console.log('Passed: Free trial link text font-size matched as expected'); } else { errors.push(`Expected: Free trial link text text font-size "20px"; Actual: "${elementSize}"`); } //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 Free Trial link', action: async () => { await driver.findElement(By.linkText('30 Day Free Trial')).click(); console.log('----->| NEXT ACTION: Clicked 30 Day Free Trial link'); console.log('---------->| SIGN UP PAGE|<----------'); //Wait until the element exists in the DOM const pageTitle = await driver.wait( until.elementLocated(By.css('h3')), 30000 ); //Wait until it becomes visible await driver.wait( until.elementIsVisible(pageTitle), 30000 ); //Wait for page to load completely await driver.wait(async () => { const readyState = await driver.executeScript('return document.readyState'); return readyState === 'complete'; }, 30000, 'Sign Up page did not fully load within 30 seconds'); console.log('Passed: Sign Up page loaded successfully'); } }, //Left Panel //ExACT logo { description: 'Verify ExACT logo is present', action: async () => { const expectedExactLogo = await driver.wait(until.elementLocated(By.css('.logo')), 5000).catch(() => false); //Track all errors const errors = []; if (expectedExactLogo) { console.log('Passed: ExACT logo present'); } else { errors.push('ExACT logo not found'); } } }, //ExACT text { description: 'Validate ExACT text', action: async () => { const multipleChecks = 'ExACT Free trial text 1'; const element = await driver.findElement(By.css('h2')); //Get text, color, and size const elementText = await element.getText(''); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'ExACT Free Trial') { console.log('Passed: ExACT Free Trial text matched as expected'); } else { errors.push(`Expected: "ExACT Free Trial'"; Actual: "${elementText}"`); } //font-family if (elementFont === `"DM Serif Display", serif`) { console.log('Passed: ExACT Free trial text font matched as expected'); } else { errors.push(`Expected: ExACT Free trial text font "DM Serif Display", serif; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(255, 255, 255, 1)') { console.log('Passed: ExACT Free trial color matched as expected'); } else { errors.push(`Expected: ExACT Free trial color "rgba(255, 255, 255, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '36px') { console.log('Passed: ExACT Free trial text font-size matched as expected'); } else { errors.push(`Expected: ExACT Free trial text font-size "36px"; Actual: "${elementSize}"`); } //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')); } } }, //Free trial text { description: 'Validate Free trial text', action: async () => { const multipleChecks = 'ExACT Free trial text 1'; const element = await driver.findElement(By.css('h2 > span')); //Get text, color, and size const elementText = await element.getText(''); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Free Trial') { console.log('Passed: ExACT Free trial text matched as expected'); } else { errors.push(`Expected: "Free Trial"; Actual: "${elementText}"`); } //font-family if (elementFont === `"DM Serif Display", serif`) { console.log('Passed: ExACT Free trial text font matched as expected'); } else { errors.push(`Expected: ExACT Free trial text font "DM Serif Display", serif; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(255, 111, 97, 1)') { console.log('Passed: ExACT Free trial color matched as expected'); } else { errors.push(`Expected: ExACT Free trial color "rgba(255, 111, 97, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '36px') { console.log('Passed: ExACT Free trial text font-size matched as expected'); } else { errors.push(`Expected: ExACT Free trial text font-size "36px"; Actual: "${elementSize}"`); } //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')); } } }, //30 Day Free Trial,... { description: 'Validate Sign Up page descriptive text 1', action: async () => { const multipleChecks = ' Sign Up page descriptive text 1'; const element = await driver.findElement(By.css('.content-inner > p:nth-child(3)')); //Get text, color, and size const elementText = await element.getText(''); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === '30 Day Free Trial, with loads of benefits!') { console.log('Passed: 30 Day Free trial,...text matched as expected'); } else { errors.push(`Expected: "30 Day Free Trial, with loads of benefits!"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: 30 Day Free trial,...text font matched as expected'); } else { errors.push(`Expected: 30 Day Free trial,...text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(255, 255, 255, 1)') { console.log('Passed: 30 Day Free trial,...text color matched as expected'); } else { errors.push(`Expected: 30 Day Free trial,...text color "rgba(255, 255, 255, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: 30 Day Free trial,...text font-size matched as expected'); } else { errors.push(`Expected: 30 Day Free trial,...text font-size "14px"; Actual: "${elementSize}"`); } //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')); } } }, //See for yourself why ExACT... { description: 'Validate Sign Up page descriptive text 2', action: async () => { const multipleChecks = ' Sign Up page descriptive text 2'; const element = await driver.findElement(By.css('p:nth-child(4)')); //Get text, color, and size const elementText = await element.getText(''); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'See for yourself why ExACT is the leading Standards and Alignment Management System in the Education market. The benefits:') { console.log('Passed: See for yourself why ExACT...text matched as expected'); } else { errors.push(`Expected: "See for yourself why ExACT is the leading Standards and Alignment Management System in the Education market. The benefits:"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: See for yourself why ExACT...text font matched as expected'); } else { errors.push(`Expected: See for yourself why ExACT...text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(255, 255, 255, 1)') { console.log('Passed: See for yourself why ExACT...text color matched as expected'); } else { errors.push(`Expected: See for yourself why ExACT...text color "rgba(255, 255, 255, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: See for yourself why ExACT...text font-size matched as expected'); } else { errors.push(`Expected: See for yourself why ExACT...text font-size "14px"; Actual: "${elementSize}"`); } //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')); } } }, //Absolutely Free (SPECIAL CASE: Text without css path) { description: 'Validate Absolutely Free', action: async () => { const multipleChecks = 'Absolutely Free'; const element = await driver.wait(until.elementLocated(By.css('.free-ico')), 5000).catch(() => false); //Track all errors const errors = []; //icon if (element) { console.log('Passed: Absolutely Free Icon present'); } else { errors.push("Absolutely Free Icon not found"); } //Filter specifically for text nodes (nodeType 3 = text node) const textOnly = await driver.executeScript(` const childNodes = arguments[0].childNodes; for (let node of childNodes) { if (node.nodeType === 3 && node.textContent.trim() !== '') { return node.textContent.trim(); } } `, element); //Get the span text " - no credit card required or hidden fees" const spanText = await driver.executeScript(` const span = arguments[0].querySelector('span'); return span ? span.textContent.trim() : ''; `, element); //Get element font attributes const elementFont = await driver.executeScript(` const style = window.getComputedStyle(arguments[0]); return style.fontFamily; `, element); const elementColor = await driver.executeScript(` const style = window.getComputedStyle(arguments[0]); return style.color; `, element); const elementSize = await driver.executeScript(` const style = window.getComputedStyle(arguments[0]); return style.fontSize; `, element); //Get span font attributes const spanFont = await driver.executeScript(` const span = arguments[0].querySelector('span'); if (!span) return null; const style = window.getComputedStyle(span); return { fontFamily: style.fontFamily, color: style.color, fontSize: style.fontSize }; `, element); //text - Absolutely Free if (textOnly === 'Absolutely Free') { console.log('Passed: Absolutely Free text matched as expected'); } else { errors.push(`Expected: "Absolutely Free"; Actual: "${textOnly}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Absolutely Free text font matched as expected'); } else { errors.push(`Expected: Absolutely Free text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgb(255, 255, 255)') { console.log('Passed: Absolutely Free text color matched as expected'); } else { errors.push(`Expected: Absolutely Free text color "rgb(255, 255, 255)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Absolutely Free text font-size matched as expected'); } else { errors.push(`Expected: Absolutely Free text font-size "14px"; Actual: "${elementSize}"`); } //text - no credit card required or hidden fees if (spanText === '- no credit card required or hidden fees') { console.log('Passed: "- no credit card required or hidden fees" text matched as expected'); } else { errors.push(`Expected: "- no credit card required or hidden fees"; Actual: "${spanText}"`); } //font-family - span if (spanFont?.fontFamily === "Poppins, sans-serif") { console.log('Passed: "- no credit card required or hidden fees" text font matched as expected'); } else { errors.push(`Expected: "- no credit card required or hidden fees" text font "Poppins, sans-serif"; Actual: ${spanFont?.fontFamily}`); } //color if (spanFont?.color === 'rgb(255, 255, 255)') { console.log('Passed: "- no credit card required or hidden fees" text color matched as expected'); } else { errors.push(`Expected: "- no credit card required or hidden fees" text color "rgb(255, 255, 255)"; Actual: "${spanFont?.color}"`); } //font size - span if (spanFont?.fontSize === '14px') { console.log('Passed: "- no credit card required or hidden fees" text font-size matched as expected'); } else { errors.push(`Expected: "- no credit card required or hidden fees" text font-size "14px"; Actual: "${spanFont?.fontSize}"`); } //Throw summary if any validation failed if (errors.length > 0) { if (errors.length > 1) { errors.unshift(`${multipleChecks} - Multiple validation checks did not pass`); } throw new Error(errors.join('\n')); } } }, //Instant Access (SPECIAL CASE: Text without css path) { description: 'Validate Instant Access', action: async () => { const multipleChecks = 'Instant Access'; const element = await driver.wait(until.elementLocated(By.css('.access-ico')), 5000).catch(() => false); //Track all errors const errors = []; //icon if (element) { console.log('Passed: Instant Access Icon present'); } else { errors.push("Instant Access Icon not found"); } //Filter specifically for text nodes (nodeType 3 = text node) const textOnly = await driver.executeScript(` const childNodes = arguments[0].childNodes; for (let node of childNodes) { if (node.nodeType === 3 && node.textContent.trim() !== '') { return node.textContent.trim(); } } `, element); //Get the span text " - no credit card required or hidden fees" const spanText = await driver.executeScript(` const span = arguments[0].querySelector('span'); return span ? span.textContent.trim() : ''; `, element); //Get element font attributes const elementFont = await driver.executeScript(` const style = window.getComputedStyle(arguments[0]); return style.fontFamily; `, element); const elementColor = await driver.executeScript(` const style = window.getComputedStyle(arguments[0]); return style.color; `, element); const elementSize = await driver.executeScript(` const style = window.getComputedStyle(arguments[0]); return style.fontSize; `, element); //Get span font attributes const spanFont = await driver.executeScript(` const span = arguments[0].querySelector('span'); if (!span) return null; const style = window.getComputedStyle(span); return { fontFamily: style.fontFamily, color: style.color, fontSize: style.fontSize }; `, element); //text - Instant Access if (textOnly === 'Instant Access') { console.log('Passed: Instant Accesse text matched as expected'); } else { errors.push(`Expected: "Instant Access"; Actual: "${textOnly}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Instant Access text font matched as expected'); } else { errors.push(`Expected: Instant Access text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgb(255, 255, 255)') { console.log('Passed: Instant Access text color matched as expected'); } else { errors.push(`Expected: Instant Access text color "rgb(255, 255, 255)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Instant Access text font-size matched as expected'); } else { errors.push(`Expected: Absolutely Free text font-size "14px"; Actual: "${elementSize}"`); } //text - Sign up and log-in, it’s that easy if (spanText === `- Sign up and log-in, it’s that easy`) { console.log(`Passed: "- Sign up and log-in, it’s that easy" text matched as expected`); } else { errors.push(`Expected: "- Sign up and log-in, it’s that easy"; Actual: "${spanText}"`); } //font-family - span if (spanFont?.fontFamily === "Poppins, sans-serif") { console.log(`Passed: "- Sign up and log-in, it’s that easy" text font matched as expected`); } else { errors.push(`Expected: "- Sign up and log-in, it’s that easy" text font "Poppins, sans-serif"; Actual: ${spanFont?.fontFamily}`); } //color if (spanFont?.color === 'rgb(255, 255, 255)') { console.log(`Passed: "- Sign up and log-in, it’s that easy" text color matched as expected`); } else { errors.push(`Expected: "- Sign up and log-in, it’s that easy" text color "rgb(255, 255, 255)"; Actual: "${spanFont?.color}"`); } //font size - span if (spanFont?.fontSize === '14px') { console.log(`Passed: "- Sign up and log-in, it’s that easy" text font-size matched as expected`); } else { errors.push(`Expected: "- Sign up and log-in, it’s that easy" text font-size "14px"; Actual: "${spanFont?.fontSize}"`); } //Throw summary if any validation failed if (errors.length > 0) { if (errors.length > 1) { errors.unshift(`${multipleChecks} - Multiple validation checks did not pass`); } throw new Error(errors.join('\n')); } } }, //Access Standards (SPECIAL CASE: Text without css path) { description: 'Validate Access Standards', action: async () => { const multipleChecks = 'Access Standards'; const element = await driver.wait(until.elementLocated(By.css('.standard-ico')), 5000).catch(() => false); //Track all errors const errors = []; //icon if (element) { console.log('Passed: Access Standards Icon present'); } else { errors.push("Access Standards Icon not found"); } //Filter specifically for text nodes (nodeType 3 = text node) const textOnly = await driver.executeScript(` const childNodes = arguments[0].childNodes; for (let node of childNodes) { if (node.nodeType === 3 && node.textContent.trim() !== '') { return node.textContent.trim(); } } `, element); //Get the span text " - no credit card required or hidden fees" const spanText = await driver.executeScript(` const span = arguments[0].querySelector('span'); return span ? span.textContent.trim() : ''; `, element); //Get element font attributes const elementFont = await driver.executeScript(` const style = window.getComputedStyle(arguments[0]); return style.fontFamily; `, element); const elementColor = await driver.executeScript(` const style = window.getComputedStyle(arguments[0]); return style.color; `, element); const elementSize = await driver.executeScript(` const style = window.getComputedStyle(arguments[0]); return style.fontSize; `, element); //Get span font attributes const spanFont = await driver.executeScript(` const span = arguments[0].querySelector('span'); if (!span) return null; const style = window.getComputedStyle(span); return { fontFamily: style.fontFamily, color: style.color, fontSize: style.fontSize }; `, element); //text - Access Standards if (textOnly === 'Access Standards') { console.log('Passed: Access Standards text matched as expected'); } else { errors.push(`Expected: "Access Standards"; Actual: "${textOnly}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Access Standards text font matched as expected'); } else { errors.push(`Expected: Access Standards text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgb(255, 255, 255)') { console.log('Passed: Access Standards text color matched as expected'); } else { errors.push(`Expected: Access Standards text color "rgb(255, 255, 255)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Access Standards text font-size matched as expected'); } else { errors.push(`Expected: Absolutely Free text font-size "14px"; Actual: "${elementSize}"`); } //text - Access all Common Core, NGSS, and NCSS Standards free if (spanText === `- Access all Common Core, NGSS, and NCSS Standards free`) { console.log(`Passed: "- Access all Common Core, NGSS, and NCSS Standards free`); } else { errors.push(`Expected: "- Access all Common Core, NGSS, and NCSS Standards free"; Actual: "${spanText}"`); } //font-family - span if (spanFont?.fontFamily === "Poppins, sans-serif") { console.log(`Passed: "- Access all Common Core, NGSS, and NCSS Standards free" text font matched as expected`); } else { errors.push(`Expected: "- Access all Common Core, NGSS, and NCSS Standards free" text font "Poppins, sans-serif"; Actual: ${spanFont?.fontFamily}`); } //color if (spanFont?.color === 'rgb(255, 255, 255)') { console.log(`Passed: "- Access all Common Core, NGSS, and NCSS Standards free" text color matched as expected`); } else { errors.push(`Expected: "- Access all Common Core, NGSS, and NCSS Standards free" text color "rgb(255, 255, 255)"; Actual: "${spanFont?.color}"`); } //font size - span if (spanFont?.fontSize === '14px') { console.log(`Passed: "- Access all Common Core, NGSS, and NCSS Standards free" text font-size matched as expected`); } else { errors.push(`Expected: "- Access all Common Core, NGSS, and NCSS Standards free" text font-size "14px"; Actual: "${spanFont?.fontSize}"`); } //Throw summary if any validation failed if (errors.length > 0) { if (errors.length > 1) { errors.unshift(`${multipleChecks} - Multiple validation checks did not pass`); } throw new Error(errors.join('\n')); } } }, //Want to talk to a representative... { description: 'Validate Want to talk to a representative', action: async () => { const multipleChecks = 'Want to talk to a representative'; const element = await driver.findElement(By.css('p:nth-child(6)')); //Get text, color, and size const elementText = await element.getText(''); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Want to talk to a representative about a the benefits of a full ExACT license? Contact Us today!') { console.log('Passed: Want to talk to a representative...text matched as expected'); } else { errors.push(`Expected: "Want to talk to a representative about a the benefits of a full ExACT license? Contact Us today!"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Want to talk to a representative...text font matched as expected'); } else { errors.push(`Expected: Want to talk to a representative...text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(255, 255, 255, 1)') { console.log('Passed: Want to talk to a representative...text color matched as expected'); } else { errors.push(`Expected: Want to talk to a representative...text color "rgba(255, 255, 255, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Want to talk to a representative...text font-size matched as expected'); } else { errors.push(`Expected: Want to talk to a representative...text font-size "14px"; Actual: "${elementSize}"`); } //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')); } } }, //Contact Us link { description: 'Validate Contact Us link', action: async () => { const multipleChecks = 'Contact Us link'; const element = await driver.findElement(By.linkText('Contact Us')); //Get href, text, color, and size const linkHref = await element.getAttribute('href'); const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //href if (linkHref === 'https://edgate.com/contact-us') { console.log('Passed: Contact Us link URL matched as expected'); } else { errors.push(`Expected: "https://edgate.com/contact-us"; Actual: "${linkHref}"`); } //text if (elementText === 'Contact Us') { console.log('Passed: Contact Us link text matched as expected'); } else { errors.push(`Expected: "Contact Us"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Contact Us link text font matched as expected'); } else { errors.push(`Expected: Contact Us link text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(48, 200, 172, 1)') { console.log('Passed: Contact Us link text color matched as expected'); } else { errors.push(`Expected: Contact Us link text color "rgba(48, 200, 172, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Contact Us link text font-size matched as expected'); } else { errors.push(`Expected: Contact Us link text text font-size "14px"; Actual: "${elementSize}"`); } //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')); } } }, //Sign Up title { description: 'Validate Sign Up title', action: async () => { const multipleChecks = 'Sign Up title'; const element = await driver.findElement(By.css('h3')); //Get text, color, and size const elementText = await element.getText(''); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Sign Up') { console.log('Passed: Sign Up title text matched as expected'); } else { errors.push(`Expected: "Sign Up"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Sign Up title text font matched as expected'); } else { errors.push(`Expected: Sign Up title text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: Sign Up title color matched as expected'); } else { errors.push(`Expected: Sign Up title color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '24px') { console.log('Passed: Sign Up title text font-size matched as expected'); } else { errors.push(`Expected: Sign Up title text font-size "24px"; Actual: "${elementSize}"`); } //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')); } } }, //Already have an account? { description: 'Validate Already have an account', action: async () => { const multipleChecks = 'Already have an account?'; const element = await driver.findElement(By.css('.alreadyacount')); //Get text, color, and size const elementText = await element.getText(''); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Already have an account? Sign In') { console.log('Passed: Already have an account? Sign In text matched as expected'); } else { errors.push(`Expected: "Already have an account? Sign In"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Already have an account? Sign In text font matched as expected'); } else { errors.push(`Expected: Already have an account? Sign In text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(32, 32, 32, 1)') { console.log('Passed: Already have an account? Sign In color matched as expected'); } else { errors.push(`Expected: Already have an account? Sign In color "rgba(32, 32, 32, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '12px') { console.log('Passed: Already have an account? Sign In text font-size matched as expected'); } else { errors.push(`Expected: Already have an account? Sign In text font-size "12px"; Actual: "${elementSize}"`); } //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')); } } }, //Sign In link { description: 'Validate Sign In link', action: async () => { const multipleChecks = 'Sign In link'; const element = await driver.wait(until.elementLocated(By.css('.alreadyacount > a')), 5000); //Get href, text, and CSS values all from the same element const linkHref = await element.getAttribute('href'); const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //href if (linkHref === 'https://correlation.edgate.com/exact/login.php') { console.log('Passed: Sign In link URL matched as expected'); } else { errors.push(`Expected: "https://correlation.edgate.com/exact/login.php"; Actual: "${linkHref}"`); } //text if (elementText === 'Sign In') { console.log('Passed: Sign In link text matched as expected'); } else { errors.push(`Expected: "Sign In"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Sign In link text font matched as expected'); } else { errors.push(`Expected: Sign In link text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(48, 200, 172, 1)') { console.log('Passed: Sign In link text color matched as expected'); } else { errors.push(`Expected: Sign In link text color "rgba(48, 200, 172, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Sign In link text font-size matched as expected'); } else { errors.push(`Expected: Sign In link text font-size "14px"; Actual: "${elementSize}"`); } //Throw summary if any validation failed if (errors.length > 0) { if (errors.length > 1) { errors.unshift(`${multipleChecks} - Multiple validation checks did not pass`); } throw new Error(errors.join('\n')); } } }, //First name (SPECIAL CASE: Placeholder validation without trigger) { description: 'Validate First name placeholder', action: async () => { const multipleChecks = 'First name placeholder'; const element = await driver.findElement(By.css('#firstname')); //Get text, color, and size const elementText = await element.getAttribute('placeholder'); //Get placeholder styles via executeScript since it's a pseudo-element const elementFont = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-family')`, element ); const elementColor = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('color')`, element ); const elementSize = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-size')`, element ); //Track all errors const errors = []; //text if (elementText === 'First name') { console.log('Passed: First name label text matched as expected'); } else { errors.push(`Expected: "First name"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: First name label text font matched as expected'); } else { errors.push(`Expected: First name label text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgb(108, 117, 125)') { console.log('Passed: First name label text color matched as expected'); } else { errors.push(`Expected: First name label text color "rgb(108, 117, 125)"; Actual: "${elementColor}"`); } //font size if (elementSize === '12.6px') { console.log('Passed: First name label text font-size matched as expected'); } else { errors.push(`Expected: First name label text font-size "12.6px"; Actual: "${elementSize}"`); } //invalid-feedback const feedbackText = await driver.executeScript(` const input = arguments[0]; const feedback = input.parentElement.querySelector('.invalid-feedback'); return feedback ? feedback.textContent.trim() : ''; `, element); if (feedbackText === 'Please enter a first name.') { console.log('Passed: First name invalid feedback validation message matched as expected'); } else { errors.push(`Expected: "Please enter a first name." validation message; Actual: "${feedbackText}"`); } //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')); } } }, //Last name textbox { description: 'Validate Last name textbox', action: async () => { const multipleChecks = 'Last name textbox'; const element = await driver.findElement(By.css('#lastname')); //Get text, color, and size const elementText = await element.getAttribute('placeholder'); //Get placeholder styles via executeScript since it's a pseudo-element const elementFont = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-family')`, element ); const elementColor = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('color')`, element ); const elementSize = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-size')`, element ); //Track all errors const errors = []; //text if (elementText === 'Last name') { console.log('Passed: Last name label text matched as expected'); } else { errors.push(`Expected: "Last name"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Last name label text font matched as expected'); } else { errors.push(`Expected: Last name label text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgb(108, 117, 125)') { console.log('Passed: Last name label text color matched as expected'); } else { errors.push(`Expected: Last name label text color "rgb(108, 117, 125)"; Actual: "${elementColor}"`); } //font size if (elementSize === '12.6px') { console.log('Passed: Last name label text font-size matched as expected'); } else { errors.push(`Expected: Last name label text font-size "12.6px"; Actual: "${elementSize}"`); } //invalid-feedback const feedbackText = await driver.executeScript(` const input = arguments[0]; const feedback = input.parentElement.querySelector('.invalid-feedback'); return feedback ? feedback.textContent.trim() : ''; `, element); if (feedbackText === 'Please enter a last name.') { console.log('Passed: First name invalid feedback validation message matched as expected'); } else { errors.push(`Expected: "Please enter a last name." validation message; Actual: "${feedbackText}"`); } //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')); } } }, //Username textbox { description: 'Validate Username textbox', action: async () => { const multipleChecks = 'Username textbox'; const element = await driver.findElement(By.css('.row:nth-child(5) > .col:nth-child(1) > .form-control')); //Get text, color, and size const elementText = await element.getAttribute('placeholder'); //Get placeholder styles via executeScript since it's a pseudo-element const elementFont = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-family')`, element ); const elementColor = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('color')`, element ); const elementSize = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-size')`, element ); //Track all errors const errors = []; //text if (elementText === 'Username') { console.log('Passed: Username label text matched as expected'); } else { errors.push(`Expected: "Username"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Username label text font matched as expected'); } else { errors.push(`Expected: Username label text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgb(108, 117, 125)') { console.log('Passed: Username label text color matched as expected'); } else { errors.push(`Expected: Username label text color "rgb(108, 117, 125)"; Actual: "${elementColor}"`); } //font size if (elementSize === '12.6px') { console.log('Passed: Username label text font-size matched as expected'); } else { errors.push(`Expected: Username label text font-size "12.6px"; Actual: "${elementSize}"`); } //Trigger validation by clicking Start Your Free Trial button await driver.findElement(By.css('#firstname')).sendKeys('EdgateAutomated'); console.log('----->| NEXT ACTION: Entered First name: EdgateAutomated'); await driver.findElement(By.css('#lastname')).sendKeys('EdGateRegression'); console.log('----->| NEXT ACTION: Entered Last name: EdGateRegression'); await driver.findElement(By.css('.btn')).click(); console.log('----->| NEXT ACTION: Clicked Start Your Free Trial button'); await driver.sleep(500); //Check native HTML5 validation message const validationMessage = await driver.executeScript(` return document.querySelector('input[name="userlogon"]').validationMessage; `); if (validationMessage === 'Please fill out this field.') { console.log('Passed: Username validation message matched as expected'); } else { errors.push(`Expected: "Please fill out this field." validation message; Actual: "${validationMessage}"`); } //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')); } } }, //Password textbox { description: 'Validate Password textbox', action: async () => { const multipleChecks = 'Password textbox'; const element = await driver.findElement(By.css('#password')); const icon = await driver.findElement(By.css('.pass-eye')); //Get text, color, and size const elementText = await element.getAttribute('placeholder'); //Get placeholder styles via executeScript since it's a pseudo-element const elementFont = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-family')`, element ); const elementColor = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('color')`, element ); const elementSize = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-size')`, element ); //Track all errors const errors = []; //text if (elementText === 'Password') { console.log('Passed: Password label text matched as expected'); } else { errors.push(`Expected: "Password"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Password label text font matched as expected'); } else { errors.push(`Expected: Password label text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgb(108, 117, 125)') { console.log('Passed: Password label text color matched as expected'); } else { errors.push(`Expected: Password label text color "rgb(108, 117, 125)"; Actual: "${elementColor}"`); } //font size if (elementSize === '12.6px') { console.log('Passed: Password label text font-size matched as expected'); } else { errors.push(`Expected: Password label text font-size "12.6px"; Actual: "${elementSize}"`); } //icon if (icon) { console.log('Passed: Passkey eye Icon present'); } else { errors.push("Passkey eye Icon not found"); } //Trigger validation by clicking Start Your Free Trial button await driver.findElement(By.css('.row:nth-child(5) > .col:nth-child(1) > .form-control')).sendKeys('EdGateAutomatedRegression'); console.log('----->| NEXT ACTION: Entered Username: EdGateAutomatedRegression'); //invalid-feedback const feedbackText = await driver.executeScript(` const input = arguments[0]; const feedback = input.parentElement.querySelector('.invalid-feedback'); return feedback ? feedback.textContent.trim() : ''; `, element); if (feedbackText === 'Please enter a password (8 or more characters).') { console.log('Passed: Please enter a password (8 or more characters). validation message matched as expected'); } else { errors.push(`Expected: "Please enter a password (8 or more characters)." validation message; Actual: "${feedbackText}"`); } //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')); } } }, //Password Requirements: { description: 'Validate Password Requirements text', action: async () => { const multipleChecks = 'Password Requirements'; const element = await driver.findElement(By.css('.pass-req')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Password Requirements:') { console.log('Passed: Password Requirements: text matched as expected'); } else { errors.push(`Expected: "Password Requirements:"; Actual: "${elementText}"`); } //font-family if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Password Requirements: text font matched as expected'); } else { errors.push(`Expected: Password Requirements: text font "DM Serif Display", serif; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: Password Requirements: text color matched as expected'); } else { errors.push(`Expected: Password Requirements: text color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '15px') { console.log('Passed: Password Requirements: text font-size matched as expected'); } else { errors.push(`Expected: Password Requirements: text font-size "15px"; Actual: "${elementSize}"`); } //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')); } } }, //Must be at least 8 characters. { description: 'Validate Password Req1 text', action: async () => { const multipleChecks = 'Password Req1'; const element = await driver.findElement(By.css('.changeul > li:nth-child(2)')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Must be at least 8 characters.') { console.log('Passed: Must be at least 8 characters. text matched as expected'); } else { errors.push(`Expected: "Must be at least 8 characters."; Actual: "${elementText}"`); } //font-family if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Must be at least 8 characters. text font matched as expected'); } else { errors.push(`Expected: Must be at least 8 characters. text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: Must be at least 8 characters. text color matched as expected'); } else { errors.push(`Expected: Must be at least 8 characters. text color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '13px') { console.log('Passed: Must be at least 8 characters. text font-size matched as expected'); } else { errors.push(`Expected: Must be at least 8 characters. text font-size "13px"; Actual: "${elementSize}"`); } //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')); } } }, //Contain at least one of each: { description: 'Validate Password Req2 text', action: async () => { const multipleChecks = 'Password Req2'; const element = await driver.wait(until.elementLocated(By.css('.changeul > li:nth-child(3)')), 5000); const textOnly = await driver.executeScript(` const childNodes = arguments[0].childNodes; for (let node of childNodes) { if (node.nodeType === 3 && node.textContent.trim() !== '') { return node.textContent.trim(); } } `, element); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (textOnly === 'Contain at least one of each:') { console.log('Passed: Contain at least one of each: text matched as expected'); } else { errors.push(`Expected: "Contain at least one of each:"; Actual: "${textOnly}"`); } //font-family if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Contain at least one of each: text font matched as expected'); } else { errors.push(`Expected: Contain at least one of each: text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: Contain at least one of each: text color matched as expected'); } else { errors.push(`Expected: Contain at least one of each: text color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '13px') { console.log('Passed: Contain at least one of each: text font-size matched as expected'); } else { errors.push(`Expected: Contain at least one of each: text font-size "13px"; Actual: "${elementSize}"`); } //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')); } } }, //Uppercase letter { description: 'Validate Password Req2a text', action: async () => { const multipleChecks = 'Password Req2a'; const element = await driver.findElement(By.css('li li:nth-child(1)')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Uppercase letter') { console.log('Passed: Uppercase letter text matched as expected'); } else { errors.push(`Expected: "Uppercase letter"; Actual: "${elementText}"`); } //font-family if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Uppercase letter text font matched as expected'); } else { errors.push(`Expected: Uppercase letter text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: Uppercase letter text color matched as expected'); } else { errors.push(`Expected: Uppercase letter text color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '13px') { console.log('Passed: Uppercase letter text font-size matched as expected'); } else { errors.push(`Expected: Uppercase letter text font-size "13px"; Actual: "${elementSize}"`); } //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')); } } }, //Lowercase letter { description: 'Validate Password Req2b text', action: async () => { const multipleChecks = 'Password Req2b'; const element = await driver.findElement(By.css('li li:nth-child(2)')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Lowercase letter') { console.log('Passed: Lowercase letter text matched as expected'); } else { errors.push(`Expected: "Lowercase letter"; Actual: "${elementText}"`); } //font-family if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Lowercase letter text font matched as expected'); } else { errors.push(`Expected: Lowercase letter text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: Lowercase letter text color matched as expected'); } else { errors.push(`Expected: Lowercase letter text color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '13px') { console.log('Passed: Lowercase letter text font-size matched as expected'); } else { errors.push(`Expected: Lowercase letter text font-size "13px"; Actual: "${elementSize}"`); } //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')); } } }, //Number { description: 'Validate Password Req2c text', action: async () => { const multipleChecks = 'Password Req2c'; const element = await driver.findElement(By.css('li li:nth-child(3)')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Number') { console.log('Passed: Number text matched as expected'); } else { errors.push(`Expected: "Number"; Actual: "${elementText}"`); } //font-family if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Number text font matched as expected'); } else { errors.push(`Expected: Number text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: Number text color matched as expected'); } else { errors.push(`Expected: Number text color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '13px') { console.log('Passed: Number text font-size matched as expected'); } else { errors.push(`Expected: Number text font-size "13px"; Actual: "${elementSize}"`); } //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')); } } }, //Special character (e.g. - ! @ # $ etc.) { description: 'Validate Password Req2d text', action: async () => { const multipleChecks = 'Password Req2d'; const element = await driver.findElement(By.css('li li:nth-child(4)')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Special character (e.g. - ! @ # $ etc.)') { console.log('Passed: Special character (e.g. - ! @ # $ etc.) text matched as expected'); } else { errors.push(`Expected: "Special character (e.g. - ! @ # $ etc.)"; Actual: "${elementText}"`); } //font-family if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Special character (e.g. - ! @ # $ etc.) text font matched as expected'); } else { errors.push(`Expected: Special character (e.g. - ! @ # $ etc.) text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: Special character (e.g. - ! @ # $ etc.) text color matched as expected'); } else { errors.push(`Expected: Special character (e.g. - ! @ # $ etc.) text color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '13px') { console.log('Passed: Special character (e.g. - ! @ # $ etc.) text font-size matched as expected'); } else { errors.push(`Expected: Special character (e.g. - ! @ # $ etc.) text font-size "13px"; Actual: "${elementSize}"`); } //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')); } } }, //Email address textbox { description: 'Validate Email address textbox', action: async () => { const multipleChecks = 'Email address textbox'; const element = await driver.findElement(By.css('.row:nth-child(6) .form-control')); //Get text, color, and size const elementText = await element.getAttribute('placeholder'); //Get placeholder styles via executeScript since it's a pseudo-element const elementFont = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-family')`, element ); const elementColor = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('color')`, element ); const elementSize = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-size')`, element ); //Track all errors const errors = []; //text if (elementText === 'Email address') { console.log('Passed: Email address label text matched as expected'); } else { errors.push(`Expected: "Email address"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Email address label text font matched as expected'); } else { errors.push(`Expected: Email address label text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgb(108, 117, 125)') { console.log('Passed: Email address label text color matched as expected'); } else { errors.push(`Expected: Email address label text color "rgb(108, 117, 125)"; Actual: "${elementColor}"`); } //font size if (elementSize === '12.6px') { console.log('Passed: Email address label text font-size matched as expected'); } else { errors.push(`Expected: Email address label text font-size "12.6px"; Actual: "${elementSize}"`); } //Trigger validation by clicking Start Your Free Trial button await driver.findElement(By.css('#password')).sendKeys('EdGate123'); console.log('----->| NEXT ACTION: Entered Password: EdGate123'); await driver.findElement(By.css('.btn')).click(); console.log('----->| NEXT ACTION: Clicked Start Your Free Trial button'); await driver.sleep(500); //Check native HTML5 validation message const validationMessage = await driver.executeScript(` return document.querySelector('input[name="email"]').validationMessage; `); if (validationMessage === 'Please fill out this field.') { console.log('Passed: Email validation message matched as expected'); } else { errors.push(`Expected: "Please fill out this field." validation message; Actual: "${validationMessage}"`); } //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')); } } }, //Organization textbox { description: 'Validate Organization textbox', action: async () => { const multipleChecks = 'Organization placeholder'; const element = await driver.findElement(By.css('.row:nth-child(7) > .col:nth-child(1) > .form-control')); //Get text, color, and size const elementText = await element.getAttribute('placeholder'); //Get placeholder styles via executeScript since it's a pseudo-element const elementFont = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-family')`, element ); const elementColor = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('color')`, element ); const elementSize = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-size')`, element ); //Track all errors const errors = []; //text if (elementText === 'Organization') { console.log('Passed: Organization label text matched as expected'); } else { errors.push(`Expected: "Organization"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Organization label text font matched as expected'); } else { errors.push(`Expected: Organization label text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgb(108, 117, 125)') { console.log('Passed: Organization label text color matched as expected'); } else { errors.push(`Expected: Organization label text color "rgb(108, 117, 125)"; Actual: "${elementColor}"`); } //font size if (elementSize === '12.6px') { console.log('Passed: Organization label text font-size matched as expected'); } else { errors.push(`Expected: Organization label text font-size "12.6px"; Actual: "${elementSize}"`); } //invalid-feedback const feedbackText = await driver.executeScript(` const input = arguments[0]; const feedback = input.parentElement.querySelector('.invalid-feedback'); return feedback ? feedback.textContent.trim() : ''; `, element); if (feedbackText === 'Please enter your organization.') { console.log('Passed: Please enter your organization. validation message matched as expected'); } else { errors.push(`Expected: "Please enter your organization." validation message; Actual: "${feedbackText}"`); } //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')); } } }, //Position textbox { description: 'Validate Position textbox', action: async () => { const multipleChecks = 'Position textbox'; const element = await driver.findElement(By.css('.row:nth-child(7) > .col:nth-child(2) > .form-control')); //Get text, color, and size const elementText = await element.getAttribute('placeholder'); //Get placeholder styles via executeScript since it's a pseudo-element const elementFont = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-family')`, element ); const elementColor = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('color')`, element ); const elementSize = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-size')`, element ); //Track all errors const errors = []; //text if (elementText === 'Position') { console.log('Passed: Position label text matched as expected'); } else { errors.push(`Expected: "Position"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Position label text font matched as expected'); } else { errors.push(`Expected: Position label text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgb(108, 117, 125)') { console.log('Passed: Position label text color matched as expected'); } else { errors.push(`Expected: Position label text color "rgb(108, 117, 125)"; Actual: "${elementColor}"`); } //font size if (elementSize === '12.6px') { console.log('Passed: Position label text font-size matched as expected'); } else { errors.push(`Expected: Position label text font-size "12.6px"; Actual: "${elementSize}"`); } //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')); } } }, //Phone number textbox { description: 'Validate Phone number textbox', action: async () => { const multipleChecks = 'Phone number textbox'; const element = await driver.findElement(By.css('.row:nth-child(8) .form-control')); //Get text, color, and size const elementText = await element.getAttribute('placeholder'); //Get placeholder styles via executeScript since it's a pseudo-element const elementFont = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-family')`, element ); const elementColor = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('color')`, element ); const elementSize = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-size')`, element ); //Track all errors const errors = []; //text if (elementText === 'Phone number') { console.log('Passed: Phone number label text matched as expected'); } else { errors.push(`Expected: Phone number"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Phone number label text font matched as expected'); } else { errors.push(`Expected: Phone number label text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgb(108, 117, 125)') { console.log('Passed: Phone number label text color matched as expected'); } else { errors.push(`Expected: Phone number label text color "rgb(108, 117, 125)"; Actual: "${elementColor}"`); } //font size if (elementSize === '12.6px') { console.log('Passed: Phone number label text font-size matched as expected'); } else { errors.push(`Expected: Phone number label text font-size "12.6px"; Actual: "${elementSize}"`); } //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')); } } }, //Terms of service { description: 'Validate Terms of service', action: async () => { const multipleChecks = 'Terms of service'; const elementcheckbox = await driver.wait(until.elementLocated(By.css('#terms')), 5000).catch(() => false); const element = await driver.findElement(By.css('.form-check-label')); //Get icon, text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //icon if (elementcheckbox) { console.log('Passed: Terms of service checkbox present'); } else { errors.push("Terms of service checkbox not found"); } //text if (elementText === 'I agree to the terms of service') { console.log('Passed: I agree to the terms of service text matched as expected'); } else { errors.push(`Expected: "I agree to the terms of service"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: I agree to the terms of service text font matched as expected'); } else { errors.push(`Expected: I agree to the terms of service text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: I agree to the terms of service text color matched as expected'); } else { errors.push(`Expected: I agree to the terms of service text color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '10px') { console.log('Passed: I agree to the terms of service text font-size matched as expected'); } else { errors.push(`Expected: I agree to the terms of service text text font-size "10px"; Actual: "${elementSize}"`); } //Trigger validation by clicking Start Your Free Trial button await driver.findElement(By.css('.row:nth-child(6) .form-control')).sendKeys('EdGateAutomatedRegression@edgate.com'); console.log('----->| NEXT ACTION: Entered Organization: EdGateAutomatedRegression@edgate.com'); await driver.findElement(By.css('.row:nth-child(7) > .col:nth-child(1) > .form-control')).sendKeys('EdGate Inc.'); console.log('----->| NEXT ACTION: Entered Organization: EdGate Inc.'); await driver.findElement(By.css('.btn')).click(); console.log('----->| NEXT ACTION: Clicked Start Your Free Trial button'); await driver.sleep(500); //Check native HTML5 validation message const validationMessage = await driver.executeScript(` return document.querySelector('input[name="terms"]').validationMessage; `); if (validationMessage === 'Please check this box if you want to proceed.') { console.log('Passed: Username validation message matched as expected'); } else { errors.push(`Expected: "Please check this box if you want to proceed." validation message; Actual: "${validationMessage}"`); } //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')); } } }, //Terms of Service link { description: 'Validate Terms of Service link', action: async () => { const multipleChecks = 'Terms of Service link'; const element = await driver.findElement(By.linkText('terms of service')); //Get href, text, color, and size const linkHref = await element.getAttribute('href'); const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //href if (linkHref === 'https://edgate.com/terms-of-service') { console.log('Passed: Terms of Service link URL matched as expected'); } else { errors.push(`Expected: "https://edgate.com/terms-of-service"; Actual: "${linkHref}"`); } //text if (elementText === 'terms of service') { console.log('Passed: terms of service link text matched as expected'); } else { errors.push(`Expected: "terms of service"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: terms of service link text font matched as expected'); } else { errors.push(`Expected: terms of service link text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(48, 200, 172, 1)') { console.log('Passed: terms of service link text color matched as expected'); } else { errors.push(`Expected: terms of service link text color "rgba(48, 200, 172, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '10px') { console.log('Passed: ExACT AutoAlign, link text font-size matched as expected'); } else { errors.push(`Expected: ExACT AutoAlign, link text text font-size "10px"; Actual: "${elementSize}"`); } //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')); } } }, //Start Your Free Trial button { description: 'Validate Start Your Free Trial button', action: async () => { const multipleChecks = 'Start Your Free Trial'; const element = await driver.findElement(By.css('.btn')); //Get text, color, and size const elementText = await element.getAttribute('value'); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('background-color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Start Your Free Trial') { console.log('Passed: Start Your Free Trial button text matched as expected'); } else { errors.push(`Expected: "Start Your Free Trial"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Start Your Free Trial button text font matched as expected'); } else { errors.push(`Expected: Start Your Free Trial button text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: Start Your Free Trial button background color matched as expected'); } else { errors.push(`Expected: Start Your Free Trial button background color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '16px') { console.log('Passed: Start Your Free Trial button text font-size matched as expected'); } else { errors.push(`Expected: Start Your Free Trial button text font-size "16px"; Actual: "${elementSize}"`); } //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')); } } }, //edgate logo { description: 'Verify edgate logo is present', action: async () => { const expectedExactLogo = await driver.wait(until.elementLocated(By.css('.signuplogo > img')), 5000).catch(() => false); //Track all errors const errors = []; if (expectedExactLogo) { console.log('Passed: edgate logo present'); } else { errors.push('edgate logo not found'); } } }, //Copyright 2026 { description: 'Validate Copyright 2026 text', action: async () => { const multipleChecks = 'Copyright 2026'; const element = await driver.findElement(By.css('p:nth-child(2)')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === '© Copyright 2026 EdGate Correlation Services') { console.log('Passed: © Copyright 2026 EdGate Correlation Services text matched as expected'); } else { errors.push(`Expected: "© Copyright 2026 EdGate Correlation Services"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: © Copyright 2026 EdGate Correlation Services text font matched as expected'); } else { errors.push(`Expected: © Copyright 2026 EdGate Correlation Services text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: © Copyright 2026 EdGate Correlation Services text color matched as expected'); } else { errors.push(`Expected: © Copyright 2026 EdGate Correlation Services text color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '12px') { console.log('Passed: © Copyright 2026 EdGate Correlation Services text font-size matched as expected'); } else { errors.push(`Expected: © Copyright 2026 EdGate Correlation Services text text font-size "12px"; Actual: "${elementSize}"`); } //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 Sign In link', action: async () => { await driver.findElement(By.linkText('Sign In')).click(); console.log('----->| NEXT ACTION: Clicked Sign In link'); console.log('---------->| RETURN TO LANDING PAGE|<----------'); //Wait until the element exists in the DOM const pageTitle = await driver.wait( until.elementLocated(By.css('.logo')), 30000 ); //Wait until it becomes visible await driver.wait( until.elementIsVisible(pageTitle), 30000 ); //Wait for page to load completely await driver.wait(async () => { const readyState = await driver.executeScript('return document.readyState'); return readyState === 'complete'; }, 30000, 'Landig page did not fully load within 30 seconds'); console.log('Passed: Landing page loaded successfully'); } }, //Bullet Point 1 { description: 'Validate bullet point 1', action: async () => { const multipleChecks = 'Bullet point 1'; const elementIcon = await driver.wait(until.elementLocated(By.css('li:nth-child(1) img')), 5000).catch(() => false); const element = await driver.findElement(By.css('li:nth-child(1) > .list-flex')); //Get icon, text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //icon if (elementIcon) { console.log('Passed: Bullet Point Icon 1 present'); } else { errors.push("Bullet Point Icon 1 not found"); } //text if (elementText === 'Learn more about ExACT AutoAlign, the AI-based alignment tool.') { console.log('Passed: Bullet point 1 text matched as expected'); } else { errors.push(`Expected: "Learn more about ExACT AutoAlign, the AI-based alignment tool."; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Bullet point 1 text font matched as expected'); } else { errors.push(`Expected: Bullet point 1 text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(255, 255, 255, 1)') { console.log('Passed: Bullet point 1 text color matched as expected'); } else { errors.push(`Expected: Bullet point 1 text color "rgba(255, 255, 255, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Bullet point 1 text font-size matched as expected'); } else { errors.push(`Expected: Bullet point 1 text text font-size "14px"; Actual: "${elementSize}"`); } //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')); } } }, //ExACT AutoAlign, link { description: 'Validate ExACT AutoAlign, link', action: async () => { const multipleChecks = 'ExACT AutoAlign link'; const element = await driver.findElement(By.linkText('ExACT AutoAlign,')); //Get href, text, color, and size const linkHref = await element.getAttribute('href'); const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //href if (linkHref === 'https://edgate.com/systems/exact/autoalign') { console.log('Passed: ExACT AutoAlign link URL matched as expected'); } else { errors.push(`Expected: "https://edgate.com/systems/exact/autoalign"; Actual: "${linkHref}"`); } //text if (elementText === 'ExACT AutoAlign,') { console.log('Passed: ExACT AutoAlign, link text matched as expected'); } else { errors.push(`Expected: "ExACT AutoAlign,"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: ExACT AutoAlign, link text font matched as expected'); } else { errors.push(`Expected: ExACT AutoAlign, link text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(48, 200, 172, 1)') { console.log('Passed: ExACT AutoAlign, link text color matched as expected'); } else { errors.push(`Expected: ExACT AutoAlign, link text color "rgba(48, 200, 172, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: ExACT AutoAlign, link text font-size matched as expected'); } else { errors.push(`Expected: ExACT AutoAlign, link text text font-size "14px"; Actual: "${elementSize}"`); } //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')); } } }, //Bullet Point 2 { description: 'Validate bullet point 2', action: async () => { const multipleChecks = 'Bullet point 2'; const elementIcon = await driver.wait(until.elementLocated(By.css('li:nth-child(2) img')), 5000).catch(() => false); const element = await driver.findElement(By.css('li:nth-child(2) > .list-flex')); //Get icon, text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //icon if (elementIcon) { console.log('Passed: Bullet Point Icon 2 present'); } else { errors.push("Bullet Point Icon 2 not found"); } //text if (elementText === 'See your Correlation Analytics.') { console.log('Passed: Bullet point 2 text matched as expected'); } else { errors.push(`Expected: "See your Correlation Analytics."; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Bullet point 2 text font matched as expected'); } else { errors.push(`Expected: Bullet point 2 text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(255, 255, 255, 1)') { console.log('Passed: Bullet point 2 text color matched as expected'); } else { errors.push(`Expected: Bullet point 2 text color "rgba(255, 255, 255, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Bullet point 2 text font-size matched as expected'); } else { errors.push(`Expected: Bullet point 2 text text font-size "14px"; Actual: "${elementSize}"`); } //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')); } } }, //Correlation Analytics. link { description: 'Validate Correlation Analytics. link', action: async () => { const multipleChecks = 'Correlation Analytics link'; const element = await driver.findElement(By.linkText('Correlation Analytics.')); //Get href, text, color, and size const linkHref = await element.getAttribute('href'); const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //href if (linkHref === 'https://edgate.com/systems/exact/analytics') { console.log('Passed: Correlation Analytics link URL matched as expected'); } else { errors.push(`Expected: "https://edgate.com/systems/exact/analytics"; Actual: "${linkHref}"`); } //text if (elementText === 'Correlation Analytics.') { console.log('Passed: Correlation Analytics. link text matched as expected'); } else { errors.push(`Expected: "Correlation Analytics."; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Correlation Analytics. link text font matched as expected'); } else { errors.push(`Expected: Correlation Analytics. link text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(48, 200, 172, 1)') { console.log('Passed: Correlation Analytics. link text color matched as expected'); } else { errors.push(`Expected: Correlation Analytics. link text color "rgba(48, 200, 172, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Correlation Analytics. link text font-size matched as expected'); } else { errors.push(`Expected: Correlation Analytics. link text text font-size "14px"; Actual: "${elementSize}"`); } //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')); } } }, //Bullet Point 3 { description: 'Validate bullet point 3', action: async () => { const multipleChecks = 'Bullet point 3'; const elementIcon = await driver.wait(until.elementLocated(By.css('li:nth-child(3) img')), 5000).catch(() => false); const element = await driver.findElement(By.css('li:nth-child(3) > .list-flex')); //Get icon, text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //icon if (elementIcon) { console.log('Passed: Bullet Point Icon 3 present'); } else { errors.push("Bullet Point Icon 3 not found"); } //text if (elementText === 'Explore how your Content maps to International Standards.') { console.log('Passed: Bullet point 3 text matched as expected'); } else { errors.push(`Expected: "Explore how your Content maps to International Standards."; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Bullet point 3 text font matched as expected'); } else { errors.push(`Expected: Bullet point 3 text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(255, 255, 255, 1)') { console.log('Passed: Bullet point 3 text color matched as expected'); } else { errors.push(`Expected: Bullet point 3 text color "rgba(255, 255, 255, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Bullet point 3 text font-size matched as expected'); } else { errors.push(`Expected: Bullet point 3 text text font-size "14px"; Actual: "${elementSize}"`); } //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')); } } }, //International Standards. link { description: 'Validate International Standards. link', action: async () => { const multipleChecks = 'International Standards link'; const element = await driver.findElement(By.linkText('International Standards.')); //Get href, text, color, and size const linkHref = await element.getAttribute('href'); const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //href if (linkHref === 'https://edgate.com/standards/international') { console.log('Passed: International Standards link URL matched as expected'); } else { errors.push(`Expected: "https://edgate.com/standards/international"; Actual: "${linkHref}"`); } //text if (elementText === 'International Standards.') { console.log('Passed: International Standards. link text matched as expected'); } else { errors.push(`Expected: "International Standards."; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: International Standards. link text font matched as expected'); } else { errors.push(`Expected: International Standards. link text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(48, 200, 172, 1)') { console.log('Passed: International Standards. link text color matched as expected'); } else { errors.push(`Expected: International Standards. link text color "rgba(48, 200, 172, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: International Standards. link text font-size matched as expected'); } else { errors.push(`Expected: International Standards. link text text font-size "14px"; Actual: "${elementSize}"`); } //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')); } } }, //RIGHT PANEL //ExACT logo { description: 'Verify ExACT logo is present', action: async () => { const expectedExactLogo = await driver.wait(until.elementLocated(By.css('.logo')), 5000).catch(() => false); //Track all errors const errors = []; if (expectedExactLogo) { console.log('Passed: ExACT logo present'); } else { errors.push('ExACT logo not found'); } } }, //Welcome Back { description: 'Validate Welcome Back', action: async () => { const multipleChecks = 'Welcome Back!'; const element = await driver.findElement(By.css('#formLogin > p')); const elementIcon = await driver.wait(until.elementLocated(By.css('p > img')), 5000).catch(() => false); //Get icon, text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'WELCOME BACK!') { console.log('Passed: Welcome Back text matched as expected'); } else { errors.push(`Expected: "WELCOME BACK!"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Welcome Back text font matched as expected'); } else { errors.push(`Expected: Welcome Back text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(117, 117, 117, 1)') { console.log('Passed: Welcome Back text color matched as expected'); } else { errors.push(`Expected: Welcome Back text color "rgba(117, 117, 117, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Welcome Back text font-size matched as expected'); } else { errors.push(`Expected: Welcome Back text text font-size "14px"; Actual: "${elementSize}"`); } //icon if (elementIcon) { console.log('Passed: Welcome Back Icon present'); } else { errors.push("Welcome Back Icon not found"); } //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')); } } }, //Login header { description: 'Validate Login header text', action: async () => { const multipleChecks = 'Login to your account'; const element = await driver.findElement(By.css('h2:nth-child(3)')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Login to your account') { console.log('Passed: Login header text matched as expected'); } else { errors.push(`Expected: "Login to your account"; Actual: "${elementText}"`); } //font-family if (elementFont === `"DM Serif Display", serif`) { console.log('Passed: Login header text font matched as expected'); } else { errors.push(`Expected: Login header text font "DM Serif Display", serif; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: Login header text color matched as expected'); } else { errors.push(`Expected: Login header text color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '32px') { console.log('Passed: Login header text font-size matched as expected'); } else { errors.push(`Expected: Login header text font-size "32px"; Actual: "${elementSize}"`); } //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')); } } }, //Username label text { description: 'Validate Username label text', action: async () => { const multipleChecks = 'Username label'; const element = await driver.findElement(By.css('.form-group:nth-child(4) > label')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Username') { console.log('Passed: Username label text matched as expected'); } else { errors.push(`Expected: "Username"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Username label text font matched as expected'); } else { errors.push(`Expected: Username label text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: Username label text color matched as expected'); } else { errors.push(`Expected: Username label text color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Username label text font-size matched as expected'); } else { errors.push(`Expected: Username label text font-size "14px"; Actual: "${elementSize}"`); } //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')); } } }, //Username textbox { description: 'Validate Username textbox', action: async () => { const multipleChecks = 'Username textbox'; const element = await driver.findElement(By.css('.form-control:nth-child(2)')); //Get text, color, and size const elementText = await element.getAttribute('placeholder'); //Get placeholder styles via executeScript since it's a pseudo-element const elementFont = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-family')`, element ); const elementColor = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('color')`, element ); const elementSize = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-size')`, element ); //Track all errors const errors = []; //text if (elementText === 'Username') { console.log('Passed: Username placeholder text matched as expected'); } else { errors.push(`Expected: "Username" placeholder; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Username placeholder text font matched as expected'); } else { errors.push(`Expected: Username placeholder text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgb(108, 117, 125)') { console.log('Passed: Username placeholder text color matched as expected'); } else { errors.push(`Expected: Username placeholder text color "rgb(108, 117, 125)"; Actual: "${elementColor}"`); } //font size if (elementSize === '12.6px') { console.log('Passed: Username placeholder text font-size matched as expected'); } else { errors.push(`Expected: Username placeholder text font-size "12.6px"; Actual: "${elementSize}"`); } //Trigger validation by clicking login button without filling in the field await driver.findElement(By.css('.login')).click(); console.log('----->| NEXT ACTION: Clicked Login button without entering credentials'); await driver.sleep(500); //Check native HTML5 validation message const validationMessage = await driver.executeScript(` return document.querySelector('input[name="username"]').validationMessage; `); if (validationMessage === 'Please fill out this field.') { console.log('Passed: Username validation message matched as expected'); } else { errors.push(`Expected: "Please fill out this field." validation message; Actual: "${validationMessage}"`); } //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')); } } }, //Password label text { description: 'Validate Password label text', action: async () => { const multipleChecks = 'Password label'; const element = await driver.findElement(By.css('.form-group:nth-child(5) > label')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Password') { console.log('Passed: Password label text matched as expected'); } else { errors.push(`Expected: "Password"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Password label text font matched as expected'); } else { errors.push(`Expected: Password label text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: Password label text color matched as expected'); } else { errors.push(`Expected:Password label text color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Password label text font-size matched as expected'); } else { errors.push(`Expected: Password label text font-size "14px"; Actual: "${elementSize}"`); } //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')); } } }, //Password textbox { description: 'Validate Password textbox', action: async () => { const multipleChecks = 'Password textbox'; const element = await driver.findElement(By.css('.passfield')); //Get text, color, and size const elementText = await element.getAttribute('placeholder'); //Get placeholder styles via executeScript since it's a pseudo-element const elementFont = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-family')`, element ); const elementColor = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('color')`, element ); const elementSize = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-size')`, element ); //Track all errors const errors = []; //text if (elementText === 'Password') { console.log('Passed: Password placeholder text matched as expected'); } else { errors.push(`Expected: "Password" placeholder; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Password placeholder text font matched as expected'); } else { errors.push(`Expected: Password placeholder text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgb(108, 117, 125)') { console.log('Passed: Password placeholder text color matched as expected'); } else { errors.push(`Expected: Password placeholder text color "rgb(108, 117, 125)"; Actual: "${elementColor}"`); } //font size if (elementSize === '12.6px') { console.log('Passed: Password placeholder text font-size matched as expected'); } else { errors.push(`Expected: Password placeholder text font-size "12.6px"; Actual: "${elementSize}"`); } //Trigger validation by clicking login button without filling in the field await driver.findElement(By.css('.form-control:nth-child(2)')).sendKeys('Edgate1'); console.log('----->| NEXT ACTION: Entered incorrect username and left password field empty'); await driver.findElement(By.css('.login')).click(); console.log('----->| NEXT ACTION: Clicked Login button'); await driver.sleep(500); //Check native HTML5 validation message const validationMessage = await driver.executeScript(` return document.querySelector('input[name="password"]').validationMessage; `); if (validationMessage === 'Please fill out this field.') { console.log('Passed: Username validation message matched as expected'); } else { errors.push(`Expected: "Please fill out this field." validation message; Actual: "${validationMessage}"`); } //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')); } } }, //Incorrect password validation { description: 'Validate Incorrect password validation', action: async () => { const multipleChecks = 'Incorrect Password'; //Track all errors const errors = []; await driver.findElement(By.css('.passfield')).sendKeys('Edgate123'); console.log('----->| NEXT ACTION: Entered incorrect password: Edgate123'); await driver.findElement(By.css('.login')).click(); console.log('----->| NEXT ACTION: Clicked Login button'); await driver.sleep(500); //Wait until the element exists in the DOM const elementVisible = await driver.wait( until.elementLocated(By.css('.alert')), 20000 ); //Wait until it becomes visible await driver.wait( until.elementIsVisible(elementVisible), 20000 ); await driver.sleep(2000); //Get text, color, and size const elementText = await elementVisible.getText(); const elementFont = await elementVisible.getCssValue('font-family'); const elementColor = await elementVisible.getCssValue('background-color'); const elementSize = await elementVisible.getCssValue('font-size'); //text if (elementText === 'Authentication Failed. Please check the username and password you entered and try again.') { console.log('Passed: Alert text matched as expected'); } else { errors.push(`Expected: Alert message "Authentication Failed. Please check the username and password you entered and try again."; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Alert text font matched as expected'); } else { errors.push(`Expected: Alert text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(231, 76, 60, 0.88)') { console.log('Passed: Alert text color matched as expected'); } else { errors.push(`Expected: Alert text color "rgba(231, 76, 60, 0.88)"; Actual: "${elementColor}"`); } //font size if (elementSize === '13px') { console.log('Passed: Alert text font-size matched as expected'); } else { errors.push(`Expected: Alert text font-size "13px"; Actual: "${elementSize}"`); } //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')); } } }, //Forgot password { description: 'Validate Forgot Password link', action: async () => { const multipleChecks = 'Forgot Password?'; const element = await driver.findElement(By.linkText('Forgot Password?')); //Get href, text, color, and size const linkHref = await element.getAttribute('href'); const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //href if (linkHref === 'https://correlation.edgate.com/exact/forgot.php') { console.log('Passed: Forgot Password? link URL matched as expected'); } else { errors.push(`Expected: "https://correlation.edgate.com/exact/forgot.php"; Actual: "${linkHref}"`); } //text if (elementText === 'Forgot Password?') { console.log('Passed: Forgot password link text matched as expected'); } else { errors.push(`Expected: "Forgot Password?"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Forgot password link text font matched as expected'); } else { errors.push(`Expected: Forgot password link text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: Forgot password link text color matched as expected'); } else { errors.push(`Expected: Forgot password link text color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '12px') { console.log('Passed: Forgot password link text font-size matched as expected'); } else { errors.push(`Expected: Forgot password link text font-size "12px"; Actual: "${elementSize}"`); } //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')); } } }, //Login button text (alt to .getText) { description: 'Validate Login button text', action: async () => { const multipleChecks = 'Login Button'; const element = await driver.findElement(By.css('.login')); //Get text, color, and size const elementText = await element.getAttribute('value'); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('background-color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Login') { console.log('Passed: Login button text matched as expected'); } else { errors.push(`Expected: "Login"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Login button text font matched as expected'); } else { errors.push(`Expected: Login buttonk text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(48, 200, 172, 1)') { console.log('Passed: Login button text background color matched as expected'); } else { errors.push(`Expected: Login button text background color "rgba(48, 200, 172, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '16px') { console.log('Passed: Login button text font-size matched as expected'); } else { errors.push(`Expected: Login button text font-size "16px"; Actual: "${elementSize}"`); } //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')); } } }, //Don't have an account? text { description: 'Validate Dont have account text', action: async () => { const multipleChecks = `Don't Have an account?`; const element = await driver.findElement(By.css('p:nth-child(1)')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === `DON'T HAVE AN ACCOUNT?`) { console.log('Passed: Dont have an account text matched as expected'); } else { errors.push(`Expected: "DON'T HAVE AN ACCOUNT?"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Dont have an account text font matched as expected'); } else { errors.push(`Expected: Dont have an account text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(32, 32, 32, 1)') { console.log('Passed: Dont have an account text color matched as expected'); } else { errors.push(`Expected: Dont have an account text color "rgba(32, 32, 32, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Dont have an account text font-size matched as expected'); } else { errors.push(`Expected: Dont have an account text font-size "14px"; Actual: "${elementSize}"`); } //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')); } } }, //Free trial button { description: 'Validate Free trial button', action: async () => { const multipleChecks = 'Free Trial'; const element = await driver.findElement(By.linkText('Sign up for a 30 Day Free Trial')); //Get href, text, color, and size const linkHref = await element.getAttribute('href'); const elementText = await element.getText(''); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('background-color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //href if (linkHref === 'https://correlation.edgate.com/exact/trial-registration.php') { console.log('Passed: Sign up for a 30 Day Free Trial link URL matched as expected'); } else { errors.push(`Expected: "2"; Actual: "${linkHref}"`); } //text if (elementText === 'Sign up for a 30 Day Free Trial') { console.log('Passed: Free trial button text matched as expected'); } else { errors.push(`Expected: "Sign up for a 30 Day Free Trial"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Free trial button text font matched as expected'); } else { errors.push(`Expected: Free trial button text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(255, 255, 255, 1)') { console.log('Passed: Free trial button background color matched as expected'); } else { errors.push(`Expected: Free trial button background color "rgba(255, 255, 255, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '16px') { console.log('Passed: Free trial button text font-size matched as expected'); } else { errors.push(`Expected: Free trial button text font-size "16px"; Actual: "${elementSize}"`); } //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')); } } }, //EdGate copyright logo { description: 'Verify EdGate copyright logo is present', action: async () => { const expectedEdGateCopyright = await driver.wait(until.elementLocated(By.css('.logincopyright > img')), 5000).catch(() => false); //Track all errors const errors = []; if (expectedEdGateCopyright) { console.log('Passed: EdGate copyright logo present'); } else { errors.push("EdGate copyright logo not found"); } } }, //NEXT ACTION { description: 'Click Forgot password link', action: async () => { await driver.findElement(By.linkText('Forgot Password?')).click(); console.log('----->| NEXT ACTION: Clicked Forgot Password? link'); console.log('---------->| PASSWORD RECOVERY PAGE|<----------'); //Wait until the element exists in the DOM const recoverUsername = await driver.wait( until.elementLocated(By.css('#username')), 30000 ); //Wait until it becomes visible await driver.wait( until.elementIsVisible(recoverUsername), 30000 ); } }, //Recover Username textbox (SPECIAL CASE: Placeholder validation with trigger) { description: 'Validate Recover Username textbox', action: async () => { const multipleChecks = 'Recover Username textbox'; const element = await driver.findElement(By.css('#username')); //Get text, color, and size const elementText = await element.getAttribute('placeholder'); //Get placeholder styles via executeScript since it's a pseudo-element const elementFont = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-family')`, element ); const elementColor = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('color')`, element ); const elementSize = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-size')`, element ); //Track all errors const errors = []; //text if (elementText === 'Username') { console.log('Passed: Username placeholder text matched as expected'); } else { errors.push(`Expected: "Username" placeholder; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Username placeholder text font matched as expected'); } else { errors.push(`Expected: Username placeholder text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgb(108, 117, 125)') { console.log('Passed: Username placeholder text color matched as expected'); } else { errors.push(`Expected: Username placeholder text color "rgb(108, 117, 125)"; Actual: "${elementColor}"`); } //font size if (elementSize === '12.6px') { console.log('Passed: Username placeholder text font-size matched as expected'); } else { errors.push(`Expected: Username placeholder text font-size "12.6px"; Actual: "${elementSize}"`); } //Trigger validation by clicking submit button without filling in the field await driver.findElement(By.css('.btn')).click(); console.log('----->| NEXT ACTION: Clicked Submit button without entering username'); await driver.sleep(500); //Check native HTML5 validation message const validationMessage = await driver.executeScript(` return document.querySelector('input[name="username"]').validationMessage; `); if (validationMessage === 'Please fill out this field.') { console.log('Passed: Username validation message matched as expected'); } else { errors.push(`Expected: "Please fill out this field." validation message; Actual: "${validationMessage}"`); } //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')); } } }, //Submit button text (alt to .getText) { description: 'Validate Submit button text', action: async () => { const multipleChecks = 'Submit Button'; const element = await driver.findElement(By.css('.btn')); //Get text, color, and size const elementText = await element.getAttribute('value'); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('background-color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Submit') { console.log('Passed: Submit button text matched as expected'); } else { errors.push(`Expected: "Submit"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Submit button text font matched as expected'); } else { errors.push(`Expected: Submit buttonk text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: Submit button text background color matched as expected'); } else { errors.push(`Expected: Submit button text background color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '16px') { console.log('Passed: Submit button text font-size matched as expected'); } else { errors.push(`Expected: Submit button text font-size "16px"; Actual: "${elementSize}"`); } //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')); } } }, //Back to Login link { description: 'Validate Back to Login link', action: async () => { const multipleChecks = '< Back to Login'; const element = await driver.findElement(By.linkText('< Back to Login')); //Get text, color, and size const linkHref = await element.getAttribute('href'); const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //href if (linkHref === 'https://correlation.edgate.com/exact/login.php') { console.log('Passed: < Back to Login link URL matched as expected'); } else { errors.push(`Expected: "https://correlation.edgate.com/exact/login.php"; Actual: "${linkHref}"`); } //text if (elementText === '< Back to Login') { console.log('Passed: < Back to Login link text matched as expected'); } else { errors.push(`Expected: "< Back to Login"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: < Back to Login link text font matched as expected'); } else { errors.push(`Expected: < Back to Login link text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: < Back to Login link text color matched as expected'); } else { errors.push(`Expected: < Back to Login link text color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '12px') { console.log('Passed: < Back to Login link text font-size matched as expected'); } else { errors.push(`Expected: < Back to Login link text font-size "12px"; Actual: "${elementSize}"`); } //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 Back to Login link', action: async () => { await driver.findElement(By.linkText('< Back to Login')).click(); console.log('----->| NEXT ACTION: Clicked < Back to Login link'); console.log('---------->| SIGN UP PAGE|<----------'); //Wait until the element exists in the DOM const pageTitle = await driver.wait( until.elementLocated(By.css('h2:nth-child(1)')), 30000 ); //Wait until it becomes visible await driver.wait( until.elementIsVisible(pageTitle), 30000 ); } }, //RIGHT PANEL //ExACT logo { description: 'Verify ExACT logo is present', action: async () => { const expectedExactLogo = await driver.wait(until.elementLocated(By.css('.logo')), 5000).catch(() => false); //Track all errors const errors = []; if (expectedExactLogo) { console.log('Passed: ExACT logo present'); } else { errors.push('ExACT logo not found'); } } }, //Welcome Back { description: 'Validate Welcome Back', action: async () => { const multipleChecks = 'Welcome Back!'; const element = await driver.findElement(By.css('#formLogin > p')); const elementIcon = await driver.wait(until.elementLocated(By.css('p > img')), 5000).catch(() => false); //Get icon, text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'WELCOME BACK!') { console.log('Passed: Welcome Back text matched as expected'); } else { errors.push(`Expected: "WELCOME BACK!"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Welcome Back text font matched as expected'); } else { errors.push(`Expected: Welcome Back text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(117, 117, 117, 1)') { console.log('Passed: Welcome Back text color matched as expected'); } else { errors.push(`Expected: Welcome Back text color "rgba(117, 117, 117, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Welcome Back text font-size matched as expected'); } else { errors.push(`Expected: Welcome Back text text font-size "14px"; Actual: "${elementSize}"`); } //icon if (elementIcon) { console.log('Passed: Welcome Back Icon present'); } else { errors.push("Welcome Back Icon not found"); } //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')); } } }, //Login header { description: 'Validate Login header text', action: async () => { const multipleChecks = 'Login to your account'; const element = await driver.findElement(By.css('h2:nth-child(3)')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Login to your account') { console.log('Passed: Login header text matched as expected'); } else { errors.push(`Expected: "Login to your account"; Actual: "${elementText}"`); } //font-family if (elementFont === `"DM Serif Display", serif`) { console.log('Passed: Login header text font matched as expected'); } else { errors.push(`Expected: Login header text font "DM Serif Display", serif; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: Login header text color matched as expected'); } else { errors.push(`Expected: Login header text color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '32px') { console.log('Passed: Login header text font-size matched as expected'); } else { errors.push(`Expected: Login header text font-size "32px"; Actual: "${elementSize}"`); } //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')); } } }, //Username label text { description: 'Validate Username label text', action: async () => { const multipleChecks = 'Username label'; const element = await driver.findElement(By.css('.form-group:nth-child(4) > label')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Username') { console.log('Passed: Username label text matched as expected'); } else { errors.push(`Expected: "Username"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Username label text font matched as expected'); } else { errors.push(`Expected: Username label text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: Username label text color matched as expected'); } else { errors.push(`Expected: Username label text color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Username label text font-size matched as expected'); } else { errors.push(`Expected: Username label text font-size "14px"; Actual: "${elementSize}"`); } //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')); } } }, //Username textbox { description: 'Validate Username textbox', action: async () => { const multipleChecks = 'Username textbox'; const element = await driver.findElement(By.css('.form-control:nth-child(2)')); //Get text, color, and size const elementText = await element.getAttribute('placeholder'); //Get placeholder styles via executeScript since it's a pseudo-element const elementFont = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-family')`, element ); const elementColor = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('color')`, element ); const elementSize = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-size')`, element ); //Track all errors const errors = []; //text if (elementText === 'Username') { console.log('Passed: Username label text matched as expected'); } else { errors.push(`Expected: "Username"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Username label text font matched as expected'); } else { errors.push(`Expected: Username label text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgb(108, 117, 125)') { console.log('Passed: Username label text color matched as expected'); } else { errors.push(`Expected: Username label text color "rgb(108, 117, 125)"; Actual: "${elementColor}"`); } //font size if (elementSize === '12.6px') { console.log('Passed: Username label text font-size matched as expected'); } else { errors.push(`Expected: Username label text font-size "12.6px"; Actual: "${elementSize}"`); } //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')); } } }, //Password label text { description: 'Validate Password label text', action: async () => { const multipleChecks = 'Password label'; const element = await driver.findElement(By.css('.form-group:nth-child(5) > label')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Password') { console.log('Passed: Password label text matched as expected'); } else { errors.push(`Expected: "Password"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Password label text font matched as expected'); } else { errors.push(`Expected: Password label text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: Password label text color matched as expected'); } else { errors.push(`Expected:Password label text color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Password label text font-size matched as expected'); } else { errors.push(`Expected: Password label text font-size "14px"; Actual: "${elementSize}"`); } //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')); } } }, //Password textbox { description: 'Validate Password textbox', action: async () => { const multipleChecks = 'Password textbox'; const element = await driver.findElement(By.css('.passfield')); //Get text, color, and size const elementText = await element.getAttribute('placeholder'); //Get placeholder styles via executeScript since it's a pseudo-element const elementFont = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-family')`, element ); const elementColor = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('color')`, element ); const elementSize = await driver.executeScript( `return window.getComputedStyle(arguments[0], '::placeholder').getPropertyValue('font-size')`, element ); //Track all errors const errors = []; //text if (elementText === 'Password') { console.log('Passed: Password label text matched as expected'); } else { errors.push(`Expected: "Password"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Password label text font matched as expected'); } else { errors.push(`Expected: Password label text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgb(108, 117, 125)') { console.log('Passed: Password label text color matched as expected'); } else { errors.push(`Expected: Password label text color "rgb(108, 117, 125)"; Actual: "${elementColor}"`); } //font size if (elementSize === '12.6px') { console.log('Passed: Password label text font-size matched as expected'); } else { errors.push(`Expected: Password label text font-size "12.6px"; Actual: "${elementSize}"`); } //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')); } } }, //Forgot password link { description: 'Validate Forgot Password link', action: async () => { const multipleChecks = 'Forgot Password?'; const element = await driver.findElement(By.linkText('Forgot Password?')); //Get text, color, and size const linkHref = await element.getAttribute('href'); const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //href if (linkHref === 'https://correlation.edgate.com/exact/forgot.php') { console.log('Passed: Forgot Password link URL matched as expected'); } else { errors.push(`Expected: "https://correlation.edgate.com/exact/forgot.php"; Actual: "${linkHref}"`); } //text if (elementText === 'Forgot Password?') { console.log('Passed: Forgot password link text matched as expected'); } else { errors.push(`Expected: "Forgot Password?"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Forgot password link text font matched as expected'); } else { errors.push(`Expected: Forgot password link text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(40, 39, 90, 1)') { console.log('Passed: Forgot password link text color matched as expected'); } else { errors.push(`Expected: Forgot password link text color "rgba(40, 39, 90, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '12px') { console.log('Passed: Forgot password link text font-size matched as expected'); } else { errors.push(`Expected: Forgot password link text font-size "12px"; Actual: "${elementSize}"`); } //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')); } } }, //Login button text (alt to .getText) { description: 'Validate Login button text', action: async () => { const multipleChecks = 'Login Button'; const element = await driver.findElement(By.css('.login')); //Get text, color, and size const elementText = await element.getAttribute('value'); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('background-color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === 'Login') { console.log('Passed: Login button text matched as expected'); } else { errors.push(`Expected: "Login"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Login button text font matched as expected'); } else { errors.push(`Expected: Login buttonk text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(48, 200, 172, 1)') { console.log('Passed: Login button text background color matched as expected'); } else { errors.push(`Expected: Login button text background color "rgba(48, 200, 172, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '16px') { console.log('Passed: Login button text font-size matched as expected'); } else { errors.push(`Expected: Login button text font-size "16px"; Actual: "${elementSize}"`); } //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')); } } }, //Don't have an account? text { description: 'Validate Dont have account text', action: async () => { const multipleChecks = `Don't Have an account?`; const element = await driver.findElement(By.css('p:nth-child(1)')); //Get text, color, and size const elementText = await element.getText(); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //text if (elementText === `DON'T HAVE AN ACCOUNT?`) { console.log('Passed: Dont have an account text matched as expected'); } else { errors.push(`Expected: "DON'T HAVE AN ACCOUNT?"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Dont have an account text font matched as expected'); } else { errors.push(`Expected: Dont have an account text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(32, 32, 32, 1)') { console.log('Passed: Dont have an account text color matched as expected'); } else { errors.push(`Expected: Dont have an account text color "rgba(32, 32, 32, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '14px') { console.log('Passed: Dont have an account text font-size matched as expected'); } else { errors.push(`Expected: Dont have an account text font-size "14px"; Actual: "${elementSize}"`); } //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')); } } }, //Free trial button { description: 'Validate Free trial button', action: async () => { const multipleChecks = 'Free Trial'; const element = await driver.findElement(By.linkText('Sign up for a 30 Day Free Trial')); //Get href, text, color, and size const linkHref = await element.getAttribute('href'); const elementText = await element.getText(''); const elementFont = await element.getCssValue('font-family'); const elementColor = await element.getCssValue('background-color'); const elementSize = await element.getCssValue('font-size'); //Track all errors const errors = []; //href if (linkHref === 'https://correlation.edgate.com/exact/trial-registration.php') { console.log('Passed: Sign up for a 30 Day Free Trial link URL matched as expected'); } else { errors.push(`Expected: "https://correlation.edgate.com/exact/trial-registration.php"; Actual: "${linkHref}"`); } //text if (elementText === 'Sign up for a 30 Day Free Trial') { console.log('Passed: Free trial button text matched as expected'); } else { errors.push(`Expected: "Sign up for a 30 Day Free Trial"; Actual: "${elementText}"`); } //font-family if (elementFont === "Poppins, sans-serif") { console.log('Passed: Free trial button text font matched as expected'); } else { errors.push(`Expected: Free trial button text font "Poppins, sans-serif"; Actual: ${elementFont}`); } //color if (elementColor === 'rgba(255, 255, 255, 1)') { console.log('Passed: Free trial button background color matched as expected'); } else { errors.push(`Expected: Free trial button background color "rgba(255, 255, 255, 1)"; Actual: "${elementColor}"`); } //font size if (elementSize === '16px') { console.log('Passed: Free trial button text font-size matched as expected'); } else { errors.push(`Expected: Free trial button text font-size "16px"; Actual: "${elementSize}"`); } //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')); } } }, //EdGate copyright logo { description: 'Verify EdGate copyright logo is present', action: async () => { const expectedEdGateCopyright = await driver.wait(until.elementLocated(By.css('.logincopyright > img')), 5000).catch(() => false); //Track all errors const errors = []; if (expectedEdGateCopyright) { console.log('Passed: EdGate copyright logo present'); } else { errors.push("EdGate copyright logo not found"); } } }, //NEXT ACTION { description: 'Login and Log Out', action: async () => { const multipleChecks = 'Log In and Out'; //Track all errors const errors = []; await driver.findElement(By.css('.form-control:nth-child(2)')).sendKeys('exact_juan'); console.log('----->| NEXT ACTION: Entered Username: exact_juan'); await driver.findElement(By.css('.passfield')).sendKeys('Edgate1!'); console.log('----->| NEXT ACTION: Entered Password: Edgate1!'); await driver.findElement(By.css('.login')).click(); console.log('----->| NEXT ACTION: Clicked Login button'); console.log('------------->| ExACT Dashboard |<-------------'); //Wait until the element exists in the DOM const pageTitle = await driver.wait( until.elementLocated(By.css('.e-heading')), 30000 ); //Wait until it becomes visible await driver.wait( until.elementIsVisible(pageTitle), 30000 ); const element = await driver.wait(until.elementLocated(By.css('.e-heading')), 5000).catch(() => false); const elementText = await element.getText(); //text if (elementText === 'Correlation Dashboard') { console.log('Passed: Correlation Dashboard page title matched as expected'); } else { errors.push(`Expected: "Correlation Dashboard"; Actual: "${elementText}"`); } //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'); await driver.findElement(By.css('#navbarDropdown > span')).click(); 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')); } } }, ]; 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', 'landingPage'); const screenshotFileName = `step_${stepIndex}_${stepDescription.replace(/\s+/g, '_')}.png`; const screenshotPath = path.join(dir, screenshotFileName); fs.writeFileSync(screenshotPath, screenshot, 'base64'); return screenshotPath; }; const resultsFile = path.join('results', 'exactLandingPage.xlsx'); const clearOldResults = () => { //Remove old screenshots const screenshotDir = path.join('screenshots', 'landingPage'); if (fs.existsSync(screenshotDir)) { fs.rmSync(screenshotDir, { recursive: true, force: true }); } fs.mkdirSync(screenshotDir, { recursive: true }); //Remove old Excel file if (fs.existsSync(resultsFile)) { fs.unlinkSync(resultsFile); } fs.mkdirSync('results', { recursive: true }); }; 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, ''); let allStepsPassed = true; const failedSteps = []; //Track failed steps for (const step of steps) { const stepIndex = steps.indexOf(step) + 1; const timestamp = new Date().toISOString(); try { await step.action(); worksheet = logStep( worksheet, step.description, 'Passed', stepIndex, timestamp, null ); } 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}`); failedSteps.push(`Step ${stepIndex}: ${step.description} - ${error.message}`); //Track failed step testStatus = 'Failed'; allStepsPassed = false; } } if (allStepsPassed) { console.log('------------->| THE END |<-------------'); console.log('PASSED: ExACT Landing Page(exactLandingPage); All test steps completed successfully'); testStatus = 'Passed'; } else { console.log('------------->| THE END |<-------------'); console.log('FAILED: ExACT Landing Page(exactLandingPage); One or more test steps failed'); console.log('FAILED STEPS:'); failedSteps.forEach(step => console.error(` ✗ ${step}`)); 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, resultsFile); } finally { await driver.quit(); } })(); } export default exactLandingPage;