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

Setting up e2e testing with cypress #235

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# env
.env
cypress.env.json

# dependencies
/node_modules
Expand Down
5 changes: 4 additions & 1 deletion components/DropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ const DropdownMenu = ({ session, handleLogin, handleLogout, toggleDropdown }: Pr
);

return (
<div className="absolute right-0 z-10 w-48 py-2 mt-2 text-sm text-gray-700 bg-white border border-gray-200 rounded-lg shadow-xl cursor-pointer dark:bg-gray-800 dark:border-gray-600 dark:text-white">
<div
className="absolute right-0 z-10 w-48 py-2 mt-2 text-sm text-gray-700 bg-white border border-gray-200 rounded-lg shadow-xl cursor-pointer dark:bg-gray-800 dark:border-gray-600 dark:text-white"
data-cy="dropdown-menu"
>
{!session?.user ? (
<>
<ThemeToggle />
Expand Down
7 changes: 6 additions & 1 deletion components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,11 @@ const Navbar = () => {
onClick={() => router.push("https://www.bekk.no/")}
/>
<div className="relative">
<button onClick={toggleDropdown} className="flex justify-end">
<button
onClick={toggleDropdown}
className="flex justify-end"
data-cy="toggle-dropdown"
>
<Bars3Icon
className={`w-10 h-10 text-gray-500 transition-transform transform dark:text-white ${
isDropdownOpen ? "rotate-45 opacity-0" : "rotate-0 opacity-100"
Expand All @@ -142,6 +146,7 @@ const Navbar = () => {
handleLogin={handleLogin}
handleLogout={handleLogout}
toggleDropdown={toggleDropdown}
data-cy="dropdown-menu"
/>
)}
</div>
Expand Down
1 change: 1 addition & 0 deletions components/ThemeToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const ThemeToggle = () => {
<button
className="p-2 transition duration-300 ease-in-out rounded-full group"
onClick={toggleTheme}
data-cy="theme-toggle"
>
{theme === "dark" ? (
<MoonIconSolid className="w-6 h-6 transition-transform duration-300 ease-in-out text-online-orange group-hover:scale-110" />
Expand Down
7 changes: 2 additions & 5 deletions components/form/ApplicationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,14 @@ export const ApplicationForm = (props: Props) => {
props.applicationData.email.includes("ntnu.no")
) {
setIsNtnuEmail(true);
// toast.error(
// "Vi har problemer med å sende e-post til ntnu.no-adresser. Vennligst bruk en annen e-postadresse."
// );
} else {
setIsNtnuEmail(false);
}
}, [props.applicationData.email]);

return (
<div className="flex justify-center items-center">
<form className="px-5 text-online-darkBlue dark:text-white max-w-sm w-full">
<div className="flex items-center justify-center">
<form className="w-full max-w-sm px-5 text-online-darkBlue dark:text-white">
{isNtnuEmail && (
<div className="px-5">
<p className="text-red-500">
Expand Down
18 changes: 18 additions & 0 deletions cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { defineConfig } from "cypress";
require("dotenv").config();

export default defineConfig({
e2e: {
chromeWebSecurity: false,
baseUrl: "http://localhost:3000",
},
env: {
auth0_username: process.env.AUTH0_USERNAME,
auth0_password: process.env.AUTH0_PASSWORD,
auth0_domain: "https://auth.online.ntnu.no",
auth0_audience: process.env.REACT_APP_AUTH0_AUDIENCE,
auth0_scope: process.env.REACT_APP_AUTH0_SCOPE,
auth0_client_id: process.env.REACT_APP_AUTH0_CLIENTID,
auth0_client_secret: process.env.AUTH0_CLIENT_SECRET,
},
});
6 changes: 6 additions & 0 deletions cypress/e2e/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import auth0 from "auth0-js";

export const auth = new auth0.WebAuth({
domain: Cypress.env("auth0Domain"),
clientID: Cypress.env("auth0ClientId"),
});
15 changes: 15 additions & 0 deletions cypress/e2e/login.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
describe("Auth0", function () {
beforeEach(function () {
//cy.task("db:seed");
cy.intercept("POST", "/graphql").as("createBankAccount");
cy.loginToAuth0(
Cypress.env("auth0_username"),
Cypress.env("auth0_password")
);
cy.visit("/");
});

it("shows onboarding", function () {
cy.contains("Get Started").should("be.visible");
});
});
64 changes: 64 additions & 0 deletions cypress/e2e/pre-login.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
describe("Home Page Tests", () => {
beforeEach(() => {
cy.visit("/");
});

it("should display login prompt when user is not logged in", () => {
cy.contains(
"Vennligst logg inn for å få tilgang til opptakssystemet"
).should("exist");
});

it("should display login prompt when user is not logged in on small screens", () => {
cy.viewport("iphone-6");
cy.contains(
"Vennligst logg inn for å få tilgang til opptakssystemet"
).should("exist");
});
});

describe("Navbar Component Tests", () => {
beforeEach(() => {
cy.visit("/");
});

it("should display login button when user is not logged in", () => {
cy.contains("Logg inn").should("exist");
});

it("should toggle dropdown menu on small screens", () => {
cy.viewport("iphone-6");
cy.get('[data-cy="toggle-dropdown"]').click();

cy.get('[data-cy="dropdown-menu"]').should("exist");
cy.get('[data-cy="dropdown-menu"]').should("be.visible");

cy.get('[data-cy="toggle-dropdown"]').click();
cy.get('[data-cy="dropdown-menu"]').should("not.exist");
});
});

describe("Footer Component Tests", () => {
beforeEach(() => {
cy.visit("/");
});

it("should display correct contact information", () => {
cy.contains("Skjedd en feil? Ta kontakt med").should("exist");
cy.contains("Appkom").should(
"have.attr",
"href",
"mailto:[email protected]"
);
});

it("should display correct contact information on small screens", () => {
cy.viewport("iphone-6");
cy.contains("Skjedd en feil? Ta kontakt med").should("exist");
cy.contains("Appkom").should(
"have.attr",
"href",
"mailto:[email protected]"
);
});
});
69 changes: 69 additions & 0 deletions cypress/e2e/theme.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
describe("Theme Toggle Tests", () => {
beforeEach(() => {
cy.visit("http://localhost:3000/");
});

it("should display the initial theme as light or dark based on localStorage", () => {
// Check the localStorage for theme setting
cy.window().then((win) => {
const theme = win.localStorage.getItem("theme");
if (theme === "dark") {
cy.get("html").should("have.class", "dark");
} else {
cy.get("html").should("not.have.class", "dark");
}
});
});

it("should toggle to dark theme and store in localStorage", () => {
cy.get('[data-cy="theme-toggle"]').click();
cy.get("html").should("have.class", "dark");

// Check if localStorage is set to dark
cy.window().then((win) => {
expect(win.localStorage.getItem("theme")).to.equal("dark");
});
});

it("should persist dark theme after page refresh", () => {
cy.get('[data-cy="theme-toggle"]').click();
cy.get("html").should("have.class", "dark");

cy.reload();

// Verify that the theme remains dark
cy.get("html").should("have.class", "dark");
cy.window().then((win) => {
expect(win.localStorage.getItem("theme")).to.equal("dark");
});
});

it("should toggle back to light theme and store in localStorage", () => {
cy.get('[data-cy="theme-toggle"]').click();
cy.get("html").should("have.class", "dark");

cy.get('[data-cy="theme-toggle"]').click();
cy.get("html").should("not.have.class", "dark");

// Check if localStorage is set to light
cy.window().then((win) => {
expect(win.localStorage.getItem("theme")).to.equal("light");
});
});

it("should persist light theme after page refresh", () => {
cy.get('[data-cy="theme-toggle"]').click();
cy.get("html").should("have.class", "dark");

cy.get('[data-cy="theme-toggle"]').click();
cy.get("html").should("not.have.class", "dark");

cy.reload();

// Verify that the theme remains light
cy.get("html").should("not.have.class", "dark");
cy.window().then((win) => {
expect(win.localStorage.getItem("theme")).to.equal("light");
});
});
});
5 changes: 5 additions & 0 deletions cypress/fixtures/example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "[email protected]",
"body": "Fixtures are a great way to mock data for responses to routes"
}
15 changes: 15 additions & 0 deletions cypress/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
declare namespace Cypress {
interface Chainable<Subject = any> {
getUserTokens(credentials?: {
username: string;
password: string;
}): Chainable<any>;
getUserInfo(accessToken: string): Chainable<any>;
login(credentials?: { username: string; password: string }): Chainable<any>;
_setAuth0Cookie(encryptedSession: string): Chainable<any>;
_clearAuth0Cookie(): Chainable<any>;
_clearAuth0SplittedCookies(): Chainable<any>;
clearAuth0Cookies(): Chainable<any>;
loginToAuth0(username: string, password: string): Chainable<any>;
}
}
33 changes: 33 additions & 0 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
function loginViaAuth0Ui(username: string, password: string) {
// App landing page redirects to Auth0.
cy.visit("/");

// Login on Auth0.
cy.origin(
Cypress.env("auth0_domain"),
{ args: { username, password } },
({ username, password }) => {
cy.get("input#username").type(username);
cy.get("input#password").type(password, { log: false });
cy.contains("button[value=default]", "Continue").click();
}
);

// Ensure Auth0 has redirected us back to the RWA.
cy.url().should("equal", "http://localhost:3000/");
}

Cypress.Commands.add("loginToAuth0", (username: string, password: string) => {
const log = Cypress.log({
displayName: "AUTH0 LOGIN",
message: [`🔐 Authenticating | ${username}`],
// @ts-ignore
autoEnd: false,
});
log.snapshot("before");

loginViaAuth0Ui(username, password);

log.snapshot("after");
log.end();
});
20 changes: 20 additions & 0 deletions cypress/support/e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/e2e.ts is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import './commands'

// Alternatively you can use CommonJS syntax:
// require('./commands')
Loading