From d8097e2f9761ceb6d148d9b455ec470d4506c344 Mon Sep 17 00:00:00 2001 From: nssensalo Date: Mon, 27 Oct 2025 14:04:03 -0700 Subject: [PATCH 1/2] Debugging broken browse-bills and testimony playwright tests --- tests/e2e/browse-bills.spec.ts | 30 +++++++++-------- tests/e2e/page_objects/billPage.ts | 31 ++++++++++++----- tests/e2e/page_objects/testimony.ts | 14 +++++++- tests/e2e/testimony.spec.ts | 52 ++++++++++++++++++----------- 4 files changed, 85 insertions(+), 42 deletions(-) diff --git a/tests/e2e/browse-bills.spec.ts b/tests/e2e/browse-bills.spec.ts index 84303aec2..ebaa62002 100644 --- a/tests/e2e/browse-bills.spec.ts +++ b/tests/e2e/browse-bills.spec.ts @@ -2,22 +2,26 @@ 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() + const billpage = new BillPage(page); - await billpage.search(searchTerm) + const searchTerm = billpage.searchWord; + + await billpage.search(searchTerm); + + await expect(billpage.queryFilter).toBeVisible(); + + await expect(billpage.queryFilter).toContainText(searchTerm); - const searchResultCount = await resultCount.textContent() - await expect(searchResultCount).not.toBe(initialResultCount) + await expect(billpage.firstBill).toBeVisible(); }) test("should show search query", async ({ page }) => { @@ -30,7 +34,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) }) @@ -50,7 +54,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") @@ -118,7 +122,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}`) ) }) diff --git a/tests/e2e/page_objects/billPage.ts b/tests/e2e/page_objects/billPage.ts index b4f77131f..91e70f854 100644 --- a/tests/e2e/page_objects/billPage.ts +++ b/tests/e2e/page_objects/billPage.ts @@ -12,6 +12,8 @@ export class BillPage { readonly currentCategorySelector: string readonly basicCategorySelector: string readonly billPageBackToList: Locator + readonly resultsCountText: Locator + constructor(page: Page) { this.page = page @@ -26,23 +28,23 @@ export class BillPage { "li:nth-child(2) input.ais-RefinementList-checkbox" this.currentCategorySelector = ".ais-CurrentRefinements-item" this.basicCategorySelector = "div.ais-RefinementList.mb-4" + this.resultsCountText = page.getByText("Results").first() + } async goto() { await this.page.goto("http://localhost:3000/bills") - await this.page.waitForSelector("li.ais-Hits-item a") + await this.resultCount.waitFor({ state: 'visible', timeout: 30000 }); +// await this.page.waitForSelector("li.ais-Hits-item a",{timeout:90000}) + } async search(query: string) { - const initialResult = await this.firstBill.textContent() + await this.searchBar.focus(); await this.searchBar.fill(query) - await this.page.waitForFunction(initialResult => { - const searchResult = document.querySelector("li.ais-Hits-item a") - return ( - !searchResult || - (searchResult && searchResult.textContent != initialResult) - ) - }, initialResult) + const activeQueryFilter = this.page.getByText(`Query: ${query}`).first(); + + await activeQueryFilter.waitFor({ state: 'visible', timeout: 50000 }); } async sort(option: string) { @@ -152,4 +154,15 @@ export class BillPage { return filterLabel } + + async removePresetCourtfilter() { + const activeCourtCheckbox = this.page + .locator('div, span, label', { has: this.page.getByText(/Court/i) }) + .getByRole('checkbox', { checked: true }); + + await activeCourtCheckbox.click({ noWaitAfter: true, timeout: 0 }); + + await this.page.getByText("Results").first().waitFor({ state: 'visible', timeout: 60000 }); + + } } diff --git a/tests/e2e/page_objects/testimony.ts b/tests/e2e/page_objects/testimony.ts index 803c4d7f7..57a44658a 100644 --- a/tests/e2e/page_objects/testimony.ts +++ b/tests/e2e/page_objects/testimony.ts @@ -38,7 +38,19 @@ export class TestimonyPage { } async sort(option: string) { - await this.page.getByText("Sort by New -> Old").click() + // previoud code: await this.page.getByText("Sort by New -> Old").click() + await this.page.getByText(/Sort by/i).first().click(); await this.page.getByRole("option", { name: option }).click() } + + async removePresetCourtfilter() { + const activeCourtCheckbox = this.page + .locator('div, span, label', { has: this.page.getByText(/Court/i) }) + .getByRole('checkbox', { checked: true }); + + await activeCourtCheckbox.click({ noWaitAfter: true, timeout: 0 }); + + await this.resultsCountText.waitFor({ state: 'visible', timeout: 60000 }); + + } } diff --git a/tests/e2e/testimony.spec.ts b/tests/e2e/testimony.spec.ts index ab57f6012..4d8ac0be9 100644 --- a/tests/e2e/testimony.spec.ts +++ b/tests/e2e/testimony.spec.ts @@ -1,5 +1,6 @@ import { test, expect } from "@playwright/test" import { TestimonyPage } from "./page_objects/testimony" +import { waitFor } from "@testing-library/dom" test.beforeEach(async ({ page }) => { await page.goto("http://localhost:3000/testimony") @@ -34,7 +35,7 @@ test.describe("Testimony Search", () => { await testimonyPage.search(queryText) const { queryFilterItem, resultsCountText } = testimonyPage - await expect(queryFilterItem).toContainText("query:") + await expect(queryFilterItem).toContainText("Query:") await expect(queryFilterItem).toContainText(queryText) await expect(resultsCountText).toBeVisible() }) @@ -102,33 +103,47 @@ test.describe("Testimony Filtering", () => { }) test("should filter by position: endorse", async ({ page }) => { - await page.getByRole("checkbox", { name: "endorse" }).check() - const testimonyPage = new TestimonyPage(page) - await expect(testimonyPage.positionFilterItem).toContainText("endorse") - await expect(page).toHaveURL(/.*position%5D%5B0%5D=endorse/) + const testimonyPage = new TestimonyPage(page); + testimonyPage.removePresetCourtfilter(); + + const endorseCheckbox = page.getByRole("checkbox", { name: /endorse/i }); + await endorseCheckbox.check({ timeout: 30000 }); + + await expect(testimonyPage.positionFilterItem).toContainText("endorse"); + await expect(page).toHaveURL(/.*position%5D%5B0%5D=endorse/); }) test("should filter by position: neutral", async ({ page }) => { - await page.getByRole("checkbox", { name: "neutral" }).check() - const testimonyPage = new TestimonyPage(page) - await expect(testimonyPage.positionFilterItem).toContainText("neutral") - await expect(page).toHaveURL(/.*position%5D%5B0%5D=neutral/) + const testimonyPage = new TestimonyPage(page); + testimonyPage.removePresetCourtfilter(); + + const checkNeutral = page.getByRole("checkbox", { name: "neutral" }); + await checkNeutral.check({timeout:30000}); + await page.getByRole("checkbox", { name: "neutral" }).check(); + + await expect(testimonyPage.positionFilterItem).toContainText("neutral"); + await expect(page).toHaveURL(/.*position%5D%5B0%5D=neutral/); }) test("should filter by bill", async ({ page }) => { + const testimonyPage = new TestimonyPage(page); + testimonyPage.removePresetCourtfilter(); + const billCheckbox = page.getByLabel(/^[S|H]\d{1,4}$/).first() const billId = await billCheckbox.inputValue() expect(billId).toBeTruthy() if (billId) { await billCheckbox.check() - const testimonyPage = new TestimonyPage(page) await expect(testimonyPage.billFilterItem).toContainText(billId as string) await expect(page).toHaveURL(new RegExp(`.*billId%5D%5B0%5D=${billId}`)) } }) test("should filter by author", async ({ page }) => { + const testimonyPage = new TestimonyPage(page); + testimonyPage.removePresetCourtfilter(); + const writtenByText = await page .getByText(/Written by/) .first() @@ -138,7 +153,6 @@ test.describe("Testimony Filtering", () => { if (writtenByText) { const authorName = writtenByText.slice(11) await page.getByRole("checkbox", { name: authorName }).check() - const testimonyPage = new TestimonyPage(page) await expect(testimonyPage.authorFilterItem).toContainText(authorName) await expect(page).toHaveURL( new RegExp( @@ -151,16 +165,16 @@ test.describe("Testimony Filtering", () => { test.describe("Testimony Sorting", () => { test("should sort by new -> old", async ({ page }) => { - const testimonyPage = new TestimonyPage(page) - await testimonyPage.sort("Sort by New -> Old") - const sortValue = page.getByText("Sort by New -> Old", { exact: true }) - await expect(sortValue).toBeVisible() + const testimonyPage = new TestimonyPage(page); + await testimonyPage.sort("Sort by New -> Old"); + const sortValue = page.getByText("Sort by New -> Old", { exact: true }); + await expect(sortValue).toBeVisible(); }) test("should sort by old -> new", async ({ page }) => { - const testimonyPage = new TestimonyPage(page) - await testimonyPage.sort("Sort by Old -> New") - const sortValue = page.getByText("Sort by Old -> New", { exact: true }) - await expect(sortValue).toBeVisible() + const testimonyPage = new TestimonyPage(page); + await testimonyPage.sort("Sort by Old -> New"); + const sortValue = page.getByText("Sort by Old -> New", { exact: true }); + await expect(sortValue).toBeVisible(); }) }) From 01d3df422b15312d7bb95b57f8890890857aebb0 Mon Sep 17 00:00:00 2001 From: nssensalo Date: Mon, 27 Oct 2025 20:35:00 -0700 Subject: [PATCH 2/2] re-submitting after running linting --- tests/e2e/browse-bills.spec.ts | 20 +++++----- tests/e2e/page_objects/billPage.ts | 35 ++++++++-------- tests/e2e/page_objects/testimony.ts | 20 +++++----- tests/e2e/testimony.spec.ts | 62 ++++++++++++++--------------- 4 files changed, 68 insertions(+), 69 deletions(-) diff --git a/tests/e2e/browse-bills.spec.ts b/tests/e2e/browse-bills.spec.ts index ebaa62002..a409e6075 100644 --- a/tests/e2e/browse-bills.spec.ts +++ b/tests/e2e/browse-bills.spec.ts @@ -5,23 +5,21 @@ test.beforeEach(async ({ page }) => { 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 billpage = new BillPage(page) + + const searchTerm = billpage.searchWord + + await billpage.search(searchTerm) + + await expect(billpage.queryFilter).toBeVisible() - const searchTerm = billpage.searchWord; - - await billpage.search(searchTerm); - - await expect(billpage.queryFilter).toBeVisible(); - - await expect(billpage.queryFilter).toContainText(searchTerm); + await expect(billpage.queryFilter).toContainText(searchTerm) - await expect(billpage.firstBill).toBeVisible(); + await expect(billpage.firstBill).toBeVisible() }) test("should show search query", async ({ page }) => { diff --git a/tests/e2e/page_objects/billPage.ts b/tests/e2e/page_objects/billPage.ts index 91e70f854..62adcf24f 100644 --- a/tests/e2e/page_objects/billPage.ts +++ b/tests/e2e/page_objects/billPage.ts @@ -14,7 +14,6 @@ export class BillPage { readonly billPageBackToList: Locator readonly resultsCountText: Locator - constructor(page: Page) { this.page = page this.searchWord = "health" @@ -29,22 +28,20 @@ export class BillPage { this.currentCategorySelector = ".ais-CurrentRefinements-item" this.basicCategorySelector = "div.ais-RefinementList.mb-4" this.resultsCountText = page.getByText("Results").first() - } async goto() { await this.page.goto("http://localhost:3000/bills") - await this.resultCount.waitFor({ state: 'visible', timeout: 30000 }); -// await this.page.waitForSelector("li.ais-Hits-item a",{timeout:90000}) - + await this.resultCount.waitFor({ state: "visible", timeout: 30000 }) + // await this.page.waitForSelector("li.ais-Hits-item a",{timeout:90000}) } async search(query: string) { - await this.searchBar.focus(); + await this.searchBar.focus() await this.searchBar.fill(query) - const activeQueryFilter = this.page.getByText(`Query: ${query}`).first(); - - await activeQueryFilter.waitFor({ state: 'visible', timeout: 50000 }); + const activeQueryFilter = this.page.getByText(`Query: ${query}`).first() + + await activeQueryFilter.waitFor({ state: "visible", timeout: 50000 }) } async sort(option: string) { @@ -154,15 +151,17 @@ export class BillPage { return filterLabel } - + async removePresetCourtfilter() { - const activeCourtCheckbox = this.page - .locator('div, span, label', { has: this.page.getByText(/Court/i) }) - .getByRole('checkbox', { checked: true }); - - await activeCourtCheckbox.click({ noWaitAfter: true, timeout: 0 }); - - await this.page.getByText("Results").first().waitFor({ state: 'visible', timeout: 60000 }); - + const activeCourtCheckbox = this.page + .locator("div, span, label", { has: this.page.getByText(/Court/i) }) + .getByRole("checkbox", { checked: true }) + + await activeCourtCheckbox.click({ noWaitAfter: true, timeout: 0 }) + + await this.page + .getByText("Results") + .first() + .waitFor({ state: "visible", timeout: 60000 }) } } diff --git a/tests/e2e/page_objects/testimony.ts b/tests/e2e/page_objects/testimony.ts index 57a44658a..02baca3f1 100644 --- a/tests/e2e/page_objects/testimony.ts +++ b/tests/e2e/page_objects/testimony.ts @@ -39,18 +39,20 @@ export class TestimonyPage { async sort(option: string) { // previoud code: await this.page.getByText("Sort by New -> Old").click() - await this.page.getByText(/Sort by/i).first().click(); + await this.page + .getByText(/Sort by/i) + .first() + .click() await this.page.getByRole("option", { name: option }).click() } async removePresetCourtfilter() { - const activeCourtCheckbox = this.page - .locator('div, span, label', { has: this.page.getByText(/Court/i) }) - .getByRole('checkbox', { checked: true }); - - await activeCourtCheckbox.click({ noWaitAfter: true, timeout: 0 }); - - await this.resultsCountText.waitFor({ state: 'visible', timeout: 60000 }); - + const activeCourtCheckbox = this.page + .locator("div, span, label", { has: this.page.getByText(/Court/i) }) + .getByRole("checkbox", { checked: true }) + + await activeCourtCheckbox.click({ noWaitAfter: true, timeout: 0 }) + + await this.resultsCountText.waitFor({ state: "visible", timeout: 60000 }) } } diff --git a/tests/e2e/testimony.spec.ts b/tests/e2e/testimony.spec.ts index 4d8ac0be9..94a1c56ea 100644 --- a/tests/e2e/testimony.spec.ts +++ b/tests/e2e/testimony.spec.ts @@ -103,32 +103,32 @@ test.describe("Testimony Filtering", () => { }) test("should filter by position: endorse", async ({ page }) => { - const testimonyPage = new TestimonyPage(page); - testimonyPage.removePresetCourtfilter(); - - const endorseCheckbox = page.getByRole("checkbox", { name: /endorse/i }); - await endorseCheckbox.check({ timeout: 30000 }); - - await expect(testimonyPage.positionFilterItem).toContainText("endorse"); - await expect(page).toHaveURL(/.*position%5D%5B0%5D=endorse/); + const testimonyPage = new TestimonyPage(page) + testimonyPage.removePresetCourtfilter() + + const endorseCheckbox = page.getByRole("checkbox", { name: /endorse/i }) + await endorseCheckbox.check({ timeout: 30000 }) + + await expect(testimonyPage.positionFilterItem).toContainText("endorse") + await expect(page).toHaveURL(/.*position%5D%5B0%5D=endorse/) }) test("should filter by position: neutral", async ({ page }) => { - const testimonyPage = new TestimonyPage(page); - testimonyPage.removePresetCourtfilter(); - - const checkNeutral = page.getByRole("checkbox", { name: "neutral" }); - await checkNeutral.check({timeout:30000}); - await page.getByRole("checkbox", { name: "neutral" }).check(); - - await expect(testimonyPage.positionFilterItem).toContainText("neutral"); - await expect(page).toHaveURL(/.*position%5D%5B0%5D=neutral/); + const testimonyPage = new TestimonyPage(page) + testimonyPage.removePresetCourtfilter() + + const checkNeutral = page.getByRole("checkbox", { name: "neutral" }) + await checkNeutral.check({ timeout: 30000 }) + await page.getByRole("checkbox", { name: "neutral" }).check() + + await expect(testimonyPage.positionFilterItem).toContainText("neutral") + await expect(page).toHaveURL(/.*position%5D%5B0%5D=neutral/) }) test("should filter by bill", async ({ page }) => { - const testimonyPage = new TestimonyPage(page); - testimonyPage.removePresetCourtfilter(); - + const testimonyPage = new TestimonyPage(page) + testimonyPage.removePresetCourtfilter() + const billCheckbox = page.getByLabel(/^[S|H]\d{1,4}$/).first() const billId = await billCheckbox.inputValue() expect(billId).toBeTruthy() @@ -141,9 +141,9 @@ test.describe("Testimony Filtering", () => { }) test("should filter by author", async ({ page }) => { - const testimonyPage = new TestimonyPage(page); - testimonyPage.removePresetCourtfilter(); - + const testimonyPage = new TestimonyPage(page) + testimonyPage.removePresetCourtfilter() + const writtenByText = await page .getByText(/Written by/) .first() @@ -165,16 +165,16 @@ test.describe("Testimony Filtering", () => { test.describe("Testimony Sorting", () => { test("should sort by new -> old", async ({ page }) => { - const testimonyPage = new TestimonyPage(page); - await testimonyPage.sort("Sort by New -> Old"); - const sortValue = page.getByText("Sort by New -> Old", { exact: true }); - await expect(sortValue).toBeVisible(); + const testimonyPage = new TestimonyPage(page) + await testimonyPage.sort("Sort by New -> Old") + const sortValue = page.getByText("Sort by New -> Old", { exact: true }) + await expect(sortValue).toBeVisible() }) test("should sort by old -> new", async ({ page }) => { - const testimonyPage = new TestimonyPage(page); - await testimonyPage.sort("Sort by Old -> New"); - const sortValue = page.getByText("Sort by Old -> New", { exact: true }); - await expect(sortValue).toBeVisible(); + const testimonyPage = new TestimonyPage(page) + await testimonyPage.sort("Sort by Old -> New") + const sortValue = page.getByText("Sort by Old -> New", { exact: true }) + await expect(sortValue).toBeVisible() }) })