import { expect } from "@playwright/test"; import type { Page } from "@playwright/test"; import { doOnOrgDomain } from "playwright/lib/testUtils"; import { v4 as uuid } from "uuid"; import { SchedulingType } from "@calcom/prisma/enums"; import type { CreateUsersFixture } from "../fixtures/users"; import { test } from "../lib/fixtures"; async function setupOrgMember(users: CreateUsersFixture) { const orgRequestedSlug = `example-${uuid()}`; const orgMember = await users.create(undefined, { hasTeam: true, isOrg: true, hasSubteam: true, isOrgVerified: true, isDnsSetup: true, orgRequestedSlug, schedulingType: SchedulingType.ROUND_ROBIN, }); const { team: org } = await orgMember.getOrgMembership(); const { team } = await orgMember.getFirstTeamMembership(); const teamEvent = await orgMember.getFirstTeamEvent(team.id); const userEvent = orgMember.eventTypes[0]; await orgMember.apiLogin(); return { orgMember, org, team, teamEvent, userEvent }; } type TestContext = Awaited>; interface ToggleSeoSwitchParams { page: Page; switchTestId: string; expectedChecked: boolean; waitForMessage?: string; } interface VerifyRobotsMetaTagParams { page: Page; orgSlug: string | null; urls: string[]; expectedContent: string; } // Helper function to toggle the SEO switch async function toggleSeoSwitch({ page, switchTestId, expectedChecked, waitForMessage, }: ToggleSeoSwitchParams): Promise { const seoSwitch = await page.getByTestId(switchTestId); await seoSwitch.click(); await expect(seoSwitch).toBeChecked({ checked: expectedChecked }); if (waitForMessage) { await page.waitForSelector(`text=${waitForMessage}`); } } async function verifyRobotsMetaTag({ page, orgSlug, urls, expectedContent }: VerifyRobotsMetaTagParams) { await doOnOrgDomain({ orgSlug, page }, async ({ page, goToUrlWithErrorHandling }) => { for (const relativeUrl of urls) { const { url } = await goToUrlWithErrorHandling(relativeUrl); const metaTag = await page.locator('head > meta[name="robots"]'); const metaTagValue = await metaTag.getAttribute("content"); expect(metaTagValue).not.toBeNull(); expect( metaTagValue ?.split(",") .map((s) => s.trim()) .join(",") ).toEqual( expectedContent .split(",") .map((s) => s.trim()) .join(",") ); } }); } test.describe("Organization Settings", () => { test.describe("Setting - 'Allow search engine indexing' inside Org profile settings", async () => { let ctx: TestContext; test.beforeEach(async ({ users }) => { ctx = await setupOrgMember(users); }); test.afterEach(async ({ users }) => { await users.deleteAll(); }); test("Disabling SEO indexing updates settings and meta tags", async ({ page }) => { await test.step("Disable 'Allow search engine indexing' for organization", async () => { await page.goto(`/settings/organizations/profile`); const seoSwitch = await page.getByTestId(`${ctx.org.id}-seo-indexing-switch`); await expect(seoSwitch).toBeChecked({ checked: false }); }); await test.step("Verify 'robots' meta tag for different pages when SEO indexing is disabled", async () => { const { team, teamEvent, org, orgMember, userEvent } = ctx; await verifyRobotsMetaTag({ page, orgSlug: org.slug, urls: [ `/team/${team.slug}`, `/team/${team.slug}/${teamEvent.slug}`, `/${orgMember.username}`, `/${orgMember.username}/${userEvent.slug}`, ], expectedContent: "noindex,nofollow", }); }); }); test("Enabling SEO indexing updates settings and meta tags", async ({ page }) => { await test.step("Enable 'Allow search engine indexing' for organization", async () => { await page.goto(`/settings/organizations/profile`); await toggleSeoSwitch({ page, switchTestId: `${ctx.org.id}-seo-indexing-switch`, expectedChecked: true, waitForMessage: "Your team has been updated successfully.", }); }); await test.step("Verify 'robots' meta tag for different pages when SEO indexing is enabled", async () => { const { team, teamEvent, org, orgMember, userEvent } = ctx; await verifyRobotsMetaTag({ page, orgSlug: org.slug, urls: [ `/team/${team.slug}`, `/team/${team.slug}/${teamEvent.slug}`, `/${orgMember.username}`, `/${orgMember.username}/${userEvent.slug}`, ], expectedContent: "index,follow", }); }); }); test("Organization settings override user settings", async ({ page }) => { await test.step("Disable 'Allow search engine indexing' for organization", async () => { await page.goto(`/settings/organizations/profile`); const seoSwitch = await page.getByTestId(`${ctx.org.id}-seo-indexing-switch`); await expect(seoSwitch).toBeChecked({ checked: false }); }); await test.step("Verify organization settings override user settings for 'robots' meta tag", async () => { const { org, orgMember, userEvent } = ctx; await verifyRobotsMetaTag({ page, orgSlug: org.slug, urls: [`/${orgMember.username}/${userEvent.slug}`], expectedContent: "noindex,nofollow", }); }); }); }); });