import { SELECTORS } from "../../fixtures/selectors"; import { expect, test } from "../../fixtures/test"; test.describe("Footer Link Rendering @smoke", () => { test.beforeEach(async ({ gotoApp, waitForAppReady }) => { await gotoApp(); await waitForAppReady(); }); test("footer renders GitHub link when configured", async ({ page }) => { const githubLink = page.locator(SELECTORS.footer.githubLink); // Check if GitHub link exists (may or may not be present based on config) const count = await githubLink.count(); if (count > 0) { // If present, should be visible and have correct attributes await expect(githubLink).toBeVisible(); await expect(githubLink).toHaveAttribute("href"); await expect(githubLink).toHaveAttribute("target", "_blank"); await expect(githubLink).toHaveAttribute("rel", "noopener"); // Should link to GitHub const href = await githubLink.getAttribute("href"); expect(href).toContain("github.com"); } }); test("footer renders contact email link when configured", async ({ page, }) => { const contactLink = page.locator(SELECTORS.footer.contactLink); // Check if contact link exists (may or may not be present based on config) const count = await contactLink.count(); if (count > 0) { // If present, should be visible and have correct attributes await expect(contactLink).toBeVisible(); await expect(contactLink).toHaveAttribute("href"); // Should be mailto link const href = await contactLink.getAttribute("href"); expect(href).toMatch(/^mailto:/); // Should have email text const text = await contactLink.textContent(); expect(text).toContain("@"); } }); test("footer layout is stable regardless of link configuration", async ({ page, }) => { const footer = page.locator(SELECTORS.footer.root); // Footer should always be visible await expect(footer).toBeVisible(); // Footer should have consistent structure const poweredBy = footer.locator(SELECTORS.footer.poweredBy); await expect(poweredBy).toBeVisible(); const termsLink = footer.locator(SELECTORS.footer.termsLink); await expect(termsLink).toBeVisible(); const attributionLink = footer.locator(SELECTORS.footer.attributionLink); await expect(attributionLink).toBeVisible(); const copyright = footer.locator("text=All rights reserved"); await expect(copyright).toBeVisible(); }); test("footer links are interactive", async ({ page }) => { // Terms link should open modal const termsLink = page.locator(SELECTORS.footer.termsLink); await termsLink.click(); const termsModal = page.locator(SELECTORS.policyModal.root); await expect(termsModal).toBeVisible(); await expect( termsModal.locator(SELECTORS.policyModal.termsTitle), ).toBeVisible(); // Close modal await page.keyboard.press("Escape"); await page.waitForTimeout(500); // Attribution link should open modal const attributionLink = page.locator(SELECTORS.footer.attributionLink); await attributionLink.click(); const attributionModal = page.locator(SELECTORS.policyModal.root); await expect(attributionModal).toBeVisible(); await expect( attributionModal.locator(SELECTORS.policyModal.attributionTitle), ).toBeVisible(); }); test("footer links have proper accessible names", async ({ page }) => { // Terms link const termsLink = page.locator(SELECTORS.footer.termsLink); const termsText = await termsLink.textContent(); expect(termsText?.toLowerCase()).toContain("terms"); // Attribution link const attributionLink = page.locator(SELECTORS.footer.attributionLink); const attributionText = await attributionLink.textContent(); expect(attributionText?.toLowerCase()).toContain("attribution"); // GitHub link (if present) const githubLink = page.locator(SELECTORS.footer.githubLink); const githubCount = await githubLink.count(); if (githubCount > 0) { const githubText = await githubLink.textContent(); expect(githubText?.toLowerCase()).toContain("github"); } }); test("footer is responsive across viewports", async ({ page, setViewport, }) => { const viewports = ["mobile", "tablet", "desktop"] as const; for (const viewport of viewports) { await setViewport(viewport); const footer = page.locator(SELECTORS.footer.root); await expect(footer).toBeVisible(); // Footer should not overflow const footerBox = await footer.boundingBox(); const viewportWidth = await page.evaluate(() => window.innerWidth); expect(footerBox!.width).toBeLessThanOrEqual(viewportWidth); } }); });