Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default defineConfig({
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
workers: process.env.CI ? 1 : 1,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: "html",
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
Expand All @@ -46,15 +46,15 @@ export default defineConfig({
use: {
...devices["Desktop Firefox"]
}
},

{
name: "webkit",
use: {
...devices["Desktop Safari"]
}
}

// {
// name: "webkit",
// use: {
// ...devices["Desktop Safari"]
// }
// }

/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
Expand Down
20 changes: 11 additions & 9 deletions tests/e2e/browse-bills.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,24 @@ import { test, expect } from "@playwright/test"
import { BillPage } from "./page_objects/billPage"

test.beforeEach(async ({ page }) => {
await page.goto("http://localhost:3000/bills")
await page.waitForSelector("li.ais-Hits-item a")
const billpage = new BillPage(page)
await billpage.goto()
await billpage.removePresetCourtfilter()
})

test.describe("Search result test", () => {
test("should search for bills", async ({ page }) => {
const billpage = new BillPage(page)

const searchTerm = billpage.searchWord
const resultCount = billpage.resultCount
const initialResultCount = await resultCount.textContent()

await billpage.search(searchTerm)

const searchResultCount = await resultCount.textContent()
await expect(searchResultCount).not.toBe(initialResultCount)
await expect(billpage.queryFilter).toBeVisible()

await expect(billpage.queryFilter).toContainText(searchTerm)

await expect(billpage.firstBill).toBeVisible()
})

test("should show search query", async ({ page }) => {
Expand All @@ -30,7 +32,7 @@ test.describe("Search result test", () => {

const queryFilter = await billpage.queryFilter

await expect(queryFilter).toContainText("query:")
await expect(queryFilter).toContainText("Query:")
await expect(queryFilter).toContainText(searchTerm)
})

Expand All @@ -50,7 +52,7 @@ test.describe("Search result test", () => {
const searchTerm = "nonexistentsearchterm12345"
const billpage = new BillPage(page)

billpage.search(searchTerm)
await billpage.search(searchTerm)

const noResultsText = await page.getByText("Looks Pretty Empty Here")
const noResultsImg = page.getByAltText("No Results")
Expand Down Expand Up @@ -118,7 +120,7 @@ test.describe("Filter Bills test", () => {
"%27"
)
await expect(page).toHaveURL(
new RegExp(`court%5D%5B1%5D=${encodedFilterLabel}`)
new RegExp(`court%5D%5B0%5D=${encodedFilterLabel}`)
)
})

Expand Down
283 changes: 283 additions & 0 deletions tests/e2e/editProfile.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
import { test, expect, Page, Locator, Browser } from "@playwright/test"
import { EditProfilePage } from "./page_objects/editProfilePage"
import { userLogin, setupPage } from "./utils/login"
import { removeSpecialChar } from "./utils/removeSpecialChar"
import { gotoStable } from "./utils/goto"

require("dotenv").config()

/**
* @param USER_EMAIL
* @param USER_PASSWORD
* @returns
*/

const USER_EMAIL = process.env.TEST_USER_USERNAME
const USER_PASSWORD = process.env.TEST_USER_PASSWORD

test.describe.serial("Edit Page", () => {
test("Prevents User A from editing User B profile", async ({ browser }) => {
/*
Logs in user and stores session state
*/
const context = await browser.newContext()
const page = await context.newPage()
try {
let userAStateObject: { cookies: any[]; origins: any[] } //stores current user/userA sesssion state

await userLogin(page, USER_EMAIL, USER_PASSWORD)

const url = "http://localhost:3000/edit-profile/about-you"
await gotoStable(page, url)

userAStateObject = await page.context().storageState() // save userA's session state

/*
Prevents user A from manipulating url to access userB's profile
*/
const userBID = "d6ZFKTVH8i4hglyv42wz8QDaKKxw" //from [email protected] test account on firebase
const attackUrl = `http://localhost:3000/profile?id=${userBID}` //manipulating url with userB's id
const attackPath = new RegExp(`.*\\/profile\\?id=${userBID}`) //manipulating path

await gotoStable(page, attackUrl)

await expect(page).not.toHaveURL(/.*\/edit-profile\/about-you/) //asserts that is doesn't navigate to userB's edit profile page

await page.waitForURL(attackPath)
await expect(page).toHaveURL(attackPath) // asserts that the manipualted URL path is the view profile page for user B

await expect(page.getByText("404")).toBeVisible() // asserts that the page shows error messages
await expect(page.getByText("This page could not be found")).toBeVisible()
} finally {
await context.close()
}
})

test.only("Assures user can add to blank profile page", async ({
browser
}) => {
/*
Fills blank fields with same sample data and
confirms edits were saved.
*/
const { page, context } = await setupPage(browser)

const editPage = new EditProfilePage(page)

await userLogin(page, USER_EMAIL, USER_PASSWORD)

const url = "http://localhost:3000/edit-profile/about-you"
await gotoStable(page, url)

//sample input
const sampleName = "John Doe"
const sampleText = "I ❤️ politics"
const sampleTwitter = "jdoe"
const sampleLinkedIn = "https://www.linkedIn.com/in/jdoe"
const sampleRepresentative = "Alan Silvia"
// const sampleRepresentative = "Aaron L. Saunders" //NOTE: names with middle initials need a space after initial
const sampleSenator = "Adam Gomez"
// const sampleSenator = "Bruce E. Tarr"

// clear and fill with sample data
await expect(editPage.editName).toHaveCount(1, { timeout: 100_000 })
await expect(editPage.editName).toBeVisible({ timeout: 50_000 })
await expect(editPage.editName).toBeEnabled()
await editPage.editName.waitFor({ state: "attached", timeout: 50_000 })
await editPage.editName.click()
await editPage.editName.fill("")
await editPage.editName.fill(sampleName)
await expect(editPage.editName).toHaveValue(sampleName, { timeout: 50_000 })
await editPage.editWriteAboutSelf.clear()
await editPage.editWriteAboutSelf.fill(sampleText)
await editPage.editTwitterUsername.clear()
await editPage.editTwitterUsername.fill(sampleTwitter)
await editPage.editLinkedInUrl.clear()
await editPage.editLinkedInUrl.fill(sampleLinkedIn)
await editPage.editRepresentative.pressSequentially(sampleRepresentative, {
delay: 50
})
await page.waitForTimeout(50)
await page.keyboard.press("Enter")
await editPage.editSenator.pressSequentially(sampleSenator, { delay: 50 })
await page.waitForTimeout(50)
await page.keyboard.press("Enter")

// save
await editPage.saveChangesButton.click()
await page.keyboard.press("Enter") //save-button activated -rerouting to profile page

//assertion: Assure it saved
//name
await expect(page.getByText(sampleName)).toHaveText(sampleName, {
timeout: 50000
})
//(about) text
await expect(page.getByText(sampleText, { exact: true })).toHaveText(
sampleText
)
//representative
const repRow = page.locator(
'div:has(> .main-text:has-text("Representative"))'
)
await expect(repRow.locator("p.sub-text")).toContainText(
sampleRepresentative
)

//senator
const senRow = page
.locator(".main-text", { hasText: "Senator" })
.locator('xpath=following-sibling::p[contains(@class,"sub-text")]')
await removeSpecialChar(senRow, sampleSenator)

//twitter
const sampleTwitterNewPage = "jdoe"

const twitterLink = page.locator('a:has(img[alt="Twitter"])')

await expect(twitterLink).toHaveAttribute(
"href",
new RegExp(sampleTwitterNewPage)
)

await context.close()
})

test("User can enable and disable notification settings", async ({
browser
}) => {
const { page, context } = await setupPage(browser)
const editPage = new EditProfilePage(page)

await userLogin(page, USER_EMAIL, USER_PASSWORD)

const url = "http://localhost:3000/edit-profile/about-you"
await gotoStable(page, url)

/**
* @param page
* @param saveButton The save button in notifications
*/
const saveButton = page.getByRole("button", { name: "Save", exact: true })

async function toggleEnabledButton(page: Page, saveButton: Locator) {
const enableButton = page.getByRole("button", { name: "Enable" })
const disableButton = page.getByRole("button", { name: "Enabled" })
const settingsButton = page.getByRole("button", {
name: "settings",
exact: true
})

await expect(settingsButton).toBeEnabled()

await settingsButton.click()

if (await enableButton.isVisible()) {
await enableButton.click()

await disableButton.isVisible()

await saveButton.click()

//verify
await page
.getByRole("button", { name: "settings", exact: true })
.click()

await disableButton.isVisible()
} else if (await disableButton.isVisible()) {
await disableButton.click()

await enableButton.isVisible()

await saveButton.click()

//verify

await page
.getByRole("button", { name: "settings", exact: true })
.click()

expect(enableButton).toBeVisible({ timeout: 15000 })
} else {
throw new Error("Unable to locate enable/d button")
}
}
try {
await toggleEnabledButton(page, saveButton)
} finally {
await context.close()
}
})

test("User can toggle private/public settings and save them", async ({
browser
}) => {
const { page, context } = await setupPage(browser)

await userLogin(page, USER_EMAIL, USER_PASSWORD)

const url = "http://localhost:3000/edit-profile/about-you"
await gotoStable(page, url)

const saveButton = page.getByRole("button", { name: "Save", exact: true })

/**
* @param page
* @param saveButton The save button in notifications
*/
async function togglePrivacyButton(page: Page, saveButton: Locator) {
const makePublic = page.getByRole("button", { name: "Make Public" })
const makePrivate = page.getByRole("button", { name: "Make Private" })
const settingsButton = page.getByRole("button", {
name: "settings",
exact: true
})

await expect(settingsButton).toBeEnabled({ timeout: 10000 })

await settingsButton.click()

// ----default is private---

// test button toggling
if (await makePublic.isVisible({ timeout: 20000 })) {
await makePublic.click()

await makePrivate.isVisible({ timeout: 20000 })
} else if (await makePrivate.isVisible({ timeout: 20000 })) {
await makePrivate.click()

await makePublic.isVisible({ timeout: 20000 })
} else {
throw Error(
"Public/Private Button is not visable or toggling correctly"
)
}

// Verify public/private state gets saved
if (await makePrivate.isVisible({ timeout: 20000 })) {
await saveButton.click()

await page
.getByRole("button", { name: "settings", exact: true })
.click()

await expect(makePrivate).toBeVisible({ timeout: 20000 })
} else if (await makePublic.isVisible({ timeout: 20000 })) {
await saveButton.click()

await page
.getByRole("button", { name: "settings", exact: true })
.click()

await expect(makePublic).toBeVisible({ timeout: 10000 })
}
}
try {
await togglePrivacyButton(page, saveButton)
} finally {
await context.close()
}
})
})
Loading