Files
2026-02-13 16:57:45 -05:00

192 lines
5.3 KiB
TypeScript

import { SELECTORS } from "../../fixtures/selectors";
import { expect, test } from "../../fixtures/test";
test.describe("Deep Link Permalink Tests @smoke", () => {
test.beforeEach(async ({ waitForAppReady }) => {
await waitForAppReady();
});
test("valid article permalink opens modal automatically", async ({
page,
gotoApp,
isSummaryModalOpen,
}) => {
// First get an article ID from the feed
await gotoApp();
await page.waitForSelector(SELECTORS.feed.articles, { timeout: 10000 });
const firstArticle = page.locator(SELECTORS.feed.articles).first();
const articleId = await firstArticle
.getAttribute("id")
.then((id) => (id ? parseInt(id.replace("news-", "")) : null));
expect(articleId).not.toBeNull();
// Navigate to article permalink
await gotoApp({ articleId: articleId! });
await page.waitForTimeout(2000); // Wait for modal to open
// Modal should be open
const isOpen = await isSummaryModalOpen();
expect(isOpen).toBe(true);
// Modal should show correct article
const modal = page.locator(SELECTORS.summaryModal.root);
const modalHeadline = await modal
.locator(SELECTORS.summaryModal.headline)
.textContent();
const articleHeadline = await firstArticle.locator("h3").textContent();
expect(modalHeadline).toBe(articleHeadline);
});
test("invalid article permalink shows error state", async ({
page,
gotoApp,
}) => {
// Navigate to invalid article ID
await gotoApp({ articleId: 999999 });
await page.waitForTimeout(2000);
// Should not show summary modal
const modal = page.locator(SELECTORS.summaryModal.root);
await expect(modal).not.toBeVisible();
// Should still show the page (not crash)
const hero = page.locator(SELECTORS.hero.root);
const feed = page.locator(SELECTORS.feed.root);
const heroVisible = await hero.isVisible().catch(() => false);
const feedVisible = await feed.isVisible().catch(() => false);
expect(heroVisible || feedVisible).toBe(true);
});
test("hero-origin modal flow via permalink", async ({
page,
gotoApp,
isSummaryModalOpen,
}) => {
// Get hero article ID
await gotoApp();
await page.waitForSelector(SELECTORS.hero.root, { timeout: 10000 });
const hero = page.locator(SELECTORS.hero.root);
const heroId = await hero
.getAttribute("id")
.then((id) => (id ? parseInt(id.replace("news-", "")) : null));
expect(heroId).not.toBeNull();
// Navigate directly to hero article
await gotoApp({ articleId: heroId! });
await page.waitForTimeout(2000);
// Modal should open
const isOpen = await isSummaryModalOpen();
expect(isOpen).toBe(true);
// Modal should show hero article content
const modal = page.locator(SELECTORS.summaryModal.root);
const modalHeadline = await modal
.locator(SELECTORS.summaryModal.headline)
.textContent();
const heroHeadline = await hero.locator("h1").textContent();
expect(modalHeadline).toBe(heroHeadline);
});
test("closing permalink modal updates URL", async ({
page,
gotoApp,
isSummaryModalOpen,
}) => {
// Open via permalink
await gotoApp({ articleId: 1 });
await page.waitForTimeout(2000);
// URL should have article parameter
await expect(page).toHaveURL(/\?article=\d+/);
// Close modal
await page.keyboard.press("Escape");
await page.waitForTimeout(500);
// URL should be cleaned up (parameter removed)
await expect(page).toHaveURL(/\/$/);
await expect(page).not.toHaveURL(/\?article=/);
});
test("modal state persists on page refresh", async ({
page,
gotoApp,
isSummaryModalOpen,
}) => {
// Open via permalink
await gotoApp({ articleId: 1 });
await page.waitForTimeout(2000);
// Verify modal is open
expect(await isSummaryModalOpen()).toBe(true);
// Refresh page
await page.reload();
await page.waitForTimeout(2000);
// Modal should still be open
expect(await isSummaryModalOpen()).toBe(true);
});
});
test.describe("Policy Modal Deep Links", () => {
test("terms policy modal opens via URL parameter", async ({
page,
gotoApp,
}) => {
await gotoApp({ policy: "terms" });
await page.waitForTimeout(1000);
// Policy modal should be visible
const modal = page.locator(SELECTORS.policyModal.root);
await expect(modal).toBeVisible();
// Should show terms title
const title = modal.locator(SELECTORS.policyModal.termsTitle);
await expect(title).toBeVisible();
});
test("attribution policy modal opens via URL parameter", async ({
page,
gotoApp,
}) => {
await gotoApp({ policy: "attribution" });
await page.waitForTimeout(1000);
// Policy modal should be visible
const modal = page.locator(SELECTORS.policyModal.root);
await expect(modal).toBeVisible();
// Should show attribution title
const title = modal.locator(SELECTORS.policyModal.attributionTitle);
await expect(title).toBeVisible();
});
test("closing policy modal clears URL parameter", async ({
page,
gotoApp,
}) => {
await gotoApp({ policy: "terms" });
await page.waitForTimeout(1000);
// URL should have policy parameter
await expect(page).toHaveURL(/\?policy=terms/);
// Close modal
const modal = page.locator(SELECTORS.policyModal.root);
await modal.locator(SELECTORS.policyModal.closeButton).click();
await page.waitForTimeout(500);
// URL should be cleaned up
await expect(page).toHaveURL(/\/$/);
await expect(page).not.toHaveURL(/\?policy=/);
});
});