diff --git a/index.js b/index.js index 15c016b..b16de3b 100644 --- a/index.js +++ b/index.js @@ -3,11 +3,11 @@ import express from 'express'; import exactLandingPage from './tests/LandingPage/exactLandingPage.js'; //import ExACT_login from './tests/ExACT_login.js'; -//DASHBOARDS +//DASHBOARD import correlationDashboard from './tests/CorrelationDashboard/correlationDashboard.js'; - import dashboardMyStandards from './tests/CorrelationDashboard/MyStandardsWidget/dashboardMyStandards.js'; - -import ExACT_dashboardMyContent from './tests/ExACT_dashboardMyContent.js'; + import myStandardsWidget from './tests/CorrelationDashboard/Widgets/myStandardsWidget.js'; + import myContentWidget from './tests/CorrelationDashboard/Widgets/myContentWidget.js'; + import ExACT_dashboardSemanticStandardsComparison from './tests/ExACT_dashboardSemanticStandardsComparison.js'; import myStandardsSearchAlignedContent from './tests/myStandardsSearchAlignedContent.js'; @@ -32,7 +32,7 @@ import uploadBatchUploadPage from './tests/Upload/uploadBatchUpload.js'; import uploadImportAlignmentsPage from './tests/Upload/uploadImportAlignmentsPage.js'; //ACTIVITY REPORT -import activityReportPage from './tests/ActivityReport/ActivityReportPage.js'; +import activityReportPage from './tests/Activity Report/ActivityReportPage.js'; //REPORT import reportBuildYourReportPage from './tests/Report/reportBuildYourReportPage.js'; @@ -67,12 +67,12 @@ app.get('/', (req, res) => {

DASHBOARD

Correlation Dashboard
-
- My Standards Widget
+
- My Standards Widget
+
- My Content Widget
- + +

FRAMEWORKS

Framework Management Page
@@ -135,7 +135,8 @@ app.get('/exactLandingPage', exactLandingPage); //DASHBOARDS app.get('/correlationDashboard', correlationDashboard); - app.get('/dashboardMyStandards', dashboardMyStandards); + app.get('/myStandardsWidget', myStandardsWidget); + app.get('/myContentWidget', myContentWidget); //FRAMEWORKS app.get('/frameworkManagementPage', frameworkManagementPage); @@ -170,7 +171,6 @@ app.get('/approveApprovalHistoryPage', approveApprovalHistoryPage); app.get('/approveRejectionHistoryPage', approveRejectionHistoryPage); //My Content -app.get('/ExACT_dashboardMyContent', ExACT_dashboardMyContent); app.get('/ExACT_dashboardSemanticStandardsComparison', ExACT_dashboardSemanticStandardsComparison); app.get('/myStandardsSearchAlignedContent', myStandardsSearchAlignedContent); diff --git a/results/myContentWidget.xlsx b/results/myContentWidget.xlsx new file mode 100644 index 0000000..3ff4e74 Binary files /dev/null and b/results/myContentWidget.xlsx differ diff --git a/results/myStandardsWidget.xlsx b/results/myStandardsWidget.xlsx new file mode 100644 index 0000000..b482ef7 Binary files /dev/null and b/results/myStandardsWidget.xlsx differ diff --git a/tests/ActivityReport/ActivityReportPage.js b/tests/Activity Report/ActivityReportPage.js similarity index 100% rename from tests/ActivityReport/ActivityReportPage.js rename to tests/Activity Report/ActivityReportPage.js diff --git a/tests/ExACT_dashboardMyContent.js b/tests/CorrelationDashboard/Widgets/myContentWidget.js similarity index 68% rename from tests/ExACT_dashboardMyContent.js rename to tests/CorrelationDashboard/Widgets/myContentWidget.js index ea7fd5b..b7c7865 100644 --- a/tests/ExACT_dashboardMyContent.js +++ b/tests/CorrelationDashboard/Widgets/myContentWidget.js @@ -1,12 +1,11 @@ -import { Builder, By, Key, until, Select, Browser } from 'selenium-webdriver'; +import { Builder, By, 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 { brotliCompress } from 'zlib'; -const ExACT_dashboardMyContent = (req, res) => { - res.send('

ExACT Automated Test Script: DASHBOARD - My Content Widget (ExACT_dashboardMyContent) | Initiated

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

ExACT Automated Test Script: DASHBOARD - My Content Widget(myContentWidget) | Initiated

