p19-bug-fixes
This commit is contained in:
139
e2e/tests/capabilities/microinteractions/footer.spec.ts
Normal file
139
e2e/tests/capabilities/microinteractions/footer.spec.ts
Normal file
@@ -0,0 +1,139 @@
|
||||
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);
|
||||
}
|
||||
});
|
||||
});
|
||||
198
e2e/tests/capabilities/microinteractions/tooltip.spec.ts
Normal file
198
e2e/tests/capabilities/microinteractions/tooltip.spec.ts
Normal file
@@ -0,0 +1,198 @@
|
||||
import { SELECTORS } from "../../fixtures/selectors";
|
||||
import { expect, test } from "../../fixtures/test";
|
||||
|
||||
test.describe("Contact Email Tooltip @smoke", () => {
|
||||
test.beforeEach(async ({ gotoApp, waitForAppReady }) => {
|
||||
await gotoApp();
|
||||
await waitForAppReady();
|
||||
});
|
||||
|
||||
test("tooltip appears on mouse hover", async ({ page }) => {
|
||||
const contactLink = page.locator(SELECTORS.footer.contactLink);
|
||||
|
||||
// Check if contact link exists
|
||||
const count = await contactLink.count();
|
||||
if (count === 0) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
|
||||
// Hover over contact link
|
||||
await contactLink.hover();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Tooltip should appear
|
||||
const tooltip = page.locator(SELECTORS.footer.contactHint);
|
||||
await expect(tooltip).toBeVisible();
|
||||
|
||||
// Tooltip should have text
|
||||
const tooltipText = await tooltip.textContent();
|
||||
expect(tooltipText).toBeTruthy();
|
||||
expect(tooltipText!.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
test("tooltip disappears on mouse leave", async ({ page }) => {
|
||||
const contactLink = page.locator(SELECTORS.footer.contactLink);
|
||||
|
||||
// Check if contact link exists
|
||||
const count = await contactLink.count();
|
||||
if (count === 0) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
|
||||
// Hover over contact link
|
||||
await contactLink.hover();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
const tooltip = page.locator(SELECTORS.footer.contactHint);
|
||||
await expect(tooltip).toBeVisible();
|
||||
|
||||
// Move mouse away
|
||||
await page.mouse.move(0, 0);
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Tooltip should disappear
|
||||
await expect(tooltip).not.toBeVisible();
|
||||
});
|
||||
|
||||
test("tooltip follows mouse movement", async ({ page }) => {
|
||||
const contactLink = page.locator(SELECTORS.footer.contactLink);
|
||||
|
||||
// Check if contact link exists
|
||||
const count = await contactLink.count();
|
||||
if (count === 0) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
|
||||
// Hover over contact link
|
||||
await contactLink.hover();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
const tooltip = page.locator(SELECTORS.footer.contactHint);
|
||||
await expect(tooltip).toBeVisible();
|
||||
|
||||
// Get initial position
|
||||
const initialBox = await tooltip.boundingBox();
|
||||
|
||||
// Move mouse slightly
|
||||
const linkBox = await contactLink.boundingBox();
|
||||
await page.mouse.move(
|
||||
linkBox!.x + linkBox!.width / 2 + 20,
|
||||
linkBox!.y + linkBox!.height / 2,
|
||||
);
|
||||
await page.waitForTimeout(200);
|
||||
|
||||
// Tooltip should still be visible
|
||||
await expect(tooltip).toBeVisible();
|
||||
});
|
||||
|
||||
test("tooltip appears on keyboard focus", async ({ page }) => {
|
||||
const contactLink = page.locator(SELECTORS.footer.contactLink);
|
||||
|
||||
// Check if contact link exists
|
||||
const count = await contactLink.count();
|
||||
if (count === 0) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
|
||||
// Focus contact link
|
||||
await contactLink.focus();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Tooltip should appear
|
||||
const tooltip = page.locator(SELECTORS.footer.contactHint);
|
||||
await expect(tooltip).toBeVisible();
|
||||
});
|
||||
|
||||
test("tooltip disappears on keyboard blur", async ({ page }) => {
|
||||
const contactLink = page.locator(SELECTORS.footer.contactLink);
|
||||
|
||||
// Check if contact link exists
|
||||
const count = await contactLink.count();
|
||||
if (count === 0) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
|
||||
// Focus contact link
|
||||
await contactLink.focus();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
const tooltip = page.locator(SELECTORS.footer.contactHint);
|
||||
await expect(tooltip).toBeVisible();
|
||||
|
||||
// Blur contact link
|
||||
await page.evaluate(() => (document.activeElement as HTMLElement)?.blur());
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Tooltip should disappear
|
||||
await expect(tooltip).not.toBeVisible();
|
||||
});
|
||||
|
||||
test("tooltip content is safe and appropriate", async ({ page }) => {
|
||||
const contactLink = page.locator(SELECTORS.footer.contactLink);
|
||||
|
||||
// Check if contact link exists
|
||||
const count = await contactLink.count();
|
||||
if (count === 0) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
|
||||
// Hover to show tooltip
|
||||
await contactLink.hover();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
const tooltip = page.locator(SELECTORS.footer.contactHint);
|
||||
const tooltipText = await tooltip.textContent();
|
||||
|
||||
// Should not contain inappropriate content
|
||||
const inappropriateWords = [
|
||||
"profanity",
|
||||
"offensive",
|
||||
"racist",
|
||||
"sexist",
|
||||
"misogynistic",
|
||||
];
|
||||
for (const word of inappropriateWords) {
|
||||
expect(tooltipText?.toLowerCase()).not.toContain(word);
|
||||
}
|
||||
|
||||
// Should contain helpful text
|
||||
expect(tooltipText).toBeTruthy();
|
||||
expect(tooltipText!.length).toBeGreaterThan(5);
|
||||
});
|
||||
|
||||
test("tooltip does not trap focus", async ({ page }) => {
|
||||
const contactLink = page.locator(SELECTORS.footer.contactLink);
|
||||
|
||||
// Check if contact link exists
|
||||
const count = await contactLink.count();
|
||||
if (count === 0) {
|
||||
test.skip();
|
||||
return;
|
||||
}
|
||||
|
||||
// Focus contact link
|
||||
await contactLink.focus();
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Tooltip should be visible
|
||||
const tooltip = page.locator(SELECTORS.footer.contactHint);
|
||||
await expect(tooltip).toBeVisible();
|
||||
|
||||
// Tab away
|
||||
await page.keyboard.press("Tab");
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Tooltip should disappear
|
||||
await expect(tooltip).not.toBeVisible();
|
||||
|
||||
// Focus should have moved
|
||||
const isStillFocused = await contactLink.isFocused();
|
||||
expect(isStillFocused).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user