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

e2e some tests done, and bug fixed found by testing #169

Merged
merged 1 commit into from
May 31, 2024
Merged
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
2 changes: 1 addition & 1 deletion actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const registerAction = async (formData: FormData) => {
const dbError = e as DatabaseError;

let errorType: DatabaseErrorType;
if (dbError.message === "Email already registered")
if (dbError.message === "Email already registered 23505")
errorType = "UniqueConstraintViolation";
else if (dbError.message === "Error registering the user")
errorType = "ConnectionError";
Expand Down
20 changes: 20 additions & 0 deletions app/api/cypress/register/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import db from "@/db/drizzle";
import { user } from "@/db/schema";
import { eq } from "drizzle-orm";
import { NextResponse } from "next/server";

export const dynamic = "force-dynamic"; // defaults to auto

export async function POST() {
try {
// Delete cypress user
await db.delete(user).where(eq(user.email, "[email protected]"));
console.log("User deleted successfully");
// Return success response
return NextResponse.json({ message: "User deleted successfully" });
} catch (error) {
console.error("Error deleting user:", error);
// Return error response
return NextResponse.json({ message: "Error deleting user" });
}
}
1 change: 1 addition & 0 deletions components/BannerImagePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const BannerImagePanel = ({ closeModal }: { closeModal: () => void }) => {
<div className="flex space-x-4">
{images.map((src, index) => (
<button
data-testid={`banner-image-${index}`}
key={index}
className={`rounded border-2 ${selectedImage === index ? "border-primary" : "border-transparent"}`}
onClick={() => handleImageClick(index)}
Expand Down
1 change: 1 addition & 0 deletions components/FormTextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const FormTextInput = ({ name, type, label }: FormTextInputProps) => {
return (
<div className="relative mt-6 flex w-full flex-col">
<input
data-testid={name}
autoComplete={type === "email" || name === "name" ? "on" : "off"}
id={name}
name={name}
Expand Down
3 changes: 2 additions & 1 deletion components/NotificationCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const NotificationCard = ({ notification }: NotificationCardProps) => {
const getTitle = (type: string) => {
switch (type) {
case "RULER":
return " Daily Ruler Survey";
return "Daily Ruler Survey";
case "SPRINT":
return "Sprint Survey";
case "FINAL":
Expand All @@ -23,6 +23,7 @@ const NotificationCard = ({ notification }: NotificationCardProps) => {

return (
<div
data-testid={`${getTitle(notification.type)}`}
className={`flex w-full items-center rounded-t-md border-b-2 border-gray-200 p-2 hover:bg-gray-200`}
>
<svg
Expand Down
1 change: 1 addition & 0 deletions components/Notifications.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ const Notifications = ({
return (
<Menu as="div" className="relative inline-block text-left">
<Menu.Button
data-testid="notification-button"
onClick={() => setIsActive(!isActive)}
className={`${isActive ? "bg-primary" : "bg-white transition-all delay-0 hover:scale-[1.175]"} group rounded-full p-2 drop-shadow-lg`}
>
Expand Down
1 change: 1 addition & 0 deletions components/Profile/ProfileBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const ProfileBanner: React.FC<ProfileBannerProps> = async ({ user }) => {
)}
</div>
<Image
data-testid={user.bannerId}
src={`/${user.bannerId}` || "/Banner1.svg"}
alt="Banner Image"
width={100}
Expand Down
8 changes: 6 additions & 2 deletions components/UserIconNavbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const UserIconNavbar = ({
return (
<Menu as="div" className="relative inline-block text-left">
<Menu.Button
data-testid="user-icon-navbar"
as="div"
onClick={() => setIsClicked(!isClicked)}
className={`${onSite || isClicked ? "bg-primary" : "bg-white transition-all delay-0 hover:scale-[1.175]"} flex rounded-full drop-shadow-lg`}
Expand Down Expand Up @@ -91,6 +92,7 @@ const UserIconNavbar = ({
)}
</Menu.Item>
<button
data-testid="settings-button"
onClick={() => {
showSettingsModal();
}}
Expand All @@ -108,10 +110,12 @@ const UserIconNavbar = ({
</Menu.Item>
</button>
</div>
<button className="w-full px-1 py-1" onClick={handleSignOut}>
<div className="w-full px-1 py-1">
<Menu.Item>
{({ active }) => (
<button
data-testid="signout-button"
onClick={handleSignOut}
className={`${
active ? "bg-red-700 text-white" : "text-gray-900"
} group flex w-full items-center rounded-md px-2 py-2 text-sm`}
Expand All @@ -120,7 +124,7 @@ const UserIconNavbar = ({
</button>
)}
</Menu.Item>
</button>
</div>
</Menu.Items>
</Transition>
</Menu>
Expand Down
1 change: 1 addition & 0 deletions components/modals/SettingsDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ const SettingsDialog = ({ showModal, onClose }: SettingsDialogProps) => {
Profile Image
</Tabs.Tab>
<Tabs.Tab
data-testid="banner-tab"
value="bannerImage"
style={{ fontWeight: 500, fontSize: "16px" }}
>
Expand Down
12 changes: 10 additions & 2 deletions components/modals/ruler/RulerStepOne.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -143,22 +143,30 @@ const RulerStepOne = ({
}
};
return (
<div className="flex flex-col" id="ruler-step-one">
<div
className="flex flex-col"
id="ruler-step-one"
data-testid="ruler-step-one"
>
<p className="my-2 text-sm text-graySubtitle">How do you feel today?</p>
<section id="ruler-survey" className="flex flex-col text-center">
<div className="flex flex-col gap-4">
{rulerEmotionsMatrix.map((row, rowIndex) => (
<div key={rowIndex} className="flex flex-row gap-4">
{row.map((emotion: Emotion, colIndex) => (
<button
data-testid={`emotion-${rowIndex}-${colIndex}`}
id={`${rowIndex}-${colIndex}`}
key={colIndex}
onMouseEnter={() => expandSize(rowIndex, colIndex)}
onMouseLeave={() => removeSize()}
onClick={() => handleClick(emotion)}
className={`${emotionBgColor(emotion)} z-10 h-10 w-14 cursor-pointer rounded-full text-center text-transparent transition-transform duration-500 hover:z-50 hover:scale-150 hover:text-white`}
>
<p className="text-[0.5rem] font-semibold duration-500">
<p
data-testid={`emotion-name-${rowIndex}-${colIndex}`}
className="text-[0.5rem] font-semibold duration-500"
>
{emotion.name}
</p>
</button>
Expand Down
6 changes: 5 additions & 1 deletion components/modals/ruler/RulerStepTwo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ const RulerStepTwo = ({
return "border-yellow-100 bg-yellow-100/20 focus:outline-yellow-200 focus-within:outline-yellow-200";
};
return (
<form action={onClose} className={`flex h-40 flex-col`}>
<form
data-testid="ruler-step-two"
action={onClose}
className={`flex h-40 flex-col`}
>
<div className="mt-4 flex flex-col items-center ">
<label
htmlFor="emotion-description"
Expand Down
2 changes: 2 additions & 0 deletions components/modals/ruler/RulerSurvey.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ const RulerSurvey = ({ showModal, onClose }: RulerSurveyProps) => {
leaveTo="opacity-0 scale-95"
>
<Dialog.Panel
data-testid="ruler-survey"
id="ruler-modal"
className={`flex ${modalWidth} w-full transform flex-col overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all duration-500`}
>
Expand All @@ -102,6 +103,7 @@ const RulerSurvey = ({ showModal, onClose }: RulerSurveyProps) => {
<p className="text-2xl font-semibold">Ruler Survey</p>
<div className="flex h-8 min-w-fit max-w-[40ch] flex-col justify-center self-end text-sm">
<span
data-testid="chosen-emotion"
className={
getEmotionTextColor() + " text-end font-medium"
}
Expand Down
40 changes: 40 additions & 0 deletions cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import db from "./db/drizzle";
import { user } from "./db/schema";
import { defineConfig } from "cypress";
import { eq } from "drizzle-orm";
import dotenv from "dotenv";

dotenv.config({
path: ".env.local",
});

export default defineConfig({
env: {
AUTH_SECRET: process.env.AUTH_SECRET,
POSTGRES_URL: process.env.POSTGRES_URL,
},
e2e: {
viewportWidth: 1920,
viewportHeight: 1080,
baseUrl: "http://localhost:3000",
setupNodeEvents(on, config) {
on("task", {
async deleteDummyUser({ email }) {
await db
.delete(user)
.where(eq(user.email, email))
.then((res) => {
if (res) {
return true;
}
})
.catch((err) => {
console.error(err);
return false;
});
return null;
},
});
},
},
});
4 changes: 4 additions & 0 deletions cypress/cypress.env.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"AUTH_SECRET": "B2MpnwcQe/tHVNSiLLNzxBsOJbz/rdkr5nryhA7V5wXn",
"POSTGRES_URL": "postgres://default:IJ9zyn6TVsRk@ep-delicate-brook-a4k70q8v-pooler.us-east-1.aws.neon.tech:5432/verceldb?sslmode=require"
}
21 changes: 21 additions & 0 deletions cypress/e2e/login.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
describe("Login", () => {
it("Visits Login page, and signs in", () => {
cy.visit("/");
cy.get("label").contains("Email").click().type("[email protected]");
cy.get("label").contains("Password").click().type("cypress");
cy.get("button").contains("Log in").click();
cy.url().should("include", "/profile");
});
it("Visits page not being signed in, and gets redirected to login", () => {
cy.visit("/profile");
cy.url().should("include", "/login");
});
it("Tries to sign in with wrong credentials", () => {
cy.visit("/");
cy.get("label").contains("Email").click().type("[email protected]");
cy.get("label").contains("Password").click().type("prueba");
cy.get("button").contains("Log in").click();
cy.get("div").contains("Email or password is not valid.").should("exist");
cy.url().should("include", "/login");
});
});
21 changes: 21 additions & 0 deletions cypress/e2e/profile.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
describe("Profile", () => {
beforeEach(() => {
cy.visit("/profile");
cy.get("label").contains("Email").click().type("[email protected]");
cy.get("label").contains("Password").click().type("cypress");
cy.get("button").contains("Log in").click();
});
it("Change banner image", () => {
const randomNumber = Math.floor(Math.random() * 5);
cy.get('[data-testid="user-icon-navbar"]').click();
cy.get('[data-testid="settings-button"]').click();
cy.get('[data-testid="banner-tab"]').click();
cy.get(`[data-testid="banner-image-${randomNumber}"]`).click();
cy.get("button").contains("Done").click();
cy.get(`[data-testid="Banner${randomNumber}.svg"]`).should(
"have.attr",
"src",
`/Banner${randomNumber}.svg`,
);
});
});
60 changes: 60 additions & 0 deletions cypress/e2e/rulerSurvey.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const randomEmotion = {
row: Math.floor(Math.random() * 12),
col: Math.floor(Math.random() * 12),
};
describe("Testing different surveys", () => {
beforeEach(() => {
cy.visit("/");
cy.get("label").contains("Email").click().type("[email protected]");
cy.get("label").contains("Password").click().type("cypress");
cy.get("button").contains("Log in").click();
cy.get('[data-testid="notification-button"]').click();
cy.get('[data-testid="Daily Ruler Survey"]').click();
cy.get('[data-testid="ruler-survey"]').should("exist");
});

it("should render step two after click", () => {
cy.get(
`[data-testid="emotion-${randomEmotion.row}-${randomEmotion.col}"]`,
).click();
cy.get('[data-testid="ruler-step-two"]').should("exist");
});
it("should render step one after go back", () => {
cy.get(
`[data-testid="emotion-${randomEmotion.row}-${randomEmotion.col}"]`,
).click();
cy.get('[data-testid="ruler-step-two"]').should("exist");
cy.get("button").contains("Go back").click();
cy.get('[data-testid="ruler-step-one"]').should("exist");
});
it("should have same emotion on comment section", () => {
cy.get(
`[data-testid="emotion-${randomEmotion.row}-${randomEmotion.col}"]`,
).trigger("mouseover");
let emotionName: string;
cy.get(
`[data-testid="emotion-name-${randomEmotion.row}-${randomEmotion.col}"]`,
)
.invoke("text")
.then((text) => (emotionName = text));
cy.get(
`[data-testid="emotion-${randomEmotion.row}-${randomEmotion.col}"]`,
).click();
cy.get('[data-testid="ruler-step-two"]').should("exist");
cy.get('[data-testid="chosen-emotion"]')
.invoke("text")
.should((chosenEmotion) => {
expect(chosenEmotion).to.eq(emotionName);
});
});
it("should type additional comment on step two", () => {
cy.get(
`[data-testid="emotion-${randomEmotion.row}-${randomEmotion.col}"]`,
).click();
cy.get('[data-testid="ruler-step-two"]').should("exist");
cy.get("textarea").type("This is a test comment");
cy.get("button").contains("Submit").click();
cy.get('[data-testid="ruler-survey"]').should("not.exist");
cy.get("div").contains("Encuesta enviada exitosamente!").should("exist");
});
});
26 changes: 26 additions & 0 deletions cypress/e2e/signin.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
describe("Register", () => {
beforeEach(() => {
cy.visit("/register");
});

it("Visits Register page, and signs up", () => {
cy.task("deleteDummyUser", { email: "[email protected]" });
cy.get("label").contains("Name").click().type("Cypress prueba");
cy.get("label").contains("Email").click().type("[email protected]");
cy.get("label").contains("Password").click().type("cypress");
cy.get("label").contains("Job Title").click().type("Cypress");
cy.get("label").contains("Department").click().type("QA");
cy.get("button").contains("Register").click();
cy.get("h2").contains("Cypress prueba");
});

it("Visits Register page, and signs up with an existing email", () => {
cy.get("label").contains("Name").click().type("Cypress prueba");
cy.get("label").contains("Email").click().type("[email protected]");
cy.get("label").contains("Password").click().type("cypress");
cy.get("label").contains("Job Title").click().type("Cypress");
cy.get("label").contains("Department").click().type("QA");
cy.get("button").contains("Register").click();
cy.get("div").contains("Email already registered.").should("exist");
});
});
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"
}
Loading
Loading