Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cypress Test for language selection and link redirection #9238

Closed
wants to merge 11 commits into from
46 changes: 46 additions & 0 deletions cypress/e2e/homepage_spec/redirect.cy.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,31 @@
import LoginPage from "../../pageobject/Login/LoginPage";
import * as ta from "../../../public/locale/ta.json";
import * as ml from "../../../public/locale/ml.json";
import * as mr from "../../../public/locale/mr.json";
import * as kn from "../../../public/locale/kn.json";
import * as hi from "../../../public/locale/hi.json";

const locales = { hi, ta, ml, mr, kn };

describe("redirect", () => {
const languageMappings = Object.fromEntries(
Object.entries(locales).map(([langCode, locale]) => [langCode, {
login: locale["login"]
}])
);

const languageSidebars = Object.fromEntries(
Object.entries(locales).map(([langCode, locale]) => [
langCode,
{ care: locale["care"], goal: locale["goal"], footer_body: locale["footer_body"] },
])
);
Comment on lines +17 to +22
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add validation for required sidebar items.

Similar to the login text, the sidebar items should be validated to ensure all required translations exist.

interface SidebarType {
  care: string;
  goal: string;
  footer_body: string;
}

const languageSidebars = Object.fromEntries(
  Object.entries(locales).map(([langCode, locale]) => {
    const required = ['care', 'goal', 'footer_body'];
    const missing = required.filter(key => !locale[key]);
    if (missing.length > 0) {
      throw new Error(`Missing translations for language ${langCode}: ${missing.join(', ')}`);
    }
    return [
      langCode,
      {
        care: locale["care"],
        goal: locale["goal"],
        footer_body: locale["footer_body"]
      }
    ];
  })
);
🧰 Tools
🪛 eslint

[error] 20-20: Replace ·care:·locale["care"],·goal:·locale["goal"],·footer_body:·locale["footer_body"] with ⏎········care:·locale["care"],⏎········goal:·locale["goal"],⏎········footer_body:·locale["footer_body"],⏎·····

(prettier/prettier)


[error] 21-21: Insert ,

(prettier/prettier)


const loginPage = new LoginPage();

beforeEach(() => {
cy.awaitUrl("/", true);
loginPage.ensureLoggedIn();
cy.log("Logging in the user devdistrictadmin");
});

Expand All @@ -28,4 +50,28 @@ describe("redirect", () => {
loginPage.ensureLoggedIn();
cy.url().should("include", "/facility");
});

it("Verify redirection of 'Contribute on GitHub' link", () => {
loginPage.clickContributeOnGitHub();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work unless we disable chromeWebSecurity which is only applicable to Chrome anyways, so just verify the link.

cy.get(loginPage.contributeOnGitHubLink)
      .should("have.attr", "href", "https://github.com/ohcnetwork")
      .and("have.attr", "target", "_blank")
      .and("have.attr", "rel", "noopener noreferrer");

cy.url({ timeout: 10000 }).should("include", "https://github.com/ohcnetwork");
cy.get("body", { timeout: 10000 })
.should("be.visible")
.and("contain", "Contribute on GitHub");
});
Comment on lines +53 to +59
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve GitHub link redirection test robustness

The test could be more specific in its assertions and should use consistent timeout values.

const NETWORK_TIMEOUT = 10000;

it("Verify redirection of 'Contribute on GitHub' link", () => {
  const expectedUrl = "https://github.com/ohcnetwork";
  loginPage.clickContributeOnGitHub();
  cy.url({ timeout: NETWORK_TIMEOUT }).should("eq", expectedUrl);
  cy.get("body", { timeout: NETWORK_TIMEOUT })
    .should("be.visible")
    .find("h1")  // Be more specific about where to find the text
    .should("contain", "Contribute on GitHub");
});


it("Verify redirection of 'Third Party Software License'", () => {
loginPage.clickThirdPartyLicense();
cy.url({ timeout: 10000 }).should("include", "/licenses");
cy.get("body", { timeout: 10000 })
.should("be.visible")
.and("contain", "Third Party Software License");
});

it("Switch languages and verify login button text", () => {
loginPage.switchLanguageAndVerifyButtonText(languageMappings);
});

it("Switch languages and verify sidebar items", () => {
loginPage.switchLanguageAndVerifySidebars(languageSidebars);
});
Comment on lines +73 to +75
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for sidebar verification.

The sidebar verification test should handle cases where elements might not be immediately visible.

it("Switch languages and verify sidebar items", () => {
  cy.log('Starting sidebar verification');
  loginPage.switchLanguageAndVerifySidebars(languageSidebars)
    .catch((error) => {
      cy.log(`Error during sidebar verification: ${error.message}`);
      throw error;
    });
});

});
85 changes: 85 additions & 0 deletions cypress/pageobject/Login/LoginPage.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
import { users } from "../utils/userConfig";