'); (async function example() { let driver = await new Builder() .forBrowser('chrome') @@ -23,9 +22,59 @@ const ExACT_dashboardMyContent = (req, res) => { let worksheet; const startTime = new Date().toISOString(); -//Constants +//CONSTANTS +const totalItems = '5045'; +//My Content Total DIV +const uniqueTitleTotals = '3472'; +const uniqueIdTotals = '3463'; +//Biology +const biologyTotalItems = '1493'; +const biologyUniqueTitles = '3472'; +const biologyUniqueIds = '3463'; +//New Content Set const createContentSetName = 'Automated Algebra Content Set - TO BE DELETED'; +//My Content sets - shared by the My Content Totals DIV table and the My Content widget list +//List in default (Count) sort order, which matches the Totals table order +// name = Content Set name +// totalItems = Total Items (Totals table) and count (widget list) +// uniqueTitles = Unique Titles (Totals table) +// uniqueIds = Unique IDs (Totals table) +// id = Content Set ID used in the link and edit icon URLs (null = not captured; URLs checked for format only) +const myContentSets = [ + { name: 'Biology', totalItems: '1493', uniqueTitles: '1482', uniqueIds: '1493', id: '585821587' }, + { name: 'Khan URL test', totalItems: '1118', uniqueTitles: '41', uniqueIds: '1', id: null }, + { name: 'Math Alignment Import Test', totalItems: '730', uniqueTitles: '707', uniqueIds: '728', id: '1423792414' }, + { name: 'English I', totalItems: '388', uniqueTitles: '388', uniqueIds: '388', id: '585821585' }, + { name: 'Copy Move Delete Test 2', totalItems: '327', uniqueTitles: '327', uniqueIds: '328', id: '1228574325' }, + { name: 'Post NIght July26', totalItems: '278', uniqueTitles: '32', uniqueIds: '0', id: null }, + { name: 'Algebra', totalItems: '194', uniqueTitles: '196', uniqueIds: '189', id: '585821586' }, + { name: 'seesaw test', totalItems: '156', uniqueTitles: '156', uniqueIds: '155', id: null }, + { name: 'US History III', totalItems: '68', uniqueTitles: '68', uniqueIds: '67', id: '585821589' }, + { name: 'Import Align - Concept Based 1', totalItems: '44', uniqueTitles: '43', uniqueIds: '44', id: '1323320445' }, + { name: 'Import Align - Concept Based 2', totalItems: '44', uniqueTitles: '43', uniqueIds: '44', id: '1323322624' }, + { name: 'Import Align - Direct Align 1', totalItems: '44', uniqueTitles: '43', uniqueIds: '44', id: '1323322921' }, + { name: 'Import Align - Direct Align 2', totalItems: '44', uniqueTitles: '43', uniqueIds: '44', id: '1323322923' }, + { name: 'Copy Move Delete Test 1', totalItems: '35', uniqueTitles: '23', uniqueIds: '33', id: '1228574323' }, + { name: 'ECS-3037 On Prod TC2', totalItems: '26', uniqueTitles: '26', uniqueIds: '26', id: null }, + { name: 'ECS-3037 On Prod TC1', totalItems: '24', uniqueTitles: '24', uniqueIds: '24', id: null }, + { name: 'create me', totalItems: '9', uniqueTitles: '9', uniqueIds: '9', id: '1427607301' }, + { name: 'Illustrative Math Test 1', totalItems: '5', uniqueTitles: '5', uniqueIds: '5', id: null }, + { name: 'Illustrative Math Test 2', totalItems: '5', uniqueTitles: '5', uniqueIds: '0', id: null }, + { name: 'webinar test', totalItems: '5', uniqueTitles: '5', uniqueIds: '5', id: null }, + { name: 'Review Screen Open', totalItems: '5', uniqueTitles: '5', uniqueIds: '0', id: null }, + { name: 'create import test', totalItems: '3', uniqueTitles: '3', uniqueIds: '3', id: null }, + { name: 'New One For Agust Post Night', totalItems: '0', uniqueTitles: '0', uniqueIds: '0', id: null }, +]; + +//My Content sets sorted by Name (Sort: "Name"), including the newly created Content Set +//Sorting is case-insensitive to match the site (e.g. "create me" sorts between "Copy..." and "ECS...") +//New Content Set ID is generated on create, so id is null (edit URL checked for format only) +const myContentSetsByName = [ + ...myContentSets, + { name: createContentSetName, totalItems: '0', uniqueTitles: '0', uniqueIds: '0', id: null }, +].sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase(), 'en')); + 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() }, @@ -35,7 +84,8 @@ const steps = [ description: 'Login', action: async () => { const multipleChecks = 'Log In'; - console.log('------------->| EDIT ITEM |<-------------'); + + console.log('------------->| MY CONTENT WIDGET |<-------------'); const errors = []; await driver.findElement(By.css('.form-control:nth-child(2)')).sendKeys('exact_juan'); @@ -108,9 +158,10 @@ const steps = [ //Dashboard title { - description: 'Validate dashboard title text, size, and color', + description: 'Dashboard title text, size, and color', action: async () => { const multipleChecks = 'Dashboard title'; + const element = await driver.findElement(By.css('.e-heading')); //Get text, font, size, and color @@ -167,9 +218,10 @@ const steps = [ //Dashboard My Content Widget title { - description: 'Validate My Content widget title text, color, and size', + description: 'My Content widget title text, color, and size', action: async () => { const multipleChecks = 'My Content widget title'; + const element = await driver.findElement(By.css('.h-100 h2:nth-child(2)')); //Get text, font, size, and color @@ -224,9 +276,10 @@ const steps = [ //My Content total item Count (SPECIAL CASE: with button) { - description: 'Validate My Content total item count', + description: 'My Content total item count', action: async () => { const multipleChecks = 'My Content total item count'; + const element = await driver.findElement(By.css('#badge_content_total')); //Get button text, text font, text size, text color, and button color @@ -240,10 +293,10 @@ const steps = [ const errors = []; //text - if (elementText === '3415 items') { + if (elementText.includes(totalItems)) { console.log('Passed: Total item count button text matched as expected'); } else { - errors.push(`Expected: "3415 items"; Actual: "${elementText}"`); + errors.push(`Expected: "${totalItems}"; Actual: "${elementText}"`); } //font-family @@ -313,9 +366,10 @@ const steps = [ //Dashboard My Content DIV { - description: 'Validate My Content Totals DIV title text, color, and size', + description: 'My Content Totals DIV title text, color, and size', action: async () => { const multipleChecks = 'My Content Totals DIV'; + const element = await driver.findElement(By.css('.content_modal_title')); //Get text, font, size, and color @@ -370,7 +424,7 @@ const steps = [ //Close icon { - description: 'Validate DIV X icon color', + description: 'DIV X icon color', action: async () => { const elementStyle = await driver.findElement(By.css('.ready-content span')).getCssValue('color'); if (elementStyle === 'rgba(246, 60, 40, 1)') { @@ -383,9 +437,10 @@ const steps = [ //My Content Totals DIV - Total Items { - description: 'Validate My Content Totals DIV - Total Items', + description: 'My Content Totals DIV - Total Items', action: async () => { const multipleChecks = 'My Content Total Item count'; + const element = await driver.findElement(By.css('#total > p')); const elementCount = await driver.findElement(By.css('#total > b')); @@ -442,10 +497,10 @@ const steps = [ //Item count //text - if (elementTotalText === '3415') { + if (elementTotalText === totalItems) { console.log('Passed: Total Items count label matched as expected'); } else { - errors.push(`Expected: Total Items: "3415"; Actual: "${elementTotalText}"`); + errors.push(`Expected: Total Items: "${totalItems}"; Actual: "${elementTotalText}"`); } //font-family @@ -484,9 +539,10 @@ const steps = [ //My Content Totals DIV - Unique Titles { - description: 'Validate My Content Totals DIV - Unique Titles', + description: 'My Content Totals DIV - Unique Titles', action: async () => { const multipleChecks = 'My Content Unique Titles count'; + const element = await driver.findElement(By.css('#total_titles > p')); const elementCount = await driver.findElement(By.css('#total_titles > b')); @@ -543,10 +599,10 @@ const steps = [ //Item count //text - if (elementTotalText === '3230') { + if (elementTotalText === uniqueTitleTotals) { console.log('Passed: Unique Titles count label matched as expected'); } else { - errors.push(`Expected: Unique Titles: "3230"; Actual: "${elementTotalText}"`); + errors.push(`Expected: Unique Titles: "${uniqueTitleTotals}"; Actual: "${elementTotalText}"`); } //font-family @@ -585,9 +641,10 @@ const steps = [ //My Content Totals DIV - Unique IDs { - description: 'Validate My Content Totals DIV - Unique IDs', + description: 'My Content Totals DIV - Unique IDs', action: async () => { const multipleChecks = 'My Content Unique IDs count'; + const element = await driver.findElement(By.css('#total_pubtotalids > p')); const elementCount = await driver.findElement(By.css('#total_pubtotalids > b')); @@ -644,10 +701,10 @@ const steps = [ //Item count //text - if (elementTotalText === '3264') { + if (elementTotalText === uniqueIdTotals) { console.log('Passed: Unique IDs count label matched as expected'); } else { - errors.push(`Expected: Unique IDs: "3264"; Actual: "${elementTotalText}"`); + errors.push(`Expected: Unique IDs: "${uniqueIdTotals}"; Actual: "${elementTotalText}"`); } //font-family @@ -686,9 +743,10 @@ const steps = [ //My Content Totals DIV - Content Set column header { - description: 'Validate My Content Totals DIV - Content Set column header', + description: 'My Content Totals DIV - Content Set column header', action: async () => { const multipleChecks = 'Content Set column headers'; + const element = await driver.findElement(By.css('.card-body > .table-sm th:nth-child(1)')); //Get text, font, size, and color @@ -743,9 +801,10 @@ const steps = [ //My Content Totals DIV - Total Items column header { - description: 'Validate My Content Totals DIV - Total Items column header', + description: 'My Content Totals DIV - Total Items column header', action: async () => { const multipleChecks = 'Total Items column headers'; + const element = await driver.findElement(By.css('.card-body > .table-sm th:nth-child(2)')); //Get text, font, size, and color @@ -800,9 +859,10 @@ const steps = [ //My Content Totals DIV - Unique Titles column header { - description: 'Validate My Content Totals DIV - Unique Titles column header', + description: 'My Content Totals DIV - Unique Titles column header', action: async () => { const multipleChecks = 'Unique Titles column headers'; + const element = await driver.findElement(By.css('.card-body > .table-sm th:nth-child(3)')); //Get text, font, size, and color @@ -857,9 +917,10 @@ const steps = [ //My Content Totals DIV - Unique IDs column header { - description: 'Validate My Content Totals DIV - Unique IDs column header', + description: 'My Content Totals DIV - Unique IDs column header', action: async () => { const multipleChecks = 'Unique IDs column headers'; + const element = await driver.findElement(By.css('.card-body > .table-sm th:nth-child(4)')); //Get text, font, size, and color @@ -912,1588 +973,90 @@ const steps = [ } }, - //My Content Totals DIV - Biology + //My Content Totals DIV - Table data (Content Set, Total Items, Unique Titles, Unique IDs) { - description: 'Validate My Content Totals DIV - Biology', + description: 'My Content Totals DIV - Table Content Set, Total Items, Unique Titles, and Unique IDs', action: async () => { - const multipleChecks = 'Biology label'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(1) > td:nth-child(1)')); + const multipleChecks = 'My Content Totals table data'; - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); + //Expected rows in display order: [Content Set, Total Items, Unique Titles, Unique IDs] (from myContentSets constant) + const expectedRows = myContentSets.map(s => [s.name, s.totalItems, s.uniqueTitles, s.uniqueIds]); + const columns = ['Content Set', 'Total Items', 'Unique Titles', 'Unique IDs']; + + //Expected cell styles per column [Content Set, Total Items, Unique Titles, Unique IDs] + const expectedStyles = [ + { font: 'Poppins, sans-serif', size: '12px', color: 'rgba(40, 39, 90, 1)' }, + { font: 'Poppins, sans-serif', size: '12px', color: 'rgba(40, 39, 90, 1)' }, + { font: 'Poppins, sans-serif', size: '12px', color: 'rgba(40, 39, 90, 1)' }, + { font: 'Poppins, sans-serif', size: '12px', color: 'rgba(40, 39, 90, 1)' }, + ]; + + //Wait for table rows to render + await driver.wait(until.elementLocated(By.css('#content_tbody > tr')), 20000, 'My Content Totals table rows did not load within 20 seconds'); + + //Read all cells in one call (textContent also works for rows scrolled out of view) + //Colors are normalized from rgb() to rgba() to match Selenium's getCssValue() format + const cellData = await driver.executeScript(` + const toRgba = c => c.startsWith('rgb(') ? c.replace('rgb(', 'rgba(').replace(')', ', 1)') : c; + return Array.from(document.querySelectorAll('#content_tbody > tr')).map(tr => + Array.from(tr.querySelectorAll('td')).map(td => { + const cs = window.getComputedStyle(td); + return { text: td.textContent.trim(), font: cs.fontFamily, size: cs.fontSize, color: toRgba(cs.color) }; + }) + ); + `); + const actualRows = cellData.map(row => row.map(cell => cell.text)); //Track all errors const errors = []; - //text - if (elementText === 'Biology') { - console.log('Passed: Biology label text matched as expected'); + //Row count + if (actualRows.length === expectedRows.length) { + console.log(`Passed: My Content Totals table row count matched as expected, ${expectedRows.length}`); } else { - errors.push(`Expected: "Biology"; Actual: "${elementText}"`); + errors.push(`Expected: ${expectedRows.length} table rows; Actual: ${actualRows.length}`); } - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Biology label text font matched as expected'); - } else { - errors.push(`Expected: Biology label text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Biology label text font-size matched as expected'); - } else { - errors.push(`Expected: Biology label text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Biology label text color matched as expected'); - } else { - errors.push(`Expected: Biology label text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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`); + //Cell-by-cell comparison + expectedRows.forEach((expected, rowIndex) => { + const actual = actualRows[rowIndex]; + if (!actual) { + errors.push(`Row ${rowIndex + 1} ("${expected[0]}") missing from table`); + return; } - //Throw collected messages — catch() will prefix with "FAILED:" - throw new Error(errors.join('\n')); - } - } - }, + const rowErrors = []; + columns.forEach((column, colIndex) => { + if (actual[colIndex] !== expected[colIndex]) { + rowErrors.push(`${column} Expected: "${expected[colIndex]}"; Actual: "${actual[colIndex]}"`); + } - //My Content Totals DIV - Biology total items count - { - description: 'Validate My Content Totals DIV - Biology total items count', - action: async () => { - const multipleChecks = 'Biology total items count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(1) > td:nth-child(2)')); + //Style checks (font-family, font-size, color) + const cell = cellData[rowIndex][colIndex]; + const style = expectedStyles[colIndex]; + if (!cell) return; + if (cell.font !== style.font) { + rowErrors.push(`${column} font Expected: "${style.font}"; Actual: "${cell.font}"`); + } + if (cell.size !== style.size) { + rowErrors.push(`${column} font-size Expected: "${style.size}"; Actual: "${cell.size}"`); + } + if (cell.color !== style.color) { + rowErrors.push(`${column} color Expected: "${style.color}"; Actual: "${cell.color}"`); + } + }); - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '1493') { - console.log('Passed: Biology total items count text matched as expected'); - } else { - errors.push(`Expected: Biology total items count: "1493"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Biology total items count text font matched as expected'); - } else { - errors.push(`Expected: Biology total items count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Biology total items count text font-size matched as expected'); - } else { - errors.push(`Expected: Biology total items count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Biology total items count text color matched as expected'); - } else { - errors.push(`Expected: Biology total items count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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`); + if (rowErrors.length === 0) { + console.log(`Passed: Row ${rowIndex + 1} "${expected[0]}" - ${columns.map((c, i) => `${c}: ${expected[i]}`).join(', ')} | Text font, size, and color all matched as expected`); + } else { + errors.push(`Row ${rowIndex + 1} ("${expected[0]}"): ${rowErrors.join('; ')}`); } + }); - //Throw collected messages — catch() will prefix with "FAILED:" - throw new Error(errors.join('\n')); - } - } - }, - - //My Content Totals DIV - Biology unique titles count - { - description: 'Validate My Content Totals DIV - Biology unique titles count', - action: async () => { - const multipleChecks = 'Biology unique titles count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(1) > td:nth-child(3)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '1482') { - console.log('Passed: Biology unique titles count text matched as expected'); - } else { - errors.push(`Expected: Biology unique titles count: "1482"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Biology unique titles count text font matched as expected'); - } else { - errors.push(`Expected: Biology unique titles count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Biology unique titles count text font-size matched as expected'); - } else { - errors.push(`Expected: Biology unique titles count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Biology unique titles count text color matched as expected'); - } else { - errors.push(`Expected: Biology unique titles count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - Biology unique ids count - { - description: 'Validate My Content Totals DIV - Biology unique ids count', - action: async () => { - const multipleChecks = 'Biology unique ids count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(1) > td:nth-child(4)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '1493') { - console.log('Passed: Biology unique ids count text matched as expected'); - } else { - errors.push(`Expected: Biology unique ids count: "1493"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Biology unique ids count text font matched as expected'); - } else { - errors.push(`Expected: Biology unique ids count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Biology unique ids count text font-size matched as expected'); - } else { - errors.push(`Expected: Biology unique ids count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Biology unique ids count text color matched as expected'); - } else { - errors.push(`Expected: Biology unique ids count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - Math Alignment Import Test - { - description: 'Validate My Content Totals DIV - Math Alignment Import Test', - action: async () => { - const multipleChecks = 'Math Alignment Import Test label'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(2) > td:nth-child(1)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === 'Math Alignment Import Test') { - console.log('Passed: Math Alignment Import Test label text matched as expected'); - } else { - errors.push(`Expected: "Math Alignment Import Test"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Math Alignment Import Test label text font matched as expected'); - } else { - errors.push(`Expected: Math Alignment Import Test label text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Math Alignment Import Test label text font-size matched as expected'); - } else { - errors.push(`Expected: Math Alignment Import Test label text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Math Alignment Import Test label text color matched as expected'); - } else { - errors.push(`Expected: Math Alignment Import Test label text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - Math Alignment Import Test total items count - { - description: 'Validate My Content Totals DIV - Math Alignment Import Test total items count', - action: async () => { - const multipleChecks = 'Math Alignment Import Test total items count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(2) > td:nth-child(2)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '730') { - console.log('Passed: Math Alignment Import Test total items count text matched as expected'); - } else { - errors.push(`Expected: Math Alignment Import Test total items count: "730"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Math Alignment Import Test total items count text font matched as expected'); - } else { - errors.push(`Expected: Math Alignment Import Test total items count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Math Alignment Import Test total items count text font-size matched as expected'); - } else { - errors.push(`Expected: Math Alignment Import Test total items count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Math Alignment Import Test total items count text color matched as expected'); - } else { - errors.push(`Expected: Math Alignment Import Test total items count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - Math Alignment Import Test unique titles count - { - description: 'Validate My Content Totals DIV - Math Alignment Import Test unique titles count', - action: async () => { - const multipleChecks = 'Math Alignment Import Test unique titles count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(2) > td:nth-child(3)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '707') { - console.log('Passed: Math Alignment Import Test unique titles count text matched as expected'); - } else { - errors.push(`Expected: Math Alignment Import Test unique titles count: "707"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Math Alignment Import Test unique titles count text font matched as expected'); - } else { - errors.push(`Expected: Math Alignment Import Test unique titles count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Math Alignment Import Test unique titles count text font-size matched as expected'); - } else { - errors.push(`Expected: Math Alignment Import Test unique titles count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Math Alignment Import Test unique titles count text color matched as expected'); - } else { - errors.push(`Expected: Math Alignment Import Test unique titles count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - Math Alignment Import Test unique ids count - { - description: 'Validate My Content Totals DIV - Math Alignment Import Test unique ids count', - action: async () => { - const multipleChecks = 'Math Alignment Import Test unique ids count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(2) > td:nth-child(4)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '728') { - console.log('Passed: Math Alignment Import Test unique ids count text matched as expected'); - } else { - errors.push(`Expected: Math Alignment Import Test unique ids count: "728"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Math Alignment Import Test unique ids count text font matched as expected'); - } else { - errors.push(`Expected: Math Alignment Import Test unique ids count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Math Alignment Import Test unique ids count text font-size matched as expected'); - } else { - errors.push(`Expected: Math Alignment Import Test unique ids count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Math Alignment Import Test unique ids count text color matched as expected'); - } else { - errors.push(`Expected: Math Alignment Import Test unique ids count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - English I - { - description: 'Validate My Content Totals DIV - English I', - action: async () => { - const multipleChecks = 'English I label'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(3) > td:nth-child(1)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === 'English I') { - console.log('Passed: English I label text matched as expected'); - } else { - errors.push(`Expected: "English I"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: English I label text font matched as expected'); - } else { - errors.push(`Expected: English I label text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: English I label text font-size matched as expected'); - } else { - errors.push(`Expected: English I label text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: English I label text color matched as expected'); - } else { - errors.push(`Expected: English I label text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - English I total items count - { - description: 'Validate My Content Totals DIV - English I total items count', - action: async () => { - const multipleChecks = 'English I total items count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(3) > td:nth-child(2)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '389') { - console.log('Passed: English I total items count text matched as expected'); - } else { - errors.push(`Expected: English I total items count: "389"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: English I total items count text font matched as expected'); - } else { - errors.push(`Expected: English I total items count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: English I total items count text font-size matched as expected'); - } else { - errors.push(`Expected: English I total items count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: English I total items count text color matched as expected'); - } else { - errors.push(`Expected: English I total items count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - English I unique titles count - { - description: 'Validate My Content Totals DIV - English I unique titles count', - action: async () => { - const multipleChecks = 'English I unique titles count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(3) > td:nth-child(3)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '389') { - console.log('Passed: English I unique titles count text matched as expected'); - } else { - errors.push(`Expected: English I unique titles count: "389"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: English I unique titles count text font matched as expected'); - } else { - errors.push(`Expected: English I unique titles count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: English I unique titles count text font-size matched as expected'); - } else { - errors.push(`Expected: English I unique titles count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: English I unique titles count text color matched as expected'); - } else { - errors.push(`Expected: English I unique titles count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - English I unique ids count - { - description: 'Validate My Content Totals DIV - English I unique ids count', - action: async () => { - const multipleChecks = 'Math Alignment Import Test unique ids count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(3) > td:nth-child(4)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '389') { - console.log('Passed: English I unique ids count text matched as expected'); - } else { - errors.push(`Expected: English I unique ids count: "389"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: English I unique ids count text font matched as expected'); - } else { - errors.push(`Expected: English I unique ids count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: English I unique ids count text font-size matched as expected'); - } else { - errors.push(`Expected: English I unique ids count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: English I unique ids count text color matched as expected'); - } else { - errors.push(`Expected: English I unique ids count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - Copy Move Delete Test 2 - { - description: 'Validate My Content Totals DIV - Copy Move Delete Test 2', - action: async () => { - const multipleChecks = 'Copy Move Delete Test 2 label'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(4) > td:nth-child(1)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === 'Copy Move Delete Test 2') { - console.log('Passed: Copy Move Delete Test 2 label text matched as expected'); - } else { - errors.push(`Expected: "Copy Move Delete Test 2"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Copy Move Delete Test 2 label text font matched as expected'); - } else { - errors.push(`Expected: Copy Move Delete Test 2 label text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Copy Move Delete Test 2 label text font-size matched as expected'); - } else { - errors.push(`Expected: Copy Move Delete Test 2 label text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Copy Move Delete Test 2 label text color matched as expected'); - } else { - errors.push(`Expected: Copy Move Delete Test 2 label text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - Copy Move Delete Test 2 total items count - { - description: 'Validate My Content Totals DIV - Copy Move Delete Test 2 total items count', - action: async () => { - const multipleChecks = 'Copy Move Delete Test 2 total items count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(4) > td:nth-child(2)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '327') { - console.log('Passed: Copy Move Delete Test 2 total items count text matched as expected'); - } else { - errors.push(`Expected: Copy Move Delete Test 2 total items count: "327"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Copy Move Delete Test 2 total items count text font matched as expected'); - } else { - errors.push(`Expected: Copy Move Delete Test 2 total items count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Copy Move Delete Test 2 total items count text font-size matched as expected'); - } else { - errors.push(`Expected: Copy Move Delete Test 2 total items count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Copy Move Delete Test 2 total items count text color matched as expected'); - } else { - errors.push(`Expected: Copy Move Delete Test 2 total items count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - Copy Move Delete Test 2 unique titles count - { - description: 'Validate My Content Totals DIV - Copy Move Delete Test 2 unique titles count', - action: async () => { - const multipleChecks = 'Copy Move Delete Test 2 unique titles count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(4) > td:nth-child(3)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '327') { - console.log('Passed: Copy Move Delete Test 2 unique titles count text matched as expected'); - } else { - errors.push(`Expected: Copy Move Delete Test 2 unique titles count: "327"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Copy Move Delete Test 2 unique titles count text font matched as expected'); - } else { - errors.push(`Expected: Copy Move Delete Test 2 unique titles count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Copy Move Delete Test 2 unique titles count text font-size matched as expected'); - } else { - errors.push(`Expected: Copy Move Delete Test 2 unique titles count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Copy Move Delete Test 2 unique titles count text color matched as expected'); - } else { - errors.push(`Expected: Copy Move Delete Test 2 unique titles count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - Copy Move Delete Test 2 unique ids count - { - description: 'Validate My Content Totals DIV - Copy Move Delete Test 2 unique ids count', - action: async () => { - const multipleChecks = 'Copy Move Delete Test 2 unique ids count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(4) > td:nth-child(4)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '328') { - console.log('Passed: Copy Move Delete Test 2 unique ids count text matched as expected'); - } else { - errors.push(`Expected: Copy Move Delete Test 2 unique ids count: "328"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Copy Move Delete Test 2 unique ids count text font matched as expected'); - } else { - errors.push(`Expected: Copy Move Delete Test 2 unique ids count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Copy Move Delete Test 2 unique ids count text font-size matched as expected'); - } else { - errors.push(`Expected: Copy Move Delete Test 2 unique ids count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Copy Move Delete Test 2 unique ids count text color matched as expected'); - } else { - errors.push(`Expected: Copy Move Delete Test 2 unique ids count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - Algebra - { - description: 'Validate My Content Totals DIV - Algebra', - action: async () => { - const multipleChecks = 'Algebra label'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(5) > td:nth-child(1)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === 'Algebra') { - console.log('Passed: Algebra label text matched as expected'); - } else { - errors.push(`Expected: "Algebra"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Algebra label text font matched as expected'); - } else { - errors.push(`Expected: Algebra label text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Algebra label text font-size matched as expected'); - } else { - errors.push(`Expected: Algebra label text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Algebra label text color matched as expected'); - } else { - errors.push(`Expected: Algebra label text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - Algebra total items count - { - description: 'Validate My Content Totals DIV - Algebra total items count', - action: async () => { - const multipleChecks = 'Algebra total items count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(5) > td:nth-child(2)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '192') { - console.log('Passed: Algebra total items count text matched as expected'); - } else { - errors.push(`Expected: Algebra total items count: "192"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Algebra total items count text font matched as expected'); - } else { - errors.push(`Expected: Algebra total items count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Algebra total items count text font-size matched as expected'); - } else { - errors.push(`Expected: Algebra total items count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Algebra total items count text color matched as expected'); - } else { - errors.push(`Expected: Algebra total items count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - Algebra unique titles count - { - description: 'Validate My Content Totals DIV - Algebra unique titles count', - action: async () => { - const multipleChecks = 'Algebra unique titles count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(5) > td:nth-child(3)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '194') { - console.log('Passed: Algebra unique titles count text matched as expected'); - } else { - errors.push(`Expected: Algebra unique titles count: "194"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Algebra unique titles count text font matched as expected'); - } else { - errors.push(`Expected: Algebra unique titles count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Algebra unique titles count text font-size matched as expected'); - } else { - errors.push(`Expected: Algebra unique titles count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Algebra unique titles count text color matched as expected'); - } else { - errors.push(`Expected: Algebra unique titles count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - Algebra unique ids count - { - description: 'Validate My Content Totals DIV - Algebra unique ids count', - action: async () => { - const multipleChecks = 'Algebra unique ids count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(5) > td:nth-child(4)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '189') { - console.log('Passed: Algebra unique ids count text matched as expected'); - } else { - errors.push(`Expected: Algebra unique ids count: "189"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Algebra unique ids count text font matched as expected'); - } else { - errors.push(`Expected: Algebra unique ids count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Algebra unique ids count text font-size matched as expected'); - } else { - errors.push(`Expected: Algebra unique ids count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Algebra unique ids count text color matched as expected'); - } else { - errors.push(`Expected: Algebra unique ids count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - US History III - { - description: 'Validate My Content Totals DIV - US History III', - action: async () => { - const multipleChecks = 'US History III label'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(6) > td:nth-child(1)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === 'US History III') { - console.log('Passed: US History III label text matched as expected'); - } else { - errors.push(`Expected: "US History III"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: US History III label text font matched as expected'); - } else { - errors.push(`Expected: US History III label text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: US History III label text font-size matched as expected'); - } else { - errors.push(`Expected: US History III label text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: US History III label text color matched as expected'); - } else { - errors.push(`Expected: US History III label text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - US History III total items count - { - description: 'Validate My Content Totals DIV - US History III total items count', - action: async () => { - const multipleChecks = 'US History III total items count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(6) > td:nth-child(2)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '67') { - console.log('Passed: US History III total items count text matched as expected'); - } else { - errors.push(`Expected: US History III total items count: "67"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: US History III total items count text font matched as expected'); - } else { - errors.push(`Expected: US History III total items count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: US History III total items count text font-size matched as expected'); - } else { - errors.push(`Expected: US History III total items count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: US History III total items count text color matched as expected'); - } else { - errors.push(`Expected: US History III total items count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - US History III unique titles count - { - description: 'Validate My Content Totals DIV - US History III unique titles count', - action: async () => { - const multipleChecks = 'US History III unique titles count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(6) > td:nth-child(3)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '67') { - console.log('Passed: US History III unique titles count text matched as expected'); - } else { - errors.push(`Expected: US History III unique titles count: "67"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: US History III unique titles count text font matched as expected'); - } else { - errors.push(`Expected: US History III unique titles count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: US History III unique titles count text font-size matched as expected'); - } else { - errors.push(`Expected: US History III unique titles count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: US History III unique titles count text color matched as expected'); - } else { - errors.push(`Expected: US History III unique titles count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - US History III unique ids count - { - description: 'Validate My Content Totals DIV - US History III unique ids count', - action: async () => { - const multipleChecks = 'US History III unique ids count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(6) > td:nth-child(4)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '66') { - console.log('Passed: US History III unique ids count text matched as expected'); - } else { - errors.push(`Expected: US History III unique ids count: "66"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: US History III unique ids count text font matched as expected'); - } else { - errors.push(`Expected: US History III unique ids count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: US History III unique ids count text font-size matched as expected'); - } else { - errors.push(`Expected: US History III unique ids count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: US History III unique ids count text color matched as expected'); - } else { - errors.push(`Expected: US History III unique ids count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - Create Me - { - description: 'Validate My Content Totals DIV - Create Me', - action: async () => { - const multipleChecks = 'Create Me label'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(12) > td:nth-child(1)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === 'create me') { - console.log('Passed: Create Me label text matched as expected'); - } else { - errors.push(`Expected: "create me"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Create Me label text font matched as expected'); - } else { - errors.push(`Expected: Create Me label text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Create Me label text font-size matched as expected'); - } else { - errors.push(`Expected: Create Me label text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Create Me label text color matched as expected'); - } else { - errors.push(`Expected: Create Me label text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - Create Me total items count - { - description: 'Validate My Content Totals DIV - Create Me total items count', - action: async () => { - const multipleChecks = 'Create Me total items count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(12) > td:nth-child(2)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '6') { - console.log('Passed: Create Me total items count text matched as expected'); - } else { - errors.push(`Expected: Create Me total items count: "6"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Create Me total items count text font matched as expected'); - } else { - errors.push(`Expected: Create Me total items count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Create Me total items count text font-size matched as expected'); - } else { - errors.push(`Expected: Create Me total items count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Create Me total items count text color matched as expected'); - } else { - errors.push(`Expected: Create Me total items count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - Create Me unique titles count - { - description: 'Validate My Content Totals DIV - Create Me unique titles count', - action: async () => { - const multipleChecks = 'Create Me unique titles count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(12) > td:nth-child(3)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '6') { - console.log('Passed: Create Me unique titles count text matched as expected'); - } else { - errors.push(`Expected: Create Me unique titles count: "6"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Create Me unique titles count text font matched as expected'); - } else { - errors.push(`Expected: Create Me unique titles count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Create Me unique titles count text font-size matched as expected'); - } else { - errors.push(`Expected: Create Me unique titles count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Create Me unique titles count text color matched as expected'); - } else { - errors.push(`Expected: Create Me unique titles count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //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')); - } - } - }, - - //My Content Totals DIV - Create Me unique ids count - { - description: 'Validate My Content Totals DIV - Create Me unique ids count', - action: async () => { - const multipleChecks = 'Create Me unique ids count'; - const element = await driver.findElement(By.css('#content_tbody > tr:nth-child(12) > td:nth-child(4)')); - - //Get text, font, size, and color - const elementText = await element.getText(''); - const elementTextFont = await element.getCssValue('font-family'); - const elementTextSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - - //Track all errors - const errors = []; - - //text - if (elementText === '5') { - console.log('Passed: Create Me unique ids count text matched as expected'); - } else { - errors.push(`Expected: Create Me unique ids count: "5"; Actual: "${elementText}"`); - } - - //font-family - if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Create Me unique ids count text font matched as expected'); - } else { - errors.push(`Expected: Create Me unique ids count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); - } - - //font size - if (elementTextSize === '12px') { - console.log('Passed: Create Me unique ids count text font-size matched as expected'); - } else { - errors.push(`Expected: Create Me unique ids count text font-size "12px"; Actual: "${elementTextSize}"`); - } - - //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Create Me unique ids count text color matched as expected'); - } else { - errors.push(`Expected: Create Me unique ids count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } + //Report any unexpected extra rows + actualRows.slice(expectedRows.length).forEach((extra, i) => { + errors.push(`Unexpected row ${expectedRows.length + i + 1}: ${JSON.stringify(extra)}`); + }); //Throw summary if any validation failed if (errors.length > 0) { @@ -2510,9 +1073,10 @@ const steps = [ //Close button { - description: 'Validate Close button', + description: 'Close button', action: async () => { const multipleChecks = 'Close button'; + const element = await driver.findElement(By.css('#all_content_modal .btn-secondary')); //text, font, size, and color @@ -2575,9 +1139,10 @@ const steps = [ //Export button { - description: 'Validate Export button', + description: 'Export button', action: async () => { const multipleChecks = 'Export button'; + const element = await driver.findElement(By.css('#export_btn')); //Get text, font, color, and size @@ -2650,7 +1215,7 @@ const steps = [ //Ellipsis icon color { - description: 'Validate ellipsis icon color', + description: 'Ellipsis icon color', action: async () => { const elementStyle = await driver.findElement(By.css('.fa-ellipsis-h')).getCssValue('color'); if (elementStyle === 'rgba(40, 39, 90, 1)') { @@ -2663,7 +1228,7 @@ const steps = [ //Search icon color { - description: 'Validate search icon color', + description: 'Search icon color', action: async () => { const elementStyle = await driver.findElement(By.css('.col-12 > .fa')).getCssValue('color'); if (elementStyle === 'rgba(40, 39, 90, 1)') { @@ -2676,9 +1241,10 @@ const steps = [ //Filter textbox placeholder { - description: 'Validate Filter placeholder text', + description: 'Filter placeholder text', action: async () => { const multipleChecks = 'Filter textbox'; + const element = await driver.findElement(By.css('#content-org-filter')); //Get text, font, size, and color @@ -2745,9 +1311,10 @@ const steps = [ //Sort label { - description: 'Validate My Sort label', + description: 'My Sort label', action: async () => { const multipleChecks = 'Sort label'; + const element = await driver.findElement(By.css('.col-4')); //Get text, font, size, and color @@ -2802,9 +1369,10 @@ const steps = [ //Sort dropdown values (SPECIAL CASE: validate default selection) { - description: 'Validate Sort dropdown values', + description: 'Sort dropdown values', action: async () => { const multipleChecks = 'Sort dropdown values'; + const dropdown = await driver.wait(until.elementLocated(By.css('#orgsort')), 5000); //Wrap with Select class for full dropdown functionality @@ -2853,9 +1421,10 @@ const steps = [ //My Content - Biology { - description: 'Validate Biology link', + description: 'Biology link', action: async () => { const multipleChecks = 'My Content - Biology link'; + const element = await driver.findElement(By.linkText('Biology')); //Get href, text, font, size, and color @@ -2918,9 +1487,10 @@ const steps = [ //My Content - Edit Biology icon { - description: 'Validate Edit Biology icon', + description: 'Edit Biology icon', action: async () => { const multipleChecks = 'My Content - Edit Biology icon'; + const element = await driver.findElement(By.css('#content-org-list > li > div.orgname > a.ml-2')); //Get href, text, font, size, and color @@ -2965,270 +1535,153 @@ const steps = [ } }, - //Validate default sort order top6 - - //My Content - Biology sort order 1st + //My Content - List data (default sort: Count) - Content Set link, edit icon, and count { - description: 'Validate Biology sort order', + description: 'My Content list - Content Set name, link, edit icon, and count (default Count sort order)', action: async () => { - const multipleChecks = 'My Content - Biology sort order'; - const elementContent = await driver.findElement(By.xpath(`//a[contains(.,'Biology')]`)).getText(); - const elementURL = await driver.findElement(By.xpath('(//ul[@id="content-org-list"])[1]/li/div[@class="orgname"]/a[2]')).getAttribute('href'); - const elementCount = await driver.findElement(By.xpath('//li/div/span')).getText(); + const multipleChecks = 'My Content list data'; + + const baseURL = 'https://correlation.edgate.com/exact/'; + + //Expected items in display order: [Content Set, Count, Content Set ID] (from myContentSets constant) + //ID null = ID not yet captured; link and edit URLs are then checked for format and matching IDs only + const expectedItems = myContentSets.map(s => [s.name, s.totalItems, s.id]); + + //Expected styles (null = not yet confirmed; actual value is logged instead of checked) + const nameStyle = { font: 'Poppins, sans-serif', size: '14.3px', color: 'rgba(73, 80, 87, 1)' }; + const editIconStyle = { title: 'Edit Content Set', color: 'rgba(73, 80, 87, 1)' }; + const countStyle = { font: 'Poppins, sans-serif', size: '12.87px', color: 'rgba(40, 39, 90, 1)' }; + + //Wait for list to render + await driver.wait(until.elementLocated(By.xpath('(//ul[@id="content-org-list"])[1]/li')), 20000, 'My Content list did not load within 20 seconds'); + + //Read all items in one call. Each item is the nth (nested) ul#content-org-list: + // li > div.orgname > a[1] = Content Set link, a[2] = edit icon; li > div > span = count + //Colors are normalized from rgb() to rgba() to match Selenium's getCssValue() format + const items = await driver.executeScript(` + const toRgba = c => c && c.startsWith('rgb(') ? c.replace('rgb(', 'rgba(').replace(')', ', 1)') : c; + const styleOf = el => { + if (!el) return null; + const cs = window.getComputedStyle(el); + return { font: cs.fontFamily, size: cs.fontSize, color: toRgba(cs.color) }; + }; + return Array.from(document.querySelectorAll('ul#content-org-list')).map(ul => { + const li = ul.querySelector(':scope > li'); + if (!li) return null; + const links = li.querySelectorAll(':scope > div.orgname > a'); + const nameLink = links[0] || null; + const editIcon = links[1] || null; + const count = li.querySelector(':scope > div > span'); + return { + name: nameLink ? nameLink.textContent.trim() : null, + nameHref: nameLink ? nameLink.href : null, + nameStyle: styleOf(nameLink), + editHref: editIcon ? editIcon.href : null, + editTitle: editIcon ? editIcon.getAttribute('title') : null, + editColor: editIcon ? toRgba(window.getComputedStyle(editIcon).color) : null, + count: count ? count.textContent.trim() : null, + countStyle: styleOf(count), + }; + }).filter(Boolean); + `); //Track all errors const errors = []; - //text - if (elementContent === 'Biology') { - console.log('Passed: Biology listed in first place as expected'); + //Item count + if (items.length === expectedItems.length) { + console.log(`Passed: My Content list item count matched as expected, ${expectedItems.length}`); } else { - errors.push(`Expected: First place: "Biology" ; Actual: "${elementContent}"`); + errors.push(`Expected: ${expectedItems.length} list items; Actual: ${items.length}`); } - //url - if (elementURL === 'https://correlation.edgate.com/exact/contentset_edit_modal.php?id=585821587') { - console.log('Passed: Biology edit icon link listed in first place as expected'); - } else { - errors.push(`Expected: First place: "https://correlation.edgate.com/exact/contentset_edit_modal.php?id=585821587"; Actual: "${elementURL}"`); - } + //Compare a style object against expected values (null expected = log only) + const checkStyle = (label, actual, expected, itemErrors) => { + if (!actual) { + itemErrors.push(`${label} element not found`); + return; + } + [['font', 'font'], ['size', 'font-size'], ['color', 'color']].forEach(([key, cssName]) => { + if (expected[key] === null) return; + if (actual[key] !== expected[key]) { + itemErrors.push(`${label} ${cssName} Expected: "${expected[key]}"; Actual: "${actual[key]}"`); + } + }); + }; - //count - if (elementCount === '1493') { - console.log('Passed: Biology content count listed in first place as expected'); - } else { - errors.push(`Expected: First place: Biology content count: "1493"; Actual: "${elementCount}"`); - } - - //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`); + //Item-by-item comparison + expectedItems.forEach(([expName, expCount, expId], index) => { + const item = items[index]; + const position = index + 1; + if (!item) { + errors.push(`Position ${position} ("${expName}") missing from list`); + return; } - //Throw collected messages — catch() will prefix with "FAILED:" - throw new Error(errors.join('\n')); - } - } - }, + const itemErrors = []; - //My Content - Math Alignment Import Test sort order 2nd - { - description: 'Validate Math Alignment Import Test sort order', - action: async () => { - const multipleChecks = 'My Content - Math Alignment Import Test sort order'; - const elementContent = await driver.findElement(By.xpath(`//a[contains(.,'Math Alignment Import Test')]`)).getText(); - const elementURL = await driver.findElement(By.xpath('(//ul[@id="content-org-list"])[2]/li/div[@class="orgname"]/a[2]')).getAttribute('href'); - const elementCount = await driver.findElement(By.xpath('//ul/ul/li/div/span')).getText(); - - //Track all errors - const errors = []; - - //text - if (elementContent === 'Math Alignment Import Test') { - console.log('Passed: Math Alignment Import Test listed in second place as expected'); - } else { - errors.push(`Expected: Second place: "Math Alignment Import Test" ; Actual: "${elementContent}"`); - } - - //url - if (elementURL === 'https://correlation.edgate.com/exact/contentset_edit_modal.php?id=1423792414') { - console.log('Passed: Math Alignment Import Test edit icon link listed in second place as expected'); - } else { - errors.push(`Expected: Second place: "https://correlation.edgate.com/exact/contentset_edit_modal.php?id=1423792414"; Actual: "${elementURL}"`); - } - - //count - if (elementCount === '730') { - console.log('Passed: Math Alignment Import Test content count listed in second place as expected'); - } else { - errors.push(`Expected: Second place: Math Alignment Import Test content count: "730"; Actual: "${elementCount}"`); - } - - //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`); + //Content Set name (also validates sort order) + if (item.name !== expName) { + itemErrors.push(`Content Set Expected: "${expName}"; Actual: "${item.name}"`); } - //Throw collected messages — catch() will prefix with "FAILED:" - throw new Error(errors.join('\n')); - } - } - }, - - //My Content - English I sort order 3rd - { - description: 'Validate English I sort order', - action: async () => { - const multipleChecks = 'My Content - English I sort order'; - const elementContent = await driver.findElement(By.xpath(`//a[contains(.,'English I')]`)).getText(); - const elementURL = await driver.findElement(By.xpath('(//ul[@id="content-org-list"])[3]/li/div[@class="orgname"]/a[2]')).getAttribute('href'); - const elementCount = await driver.findElement(By.xpath('//ul/ul/ul/li/div/span')).getText(); - - //Track all errors - const errors = []; - - //text - if (elementContent === 'English I') { - console.log('Passed: English I listed in third place as expected'); - } else { - errors.push(`Expected: Third place: "English I" ; Actual: "${elementContent}"`); - } - - //url - if (elementURL === 'https://correlation.edgate.com/exact/contentset_edit_modal.php?id=585821585') { - console.log('Passed: English I edit icon link listed in third place as expected'); - } else { - errors.push(`Expected: Third place: "https://correlation.edgate.com/exact/contentset_edit_modal.php?id=585821585"; Actual: "${elementURL}"`); - } - - //count - if (elementCount === '389') { - console.log('Passed: English I content count listed in third place as expected'); - } else { - errors.push(`Expected: Third place: English I content count: "389"; Actual: "${elementCount}"`); - } - - //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`); + //Count + if (item.count !== expCount) { + itemErrors.push(`Count Expected: "${expCount}"; Actual: "${item.count}"`); } - //Throw collected messages — catch() will prefix with "FAILED:" - throw new Error(errors.join('\n')); - } - } - }, - - //My Content - Copy Move Delete Test 2 sort order 4th - { - description: 'Validate Copy Move Delete Test 2 sort order', - action: async () => { - const multipleChecks = 'My Content - Copy Move Delete Test 2 sort order'; - const elementContent = await driver.findElement(By.xpath(`//a[contains(.,'Copy Move Delete Test 2')]`)).getText(); - const elementURL = await driver.findElement(By.xpath('(//ul[@id="content-org-list"])[4]/li/div[@class="orgname"]/a[2]')).getAttribute('href'); - const elementCount = await driver.findElement(By.xpath('//ul/ul/ul/ul/li/div/span')).getText(); - - //Track all errors - const errors = []; - - //text - if (elementContent === 'Copy Move Delete Test 2') { - console.log('Passed: Copy Move Delete Test 2 in fourth place as expected'); - } else { - errors.push(`Expected: Fourth place: "Copy Move Delete Test 2" ; Actual: "${elementContent}"`); - } - - //url - if (elementURL === 'https://correlation.edgate.com/exact/contentset_edit_modal.php?id=1228574325') { - console.log('Passed: Copy Move Delete Test 2 edit icon link listed in fourth place as expected'); - } else { - errors.push(`Expected: Fourth place: "https://correlation.edgate.com/exact/contentset_edit_modal.php?id=1228574325"; Actual: "${elementURL}"`); - } - - //count - if (elementCount === '327') { - console.log('Passed: Copy Move Delete Test 2 content count listed in fourth place as expected'); - } else { - errors.push(`Expected: Fourth place: Copy Move Delete Test 2 content count: "327"; Actual: "${elementCount}"`); - } - - //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`); + //Content Set link and edit icon URLs + const nameId = (item.nameHref || '').match(/[?&]iPublisherId=(\d+)&function=listUnits$/); + const editId = (item.editHref || '').match(/contentset_edit_modal\.php\?id=(\d+)$/); + if (expId) { + const expNameURL = `${baseURL}?iPublisherId=${expId}&function=listUnits`; + const expEditURL = `${baseURL}contentset_edit_modal.php?id=${expId}`; + if (item.nameHref !== expNameURL) { + itemErrors.push(`Content Set link Expected: "${expNameURL}"; Actual: "${item.nameHref}"`); + } + if (item.editHref !== expEditURL) { + itemErrors.push(`Edit icon link Expected: "${expEditURL}"; Actual: "${item.editHref}"`); + } + } else { + if (!nameId || !(item.nameHref || '').startsWith(baseURL)) { + itemErrors.push(`Content Set link Expected format: "${baseURL}?iPublisherId=&function=listUnits"; Actual: "${item.nameHref}"`); + } + if (!editId || !(item.editHref || '').startsWith(baseURL)) { + itemErrors.push(`Edit icon link Expected format: "${baseURL}contentset_edit_modal.php?id="; Actual: "${item.editHref}"`); + } + if (nameId && editId && nameId[1] !== editId[1]) { + itemErrors.push(`Content Set link ID "${nameId[1]}" does not match edit icon ID "${editId[1]}"`); + } } - //Throw collected messages — catch() will prefix with "FAILED:" - throw new Error(errors.join('\n')); - } - } - }, - - //My Content - Algebra sort order 5th - { - description: 'Validate Algebra sort order', - action: async () => { - const multipleChecks = 'My Content - Algebra sort order'; - const elementContent = await driver.findElement(By.xpath(`//a[contains(.,'Algebra')]`)).getText(); - const elementURL = await driver.findElement(By.xpath('(//ul[@id="content-org-list"])[5]/li/div[@class="orgname"]/a[2]')).getAttribute('href'); - const elementCount = await driver.findElement(By.xpath('//ul/ul/ul/ul/ul/li/div/span')).getText(); - - //Track all errors - const errors = []; - - //text - if (elementContent === 'Algebra') { - console.log('Passed: Algebra in fifth place as expected'); - } else { - errors.push(`Expected: Fifth place: "Algebra" ; Actual: "${elementContent}"`); - } - - //url - if (elementURL === 'https://correlation.edgate.com/exact/contentset_edit_modal.php?id=585821586') { - console.log('Passed: Algebra edit icon link listed in fifth place as expected'); - } else { - errors.push(`Expected: Fifth place: "https://correlation.edgate.com/exact/contentset_edit_modal.php?id=585821586"; Actual: "${elementURL}"`); - } - - //count - if (elementCount === '192') { - console.log('Passed: Algebra content count listed in fifth place as expected'); - } else { - errors.push(`Expected: Fifth place: Algebra content count: "192"; Actual: "${elementCount}"`); - } - - //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`); + //Edit icon title and color + if (item.editTitle !== editIconStyle.title) { + itemErrors.push(`Edit icon title Expected: "${editIconStyle.title}"; Actual: "${item.editTitle}"`); + } + if (item.editColor !== editIconStyle.color) { + itemErrors.push(`Edit icon color Expected: "${editIconStyle.color}"; Actual: "${item.editColor}"`); } - //Throw collected messages — catch() will prefix with "FAILED:" - throw new Error(errors.join('\n')); - } - } - }, + //Content Set link and count styles + checkStyle('Content Set', item.nameStyle, nameStyle, itemErrors); + checkStyle('Count', item.countStyle, countStyle, itemErrors); - //My Content - US History III sort order 6th - { - description: 'Validate US History III sort order', - action: async () => { - const multipleChecks = 'My Content - US History III sort order'; - const elementContent = await driver.findElement(By.xpath(`//a[contains(.,'US History III')]`)).getText(); - const elementURL = await driver.findElement(By.xpath('(//ul[@id="content-org-list"])[6]/li/div[@class="orgname"]/a[2]')).getAttribute('href'); - const elementCount = await driver.findElement(By.xpath('//ul/ul/ul/ul/ul/ul/li/div/span')).getText(); + if (itemErrors.length === 0) { + console.log(`Passed: Position ${position} "${expName}" - Item count: ${expCount}, URL, edit icon, and styles all matched as expected`); + } else { + errors.push(`Position ${position} ("${expName}"): ${itemErrors.join('; ')}`); + } + }); - //Track all errors - const errors = []; - - //text - if (elementContent === 'US History III') { - console.log('Passed: US History III in sixth place as expected'); - } else { - errors.push(`Expected: Sixth place: "US History III" ; Actual: "${elementContent}"`); + //Log actual count styles while countStyle expected values are not yet set + if (Object.values(countStyle).some(v => v === null) && items[0] && items[0].countStyle) { + console.log(`INFO: Count style not yet validated; actual (position 1): ${JSON.stringify(items[0].countStyle)}`); } - //url - if (elementURL === 'https://correlation.edgate.com/exact/contentset_edit_modal.php?id=585821589') { - console.log('Passed: US History III edit icon link listed in sixth place as expected'); - } else { - errors.push(`Expected: Sxth place: "https://correlation.edgate.com/exact/contentset_edit_modal.php?id=585821589"; Actual: "${elementURL}"`); - } - - //count - if (elementCount === '67') { - console.log('Passed: US History III content count listed in sixth place as expected'); - } else { - errors.push(`Expected: Sixth place: US History III content count: "67"; Actual: "${elementCount}"`); - } + //Report any unexpected extra items + items.slice(expectedItems.length).forEach((extra, i) => { + errors.push(`Unexpected item at position ${expectedItems.length + i + 1}: "${extra.name}" (${extra.count})`); + }); //Throw summary if any validation failed if (errors.length > 0) { @@ -3249,6 +1702,7 @@ const steps = [ action: async () => { await driver.findElement(By.css('#content-org-list > li > div.orgname > a.ml-2')).click(); console.log('----->| NEXT ACTION: Clicked Biology edit icon'); + await driver.sleep(2000); //Wait until the modal title is located AND visible await driver.wait(async () => { @@ -3266,9 +1720,10 @@ const steps = [ //Edit DIV - title { - description: 'Validate Edit DIV title', + description: 'Edit DIV title', action: async () => { const multipleChecks = 'Edit DIV title'; + const element = await driver.findElement(By.css('.modal-lg .modal-title')); //Get text, font, size, and color @@ -3323,9 +1778,10 @@ const steps = [ //Edit DIV - label { - description: 'Validate Edit DIV - Content Set Name label', + description: 'Edit DIV - Content Set Name label', action: async () => { const multipleChecks = 'Edit DIV label'; + const element = await driver.findElement(By.css('.modal-lg .form-label')); //Get text, font, size, and color @@ -3380,9 +1836,10 @@ const steps = [ //Edit DIV - textbox { - description: 'Validate Edit DIV textbox', + description: 'Edit DIV textbox', action: async () => { const multipleChecks = 'Edit DIV texbox'; + const element = await driver.findElement(By.css('#orgname')); //Get text, font, size, and color @@ -3437,9 +1894,10 @@ const steps = [ //Delete button { - description: 'Validate Delete button', + description: 'Delete button', action: async () => { const multipleChecks = 'Delete button'; + const element = await driver.findElement(By.css('.modal-lg #orgdelete')); //Get text, font, color, and size @@ -3518,9 +1976,10 @@ const steps = [ //Save button { - description: 'Validate Save button', + description: 'Save button', action: async () => { const multipleChecks = 'Save button'; + const element = await driver.findElement(By.css('#modalop')); //Get text, font, color, and size @@ -3583,9 +2042,10 @@ const steps = [ //Close button { - description: 'Validate Close button', + description: 'Close button', action: async () => { const multipleChecks = 'Close button'; + const element = await driver.findElement(By.css('#modalclose')); //Get text, font, color, and size @@ -3662,6 +2122,7 @@ const steps = [ action: async () => { await driver.findElement(By.css('#mycontentlist > #content-org-list > .content-org .badge')).click(); console.log('----->| NEXT ACTION: Clicked Biology 1493 content link'); + await driver.sleep(2000); //Wait until the modal title is located AND visible await driver.wait(async () => { @@ -3679,9 +2140,10 @@ const steps = [ //Biology Totals DIV - title { - description: 'Validate Biology Totals DIV title', + description: 'Biology Totals DIV title', action: async () => { const multipleChecks = 'Biology Totals DIV title'; + const element = await driver.findElement(By.css('.content_modal_title')); //Get text, font, size, and color @@ -3736,9 +2198,10 @@ const steps = [ //Biology Total Items count 1493 { - description: 'Validate Biology DIV - Total Items count', + description: 'Biology DIV - Total Items count', action: async () => { const multipleChecks = 'Biology DIV Total Items count'; + const element = await driver.findElement(By.css('#total > b')); //Get text, font, size, and color @@ -3751,31 +2214,31 @@ const steps = [ const errors = []; //text - if (elementText === '1493') { - console.log('Passed: Biology Total Items: 1493 count text matched as expected'); + if (elementText === biologyTotalItems) { + console.log(`Passed: Biology Total Items: ${biologyTotalItems} count text matched as expected`); } else { - errors.push(`Expected: Biology Total Items: "1493"; Actual: "${elementText}"`); + errors.push(`Expected: Biology Total Items: "${biologyTotalItems}"; Actual: "${elementText}"`); } //font-family if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Biology Total Items: 1493 count text font matched as expected'); + console.log('Passed: Biology Total Items: Count text font matched as expected'); } else { - errors.push(`Expected: Biology Total Items: 1493 count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); + errors.push(`Expected: Biology Total Items: Count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); } //font size if (elementTextSize === '36px') { - console.log('Passed: Biology Total Items: 1493 count text ont-size matched as expected'); + console.log('Passed: Biology Total Items: Count text font-size matched as expected'); } else { - errors.push(`Expected: Biology Total Items: 1493 count text font-size "36px"; Actual: "${elementTextSize}"`); + errors.push(`Expected: Biology Total Items: Count text font-size "36px"; Actual: "${elementTextSize}"`); } //color if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Biology Total Items: 1493 count text color matched as expected'); + console.log('Passed: Biology Total Items: Count text color matched as expected'); } else { - errors.push(`Expected: Biology Total Items: 1493 count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); + errors.push(`Expected: Biology Total Items: Count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); } //Throw summary if any validation failed @@ -3793,9 +2256,10 @@ const steps = [ //Biology Total Items (SPECIAL CASE: css path with trimmed text) { - description: 'Validate Biology DIV - Total Items', + description: 'Biology DIV - Total Items', action: async () => { const multipleChecks = 'Biology DIV Total Items'; + const element = await driver.findElement(By.css('#total')); //Extract the bare text node (everything that's not a tag) @@ -3860,9 +2324,10 @@ const steps = [ //Biology Unique Titles count 3230 { - description: 'Validate Biology DIV - Unique Titles count', + description: 'Biology DIV - Unique Titles count', action: async () => { const multipleChecks = 'Biology DIV Unique Titles count'; + const element = await driver.findElement(By.css('#total_titles > b')); //Get text, font, size, and color @@ -3875,31 +2340,31 @@ const steps = [ const errors = []; //text - if (elementText === '3230') { - console.log('Passed: Biology Unique Titles: 3230 count text matched as expected'); + if (elementText === biologyUniqueTitles) { + console.log(`Passed: Biology Unique Titles: ${biologyUniqueTitles} count text matched as expected`); } else { - errors.push(`Expected: Biology Unique Titles: "3230"; Actual: "${elementText}"`); + errors.push(`Expected: Biology Unique Titles: "${biologyUniqueTitles}"; Actual: "${elementText}"`); } //font-family if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Biology Unique Titles: 3230 count text font matched as expected'); + console.log('Passed: Biology Unique Titles: Count text font matched as expected'); } else { - errors.push(`Expected: Biology Unique Titles: 3230 count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); + errors.push(`Expected: Biology Unique Titles: Count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); } //font size if (elementTextSize === '36px') { - console.log('Passed: Biology Unique Titles: 3230 count text ont-size matched as expected'); + console.log('Passed: Biology Unique Titles: Count text font-size matched as expected'); } else { - errors.push(`Expected: Biology Unique Titles: 3230 count text font-size "36px"; Actual: "${elementTextSize}"`); + errors.push(`Expected: Biology Unique Titles: Count text font-size "36px"; Actual: "${elementTextSize}"`); } //color if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Biology Unique Titles: 3230 count text color matched as expected'); + console.log('Passed: Biology Unique Titles: Count text color matched as expected'); } else { - errors.push(`Expected: Biology Unique Titles: 3230 count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); + errors.push(`Expected: Biology Unique Titles: Count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); } //Throw summary if any validation failed @@ -3917,9 +2382,10 @@ const steps = [ //Biology Unique Titles (SPECIAL CASE: css path with trimmed text) { - description: 'Validate Biology DIV - Unique Titles', + description: 'Biology DIV - Unique Titles', action: async () => { const multipleChecks = 'Biology DIV Unique Titles'; + const element = await driver.findElement(By.css('#total_titles')); //Extract the bare text node (everything that's not a tag) @@ -3984,9 +2450,10 @@ const steps = [ //Biology Unique IDs count 3264 { - description: 'Validate Biology DIV - Unique IDs count', + description: 'Biology DIV - Unique IDs count', action: async () => { const multipleChecks = 'Biology DIV Unique IDs count'; + const element = await driver.findElement(By.css('#total_pubtotalids > b')); //Get text, font, size, and color @@ -3999,31 +2466,31 @@ const steps = [ const errors = []; //text - if (elementText === '3264') { - console.log('Passed: Biology Unique IDs: 3264 count text matched as expected'); + if (elementText === biologyUniqueIds) { + console.log(`Passed: Biology Unique IDs: ${biologyUniqueIds} count text matched as expected`); } else { - errors.push(`Expected: Biology Unique IDs: "3264"; Actual: "${elementText}"`); + errors.push(`Expected: Biology Unique IDs: "${biologyUniqueIds}"; Actual: "${elementText}"`); } //font-family if (elementTextFont === "Poppins, sans-serif") { - console.log('Passed: Biology Unique IDs: 3264 count text font matched as expected'); + console.log('Passed: Biology Unique IDs: Count text font matched as expected'); } else { - errors.push(`Expected: Biology Unique IDs: 3264 count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); + errors.push(`Expected: Biology Unique IDs: Count text font "Poppins, sans-serif"; Actual: ${elementTextFont}`); } //font size if (elementTextSize === '36px') { - console.log('Passed: Biology Unique IDs: 3264 count text ont-size matched as expected'); + console.log('Passed: Biology Unique IDs: Count text font-size matched as expected'); } else { - errors.push(`Expected: Biology Unique IDs: 3264 count text font-size "36px"; Actual: "${elementTextSize}"`); + errors.push(`Expected: Biology Unique IDs: Count text font-size "36px"; Actual: "${elementTextSize}"`); } //color if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Biology Unique IDs: 3264 count text color matched as expected'); + console.log('Passed: Biology Unique IDs: Count text color matched as expected'); } else { - errors.push(`Expected: Biology Unique IDs: 3264 count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); + errors.push(`Expected: Biology Unique IDs: Count text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); } //Throw summary if any validation failed @@ -4041,9 +2508,10 @@ const steps = [ //Biology Unique IDs (SPECIAL CASE: css path with trimmed text) { - description: 'Validate Biology DIV - Unique IDs', + description: 'Biology DIV - Unique IDs', action: async () => { const multipleChecks = 'Biology DIV Unique IDs'; + const element = await driver.findElement(By.css('#total_pubtotalids')); //Extract the bare text node (everything that's not a tag) @@ -4108,9 +2576,10 @@ const steps = [ //Close button { - description: 'Validate Close button', + description: 'Close button', action: async () => { const multipleChecks = 'Close button'; + const element = await driver.findElement(By.css('#all_content_modal .btn-secondary')); //Get text, font, color, and size @@ -4173,9 +2642,10 @@ const steps = [ //Export button { - description: 'Validate Export button', + description: 'Export button', action: async () => { const multipleChecks = 'Export button'; + const element = await driver.findElement(By.css('#export_btn')); //Get text, font, color, and size @@ -4269,9 +2739,10 @@ const steps = [ //Create Content Set { - description: 'Validate Add Create Content Set', + description: 'Add Create Content Set', action: async () => { const multipleChecks = 'Add Create Content Set'; + const elementIcon = await driver.findElement(By.css('.fa-plus')).getCssValue('color'); const element = await driver.findElement(By.linkText('Create Content Set')); @@ -4280,7 +2751,6 @@ const steps = [ const elementFont = await element.getCssValue('font-family'); const elementSize = await element.getCssValue('font-size'); const elementTextColor = await element.getCssValue('color'); - const elementColor = await element.getCssValue('background-color'); //Track all errors const errors = []; @@ -4335,9 +2805,10 @@ const steps = [ //Export Content Set { - description: 'Validate Export Content Set', + description: 'Export Content Set', action: async () => { const multipleChecks = 'Export Content Set'; + const elementIcon = await driver.findElement(By.css('.fa-download')).getCssValue('color'); const element = await driver.findElement(By.linkText('Export Content Set')); @@ -4346,7 +2817,6 @@ const steps = [ const elementFont = await element.getCssValue('font-family'); const elementSize = await element.getCssValue('font-size'); const elementTextColor = await element.getCssValue('color'); - const elementColor = await element.getCssValue('background-color'); //Track all errors const errors = []; @@ -4405,8 +2875,14 @@ const steps = [ action: async () => { await driver.findElement(By.linkText('Create Content Set')).click(); console.log('----->| NEXT ACTION: Clicked Create Content Set link'); - await driver.sleep(5000); //INCONSISTENT ATTEMPTING TO READ DIV TITLE - + + //Wait for the dashboard container to exist in DOM + await driver.wait( + until.elementLocated(By.css('.modal-lg .modal-title')), + 30000, + 'DIV did not appear within 30 seconds' + ); + //Wait until the modal title is located AND visible await driver.wait(async () => { try { @@ -4415,7 +2891,7 @@ const steps = [ } catch (e) { return false; //Element not ready yet, keep waiting } - }, 30000, 'Modal did not become visible within 30 seconds'); + }, 30000, 'DIV did not become visible within 30 seconds'); console.log('Passed: DIV loaded successfully'); } @@ -4423,9 +2899,10 @@ const steps = [ //Create Content Set DIV - title { - description: 'Validate Create Content Set DIV title', + description: 'Create Content Set DIV title', action: async () => { const multipleChecks = 'Create Content Set DIV title'; + const element = await driver.findElement(By.css('.modal-lg .modal-title')); //Get text, font, size, and color @@ -4480,9 +2957,10 @@ const steps = [ //Content Set Name label { - description: 'Validate Content Set Name label', + description: 'Content Set Name label', action: async () => { const multipleChecks = 'Content Set Name label'; + const element = await driver.findElement(By.css('.form-row:nth-child(2) .form-label')); //Get text, font, size, and color @@ -4537,9 +3015,10 @@ const steps = [ //Create button { - description: 'Validate Create button', + description: 'Create button', action: async () => { const multipleChecks = 'Create button'; + const element = await driver.findElement(By.css('.modal-lg #modalop')); //Get text, font, color, and size @@ -4602,9 +3081,10 @@ const steps = [ //Close button { - description: 'Validate Close button', + description: 'Close button', action: async () => { const multipleChecks = 'Close button'; + const element = await driver.findElement(By.css('#modalclose')); //text, font, size, and color @@ -4683,14 +3163,16 @@ const steps = [ until.elementIsVisible(elementVisible), 20000 ); + await driver.sleep(2000); } }, //Validation { - description: 'Validate empty Content Set name validation message', + description: 'Empty Content Set name validation message', action: async () => { const multipleChecks = 'Empty Content Set Name validation'; + const element = await driver.findElement(By.css('#metawarn > b')); //Get text, font, size, and color @@ -4745,10 +3227,11 @@ const steps = [ //NEXT ACTION { - description: 'Click Create button', + description: 'Enter organization name and click Create button', action: async () => { await driver.findElement(By.css('#orgname')).sendKeys('Biology'); console.log('----->| NEXT ACTION: Entered duplicate Content Set name'); + await driver.sleep(2000); await driver.findElement(By.css('.modal-lg #modalop')).click(); console.log('----->| NEXT ACTION: Clicked Create button'); @@ -4764,14 +3247,16 @@ const steps = [ until.elementIsVisible(elementVisible), 20000 ); + await driver.sleep(2000); } }, //Validation { - description: 'Validate duplicate Content Set name validation message', + description: 'Duplicate Content Set name validation message', action: async () => { const multipleChecks = 'Duplicate Content Set Name validation'; + const element = await driver.findElement(By.css('#namewarn')); //Get text, font, size, and color @@ -4826,14 +3311,20 @@ const steps = [ //NEXT ACTION { - description: 'Click Create button', + description: 'Click Create New Content Set', action: async () => { - await driver.findElement(By.css('.form-row:nth-child(2) #orgname')).clear(); - console.log('----->| NEXT ACTION: Cleared Content Set name'); - await driver.sleep(2000); + const elementInput = await driver.wait(until.elementLocated(By.css('.form-row:nth-child(2) #orgname')), 5000); - await driver.findElement(By.css('.form-row:nth-child(2) #orgname')).sendKeys(createContentSetName); - console.log('----->| NEXT ACTION: Entered new Content Set name'); + await elementInput.clear(); + console.log('----->| NEXT ACTION: Cleared Content Set name'); + + //Type the deleted Content Set name to filter for it specifically + for (const char of createContentSetName) { + await elementInput.sendKeys(char); + await driver.executeScript(`$(document.querySelector('.form-row:nth-child(2) #orgname')).trigger('keyup');`); + await driver.sleep(100); + } + console.log('----->| NEXT ACTION: Entered new Content Set name'); await driver.findElement(By.css('.modal-lg #modalop')).click(); console.log('----->| NEXT ACTION: Clicked Create button'); @@ -4849,14 +3340,16 @@ const steps = [ }, 20000, 'Modal did not become visible within 20 seconds'); console.log('Passed: DIV loaded successfully'); + await driver.sleep(2000); } }, //Alert banner { - description: 'Validate alert banner', + description: 'Alert banner', action: async () => { const multipleChecks = 'Alert banner'; + const element = await driver.findElement(By.css('strong')); const elementBanner = await driver.findElement(By.css('#statalert')); @@ -4939,9 +3432,10 @@ const steps = [ //My Content - Biology { - description: 'Validate Biology link', + description: 'Biology link', action: async () => { const multipleChecks = 'My Content - Biology link'; + const element = await driver.findElement(By.linkText('Biology')); //Get href, text, font, size, and color @@ -5004,9 +3498,10 @@ const steps = [ //My Content - Edit Biology icon { - description: 'Validate Edit Biology icon', + description: 'Edit Biology icon', action: async () => { const multipleChecks = 'My Content - Edit Biology icon'; + const element = await driver.findElement(By.css('#content-org-list > li > div.orgname > a.ml-2')); //Get href, text, font, size, and color @@ -5053,35 +3548,137 @@ const steps = [ //My Content - Newly created content { - description: 'Validate Newly created Content Set sort order', + description: 'Newly created Content Set sort order', action: async () => { const multipleChecks = `${createContentSetName} sort order`; - const elementContent = await driver.findElement(By.linkText(`${createContentSetName}`)).getText(); - const elementEditIcon = await driver.findElement(By.xpath('//ul/ul/ul/ul/ul/ul/ul/ul/ul/ul/ul/ul/ul/li/div[2]/a[2]/i')); - const elementCount = await driver.findElement(By.xpath('//ul/ul/ul/ul/ul/ul/ul/ul/ul/ul/ul/ul/ul/li/div/span')).getText(); + + const element = await driver.findElement(By.linkText(`${createContentSetName}`)); + //Get href, text, font, size, and color + const elementURL = await element.getAttribute('href'); + const elementText = await element.getText(); + const elementFont = await element.getCssValue('font-family'); + const elementSize = await element.getCssValue('font-size'); + const elementColor = await element.getCssValue('color'); + + //Edit icon = the sibling right after the Content Set link (NOT the inner , which has no href/title) + const elementEditIcon = await element.findElement(By.xpath('./following-sibling::a[@title="Edit Content Set" or contains(@href, "contentset_edit_modal.php")]')); + //Get href, title, and color + const elementEditIconURL = await elementEditIcon.getAttribute('href'); + const elementEditIconTitle = await elementEditIcon.getAttribute('title'); + const elementEditIconColor = await elementEditIcon.getCssValue('color'); + + //Count = badge in the same
  • as the Content Set link (no hardcoded nesting depth) + const elementCount = await element.findElement(By.xpath('./ancestor::li[1]/div/span')); + //Get text, font, size, and color + const elementCountText = await elementCount.getText(); + const elementCountFont = await elementCount.getCssValue('font-family'); + const elementCountSize = await elementCount.getCssValue('font-size'); + const elementCountColor = await elementCount.getCssValue('color'); + + //All Content Set names in list order (to confirm the new one is last) + const listNames = await driver.executeScript(` + return Array.from(document.querySelectorAll('ul#content-org-list > li > div.orgname > a:first-child')) + .map(a => a.textContent.trim()); + `); + const expectedPosition = myContentSets.length + 1; //Track all errors const errors = []; - //text - if (elementContent === `${createContentSetName}`) { - console.log(`Passed: ${createContentSetName} listed in last place as expected`); + //New Content Set ID is generated on create, so read it from the link and reuse it for the edit icon check + const idMatch = (elementURL || '').match(/^https:\/\/correlation\.edgate\.com\/exact\/\?iPublisherId=(\d+)&function=listUnits$/); + const newContentSetId = idMatch ? idMatch[1] : null; + + //url + if (newContentSetId) { + console.log(`Passed: Newly created Content Set link URL matched as expected, ID ${newContentSetId}`); } else { - errors.push(`Expected: Last place: "${createContentSetName}" ; Actual: "${elementContent}"`); + errors.push(`Expected: Element URL link format: "https://correlation.edgate.com/exact/?iPublisherId=&function=listUnits"; Actual: "${elementURL}"`); } - //icon present - if (elementEditIcon) { - console.log(`Passed: ${createContentSetName} edit icon listed in last place as expected`); + //text + if (elementText === createContentSetName) { + console.log(`Passed: ${createContentSetName} link text matched as expected`); } else { - errors.push(`Expected: ${createContentSetName} edit icon not found in last place`); + errors.push(`Expected: "${createContentSetName}" ; Actual: "${elementText}"`); + } + + //sort order - last place + if (listNames.length === expectedPosition && listNames[listNames.length - 1] === createContentSetName) { + console.log(`Passed: ${createContentSetName} listed in last place, position ${expectedPosition} as expected`); + } else { + errors.push(`Expected: Last place (position ${expectedPosition}): "${createContentSetName}"; Actual: position ${listNames.indexOf(createContentSetName) + 1} of ${listNames.length}, last item "${listNames[listNames.length - 1]}"`); + } + + //font-family + if (elementFont === "Poppins, sans-serif") { + console.log('Passed: Newly created Content Set link text font matched as expected'); + } else { + errors.push(`Expected: Newly created Content Set link text font "Poppins, sans-serif"; Actual: ${elementFont}`); + } + + //font size + if (elementSize === '14.3px') { + console.log('Passed: Newly created Content Set link text font-size matched as expected'); + } else { + errors.push(`Expected: Newly created Content Set link text font-size "14.3px"; Actual: "${elementSize}"`); + } + + //color + if (elementColor === 'rgba(73, 80, 87, 1)') { + console.log('Passed: Newly created Content Set link text color matched as expected'); + } else { + errors.push(`Expected: Newly created Content Set link text color: "rgba(73, 80, 87, 1)"; Actual: "${elementColor}"`); + } + + //icon title + if (elementEditIconTitle === 'Edit Content Set') { + console.log('Passed: Newly created Content Set edit icon title matched as expected'); + } else { + errors.push(`Expected: Newly created Content Set edit icon title "Edit Content Set"; Actual: "${elementEditIconTitle}"`); + } + + //icon url - must use the same ID as the Content Set link + const expectedEditIconURL = `https://correlation.edgate.com/exact/contentset_edit_modal.php?id=${newContentSetId}`; + if (newContentSetId && elementEditIconURL === expectedEditIconURL) { + console.log(`Passed: Newly created Content Set edit icon URL matched as expected, ID ${newContentSetId}`); + } else { + errors.push(`Expected: Edit icon URL: "${expectedEditIconURL}"; Actual: "${elementEditIconURL}"`); + } + + //icon color + if (elementEditIconColor === 'rgba(73, 80, 87, 1)') { + console.log('Passed: Newly created Content Set edit icon color matched as expected'); + } else { + errors.push(`Expected: Newly created Content Set edit icon color: "rgba(73, 80, 87, 1)"; Actual: "${elementEditIconColor}"`); } //count - if (elementCount === '0') { + if (elementCountText === '0') { console.log(`Passed: ${createContentSetName} content count listed in last place as expected`); } else { - errors.push(`Expected: Last place: ${createContentSetName} content count: "0"; Actual: "${elementCount}"`); + errors.push(`Expected: Last place: ${createContentSetName} content count: "0"; Actual: "${elementCountText}"`); + } + + //count font-family + if (elementCountFont === "Poppins, sans-serif") { + console.log('Passed: Newly created Content Set content count font matched as expected'); + } else { + errors.push(`Expected: Newly created Content Set content count font "Poppins, sans-serif"; Actual: ${elementCountFont}`); + } + + //count font size + if (elementCountSize === '12.87px') { + console.log('Passed: Newly created Content Set content count font-size matched as expected'); + } else { + errors.push(`Expected: Newly created Content Set content count font-size "12.87px"; Actual: "${elementCountSize}"`); + } + + //count color + if (elementCountColor === 'rgba(40, 39, 90, 1)') { + console.log('Passed: Newly created Content Set content count color matched as expected'); + } else { + errors.push(`Expected: Newly created Content Set content count color: "rgba(40, 39, 90, 1)"; Actual: "${elementCountColor}"`); } //Throw summary if any validation failed @@ -5120,9 +3717,10 @@ const steps = [ //Filter Results label { - description: 'Validate Filter Results label', + description: 'Filter Results label', action: async () => { const multipleChecks = 'Filter Results label'; + const element = await driver.findElement(By.css('.well > b')); //Get text, font, size, and color @@ -5177,9 +3775,10 @@ const steps = [ //Grade label { - description: 'Validate Grade label', + description: 'Grade label', action: async () => { const multipleChecks = 'Grade label'; + const element = await driver.findElement(By.css('.form-group:nth-child(1) > b')); //Get text, font, size, and color @@ -5234,9 +3833,10 @@ const steps = [ //Subject label { - description: 'Validate Subject label', + description: 'Subject label', action: async () => { const multipleChecks = 'Subject label'; + const element = await driver.findElement(By.css('.form-group:nth-child(3) > b')); //Get text, font, size, and color @@ -5291,9 +3891,10 @@ const steps = [ //Reset All link { - description: 'Validate Reset All link', + description: 'Reset All link', action: async () => { const multipleChecks = 'Reset All link'; + const element = await driver.findElement(By.linkText('Reset All')); //Get text, font, size, and color @@ -5348,9 +3949,10 @@ const steps = [ //Home link { - description: 'Validate Home link', + description: 'Home link', action: async () => { const multipleChecks = 'Home link'; + const element = await driver.findElement(By.linkText('Home')); //Get text, font, size, and color @@ -5405,9 +4007,10 @@ const steps = [ //Content link { - description: 'Validate Content link', + description: 'Content link', action: async () => { const multipleChecks = 'Content link'; + const element = await driver.findElement(By.css('.breadcrumb-item:nth-child(2)')); //Get text, font, size, and color @@ -5462,9 +4065,10 @@ const steps = [ //Results text { - description: 'Validate Results text', + description: 'Results text', action: async () => { - const multipleChecks = 'Reset All link'; + const multipleChecks = 'Results text'; + const element = await driver.findElement(By.css('b:nth-child(2)')); //Get text, font, size, and color @@ -5550,14 +4154,28 @@ const steps = [ description: 'Click My Content ellipsis icon', action: async () => { await driver.findElement(By.css('.fa-ellipsis-h')).click(); - await driver.sleep(2000); + + //Wait until the element exists in the DOM + const elementVisible = await driver.wait( + until.elementLocated(By.css('.fa-plus')), + 20000 + ); + await driver.sleep(1000); + + //Wait until it becomes visible + await driver.wait( + until.elementIsVisible(elementVisible), + 20000 + ); + await driver.sleep(1000); + await driver.findElement(By.linkText('Export Content Set')).click(); console.log('----->| NEXT ACTION: Clicked My Content ellipsis icon and Export Content Set link'); //Wait until the modal title is located AND visible await driver.wait(async () => { try { - const element = await driver.findElement(By.css('.modal-lg .modal-title')); + const element = await driver.findElement(By.css('.modal-header:nth-child(5) > .modal-title')); return await element.isDisplayed(); } catch (e) { return false; //Element not ready yet, keep waiting @@ -5570,10 +4188,11 @@ const steps = [ //Export Content DIV { - description: 'Validate Export Content DIV', + description: 'Export Content DIV', action: async () => { const multipleChecks = 'Export Content DIV'; - const element = await driver.findElement(By.css('.modal-header:nth-child(4) > .modal-title'));//.modal-lg .modal-title')); + + const element = await driver.findElement(By.css('.modal-header:nth-child(5) > .modal-title')); //Get text, font, size, and color const elementText = await element.getText(''); @@ -5606,10 +4225,10 @@ const steps = [ } //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { + if (elementTextColor === 'rgba(48, 48, 96, 1)') { console.log('Passed: Export Content DIV title color matched as expected'); } else { - errors.push(`Expected: Export Content DIV title color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); + errors.push(`Expected: Export Content DIV title color: "rgba(48, 48, 96, 1)"; Actual: "${elementTextColor}"`); } //Throw summary if any validation failed @@ -5627,9 +4246,10 @@ const steps = [ //Export Content DIV label { - description: 'Validate Export Content label', + description: 'Export Content label', action: async () => { const multipleChecks = 'Export Content label'; + const element = await driver.findElement(By.css('#content-export-container > h5')); //Get text, font, size, and color @@ -5684,9 +4304,10 @@ const steps = [ //Content Set label { - description: 'Validate Content Set label', + description: 'Content Set label', action: async () => { const multipleChecks = 'Content Set label'; + const element = await driver.findElement(By.css('#content_export .form-label')); //Get text, font, size, and color @@ -5713,17 +4334,17 @@ const steps = [ } //font size - if (elementTextSize === '13px') { + if (elementTextSize === '15px') { console.log('Passed: Content Set label font-size matched as expected'); } else { - errors.push(`Expected: Content Set label font-size "13px"; Actual: "${elementTextSize}"`); + errors.push(`Expected: Content Set label font-size "15px"; Actual: "${elementTextSize}"`); } //color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { + if (elementTextColor === 'rgba(48, 48, 96, 1)') { console.log('Passed: Content Set label color matched as expected'); } else { - errors.push(`Expected: Content Set label color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); + errors.push(`Expected: Content Set label color: "rgba(48, 48, 96, 1)"; Actual: "${elementTextColor}"`); } //Throw summary if any validation failed @@ -5739,9 +4360,254 @@ const steps = [ } }, + //Content Set dropdown value + { + description: 'Content Set dropdown value', + action: async () => { + const multipleChecks = 'Content Set dropdown value'; + + const element = await driver.findElement(By.css('.form-group:nth-child(1) .multiselect-selected-text')); + + //Get text, font, size, and color + const elementText = await element.getText(''); + const elementTextFont = await element.getCssValue('font-family'); + const elementTextSize = await element.getCssValue('font-size'); + const elementTextColor = await element.getCssValue('color'); + const elementTitle = await driver.findElement(By.css('.form-group:nth-child(1) .multiselect')).getAttribute('title'); + + //Track all errors + const errors = []; + + //text + if (elementText === 'Please select a Content Set') { + console.log('Passed: Content Set dropdown value matched as expected'); + } else { + errors.push(`Expected: "Please select a Content Set"; Actual: "${elementText}"`); + } + + //font-family + if (elementTextFont === "Poppins, sans-serif") { + console.log('Passed: Content Set dropdown value font matched as expected'); + } else { + errors.push(`Expected: Content Set dropdown value font "Poppins, sans-serif"; Actual: ${elementTextFont}`); + } + + //font size + if (elementTextSize === '16px') { + console.log('Passed: Content Set dropdown value font-size matched as expected'); + } else { + errors.push(`Expected: Content Set dropdown value font-size "16px"; Actual: "${elementTextSize}"`); + } + + //color + if (elementTextColor === 'rgba(40, 39, 90, 1)') { + console.log('Passed: Content Set dropdown value color matched as expected'); + } else { + errors.push(`Expected: Content Set dropdown value color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); + } + + //title + if (elementTitle === 'Please select a Content Set') { + console.log('Passed: Content Set dropdown value title matched as expected'); + } else { + errors.push(`Expected: Content Set dropdown value title: "Please select a Content Set"; Actual: "${elementTitle}"`); + } + + //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')); + } + } + }, + + //Export button + { + description: 'Export button', + action: async () => { + const multipleChecks = 'Export button'; + + const element = await driver.findElement(By.css('#exportButton')); + + //Get text, font, color, and size + const elementText = await element.getText(''); + const elementFont = await element.getCssValue('font-family'); + const elementSize = await element.getCssValue('font-size'); + const elementTextColor = await element.getCssValue('color'); + const elementColor = await element.getCssValue('background-color'); + + //Track all errors + const errors = []; + + //text + if (elementText === 'Export') { + console.log('Passed: Export button text matched as expected'); + } else { + errors.push(`Expected: "Export"; Actual: "${elementText}"`); + } + + //font-family + if (elementFont === "Poppins, sans-serif") { + console.log('Passed: Export button text font matched as expected'); + } else { + errors.push(`Expected: Export button text font "Poppins, sans-serif"; Actual: ${elementFont}`); + } + + //font size + if (elementSize === '15px') { + console.log('Passed: Export button text font-size matched as expected'); + } else { + errors.push(`Expected: Export button text font-size "15px"; Actual: "${elementSize}"`); + } + + //text color + if (elementTextColor === 'rgba(255, 255, 255, 1)') { + console.log('Passed: Export button text color matched as expected'); + } else { + errors.push(`Expected: Export button text color: "rgba(255, 255, 255, 1)"; Actual: "${elementTextColor}"`); + } + + //color + if (elementColor === 'rgba(48, 200, 172, 1)') { + console.log('Passed: Export button background color matched as expected'); + } else { + errors.push(`Expected: Export button background color: "rgba(48, 200, 172, 1)"; Actual: "${elementColor}"`); + } + + //Throw summary if any validation failed + if (errors.length > 0) { + //Add summary line only when multiple checks failed + if (errors.length > 1) { + errors.unshift(`${multipleChecks} - Multiple validation checks did not pass`); + } + + //Throw collected messages — catch() will prefix with "FAILED:" + throw new Error(errors.join('\n')); + } + } + }, + + //Close button + { + description: 'Close button', + action: async () => { + const multipleChecks = 'Close button'; + + const element = await driver.findElement(By.css('.btn:nth-child(3)')); + + //Get text, font, color, and size + const elementText = await element.getText(''); + const elementFont = await element.getCssValue('font-family'); + const elementSize = await element.getCssValue('font-size'); + const elementTextColor = await element.getCssValue('color'); + const elementColor = await element.getCssValue('background-color'); + + //Track all errors + const errors = []; + + //text + if (elementText === 'Close') { + console.log('Passed: Close button text matched as expected'); + } else { + errors.push(`Expected: "Close"; Actual: "${elementText}"`); + } + + //font-family + if (elementFont === "Poppins, sans-serif") { + console.log('Passed: Close button text font matched as expected'); + } else { + errors.push(`Expected: Close button text font "Poppins, sans-serif"; Actual: ${elementFont}`); + } + + //font size + if (elementSize === '15px') { + console.log('Passed: Close button text font-size matched as expected'); + } else { + errors.push(`Expected: Close button text font-size "15px"; Actual: "${elementSize}"`); + } + + //text color + if (elementTextColor === 'rgba(40, 39, 90, 1)') { + console.log('Passed: Close button text color matched as expected'); + } else { + errors.push(`Expected: Close button text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); + } + + //color + if (elementColor === 'rgba(0, 0, 0, 0)') { + console.log('Passed: Close button background color matched as expected'); + } else { + errors.push(`Expected: Close button background color: "rgba(0, 0, 0, 0)"; Actual: "${elementColor}"`); + } + + //Throw summary if any validation failed + if (errors.length > 0) { + //Add summary line only when multiple checks failed + if (errors.length > 1) { + errors.unshift(`${multipleChecks} - Multiple validation checks did not pass`); + } + + //Throw collected messages — catch() will prefix with "FAILED:" + throw new Error(errors.join('\n')); + } + } + }, + + //NEXT ACTION + { + description: 'Export DIV alert message', + action: async () => { + const multipleChecks = 'Export DIV alert'; + + const errors = []; + + //Wait for modal to be ready + await driver.wait(until.elementLocated(By.css('.modal-header:nth-child(5) > .modal-title')), 5000); + + //Click export button + await driver.wait(until.elementLocated(By.css('#exportButton')), 5000).click(); + await driver.sleep(2500); + console.log('----->| NEXT ACTION: Clicked Export button'); + + //Wait for confirm dialog to appear + const alert = await driver.wait(until.alertIsPresent(), 5000); + console.log('----->| NEXT ACTION: Alert dialog appeared'); + + //Get alert text + const alertText = await alert.getText(); + + //Validate alert message text + const expectedText = 'Please select at least one Content Set.'; + if (alertText === expectedText) { + console.log('Passed: Export alert message text matched as expected'); + } else { + errors.push(`Expected: "${expectedText}"; Actual: "${alertText}"`); + } + + //Throw summary before dismissing if errors found + if (errors.length > 0) { + await alert.dismiss(); //Cancel the export if validation failed + if (errors.length > 1) { + errors.unshift(`${multipleChecks} - Multiple validation checks did not pass`); + } + throw new Error(errors.join('\n')); + } + + //Accept the alert (click OK) to proceed with export + await alert.accept(); + console.log('----->| NEXT ACTION: Clicked OK on alert DIV'); + await driver.sleep(2000); + } + }, + //Export - Search textbox placeholder { - description: 'Validate Export Search placeholder text', + description: 'Export Search placeholder text', action: async () => { const multipleChecks = 'Export Search textbox'; @@ -5798,10 +4664,10 @@ const steps = [ } //font size - if (elementSize === '10.8px') { + if (elementSize === '13.5px') { console.log('Passed: Search placeholder text font-size matched as expected'); } else { - errors.push(`Expected: Search placeholder text font-size "10.8px"; Actual: "${elementSize}"`); + errors.push(`Expected: Search placeholder text font-size "13.5px"; Actual: "${elementSize}"`); } //color @@ -5812,10 +4678,10 @@ const steps = [ } //Clear icon color - if (elementClearIcon === 'rgba(33, 37, 41, 1)') { + if (elementClearIcon === 'rgba(255, 59, 48, 1)') { console.log('Passed: Search clear icon color matched as expected'); } else { - errors.push(`Expected: Search clear icon color: "rgba(33, 37, 41, 1)"; Actual: "${elementClearIcon}"`); + errors.push(`Expected: Search clear icon color: "rgba(255, 59, 48, 1)"; Actual: "${elementClearIcon}"`); } //Throw summary if any validation failed @@ -5830,20 +4696,13 @@ const steps = [ //Sort dropdown values (SPECIAL CASE: multi-selection) { - description: 'Validate Export multiselect dropdown list', + description: 'Export multiselect dropdown list', action: async () => { const multipleChecks = 'Export multiselect dropdown list'; //Track all errors// const errors = []; - /* await driver.sleep(2000); - - //If the select has a unique id or name - await driver.executeScript(` - document.querySelector('button.multiselect[title="Please select a Content Set"]').click(); - `); */ - //Target the correct dropdown directly by its unique id const dropdown = await driver.wait(until.elementLocated(By.css('#selectOrg')), 5000); const selectElement = new Select(dropdown); @@ -5865,7 +4724,18 @@ const steps = [ 'Import Align - Direct Align 2', 'Math Alignment Import Test', 'create me', - 'Automated Algebra Content Set - TO BE DELETED' + 'Illustrative Math Test 1', + 'Illustrative Math Test 2', + 'Khan URL test', + 'seesaw test', + 'ECS-3037 On Prod TC2', + 'ECS-3037 On Prod TC1', + 'webinar test', + 'Review Screen Open', + 'New One For Agust Post Night', + 'Automated Algebra Content Set - TO BE DELETED', + 'Post NIght July26', + 'create import test' ]; const actual = []; @@ -5898,148 +4768,28 @@ const steps = [ } }, - //Export button - { - description: 'Validate Export button', - action: async () => { - const multipleChecks = 'Export button'; - const element = await driver.findElement(By.css('.modal-footer:nth-child(6) > .btn-primary')); - - //Get text, font, color, and size - const elementText = await element.getAttribute('value'); - const elementFont = await element.getCssValue('font-family'); - const elementSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - const elementColor = await element.getCssValue('background-color'); - - //Track all errors - const errors = []; - - //text - if (elementText === 'Export') { - console.log('Passed: Export button text matched as expected'); - } else { - errors.push(`Expected: "Export"; Actual: "${elementText}"`); - } - - //font-family - if (elementFont === "Poppins, sans-serif") { - console.log('Passed: Export button text font matched as expected'); - } else { - errors.push(`Expected: Export button text font "Poppins, sans-serif"; Actual: ${elementFont}`); - } - - //font size - if (elementSize === '16px') { - console.log('Passed: Export button text font-size matched as expected'); - } else { - errors.push(`Expected: Export button text font-size "16px"; Actual: "${elementSize}"`); - } - - //text color - if (elementTextColor === 'rgba(255, 255, 255, 1)') { - console.log('Passed: Export button text color matched as expected'); - } else { - errors.push(`Expected: Export button text color: "rgba(255, 255, 255, 1)"; Actual: "${elementTextColor}"`); - } - - //color - if (elementColor === 'rgba(48, 200, 172, 1)') { - console.log('Passed: Export button background color matched as expected'); - } else { - errors.push(`Expected: Export button background color: "rgba(48, 200, 172, 1)"; Actual: "${elementColor}"`); - } - - //Throw summary if any validation failed - if (errors.length > 0) { - //Add summary line only when multiple checks failed - if (errors.length > 1) { - errors.unshift(`${multipleChecks} - Multiple validation checks did not pass`); - } - - //Throw collected messages — catch() will prefix with "FAILED:" - throw new Error(errors.join('\n')); - } - } - }, - - //Close button - { - description: 'Validate Close button', - action: async () => { - const multipleChecks = 'Close button'; - const element = await driver.findElement(By.css('.btn:nth-child(3)')); - - //Get text, font, color, and size - const elementText = await element.getText(''); - const elementFont = await element.getCssValue('font-family'); - const elementSize = await element.getCssValue('font-size'); - const elementTextColor = await element.getCssValue('color'); - const elementColor = await element.getCssValue('background-color'); - - //Track all errors - const errors = []; - - //text - if (elementText === 'Close') { - console.log('Passed: Close button text matched as expected'); - } else { - errors.push(`Expected: "Close"; Actual: "${elementText}"`); - } - - //font-family - if (elementFont === "Poppins, sans-serif") { - console.log('Passed: Close button text font matched as expected'); - } else { - errors.push(`Expected: Close button text font "Poppins, sans-serif"; Actual: ${elementFont}`); - } - - //font size - if (elementSize === '16px') { - console.log('Passed: Close button text font-size matched as expected'); - } else { - errors.push(`Expected: Close button text font-size "16px"; Actual: "${elementSize}"`); - } - - //text color - if (elementTextColor === 'rgba(40, 39, 90, 1)') { - console.log('Passed: Close button text color matched as expected'); - } else { - errors.push(`Expected: Close button text color: "rgba(40, 39, 90, 1)"; Actual: "${elementTextColor}"`); - } - - //color - if (elementColor === 'rgba(0, 0, 0, 0)') { - console.log('Passed: Close button background color matched as expected'); - } else { - errors.push(`Expected: Close button background color: "rgba(0, 0, 0, 0)"; Actual: "${elementColor}"`); - } - - //Throw summary if any validation failed - if (errors.length > 0) { - //Add summary line only when multiple checks failed - if (errors.length > 1) { - errors.unshift(`${multipleChecks} - Multiple validation checks did not pass`); - } - - //Throw collected messages — catch() will prefix with "FAILED:" - throw new Error(errors.join('\n')); - } - } - }, - //NEXT ACTION { description: 'Click filter Content Set list and select newly created Content Set', action: async () => { - await driver.findElement(By.css('.show > .multiselect-item .form-control')).sendKeys('Auto'); - console.log('----->| NEXT ACTION: Entered search term - Auto'); + const elementInput = await driver.wait(until.elementLocated(By.css('.show > .multiselect-item .form-control')), 5000); - await driver.findElement(By.css('.show > li:nth-child(15) input')).click(); + for (const char of 'Auto') { + await elementInput.sendKeys(char); + await driver.executeScript(`$(document.querySelector('.show > .multiselect-item .form-control')).trigger('keyup');`); + await driver.sleep(100); + } + console.log('----->| NEXT ACTION: Entered search term - Auto'); + + await driver.findElement(By.css('li:nth-child(24) input')).click(); console.log(`----->| NEXT ACTION: Clicked checkbox for: ${createContentSetName}`); await driver.sleep(2000); - await driver.findElement(By.css('.modal-footer:nth-child(6) > .btn-primary')).click(); + await driver.findElement(By.css('.modal-header:nth-child(5)')).click(); + console.log('----->| NEXT ACTION: Clicked modal to close dropdown list'); + await driver.sleep(2000); + + await driver.findElement(By.css('#exportButton')).click(); console.log('----->| NEXT ACTION: Clicked Export button'); //Wait until the modal title is located AND visible @@ -6058,9 +4808,10 @@ const steps = [ //Export page { - description: 'Validate Export page title', + description: 'Export page title', action: async () => { const multipleChecks = 'Export page title'; + const element = await driver.findElement(By.css('h2')); //Get text, font, size, and color @@ -6115,9 +4866,10 @@ const steps = [ //Export page label { - description: 'Validate Export page label', + description: 'Export page label', action: async () => { const multipleChecks = 'Export page label'; + const element = await driver.findElement(By.css('body > div.container.body > div > div.right_col > div > b')); //Get text, font, size, and color @@ -6172,9 +4924,10 @@ const steps = [ //Download Export button { - description: 'Validate Download Export button', + description: 'Download Export button', action: async () => { const multipleChecks = 'Download Export button'; + const elementIcon = await driver.wait(until.elementLocated(By.css('.fa-download')), 5000).catch(() => false); const element = await driver.findElement(By.linkText('Download Export')); @@ -6263,72 +5016,149 @@ const steps = [ } }, - //Sort by Count (default) + //My Content - Sort by Count (default) { - description: 'Validate sort order by Count', + description: 'Newly created Content Set sort order', action: async () => { - const multipleChecks = 'My Content - Sort order by Count'; + const multipleChecks = `${createContentSetName} sort order`; + + const element = await driver.findElement(By.linkText(`${createContentSetName}`)); + //Get href, text, font, size, and color + const elementURL = await element.getAttribute('href'); + const elementText = await element.getText(); + const elementFont = await element.getCssValue('font-family'); + const elementSize = await element.getCssValue('font-size'); + const elementColor = await element.getCssValue('color'); + + //Edit icon = the sibling right after the Content Set link (NOT the inner , which has no href/title) + const elementEditIcon = await element.findElement(By.xpath('./following-sibling::a[@title="Edit Content Set" or contains(@href, "contentset_edit_modal.php")]')); + //Get href, title, and color + const elementEditIconURL = await elementEditIcon.getAttribute('href'); + const elementEditIconTitle = await elementEditIcon.getAttribute('title'); + const elementEditIconColor = await elementEditIcon.getCssValue('color'); + + //Count = badge in the same
  • as the Content Set link (no hardcoded nesting depth) + const elementCount = await element.findElement(By.xpath('./ancestor::li[1]/div/span')); + //Get text, font, size, and color + const elementCountText = await elementCount.getText(); + const elementCountFont = await elementCount.getCssValue('font-family'); + const elementCountSize = await elementCount.getCssValue('font-size'); + const elementCountColor = await elementCount.getCssValue('color'); + + //All Content Set names in list order (to confirm the new one is last) + const listNames = await driver.executeScript(` + return Array.from(document.querySelectorAll('ul#content-org-list > li > div.orgname > a:first-child')) + .map(a => a.textContent.trim()); + `); + const expectedPosition = myContentSets.length + 1; + + //Track all errors const errors = []; - const rows = await driver.executeScript(` - const results = []; - const items = document.querySelectorAll('#mycontentlist .orgname'); - items.forEach((item, index) => { - const nameLink = item.querySelector('a:first-child'); - const name = nameLink ? nameLink.textContent.trim() : ''; - const editLink = item.querySelector('a.ml-2'); - const href = editLink ? editLink.getAttribute('href') : ''; - const countSpan = item.closest('li').querySelector('.badge.contnet_set_count'); - const count = countSpan ? countSpan.textContent.trim() : ''; - results.push({ position: index + 1, name, href, count }); - }); - return results; - `); + //New Content Set ID is generated on create, so read it from the link and reuse it for the edit icon check + const idMatch = (elementURL || '').match(/^https:\/\/correlation\.edgate\.com\/exact\/\?iPublisherId=(\d+)&function=listUnits$/); + const newContentSetId = idMatch ? idMatch[1] : null; - const expected = [ - { position: 1, name: 'Biology', count: '1493', href: '/exact/contentset_edit_modal.php?id=585821587' }, - { position: 2, name: 'Math Alignment Import Test', count: '730', href: '/exact/contentset_edit_modal.php?id=1423792414' }, - { position: 3, name: 'English I', count: '389', href: '/exact/contentset_edit_modal.php?id=585821585' }, - { position: 4, name: 'Copy Move Delete Test 2', count: '327', href: '/exact/contentset_edit_modal.php?id=1228574325' }, - { position: 5, name: 'Algebra', count: '192', href: '/exact/contentset_edit_modal.php?id=585821586' }, - { position: 6, name: 'US History III', count: '67', href: '/exact/contentset_edit_modal.php?id=585821589' }, - { position: 7, name: 'Import Align - Concept Based 1', count: '44', href: '/exact/contentset_edit_modal.php?id=1323320445' }, - { position: 8, name: 'Import Align - Concept Based 2', count: '44', href: '/exact/contentset_edit_modal.php?id=1323322624' }, - { position: 9, name: 'Import Align - Direct Align 1', count: '44', href: '/exact/contentset_edit_modal.php?id=1323322921' }, - { position: 10, name: 'Import Align - Direct Align 2', count: '44', href: '/exact/contentset_edit_modal.php?id=1323322923' }, - { position: 11, name: 'Copy Move Delete Test 1', count: '35', href: '/exact/contentset_edit_modal.php?id=1228574323' }, - { position: 12, name: 'create me', count: '6', href: '/exact/contentset_edit_modal.php?id=1427607301' }, - { position: 13, name: 'Automated Algebra Content Set - TO BE DELETED', count: '0', hrefContains: '/exact/contentset_edit_modal.php?id=' } - ]; + //url + if (newContentSetId) { + console.log(`Passed: Newly created Content Set link URL matched as expected, ID ${newContentSetId}`); + } else { + errors.push(`Expected: Element URL link format: "https://correlation.edgate.com/exact/?iPublisherId=&function=listUnits"; Actual: "${elementURL}"`); + } - for (const exp of expected) { - const actual = rows[exp.position - 1]; - if (!actual) { - errors.push(`Position ${exp.position}: row not found`); - continue; - } + //text + if (elementText === createContentSetName) { + console.log(`Passed: ${createContentSetName} link text matched as expected`); + } else { + errors.push(`Expected: "${createContentSetName}" ; Actual: "${elementText}"`); + } - const nameMatch = actual.name === exp.name; - const countMatch = actual.count === exp.count; - //Use includes() for href if exp.hrefContains is defined, otherwise exact match - const hrefMatch = exp.hrefContains - ? actual.href.includes(exp.hrefContains) - : actual.href === exp.href; + //sort order - last place + if (listNames.length === expectedPosition && listNames[listNames.length - 1] === createContentSetName) { + console.log(`Passed: ${createContentSetName} listed in last place, position ${expectedPosition} as expected`); + } else { + errors.push(`Expected: Last place (position ${expectedPosition}): "${createContentSetName}"; Actual: position ${listNames.indexOf(createContentSetName) + 1} of ${listNames.length}, last item "${listNames[listNames.length - 1]}"`); + } - if (nameMatch && countMatch && hrefMatch) { - console.log(`Passed: Sort Order ${exp.position} - ${exp.name} | Count: ${exp.count} | href | All matched as expected`); - } else { - if (!nameMatch) errors.push(`Sort Order ${exp.position} name - Expected: "${exp.name}"; Actual: "${actual.name}"`); - if (!countMatch) errors.push(`Sort Order ${exp.position} count - Expected: "${exp.count}"; Actual: "${actual.count}"`); - if (!hrefMatch) errors.push(`Sort Order ${exp.position} href - Expected: "${exp.href}"; Actual: "${actual.href}"`); - } + //font-family + if (elementFont === "Poppins, sans-serif") { + console.log('Passed: Newly created Content Set link text font matched as expected'); + } else { + errors.push(`Expected: Newly created Content Set link text font "Poppins, sans-serif"; Actual: ${elementFont}`); + } + + //font size + if (elementSize === '14.3px') { + console.log('Passed: Newly created Content Set link text font-size matched as expected'); + } else { + errors.push(`Expected: Newly created Content Set link text font-size "14.3px"; Actual: "${elementSize}"`); + } + + //color + if (elementColor === 'rgba(73, 80, 87, 1)') { + console.log('Passed: Newly created Content Set link text color matched as expected'); + } else { + errors.push(`Expected: Newly created Content Set link text color: "rgba(73, 80, 87, 1)"; Actual: "${elementColor}"`); + } + + //icon title + if (elementEditIconTitle === 'Edit Content Set') { + console.log('Passed: Newly created Content Set edit icon title matched as expected'); + } else { + errors.push(`Expected: Newly created Content Set edit icon title "Edit Content Set"; Actual: "${elementEditIconTitle}"`); + } + + //icon url - must use the same ID as the Content Set link + const expectedEditIconURL = `https://correlation.edgate.com/exact/contentset_edit_modal.php?id=${newContentSetId}`; + if (newContentSetId && elementEditIconURL === expectedEditIconURL) { + console.log(`Passed: Newly created Content Set edit icon URL matched as expected, ID ${newContentSetId}`); + } else { + errors.push(`Expected: Edit icon URL: "${expectedEditIconURL}"; Actual: "${elementEditIconURL}"`); + } + + //icon color + if (elementEditIconColor === 'rgba(73, 80, 87, 1)') { + console.log('Passed: Newly created Content Set edit icon color matched as expected'); + } else { + errors.push(`Expected: Newly created Content Set edit icon color: "rgba(73, 80, 87, 1)"; Actual: "${elementEditIconColor}"`); + } + + //count + if (elementCountText === '0') { + console.log(`Passed: ${createContentSetName} content count listed in last place as expected`); + } else { + errors.push(`Expected: Last place: ${createContentSetName} content count: "0"; Actual: "${elementCountText}"`); + } + + //count font-family + if (elementCountFont === "Poppins, sans-serif") { + console.log('Passed: Newly created Content Set content count font matched as expected'); + } else { + errors.push(`Expected: Newly created Content Set content count font "Poppins, sans-serif"; Actual: ${elementCountFont}`); + } + + //count font size + if (elementCountSize === '12.87px') { + console.log('Passed: Newly created Content Set content count font-size matched as expected'); + } else { + errors.push(`Expected: Newly created Content Set content count font-size "12.87px"; Actual: "${elementCountSize}"`); + } + + //count color + if (elementCountColor === 'rgba(40, 39, 90, 1)') { + console.log('Passed: Newly created Content Set content count color matched as expected'); + } else { + errors.push(`Expected: Newly created Content Set content count color: "rgba(40, 39, 90, 1)"; Actual: "${elementCountColor}"`); } //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')); } } @@ -6345,7 +5175,7 @@ const steps = [ for (const char of 'algebra') { await filterInput.sendKeys(char); await driver.executeScript(`$(document.querySelector('#content-org-filter')).trigger('keyup');`); - await driver.sleep(300); + await driver.sleep(100); } console.log('----->| NEXT ACTION: Filtered My Content list by - algebra'); await driver.sleep(2000); @@ -6372,9 +5202,10 @@ const steps = [ //Validate sort order by filter algebra { - description: 'Validate sort order by filter algebra', + description: 'Sort order by filter algebra', action: async () => { const multipleChecks = 'My Content - Sort order by filter algebra'; + const errors = []; const rows = await driver.executeScript(` @@ -6399,7 +5230,7 @@ const steps = [ //Positions are now 1 and 2 since we only have 2 visible items const expected = [ - { position: 1, name: 'Algebra', count: '192', href: '/exact/contentset_edit_modal.php?id=585821586' }, + { position: 1, name: 'Algebra', count: '194', href: '/exact/contentset_edit_modal.php?id=585821586' }, { position: 2, name: 'Automated Algebra Content Set - TO BE DELETED', count: '0', hrefContains: '/exact/contentset_edit_modal.php?id=' } ]; @@ -6435,7 +5266,7 @@ const steps = [ } }, - //NEXT ACTION orgsort (SPECIAL CASE: visible in DOM) + //NEXT ACTION orgsort { description: 'Click Name sort by option', action: async () => { @@ -6445,14 +5276,15 @@ const steps = [ await selectElement.selectByVisibleText('Name'); console.log('----->| NEXT ACTION: Selected Sort: "Name" option'); - //Wait specifically for the list to re-render with Algebra first + //Wait specifically for the list to re-render with the first Name-sorted Content Set first + const expectedFirst = myContentSetsByName[0].name; await driver.wait(async () => { try { const firstItem = await driver.executeScript(` const first = document.querySelector('#mycontentlist .orgname a:first-child'); return first ? first.textContent.trim() : ''; `); - return firstItem === 'Algebra'; + return firstItem === expectedFirst; } catch (e) { return false; } @@ -6464,9 +5296,10 @@ const steps = [ //Sort by Name { - description: 'Validate sort order by Name', + description: 'Sort order by Name', action: async () => { const multipleChecks = 'My Content - Sort order by Name'; + const errors = []; const rows = await driver.executeScript(` @@ -6484,21 +5317,22 @@ const steps = [ return results; `); - const expected = [ - { position: 1, name: 'Algebra', count: '192', href: '/exact/contentset_edit_modal.php?id=585821586' }, - { position: 2, name: 'Automated Algebra Content Set - TO BE DELETED', count: '0', hrefContains: '/exact/contentset_edit_modal.php?id=' }, - { position: 3, name: 'Biology', count: '1493', href: '/exact/contentset_edit_modal.php?id=585821587' }, - { position: 4, name: 'Copy Move Delete Test 1', count: '35', href: '/exact/contentset_edit_modal.php?id=1228574323' }, - { position: 5, name: 'Copy Move Delete Test 2', count: '327', href: '/exact/contentset_edit_modal.php?id=1228574325' }, - { position: 6, name: 'create me', count: '6', href: '/exact/contentset_edit_modal.php?id=1427607301' }, - { position: 7, name: 'English I', count: '389', href: '/exact/contentset_edit_modal.php?id=585821585' }, - { position: 8, name: 'Import Align - Concept Based 1', count: '44', href: '/exact/contentset_edit_modal.php?id=1323320445' }, - { position: 9, name: 'Import Align - Concept Based 2', count: '44', href: '/exact/contentset_edit_modal.php?id=1323322624' }, - { position: 10, name: 'Import Align - Direct Align 1', count: '44', href: '/exact/contentset_edit_modal.php?id=1323322921' }, - { position: 11, name: 'Import Align - Direct Align 2', count: '44', href: '/exact/contentset_edit_modal.php?id=1323322923' }, - { position: 12, name: 'Math Alignment Import Test', count: '730', href: '/exact/contentset_edit_modal.php?id=1423792414' }, - { position: 13, name: 'US History III', count: '67', href: '/exact/contentset_edit_modal.php?id=585821589' } - ]; + //Expected Name sort order built from the myContentSets constant (+ newly created Content Set) + //Known IDs check the exact edit URL; null IDs (incl. the new Content Set) check the URL format only + const editURL = '/exact/contentset_edit_modal.php?id='; + const expected = myContentSetsByName.map((s, i) => ({ + position: i + 1, + name: s.name, + count: s.totalItems, + ...(s.id ? { href: `${editURL}${s.id}` } : { hrefContains: editURL }), + })); + + //Item count + if (rows.length === expected.length) { + console.log(`Passed: Sort by Name item count matched as expected (${expected.length})`); + } else { + errors.push(`Expected: ${expected.length} items sorted by Name; Actual: ${rows.length}`); + } for (const exp of expected) { const actual = rows[exp.position - 1]; @@ -6519,10 +5353,15 @@ const steps = [ } else { if (!nameMatch) errors.push(`Sort Order ${exp.position} name - Expected: "${exp.name}"; Actual: "${actual.name}"`); if (!countMatch) errors.push(`Sort Order ${exp.position} count - Expected: "${exp.count}"; Actual: "${actual.count}"`); - if (!hrefMatch) errors.push(`Sort Order ${exp.position} href - Expected: "${exp.href}"; Actual: "${actual.href}"`); + if (!hrefMatch) errors.push(`Sort Order ${exp.position} href - Expected: "${exp.href || exp.hrefContains + ''}"; Actual: "${actual.href}"`); } } + //Report any unexpected extra items + rows.slice(expected.length).forEach(extra => { + errors.push(`Unexpected item at Sort Order ${extra.position}: "${extra.name}" (${extra.count})`); + }); + //Throw summary if any validation failed if (errors.length > 0) { if (errors.length > 1) { @@ -6556,9 +5395,10 @@ const steps = [ //Edit DIV - title { - description: 'Validate Edit DIV title', + description: 'Edit DIV title', action: async () => { const multipleChecks = 'Edit DIV title'; + const element = await driver.findElement(By.css('.modal-lg .modal-title')); //Get text, font, size, and color @@ -6613,9 +5453,10 @@ const steps = [ //Edit DIV - label { - description: 'Validate Edit DIV - Content Set Name label', + description: 'Edit DIV - Content Set Name label', action: async () => { const multipleChecks = 'Edit DIV label'; + const element = await driver.findElement(By.css('#divname > .form-label')); //Get text, font, size, and color @@ -6670,9 +5511,10 @@ const steps = [ //Edit DIV - textbox { - description: 'Validate Edit DIV textbox', + description: 'Edit DIV textbox', action: async () => { const multipleChecks = 'Edit DIV texbox'; + const element = await driver.findElement(By.css('#orgname')); //Get text, font, size, and color @@ -6727,9 +5569,10 @@ const steps = [ //Delete button { - description: 'Validate Delete button', + description: 'Delete button', action: async () => { const multipleChecks = 'Delete button'; + const element = await driver.findElement(By.css('#orgdelete')); //Get text, font, color, and size @@ -6800,9 +5643,10 @@ const steps = [ //Save button { - description: 'Validate Save button', + description: 'Save button', action: async () => { const multipleChecks = 'Save button'; + const element = await driver.findElement(By.css('#modalop')); //Get text, font, color, and size @@ -6865,9 +5709,10 @@ const steps = [ //Close button { - description: 'Validate Close button', + description: 'Close button', action: async () => { const multipleChecks = 'Close button'; + const element = await driver.findElement(By.css('#modalclose')); //Get text, font, color, and size @@ -6933,6 +5778,7 @@ const steps = [ description: 'Delete created content and validate alert message', action: async () => { const multipleChecks = 'Delete content alert'; + const errors = []; //Wait for modal to be ready @@ -6940,9 +5786,8 @@ const steps = [ await driver.sleep(1000); //Click delete button - const deleteButton = await driver.wait(until.elementLocated(By.css('#orgdelete')), 5000); - await deleteButton.click(); - await driver.sleep(5000); + await driver.wait(until.elementLocated(By.css('#orgdelete')), 5000).click(); + await driver.sleep(2500); console.log('----->| NEXT ACTION: Clicked Delete button'); //Wait for confirm dialog to appear @@ -6988,9 +5833,10 @@ const steps = [ //Alert banner { - description: 'Validate alert banner', + description: 'Alert banner', action: async () => { const multipleChecks = 'Alert banner'; + const element = await driver.findElement(By.css('strong')); const elementBanner = await driver.findElement(By.css('#statalert')); @@ -7087,7 +5933,7 @@ const steps = [ for (const char of 'Automated Algebra') { await filterInput.sendKeys(char); await driver.executeScript(`$(document.querySelector('#content-org-filter')).trigger('keyup');`); - await driver.sleep(300); + await driver.sleep(100); } console.log('----->| NEXT ACTION: Filtered list by "Automated Algebra"'); await driver.sleep(1000); @@ -7110,11 +5956,169 @@ const steps = [ } else { console.log(`Passed: ${createContentSetName} successfully deleted and no longer visible`); } + + //Clear the filter - .clear() fires no key events, so trigger keyup (same event the filter listens to) + await filterInput.clear(); + await driver.executeScript(`$(document.querySelector('#content-org-filter')).trigger('keyup');`); + console.log('----->| NEXT ACTION: Deleted filter term'); + + //Wait until the full list is visible again (all original Content Sets; new one was deleted) + await driver.wait(async () => { + const visibleCount = await driver.executeScript(` + return Array.from(document.querySelectorAll('#mycontentlist .orgname')).filter(el => { + const style = window.getComputedStyle(el.closest('li')); + return style.display !== 'none' && style.visibility !== 'hidden'; + }).length; + `); + return visibleCount === myContentSets.length; + }, 10000, `My Content list did not reset to ${myContentSets.length} items within 10 seconds after clearing filter`, 300); + console.log('Passed: My Content list reset after clearing filter'); + } + }, + + //NEXT ACTION - reopen My Content Totals DIV (table rows only load when the DIV is opened) + { + description: 'Click My Content Items Count button (re-validate totals after delete)', + action: async () => { + await driver.findElement(By.css('#content_total')).click(); + console.log('----->| NEXT ACTION: Clicked Total items count button'); + + //Wait until the modal title is located AND visible + await driver.wait(async () => { + try { + const element = await driver.findElement(By.css('.content_modal_title')); + return await element.isDisplayed(); + } catch (e) { + return false; //Element not ready yet, keep waiting + } + }, 20000, 'My Content Totals DIV did not become visible within 20 seconds'); + + //Wait until table rows have loaded + await driver.wait(until.elementLocated(By.css('#content_tbody > tr')), 20000, 'My Content Totals table rows did not load within 20 seconds'); + console.log('Passed: My Content Totals DIV loaded successfully'); + } + }, + + //My Content Totals DIV - Table data (Content Set, Total Items, Unique Titles, Unique IDs) + { + description: 'My Content Totals DIV - Table Content Set, Total Items, Unique Titles, and Unique IDs', + action: async () => { + const multipleChecks = 'My Content Totals table data'; + + //Expected rows in display order: [Content Set, Total Items, Unique Titles, Unique IDs] (from myContentSets constant) + const expectedRows = myContentSets.map(s => [s.name, s.totalItems, s.uniqueTitles, s.uniqueIds]); + const columns = ['Content Set', 'Total Items', 'Unique Titles', 'Unique IDs']; + + //Expected cell styles per column [Content Set, Total Items, Unique Titles, Unique IDs] + const expectedStyles = [ + { font: 'Poppins, sans-serif', size: '12px', color: 'rgba(40, 39, 90, 1)' }, + { font: 'Poppins, sans-serif', size: '12px', color: 'rgba(40, 39, 90, 1)' }, + { font: 'Poppins, sans-serif', size: '12px', color: 'rgba(40, 39, 90, 1)' }, + { font: 'Poppins, sans-serif', size: '12px', color: 'rgba(40, 39, 90, 1)' }, + ]; + + //Wait for table rows to render + await driver.wait(until.elementLocated(By.css('#content_tbody > tr')), 20000, 'My Content Totals table rows did not load within 20 seconds'); + + //Read all cells in one call (textContent also works for rows scrolled out of view) + //Colors are normalized from rgb() to rgba() to match Selenium's getCssValue() format + const cellData = await driver.executeScript(` + const toRgba = c => c.startsWith('rgb(') ? c.replace('rgb(', 'rgba(').replace(')', ', 1)') : c; + return Array.from(document.querySelectorAll('#content_tbody > tr')).map(tr => + Array.from(tr.querySelectorAll('td')).map(td => { + const cs = window.getComputedStyle(td); + return { text: td.textContent.trim(), font: cs.fontFamily, size: cs.fontSize, color: toRgba(cs.color) }; + }) + ); + `); + const actualRows = cellData.map(row => row.map(cell => cell.text)); + + //Track all errors + const errors = []; + + //Row count + if (actualRows.length === expectedRows.length) { + console.log(`Passed: My Content Totals table row count matched as expected, ${expectedRows.length}`); + } else { + errors.push(`Expected: ${expectedRows.length} table rows; Actual: ${actualRows.length}`); + } + + //Cell-by-cell comparison + expectedRows.forEach((expected, rowIndex) => { + const actual = actualRows[rowIndex]; + if (!actual) { + errors.push(`Row ${rowIndex + 1} ("${expected[0]}") missing from table`); + return; + } + + const rowErrors = []; + columns.forEach((column, colIndex) => { + if (actual[colIndex] !== expected[colIndex]) { + rowErrors.push(`${column} Expected: "${expected[colIndex]}"; Actual: "${actual[colIndex]}"`); + } + + //Style checks (font-family, font-size, color) + const cell = cellData[rowIndex][colIndex]; + const style = expectedStyles[colIndex]; + if (!cell) return; + if (cell.font !== style.font) { + rowErrors.push(`${column} font Expected: "${style.font}"; Actual: "${cell.font}"`); + } + if (cell.size !== style.size) { + rowErrors.push(`${column} font-size Expected: "${style.size}"; Actual: "${cell.size}"`); + } + if (cell.color !== style.color) { + rowErrors.push(`${column} color Expected: "${style.color}"; Actual: "${cell.color}"`); + } + }); + + if (rowErrors.length === 0) { + console.log(`Passed: Row ${rowIndex + 1} "${expected[0]}" - ${columns.map((c, i) => `${c}: ${expected[i]}`).join(', ')} | Text font, size, and color all matched as expected`); + } else { + errors.push(`Row ${rowIndex + 1} ("${expected[0]}"): ${rowErrors.join('; ')}`); + } + }); + + //Report any unexpected extra rows + actualRows.slice(expectedRows.length).forEach((extra, i) => { + errors.push(`Unexpected row ${expectedRows.length + i + 1}: ${JSON.stringify(extra)}`); + }); + + //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 - close My Content Totals DIV before logging out + { + description: 'Close My Content Totals DIV', + action: async () => { + const closeButton = await driver.findElement(By.css('#all_content_modal .btn-secondary')); + await closeButton.click(); + console.log('----->| NEXT ACTION: Clicked My Content Totals DIV Close button'); + + //Wait until the DIV is hidden + await driver.wait(async () => { + try { + return !(await driver.findElement(By.css('.content_modal_title')).isDisplayed()); + } catch (e) { + return true; + } + }, 10000, 'My Content Totals DIV did not close within 10 seconds'); + console.log('Passed: My Content Totals DIV closed'); } }, //NEXT ACTION - { + { description: 'Log Out', action: async () => { const multipleChecks = 'Log Out'; @@ -7169,7 +6173,7 @@ const logStep = (worksheet, stepDescription, status, stepIndex, timestamp, scree const takeScreenshot = async (driver, stepIndex, stepDescription) => { const screenshot = await driver.takeScreenshot(); - const dir = path.join('screenshots', 'dashboardMyContent'); + const dir = path.join('screenshots', 'myContentWidget'); const screenshotFileName = `step_${stepIndex}_${stepDescription.replace(/\s+/g, '_')}.png`; const screenshotPath = path.join(dir, screenshotFileName); @@ -7177,17 +6181,19 @@ const takeScreenshot = async (driver, stepIndex, stepDescription) => { return screenshotPath; }; +const resultsFile = path.join('results', 'myContentWidget.xlsx'); + const clearOldResults = () => { //Remove old screenshots - const screenshotDir = path.join('screenshots', 'dashboardMyContent'); + const screenshotDir = path.join('screenshots', 'myContentWidget'); if (fs.existsSync(screenshotDir)) { fs.rmSync(screenshotDir, { recursive: true, force: true }); } fs.mkdirSync(screenshotDir, { recursive: true }); //Remove old Excel file - if (fs.existsSync('dashboardMyContentResults.xlsx')) { - fs.unlinkSync('dashboardMyContentResults.xlsx'); + if (fs.existsSync(resultsFile)) { + fs.unlinkSync(resultsFile); } }; @@ -7249,11 +6255,11 @@ try { if (allStepsPassed) { console.log('------------->| THE END |<-------------'); - console.log('PASSED: DASHBOARD - My Content widget (ExACT_dashboardMyContent); All test steps completed successfully'); + console.log('PASSED: DASHBOARD - My Content Widget(myContentWidget); All test steps completed successfully'); testStatus = 'Passed'; } else { console.log('------------->| THE END |<-------------'); - console.log('FAILED: DASHBOARD - My Content widget (ExACT_dashboardMyContent); One or more test steps failed'); + console.log('FAILED: DASHBOARD - My Content Widget(myContentWidget); One or more test steps failed'); console.log('FAILED STEPS:'); failedSteps.forEach(step => console.error(` ✗ ${step}`)); testStatus = 'Failed'; @@ -7265,11 +6271,11 @@ try { //Write the updated worksheet back to the workbook and save it workbook.Sheets['Sheet1'] = worksheet; - XLSX.writeFile(workbook, 'dashboardMyContentResults.xlsx'); + XLSX.writeFile(workbook, resultsFile); } finally { await driver.quit(); } })(); } -export default ExACT_dashboardMyContent; +export default myContentWidget; diff --git a/tests/CorrelationDashboard/MyStandardsWidget/dashboardMyStandards.js b/tests/CorrelationDashboard/Widgets/myStandardsWidget.js similarity index 97% rename from tests/CorrelationDashboard/MyStandardsWidget/dashboardMyStandards.js rename to tests/CorrelationDashboard/Widgets/myStandardsWidget.js index 1418dbb..0c30805 100644 --- a/tests/CorrelationDashboard/MyStandardsWidget/dashboardMyStandards.js +++ b/tests/CorrelationDashboard/Widgets/myStandardsWidget.js @@ -1,12 +1,13 @@ -import { Builder, By, Key, until, Select, Browser } from 'selenium-webdriver'; +import { Builder, By, until } 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 os from 'os'; import { myStandardsSearch_AlignedContent } from '../../myStandardsSearchAlignedContent.js'; -const dashboardMyStandards = (req, res) => { - res.send('

    ExACT Automated Test Script: DASHBOARD - My Standards Widget(dashboardMyStandards) | Initiated

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

    ExACT Automated Test Script: DASHBOARD - My Standards Widget(myStandardsWidget) | Initiated

    '); (async function example() { let driver = await new Builder() .forBrowser('chrome') @@ -23,6 +24,80 @@ const dashboardMyStandards = (req, res) => { let worksheet; const startTime = new Date().toISOString(); +//DOWNLOAD / PAGE-READY HELPERS +//Chrome (Selenium profile) saves downloads to the user's Downloads folder by default +const downloadDir = path.join(os.homedir(), 'Downloads'); +const exportTimeoutMs = 180000; //max time to wait for Export processing + download +const inProgressDownload = /\.(crdownload|tmp|part)$/i; + +//Snapshot of files currently in the Downloads folder +const listDownloads = () => { + try { + return fs.readdirSync(downloadDir); + } catch (e) { + return []; + } +}; + +//Wait until a NEW file (not in beforeFiles) is fully downloaded: +//no in-progress (.crdownload/.tmp/.part) files remain and the new file's size has stopped changing +const waitForDownloadComplete = async (beforeFiles, timeoutMs = exportTimeoutMs) => { + const before = new Set(beforeFiles); + let lastSize = -1; + let stableSince = 0; + let downloadedFile = null; + + await driver.wait(async () => { + const newFiles = listDownloads().filter(f => !before.has(f)); + + //Still downloading + if (newFiles.some(f => inProgressDownload.test(f))) { + lastSize = -1; + return false; + } + + const finished = newFiles.filter(f => !inProgressDownload.test(f)); + if (finished.length === 0) return false; + + const file = finished[finished.length - 1]; + let size; + try { + size = fs.statSync(path.join(downloadDir, file)).size; + } catch (e) { + return false; //file being renamed, check again + } + + //Require the size to be unchanged for at least 1 second + if (size > 0 && size === lastSize && Date.now() - stableSince >= 1000) { + downloadedFile = file; + return true; + } + if (size !== lastSize) { + lastSize = size; + stableSince = Date.now(); + } + return false; + }, timeoutMs, `Export download did not complete within ${timeoutMs / 1000} seconds (watching ${downloadDir})`, 500); + + return downloadedFile; +}; + +//Wait until the page is truly ready: document loaded, no pending jQuery AJAX, +//no open/animating modal or backdrop, and the My Standards table has rows +const waitForDashboardReady = async (timeoutMs = 60000) => { + await driver.wait(async () => { + return await driver.executeScript(` + if (document.readyState !== 'complete') return false; + if (window.jQuery && window.jQuery.active > 0) return false; + const visibleModal = Array.from(document.querySelectorAll('.modal')) + .some(m => m.classList.contains('show') || window.getComputedStyle(m).display !== 'none'); + if (visibleModal) return false; + if (document.querySelector('.modal-backdrop')) return false; + return document.querySelectorAll('#stdbody > tr').length > 0; + `); + }, timeoutMs, `ExACT Dashboard was not ready within ${timeoutMs / 1000} seconds`, 500); +}; + 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() }, @@ -32,6 +107,7 @@ const steps = [ description: 'Login', action: async () => { const multipleChecks = 'Log In'; + console.log('------------->| MY STANDARDS WIDGET |<-------------'); const errors = []; @@ -108,6 +184,7 @@ const steps = [ description: 'Validate dashboard title text, size, and color', action: async () => { const multipleChecks = 'Dashboard title'; + const element = await driver.findElement(By.css('.e-heading')); //Get text, font, size, and color @@ -166,6 +243,7 @@ const steps = [ description: 'Validate Dashboard Semantic Standards Comparison Widget title text, color, and size', action: async () => { const multipleChecks = 'My Standards Widget title (active)'; + const element = await driver.findElement(By.css('#mystd-tab')); //Get text, font, size, and color @@ -223,6 +301,7 @@ const steps = [ description: 'Validate Dashboard - Other Available Stndards tab title text, color, and size', action: async () => { const multipleChecks = 'Other Available Stndards tab title'; + const element = await driver.findElement(By.css('#availstd-tab')); //Get text, font, size, and color @@ -280,6 +359,7 @@ const steps = [ description: 'Validate Dashboard - My Standards dropdown list and value', action: async () => { const multipleChecks = 'My Standards dropdown list'; + const elementDropdown = await driver.findElement(By.css('#stdparent')); const selectedOption = await elementDropdown.findElement(By.css('option:checked')); @@ -368,6 +448,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Organization column title, text, and font size', action: async () => { const multipleChecks = 'My Standards Organization column title' + const element = await driver.findElement(By.css('.table:nth-child(2) th:nth-child(1)')); //Get text, font, size, and color @@ -425,6 +506,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Export column title, text, and font size', action: async () => { const multipleChecks = 'My Standards Export column title'; + const element = await driver.findElement(By.css('.table:nth-child(2) > thead .text-center:nth-child(2)')); //Get text, font, size, and color @@ -482,6 +564,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Manage column title, text, and font size', action: async () => { const multipleChecks = 'My Standards Manage column title'; + const element = await driver.findElement(By.css('.text-center:nth-child(3)')); //Get text, font, size, and color @@ -539,6 +622,7 @@ const steps = [ description: 'Validate Dashboard - My Standards More Info column title, text, and font size', action: async () => { const multipleChecks = 'My Standards More Info column title'; + const element = await driver.findElement(By.css('.table-sm > thead .text-center:nth-child(4)')); //Get text, font, size, and color @@ -596,6 +680,7 @@ const steps = [ description: 'Validate Dashboard - My Standards View column title, text, and font size', action: async () => { const multipleChecks = 'My Standards View column title'; + const element = await driver.findElement(By.css('thead .text-center:nth-child(5)')); //Get text, font, size, and color @@ -653,6 +738,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Organization = Alabama Standards text', action: async () => { const multipleChecks = 'My Standards Organization - Alabama'; + const element = await driver.findElement(By.css('#stdbody > tr:nth-child(1) > td:nth-child(1)')); //Get text, font, color, and size @@ -735,6 +821,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Organization = Arizona Standards text', action: async () => { const multipleChecks = 'My Standards Organization - Arizona'; + const element = await driver.findElement(By.css('#stdbody > tr:nth-child(2) > td:nth-child(1)')); //Get text, font, color, and size @@ -817,6 +904,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Organization = California Standards text', action: async () => { const multipleChecks = 'My Standards Organization - California'; + const element = await driver.findElement(By.css('#stdbody > tr:nth-child(3) > td:nth-child(1)')); //Get text, font, color, and size @@ -899,6 +987,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Organization = Florida Standards text', action: async () => { const multipleChecks = 'My Standards Organization - Florida'; + const element = await driver.findElement(By.css('#stdbody > tr:nth-child(4) > td:nth-child(1)')); //Get text, font, color, and size @@ -981,6 +1070,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Organization = Georgia Standards text', action: async () => { const multipleChecks = 'My Standards Organization - Georgia'; + const element = await driver.findElement(By.css('#stdbody > tr:nth-child(5) > td:nth-child(1)')); //Get text, font, color, and size @@ -1063,6 +1153,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Organization = Illinois Standards text', action: async () => { const multipleChecks = 'My Standards Organization - Illinois'; + const element = await driver.findElement(By.css('#stdbody > tr:nth-child(6) > td:nth-child(1)')); //Get text, font, color, and size @@ -1145,6 +1236,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Organization = New York Standards text', action: async () => { const multipleChecks = 'My Standards Organization - New York'; + const element = await driver.findElement(By.css('#stdbody > tr:nth-child(7) > td:nth-child(1)')); //Get text, font, color, and size @@ -1227,6 +1319,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Organization = Texas Standards text', action: async () => { const multipleChecks = 'My Standards Organization - Texas'; + const element = await driver.findElement(By.css('#stdbody > tr:nth-child(8) > td:nth-child(1)')); //Get text, font, color, and size @@ -1309,6 +1402,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Organization = Washington Standards text', action: async () => { const multipleChecks = 'My Standards Organization - Washington'; + const element = await driver.findElement(By.css('#stdbody > tr:nth-child(9) > td:nth-child(1)')); //Get text, font, color, and size @@ -1412,6 +1506,7 @@ const steps = [ description: 'Validate Dashboard Semantic Standards Comparison Widget title text, color, and size', action: async () => { const multipleChecks = 'Dashboard Semantic Standards Comparison Widget title'; + const element = await driver.findElement(By.css('#mystd-tab')); //Get text, font, color, and size @@ -1469,6 +1564,7 @@ const steps = [ description: 'Validate Dashboard - Other Available Stndards tab title text, color, and size', action: async () => { const multipleChecks = 'Other Available Stndards tab title'; + const element = await driver.findElement(By.css('#availstd-tab')); //Get text, font, color, and size @@ -1526,6 +1622,7 @@ const steps = [ description: 'Validate Dashboard - Other Available Stndards tab title text, color, and size', action: async () => { const multipleChecks = 'Other Available Stndards tab title'; + const element = await driver.findElement(By.css('p:nth-child(1)')); //Get text, font, color, and size @@ -1583,6 +1680,7 @@ const steps = [ description: 'Validate Dashboard - Other Available Standards dropdown list and value', action: async () => { const multipleChecks = 'Other Available Standards'; + const elementDropdown = await driver.findElement(By.css('#defstdparent')); const selectedOption = await elementDropdown.findElement(By.css('option:checked')); @@ -1686,7 +1784,8 @@ const steps = [ { description: 'Validate Dashboard - Other Available Standards Organization column title, text, and font size', action: async () => { - const multiple = 'Other Available Standards Organization column title'; + const multipleChecks = 'Other Available Standards Organization column title'; + const element = await driver.findElement(By.css('.table:nth-child(3) th:nth-child(1)')); //Get text, font, color, and size @@ -1744,6 +1843,7 @@ const steps = [ description: 'Validate Dashboard - Other Available Standards More Info column title, text, and font size', action: async () => { const multipleChecks = 'Other Available Organization column title'; + const element = await driver.findElement(By.css('.table:nth-child(3) > thead .text-center')); //Get text, font, color, and size @@ -1801,6 +1901,7 @@ const steps = [ description: 'Validate Dashboard - Other Available Standards - Alaska', action: async () => { const multipleChecks = 'Other Available Standards - Alaska'; + const element = await driver.findElement(By.css('#defstdbody > tr:nth-child(1) > td:nth-child(1)')); //Get text, font, color, and size @@ -1867,6 +1968,7 @@ const steps = [ description: 'Validate Dashboard - Other Available Standards - Arkansas', action: async () => { const multipleChecks = 'Other Available Standards - Arkansas'; + const element = await driver.findElement(By.css('#defstdbody > tr:nth-child(2) > td:nth-child(1)')); //Get text, font, color, and size @@ -1933,6 +2035,7 @@ const steps = [ description: 'Validate Dashboard - Other Available Standards - Colorado', action: async () => { const multipleChecks = 'Other Available Standards - Colorado'; + const element = await driver.findElement(By.css('#defstdbody > tr:nth-child(3) > td:nth-child(1)')); //Get text, font, color, and size @@ -1999,6 +2102,7 @@ const steps = [ description: 'Validate Dashboard - Other Available Standards - Connecticut', action: async () => { const multipleChecks = 'Other Available Standards - Connecticut'; + const element = await driver.findElement(By.css('#defstdbody > tr:nth-child(4) > td:nth-child(1)')); //Get text, font, color, and size @@ -2065,6 +2169,7 @@ const steps = [ description: 'Validate Dashboard - Other Available Standards - Delaware', action: async () => { const multipleChecks = 'Other Available Standards - Delaware'; + const element = await driver.findElement(By.css('#defstdbody > tr:nth-child(5) > td:nth-child(1)')); //Get text, font, color, and size @@ -2152,6 +2257,7 @@ const steps = [ description: 'Validate Dashboard Semantic Standards Comparison Widget title text, color, and size', action: async () => { const multipleChecks = 'My Standards Widget title (active)'; + const element = await driver.findElement(By.css('#mystd-tab')); //Get text, font, color, and size @@ -2209,6 +2315,7 @@ const steps = [ description: 'Validate Dashboard - Other Available Stndards tab title text, color, and size', action: async () => { const multipleChecks = 'Other Available Stndards tab title'; + const element = await driver.findElement(By.css('#availstd-tab')); //Get text, font, color, and size @@ -2266,6 +2373,7 @@ const steps = [ description: 'Validate Dashboard - My Standards dropdown list and value', action: async () => { const multipleChecks = 'My Standards dropdown list'; + const elementDropdown = await driver.findElement(By.css('#stdparent')); const selectedOption = await elementDropdown.findElement(By.css('option:checked')); @@ -2354,6 +2462,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Organization column title, text, and font size', action: async () => { const multipleChecks = 'My Standards Organization column title' + const element = await driver.findElement(By.css('.table:nth-child(2) th:nth-child(1)')); //Get text, font, color, and size @@ -2411,6 +2520,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Export column title, text, and font size', action: async () => { const multipleChecks = 'My Standards Export column title'; + const element = await driver.findElement(By.css('.table:nth-child(2) > thead .text-center:nth-child(2)')); //Get text, font, color, and size @@ -2468,6 +2578,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Manage column title, text, and font size', action: async () => { const multipleChecks = 'My Standards Manage column title'; + const element = await driver.findElement(By.css('.text-center:nth-child(3)')); //Get text, font, color, and size @@ -2525,6 +2636,7 @@ const steps = [ description: 'Validate Dashboard - My Standards More Info column title, text, and font size', action: async () => { const multipleChecks = 'My Standards More Info column title'; + const element = await driver.findElement(By.css('.table-sm > thead .text-center:nth-child(4)')); //Get text, font, color, and size @@ -2582,6 +2694,7 @@ const steps = [ description: 'Validate Dashboard - My Standards View column title, text, and font size', action: async () => { const multipleChecks = 'My Standards View column title'; + const element = await driver.findElement(By.css('thead .text-center:nth-child(5)')); //Get text, font, color, and size @@ -2639,6 +2752,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Organization = Alabama Standards text', action: async () => { const multipleChecks = 'My Standards Organization - Alabama'; + const element = await driver.findElement(By.css('#stdbody > tr:nth-child(1) > td:nth-child(1)')); //Get text, font, color, and size @@ -2721,6 +2835,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Organization = Arizona Standards text', action: async () => { const multipleChecks = 'My Standards Organization - Arizona'; + const element = await driver.findElement(By.css('#stdbody > tr:nth-child(2) > td:nth-child(1)')); //Get text, font, color, and size @@ -2803,6 +2918,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Organization = California Standards text', action: async () => { const multipleChecks = 'My Standards Organization - California'; + const element = await driver.findElement(By.css('#stdbody > tr:nth-child(3) > td:nth-child(1)')); //Get text, font, color, and size @@ -2885,6 +3001,7 @@ const steps = [ description: 'Validate Dashboard - My Standards Organization = Florida Standards text', action: async () => { const multipleChecks = 'My Standards Organization - Florida'; + const element = await driver.findElement(By.css('#stdbody > tr:nth-child(4) > td:nth-child(1)')); //Get text, font, color, and size @@ -2989,6 +3106,7 @@ const steps = [ description: 'Validate DIV - Export Standards title text, color, and size', action: async () => { const multipleChecks = 'DIV - Export Standards title'; + const element = await driver.findElement(By.css('.modal-lg .modal-title')); //Get text, font, color, and size @@ -3046,6 +3164,7 @@ const steps = [ description: 'Validate DIV - Alabama sub-title text, color, and size', action: async () => { const multipleChecks = 'DIV - Alabama sub-title'; + const element = await driver.findElement(By.css('p > b')); //Get text, font, color, and size @@ -3103,6 +3222,7 @@ const steps = [ description: 'Validate DIV - Alabama Standards Subject label text, color, and size', action: async () => { const multipleChecks = 'DIV - Alabama Standards Subject label'; + const element = await driver.findElement(By.css('.form-row:nth-child(2) > .form-group:nth-child(1) > label')); //Get text, font, color, and size @@ -3160,6 +3280,7 @@ const steps = [ description: 'Validate DIV - Subject dropdown list and value', action: async () => { const multipleChecks = 'DIV - Subject dropdown'; + const elementDropdown = await driver.findElement(By.css('#exsubject')); const selectedOption = await elementDropdown.findElement(By.css('option:checked')); @@ -3242,6 +3363,7 @@ const steps = [ description: 'Validate DIV - Alabama Standards Format label text, color, and size', action: async () => { const multipleChecks = 'DIV - Alabama Standards Format label'; + const element = await driver.findElement(By.css('.form-row:nth-child(2) > .form-group:nth-child(2) > label')); //Get text, font, color, and size @@ -3299,6 +3421,7 @@ const steps = [ description: 'Validate DIV - Format dropdown list and value', action: async () => { const multipleChecks = 'DIV - Format dropdown'; + const elementDropdown = await driver.findElement(By.css('#exformat')); const selectedOption = await elementDropdown.findElement(By.css('option:checked')); @@ -3376,6 +3499,7 @@ const steps = [ description: 'Validate DIV - Grades label text, color, and size', action: async () => { const multipleChecks = 'DIV - Grades label'; + const element = await driver.findElement(By.css('.col-md-12:nth-child(1) > label')); //Get text, font, color, and size @@ -3433,6 +3557,7 @@ const steps = [ description: 'Validate DIV - Grades dropdown list and value', action: async () => { const multipleChecks = 'DIV - Grades dropdown'; + const elementDropdown = await driver.findElement(By.css('#exgrades')); const elementText = await elementDropdown.getText(); @@ -3508,6 +3633,7 @@ const steps = [ description: 'Validate DIV - Download button icon, text, and color', action: async () => { const multipleChecks = 'DIV - Download button'; + const elementIcon = await driver.findElement(By.css('#exsubmit > .fa')); const element = await driver.findElement(By.css('#exsubmit')); @@ -3581,6 +3707,7 @@ const steps = [ description: 'Validate DIV - Close button text, style, font, and color', action: async () => { const multipleChecks = 'DIV - Close button'; + const element = await driver.findElement(By.css('#modalclose')); //Get text, font, color, and size @@ -3770,6 +3897,7 @@ const steps = [ description: 'Validate DIV - Grade 9', action: async () => { const multipleChecks = 'DIV - Grade 9'; + const elementIconToolTip = await driver.findElement(By.css('#select2-exgrades-container > li:nth-child(1) > button')).getAttribute('title'); const element = await driver.findElement(By.css('#select2-exgrades-container > li:nth-child(1)')); @@ -3818,6 +3946,7 @@ const steps = [ description: 'Validate DIV - Grade 10', action: async () => { const multipleChecks = 'DIV - Grade 10'; + const elementIconToolTip = await driver.findElement(By.css('#select2-exgrades-container > li:nth-child(2) > button')).getAttribute('title'); const element = await driver.findElement(By.css('#select2-exgrades-container > li:nth-child(2)')); @@ -3866,6 +3995,7 @@ const steps = [ description: 'Validate DIV - Grade 11', action: async () => { const multipleChecks = 'DIV - Grade 11'; + const elementIconToolTip = await driver.findElement(By.css('#select2-exgrades-container > li:nth-child(3) > button')).getAttribute('title'); const element = await driver.findElement(By.css('#select2-exgrades-container > li:nth-child(3)')); @@ -3914,6 +4044,7 @@ const steps = [ description: 'Validate DIV - Grade 12', action: async () => { const multipleChecks = 'DIV - Grade 12'; + const elementIconToolTip = await driver.findElement(By.css('#select2-exgrades-container > li:nth-child(4) > button')).getAttribute('title'); const element = await driver.findElement(By.css('#select2-exgrades-container > li:nth-child(4)')); @@ -3992,6 +4123,9 @@ const steps = [ }); `); + //Snapshot Downloads folder so the new export file can be identified + const downloadsBefore = listDownloads(); + //Now click Export await driver.findElement(By.css('#exsubmit')).click(); console.log('----->| NEXT ACTION: Clicked Export button'); @@ -4042,17 +4176,22 @@ const steps = [ } catch (e) { return true; } - }, 30000, 'Processing... Status did not disappear within 30 seconds'); + }, exportTimeoutMs, `Processing... Status did not disappear within ${exportTimeoutMs / 1000} seconds`, 500); console.log('Passed: Processing... Status is no longer visible as expected'); - await driver.findElement(By.css('#modalclose')).click(); + //Wait until the export file is fully downloaded (not just started) + const downloadedFile = await waitForDownloadComplete(downloadsBefore); + console.log(`Passed: Export download completed: "${downloadedFile}"`); + + //Wait for Close button to be clickable, then close the DIV + const closeButton = await driver.wait(until.elementLocated(By.css('#modalclose')), 20000, 'Close button not found within 20 seconds'); + await driver.wait(until.elementIsVisible(closeButton), 20000, 'Close button not visible within 20 seconds'); + await driver.wait(until.elementIsEnabled(closeButton), 20000, 'Close button not enabled within 20 seconds'); + await closeButton.click(); console.log('----->| NEXT ACTION: Clicked Close button'); - //Wait for page to load completely - await driver.wait(async () => { - const readyState = await driver.executeScript('return document.readyState'); - return readyState === 'complete'; - }, 20000, 'ExACT Dashboard did not fully load within 60 seconds'); + //Wait for the DIV to fully close and the dashboard to be ready + await waitForDashboardReady(); console.log('Passed: ExACT Dashboard loaded successfully'); //Throw summary if any validation failed @@ -4095,6 +4234,7 @@ const steps = [ description: 'Validate DIV - Alabama Courses of Study title text, color, and size', action: async () => { const multipleChecks = 'DIV - Alabama Courses of Study title'; + const element = await driver.findElement(By.css('.modal-lg .modal-title')); //Get text, font, size, and color @@ -4152,6 +4292,7 @@ const steps = [ description: 'Validate DIV - More Info Alabma sub-text, color, and size', action: async () => { const multipleChecks = 'DIV - Alabama sut-text'; + const element = await driver.findElement(By.css('.modal-body > .notenabled')); //Get text, font, size, and color @@ -4209,6 +4350,7 @@ const steps = [ description: 'Validate DIV - More Info Alabama Contact Us link text, color, and size', action: async () => { const multipleChecks = 'DIV - Alabama Courses of Study Contact Us link'; + const element = await driver.findElement(By.linkText('Contact Us')); //Get text, font, size, color, url @@ -4274,6 +4416,7 @@ const steps = [ description: 'Validate DIV - More Info Alabama Subject column title text, color, and size', action: async () => { const multipleChecks = 'DIV - Alabama Courses of Study column title'; + const element = await driver.findElement(By.css('#myModal > div > div > div.modal-body > table > thead > tr > th:nth-child(1)')); //Get text, font, size, and color @@ -4331,6 +4474,7 @@ const steps = [ description: 'Validate DIV - More Info Alabama Adopted column title text, color, and size', action: async () => { const multipleChecks = 'DIV - Alabama Courses of Study Adopted column title'; + const element = await driver.findElement(By.css('#myModal > div > div > div.modal-body > table > thead > tr > th:nth-child(2)')); //Get text, font, size, and color @@ -4388,6 +4532,7 @@ const steps = [ description: 'Validate DIV - More Info Alabama Grades column title text, color, and size', action: async () => { const multipleChecks = 'DIV - Alabama Courses of Study Grades column title'; + const element = await driver.findElement(By.css('#myModal > div > div > div.modal-body > table > thead > tr > th:nth-child(3)')); //Get text, font, size, and color @@ -5712,6 +5857,7 @@ const steps = [ description: 'Validate Content tab title text, size, and color', action: async () => { const multipleChecks = 'Content tab title'; + const element = await driver.findElement(By.linkText('Content')); //Get text, font, size, and color @@ -5777,6 +5923,7 @@ const steps = [ description: 'Validate Standards tab title text, size, and color', action: async () => { const multipleChecks = 'By Standard tab title'; + const element = await driver.findElement(By.linkText('Standards')); //Get text, font, size, and color @@ -5842,6 +5989,7 @@ const steps = [ description: 'Validate AutoAlign tab title text, size, and color', action: async () => { const multipleChecks = 'AutoAlign tab title'; + const element = await driver.findElement(By.linkText('AutoAlign')); //Get text, font, size, and color @@ -5865,7 +6013,7 @@ const steps = [ if (elementTextFont === 'Poppins, sans-serif') { console.log('Passed: AutoAlign tab title font-family matched as expected'); } else { - errors.push(`Expected: AutoAlign tab title font-family "DM Serif Display, serif"; Actual: ${elementTextFont}`); + errors.push(`Expected: AutoAlign tab title font-family "Poppins, sans-serif"; Actual: ${elementTextFont}`); } //size @@ -5907,6 +6055,7 @@ const steps = [ description: 'Validate Browse - Browse standards sub-title text, color, and size', action: async () => { const multipleChecks = 'Browse sub-title'; + const element = await driver.findElement(By.css('#std .fom-title')); //Get text, font, size, and color @@ -5929,7 +6078,7 @@ const steps = [ if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Browse page - Browse standards sub-title font-family matched as expected'); } else { - errors.push(`Expected: Browse page - Browse standards sub-title font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + errors.push(`Expected: Browse page - Browse standards sub-title font-family "Poppins, sans-serif"; Actual: ${elementFont}`); } //size @@ -5964,6 +6113,7 @@ const steps = [ description: 'Validate Standards label text, font, size, and color', action: async () => { const multipleChecks = 'Standards label'; + const element = await driver.findElement(By.css('#browse-standards > .form-group:nth-child(1) > .col-sm-12')); //Get text, font, size, and color @@ -5986,7 +6136,7 @@ const steps = [ if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Standards label font-family matched as expected'); } else { - errors.push(`Expected: Standards label font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + errors.push(`Expected: Standards label font-family "Poppins, sans-serif"; Actual: ${elementFont}`); } //size @@ -6021,6 +6171,7 @@ const steps = [ description: 'Validate Standards dropdown list and value', action: async () => { const multipleChecks = 'Standards Dropdown List'; + const select = await driver.findElement(By.css('#stdselect')); //Get text, font, size, and color @@ -6041,7 +6192,7 @@ const steps = [ if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Alabama default text font-family matched as expected'); } else { - errors.push(`Expected: Alabama default text font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + errors.push(`Expected: Alabama default text font-family "Poppins, sans-serif"; Actual: ${elementFont}`); } //size @@ -6125,6 +6276,7 @@ const steps = [ description: 'Validate Standards Display label text, font, size, and color', action: async () => { const multipleChecks = 'Standards Display label'; + const element = await driver.findElement(By.css('.form-group:nth-child(2) > .col-sm-2')); //Get text, font, size, and color @@ -6147,7 +6299,7 @@ const steps = [ if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Standards Display label font-family matched as expected'); } else { - errors.push(`Expected: Standards Display label font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + errors.push(`Expected: Standards Display label font-family "Poppins, sans-serif"; Actual: ${elementFont}`); } //size @@ -6182,6 +6334,7 @@ const steps = [ description: 'Validate All radio option text, font, size, and color', action: async () => { const multipleChecks = 'All radio option'; + const elementOption = await driver.findElement(By.css('#gap1')).getAttribute('checked'); const element = await driver.findElement(By.css('.form-check:nth-child(1) > .form-check-label')); @@ -6212,7 +6365,7 @@ const steps = [ if (elementTextFont === 'Poppins, sans-serif') { console.log('Passed: All radio label font matched as expected'); } else { - errors.push(`Expected: All radio label font "DM Serif Display, serif"; Actual: ${elementTextFont}`); + errors.push(`Expected: All radio label font "Poppins, sans-serif"; Actual: ${elementTextFont}`); } //font size @@ -6247,6 +6400,7 @@ const steps = [ description: 'Validate Correlated Only radio option text, font, size, and color', action: async () => { const multipleChecks = 'Correlated Only radio option'; + const elementOption = await driver.findElement(By.css('#gap2')); const element = await driver.findElement(By.css('.form-check:nth-child(2) > .form-check-label')); @@ -6277,7 +6431,7 @@ const steps = [ if (elementTextFont === 'Poppins, sans-serif') { console.log('Passed: Correlated Only radio label font matched as expected'); } else { - errors.push(`Expected: Correlated Only radio label font "DM Serif Display, serif"; Actual: ${elementTextFont}`); + errors.push(`Expected: Correlated Only radio label font "Poppins, sans-serif"; Actual: ${elementTextFont}`); } //font size @@ -6312,6 +6466,7 @@ const steps = [ description: 'Validate Uncorrelated Only radio option text, font, size, and color', action: async () => { const multipleChecks = 'Uncorrelated Only radio option'; + const elementOption = await driver.findElement(By.css('#gap3')); const element = await driver.findElement(By.css('.form-check:nth-child(3) > .form-check-label')); @@ -6342,7 +6497,7 @@ const steps = [ if (elementTextFont === 'Poppins, sans-serif') { console.log('Passed: Uncorrelated Only radio label font matched as expected'); } else { - errors.push(`Expected: Uncorrelated Only radio label font "DM Serif Display, serif"; Actual: ${elementTextFont}`); + errors.push(`Expected: Uncorrelated Only radio label font "Poppins, sans-serif"; Actual: ${elementTextFont}`); } //font size @@ -6377,6 +6532,7 @@ const steps = [ description: 'Validate Subject label text, font, size, and color', action: async () => { const multipleChecks = 'Subject label'; + const element = await driver.findElement(By.css('.hideSubject > .col-form-label')); //Get text, font, size, and color @@ -6399,7 +6555,7 @@ const steps = [ if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Subject label font-family matched as expected'); } else { - errors.push(`Expected: Subject label font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + errors.push(`Expected: Subject label font-family "Poppins, sans-serif"; Actual: ${elementFont}`); } //size @@ -6434,6 +6590,7 @@ const steps = [ description: 'Validate Subject dropdown list and value', action: async () => { const multipleChecks = 'Subject Dropdown List'; + const select = await driver.findElement(By.css('#selectSubjects')); //Get text, font, size, and color @@ -6454,7 +6611,7 @@ const steps = [ if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Select a subject default text font-family matched as expected'); } else { - errors.push(`Expected: Select a subject default text font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + errors.push(`Expected: Select a subject default text font-family "Poppins, sans-serif"; Actual: ${elementFont}`); } //size @@ -6515,6 +6672,7 @@ const steps = [ description: 'Validate Grade label and dropdown are hidden', action: async () => { const multipleChecks = 'Grade label and dropdown are hidden'; + const errors = []; const visibility = await driver.executeScript(` @@ -6553,6 +6711,7 @@ const steps = [ description: 'Validate Show Correlations From label text, font, size, and color', action: async () => { const multipleChecks = 'Show Correlations From label'; + const element = await driver.findElement(By.css('.form-group:nth-child(3) > .col-form-label')); //Get text, font, size, and color @@ -6575,7 +6734,7 @@ const steps = [ if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Show Correlations From label font-family matched as expected'); } else { - errors.push(`Expected: Show Correlations From label font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + errors.push(`Expected: Show Correlations From label font-family "Poppins, sans-serif"; Actual: ${elementFont}`); } //size @@ -6612,10 +6771,6 @@ const steps = [ const multipleChecks = 'Show Correlations From dropdown value'; //Locate and validate selected (collapsed) value - const dropdownButton = await driver.findElement( - By.css('button.multiselect.dropdown-toggle') - ); - const selectedOption = await driver.findElement(By.css('#browse-standards > div:nth-child(3) > div > div > div:nth-child(3) > div > div > button > span')); //Get text, font, size, and color @@ -6638,7 +6793,7 @@ const steps = [ if (elementFont === 'Poppins, sans-serif') { console.log('Passed: All Content Sets default text font-family matched as expected'); } else { - errors.push(`Expected: All Content Sets default text font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + errors.push(`Expected: All Content Sets default text font-family "Poppins, sans-serif"; Actual: ${elementFont}`); } //size @@ -6673,6 +6828,7 @@ const steps = [ description: 'Validate Term Search label text, font, size, and color', action: async () => { const multipleChecks = 'Term Search label'; + const element = await driver.findElement(By.css('.form-group:nth-child(7) > .col-sm-2')); //Get text, font, size, and color @@ -6695,7 +6851,7 @@ const steps = [ if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Term Search label font-family matched as expected'); } else { - errors.push(`Expected: Term Search label font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + errors.push(`Expected: Term Search label font-family "Poppins, sans-serif"; Actual: ${elementFont}`); } //size @@ -6758,6 +6914,7 @@ const steps = [ description: 'Validate Include Related Standards label text, font, size, and color', action: async () => { const multipleChecks = 'Include Related Standards label'; + const element = await driver.findElement(By.css('.col-sm-offset-2 > label')); //Get text, font, size, and color @@ -6780,7 +6937,7 @@ const steps = [ if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Include Related Standards label font-family matched as expected'); } else { - errors.push(`Expected: Include Related Standards label font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + errors.push(`Expected: Include Related Standards label font-family "Poppins, sans-serif"; Actual: ${elementFont}`); } //size @@ -6815,6 +6972,7 @@ const steps = [ description: 'Validate Search button text, size, and color', action: async () => { const multipleChecks = 'Search button'; + const element = await driver.findElement(By.css('#stdsubmit')); //Get text, font, size, and color @@ -6880,10 +7038,11 @@ const steps = [ description: 'Validate alert message', action: async () => { const multipleChecks = 'Validate alert message'; + const errors = []; - //Click delete button - const element = await driver.findElement(By.css('#stdsubmit')).click(); + //Click Search button + await driver.findElement(By.css('#stdsubmit')).click(); await driver.sleep(5000); console.log('----->| NEXT ACTION: Clicked Search button'); @@ -6960,6 +7119,7 @@ const steps = [ description: 'Validate Grade label text, font, size, and color', action: async () => { const multipleChecks = 'Grade label'; + const element = await driver.findElement(By.css('.hideGrade > .col-form-label')); //Get text, font, size, and color @@ -6982,7 +7142,7 @@ const steps = [ if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Grade label font-family matched as expected'); } else { - errors.push(`Expected: Grade label font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + errors.push(`Expected: Grade label font-family "Poppins, sans-serif"; Actual: ${elementFont}`); } //size @@ -7017,6 +7177,7 @@ const steps = [ description: 'Validate Grade dropdown list and value', action: async () => { const multipleChecks = 'Grade Dropdown List'; + const select = await driver.findElement(By.css('#selectGrade')); //Get text, font, size, and color @@ -7037,7 +7198,7 @@ const steps = [ if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Select a grade default text font-family matched as expected'); } else { - errors.push(`Expected: Select a grade default text font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + errors.push(`Expected: Select a grade default text font-family "Poppins, sans-serif"; Actual: ${elementFont}`); } //size @@ -7105,10 +7266,11 @@ const steps = [ description: 'Validate alert message', action: async () => { const multipleChecks = 'Validate alert message'; + const errors = []; - //Click delete button - const element = await driver.findElement(By.css('#stdsubmit')).click(); + //Click Search button + await driver.findElement(By.css('#stdsubmit')).click(); await driver.sleep(5000); console.log('----->| NEXT ACTION: Clicked Search button'); @@ -7162,11 +7324,10 @@ const steps = [ action: async () => { const multipleChecks = 'Show Correlations From dropdown list'; - //Locate and validate selected (collapsed) value - const dropdownButton = await driver.findElement( - By.css('button.multiselect.dropdown-toggle') - ); + //Track all errors + const errors = []; + //Locate and validate selected (collapsed) value const selectedOption = await driver.findElement(By.css('#browse-standards > div:nth-child(3) > div > div > div:nth-child(3) > div > div > button > span')); //Get text, font, size, and color @@ -7186,7 +7347,7 @@ const steps = [ if (elementFont === 'Poppins, sans-serif') { console.log('Passed: All Content Sets default text font-family matched as expected'); } else { - errors.push(`Expected: All Content Sets default text font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + errors.push(`Expected: All Content Sets default text font-family "Poppins, sans-serif"; Actual: ${elementFont}`); } //size @@ -7260,9 +7421,6 @@ const steps = [ 'create import test' ]; - //Track all errors - const errors = []; - //Length validation if (actualOptions.length !== expectedOptions.length) { errors.push( @@ -7311,6 +7469,7 @@ const steps = [ description: 'Validate Include Related Standards options are hidden', action: async () => { const multipleChecks = 'Include Related Standards labels and dropdowns are hidden'; + const errors = []; const visibility = await driver.executeScript(` @@ -7371,10 +7530,11 @@ const steps = [ description: 'Validate alert message', action: async () => { const multipleChecks = 'Validate alert message'; + const errors = []; - //Click delete button - const element = await driver.findElement(By.css('#stdsubmit')).click(); + //Click Search button + await driver.findElement(By.css('#stdsubmit')).click(); await driver.sleep(5000); console.log('----->| NEXT ACTION: Clicked Search button'); @@ -7445,7 +7605,7 @@ const steps = [ if (elementFont === 'Poppins, sans-serif') { console.log('Passed: None Selected default text font-family matched as expected'); } else { - errors.push(`Expected: None Selected default text font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + errors.push(`Expected: None Selected default text font-family "Poppins, sans-serif"; Actual: ${elementFont}`); } //size @@ -7574,6 +7734,7 @@ const steps = [ description: 'Validate Show Correlations From dropdown value', action: async () => { const multipleChecks = 'Show Correlations From dropdown value'; + const selectedOption = await driver.findElement(By.css('.col-auto .multiselect-selected-text')); //Get text, font, size, and color @@ -7596,7 +7757,7 @@ const steps = [ if (elementFont === 'Poppins, sans-serif') { console.log('Passed: Selected Content Sets dropdown text font-family matched as expected'); } else { - errors.push(`Expected: Selected Content Sets dropdown text font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + errors.push(`Expected: Selected Content Sets dropdown text font-family "Poppins, sans-serif"; Actual: ${elementFont}`); } //size @@ -7631,6 +7792,7 @@ const steps = [ description: 'Validate based on label text, font, size, and color', action: async () => { const multipleChecks = 'based on label'; + const element = await driver.findElement(By.css('.col-auto:nth-child(2)')); //Get text, font, size, and color @@ -7653,7 +7815,7 @@ const steps = [ if (elementFont === 'Poppins, sans-serif') { console.log('Passed: based on label font-family matched as expected'); } else { - errors.push(`Expected: based on label font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + errors.push(`Expected: based on label font-family "Poppins, sans-serif"; Actual: ${elementFont}`); } //size @@ -7688,6 +7850,7 @@ const steps = [ description: 'Validate best match dropdown list and value', action: async () => { const multipleChecks = 'best match Dropdown List'; + const select = await driver.findElement(By.css('.custom-select')); //Get text, font, size, and color @@ -7708,7 +7871,7 @@ const steps = [ if (elementFont === 'Poppins, sans-serif') { console.log('Passed: best match default text font-family matched as expected'); } else { - errors.push(`Expected: best match default text font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + errors.push(`Expected: best match default text font-family "Poppins, sans-serif"; Actual: ${elementFont}`); } //size @@ -7765,6 +7928,7 @@ const steps = [ description: 'Validate info icon', action: async () => { const multipleChecks = 'info icon'; + const errors = []; //Get both text and styles in one executeScript call @@ -7832,6 +7996,7 @@ const steps = [ description: 'Validate note text, font, size, and color', action: async () => { const multipleChecks = 'note label'; + const element = await driver.findElement(By.css('em')); //Get text, font, size, and color @@ -7854,7 +8019,7 @@ const steps = [ if (elementFont === 'Poppins, sans-serif') { console.log('Passed: ** note text font-family matched as expected'); } else { - errors.push(`Expected: ** note text font-family "DM Serif Display, serif"; Actual: ${elementFont}`); + errors.push(`Expected: ** note text font-family "Poppins, sans-serif"; Actual: ${elementFont}`); } //size @@ -7926,7 +8091,7 @@ const logStep = (worksheet, stepDescription, status, stepIndex, timestamp, scree const takeScreenshot = async (driver, stepIndex, stepDescription) => { const screenshot = await driver.takeScreenshot(); - const dir = path.join('screenshots', 'dashboardMyStandardsResults'); + const dir = path.join('screenshots', 'myStandardsWidget'); const screenshotFileName = `step_${stepIndex}_${stepDescription.replace(/\s+/g, '_')}.png`; const screenshotPath = path.join(dir, screenshotFileName); @@ -7934,11 +8099,11 @@ const takeScreenshot = async (driver, stepIndex, stepDescription) => { return screenshotPath; }; -const resultsFile = path.join('results', 'dashboardMyStandards.xlsx'); +const resultsFile = path.join('results', 'myStandardsWidget.xlsx'); const clearOldResults = () => { //Remove old screenshots - const screenshotDir = path.join('screenshots', 'dashboardMyStandards'); + const screenshotDir = path.join('screenshots', 'myStandardsWidget'); if (fs.existsSync(screenshotDir)) { fs.rmSync(screenshotDir, { recursive: true, force: true }); } @@ -8011,11 +8176,11 @@ try { if (allStepsPassed) { console.log('------------->| THE END |<-------------'); - console.log('PASSED: DASHBOARD - My Standards Widget(dashboardMyStandards); All test steps completed successfully'); + console.log('PASSED: DASHBOARD - My Standards Widget(myStandardsWidget); All test steps completed successfully'); testStatus = 'Passed'; } else { console.log('------------->| THE END |<-------------'); - console.log('FAILED: DASHBOARD - My Standards Widget(dashboardMyStandards); One or more test steps failed'); + console.log('FAILED: DASHBOARD - My Standards Widget(myStandardsWidget); One or more test steps failed'); console.log('FAILED STEPS:'); failedSteps.forEach(step => console.error(` ✗ ${step}`)); testStatus = 'Failed'; @@ -8034,4 +8199,4 @@ try { })(); } -export default dashboardMyStandards; +export default myStandardsWidget; diff --git a/tests/myStandardsSearchAlignedContent.js b/tests/myStandardsSearchAlignedContent.js index 8939882..dcb70fb 100644 --- a/tests/myStandardsSearchAlignedContent.js +++ b/tests/myStandardsSearchAlignedContent.js @@ -8306,7 +8306,7 @@ const myStandardsSearch = (req, res) => { const takeScreenshot = async (driver, stepIndex, stepDescription) => { const screenshot = await driver.takeScreenshot(); - const dir = path.join('screenshots', 'myStandardsSearchAlignedContentResults'); + const dir = path.join('screenshots', 'myStandardsSearchAlignedContent'); const screenshotFileName = `step_${stepIndex}_${stepDescription.replace(/\s+/g, '_')}.png`; const screenshotPath = path.join(dir, screenshotFileName);