diff --git a/e2e-tests/footer/footer.spec.ts b/e2e-tests/footer/footer.spec.ts new file mode 100644 index 0000000..d9c95ed --- /dev/null +++ b/e2e-tests/footer/footer.spec.ts @@ -0,0 +1,71 @@ +import { test, expect } from "@playwright/test"; + +test.describe("Footer Component", () => { + test.beforeEach(async ({ page }) => { + // Navigate to the page where the Footer is rendered + await page.goto("/"); + }); + + test("should render the Footer component", async ({ page }) => { + const footer = await page.locator('[data-test="Footer"]'); + await expect(footer).toBeVisible(); + }); + + test("should render social media icons with correct links", async ({ + page, + }) => { + // Check for Colabs logo link + const colabsLogoLink = page.locator('img[alt="Colabs logo"]'); + await expect(colabsLogoLink).toBeVisible(); + + // Check for X icon link + const xIconLink = page.locator('img[alt="X Icon"]'); + await expect(xIconLink).toBeVisible(); + await expect(xIconLink).toHaveAttribute("src", /x-icon\.png/); + const xLink = page.locator('a[href="http://www.x.com"]'); + await expect(xLink).toHaveAttribute("target", "_blank"); + + // Check for LinkedIn icon link + const linkedinIconLink = page.locator('img[alt="Linkedin Icon"]'); + await expect(linkedinIconLink).toBeVisible(); + await expect(linkedinIconLink).toHaveAttribute("src", /linkedin-icon\.png/); + const linkedinLink = page.locator('a[href="http://www.linkedin.com"]'); + await expect(linkedinLink).toHaveAttribute("target", "_blank"); + }); + + test("should render internal links with correct routes", async ({ page }) => { + // Check internal navigation links + const aboutLink = page.locator("text=About"); + const hackathonsLink = page.locator("text=Hackathons"); + const leaderboardLink = page.locator("text=Leaderboard"); + const privacyLink = page.locator("text=Privacy & Terms"); + const cookiesLink = page.locator("text=Cookies"); + + // Assert visibility of links + await expect(aboutLink).toBeVisible(); + await expect(hackathonsLink).toBeVisible(); + await expect(leaderboardLink).toBeVisible(); + await expect(privacyLink).toBeVisible(); + await expect(cookiesLink).toBeVisible(); + + // Assert href attributes for navigation links + await expect(aboutLink).toHaveAttribute("href", "/"); + await expect(hackathonsLink).toHaveAttribute( + "href", + "/dashboard/hackathons", + ); + await expect(leaderboardLink).toHaveAttribute( + "href", + "/dashboard/leaderboards", + ); + await expect(privacyLink).toHaveAttribute("href", "/"); + await expect(cookiesLink).toHaveAttribute("href", "/"); + }); + + test("should render copyright notice", async ({ page }) => { + const copyrightNotice = page.locator( + "text=© 2024 Colabs by SpaceYaTech. All rights reserved.", + ); + await expect(copyrightNotice).toBeVisible(); + }); +}); diff --git a/e2e-tests/footer/footerCTA.spec.ts b/e2e-tests/footer/footerCTA.spec.ts new file mode 100644 index 0000000..b654a3f --- /dev/null +++ b/e2e-tests/footer/footerCTA.spec.ts @@ -0,0 +1,71 @@ +import { test, expect } from "@playwright/test"; + +test.describe("FooterCTA Component", () => { + test.beforeEach(async ({ page }) => { + // Replace with the route that renders the FooterCTA component + await page.goto("http://localhost:3000"); + }); + + test("should render the FooterCTA component", async ({ page }) => { + const footerCTA = await page.locator('[data-test="FooterCTA"]'); + await expect(footerCTA).toBeVisible(); + }); + + test("should display the main text", async ({ page }) => { + const mainText = await page.locator( + "text=Experience counts. Get it on Colabs.", + ); + await expect(mainText).toBeVisible(); + }); + + test("should display the secondary text", async ({ page }) => { + const secondaryText = await page.locator( + "text=Colabs is where you cut your teeth on enterprise projects. We have over 100 repositories on all tech tracks, carefully picked for you.", + ); + await expect(secondaryText).toBeVisible(); + }); + + test("should render the Join Colabs for free button", async ({ page }) => { + const joinButton = await page.locator("text=Join Colabs for free"); + await expect(joinButton).toBeVisible(); + await expect(joinButton).toHaveAttribute( + "href", + "/auth/signup?returnTo=%2Fdashboard", + ); + await joinButton.click(); + }); + + test("should render the Launch a Hackathon button", async ({ page }) => { + const hackathonButton = await page.locator("text=Launch a Hackathon"); + await expect(hackathonButton).toBeVisible(); + await expect(hackathonButton).toHaveAttribute( + "href", + "/dashboard/hackathons", + ); + }); + + test("should display images", async ({ page }) => { + const robotImage = await page.locator('img[alt="Standing robot"]'); + const ellipseImage = await page.locator('img[alt="ellipse background"]'); + + await expect(robotImage).toBeVisible(); + await expect(ellipseImage).toBeVisible(); + }); + + test("Join Colabs for free button navigates correctly", async ({ page }) => { + const joinButton = await page.locator("text=Join Colabs for free"); + await expect(joinButton).toBeVisible(); + await joinButton.click(); + await expect(joinButton).toHaveAttribute( + "href", + "/auth/signup?returnTo=%2Fdashboard", + ); + }); + + test("Launch a Hackathon button navigates correctly", async ({ page }) => { + const hackathonButton = await page.locator("text=Launch a Hackathon"); + await expect(hackathonButton).toBeVisible(); + //setting this up to force a click because the rocket icon is in the way of the button + await hackathonButton.click({ force: true }); + }); +}); diff --git a/index.html b/index.html index 490d040..d12abc3 100644 --- a/index.html +++ b/index.html @@ -1,19 +1,23 @@ - - - - - - - - Colabs - - -
- - - + + + + + + + + + + + Colabs + + + +
+ + + + \ No newline at end of file diff --git a/playwright.config.ts b/playwright.config.ts index b9a3207..eaf9380 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -1,4 +1,4 @@ -import { defineConfig, devices } from '@playwright/test'; +import { defineConfig, devices } from "@playwright/test"; /** * Read environment variables from file. @@ -45,10 +45,10 @@ export default defineConfig({ use: { ...devices["Desktop Firefox"] }, }, - { - name: "webkit", - use: { ...devices["Desktop Safari"] }, - }, + // { + // name: "webkit", + // use: { ...devices["Desktop Safari"] }, + // }, /* Test against mobile viewports. */ // { diff --git a/src/assets/ellipse.png b/src/assets/ellipse.png new file mode 100644 index 0000000..4829a52 Binary files /dev/null and b/src/assets/ellipse.png differ diff --git a/src/assets/linkedin-icon.png b/src/assets/linkedin-icon.png new file mode 100644 index 0000000..5dfe17d Binary files /dev/null and b/src/assets/linkedin-icon.png differ diff --git a/src/assets/logo-container.png b/src/assets/logo-container.png new file mode 100644 index 0000000..bdb6429 Binary files /dev/null and b/src/assets/logo-container.png differ diff --git a/src/assets/robot-assistant.png b/src/assets/robot-assistant.png new file mode 100644 index 0000000..048b3d3 Binary files /dev/null and b/src/assets/robot-assistant.png differ diff --git a/src/assets/rocket.png b/src/assets/rocket.png new file mode 100644 index 0000000..ca7b57a Binary files /dev/null and b/src/assets/rocket.png differ diff --git a/src/assets/x-icon.png b/src/assets/x-icon.png new file mode 100644 index 0000000..64d2b2f Binary files /dev/null and b/src/assets/x-icon.png differ diff --git a/src/routes/-components/Footer.tsx b/src/routes/-components/Footer.tsx new file mode 100644 index 0000000..c6821c6 --- /dev/null +++ b/src/routes/-components/Footer.tsx @@ -0,0 +1,47 @@ +import ColabsLogo from "../../assets/logo-container.png"; +import XIcon from "../../assets/x-icon.png"; +import LinkedinIcon from "../../assets/linkedin-icon.png"; +import { Link } from "@tanstack/react-router"; + +export default function Footer() { + return ( + + ); +} diff --git a/src/routes/-components/FooterCTA.tsx b/src/routes/-components/FooterCTA.tsx new file mode 100644 index 0000000..9724da7 --- /dev/null +++ b/src/routes/-components/FooterCTA.tsx @@ -0,0 +1,48 @@ +import { Link } from "@tanstack/react-router"; +import rocketIcon from "../../assets/rocket.png"; +import robot from "../../assets/robot-assistant.png"; +import ellipse from "../../assets/ellipse.png"; +export const FooterCTA = () => { + return ( +
+
+

+ Experience counts. Get it on Colabs. +

+

+ Colabs is where you cut your teeth on enterprise projects. We have + over 100 repositories on all tech tracks, carefully picked for you. +

+
+ + Join Colabs for free + + + Launch a Hackathon Rocket icon + +
+
+ + Standing robot + ellipse background +
+ ); +}; diff --git a/src/routes/-components/HomePage.tsx b/src/routes/-components/HomePage.tsx index 3e06c6a..1975c11 100644 --- a/src/routes/-components/HomePage.tsx +++ b/src/routes/-components/HomePage.tsx @@ -4,6 +4,8 @@ import RepositoriesSection from "./RepositoriesSection"; import { projects } from "@/data/projects"; import { ToolsSection } from "./tools-section/ToolsSection"; +import { FooterCTA } from "./FooterCTA"; +import Footer from "./Footer"; export function HomePage() { return ( @@ -18,8 +20,10 @@ export function HomePage() { Go to Dashboard - + + +