From c54ea37907cfae7048821ba9b0c1bbdd90885874 Mon Sep 17 00:00:00 2001 From: jhuerta Date: Fri, 4 Oct 2024 15:41:21 -0700 Subject: [PATCH] Completed landing page script --- landingPageResults.xlsx | Bin 26797544 -> 3597590 bytes tests/ExACT_landingPage.js | 400 +++++++++++++++++++++++++++++++------ 2 files changed, 334 insertions(+), 66 deletions(-) diff --git a/landingPageResults.xlsx b/landingPageResults.xlsx index 8c94f34c67048b3d22386d1070a15357f6fa2256..ed4d70e52c52a284e33d5bbf11f148ce8cd306f1 100644 GIT binary patch delta 96055 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 BtZ)DT delta 19092 zcmeHP&ubGw6yCI9dvMZ35NWB6scmy;tuzKltcC8`n+NgO{R0#{dJqgKiQs}4aeMT( znnUpyT@UJ2R8&wYN)K5~1U-21s268zS!cF98Jo?f4_+Zc7DRj zYxIcv{?QC6&>F*H<5r|^J}T|hW(`|nV`%h%L~PG;Fk8RG#%eKds8y{QRA46cP*vHG z6Qv%Ii10I^Q z=4WVuNoz2AHZ)1}AR$NIdBJn3G5e5+PGm)g95zA7={<5(SitB67P<&+(m!+0I-1$ETcn|UO`1b4~_%mPY``(igS8APdm zr#Aqqf>KnCZylh`k<fgVM*LH-zjJx+tu5VCOeAQ z&!`V&Zj)7~+)ItoL;ktO==-ZU07KLjiBgtw@*#p#jMLYvB#)T}M+B#B)K7xRHkX7P zL?SpT1mWJGiB*3InOq8BMT+6F9elPpLNOJR9^dA)lG3al43OAYu*? zoKlE6>JpOHwAx^+RY?w9QBZ@_S5?~G`qku;s6$G&K<2_vuBz(JdWt^c>VpVQ@R{Ww z@Fap$zg`gWT10SC-<*>IYLelxWfH+j^=FS9O$4X@UD*Xha7rbZ5Wz`$Il4!2ga}Uk ziz5vpIHeLt8V(VhQrVPXrza4>N%L|BI^;@83KFrAzbcc+MLFag$$#pC?efwJ&DTQM zBM1?k(ug2LaO&Hp)fWV(%Oizn=FP`zcMT)_j2MRDuD1Ay`{g5FaIa5SR|hM+;xCq~ z%Xi!tulcFX>i#$U`99?*pxket`RRd`jJw$8^wTY+A@{4sfH*XR { let worksheet; const startTime = new Date().toISOString(); -//Text to be verified +//Left Panel: +//Title const expectedTitleText = 'Empowering publishers with the ability to correlate their unique content to standards.'; + const expectedTitleFont = '32px'; +//Description const expectedDescriptiveText1 = 'The ExACT platform is the education industry’s most trusted source to globally correlate content to standards and produce content alignment reports.'; const expectedDescriptiveText2 = 'With access to over five million learning outcomes, ExACT’s robust toolset allows end users to discover new markets for their content, find gaps, and adjust alignments for specific opportunities.'; +//Sign Up const expectedSignUpText = 'Sign Up For A 30 Day Free Trial'; - const expectedFreeTrialLink = '30 Day Free Trial'; -const expectedBulletPoint1 = 'Learn more about ExACT AutoAlign, the AI-based alignment tool.'; - const expectedBulletPointLink1 = 'ExACT AutoAlign,'; -const expectedBulletPoint2 = 'See your Correlation Analytics.'; - const expectedBulletPointLink2 = 'Correlation Analytics.'; -const expectedBulletPoint3 = 'Explore how your Content maps to International Standards.'; - const expectedBulletPointLink3 = 'International Standards.'; + const expectedFreeTrialLinkColor = 'rgba(255, 111, 97, 1)'; //Red/Orange +//Bullet Points +const expectedBulletPointText1 = 'Learn more about ExACT AutoAlign, the AI-based alignment tool.'; + const expectedBulletPointLinkColor1 = 'rgba(48, 200, 172, 1)'; //teal +const expectedBulletPointText2 = 'See your Correlation Analytics.'; + const expectedBulletPointLinkColor2 = 'rgba(48, 200, 172, 1)'; //teal +const expectedBulletPointText3 = 'Explore how your Content maps to International Standards.'; + const expectedBulletPointLinkColor3 = 'rgba(48, 200, 172, 1)'; //teal + +//Right Panel: +//Welcome back +const expectedWelcomeBackText = 'WELCOME BACK!'; + const expectedWelcomeBackColor = 'rgba(117, 117, 117, 1)' //gray +//Login +const expectedLoginTitleText = 'Login to your account'; + const expectedLoginTitleColor = 'rgba(40, 39, 90, 1)'; //navy blue + const expectedLoginTitleFont = '32px'; +//Username +const expectedUsernameLabel = 'Username'; + const expectedUsernameColor = 'rgba(40, 39, 90, 1)'; //navy blue + const expectedUsernamePlaceholder = 'Username'; +//Password +const expectedPasswordLabel = 'Password'; + const expectedPasswordColor = 'rgba(40, 39, 90, 1)'; //navy blue + const expectedPasswordPlaceholder = 'Password'; +//Forgot password link +const expectedForgotPasswordLinkColor = 'rgba(40, 39, 90, 1)'; //navy blue +//Login button +const expectedLoginButtonText = 'Login'; + const expectedLoginButtonColor = 'rgba(48, 200, 172, 1)'; //teal +//Don't have account text +const expectedDontHaveAccountText = `DON'T HAVE AN ACCOUNT?`; +//Free trial button +const expectedFreeTrialButtonText = '30 Day'; + const expectedFreeTrialButtonColor = 'rgba(0, 0, 0, 0)'; //white const steps = [ { description: 'Navigate to ExACT Landing Page', action: async () => await driver.navigate().to('https://stage.edgate.com/exact/login.php') }, //PROD - https://correlation.edgate.com/exact/login.php { description: 'Expand browser', action: async () => await driver.manage().window().maximize() }, + //LEFT PANEL //Title text { description: 'Wait for title text to be present', action: async () => await driver.wait(until.elementLocated(By.css('h2:nth-child(1)')), 5000) }, { description: 'Validate title text', action: async () => { const elementText = await driver.findElement(By.css('h2:nth-child(1)')).getText(); if (elementText === expectedTitleText) - {console.log('Passed: Title matched as expected');} + {console.log('Passed: Title text matched as expected');} else - {console.log(`FAILED: Expected: "${expectedTitleText}", but found "${elementText}"`);} + {console.log(`FAILED: Expected: "${expectedTitleText}"; Actual: "${elementText}"`);} + } + }, + + //Title text font + { description: 'Validate Title text font size', action: async () => + { const elementStyle = await driver.findElement(By.css('h2:nth-child(3)')).getCssValue('font-size'); + if (elementStyle === expectedTitleFont) + {console.log('Passed: Title text font-size matched as expected');} + else + {console.log(`FAILED: Title text font-size Expected: "${expectedTitleFont}"; Actual: "${elementStyle}"`);} } }, @@ -47,7 +90,7 @@ const steps = [ if (elementText === expectedDescriptiveText1) {console.log('Passed: Descriptive text 1 matched as expected');} else - {console.log(`FAILED: Expected: "${expectedDescriptiveText1}", but found "${elementText}"`);} + {console.log(`FAILED: Expected: "${expectedDescriptiveText1}"; Actual: "${elementText}"`);} } }, @@ -57,7 +100,7 @@ const steps = [ if (elementText === expectedDescriptiveText2) {console.log('Passed: Descriptive text 2 matched as expected');} else - {console.log(`FAILED: Expected: "${expectedDescriptiveText2}", but found "${elementText}"`);} + {console.log(`FAILED: Expected: "${expectedDescriptiveText2}"; Actual: "${elementText}"`);} } }, @@ -67,80 +110,314 @@ const steps = [ if (elementText === expectedSignUpText) {console.log('Passed: Sign up text matched as expected');} else - {console.log(`FAILED: Expected: "${expectedSignUpText}", but found "${elementText}"`);} + {console.log(`FAILED: Expected: "${expectedSignUpText}"; Actual: "${elementText}"`);} } }, - //Free trial link - { description: 'Validate free trial link', action: async () => - { const elementText = await driver.findElement(By.linkText('30 Day Free Trial')).getText(); - if (elementText === expectedFreeTrialLink) - {console.log('Passed: Free trial link matched as expected');} + //Free trial link text color + { description: 'Validate free trial link color', action: async () => + { const elementStyle = await driver.findElement(By.linkText('30 Day Free Trial')).getCssValue('color'); + if (elementStyle === expectedFreeTrialLinkColor) + {console.log('Passed: Free trial link text color matched as expected');} else - {console.log(`FAILED: Expected: "${expectedFreeTrialLink}", but found "${elementText}"`);} + {console.log(`FAILED: Free trial link text color Expected: "${expectedFreeTrialLinkColor}"; Actual: "${elementStyle}"`);} } }, - //Bullet Point 1 - { description: 'Validate bullet point 1', action: async () => + //Bullet Point Icon 1 + { description: 'Verify bullet point icon 1 is present', action: async () => + { const expectedbulletPointIcon = await driver.wait(until.elementLocated(By.css('li:nth-child(1) img')), 5000).catch(() => false); + if (expectedbulletPointIcon) + {console.log('Passed: Bullet Point Icon 1 present');} + else + {console.log('FAILED: Bullet Point Icon 1 not found');} + } + }, + + //Bullet Point 1 text + { description: 'Validate bullet point 1 text', action: async () => { const elementText = await driver.findElement(By.css('li:nth-child(1) > .list-flex')).getText(); - if (elementText === expectedBulletPoint1) - {console.log('Passed: Bullet point 1 matched as expected');} + if (elementText === expectedBulletPointText1) + {console.log('Passed: Bullet point 1 text matched as expected');} else - {console.log(`FAILED: Expected: "${expectedBulletPoint1}", but found "${elementText}"`);} + {console.log(`FAILED: Expected: "${expectedBulletPointText1}"; Actual: "${elementText}"`);} } }, - //Bullet Point link 1 - { description: 'Validate bullet point link 1', action: async () => - { const elementText = await driver.findElement(By.linkText('ExACT AutoAlign,')).getText(); - if (elementText === expectedBulletPointLink1) - {console.log('Passed: Bullet pont link 1 matched as expected');} + //Bullet Point link 1 text color + { description: 'Validate bullet point link 1 text color', action: async () => + { const elementStyle = await driver.findElement(By.linkText('ExACT AutoAlign,')).getCssValue('color'); + if (elementStyle === expectedBulletPointLinkColor1) + {console.log('Passed: Bullet point link 1 text color matched as expected');} else - {console.log(`FAILED: Expected: "${expectedBulletPointLink1}", but found "${elementText}"`);} + {console.log(`FAILED: Bullet point link 1 text color Expected: "${expectedBulletPointLinkColor1}"; Actual: "${elementStyle}"`);} } }, - //Bullet Point 2 - { description: 'Validate bullet point 2', action: async () => + //Bullet Point Icon 2 + { description: 'Verify bullet point icon 2 is present', action: async () => + { const expectedbulletPointIcon = await driver.wait(until.elementLocated(By.css('li:nth-child(2) img')), 5000).catch(() => false); + if (expectedbulletPointIcon) + {console.log('Passed: Bullet Point Icon 2 present');} + else + {console.log('FAILED: Bullet Point Icon 2 not found');} + } + }, + + //Bullet Point 2 text + { description: 'Validate bullet point 2 text', action: async () => { const elementText = await driver.findElement(By.css('li:nth-child(2) > .list-flex')).getText(); - if (elementText === expectedBulletPoint2) - {console.log('Passed: Bullet point 2 matched as expected');} + if (elementText === expectedBulletPointText2) + {console.log('Passed: Bullet point 2 text matched as expected');} else - {console.log(`FAILED: Expected: "${expectedBulletPoint2}", but found "${elementText}"`);} + {console.log(`FAILED: Expected: "${expectedBulletPointText2}"; Actual: "${elementText}"`);} } }, - //Bullet Point link 2 - { description: 'Validate bullet point link 2', action: async () => - { const elementText = await driver.findElement(By.linkText('Correlation Analytics.')).getText(); - if (elementText === expectedBulletPointLink2) - {console.log('Passed: Bullet pont link 2 matched as expected');} + //Bullet Point link 2 text color + { description: 'Validate bullet point link 2 text color', action: async () => + { const elementStyle = await driver.findElement(By.linkText('Correlation Analytics.')).getCssValue('color'); + if (elementStyle === expectedBulletPointLinkColor2) + {console.log('Passed: Bullet point link 2 text color matched as expected');} else - {console.log(`FAILED: Expected: "${expectedBulletPointLink2}", but found "${elementText}"`);} + {console.log(`FAILED: Bullet point link 2 text color Expected: "${expectedBulletPointLinkColor2}"; Actual: "${elementStyle}"`);} } }, - //Bullet Point 3 - { description: 'Validate bullet point 3', action: async () => + //Bullet Point Icon 3 + { description: 'Verify bullet point icon 3 is present', action: async () => + { const expectedbulletPointIcon = await driver.wait(until.elementLocated(By.css('li:nth-child(3) img')), 5000).catch(() => false); + if (expectedbulletPointIcon) + {console.log('Passed: Bullet Point Icon 3 present');} + else + {console.log('FAILED: Bullet Point Icon 3 not found');} + } + }, + + //Bullet Point 3 text + { description: 'Validate bullet point 3 text', action: async () => { const elementText = await driver.findElement(By.css('li:nth-child(3) > .list-flex')).getText(); - if (elementText === expectedBulletPoint3) - {console.log('Passed: Bullet point 3 matched as expected');} + if (elementText === expectedBulletPointText3) + {console.log('Passed: Bullet point 3 text matched as expected');} else - {console.log(`FAILED: Expected: "${expectedBulletPoint3}", but found "${elementText}"`);} + {console.log(`FAILED: Expected: "${expectedBulletPointText3}"; Actual: "${elementText}"`);} } }, - //Bullet Point link 3 - { description: 'Validate bullet point link 3', action: async () => - { const elementText = await driver.findElement(By.linkText('International Standards.')).getText(); - if (elementText === expectedBulletPointLink3) - {console.log('Passed: Bullet pont link 3 matched as expected');} + //Bullet Point link 3 text color + { description: 'Validate bullet point link 3 text color', action: async () => + { const elementStyle = await driver.findElement(By.linkText('International Standards.')).getCssValue('color'); + if (elementStyle === expectedBulletPointLinkColor3) + {console.log('Passed: Bullet point link 3 text color matched as expected');} else - {console.log(`FAILED: Expected: "${expectedBulletPointLink3}", but found "${elementText}"`);} + {console.log(`FAILED: Bullet point link 3 text color Expected: "${expectedBulletPointLinkColor3}"; Actual: "${elementStyle}"`);} } }, + //RIGHT PANEL + //ExACT logo + { description: 'Verify ExACT logo is present', action: async () => + { const expectedExactLogo = await driver.wait(until.elementLocated(By.css('.logo')), 5000).catch(() => false); + if (expectedExactLogo) + {console.log('Passed: ExACT logo present');} + else + {console.log('FAILED: ExACT logo not found');} + } + }, + + //Welcome back text + { description: 'Validate Welcome back text', action: async () => + { const elementText = await driver.findElement(By.css('#formLogin > p')).getText(); + if (elementText === expectedWelcomeBackText) + {console.log('Passed: Welcome Back! text matched as expected');} + else + {console.log(`FAILED: Expected: "${expectedWelcomeBackText}"; Actual: "${elementText}"`);} + } + }, + + //Welcome back text color + { description: 'Validate Welcome back text color', action: async () => + { const elementStyle = await driver.findElement(By.css('#formLogin > p')).getCssValue('color'); + if (elementStyle === expectedWelcomeBackColor) + {console.log('Passed: Welcome back text color matched as expected');} + else + {console.log(`FAILED: Welcome back text color Expected: "${expectedWelcomeBackColor}"; Actual: "${elementStyle}"`);} + } + }, + + //Welcome back icon + { description: 'Verify Welcome back icon is present', action: async () => + { const expectedWelcomeBackIcon = await driver.wait(until.elementLocated(By.css('p > img')), 5000).catch(() => false); + if (expectedWelcomeBackIcon) + {console.log('Passed: Welcome back icon present');} + else + {console.log('FAILED: Welcome back icon not found');} + } + }, + + //Login title text + { description: 'Validate Login title text', action: async () => + { const elementText = await driver.findElement(By.css('h2:nth-child(3)')).getText(); + if (elementText === expectedLoginTitleText) + {console.log('Passed: Login title text matched as expected');} + else + {console.log(`FAILED: Expected: "${expectedLoginTitleText}"; Actual: "${elementText}"`);} + } + }, + + //Login title text color + { description: 'Validate Login title text color', action: async () => + { const elementStyle = await driver.findElement(By.css('h2:nth-child(3)')).getCssValue('color'); + if (elementStyle === expectedLoginTitleColor) + {console.log('Passed: Login title text color matched as expected');} + else + {console.log(`FAILED: Login title text color Expected: "${expectedLoginTitleColor}"; Actual: "${elementStyle}"`);} + } + }, + + //Login title text font + { description: 'Validate Login title text font size', action: async () => + { const elementStyle = await driver.findElement(By.css('h2:nth-child(3)')).getCssValue('font-size'); + if (elementStyle === expectedLoginTitleFont) + {console.log('Passed: Login title text font-size matched as expected');} + else + {console.log(`FAILED: Login title text font-size Expected: "${expectedLoginTitleFont}"; Actual: "${elementStyle}"`);} + } + }, + + //Username label text + { description: 'Validate Username label text', action: async () => + { const elementText = await driver.findElement(By.css('.form-group:nth-child(4) > label')).getText(); + if (elementText === expectedUsernameLabel) + {console.log('Passed: Username label text matched as expected');} + else + {console.log(`FAILED: Expected: "${expectedUsernameLabel}"; Actual: "${elementText}"`);} + } + }, + + //Username label text color + { description: 'Validate Username label text color', action: async () => + { const elementStyle = await driver.findElement(By.css('.form-group:nth-child(4) > label')).getCssValue('color'); + if (elementStyle === expectedUsernameColor) + {console.log('Passed: Username label text color matched as expected');} + else + {console.log(`FAILED: Username label text color Expected: "${expectedUsernameColor}"; Actual: "${elementStyle}"`);} + } + }, + + //Username textbox placeholder + { description: 'Validate Username placeholder text', action: async () => + { const elementValue = await driver.findElement(By.css('.form-control:nth-child(2)')).getAttribute('placeholder'); + if (elementValue === expectedUsernamePlaceholder) + {console.log('Passed: Username placeholder text matched as expected');} + else + {console.log(`FAILED: Username placeholder text Expected: "${expectedUsernamePlaceholder}"; Actual: "${elementValue}"`);} + } + }, + + //Password label text + { description: 'Validate Password label text', action: async () => + { const elementText = await driver.findElement(By.css('.form-group:nth-child(5) > label')).getText(); + if (elementText === expectedPasswordLabel) + {console.log('Passed: Password label text matched as expected');} + else + {console.log(`FAILED: Expected: "${expectedPasswordLabel}"; Actual: "${elementText}"`);} + } + }, + + //Password label text color + { description: 'Validate Password label text color', action: async () => + { const elementStyle = await driver.findElement(By.css('.form-group:nth-child(5) > label')).getCssValue('color'); + if (elementStyle === expectedPasswordColor) + {console.log('Passed: Password label text color matched as expected');} + else + {console.log(`FAILED: Password label text color Expected: "${expectedPasswordColor}"; Actual: "${elementStyle}"`);} + } + }, + + //Password textbox placeholder + { description: 'Validate Password placeholder text', action: async () => + { const elementValue = await driver.findElement(By.css('.passfield')).getAttribute('placeholder'); + if (elementValue === expectedPasswordPlaceholder) + {console.log('Passed: Password placeholder text matched as expected');} + else + {console.log(`FAILED: Password placeholder text Expected: "${expectedPasswordPlaceholder}"; Actual: "${elementValue}"`);} + } + }, + + //Forgot password text link color + { description: 'Validate Forgot Password link text color', action: async () => + { const elementStyle = await driver.findElement(By.linkText('Forgot Password?')).getCssValue('color'); + if (elementStyle === expectedForgotPasswordLinkColor) + {console.log('Passed: Forgot password link text color matched as expected');} + else + {console.log(`FAILED: Forgot password link text color Expected: "${expectedForgotPasswordLinkColor}"; Actual: "${elementStyle}"`);} + } + }, + + //Login button text + { description: 'Validate Login button text', action: async () => + { const elementText = await driver.findElement(By.css('.login')).getAttribute('value'); + if (elementText === expectedLoginButtonText) + {console.log('Passed: Login button text matched as expected');} + else + {console.log(`FAILED: Expected: "${expectedLoginButtonText}"; Actual: "${elementText}"`);} + } + }, + + //Login button background color + { description: 'Validate Login button background color', action: async () => + { const elementStyle = await driver.findElement(By.css('.login')).getCssValue('background-color'); + if (elementStyle === expectedLoginButtonColor) + {console.log('Passed: Login button background color matched as expected');} + else + {console.log(`FAILED: Login button background color Expected: "${expectedLoginButtonColor}"; Actual: "${elementStyle}"`);} + } + }, + + //Don't have an account? text + { description: 'Validate Dont have account text', action: async () => + { const elementText = await driver.findElement(By.css('p:nth-child(1)')).getText(); + if (elementText === expectedDontHaveAccountText) + {console.log('Passed: Dont have an account text matched as expected');} + else + {console.log(`FAILED: Expected: "${expectedDontHaveAccountText}"; Actual: "${elementText}"`);} + } + }, + + //Free trial button text + { description: 'Validate Free trial button text', action: async () => + { const elementText = await driver.findElement(By.css('.btn > span')).getText();//attribute + if (elementText === expectedFreeTrialButtonText) + {console.log('Passed: Free trial button text matched as expected');} + else + {console.log(`FAILED: Expected: "${expectedFreeTrialButtonText}"; Actual: "${elementText}"`);} + } + }, + + //Free trial button background color + { description: 'Validate Free trial button background color', action: async () => + { const elementStyle = await driver.findElement(By.css('.btn > span')).getCssValue('background-color'); + if (elementStyle === expectedFreeTrialButtonColor) + {console.log('Passed: Free trial button background color matched as expected');} + else + {console.log(`FAILED: Free trial button background color Expected: "${expectedFreeTrialButtonColor}"; Actual: "${elementStyle}"`);} + } + }, + + //EdGate copyright image + { description: 'Verify EdGate copyright image is present', action: async () => + { const expectedEdGateCopyright = await driver.wait(until.elementLocated(By.css('.logincopyright > img')), 5000).catch(() => false); + if (expectedEdGateCopyright) + {console.log('Passed: EdGate copyright image present');} + else + {console.log('FAILED: EdGate copyright not found');} + } + }, + + //Validation + { description: 'Click Login button', action: async () => await driver.findElement(By.css('.login')).click() }, + /* { description: 'Enter username', action: async () => await driver.findElement(By.id('txtU')).sendKeys('gnight147', Key.RETURN) }, { description: 'Wait for password field to be present', action: async () => await driver.sleep(3000) }, @@ -201,23 +478,14 @@ try { } } - // Check if landing page test was successful - const loginButton = await driver.wait(until.elementLocated(By.css('.login')), 5000).catch(() => false); + //Check if landing page username validation was successful + const usernameValidation = await driver.wait(until.elementLocated(By.css('.form-group:nth-child(5) > label')), 5000).catch(() => false); - if (loginButton) { - console.log('Login button present'); + if (usernameValidation) { + console.log('Passed: Username validation'); testStatus = 'Passed'; } else { - console.log('Login button not found'); - } - - const freeTialButton = await driver.wait(until.elementLocated(By.css('.btn > span')), 5000).catch(() => false); - - if (freeTialButton) { - console.log('Free Trial button present'); - testStatus = 'Passed'; - } else { - console.log('Free Trial button not found'); + console.log('FAILED: Username validation not triggered'); } // Log test end time