/** * Reusable test helpers for Playwright tests * * These helpers encapsulate common test patterns to reduce code duplication * and make tests more maintainable. */ import { Page, expect } from '@playwright/test'; const TEST_HANDLE = process.env.TEST_BLUESKY_HANDLE; const TEST_PASSWORD = process.env.TEST_BLUESKY_PASSWORD; if (!TEST_HANDLE || !TEST_PASSWORD) { throw new Error( 'TEST_BLUESKY_HANDLE and TEST_BLUESKY_PASSWORD must be set in .env file' ); } /** * Performs complete OAuth login flow * * This function navigates to the login page and completes the full OAuth flow: * 1. Navigate to /login * 2. Enter handle and click "Log in with Bluesky" * 3. Wait for redirect to Bluesky OAuth page * 4. Enter password and click "Sign in" * 5. Click "Authorize" button * 6. Wait for redirect to /chat * 7. Verify authentication successful * * @param page - The Playwright Page object */ export async function performOAuthLogin(page: Page) { console.log('[Helper] Starting OAuth login flow'); // Navigate to login page await page.goto('/login'); // Fill in handle and initiate OAuth await page.getByLabel('Your Handle').fill(TEST_HANDLE!); // Click button and wait for navigation to Bluesky OAuth page await Promise.all([ page.waitForURL('**/bsky.social/**', { timeout: 30000 }), page.getByRole('button', { name: 'Log in with Bluesky' }).click(), ]); console.log('[Helper] Redirected to Bluesky OAuth page'); // The identifier is pre-filled from our login flow, just fill in password // Use getByRole to avoid strict mode violations with multiple "Password" labeled elements await page.getByRole('textbox', { name: 'Password' }).fill(TEST_PASSWORD!); // Click Sign in button await page.getByRole('button', { name: /sign in/i }).click(); // Wait for the OAuth authorization page by looking for the Authorize button await page.getByRole('button', { name: 'Authorize' }).waitFor({ timeout: 10000 }); console.log('[Helper] On OAuth authorization page'); // Click Authorize button to grant access and wait for redirect await Promise.all([ page.waitForURL('**/chat', { timeout: 20000 }), page.getByRole('button', { name: 'Authorize' }).click(), ]); console.log('[Helper] Successfully authorized, redirected to /chat'); // Verify we're actually logged in by checking for Profile nav link await expect(page.getByText('Profile')).toBeVisible({ timeout: 5000 }); console.log('[Helper] Verified authentication successful'); } /** * Test credentials for use in tests that need them directly */ export const TEST_CREDENTIALS = { handle: TEST_HANDLE, password: TEST_PASSWORD, } as const;