interface LanguageMapping {
[key: string]: {
login: string;
};
}
interface SidebarMapping {
[key: string]: {
care: string;
goal: string;
footer_body: string;
};
}

class LoginPage {
languageSelector = "#language-selector";
submitButtonSelector: string = "#login-button";
sidebarSelectors = {
care: "#care",
goal: "#goal",
footer_body: "#footer_body",
};
contributeOnGitHubLink = 'a[href="https://github.com/ohcnetwork"]';
thirdPartyLicenseLink = 'a[href="/licenses"]';

loginByRole(role: keyof typeof users): void {
const user = users[role];
if (!user) {
Expand Down Expand Up @@ -88,6 +111,68 @@ class LoginPage {
verifyForgotPasswordHeading(text: string[]): void {
cy.verifyContentPresence("#forgot-password-heading", text);
}

clickContributeOnGitHub(): void {
cy.get(this.contributeOnGitHubLink).scrollIntoView().click();
}

clickThirdPartyLicense(): void {
cy.get(this.thirdPartyLicenseLink).scrollIntoView().click();
}

switchLanguage(languageCode: string): void {
cy.get(this.languageSelector).select(languageCode);
}

getSubmitButton() {
return cy.get(this.submitButtonSelector);
}

getSidebarItems() {
return cy.get(`${this.sidebarSelectors.care}, ${this.sidebarSelectors.goal}, ${this.sidebarSelectors.footer_body}`);
}

switchLanguageAndVerifyButtonText(languageMappings: LanguageMapping): void {
Object.entries(languageMappings).forEach(([languageCode, texts]) => {
cy.get(this.languageSelector)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic below suggests you are trying to use language selector on profile page, but here it seems like you are referring to login page 😅

.find(`option[value="${languageCode}"]`)
.should("exist")
.then(($option) => {
if ($option.length === 0) {
throw new Error(`Language option ${languageCode} not found`);
}
this.switchLanguage(languageCode);
cy.get(this.submitButtonSelector, { timeout: 10000 })
.should("be.visible")
.should("have.text", texts.login)
.should("not.be.disabled");
});
});
}

private verifySidebarElement(selector: string, expectedText: string): void {
cy.get(selector, { timeout: 10000 })
.should("be.visible")
.should("have.text", expectedText)
.should("not.be.disabled");
}

switchLanguageAndVerifySidebars(languageMappings: SidebarMapping): void {
Object.entries(languageMappings).forEach(([languageCode, texts]) => {
cy.get(this.languageSelector)
Copy link
Contributor

@Jacobjeevan Jacobjeevan Dec 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So language selector doesn't exist, from this code I assume you are referring to language selector from the profile page, but this test is not being called for a logged in user.

Additionally profile page was just replaced anyways. So you would need add logic for logging in and add the selector Id to the selection dropdown on profile page or rewrite the logic to use the language selection options on the login page.

.find(`option[value="${languageCode}"]`)
.should("exist")
.then(($option) => {
if ($option.length === 0) {
throw new Error(`Language option ${languageCode} not found`);
}
this.switchLanguage(languageCode);
this.verifySidebarElement(this.sidebarSelectors.care, texts.care);
this.verifySidebarElement(this.sidebarSelectors.goal, texts.goal);
this.verifySidebarElement(this.sidebarSelectors.footer_body, texts.footer_body);
});
});
}
}

export default LoginPage;
Loading