import { expect, test } from "@playwright/test"; test("home page loads with Buzz heading", async ({ page }) => { await page.goto("/"); await expect(page.locator("header")).toContainText("Buzz"); }); test("home page shows repositories section", async ({ page }) => { await page.goto("/"); await expect(page.getByText("Repositories")).toBeVisible(); }); test("invite requires age and legal consent before opening Buzz", async ({ page, }) => { await page.route("**/api/join-policy", async (route) => { await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ policy: { terms_markdown: "# Terms", privacy_markdown: "# Privacy", age_attestation_required: true, version: "policy-v1", }, }), }); }); await page.route("https://api.github.com/**", async (route) => { await route.fulfill({ status: 200, contentType: "application/json", headers: { "Access-Control-Allow-Origin": "*" }, body: JSON.stringify([ { draft: false, prerelease: false, assets: [] }, { draft: false, prerelease: false, assets: [ { name: "Buzz_0.4.9_aarch64.dmg", browser_download_url: "https://github.com/block/buzz/releases/download/v0.4.9/Buzz_0.4.9_aarch64.dmg", }, { name: "Buzz_0.4.9_x64.dmg", browser_download_url: "https://github.com/block/buzz/releases/download/v0.4.9/Buzz_0.4.9_x64.dmg", }, { name: "Buzz_0.4.9_amd64.AppImage", browser_download_url: "https://github.com/block/buzz/releases/download/v0.4.9/Buzz_0.4.9_amd64.AppImage", }, { name: "Buzz_0.4.9_x64-setup_alpha-unsigned.exe", browser_download_url: "https://github.com/block/buzz/releases/download/v0.4.9/Buzz_0.4.9_x64-setup_alpha-unsigned.exe", }, ], }, ]), }); }); await page.goto("/invite/demo-code"); await expect( page.getByRole("link", { name: "Download it now" }), ).toHaveAttribute( "href", "https://github.com/block/buzz/releases/download/v0.4.9/Buzz_0.4.9_x64-setup_alpha-unsigned.exe", ); const ageConfirmation = page.getByLabel("I am 18 years of age or older."); const agreementConfirmation = page.getByLabel( "I agree to the Buzz Terms of Service and Privacy Policy.", ); const acceptInvite = page.getByRole("button", { name: "Accept invite in Buzz", }); await expect(ageConfirmation).toBeVisible(); await expect(agreementConfirmation).toBeVisible(); await expect(acceptInvite).toBeDisabled(); const termsLink = page.getByRole("button", { name: "Terms of Service" }); const privacyLink = page.getByRole("button", { name: "Privacy Policy" }); await expect(termsLink).toHaveCSS("text-decoration-line", "none"); await expect(privacyLink).toHaveCSS("text-decoration-line", "none"); await termsLink.hover(); await expect(termsLink).toHaveCSS("text-decoration-line", "underline"); await page.mouse.move(0, 0); await privacyLink.hover(); await expect(privacyLink).toHaveCSS("text-decoration-line", "underline"); await page .locator("label") .filter({ hasText: "I am 18 years of age or older." }) .click(); await expect(ageConfirmation).toBeChecked(); await expect(acceptInvite).toBeDisabled(); await page .locator("label") .filter({ hasText: "I agree to the Buzz Terms of Service and Privacy Policy.", }) .click({ position: { x: 8, y: 8 } }); await expect(agreementConfirmation).toBeChecked(); await expect(acceptInvite).toBeEnabled(); const consentBox = await page .getByTestId("invite-join-policy-notice") .boundingBox(); const acceptButtonBox = await acceptInvite.boundingBox(); expect(consentBox?.y).toBeLessThan(acceptButtonBox?.y ?? 0); expect(consentBox?.width).toBe(acceptButtonBox?.width); }); test("invite download falls back for mobile and non-desktop devices", async ({ browser, }) => { const unsupportedDevices = [ { name: "iPhone Safari", platform: "iPhone", userAgent: "Mozilla/5.0 (iPhone; CPU iPhone OS 18_5 like Mac OS X) AppleWebKit/605.1.15", maxTouchPoints: 5, }, { name: "iPadOS desktop mode", platform: "MacIntel", userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15", maxTouchPoints: 5, }, { name: "Android phone", platform: "Linux armv8l", userAgent: "Mozilla/5.0 (Linux; Android 15; Pixel 9 Pro) AppleWebKit/537.36 Mobile", maxTouchPoints: 5, }, { name: "ChromeOS", platform: "Linux x86_64", userAgent: "Mozilla/5.0 (X11; CrOS x86_64 16093.68.0) AppleWebKit/537.36", maxTouchPoints: 0, }, ]; for (const device of unsupportedDevices) { const context = await browser.newContext({ userAgent: device.userAgent }); await context.addInitScript(({ platform, maxTouchPoints }) => { Object.defineProperties(navigator, { platform: { configurable: true, value: platform }, maxTouchPoints: { configurable: true, value: maxTouchPoints }, userAgentData: { configurable: true, value: { platform, mobile: maxTouchPoints > 0 }, }, }); }, device); const page = await context.newPage(); await page.route("**/api/join-policy", async (route) => { await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ policy: null }), }); }); await page.route("https://api.github.com/**", async (route) => { await route.fulfill({ status: 200, contentType: "application/json", headers: { "Access-Control-Allow-Origin": "*" }, body: JSON.stringify([ { draft: false, prerelease: false, assets: [ { name: "Buzz_0.4.9_x64.dmg", browser_download_url: "https://github.com/block/buzz/releases/download/v0.4.9/Buzz_0.4.9_x64.dmg", }, { name: "Buzz_0.4.9_amd64.AppImage", browser_download_url: "https://github.com/block/buzz/releases/download/v0.4.9/Buzz_0.4.9_amd64.AppImage", }, ], }, ]), }); }); await page.goto("/invite/demo-code"); await expect( page.getByRole("link", { name: "Download it now" }), device.name, ).toHaveAttribute("href", "https://github.com/block/buzz/releases"); await context.close(); } });