194 lines
5.4 KiB
TypeScript
194 lines
5.4 KiB
TypeScript
import { SELECTORS } from "../../fixtures/selectors";
|
|
import { expect, test } from "../../fixtures/test";
|
|
|
|
test.describe("Source CTA and Share Interactions", () => {
|
|
test.beforeEach(async ({ gotoApp, waitForAppReady, waitForHero }) => {
|
|
await gotoApp();
|
|
await waitForAppReady();
|
|
|
|
// Open modal from hero
|
|
const hero = await waitForHero();
|
|
await hero.locator(SELECTORS.hero.readButton).click();
|
|
await expect(page.locator(SELECTORS.summaryModal.root)).toBeVisible();
|
|
});
|
|
|
|
let page: any;
|
|
|
|
test("source link opens in new tab @smoke", async ({ page: p, context }) => {
|
|
page = p;
|
|
const modal = page.locator(SELECTORS.summaryModal.root);
|
|
const sourceLink = modal.locator(SELECTORS.summaryModal.sourceLink);
|
|
|
|
// Check link attributes
|
|
await expect(sourceLink).toHaveAttribute("target", "_blank");
|
|
await expect(sourceLink).toHaveAttribute("rel", "noopener");
|
|
await expect(sourceLink).toHaveAttribute("href");
|
|
|
|
// Click should open new tab
|
|
const [newPage] = await Promise.all([
|
|
context.waitForEvent("page"),
|
|
sourceLink.click(),
|
|
]);
|
|
|
|
// New page should have loaded
|
|
expect(newPage).toBeDefined();
|
|
await newPage.close();
|
|
|
|
// Modal should remain open
|
|
await expect(modal).toBeVisible();
|
|
});
|
|
|
|
test("share on X opens correct URL", async ({ page: p, context }) => {
|
|
page = p;
|
|
const modal = page.locator(SELECTORS.summaryModal.root);
|
|
const shareX = modal.locator(SELECTORS.summaryModal.shareX);
|
|
|
|
// Get article headline for URL verification
|
|
const headline = await modal
|
|
.locator(SELECTORS.summaryModal.headline)
|
|
.textContent();
|
|
|
|
// Click should open X share in new tab
|
|
const [newPage] = await Promise.all([
|
|
context.waitForEvent("page"),
|
|
shareX.click(),
|
|
]);
|
|
|
|
// Verify URL contains X intent
|
|
const url = newPage.url();
|
|
expect(url).toContain("x.com/intent/tweet");
|
|
expect(url).toContain(encodeURIComponent(headline || ""));
|
|
|
|
await newPage.close();
|
|
});
|
|
|
|
test("share on WhatsApp opens correct URL", async ({ page: p, context }) => {
|
|
page = p;
|
|
const modal = page.locator(SELECTORS.summaryModal.root);
|
|
const shareWhatsApp = modal.locator(SELECTORS.summaryModal.shareWhatsApp);
|
|
|
|
// Get article headline for URL verification
|
|
const headline = await modal
|
|
.locator(SELECTORS.summaryModal.headline)
|
|
.textContent();
|
|
|
|
// Click should open WhatsApp share in new tab
|
|
const [newPage] = await Promise.all([
|
|
context.waitForEvent("page"),
|
|
shareWhatsApp.click(),
|
|
]);
|
|
|
|
// Verify URL contains WhatsApp share
|
|
const url = newPage.url();
|
|
expect(url).toContain("wa.me");
|
|
expect(url).toContain(encodeURIComponent(headline || ""));
|
|
|
|
await newPage.close();
|
|
});
|
|
|
|
test("share on LinkedIn opens correct URL", async ({ page: p, context }) => {
|
|
page = p;
|
|
const modal = page.locator(SELECTORS.summaryModal.root);
|
|
const shareLinkedIn = modal.locator(SELECTORS.summaryModal.shareLinkedIn);
|
|
|
|
// Click should open LinkedIn share in new tab
|
|
const [newPage] = await Promise.all([
|
|
context.waitForEvent("page"),
|
|
shareLinkedIn.click(),
|
|
]);
|
|
|
|
// Verify URL contains LinkedIn share
|
|
const url = newPage.url();
|
|
expect(url).toContain("linkedin.com/sharing");
|
|
|
|
await newPage.close();
|
|
});
|
|
|
|
test("copy link button copies permalink to clipboard @smoke", async ({
|
|
page: p,
|
|
context,
|
|
}) => {
|
|
page = p;
|
|
const modal = page.locator(SELECTORS.summaryModal.root);
|
|
const copyButton = modal.locator(SELECTORS.summaryModal.shareCopy);
|
|
|
|
// Grant clipboard permissions
|
|
await context.grantPermissions(["clipboard-read", "clipboard-write"]);
|
|
|
|
// Click copy button
|
|
await copyButton.click();
|
|
|
|
// Wait for success message
|
|
const successMessage = modal.locator(SELECTORS.summaryModal.copySuccess);
|
|
await expect(successMessage).toBeVisible();
|
|
await expect(successMessage).toContainText("Permalink copied");
|
|
|
|
// Verify clipboard content
|
|
const clipboardContent = await page.evaluate(() =>
|
|
navigator.clipboard.readText(),
|
|
);
|
|
expect(clipboardContent).toContain("/?article=");
|
|
expect(clipboardContent).toMatch(/http/);
|
|
});
|
|
|
|
test("copy link does not navigate away", async ({ page: p }) => {
|
|
page = p;
|
|
const modal = page.locator(SELECTORS.summaryModal.root);
|
|
const copyButton = modal.locator(SELECTORS.summaryModal.shareCopy);
|
|
|
|
// Get current URL
|
|
const currentUrl = page.url();
|
|
|
|
// Click copy button
|
|
await copyButton.click();
|
|
|
|
// Wait a moment
|
|
await page.waitForTimeout(1000);
|
|
|
|
// URL should not have changed
|
|
await expect(page).toHaveURL(currentUrl);
|
|
|
|
// Modal should still be open
|
|
await expect(modal).toBeVisible();
|
|
});
|
|
|
|
test("navigation is preserved after share interactions", async ({
|
|
page: p,
|
|
context,
|
|
}) => {
|
|
page = p;
|
|
const modal = page.locator(SELECTORS.summaryModal.root);
|
|
|
|
// Interact with multiple share buttons
|
|
const shareButtons = [
|
|
modal.locator(SELECTORS.summaryModal.shareX),
|
|
modal.locator(SELECTORS.summaryModal.shareWhatsApp),
|
|
modal.locator(SELECTORS.summaryModal.shareLinkedIn),
|
|
];
|
|
|
|
for (const button of shareButtons) {
|
|
if (await button.isVisible()) {
|
|
const [newPage] = await Promise.all([
|
|
context.waitForEvent("page"),
|
|
button.click(),
|
|
]);
|
|
await newPage.close();
|
|
|
|
// Modal should remain open after each interaction
|
|
await expect(modal).toBeVisible();
|
|
}
|
|
}
|
|
|
|
// Close modal
|
|
await page.keyboard.press("Escape");
|
|
await page.waitForTimeout(500);
|
|
|
|
// Should be back on main page without navigation
|
|
await expect(page).toHaveURL(/\/$/);
|
|
|
|
// Feed should be visible
|
|
const feed = page.locator(SELECTORS.feed.root);
|
|
await expect(feed).toBeVisible();
|
|
});
|
|
});
|