diff --git a/tests/e2e/page_objects/profilePage.ts b/tests/e2e/page_objects/profilePage.ts new file mode 100644 index 000000000..31aab8481 --- /dev/null +++ b/tests/e2e/page_objects/profilePage.ts @@ -0,0 +1,58 @@ +import { Page, Locator } from "@playwright/test" + +export class ProfilePage { + readonly page: Page + readonly spinner: Locator + readonly container: Locator + readonly pendingUpgradeBanner: Locator + readonly profileVisibilityBanner: Locator + readonly profileHeader: Locator + readonly verifyAccountSection: Locator + readonly orgContactInfo: Locator + readonly profileAboutSection: Locator + readonly profileLegislators: Locator + readonly viewTestimony: Locator + + + + constructor(page: Page) { + this.page = page + this.spinner = page.getByRole("status") + this.container = page.locator(".container") + this.pendingUpgradeBanner = page.getByTestId("pending-upgrade-banner") + this.profileVisibilityBanner = page.getByTestId("profile-visibility-banner") + this.profileHeader = page.getByTestId("profile-header") + + this.verifyAccountSection = page.getByTestId("verify-account-section") + this.orgContactInfo = page.getByTestId("org-contact-info") + this.profileAboutSection = page.getByTestId("profile-about-section") + this.profileLegislators = page.getByTestId("profile-legislators") + this.viewTestimony = page.getByTestId("view-testimony") + + // this.profileVisibilityBanner = page.getByText("You are viewing your profile") + // this.publicBannerText = page.getByText("Your profile is public") + // this.privateBannerText = page.getByText("Your profile is private") + + // this.pendingUpgradeBanner = page.getByRole("alert") + // // or + // this.pendingUpgradeBanner = page.getByText("pending", { exact: false }) + } + + async goto(profileId: string) { + await this.page.goto(`http://localhost:3000/profile?id=${profileId}`) + } + + async gotoOrgPorfile(orgId: string) { + await this.page.goto(`http://localhost:3000/profile?id=${orgId}&verifyisorg=true`) + } + + async isPublicProfile(): Promise { + const banner = await this.profileVisibilityBanner.textContent() + return banner?.includes("public") ?? false + } + + async isPrivateProfile(): Promise { + const banner = await this.profileVisibilityBanner.textContent() + return banner?.includes("private") ?? false + } +} diff --git a/tests/e2e/profilePage.spec.ts b/tests/e2e/profilePage.spec.ts new file mode 100644 index 000000000..2a376327a --- /dev/null +++ b/tests/e2e/profilePage.spec.ts @@ -0,0 +1,195 @@ +import { test, expect, type Page, Browser, BrowserContext, chromium } from "@playwright/test" +import { ProfilePage } from "./page_objects/profilePage" +// @ts-check + + +test.describe.serial("Profile Page", () => { + let browser: Browser + let context: BrowserContext + let page: Page + + test.beforeAll(async () => { + + + + browser = await chromium.launch() + context = await browser.newContext() + page = await context.newPage() + + const adminEmail = process.env.TEST_ADMIN_USERNAME + const adminPassword = process.env.TEST_ADMIN_PASSWORD + const url = process.env.APP_API_URL + + + // Ensure admin credentials and URL are set, otherwise throw an error + if (!adminEmail || !adminPassword) { + throw new Error( + "Admin credentials are not defined in the environment variables." + ) + } + + if (!url) { + throw new Error( + "URL credentials are not defined in the environment variables." + ) + } + + // Navigate to the application URL, perform login, and verify successful login + await page.goto(url) + await page.getByRole("button", { name: "Log in / Sign up" }).click() + await page.getByRole("button", { name: "Sign In", exact: true }).click() + await page.fill('input[name="email"]', adminEmail) + await page.fill('input[name="password"]', adminPassword) + await page.click('button[type="submit"]') + + + // //TODO: grab user_id from firebase + // const profilepage = new ProfilePage(page) + // await profilepage.goto() + // Wait for login to complete before proceeding + await expect(page.getByAltText("profileMenu")).toBeVisible() + + // Navigate to profile and wait for it to fully load + await page.getByRole('button', { name: 'profileMenu' }).click() + await page.getByRole('link', { name: 'View Profile' }).click() + + // Wait for a key element that confirms the profile page has rendered + await expect(page.getByAltText("Profile Icon")).toBeVisible({ timeout: 10000 }) + }) + + test.afterAll(async () => { + await context.close() + await browser.close() + + }) + + + //render page to double check how each componenet is stored + + test.describe("Profile Page Information", () => { + test('should display username', async () => { + const username = page.locator("[class*='ProfileDisplayName']") + await expect(username).toBeVisible() + }) + + test('should display user bio', async () => { + //go into edit profile to create a test bio + const testBio = "Test bio" + + + await page.getByRole('button', { name: "Edit Profile" }).click() + await expect(page.getByRole('heading', { name: 'Edit Profile' })).toBeVisible() + + const bio = page.locator("div.form-floating textarea") + await bio.clear() + await bio.fill(testBio) + + await expect(bio).toHaveValue(testBio) + await page.getByRole('button', { name: 'Save Personal Information' }).click() + await expect(page.getByRole('img', { name: 'Profile Icon' })).toBeVisible({ timeout: 10000 }) + + await expect(page.getByText(testBio)).toBeVisible() + + + + }) + + test('should display legislators', async () => { + //TODO: Go into edit profile to add representative/senator + // const representative = page.locator("[class*='LabeledIcon']").filter({ hasText: /^Representative$/ }).first() + // const senator = page.locator("[class*='LabeledIcon']").filter({ hasText: /^Senator$/ }).first() + // await expect(representative).toBeVisible() + // await expect(senator).toBeVisible() + + + + await page.getByRole('button', { name: "Edit Profile" }).click() + await expect(page.getByRole('heading', { name: 'Edit Profile' })).toBeVisible() + + //Pick first rep and senator + await page.getByText('RepresentativeSearch your').click() + await page.getByRole('option', { name: 'Aaron L. Saunders | 7th' }).click() + await page.locator('div').filter({ hasText: /^Search your senator$/ }).nth(2).click() + await page.getByRole('option', { name: 'Adam Gómez | Hampden' }).click() + + await page.getByRole('button', { name: 'Save Personal Information' }).click() + await expect(page.getByRole('img', { name: 'Profile Icon' })).toBeVisible({ timeout: 10000 }) + + // const representative = page.locator("[class*='LabeledIcon']").filter({ hasText: /^Representative$/ }).first() + // const senator = page.locator("[class*='LabeledIcon']").filter({ hasText: /^Senator$/ }).first() + + const representative = page.locator('div').filter({ hasText: /^RepresentativeAaron L\. Saunders$/ }).first() + const senator = page.locator('div').filter({ hasText: /^SenatorAdam Gómez$/ }).first() + await expect(representative).toBeVisible() + await expect(senator).toBeVisible() + + + + + + }) + + test('should display testimonies', async () => { + const testimonies = page.getByText("There are no testimonies") + await expect(testimonies).toBeVisible() + }) + }) + + + + + test.describe("verify banners/buttons on page", () => { + // test.beforeAll(async () => { + // await page.getByRole('button', { name: 'profileMenu' }).click(); + // await page.getByRole('link', { name: 'View Profile' }).click(); + // }) + + test('should display orange banner', async () => { + const banner = page.getByText("Currently viewing your") + await expect(banner).toBeVisible() + }) + + test('should display edit profile button', async () => { + const editProfileButton = page.getByRole('button', { name: "Edit Profile" }) + await expect(editProfileButton).toBeVisible() + await editProfileButton.click() + + }) + + //If user is public, a Make private button should be displayed + test('should display Make Private button', async () => { + + //navigate to make private button + + await page.getByRole('button', { name: 'settings' }).click() + + await expect(page.getByRole('button', { name: 'Make Private' })).toBeVisible() + await page.getByRole('button', { name: 'Make Private' }).click() + await expect(page.getByRole('button', { name: 'Make Public' })).toBeVisible() + await page.getByRole('button', { name: 'Make Public' }).click() + + await page.getByRole('img', { name: 'navigation.closeNavMenu' }).click() + + }) + + test('should display edit option on testimonies', async () => { + await page.getByRole('tab', { name: 'Testimonies' }).click() + const testimonyCount = await page.getByTestId("view-testimony").count() + + if (testimonyCount > 0) { + await expect(page.getByRole("button", {name: /edit/i}).first()).toBeVisible() + } else { + test.skip() + } + + }) + + + }) + + + + + +}) +