From a40a8a91b18b23eac48687ba2c0703a460fa0faf Mon Sep 17 00:00:00 2001 From: Niraj Date: Mon, 2 Jun 2025 16:28:16 +0545 Subject: [PATCH 1/3] feat: enhance sorting functionality for proposed governance actions --- .../lib/pages/proposalDiscussionPage.ts | 29 +++++++++-- .../govtool-frontend/playwright/lib/types.ts | 21 ++++++++ .../proposalDiscussion.spec.ts | 50 +++++++++++++++---- 3 files changed, 85 insertions(+), 15 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts b/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts index 07da72fda..c2c301c39 100644 --- a/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts @@ -1,5 +1,10 @@ import { expect, Locator, Page } from "@playwright/test"; -import { ProposalCreateRequest, ProposalType, ProposedGovAction } from "@types"; +import { + ProposalCreateRequest, + ProposalDiscussionFilterTypes, + ProposalType, + ProposedGovAction, +} from "@types"; import environments from "lib/constants/environments"; import ProposalDiscussionDetailsPage from "./proposalDiscussionDetailsPage"; import { functionWaitedAssert, waitedLoop } from "@helpers/waitedLoop"; @@ -147,16 +152,30 @@ export default class ProposalDiscussionPage { } async sortAndValidate( - option: "asc" | "desc", + type: ProposalDiscussionFilterTypes, validationFn: (p1: ProposedGovAction, p2: ProposedGovAction) => boolean ) { + const sortMappings = { + "Name A-Z": "&sort[prop_name]=ASC", + "Name Z-A": "&sort[prop_name]=DESC", + "Most comments": "&sort[proposal][prop_comments_number]=DESC", + "Least comments": "&sort[proposal][prop_comments_number]=ASC", + "Most likes": "&sort[proposal][prop_likes]=DESC", + "Least likes": "&sort[proposal][prop_likes]=ASC", + "Most dislikes": "&sort[proposal][prop_dislikes]=DESC", + "Least dislikes": "&sort[proposal][prop_dislikes]=ASC", + Oldest: "&sort[createdAt]=ASC", + Newest: "&sort[createdAt]=DESC", + }; + + const urlParam = sortMappings[type]; + const populateParam = "&populate[0]=proposal_links"; const responsePromise = this.page.waitForResponse((response) => - response - .url() - .includes(`&sort[createdAt]=${option}&populate[0]=proposal_links`) + response.url().includes(`${urlParam}${populateParam}`) ); await this.sortBtn.click(); + await this.page.getByTestId(`${type}-sort-option`).click(); const response = await responsePromise; let proposals: ProposedGovAction[] = (await response.json()).data; diff --git a/tests/govtool-frontend/playwright/lib/types.ts b/tests/govtool-frontend/playwright/lib/types.ts index 5ac7273ca..2ffdac42c 100644 --- a/tests/govtool-frontend/playwright/lib/types.ts +++ b/tests/govtool-frontend/playwright/lib/types.ts @@ -201,8 +201,17 @@ export type ProposedGovAction = { attributes: { gov_action_type_name: string; prop_comments_number: number; + prop_likes: number; + prop_dislikes: number; createdAt: string; updatedAt: string; + content: { + id: string; + attributes: { + proposal_id: string; + prop_name: string; + }; + }; creator: { data: { id: number; @@ -547,3 +556,15 @@ export type BudgetProposalFilterTypes = | "Name Z-A" | "Proposer A-Z" | "Proposer Z-A"; + +export type ProposalDiscussionFilterTypes = + | "Newest" + | "Oldest" + | "Most likes" + | "Least likes" + | "Most dislikes" + | "Least dislikes" + | "Most comments" + | "Least comments" + | "Name A-Z" + | "Name Z-A"; diff --git a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts index cdecc19cc..a895ecfa5 100644 --- a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts +++ b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts @@ -13,7 +13,11 @@ import { functionWaitedAssert } from "@helpers/waitedLoop"; import ProposalDiscussionDetailsPage from "@pages/proposalDiscussionDetailsPage"; import ProposalDiscussionPage from "@pages/proposalDiscussionPage"; import { expect } from "@playwright/test"; -import { ProposalType } from "@types"; +import { + ProposalDiscussionFilterTypes, + ProposalType, + ProposedGovAction, +} from "@types"; const mockProposal = require("../../lib/_mock/proposal.json"); const mockPoll = require("../../lib/_mock/proposalPoll.json"); @@ -65,15 +69,41 @@ test.describe("Filter and sort proposals", () => { }); test("8B_2. Should sort the list of proposed governance actions.", async () => { - await proposalDiscussionPage.sortAndValidate( - "asc", - (p1, p2) => p1.attributes.createdAt <= p2.attributes.createdAt - ); - - await proposalDiscussionPage.sortAndValidate( - "desc", - (p1, p2) => p1.attributes.createdAt >= p2.attributes.createdAt - ); + const sortOptions = { + Oldest: (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.createdAt <= p2.attributes.createdAt, + Newest: (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.createdAt >= p2.attributes.createdAt, + "Most likes": (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.prop_likes >= p2.attributes.prop_likes, + "Least likes": (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.prop_likes <= p2.attributes.prop_likes, + "Most dislikes": (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.prop_dislikes >= p2.attributes.prop_dislikes, + "Least dislikes": (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.prop_dislikes <= p2.attributes.prop_dislikes, + "Most comments": (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.prop_comments_number >= + p2.attributes.prop_comments_number, + "Least comments": (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.prop_comments_number <= + p2.attributes.prop_comments_number, + "Name A-Z": (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.content.attributes.prop_name.localeCompare( + p2.attributes.content.attributes.prop_name + ) <= 0, + "Name Z-A": (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.content.attributes.prop_name.localeCompare( + p2.attributes.content.attributes.prop_name + ) >= 0, + }; + + for (const [sortOption, sortFunction] of Object.entries(sortOptions)) { + await proposalDiscussionPage.sortAndValidate( + sortOption as ProposalDiscussionFilterTypes, + sortFunction + ); + } }); }); From aa41aa19ecd3f6a85b9e2fc37d0d3972df39c114 Mon Sep 17 00:00:00 2001 From: Niraj Date: Tue, 3 Jun 2025 09:37:37 +0545 Subject: [PATCH 2/3] fix: update response URL filter for vote count in proposal visibility tests --- .../4-proposal-visibility/proposalVisibility.dRep.spec.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts index fd75c0b1d..7e6623005 100644 --- a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts @@ -147,7 +147,11 @@ test.describe("Check vote count", () => { : GovernanceActionType; const responsesPromise = Object.keys(voteWhiteListOption).map((filterKey) => page.waitForResponse((response) => - response.url().includes(`&type[]=${voteWhiteListOption[filterKey]}`) + response + .url() + .includes( + `proposal/list?page=0&pageSize=7&type[]=${voteWhiteListOption[filterKey]}` + ) ) ); From e5ba568984a4df8d29d520aa74b9660c0c5e32ac Mon Sep 17 00:00:00 2001 From: Niraj Date: Tue, 3 Jun 2025 12:31:11 +0545 Subject: [PATCH 3/3] fix: handle visibility of progress bar during outcome searches --- .../playwright/lib/pages/outcomesPage.ts | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/pages/outcomesPage.ts b/tests/govtool-frontend/playwright/lib/pages/outcomesPage.ts index bed26b0aa..e86db03e7 100644 --- a/tests/govtool-frontend/playwright/lib/pages/outcomesPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/outcomesPage.ts @@ -456,10 +456,15 @@ export default class OutComesPage { async searchOutcomesById(governanceActionId: string) { await this.searchInput.fill(governanceActionId); - await expect( - this.page.getByRole("progressbar").getByRole("img") - ).toBeVisible(); + try { + await expect( + this.page.getByRole("progressbar").getByRole("img") + ).toBeVisible(); + } catch (error) { + // Handle the case where the progress bar is not visible + console.warn("Progress bar not visible, proceeding with search."); + } await functionWaitedAssert( async () => { const idSearchOutcomeCards = await this.getAllOutcomes(); @@ -480,9 +485,14 @@ export default class OutComesPage { async searchOutcomesByTitle(governanceActionTitle: string) { await this.searchInput.fill(governanceActionTitle); - await expect( - this.page.getByRole("progressbar").getByRole("img") - ).toBeVisible(); + try { + await expect( + this.page.getByRole("progressbar").getByRole("img") + ).toBeVisible(); + } catch (error) { + // Handle the case where the progress bar is not visible + console.warn("Progress bar not visible, proceeding with search."); + } await functionWaitedAssert( async () => {