From 6ee05fde091a8d9d8b4c6f4cb9e31916e4a20f62 Mon Sep 17 00:00:00 2001 From: Niraj Date: Wed, 18 Dec 2024 16:40:18 +0545 Subject: [PATCH 01/30] chore: add utility to fetch first active dRep from directory --- .../playwright/lib/helpers/dRep.ts | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 tests/govtool-frontend/playwright/lib/helpers/dRep.ts diff --git a/tests/govtool-frontend/playwright/lib/helpers/dRep.ts b/tests/govtool-frontend/playwright/lib/helpers/dRep.ts new file mode 100644 index 000000000..5d7e3eff7 --- /dev/null +++ b/tests/govtool-frontend/playwright/lib/helpers/dRep.ts @@ -0,0 +1,39 @@ +import DRepDirectoryPage from "@pages/dRepDirectoryPage"; +import { Page } from "@playwright/test"; + +export async function fetchFirstActiveDRepDetails(page: Page) { + let dRepGivenName: string; + let dRepId: string; + let dRepDirectoryPage: DRepDirectoryPage; + await page.route( + "**/drep/list?page=0&pageSize=10&sort=Random", + async (route) => { + const response = await route.fetch(); + const json = await response.json(); + const elements = json["elements"].filter( + (element) => element["givenName"] != null + ); + dRepGivenName = + elements[Math.floor(Math.random() * elements.length)]["givenName"]; + dRepId = json["elements"][0]["view"]; + await route.fulfill({ + status: 200, + contentType: "application/json", + body: JSON.stringify(json), + }); + } + ); + + const responsePromise = page.waitForResponse( + "**/drep/list?page=0&pageSize=10&sort=Random" + ); + + dRepDirectoryPage = new DRepDirectoryPage(page); + await dRepDirectoryPage.goto(); + await dRepDirectoryPage.filterBtn.click(); + await page.getByTestId("Active-checkbox").click(); + await dRepDirectoryPage.searchInput.click(); + + await responsePromise; + return { dRepGivenName, dRepId, dRepDirectoryPage }; +} From 6d2ffe4300132405d962607ad9706ffb20a33c4d Mon Sep 17 00:00:00 2001 From: Niraj Date: Wed, 18 Dec 2024 16:43:37 +0545 Subject: [PATCH 02/30] refactor(tests): streamline delegation tests and remove redundant cases --- .../2-delegation/delegation.drep.spec.ts | 142 ------------------ .../2-delegation/delegation.loggedin.spec.ts | 54 +++++++ .../tests/2-delegation/delegation.spec.ts | 64 ++++++++ 3 files changed, 118 insertions(+), 142 deletions(-) diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.drep.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.drep.spec.ts index c6ecf9c49..1c6561e29 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.drep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.drep.spec.ts @@ -1,16 +1,11 @@ import environments from "@constants/environments"; -import { dRep01Wallet, user01Wallet } from "@constants/staticWallets"; import { createTempDRepAuth } from "@datafactory/createAuth"; import { faker } from "@faker-js/faker"; import { test } from "@fixtures/walletExtension"; import { setAllureEpic } from "@helpers/allure"; import { skipIfNotHardFork } from "@helpers/cardano"; import { ShelleyWallet } from "@helpers/crypto"; -import { isMobile, openDrawer } from "@helpers/mobile"; import { createNewPageWithWallet } from "@helpers/page"; -import extractDRepFromWallet from "@helpers/shellyWallet"; -import DRepDetailsPage from "@pages/dRepDetailsPage"; -import DRepDirectoryPage from "@pages/dRepDirectoryPage"; import DRepRegistrationPage from "@pages/dRepRegistrationPage"; import { expect } from "@playwright/test"; import { LinkType } from "@types"; @@ -21,22 +16,6 @@ test.beforeEach(async () => { await skipIfNotHardFork(); }); -test("2C. Should open wallet connection popup on delegate in disconnected state", async ({ - page, -}) => { - await page.goto("/"); - if (isMobile(page)) { - openDrawer(page); - } - - await page.getByTestId("view-drep-directory-button").click(); - await page.getByTestId("search-input").fill(dRep01Wallet.dRepId); - await page - .getByTestId(`${dRep01Wallet.dRepId}-connect-to-delegate-button`) - .click(); - await expect(page.getByTestId("connect-your-wallet-modal")).toBeVisible(); -}); - test("2N. Should show DRep information on details page", async ({ page, browser, @@ -124,124 +103,3 @@ test("2N. Should show DRep information on details page", async ({ ).toHaveText(link.url); } }); - -test("2P. Should enable sharing of DRep details", async ({ page, context }) => { - await context.grantPermissions(["clipboard-read", "clipboard-write"]); - - const dRepDetailsPage = new DRepDetailsPage(page); - await dRepDetailsPage.goto(dRep01Wallet.dRepId); - - await dRepDetailsPage.shareLink(); - await expect(page.getByText("Copied to clipboard")).toBeVisible(); - - const copiedText = await page.evaluate(() => navigator.clipboard.readText()); - expect(copiedText).toEqual( - `${environments.frontendUrl}/drep_directory/${dRep01Wallet.dRepId}` - ); -}); - -test("2Q. Should include DRep status and voting power on the DRep card", async ({ - page, -}) => { - const dRepDirectory = new DRepDirectoryPage(page); - await dRepDirectory.goto(); - - await dRepDirectory.searchInput.fill(dRep01Wallet.dRepId); - const dRepCard = dRepDirectory.getDRepCard(dRep01Wallet.dRepId); - - await expect( - dRepCard.getByTestId(`${dRep01Wallet.dRepId}-voting-power`) - ).toBeVisible(); - await expect( - dRepCard.getByTestId(`${dRep01Wallet.dRepId}-Active-pill`) - ).toBeVisible(); -}); - -test.describe("Insufficient funds", () => { - test.use({ storageState: ".auth/user01.json", wallet: user01Wallet }); - - test("2T. Should show warning message on delegation when insufficient funds", async ({ - page, - }) => { - const dRepDirectoryPage = new DRepDirectoryPage(page); - await dRepDirectoryPage.goto(); - - await dRepDirectoryPage.searchInput.fill(dRep01Wallet.dRepId); - const delegateBtn = page.getByTestId( - `${dRep01Wallet.dRepId}-delegate-button` - ); - await expect(delegateBtn).toBeVisible(); - await page.getByTestId(`${dRep01Wallet.dRepId}-delegate-button`).click(); - - await expect(dRepDirectoryPage.delegationErrorModal).toBeVisible({ - timeout: 10_000, - }); - }); -}); - -test("2I. Should check validity of DRep Id", async ({ page }) => { - const dRepDirectory = new DRepDirectoryPage(page); - await dRepDirectory.goto(); - - await dRepDirectory.searchInput.fill(dRep01Wallet.dRepId); - await expect(dRepDirectory.getDRepCard(dRep01Wallet.dRepId)).toBeVisible(); - - const wallet = await ShelleyWallet.generate(); - const invalidDRepId = extractDRepFromWallet(wallet); - - await dRepDirectory.searchInput.fill(invalidDRepId); - await expect(dRepDirectory.getDRepCard(invalidDRepId)).not.toBeVisible(); -}); - -test("2J. Should search by DRep id and DRep givenname", async ({ page }) => { - let dRepGivenName = "test"; - - await page.route( - "**/drep/list?page=0&pageSize=10&sort=Random", - async (route) => { - const response = await route.fetch(); - const json = await response.json(); - const elements = json["elements"].filter( - (element) => element["givenName"] != null - ); - dRepGivenName = - elements[Math.floor(Math.random() * elements.length)]["givenName"]; - await route.fulfill({ - status: 200, - contentType: "application/json", - body: JSON.stringify(json), - }); - } - ); - - const responsePromise = page.waitForResponse( - "**/drep/list?page=0&pageSize=10&sort=Random" - ); - - const dRepDirectory = new DRepDirectoryPage(page); - await dRepDirectory.goto(); - - await responsePromise; - - // search by dRep Id - await dRepDirectory.searchInput.fill(dRep01Wallet.dRepId); - await expect(dRepDirectory.getDRepCard(dRep01Wallet.dRepId)).toBeVisible(); - - // search by dRep givenname - await dRepDirectory.searchInput.fill(dRepGivenName); - const searchDRepCards = await dRepDirectory.getAllListedDReps(); - - for (const dRepCard of searchDRepCards) { - expect((await dRepCard.innerText()).includes(dRepGivenName)); - } -}); - -test("2M. Should access dRep directory page on disconnected state", async ({ - page, -}) => { - const dRepDirectoryPage = new DRepDirectoryPage(page); - await dRepDirectoryPage.goto(); - - const dRepCards = await dRepDirectoryPage.getAllListedDReps(); - expect(dRepCards.length).toBeGreaterThan(1); -}); diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts index 4a9081968..44e447a6e 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts @@ -2,7 +2,10 @@ import { user01Wallet } from "@constants/staticWallets"; import { test } from "@fixtures/walletExtension"; import { setAllureEpic } from "@helpers/allure"; import { skipIfNotHardFork } from "@helpers/cardano"; +import { ShelleyWallet } from "@helpers/crypto"; +import { fetchFirstActiveDRepDetails } from "@helpers/dRep"; import { isMobile } from "@helpers/mobile"; +import extractDRepFromWallet from "@helpers/shellyWallet"; import DRepDirectoryPage from "@pages/dRepDirectoryPage"; import { expect } from "@playwright/test"; @@ -71,3 +74,54 @@ test("2X_2. Should include info button and voting power on the Signal-No-Confide await expect(dRepDirectoryPage.signalNoConfidenceInfoButton).toBeVisible(); }); + +test.describe("DRep dependent tests", () => { + let dRepGivenName = "test"; + let dRepId = "drep1ef7uslcjhjqrn4vv2y39c3yn345gzjsg7yufn76zye3v6fkz23q"; + let dRepDirectoryPage: DRepDirectoryPage; + + test.beforeEach(async ({ page }) => { + ({ dRepDirectoryPage, dRepId, dRepGivenName } = + await fetchFirstActiveDRepDetails(page)); + }); + + test("2T. Should show warning message on delegation when insufficient funds", async ({ + page, + }) => { + await dRepDirectoryPage.searchInput.fill(dRepId); + const delegateBtn = page.getByTestId(`${dRepId}-delegate-button`); + await expect(delegateBtn).toBeVisible(); + await page.getByTestId(`${dRepId}-delegate-button`).click(); + + await expect(dRepDirectoryPage.delegationErrorModal).toBeVisible({ + timeout: 10_000, + }); + }); + + test("2I. Should check validity of DRep Id", async () => { + await dRepDirectoryPage.searchInput.fill(dRepId); + await expect(dRepDirectoryPage.getDRepCard(dRepId)).toBeVisible(); + + const wallet = await ShelleyWallet.generate(); + const invalidDRepId = extractDRepFromWallet(wallet); + + await dRepDirectoryPage.searchInput.fill(invalidDRepId); + await expect( + dRepDirectoryPage.getDRepCard(invalidDRepId) + ).not.toBeVisible(); + }); + + test("2J. Should search by DRep id and DRep givenname", async () => { + // search by dRep Id + await dRepDirectoryPage.searchInput.fill(dRepId); + await expect(dRepDirectoryPage.getDRepCard(dRepId)).toBeVisible(); + + // search by dRep givenname + await dRepDirectoryPage.searchInput.fill(dRepGivenName); + const searchDRepCards = await dRepDirectoryPage.getAllListedDReps(); + + for (const dRepCard of searchDRepCards) { + expect((await dRepCard.innerText()).includes(dRepGivenName)); + } + }); +}); diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts index 980081980..729740620 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts @@ -1,5 +1,8 @@ +import environments from "@constants/environments"; import { setAllureEpic } from "@helpers/allure"; import { skipIfNotHardFork } from "@helpers/cardano"; +import { fetchFirstActiveDRepDetails } from "@helpers/dRep"; +import DRepDetailsPage from "@pages/dRepDetailsPage"; import DRepDirectoryPage from "@pages/dRepDirectoryPage"; import { expect, test } from "@playwright/test"; import { DRepStatus, IDRep } from "@types"; @@ -122,3 +125,64 @@ test("2K_1. Should filter DReps", async ({ page }) => { multipleFilterOptionNames.pop(); } }); + +test("2M. Should access dRep directory page on disconnected state", async ({ + page, +}) => { + const dRepDirectoryPage = new DRepDirectoryPage(page); + await dRepDirectoryPage.goto(); + + const dRepCards = await dRepDirectoryPage.getAllListedDReps(); + expect(dRepCards.length).toBeGreaterThan(1); +}); + +test.describe("DRep dependent tests", () => { + let dRepGivenName = "test"; + let dRepId = "drep1ef7uslcjhjqrn4vv2y39c3yn345gzjsg7yufn76zye3v6fkz23q"; + let dRepDirectoryPage: DRepDirectoryPage; + + test.beforeEach(async ({ page }) => { + ({ dRepDirectoryPage, dRepId, dRepGivenName } = + await fetchFirstActiveDRepDetails(page)); + }); + + test("2P. Should enable sharing of DRep details", async ({ + page, + context, + }) => { + await context.grantPermissions(["clipboard-read", "clipboard-write"]); + + const dRepDetailsPage = new DRepDetailsPage(page); + await dRepDetailsPage.goto(dRepId); + + await dRepDetailsPage.shareLink(); + await expect(page.getByText("Copied to clipboard")).toBeVisible(); + + const copiedText = await page.evaluate(() => + navigator.clipboard.readText() + ); + expect(copiedText).toEqual( + `${environments.frontendUrl}/drep_directory/${dRepId}` + ); + }); + + test("2Q. Should include DRep status and voting power on the DRep card", async ({ + page, + }) => { + await dRepDirectoryPage.searchInput.fill(dRepId); + const dRepCard = dRepDirectoryPage.getDRepCard(dRepId); + + await expect(dRepCard.getByTestId(`${dRepId}-voting-power`)).toBeVisible(); + await expect( + dRepCard.locator(`[data-testid^="${dRepId}-"][data-testid$="-pill"]`) + ).toBeVisible(); + }); + + test("2C. Should open wallet connection popup on delegate in disconnected state", async ({ + page, + }) => { + await page.getByTestId("search-input").fill(dRepId); + await page.getByTestId(`${dRepId}-connect-to-delegate-button`).click(); + await expect(page.getByTestId("connect-your-wallet-modal")).toBeVisible(); + }); +}); From 16a56a9b0f00249049efb7fc41b78acab9166459 Mon Sep 17 00:00:00 2001 From: Niraj Date: Wed, 18 Dec 2024 20:03:11 +0545 Subject: [PATCH 03/30] fix: enhance dRep fetch logic for dynamic queries --- tests/govtool-frontend/playwright/lib/helpers/dRep.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/helpers/dRep.ts b/tests/govtool-frontend/playwright/lib/helpers/dRep.ts index 5d7e3eff7..33b6b1823 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/dRep.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/dRep.ts @@ -6,7 +6,7 @@ export async function fetchFirstActiveDRepDetails(page: Page) { let dRepId: string; let dRepDirectoryPage: DRepDirectoryPage; await page.route( - "**/drep/list?page=0&pageSize=10&sort=Random", + "**/drep/list?page=0&pageSize=10&sort=Random&**", async (route) => { const response = await route.fetch(); const json = await response.json(); @@ -25,15 +25,15 @@ export async function fetchFirstActiveDRepDetails(page: Page) { ); const responsePromise = page.waitForResponse( - "**/drep/list?page=0&pageSize=10&sort=Random" + "**/drep/list?page=0&pageSize=10&sort=Random&**" ); dRepDirectoryPage = new DRepDirectoryPage(page); await dRepDirectoryPage.goto(); await dRepDirectoryPage.filterBtn.click(); await page.getByTestId("Active-checkbox").click(); - await dRepDirectoryPage.searchInput.click(); - await responsePromise; + + await dRepDirectoryPage.searchInput.click(); return { dRepGivenName, dRepId, dRepDirectoryPage }; } From f6a7b8d70f33c60e3014df832ad9b0271a7fdb2c Mon Sep 17 00:00:00 2001 From: Niraj Date: Wed, 18 Dec 2024 20:03:48 +0545 Subject: [PATCH 04/30] fix: add assertion instead of wait for timeout on dRepList --- .../govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts b/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts index 9c4ccceb3..54e960c70 100644 --- a/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts @@ -147,7 +147,8 @@ export default class DRepDirectoryPage { } async getAllListedDReps() { - await this.page.waitForTimeout(5_000); // load until the dRep card load properly + // add assertion to wait until the search input is visible + await expect(this.searchInput).toBeVisible({ timeout: 10_000 }); return await this.page .getByRole("list") From 13545983584cda6111c9506ba7afd90155bf071d Mon Sep 17 00:00:00 2001 From: Niraj Date: Thu, 19 Dec 2024 11:52:20 +0545 Subject: [PATCH 05/30] chore: relocate test 2L to delection spec --- .../tests/2-delegation/delegation.spec.ts | 18 +++++++++++++++--- .../delegationFunctionality.delegation.spec.ts | 18 ------------------ 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts index 729740620..8cac54d43 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts @@ -137,13 +137,11 @@ test("2M. Should access dRep directory page on disconnected state", async ({ }); test.describe("DRep dependent tests", () => { - let dRepGivenName = "test"; let dRepId = "drep1ef7uslcjhjqrn4vv2y39c3yn345gzjsg7yufn76zye3v6fkz23q"; let dRepDirectoryPage: DRepDirectoryPage; test.beforeEach(async ({ page }) => { - ({ dRepDirectoryPage, dRepId, dRepGivenName } = - await fetchFirstActiveDRepDetails(page)); + ({ dRepDirectoryPage, dRepId } = await fetchFirstActiveDRepDetails(page)); }); test("2P. Should enable sharing of DRep details", async ({ @@ -185,4 +183,18 @@ test.describe("DRep dependent tests", () => { await page.getByTestId(`${dRepId}-connect-to-delegate-button`).click(); await expect(page.getByTestId("connect-your-wallet-modal")).toBeVisible(); }); + + test("2L. Should copy DRepId", async ({ page, context }) => { + await context.grantPermissions(["clipboard-read", "clipboard-write"]); + + await dRepDirectoryPage.searchInput.fill(dRepId); + await page.getByTestId(`${dRepId}-copy-id-button`).click(); + await expect(page.getByText("Copied to clipboard")).toBeVisible({ + timeout: 10_000, + }); + const copiedTextDRepDirectory = await page.evaluate(() => + navigator.clipboard.readText() + ); + expect(copiedTextDRepDirectory).toEqual(dRepId); + }); }); diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts index ed98314d0..2889c1217 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts @@ -74,24 +74,6 @@ test.describe("Delegate to others", () => { page.getByTestId("delegate-to-another-drep-button") ).toBeVisible(); }); - - test("2L. Should copy delegated DRepId", async ({ page, context }) => { - await context.grantPermissions(["clipboard-read", "clipboard-write"]); - - const dRepDirectory = new DRepDirectoryPage(page); - await dRepDirectory.goto(); - - await dRepDirectory.searchInput.fill(dRep01Wallet.dRepId); - await page.getByTestId(`${dRep01Wallet.dRepId}-copy-id-button`).click(); - await expect(page.getByText("Copied to clipboard")).toBeVisible({ - timeout: 10_000, - }); - - const copiedTextDRepDirectory = await page.evaluate(() => - navigator.clipboard.readText() - ); - expect(copiedTextDRepDirectory).toEqual(dRep01Wallet.dRepId); - }); }); test.describe("Change delegation", () => { From 308eaf0469432af70566cb0798d7853bcf486c0a Mon Sep 17 00:00:00 2001 From: Niraj Date: Fri, 20 Dec 2024 10:16:26 +0545 Subject: [PATCH 06/30] refactor: move bad proposal tests 5G and 5H to independent tests --- .../proposalFunctionality.dRep.spec.ts | 55 ++----------------- .../proposalFunctionality.spec.ts | 49 +++++++++++++++++ 2 files changed, 54 insertions(+), 50 deletions(-) create mode 100644 tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.spec.ts diff --git a/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.dRep.spec.ts index ef3771ad7..b017ad2b4 100644 --- a/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.dRep.spec.ts @@ -12,17 +12,13 @@ import GovernanceActionDetailsPage from "@pages/governanceActionDetailsPage"; import GovernanceActionsPage from "@pages/governanceActionsPage"; import { Page, expect } from "@playwright/test"; import kuberService from "@services/kuberService"; -import { - BootstrapGovernanceActionType, - GovernanceActionType, -} from "@types"; +import { BootstrapGovernanceActionType, GovernanceActionType } from "@types"; import walletManager from "lib/walletManager"; -const invalidInfinityProposals = require("../../lib/_mock/invalidInfinityProposals.json"); - test.beforeEach(async () => { await setAllureEpic("5. Proposal functionality"); await skipIfNotHardFork(); + test.skip(environments.networkId === 1); }); test.describe("Proposal checks", () => { @@ -128,47 +124,6 @@ test.describe("Proposal checks", () => { }); }); -test.describe("Bad Proposals", () => { - test.use({ storageState: ".auth/dRep01.json", wallet: dRep01Wallet }); - - let govActionsPage: GovernanceActionsPage; - - test.beforeEach(async ({ page }) => { - await page.route("**/proposal/list?**", async (route) => - route.fulfill({ - body: JSON.stringify(invalidInfinityProposals), - }) - ); - - govActionsPage = new GovernanceActionsPage(page); - await govActionsPage.goto(); - }); - - test("5G. Should show warning in bad governance action proposal to the users to visit the site at their own risk, when external url is opened", async () => { - const govActionDetailsPage = await govActionsPage.viewFirstProposal(); - - await govActionDetailsPage.externalModalBtn.click(); - - await expect(govActionDetailsPage.externalLinkModal).toBeVisible(); - await expect( - govActionDetailsPage.currentPage.getByText("Be careful", { - exact: false, - }) - ).toBeVisible(); - }); - - test("5H. Should open a new tab in Bad governance action proposal, when external URL is opened", async ({ - page, - }) => { - const govActionDetailsPage = await govActionsPage.viewFirstProposal(); - - await govActionDetailsPage.externalModalBtn.click(); - await govActionDetailsPage.continueModalBtn.click(); - const existingPages = page.context().pages(); - expect(existingPages).toHaveLength(1); - }); -}); - test.describe("Perform voting", () => { let govActionDetailsPage: GovernanceActionDetailsPage; let dRepPage: Page; @@ -287,9 +242,9 @@ test.describe("Bootstrap phase", () => { test("5L. Should restrict dRep votes to Info Governance actions During Bootstrapping Phase", async ({ browser, }) => { - const voteBlacklistOptions = Object.keys(BootstrapGovernanceActionType).filter( - (option) => option !== GovernanceActionType.InfoAction - ); + const voteBlacklistOptions = Object.keys( + BootstrapGovernanceActionType + ).filter((option) => option !== GovernanceActionType.InfoAction); await Promise.all( voteBlacklistOptions.map(async (voteBlacklistOption) => { diff --git a/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.spec.ts b/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.spec.ts new file mode 100644 index 000000000..595566e79 --- /dev/null +++ b/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.spec.ts @@ -0,0 +1,49 @@ +import { test } from "@fixtures/walletExtension"; +import { setAllureEpic } from "@helpers/allure"; +import { skipIfNotHardFork } from "@helpers/cardano"; +import GovernanceActionsPage from "@pages/governanceActionsPage"; +import { expect } from "@playwright/test"; +const invalidInfinityProposals = require("../../lib/_mock/invalidInfinityProposals.json"); + +test.beforeEach(async () => { + await setAllureEpic("5. Proposal functionality"); + await skipIfNotHardFork(); +}); +test.describe("Bad Proposals", () => { + let govActionsPage: GovernanceActionsPage; + + test.beforeEach(async ({ page }) => { + await page.route("**/proposal/list?**", async (route) => + route.fulfill({ + body: JSON.stringify(invalidInfinityProposals), + }) + ); + + govActionsPage = new GovernanceActionsPage(page); + await govActionsPage.goto(); + }); + + test("5G. Should show warning in bad governance action proposal to the users to visit the site at their own risk, when external url is opened", async () => { + const govActionDetailsPage = await govActionsPage.viewFirstProposal(); + + await govActionDetailsPage.externalModalBtn.click(); + + await expect(govActionDetailsPage.externalLinkModal).toBeVisible(); + await expect( + govActionDetailsPage.currentPage.getByText("Be careful", { + exact: false, + }) + ).toBeVisible(); + }); + + test("5H. Should open a new tab in Bad governance action proposal, when external URL is opened", async ({ + page, + }) => { + const govActionDetailsPage = await govActionsPage.viewFirstProposal(); + + await govActionDetailsPage.externalModalBtn.click(); + await govActionDetailsPage.continueModalBtn.click(); + const existingPages = page.context().pages(); + expect(existingPages).toHaveLength(1); + }); +}); From c8fd3a20c509761d92b170d73293670d35d8497d Mon Sep 17 00:00:00 2001 From: Niraj Date: Fri, 20 Dec 2024 10:19:36 +0545 Subject: [PATCH 07/30] fix: update networkId logic and utilize it in wallet connection tests --- .../playwright/lib/constants/environments.ts | 4 ++-- .../playwright/lib/fixtures/loadExtension.ts | 1 + .../tests/1-wallet-connect/walletConnect.spec.ts | 14 ++++++++++---- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/constants/environments.ts b/tests/govtool-frontend/playwright/lib/constants/environments.ts index 13622c431..411e80870 100644 --- a/tests/govtool-frontend/playwright/lib/constants/environments.ts +++ b/tests/govtool-frontend/playwright/lib/constants/environments.ts @@ -14,9 +14,9 @@ const environments = { apiUrl: `${SERVER_HOST_URL}/api`, docsUrl: process.env.DOCS_URL || "https://docs.gov.tools/cardano-govtool", pdfUrl: process.env.PDF_URL || "https://dev.api.pdf.gov.tools", - networkId: parseInt(process.env.NETWORK_ID) || 0, + networkId: NETWORK === "mainnet" ? 1 : 0, faucet: { - apiUrl:`https://faucet.${NETWORK}.world.dev.cardano.org`, + apiUrl: `https://faucet.${NETWORK}.world.dev.cardano.org`, apiKey: process.env.FAUCET_API_KEY || "", address: process.env.FAUCET_ADDRESS || diff --git a/tests/govtool-frontend/playwright/lib/fixtures/loadExtension.ts b/tests/govtool-frontend/playwright/lib/fixtures/loadExtension.ts index 34c508d5b..e61609671 100644 --- a/tests/govtool-frontend/playwright/lib/fixtures/loadExtension.ts +++ b/tests/govtool-frontend/playwright/lib/fixtures/loadExtension.ts @@ -19,6 +19,7 @@ export default async function loadDemosExtension( let walletConfig: CardanoTestWalletConfig = { enableStakeSigning, kuberApiUrl: environments.kuber.apiUrl, + networkId: environments.networkId, kuberApiKey: environments.kuber.apiKey, blockfrostApiKey: environments.blockfrostApiKey, blockfrostApiUrl: environments.blockfrostApiUrl, diff --git a/tests/govtool-frontend/playwright/tests/1-wallet-connect/walletConnect.spec.ts b/tests/govtool-frontend/playwright/tests/1-wallet-connect/walletConnect.spec.ts index 1361de324..557b55cd1 100644 --- a/tests/govtool-frontend/playwright/tests/1-wallet-connect/walletConnect.spec.ts +++ b/tests/govtool-frontend/playwright/tests/1-wallet-connect/walletConnect.spec.ts @@ -1,3 +1,4 @@ +import environments from "@constants/environments"; import createWallet from "@fixtures/createWallet"; import { test } from "@fixtures/walletExtension"; import { setAllureEpic } from "@helpers/allure"; @@ -17,12 +18,13 @@ test("1A. Should connect wallet and choose stake-key to use", async ({ const shellyWallet = await ShelleyWallet.generate(); const extraPubStakeKey = convertBufferToHex(shellyWallet.stakeKey.public); const extraRewardAddress = convertBufferToHex( - shellyWallet.rewardAddressRawBytes(0) + shellyWallet.rewardAddressRawBytes(environments.networkId) ); await createWallet(page, { extraRegisteredPubStakeKeys: [extraPubStakeKey], extraRewardAddresses: [extraRewardAddress], + networkId: environments.networkId, }); const loginPage = new LoginPage(page); @@ -30,7 +32,9 @@ test("1A. Should connect wallet and choose stake-key to use", async ({ }); test("1C. Should disconnect Wallet When connected", async ({ page }) => { - await createWallet(page); + await createWallet(page, { + networkId: environments.networkId, + }); const loginPage = new LoginPage(page); await loginPage.login(); @@ -38,8 +42,10 @@ test("1C. Should disconnect Wallet When connected", async ({ page }) => { await loginPage.logout(); }); -test("1D. Should reject wallet connection in mainnet", async ({ page }) => { - const wrongNetworkId = 1; // mainnet network +test("1D. Should reject wallet connection if on different network", async ({ + page, +}) => { + const wrongNetworkId = environments.networkId == 0 ? 1 : 0; await createWallet(page, { networkId: wrongNetworkId, }); From aff8198c5eb3b36ca33f04f5262a644766ab1e22 Mon Sep 17 00:00:00 2001 From: Niraj Date: Fri, 20 Dec 2024 10:20:55 +0545 Subject: [PATCH 08/30] fix: skip ada dependent test for mainnet --- .../playwright/tests/2-delegation/delegation.drep.spec.ts | 1 + .../2-delegation/delegationFunctionality.delegation.spec.ts | 1 + .../tests/3-drep-registration/dRepRegistration.dRep.spec.ts | 1 + .../tests/3-drep-registration/editDRep.dRep.spec.ts | 2 ++ .../4-proposal-visibility/proposalVisibility.dRep.spec.ts | 1 + .../tests/6-miscellaneous/miscellaneous.dRep.spec.ts | 1 + .../7-proposal-submission/proposalSubmission.ga.spec.ts | 1 + tests/govtool-frontend/playwright/tests/dRep.setup.ts | 1 + tests/govtool-frontend/playwright/tests/dRep.teardown.ts | 1 + .../govtool-frontend/playwright/tests/delegation.teardown.ts | 1 + tests/govtool-frontend/playwright/tests/faucet.setup.ts | 1 + tests/govtool-frontend/playwright/tests/faucet.teardown.ts | 5 +++-- tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts | 1 + 13 files changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.drep.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.drep.spec.ts index 1c6561e29..197a75945 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.drep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.drep.spec.ts @@ -14,6 +14,7 @@ import walletManager from "lib/walletManager"; test.beforeEach(async () => { await setAllureEpic("2. Delegation"); await skipIfNotHardFork(); + test.skip(environments.networkId === 1); }); test("2N. Should show DRep information on details page", async ({ diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts index 2889c1217..4d7040415 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts @@ -24,6 +24,7 @@ import walletManager from "lib/walletManager"; test.beforeEach(async () => { await setAllureEpic("2. Delegation"); await skipIfNotHardFork(); + test.skip(environments.networkId === 1); }); test.describe("Delegate to others", () => { diff --git a/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.dRep.spec.ts index 9f593c004..5687d9b76 100644 --- a/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.dRep.spec.ts @@ -18,6 +18,7 @@ import { GovernanceActionType } from "@types"; test.beforeEach(async () => { await setAllureEpic("3. DRep registration"); await skipIfNotHardFork(); + test.skip(environments.networkId === 1); }); test.describe("Logged in DReps", () => { diff --git a/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts index 656dc4714..0f20aad56 100644 --- a/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts @@ -7,10 +7,12 @@ import { invalid as mockInvalid, valid as mockValid } from "@mock/index"; import { skipIfNotHardFork } from "@helpers/cardano"; import EditDRepPage from "@pages/editDRepPage"; import { expect } from "@playwright/test"; +import environments from "@constants/environments"; test.beforeEach(async () => { await setAllureEpic("3. DRep registration"); await skipIfNotHardFork(); + test.skip(environments.networkId === 1); }); test.use({ wallet: dRep02Wallet, storageState: ".auth/dRep02.json" }); 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 bbd615d1b..4bdae4c5e 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 @@ -30,6 +30,7 @@ import { test.beforeEach(async () => { await setAllureEpic("4. Proposal visibility"); await skipIfNotHardFork(); + test.skip(environments.networkId === 1); }); test.describe("Logged in DRep", () => { diff --git a/tests/govtool-frontend/playwright/tests/6-miscellaneous/miscellaneous.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/6-miscellaneous/miscellaneous.dRep.spec.ts index c0f38d48f..073d52d3a 100644 --- a/tests/govtool-frontend/playwright/tests/6-miscellaneous/miscellaneous.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/6-miscellaneous/miscellaneous.dRep.spec.ts @@ -8,6 +8,7 @@ import { expect } from "@playwright/test"; test.beforeEach(async () => { await setAllureEpic("6. Miscellaneous"); await skipIfNotHardFork(); + test.skip(environments.networkId === 1); }); test.use({ diff --git a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts index b70e938d2..48eb5cb0a 100644 --- a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts +++ b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts @@ -14,6 +14,7 @@ import { proposalFaucetWallet } from "@constants/proposalFaucetWallet"; test.beforeEach(async () => { await setAllureEpic("7. Proposal submission"); await skipIfNotHardFork(); + test.skip(environments.networkId === 1); }); Object.values(ProposalType).forEach((proposalType, index) => { diff --git a/tests/govtool-frontend/playwright/tests/dRep.setup.ts b/tests/govtool-frontend/playwright/tests/dRep.setup.ts index 319f00ec7..96af045f9 100644 --- a/tests/govtool-frontend/playwright/tests/dRep.setup.ts +++ b/tests/govtool-frontend/playwright/tests/dRep.setup.ts @@ -23,6 +23,7 @@ setup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Register DRep"); await skipIfNotHardFork(); + setup.skip(environments.networkId === 1); }); async function generateWallets(num: number) { diff --git a/tests/govtool-frontend/playwright/tests/dRep.teardown.ts b/tests/govtool-frontend/playwright/tests/dRep.teardown.ts index 402d9a48b..6e22c44f9 100644 --- a/tests/govtool-frontend/playwright/tests/dRep.teardown.ts +++ b/tests/govtool-frontend/playwright/tests/dRep.teardown.ts @@ -11,6 +11,7 @@ cleanup.describe.configure({ timeout: environments.txTimeOut }); cleanup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Cleanup"); + cleanup.skip(environments.networkId === 1); }); cleanup("DRep de-registration", async () => { diff --git a/tests/govtool-frontend/playwright/tests/delegation.teardown.ts b/tests/govtool-frontend/playwright/tests/delegation.teardown.ts index 5759f1741..8a994c3b1 100644 --- a/tests/govtool-frontend/playwright/tests/delegation.teardown.ts +++ b/tests/govtool-frontend/playwright/tests/delegation.teardown.ts @@ -11,6 +11,7 @@ cleanup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Cleanup"); await skipIfNotHardFork(); + cleanup.skip(environments.networkId === 1); }); cleanup(`Abstain delegation`, async () => { const stakePrivKeys = adaHolderWallets.map((wallet) => wallet.stake.private); diff --git a/tests/govtool-frontend/playwright/tests/faucet.setup.ts b/tests/govtool-frontend/playwright/tests/faucet.setup.ts index 2b872e8af..db1bd708e 100644 --- a/tests/govtool-frontend/playwright/tests/faucet.setup.ts +++ b/tests/govtool-frontend/playwright/tests/faucet.setup.ts @@ -11,6 +11,7 @@ setup.describe.configure({ timeout: environments.txTimeOut }); setup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Faucet"); + setup.skip(environments.networkId === 1); }); setup("Faucet setup", async () => { diff --git a/tests/govtool-frontend/playwright/tests/faucet.teardown.ts b/tests/govtool-frontend/playwright/tests/faucet.teardown.ts index b32425873..1708d3211 100644 --- a/tests/govtool-frontend/playwright/tests/faucet.teardown.ts +++ b/tests/govtool-frontend/playwright/tests/faucet.teardown.ts @@ -9,6 +9,7 @@ cleanup.describe.configure({ timeout: environments.txTimeOut }); cleanup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Cleanup"); + cleanup.skip(environments.networkId === 1); }); cleanup("Refund faucet", async () => { @@ -16,7 +17,7 @@ cleanup("Refund faucet", async () => { const faucetRemainingBalance = await kuberService.getBalance( faucetWallet.address ); - + const transferBalance = Math.floor(faucetRemainingBalance) - 3; const { txId, lockInfo } = await kuberService.transferADA( [environments.faucet.address], @@ -24,7 +25,7 @@ cleanup("Refund faucet", async () => { ); await pollTransaction(txId, lockInfo); } catch (err) { - console.log(err); + console.log(err); if (err.status === 400) { expect(true, "Failed to trasfer Ada").toBeTruthy(); } else { diff --git a/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts b/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts index 1a4b6500d..fa28c262d 100644 --- a/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts +++ b/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts @@ -10,6 +10,7 @@ setup.describe.configure({ mode: "serial", timeout: environments.txTimeOut }); setup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Wallet bootstrap"); + setup.skip(environments.networkId === 1); }); setup("Initialize static wallets", async () => { From 6fff4887fb4c335008e8a29f98275d01d4ba3123 Mon Sep 17 00:00:00 2001 From: Niraj Date: Fri, 20 Dec 2024 11:34:05 +0545 Subject: [PATCH 09/30] fix: add timeout to ensure dRep list renders correctly --- .../govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts b/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts index 54e960c70..535f55a52 100644 --- a/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts @@ -147,6 +147,8 @@ export default class DRepDirectoryPage { } async getAllListedDReps() { + // wait for the dRep list to render properly + await this.page.waitForTimeout(3_000); // add assertion to wait until the search input is visible await expect(this.searchInput).toBeVisible({ timeout: 10_000 }); From 0eeb1a90005cf08fd68bdb15403c2da7ac04b2f1 Mon Sep 17 00:00:00 2001 From: Niraj Date: Fri, 20 Dec 2024 12:06:03 +0545 Subject: [PATCH 10/30] chore: remove unnecessary assertions and add text assertions on delegation popup modal --- .../tests/2-delegation/delegation.loggedin.spec.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts index 44e447a6e..4490463c0 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts @@ -89,13 +89,14 @@ test.describe("DRep dependent tests", () => { page, }) => { await dRepDirectoryPage.searchInput.fill(dRepId); - const delegateBtn = page.getByTestId(`${dRepId}-delegate-button`); - await expect(delegateBtn).toBeVisible(); await page.getByTestId(`${dRepId}-delegate-button`).click(); await expect(dRepDirectoryPage.delegationErrorModal).toBeVisible({ timeout: 10_000, }); + await expect(dRepDirectoryPage.delegationErrorModal).toHaveText( + /UTxO Balance Insufficient/ + ); }); test("2I. Should check validity of DRep Id", async () => { From 72c64e9fa37cef464347b3730a8433c25fd39f73 Mon Sep 17 00:00:00 2001 From: Niraj Date: Fri, 20 Dec 2024 12:40:50 +0545 Subject: [PATCH 11/30] fix: dynamically fetch proposal titles in governance actions for search --- .../proposalVisibility.loggedin.spec.ts | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.loggedin.spec.ts index 1705c8ed6..bf80f2929 100644 --- a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.loggedin.spec.ts +++ b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.loggedin.spec.ts @@ -131,11 +131,29 @@ test("4C_3. Should filter and sort Governance Action Type on governance actions }); test("4L. Should search governance actions", async ({ page }) => { - const governanceActionTitle = "TreasuryTitle"; - const governanceActionPage = new GovernanceActionsPage(page); + let governanceActionTitle = "TreasuryTitle"; + await page.route("**/proposal/list?**", async (route) => { + const response = await route.fetch(); + const data = await response.json(); + const elementsWithTitle = data["elements"].filter( + (element) => element["title"] + ); + if (elementsWithTitle.length !== 0) { + governanceActionTitle = elementsWithTitle[0]["title"]; + } + await route.fulfill({ + status: 200, + contentType: "application/json", + body: JSON.stringify(data), + }); + }); + const responsePromise = page.waitForResponse("**/proposal/list?**"); + const governanceActionPage = new GovernanceActionsPage(page); await governanceActionPage.goto(); + await responsePromise; + await governanceActionPage.searchInput.fill(governanceActionTitle); const proposalCards = await governanceActionPage.getAllProposals(); From 028c6c2c6cf659964584ec43ed92cb7671c918dd Mon Sep 17 00:00:00 2001 From: Niraj Date: Fri, 20 Dec 2024 12:49:10 +0545 Subject: [PATCH 12/30] fix: align proposal type creation logic with protocol version --- .../lib/pages/proposalSubmissionPage.ts | 2 +- .../proposalSubmission.loggedin.spec.ts | 27 ++++++++++++------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts b/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts index 1689016ba..de947584c 100644 --- a/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts @@ -184,7 +184,7 @@ export default class ProposalSubmissionPage { async getFirstDraft() { await expect( - this.page.locator('[data-testid^="draft-"][data-testid$="-card"]') + this.page.locator('[data-testid^="draft-"][data-testid$="-card"]').first() ).toBeVisible({ timeout: 10_000 }); // slow rendering return this.page diff --git a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts index f870e5881..3695e2b97 100644 --- a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts +++ b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts @@ -12,6 +12,7 @@ import { setAllureEpic } from "@helpers/allure"; import { skipIfTreasuryAndBootstrapping, skipIfNotHardFork, + isBootStrapingPhase, } from "@helpers/cardano"; import { ShelleyWallet } from "@helpers/crypto"; import { createNewPageWithWallet } from "@helpers/page"; @@ -329,9 +330,11 @@ test.describe("Info Proposal Draft", () => { }); const proposalSubmissionPage = new ProposalSubmissionPage(page); - const { proposalFormValue } = await proposalSubmissionPage.createDraft( - ProposalType.treasury - ); + const createProposalType = (await isBootStrapingPhase()) + ? ProposalType.info + : ProposalType.treasury; + const { proposalFormValue } = + await proposalSubmissionPage.createDraft(createProposalType); const draftCard = proposalSubmissionPage.getFirstDraft(); const draftCardAllInnerText = await (await draftCard).allInnerTexts(); @@ -343,7 +346,7 @@ test.describe("Info Proposal Draft", () => { .click(); await expect(proposalSubmissionPage.governanceActionType).toHaveText( - ProposalType.treasury + createProposalType ); await expect(proposalSubmissionPage.titleInput).toHaveValue( proposalFormValue.prop_name @@ -357,12 +360,16 @@ test.describe("Info Proposal Draft", () => { await expect(proposalSubmissionPage.rationaleInput).toHaveValue( proposalFormValue.prop_rationale ); - await expect(proposalSubmissionPage.receivingAddressInput).toHaveValue( - proposalFormValue.prop_receiving_address - ); - await expect(proposalSubmissionPage.amountInput).toHaveValue( - proposalFormValue.prop_amount - ); + + if (createProposalType === ProposalType.treasury) { + await expect(proposalSubmissionPage.receivingAddressInput).toHaveValue( + proposalFormValue.prop_receiving_address + ); + await expect(proposalSubmissionPage.amountInput).toHaveValue( + proposalFormValue.prop_amount + ); + } + await expect(proposalSubmissionPage.linkUrlInput).toHaveValue( proposalFormValue.proposal_links[0].prop_link ); From a478bfb1401d1c4f36d06b62984445943a306296 Mon Sep 17 00:00:00 2001 From: Niraj Date: Fri, 20 Dec 2024 14:39:42 +0545 Subject: [PATCH 13/30] fix: remove temporary workaround for blank proposals issue in proposal view --- .../playwright/lib/pages/proposalDiscussionPage.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts b/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts index 1734518e0..b44d9ca46 100644 --- a/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts @@ -29,15 +29,7 @@ export default class ProposalDiscussionPage { async goto() { await this.page.goto(`${environments.frontendUrl}/proposal_discussion`); - // Temporary fix for blank proposals issue in proposal view during disconnected state - // This code handles the blank proposals error, which is causing failing tests. - // It will be removed once the underlying issue is resolved. - await this.page.getByTestId("logo-button").click(); - if (isMobile(this.page)) { - await this.page.getByTestId("open-drawer-button").click(); - } - await this.page.getByText("Proposals", { exact: true }).click(); - + // wait for the proposal cards to load await this.page.waitForTimeout(2_000); } From 0fd8fe54f9ceebb9b6d7907d4b49886db301e267 Mon Sep 17 00:00:00 2001 From: Niraj Date: Fri, 20 Dec 2024 14:50:48 +0545 Subject: [PATCH 14/30] chore: increase timeout for identity verification button visibility --- tests/govtool-frontend/playwright/lib/helpers/auth.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/govtool-frontend/playwright/lib/helpers/auth.ts b/tests/govtool-frontend/playwright/lib/helpers/auth.ts index ae839ebd4..fd4f43dc3 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/auth.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/auth.ts @@ -45,7 +45,7 @@ export async function createAuthWithUserName({ const proposalDiscussionPage = new ProposalDiscussionPage(page); await proposalDiscussionPage.goto(); - await proposalDiscussionPage.verifyIdentityBtn.click(); + await proposalDiscussionPage.verifyIdentityBtn.click({ timeout: 15_000 }); await proposalDiscussionPage.setUsername(mockValid.username()); From 5f2832b941f7f88ff1441150f43351d5130ca5f7 Mon Sep 17 00:00:00 2001 From: Niraj Date: Fri, 20 Dec 2024 14:58:48 +0545 Subject: [PATCH 15/30] feat: configure gov.tools inputs and align network variables for deployment --- .../workflows/test_integration_playwright.yml | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test_integration_playwright.yml b/.github/workflows/test_integration_playwright.yml index 3f3c5fab1..e478aec0d 100644 --- a/.github/workflows/test_integration_playwright.yml +++ b/.github/workflows/test_integration_playwright.yml @@ -15,6 +15,7 @@ on: - "staging.govtool.byron.network" - "govtool.cardanoapi.io" - "preview.gov.tools" + - "gov.tools" workflow_run: workflows: ["Build and deploy GovTool to TEST server"] @@ -54,18 +55,27 @@ jobs: mkdir -p ./lib/_mock chmod +w ./lib/_mock npm run generate-wallets - if [[ "${{ env.NETWORK }}" == "preprod" ]]; then + + # Set network variables based on deployment input and environment + if [[ "${{inputs.deployment}}" == "gov.tools" ]]; then + export NETWORK='mainnet' + else + export NETWORK="${{ vars.NETWORK }}" + fi + + # Set API keys based on the network + if [[ "${{ vars.NETWORK }}" == "preprod" ]]; then export FAUCET_API_KEY="${{ secrets.FAUCET_API_KEY_PREPROD }}" export BLOCKFROST_API_KEY="${{ secrets.BLOCKFROST_API_KEY_PREPROD }}" - elif [[ "${{ env.NETWORK }}" == "sanchonet" ]]; then + elif [[ "${{ vars.NETWORK }}" == "sanchonet" ]]; then export FAUCET_API_KEY="${{ secrets.FAUCET_API_KEY_SANCHONET }}" export BLOCKFROST_API_KEY="${{ secrets.BLOCKFROST_API_KEY_SANCHONET }}" else export FAUCET_API_KEY="${{ secrets.FAUCET_API_KEY_PREVIEW }}" export BLOCKFROST_API_KEY="${{ secrets.BLOCKFROST_API_KEY_PREVIEW }}" fi + npm test - - name: Upload report uses: actions/upload-artifact@v3 @@ -88,7 +98,6 @@ jobs: KUBER_API_KEY: ${{secrets.KUBER_API_KEY}} TEST_WORKERS: ${{vars.TEST_WORKERS}} CI: ${{vars.CI}} - NETWORK: ${{vars.NETWORK}} FAUCET_ADDRESS: ${{vars.FAUCET_ADDRESS}} CARDANOAPI_METADATA_URL: ${{vars.CARDANOAPI_METADATA_URL}} PROPOSAL_FAUCET_PAYMENT_PRIVATE: ${{secrets.PROPOSAL_FAUCET_PAYMENT_PRIVATE}} From 193455c94c3865327154041079daf20a20d8cdca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Fri, 20 Dec 2024 16:24:21 +0100 Subject: [PATCH 16/30] feat: split new committe on-chain details into tabs --- CHANGELOG.md | 2 +- govtool/frontend/package-lock.json | 4 +- ...ActionNewConstitutionDetailsTabContent.tsx | 30 ++++++++++++++ .../src/components/molecules/index.ts | 1 + .../GovernanceActionDetailsCardData.tsx | 40 +++++++------------ 5 files changed, 49 insertions(+), 28 deletions(-) create mode 100644 govtool/frontend/src/components/molecules/GovernanceActionNewConstitutionDetailsTabContent.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index e77f1fb49..f163b6c8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ changes. ### Changed -- +- Split New committee on-chain details into tabs ### Removed diff --git a/govtool/frontend/package-lock.json b/govtool/frontend/package-lock.json index 55b16c656..24d068e3d 100644 --- a/govtool/frontend/package-lock.json +++ b/govtool/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "@govtool/frontend", - "version": "2.0.1", + "version": "2.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@govtool/frontend", - "version": "2.0.1", + "version": "2.0.2", "hasInstallScript": true, "dependencies": { "@emotion/react": "^11.11.1", diff --git a/govtool/frontend/src/components/molecules/GovernanceActionNewConstitutionDetailsTabContent.tsx b/govtool/frontend/src/components/molecules/GovernanceActionNewConstitutionDetailsTabContent.tsx new file mode 100644 index 000000000..9c0f4016c --- /dev/null +++ b/govtool/frontend/src/components/molecules/GovernanceActionNewConstitutionDetailsTabContent.tsx @@ -0,0 +1,30 @@ +import { Box } from "@mui/material"; + +import { NewConstitutionAnchor, ProposalData } from "@/models"; +import { useScreenDimension } from "@/hooks"; + +import { GovernanceActionCardElement } from "./GovernanceActionCardElement"; + +export const GovernanceActionNewConstitutionDetailsTabContent = ({ + details, +}: Pick) => { + const { screenWidth } = useScreenDimension(); + return ( + + 1600 ? "longText" : "oneLine"} + /> + 1600 ? "longText" : "oneLine"} + /> + + ); +}; diff --git a/govtool/frontend/src/components/molecules/index.ts b/govtool/frontend/src/components/molecules/index.ts index 89005427a..1335d5237 100644 --- a/govtool/frontend/src/components/molecules/index.ts +++ b/govtool/frontend/src/components/molecules/index.ts @@ -28,6 +28,7 @@ export * from "./GovernanceActionDetailsCardLinks"; export * from "./GovernanceActionDetailsCardOnChainData"; export * from "./GovernanceActionDetailsCardVotes"; export * from "./GovernanceActionDetailsDiffView"; +export * from "./GovernanceActionNewConstitutionDetailsTabContent"; export * from "./GovernanceActionNewCommitteeDetailsTabContent"; export * from "./GovernanceActionsDatesBox"; export * from "./GovernanceVotedOnCard"; diff --git a/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx b/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx index 8928a6566..bd3941f2c 100644 --- a/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx +++ b/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx @@ -11,6 +11,7 @@ import { GovernanceActionDetailsDiffView, GovernanceActionNewCommitteeDetailsTabContent, GovernanceActionCardTreasuryWithdrawalElement, + GovernanceActionNewConstitutionDetailsTabContent, } from "@molecules"; import { useScreenDimension, useTranslation } from "@hooks"; import { @@ -22,11 +23,7 @@ import { mapArrayToObjectByKeys, encodeCIP129Identifier, } from "@utils"; -import { - MetadataValidationStatus, - NewConstitutionAnchor, - ProposalData, -} from "@models"; +import { MetadataValidationStatus, ProposalData } from "@models"; import { GovernanceActionType } from "@/types/governanceAction"; import { useAppContext } from "@/context"; @@ -200,6 +197,19 @@ export const GovernanceActionDetailsCardData = ({ ), visible: type === GovernanceActionType.NewCommittee && !!details, }, + { + label: "Parameters", + dataTestId: "parameters-tab", + content: ( + + ), + visible: + type === GovernanceActionType.NewConstitution && + !!details && + !!details?.anchor, + }, ].filter((tab) => tab.visible), [ abstract, @@ -307,26 +317,6 @@ export const GovernanceActionDetailsCardData = ({ amount={withdrawal.amount} /> ))} - {details?.anchor && type === GovernanceActionType.NewConstitution && ( - <> - 1600 ? "longText" : "oneLine"} - /> - 1600 ? "longText" : "oneLine"} - /> - - )} ); From f2380e41a82ada03019a5d6a6daeb8de46fae6e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Fri, 20 Dec 2024 16:27:17 +0100 Subject: [PATCH 17/30] Update govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ryan Signed-off-by: Michał Szałowski --- .../components/organisms/GovernanceActionDetailsCardData.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx b/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx index bd3941f2c..149eebeb3 100644 --- a/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx +++ b/govtool/frontend/src/components/organisms/GovernanceActionDetailsCardData.tsx @@ -198,7 +198,7 @@ export const GovernanceActionDetailsCardData = ({ visible: type === GovernanceActionType.NewCommittee && !!details, }, { - label: "Parameters", + label: "Details", dataTestId: "parameters-tab", content: ( Date: Mon, 23 Dec 2024 08:31:57 +0545 Subject: [PATCH 18/30] feat: add skipIfMainnet helper function to conditionally skip tests on mainnet --- .../playwright/lib/helpers/cardano.ts | 12 +++++++++++- .../tests/2-delegation/delegation.drep.spec.ts | 4 ++-- .../delegationFunctionality.delegation.spec.ts | 4 ++-- .../dRepRegistration.dRep.spec.ts | 4 ++-- .../tests/3-drep-registration/editDRep.dRep.spec.ts | 4 ++-- .../proposalVisibility.dRep.spec.ts | 3 ++- .../proposalFunctionality.dRep.spec.ts | 8 ++++++-- .../tests/6-miscellaneous/miscellaneous.dRep.spec.ts | 4 ++-- .../proposalSubmission.ga.spec.ts | 4 ++-- .../govtool-frontend/playwright/tests/dRep.setup.ts | 4 ++-- .../playwright/tests/dRep.teardown.ts | 3 ++- .../playwright/tests/delegation.teardown.ts | 4 ++-- .../playwright/tests/faucet.setup.ts | 3 ++- .../playwright/tests/faucet.teardown.ts | 3 ++- .../playwright/tests/wallet.bootstrap.ts | 3 ++- 15 files changed, 43 insertions(+), 24 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/helpers/cardano.ts b/tests/govtool-frontend/playwright/lib/helpers/cardano.ts index c501a05c6..37a06b2d1 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/cardano.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/cardano.ts @@ -1,4 +1,5 @@ -import test, { expect } from "@playwright/test"; +import environments from "@constants/environments"; +import test from "@playwright/test"; import kuberService from "@services/kuberService"; import { ProposalType, ProtocolParams } from "@types"; import { allure } from "allure-playwright"; @@ -45,3 +46,12 @@ export async function skipIfNotHardFork() { test.skip(); } } + +export async function skipIfMainnet() { + if (environments.networkId === 1) { + await allure.description( + "Ada spendable features are not available on mainnet." + ); + test.skip(); + } +} diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.drep.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.drep.spec.ts index 197a75945..dcc9fcf8c 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.drep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.drep.spec.ts @@ -3,7 +3,7 @@ import { createTempDRepAuth } from "@datafactory/createAuth"; import { faker } from "@faker-js/faker"; import { test } from "@fixtures/walletExtension"; import { setAllureEpic } from "@helpers/allure"; -import { skipIfNotHardFork } from "@helpers/cardano"; +import { skipIfMainnet, skipIfNotHardFork } from "@helpers/cardano"; import { ShelleyWallet } from "@helpers/crypto"; import { createNewPageWithWallet } from "@helpers/page"; import DRepRegistrationPage from "@pages/dRepRegistrationPage"; @@ -14,7 +14,7 @@ import walletManager from "lib/walletManager"; test.beforeEach(async () => { await setAllureEpic("2. Delegation"); await skipIfNotHardFork(); - test.skip(environments.networkId === 1); + await skipIfMainnet(); }); test("2N. Should show DRep information on details page", async ({ diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts index 4d7040415..cee19afa1 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts @@ -12,7 +12,7 @@ import { import { createTempDRepAuth } from "@datafactory/createAuth"; import { test } from "@fixtures/walletExtension"; import { setAllureEpic } from "@helpers/allure"; -import { skipIfNotHardFork } from "@helpers/cardano"; +import { skipIfMainnet, skipIfNotHardFork } from "@helpers/cardano"; import { createNewPageWithWallet } from "@helpers/page"; import { waitForTxConfirmation } from "@helpers/transaction"; import DRepDirectoryPage from "@pages/dRepDirectoryPage"; @@ -24,7 +24,7 @@ import walletManager from "lib/walletManager"; test.beforeEach(async () => { await setAllureEpic("2. Delegation"); await skipIfNotHardFork(); - test.skip(environments.networkId === 1); + await skipIfMainnet(); }); test.describe("Delegate to others", () => { diff --git a/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.dRep.spec.ts index 5687d9b76..a898d7df6 100644 --- a/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.dRep.spec.ts @@ -5,7 +5,7 @@ import { faker } from "@faker-js/faker"; import { test } from "@fixtures/walletExtension"; import { setAllureEpic } from "@helpers/allure"; import { ShelleyWallet } from "@helpers/crypto"; -import { skipIfNotHardFork } from "@helpers/cardano"; +import { skipIfMainnet, skipIfNotHardFork } from "@helpers/cardano"; import { createNewPageWithWallet } from "@helpers/page"; import { waitForTxConfirmation } from "@helpers/transaction"; import DRepRegistrationPage from "@pages/dRepRegistrationPage"; @@ -18,7 +18,7 @@ import { GovernanceActionType } from "@types"; test.beforeEach(async () => { await setAllureEpic("3. DRep registration"); await skipIfNotHardFork(); - test.skip(environments.networkId === 1); + await skipIfMainnet(); }); test.describe("Logged in DReps", () => { diff --git a/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts index 0f20aad56..27abd1a31 100644 --- a/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts @@ -4,7 +4,7 @@ import { test } from "@fixtures/walletExtension"; import { setAllureEpic } from "@helpers/allure"; import { ShelleyWallet } from "@helpers/crypto"; import { invalid as mockInvalid, valid as mockValid } from "@mock/index"; -import { skipIfNotHardFork } from "@helpers/cardano"; +import { skipIfMainnet, skipIfNotHardFork } from "@helpers/cardano"; import EditDRepPage from "@pages/editDRepPage"; import { expect } from "@playwright/test"; import environments from "@constants/environments"; @@ -12,7 +12,7 @@ import environments from "@constants/environments"; test.beforeEach(async () => { await setAllureEpic("3. DRep registration"); await skipIfNotHardFork(); - test.skip(environments.networkId === 1); + await skipIfMainnet(); }); test.use({ wallet: dRep02Wallet, storageState: ".auth/dRep02.json" }); 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 4bdae4c5e..8e532d35f 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 @@ -7,6 +7,7 @@ import { setAllureEpic } from "@helpers/allure"; import { isBootStrapingPhase, lovelaceToAda, + skipIfMainnet, skipIfNotHardFork, } from "@helpers/cardano"; import { createNewPageWithWallet } from "@helpers/page"; @@ -30,7 +31,7 @@ import { test.beforeEach(async () => { await setAllureEpic("4. Proposal visibility"); await skipIfNotHardFork(); - test.skip(environments.networkId === 1); + await skipIfMainnet(); }); test.describe("Logged in DRep", () => { diff --git a/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.dRep.spec.ts index b017ad2b4..1fb3059d6 100644 --- a/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.dRep.spec.ts @@ -4,7 +4,11 @@ import { createTempDRepAuth } from "@datafactory/createAuth"; import { faker } from "@faker-js/faker"; import { test } from "@fixtures/walletExtension"; import { setAllureEpic } from "@helpers/allure"; -import { isBootStrapingPhase, skipIfNotHardFork } from "@helpers/cardano"; +import { + isBootStrapingPhase, + skipIfMainnet, + skipIfNotHardFork, +} from "@helpers/cardano"; import { encodeCIP129Identifier } from "@helpers/encodeDecode"; import { createNewPageWithWallet } from "@helpers/page"; import { waitForTxConfirmation } from "@helpers/transaction"; @@ -18,7 +22,7 @@ import walletManager from "lib/walletManager"; test.beforeEach(async () => { await setAllureEpic("5. Proposal functionality"); await skipIfNotHardFork(); - test.skip(environments.networkId === 1); + await skipIfMainnet(); }); test.describe("Proposal checks", () => { diff --git a/tests/govtool-frontend/playwright/tests/6-miscellaneous/miscellaneous.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/6-miscellaneous/miscellaneous.dRep.spec.ts index 073d52d3a..cc299875e 100644 --- a/tests/govtool-frontend/playwright/tests/6-miscellaneous/miscellaneous.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/6-miscellaneous/miscellaneous.dRep.spec.ts @@ -2,13 +2,13 @@ import environments from "@constants/environments"; import { dRep01Wallet } from "@constants/staticWallets"; import { test } from "@fixtures/walletExtension"; import { setAllureEpic } from "@helpers/allure"; -import { skipIfNotHardFork } from "@helpers/cardano"; +import { skipIfMainnet, skipIfNotHardFork } from "@helpers/cardano"; import { expect } from "@playwright/test"; test.beforeEach(async () => { await setAllureEpic("6. Miscellaneous"); await skipIfNotHardFork(); - test.skip(environments.networkId === 1); + await skipIfMainnet(); }); test.use({ diff --git a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts index 48eb5cb0a..1918b7a47 100644 --- a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts +++ b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.ga.spec.ts @@ -7,14 +7,14 @@ import { waitForTxConfirmation } from "@helpers/transaction"; import ProposalDiscussionPage from "@pages/proposalDiscussionPage"; import ProposalSubmissionPage from "@pages/proposalSubmissionPage"; import { expect } from "@playwright/test"; -import { skipIfNotHardFork } from "@helpers/cardano"; +import { skipIfMainnet, skipIfNotHardFork } from "@helpers/cardano"; import { ProposalType } from "@types"; import { proposalFaucetWallet } from "@constants/proposalFaucetWallet"; test.beforeEach(async () => { await setAllureEpic("7. Proposal submission"); await skipIfNotHardFork(); - test.skip(environments.networkId === 1); + await skipIfMainnet(); }); Object.values(ProposalType).forEach((proposalType, index) => { diff --git a/tests/govtool-frontend/playwright/tests/dRep.setup.ts b/tests/govtool-frontend/playwright/tests/dRep.setup.ts index 96af045f9..5da1f4f50 100644 --- a/tests/govtool-frontend/playwright/tests/dRep.setup.ts +++ b/tests/govtool-frontend/playwright/tests/dRep.setup.ts @@ -1,7 +1,7 @@ import environments from "@constants/environments"; import { dRepWallets } from "@constants/staticWallets"; import { setAllureEpic, setAllureStory } from "@helpers/allure"; -import { skipIfNotHardFork } from "@helpers/cardano"; +import { skipIfMainnet, skipIfNotHardFork } from "@helpers/cardano"; import { ShelleyWallet } from "@helpers/crypto"; import { uploadMetadataAndGetJsonHash } from "@helpers/metadata"; import { pollTransaction } from "@helpers/transaction"; @@ -23,7 +23,7 @@ setup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Register DRep"); await skipIfNotHardFork(); - setup.skip(environments.networkId === 1); + await skipIfMainnet(); }); async function generateWallets(num: number) { diff --git a/tests/govtool-frontend/playwright/tests/dRep.teardown.ts b/tests/govtool-frontend/playwright/tests/dRep.teardown.ts index 6e22c44f9..89be4b0f2 100644 --- a/tests/govtool-frontend/playwright/tests/dRep.teardown.ts +++ b/tests/govtool-frontend/playwright/tests/dRep.teardown.ts @@ -1,6 +1,7 @@ import environments from "@constants/environments"; import { dRepWallets } from "@constants/staticWallets"; import { setAllureEpic, setAllureStory } from "@helpers/allure"; +import { skipIfMainnet } from "@helpers/cardano"; import { pollTransaction } from "@helpers/transaction"; import { test as cleanup, expect } from "@playwright/test"; import kuberService from "@services/kuberService"; @@ -11,7 +12,7 @@ cleanup.describe.configure({ timeout: environments.txTimeOut }); cleanup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Cleanup"); - cleanup.skip(environments.networkId === 1); + await skipIfMainnet(); }); cleanup("DRep de-registration", async () => { diff --git a/tests/govtool-frontend/playwright/tests/delegation.teardown.ts b/tests/govtool-frontend/playwright/tests/delegation.teardown.ts index 8a994c3b1..26dbaa135 100644 --- a/tests/govtool-frontend/playwright/tests/delegation.teardown.ts +++ b/tests/govtool-frontend/playwright/tests/delegation.teardown.ts @@ -1,7 +1,7 @@ import environments from "@constants/environments"; import { adaHolderWallets } from "@constants/staticWallets"; import { setAllureStory, setAllureEpic } from "@helpers/allure"; -import { skipIfNotHardFork } from "@helpers/cardano"; +import { skipIfMainnet, skipIfNotHardFork } from "@helpers/cardano"; import { pollTransaction } from "@helpers/transaction"; import { test as cleanup } from "@playwright/test"; import kuberService from "@services/kuberService"; @@ -11,7 +11,7 @@ cleanup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Cleanup"); await skipIfNotHardFork(); - cleanup.skip(environments.networkId === 1); + await skipIfMainnet(); }); cleanup(`Abstain delegation`, async () => { const stakePrivKeys = adaHolderWallets.map((wallet) => wallet.stake.private); diff --git a/tests/govtool-frontend/playwright/tests/faucet.setup.ts b/tests/govtool-frontend/playwright/tests/faucet.setup.ts index db1bd708e..bd5a501f1 100644 --- a/tests/govtool-frontend/playwright/tests/faucet.setup.ts +++ b/tests/govtool-frontend/playwright/tests/faucet.setup.ts @@ -1,6 +1,7 @@ import environments from "@constants/environments"; import { faucetWallet } from "@constants/staticWallets"; import { setAllureEpic, setAllureStory } from "@helpers/allure"; +import { skipIfMainnet } from "@helpers/cardano"; import { pollTransaction } from "@helpers/transaction"; import { test as setup } from "@playwright/test"; import { loadAmountFromFaucet } from "@services/faucetService"; @@ -11,7 +12,7 @@ setup.describe.configure({ timeout: environments.txTimeOut }); setup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Faucet"); - setup.skip(environments.networkId === 1); + await skipIfMainnet(); }); setup("Faucet setup", async () => { diff --git a/tests/govtool-frontend/playwright/tests/faucet.teardown.ts b/tests/govtool-frontend/playwright/tests/faucet.teardown.ts index 1708d3211..f64398eeb 100644 --- a/tests/govtool-frontend/playwright/tests/faucet.teardown.ts +++ b/tests/govtool-frontend/playwright/tests/faucet.teardown.ts @@ -1,6 +1,7 @@ import environments from "@constants/environments"; import { faucetWallet } from "@constants/staticWallets"; import { setAllureEpic, setAllureStory } from "@helpers/allure"; +import { skipIfMainnet } from "@helpers/cardano"; import { pollTransaction } from "@helpers/transaction"; import { test as cleanup, expect } from "@playwright/test"; import kuberService from "@services/kuberService"; @@ -9,7 +10,7 @@ cleanup.describe.configure({ timeout: environments.txTimeOut }); cleanup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Cleanup"); - cleanup.skip(environments.networkId === 1); + await skipIfMainnet(); }); cleanup("Refund faucet", async () => { diff --git a/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts b/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts index fa28c262d..72dd3e4d6 100644 --- a/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts +++ b/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts @@ -1,5 +1,6 @@ import { adaHolderWallets, dRepWallets } from "@constants/staticWallets"; import { setAllureEpic, setAllureStory } from "@helpers/allure"; +import { skipIfMainnet } from "@helpers/cardano"; import { pollTransaction } from "@helpers/transaction"; import { expect, test as setup } from "@playwright/test"; import kuberService from "@services/kuberService"; @@ -10,7 +11,7 @@ setup.describe.configure({ mode: "serial", timeout: environments.txTimeOut }); setup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Wallet bootstrap"); - setup.skip(environments.networkId === 1); + await skipIfMainnet(); }); setup("Initialize static wallets", async () => { From b1ee1eaba390fd363a216315afc14de1288e8198 Mon Sep 17 00:00:00 2001 From: Niraj Date: Mon, 23 Dec 2024 12:11:33 +0545 Subject: [PATCH 19/30] refactor: add cleanup logic for test-created proposals --- .../proposalSubmission.loggedin.spec.ts | 11 +++++++++++ .../proposalDiscussion.loggedin.spec.ts | 16 ---------------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts index 3695e2b97..0a9697715 100644 --- a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts +++ b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts @@ -141,6 +141,8 @@ test.describe("Proposal created logged state", () => { await proposalSubmissionPage.submitBtn.click(); await expect(page.getByTestId("submit-as-GA-button")).toBeVisible(); + const proposalDetailsPage = new ProposalDiscussionDetailsPage(page); + await expect(proposalSubmissionPage.titleContent).toHaveText( proposal.prop_name ); @@ -159,6 +161,9 @@ test.describe("Proposal created logged state", () => { await expect(proposalSubmissionPage.linkTextContent).toHaveText( proposal.proposal_links[0].prop_link_text ); + + // cleanup + await proposalDetailsPage.deleteProposal(); }); }); }); @@ -428,6 +433,9 @@ test.describe("Info Proposal Draft", () => { await proposalSubmissionPage.submitBtn.click(); await expect(page.getByTestId("submit-as-GA-button")).toBeVisible(); + const proposalDiscussionDetailsPage = new ProposalDiscussionDetailsPage( + page + ); await expect(proposalSubmissionPage.titleContent).toHaveText( proposalFormValue.prop_name ); @@ -446,6 +454,9 @@ test.describe("Info Proposal Draft", () => { await expect(proposalSubmissionPage.linkTextContent).toHaveText( proposalFormValue.proposal_links[0].prop_link_text ); + + //cleanup + proposalDiscussionDetailsPage.deleteProposal(); }); }); diff --git a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.loggedin.spec.ts index fa9dbc999..36568db3b 100644 --- a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.loggedin.spec.ts +++ b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.loggedin.spec.ts @@ -3,10 +3,8 @@ import { proposal02Wallet, user01Wallet, } from "@constants/staticWallets"; -import { createTempUserAuth } from "@datafactory/createAuth"; import { faker } from "@faker-js/faker"; import { test } from "@fixtures/proposal"; -import { ShelleyWallet } from "@helpers/crypto"; import { createNewPageWithWallet } from "@helpers/page"; import ProposalDiscussionDetailsPage from "@pages/proposalDiscussionDetailsPage"; import { Page, expect } from "@playwright/test"; @@ -133,20 +131,6 @@ test.describe("Proposal created with poll enabled (user auth)", () => { }); }); -test.describe("Proposal created logged out state", () => { - let userPage: Page; - - test.beforeEach(async ({ page, browser }) => { - const wallet = (await ShelleyWallet.generate()).json(); - const tempUserAuth = await createTempUserAuth(page, wallet); - - userPage = await createNewPageWithWallet(browser, { - storageState: tempUserAuth, - wallet, - }); - }); -}); - test.describe("Proposal created with poll enabled (proposal auth)", () => { test.use({ storageState: ".auth/user01.json", From 63b50c4f3ca286a65fe811f48cbef366e28fb234 Mon Sep 17 00:00:00 2001 From: Niraj Date: Mon, 23 Dec 2024 14:44:51 +0545 Subject: [PATCH 20/30] fix: remove unnecessary mainnet dummy dRep id --- .../playwright/tests/2-delegation/delegation.loggedin.spec.ts | 4 ++-- .../playwright/tests/2-delegation/delegation.spec.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts index 4490463c0..837c41011 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts @@ -76,8 +76,8 @@ test("2X_2. Should include info button and voting power on the Signal-No-Confide }); test.describe("DRep dependent tests", () => { - let dRepGivenName = "test"; - let dRepId = "drep1ef7uslcjhjqrn4vv2y39c3yn345gzjsg7yufn76zye3v6fkz23q"; + let dRepGivenName: string; + let dRepId: string; let dRepDirectoryPage: DRepDirectoryPage; test.beforeEach(async ({ page }) => { diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts index 8cac54d43..ddd37c318 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.spec.ts @@ -137,7 +137,7 @@ test("2M. Should access dRep directory page on disconnected state", async ({ }); test.describe("DRep dependent tests", () => { - let dRepId = "drep1ef7uslcjhjqrn4vv2y39c3yn345gzjsg7yufn76zye3v6fkz23q"; + let dRepId: string; let dRepDirectoryPage: DRepDirectoryPage; test.beforeEach(async ({ page }) => { From 5a38c88721c20f5b3b3570fbede59c12b665cd69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Mon, 23 Dec 2024 14:50:51 +0100 Subject: [PATCH 21/30] Update govtool/frontend/src/components/molecules/GovernanceActionNewConstitutionDetailsTabContent.tsx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ryan Signed-off-by: Michał Szałowski --- .../GovernanceActionNewConstitutionDetailsTabContent.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/govtool/frontend/src/components/molecules/GovernanceActionNewConstitutionDetailsTabContent.tsx b/govtool/frontend/src/components/molecules/GovernanceActionNewConstitutionDetailsTabContent.tsx index 9c0f4016c..82e9e26f5 100644 --- a/govtool/frontend/src/components/molecules/GovernanceActionNewConstitutionDetailsTabContent.tsx +++ b/govtool/frontend/src/components/molecules/GovernanceActionNewConstitutionDetailsTabContent.tsx @@ -20,7 +20,7 @@ export const GovernanceActionNewConstitutionDetailsTabContent = ({ /> 1600 ? "longText" : "oneLine"} From 1830056f58b59eb5522cdc56fb9ab04170416204 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Mon, 23 Dec 2024 14:51:00 +0100 Subject: [PATCH 22/30] Update CHANGELOG.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ryan Signed-off-by: Michał Szałowski --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f163b6c8b..827cd4ce9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,7 @@ changes. ### Changed -- Split New committee on-chain details into tabs +- Split New constitution on-chain details into tabs ### Removed From 13b4c177b29e21626d11d9bac719d83da84a2618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Mon, 23 Dec 2024 14:49:43 +0100 Subject: [PATCH 23/30] fix(#2571): add support for searching by cip-129 identifiers --- CHANGELOG.md | 3 +- govtool/backend/sql/list-dreps.sql | 2 +- ...nceActionNewCommitteeDetailsTabContent.tsx | 4 +- .../src/components/organisms/DRepCard.tsx | 108 +++++++++++++----- .../components/organisms/DRepDetailsCard.tsx | 19 ++- govtool/frontend/src/i18n/locales/en.json | 1 + .../src/services/requests/getDRepList.ts | 22 +++- .../src/services/requests/getProposals.ts | 16 ++- govtool/metadata-validation/package-lock.json | 4 +- 9 files changed, 143 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 827cd4ce9..9cebca540 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,7 @@ changes. - -## [v2.0.2](https://github.com/IntersectMBO/govtool/releases/tag/v2.0.2) 2024-12-20 +## [v2.0.2](https://github.com/IntersectMBO/govtool/releases/tag/v2.0.2) 2024-12-23 ### Added @@ -37,6 +37,7 @@ changes. - Move matomo initalization out of the react code - Fix some non-ipfs related errors while fetching the DRep images [Issue 2546](https://github.com/IntersectMBO/govtool/issues/2546) - Remaining mobile responsiveness issue [Issue 2493](https://github.com/IntersectMBO/govtool/issues/2493) +- Fix searching by CIP-129 identifiers [Issue 2571](https://github.com/IntersectMBO/govtool/issues/2571) ### Changed diff --git a/govtool/backend/sql/list-dreps.sql b/govtool/backend/sql/list-dreps.sql index 043b316d2..e6518a7cb 100644 --- a/govtool/backend/sql/list-dreps.sql +++ b/govtool/backend/sql/list-dreps.sql @@ -26,7 +26,7 @@ SELECT encode(va.data_hash, 'hex'), dr_deposit.deposit, DRepDistr.amount, -(DRepActivity.epoch_no - Max(coalesce(block.epoch_no, block_first_register.epoch_no))) <= DRepActivity.drep_activity AS active, + (DRepActivity.epoch_no - Max(coalesce(block.epoch_no, block_first_register.epoch_no))) <= DRepActivity.drep_activity AS active, encode(dr_voting_anchor.tx_hash, 'hex') AS tx_hash, newestRegister.time AS last_register_time, COALESCE(latestDeposit.deposit, 0), diff --git a/govtool/frontend/src/components/molecules/GovernanceActionNewCommitteeDetailsTabContent.tsx b/govtool/frontend/src/components/molecules/GovernanceActionNewCommitteeDetailsTabContent.tsx index 920b72b08..fc244db2f 100644 --- a/govtool/frontend/src/components/molecules/GovernanceActionNewCommitteeDetailsTabContent.tsx +++ b/govtool/frontend/src/components/molecules/GovernanceActionNewCommitteeDetailsTabContent.tsx @@ -21,7 +21,7 @@ export const GovernanceActionNewCommitteeDetailsTabContent = ({ .filter((member) => member.newExpirationEpoch === undefined) .map((member) => ({ cip129Identifier: encodeCIP129Identifier({ - txID: member.hash, + txID: (member.hasScript ? "02" : "13") + member.hash, bech32Prefix: member.hasScript ? "cc_hot" : "cc_cold", }), expirationEpoch: member.expirationEpoch, @@ -31,7 +31,7 @@ export const GovernanceActionNewCommitteeDetailsTabContent = ({ .filter((member) => member.newExpirationEpoch !== undefined) .map((member) => ({ cip129Identifier: encodeCIP129Identifier({ - txID: member.hash, + txID: (member.hasScript ? "02" : "13") + member.hash, bech32Prefix: member.hasScript ? "cc_hot" : "cc_cold", }), expirationEpoch: member.expirationEpoch, diff --git a/govtool/frontend/src/components/organisms/DRepCard.tsx b/govtool/frontend/src/components/organisms/DRepCard.tsx index ed044d0ba..75f17b725 100644 --- a/govtool/frontend/src/components/organisms/DRepCard.tsx +++ b/govtool/frontend/src/components/organisms/DRepCard.tsx @@ -10,6 +10,7 @@ import { Card } from "@molecules"; import { correctDRepDirectoryFormat, ellipsizeText, + encodeCIP129Identifier, getMetadataDataMissingStatusTranslation, } from "@utils"; @@ -24,7 +25,16 @@ type DRepCardProps = { }; export const DRepCard = ({ - dRep: { status, type, view, votingPower, givenName, metadataStatus, image }, + dRep: { + status, + type, + view, + votingPower, + givenName, + metadataStatus, + image, + drepId, + }, isConnected, isDelegationLoading, isInProgress, @@ -48,6 +58,11 @@ export const DRepCard = ({ }, }); + const cip129Identifier = encodeCIP129Identifier({ + txID: `22${drepId}`, + bech32Prefix: "drep", + }); + return ( - { - navigator.clipboard.writeText(view); - addSuccessAlert(t("alerts.copiedToClipboard")); - e.stopPropagation(); - }} + - { + navigator.clipboard.writeText(view); + addSuccessAlert(t("alerts.copiedToClipboard")); + e.stopPropagation(); + }} + sx={{ + gap: 1, + width: "250px", + maxWidth: { + xxs: "200px", + xs: "100%", + }, + "&:hover": { + opacity: 0.6, + transition: "opacity 0.3s", + }, + }} > - {view} - - - + + {view} + + + + { + navigator.clipboard.writeText(cip129Identifier); + addSuccessAlert(t("alerts.copiedToClipboard")); + e.stopPropagation(); + }} + sx={{ + gap: 1, + width: "250px", + maxWidth: { + xxs: "200px", + xs: "100%", + }, + "&:hover": { + opacity: 0.6, + transition: "opacity 0.3s", + }, + display: "flex", + flexDirection: "row", + }} + > + + (CIP-129){" "} + + {cip129Identifier} + + + + + diff --git a/govtool/frontend/src/components/organisms/DRepDetailsCard.tsx b/govtool/frontend/src/components/organisms/DRepDetailsCard.tsx index 90518a64a..196802c30 100644 --- a/govtool/frontend/src/components/organisms/DRepDetailsCard.tsx +++ b/govtool/frontend/src/components/organisms/DRepDetailsCard.tsx @@ -6,7 +6,11 @@ import { ICONS, PATHS } from "@consts"; import { useCardano, useModal } from "@context"; import { useDelegateTodRep, useScreenDimension, useTranslation } from "@hooks"; import { Card, DataMissingInfoBox } from "@molecules"; -import { correctAdaFormat, testIdFromLabel } from "@utils"; +import { + correctAdaFormat, + encodeCIP129Identifier, + testIdFromLabel, +} from "@utils"; import { DRepData } from "@/models"; import { DRepDetailsCardHeader } from "./DRepDetailsCardHeader"; @@ -41,6 +45,7 @@ export const DRepDetailsCard = ({ status, url, view, + drepId, votingPower, } = dRepData; @@ -109,6 +114,18 @@ export const DRepDetailsCard = ({ + + + diff --git a/govtool/frontend/src/i18n/locales/en.json b/govtool/frontend/src/i18n/locales/en.json index f9faf8cbc..19bef3aeb 100644 --- a/govtool/frontend/src/i18n/locales/en.json +++ b/govtool/frontend/src/i18n/locales/en.json @@ -747,6 +747,7 @@ "copiedLink": "Copied link", "delegate": "Delegate", "drepId": "DRep ID", + "cip129DrepId": "(CIP-129) DRep ID", "email": "Email", "feedback": "Feedback", "filter": "Filter", diff --git a/govtool/frontend/src/services/requests/getDRepList.ts b/govtool/frontend/src/services/requests/getDRepList.ts index 532f7ee60..5005e1313 100644 --- a/govtool/frontend/src/services/requests/getDRepList.ts +++ b/govtool/frontend/src/services/requests/getDRepList.ts @@ -8,7 +8,11 @@ import { DrepDataDTO, } from "@models"; import { API } from "../API"; -import { mapDtoToDrep } from "@/utils"; +import { + decodeCIP129Identifier, + encodeCIP129Identifier, + mapDtoToDrep, +} from "@/utils"; export type GetDRepListArguments = { filters?: string[]; @@ -34,6 +38,22 @@ export const getDRepList = async ({ const { words } = bech32.decode(rawSearchPhrase); return bech32.encode("drep", words); } + if (rawSearchPhrase.startsWith("drep")) { + const decodedIdentifier = decodeCIP129Identifier(rawSearchPhrase); + if (decodedIdentifier) { + const isCIP129Identifier = decodedIdentifier.txID.startsWith("22"); + if (isCIP129Identifier) { + return encodeCIP129Identifier({ + txID: decodedIdentifier.txID.slice(2), + bech32Prefix: "drep", + }); + } + return encodeCIP129Identifier({ + txID: decodedIdentifier.txID, + bech32Prefix: "drep", + }); + } + } return rawSearchPhrase; })(); diff --git a/govtool/frontend/src/services/requests/getProposals.ts b/govtool/frontend/src/services/requests/getProposals.ts index 333cad371..9e9fef4d0 100644 --- a/govtool/frontend/src/services/requests/getProposals.ts +++ b/govtool/frontend/src/services/requests/getProposals.ts @@ -1,7 +1,11 @@ import { Infinite, ProposalData, ProposalDataDTO } from "@models"; import { API } from "../API"; -import { mapDtoToProposal } from "@/utils"; +import { + decodeCIP129Identifier, + getFullGovActionId, + mapDtoToProposal, +} from "@/utils"; export type GetProposalsArguments = { dRepID?: string; @@ -18,9 +22,17 @@ export const getProposals = async ({ page = 0, // It allows fetch proposals and if we have 7 items, display 6 cards and "view all" button pageSize = 7, - searchPhrase = "", + searchPhrase: rawSearchPhrase = "", sorting = "", }: GetProposalsArguments): Promise> => { + const searchPhrase = (() => { + if (rawSearchPhrase.startsWith("gov_action")) { + const { txID } = decodeCIP129Identifier(rawSearchPhrase); + return getFullGovActionId(txID, 0); + } + + return rawSearchPhrase; + })(); const response = await API.get>("/proposal/list", { params: { page, diff --git a/govtool/metadata-validation/package-lock.json b/govtool/metadata-validation/package-lock.json index 061b263db..e31f70cbf 100644 --- a/govtool/metadata-validation/package-lock.json +++ b/govtool/metadata-validation/package-lock.json @@ -1,12 +1,12 @@ { "name": "@govtool/metadata-validation", - "version": "2.0.0", + "version": "2.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@govtool/metadata-validation", - "version": "2.0.0", + "version": "2.0.2", "license": "UNLICENSED", "dependencies": { "@nestjs/axios": "^3.0.2", From 3d8016041595d99f6ff35786e27f52c1ccb9905f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Mon, 23 Dec 2024 15:22:43 +0100 Subject: [PATCH 24/30] chore: optimize the db connection and drep list sql --- govtool/backend/app/Main.hs | 18 +++++-- govtool/backend/sql/list-dreps.sql | 78 +++++++++++++++++------------- 2 files changed, 59 insertions(+), 37 deletions(-) diff --git a/govtool/backend/app/Main.hs b/govtool/backend/app/Main.hs index 02f217e21..9accf102d 100644 --- a/govtool/backend/app/Main.hs +++ b/govtool/backend/app/Main.hs @@ -26,7 +26,7 @@ import Data.Monoid (mempty) import Data.OpenApi (OpenApi, Server (Server), _openApiServers, _serverDescription, _serverUrl, _serverVariables, servers) -import Data.Pool (createPool) +import Data.Pool (createPool, Pool) import Data.Proxy import Data.String (fromString) import Data.String.Conversions (cs) @@ -36,7 +36,7 @@ import qualified Data.Text.IO as Text import qualified Data.Text.Lazy as LazyText import qualified Data.Text.Lazy.Encoding as LazyText -import Database.PostgreSQL.Simple (close, connectPostgreSQL) +import Database.PostgreSQL.Simple (close, connectPostgreSQL, Connection) import Network.Wai import Network.Wai.Handler.Warp @@ -65,6 +65,15 @@ import VVA.Types (AppEnv (..), AppError (CriticalError, InternalError, NotFoundError, ValidationError), CacheEnv (..)) +-- Function to create a connection pool with optimized settings +createOptimizedConnectionPool :: BS.ByteString -> IO (Pool Connection) +createOptimizedConnectionPool connectionString = createPool + (connectPostgreSQL connectionString) -- Connection creation function + close -- Connection destruction function + 1 -- Number of stripes (sub-pools) + 60 -- Idle timeout (seconds) + 50 -- Maximum number of connections per stripe + proxyAPI :: Proxy (VVAApi :<|> SwaggerAPI) proxyAPI = Proxy @@ -125,7 +134,10 @@ startApp vvaConfig sentryService = do , dRepListCache , networkMetricsCache } - connectionPool <- createPool (connectPostgreSQL (encodeUtf8 (dbSyncConnectionString $ getter vvaConfig))) close 1 10 60 + + let connectionString = encodeUtf8 (dbSyncConnectionString $ getter vvaConfig) + connectionPool <- createOptimizedConnectionPool connectionString + let appEnv = AppEnv {vvaConfig=vvaConfig, vvaCache=cacheEnv, vvaConnectionPool=connectionPool } server' <- mkVVAServer appEnv runSettings settings server' diff --git a/govtool/backend/sql/list-dreps.sql b/govtool/backend/sql/list-dreps.sql index e6518a7cb..f5680c319 100644 --- a/govtool/backend/sql/list-dreps.sql +++ b/govtool/backend/sql/list-dreps.sql @@ -1,6 +1,6 @@ WITH DRepDistr AS ( SELECT - *, + drep_distr.*, ROW_NUMBER() OVER (PARTITION BY drep_hash.id ORDER BY drep_distr.epoch_no DESC) AS rn FROM drep_distr @@ -8,8 +8,8 @@ WITH DRepDistr AS ( ), DRepActivity AS ( SELECT - drep_activity AS drep_activity, - epoch_no AS epoch_no + drep_activity, + epoch_no FROM epoch_param WHERE @@ -26,7 +26,7 @@ SELECT encode(va.data_hash, 'hex'), dr_deposit.deposit, DRepDistr.amount, - (DRepActivity.epoch_no - Max(coalesce(block.epoch_no, block_first_register.epoch_no))) <= DRepActivity.drep_activity AS active, + (DRepActivity.epoch_no - COALESCE(block.epoch_no, block_first_register.epoch_no)) <= DRepActivity.drep_activity AS active, encode(dr_voting_anchor.tx_hash, 'hex') AS tx_hash, newestRegister.time AS last_register_time, COALESCE(latestDeposit.deposit, 0), @@ -50,17 +50,17 @@ FROM FROM drep_registration dr WHERE - dr.deposit IS NOT NULL) AS dr_deposit ON dr_deposit.drep_hash_id = dh.id - AND dr_deposit.rn = 1 - JOIN ( + dr.deposit IS NOT NULL + ) AS dr_deposit ON dr_deposit.drep_hash_id = dh.id AND dr_deposit.rn = 1 + JOIN ( SELECT dr.id, dr.drep_hash_id, dr.deposit, ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id DESC) AS rn FROM - drep_registration dr) AS latestDeposit ON latestDeposit.drep_hash_id = dh.id - AND latestDeposit.rn = 1 + drep_registration dr + ) AS latestDeposit ON latestDeposit.drep_hash_id = dh.id AND latestDeposit.rn = 1 LEFT JOIN ( SELECT dr.id, @@ -70,9 +70,11 @@ FROM tx.hash AS tx_hash FROM drep_registration dr - JOIN tx ON tx.id = dr.tx_id) AS dr_voting_anchor ON dr_voting_anchor.drep_hash_id = dh.id - AND dr_voting_anchor.rn = 1 - LEFT JOIN ( + JOIN tx ON tx.id = dr.tx_id + WHERE + dr.deposit IS NOT NULL AND dr.deposit >= 0 + ) AS dr_voting_anchor ON dr_voting_anchor.drep_hash_id = dh.id AND dr_voting_anchor.rn = 1 + LEFT JOIN ( SELECT dr.id, dr.drep_hash_id, @@ -82,9 +84,7 @@ FROM FROM drep_registration dr JOIN tx ON tx.id = dr.tx_id - WHERE dr.deposit is not null - AND dr.deposit >= 0) AS dr_non_deregister_voting_anchor ON dr_non_deregister_voting_anchor.drep_hash_id = dh.id - AND dr_non_deregister_voting_anchor.rn = 1 + ) AS dr_non_deregister_voting_anchor ON dr_non_deregister_voting_anchor.drep_hash_id = dh.id AND dr_non_deregister_voting_anchor.rn = 1 LEFT JOIN ( SELECT dr.id, @@ -92,26 +92,34 @@ FROM dr.voting_anchor_id, ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id DESC) AS rn FROM - drep_registration dr) AS second_to_newest_drep_registration ON second_to_newest_drep_registration.drep_hash_id = dh.id - AND second_to_newest_drep_registration.rn = 2 - LEFT JOIN DRepDistr ON DRepDistr.hash_id = dh.id - AND DRepDistr.rn = 1 + drep_registration dr + ) AS second_to_newest_drep_registration ON second_to_newest_drep_registration.drep_hash_id = dh.id AND second_to_newest_drep_registration.rn = 2 + LEFT JOIN DRepDistr ON DRepDistr.hash_id = dh.id AND DRepDistr.rn = 1 LEFT JOIN voting_anchor va ON va.id = dr_voting_anchor.voting_anchor_id LEFT JOIN voting_anchor non_deregister_voting_anchor ON non_deregister_voting_anchor.id = dr_non_deregister_voting_anchor.voting_anchor_id LEFT JOIN ( - SELECT fetch_error as message, voting_anchor_id - FROM off_chain_vote_fetch_error - WHERE fetch_time = ( - SELECT max(fetch_time) - FROM off_chain_vote_fetch_error) - GROUP BY fetch_error, voting_anchor_id + SELECT + fetch_error as message, + voting_anchor_id + FROM + off_chain_vote_fetch_error + WHERE + fetch_time = ( + SELECT + max(fetch_time) + FROM + off_chain_vote_fetch_error + ) + GROUP BY + fetch_error, + voting_anchor_id ) AS fetch_error ON fetch_error.voting_anchor_id = va.id LEFT JOIN off_chain_vote_data ON off_chain_vote_data.voting_anchor_id = va.id - LEFT JOIN off_chain_vote_drep_data on off_chain_vote_drep_data.off_chain_vote_data_id = off_chain_vote_data.id + LEFT JOIN off_chain_vote_drep_data ON off_chain_vote_drep_data.off_chain_vote_data_id = off_chain_vote_data.id CROSS JOIN DRepActivity - LEFT JOIN voting_procedure AS voting_procedure ON voting_procedure.drep_voter = dh.id - LEFT JOIN tx AS tx ON tx.id = voting_procedure.tx_id - LEFT JOIN block AS block ON block.id = tx.block_id + LEFT JOIN voting_procedure ON voting_procedure.drep_voter = dh.id + LEFT JOIN tx ON tx.id = voting_procedure.tx_id + LEFT JOIN block ON block.id = tx.block_id LEFT JOIN ( SELECT block.time, @@ -122,16 +130,16 @@ FROM JOIN tx ON tx.id = dr.tx_id JOIN block ON block.id = tx.block_id WHERE - NOT (dr.deposit < 0)) AS newestRegister ON newestRegister.drep_hash_id = dh.id - AND newestRegister.rn = 1 + NOT (dr.deposit < 0) + ) AS newestRegister ON newestRegister.drep_hash_id = dh.id AND newestRegister.rn = 1 LEFT JOIN ( SELECT dr.tx_id, dr.drep_hash_id, ROW_NUMBER() OVER (PARTITION BY dr.drep_hash_id ORDER BY dr.tx_id ASC) AS rn FROM - drep_registration dr) AS dr_first_register ON dr_first_register.drep_hash_id = dh.id - AND dr_first_register.rn = 1 + drep_registration dr + ) AS dr_first_register ON dr_first_register.drep_hash_id = dh.id AND dr_first_register.rn = 1 LEFT JOIN tx AS tx_first_register ON tx_first_register.id = dr_first_register.tx_id LEFT JOIN block AS block_first_register ON block_first_register.id = tx_first_register.block_id WHERE @@ -142,6 +150,8 @@ WHERE off_chain_vote_drep_data.given_name ILIKE ? ) GROUP BY + block_first_register.epoch_no, + block.epoch_no, dh.raw, second_to_newest_drep_registration.voting_anchor_id, dh.view, @@ -163,4 +173,4 @@ GROUP BY off_chain_vote_drep_data.motivations, off_chain_vote_drep_data.qualifications, off_chain_vote_drep_data.image_url, - off_chain_vote_drep_data.image_hash + off_chain_vote_drep_data.image_hash; From 29f24b963418db6f5a13a73ad3c9de49b9515157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Tue, 24 Dec 2024 16:12:18 +0100 Subject: [PATCH 25/30] fix(#2460): fix calculating live voting power --- CHANGELOG.md | 2 +- govtool/backend/sql/get-voting-power.sql | 27 ++++++++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cebca540..5b074cb93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ changes. ### Fixed -- +- Fix calculating DRep live voting power [Issue 2460](https://github.com/IntersectMBO/govtool/issues/2460) ### Changed diff --git a/govtool/backend/sql/get-voting-power.sql b/govtool/backend/sql/get-voting-power.sql index 14662c65d..2a39edf1d 100644 --- a/govtool/backend/sql/get-voting-power.sql +++ b/govtool/backend/sql/get-voting-power.sql @@ -1,6 +1,21 @@ -select coalesce(sum(uv.value), 0) as amount -from utxo_view uv -join delegation_vote dv on uv.stake_address_id = dv.addr_id -join drep_hash dh on dv.drep_hash_id = dh.id -where dh.raw = decode(?,'hex') -and dv.cert_index != 0 \ No newline at end of file +WITH LatestDelegationVote AS ( + SELECT + addr_id, + MAX(id) AS latest_vote_id + FROM + delegation_vote + GROUP BY + addr_id +) +SELECT + SUM(uv.value) AS total_value +FROM + utxo_view uv +JOIN + stake_address sa ON sa.id = uv.stake_address_id +JOIN + LatestDelegationVote ldv ON uv.stake_address_id = ldv.addr_id +JOIN + delegation_vote dv ON dv.id = ldv.latest_vote_id +WHERE + dv.drep_hash_id = (SELECT id FROM drep_hash WHERE raw = decode(?,'hex')) From b68d808e46b38fa4774c4df49a896e5081bff177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Tue, 24 Dec 2024 16:25:27 +0100 Subject: [PATCH 26/30] fix: increase heap memory limit --- govtool/frontend/Dockerfile | 2 ++ govtool/frontend/Dockerfile.qovery | 2 ++ 2 files changed, 4 insertions(+) diff --git a/govtool/frontend/Dockerfile b/govtool/frontend/Dockerfile index a9b01bad9..7c3eb3740 100644 --- a/govtool/frontend/Dockerfile +++ b/govtool/frontend/Dockerfile @@ -13,6 +13,8 @@ ARG VITE_PDF_API_URL ARG VITE_IPFS_GATEWAY ARG VITE_IPFS_PROJECT_ID +ENV NODE_OPTIONS="--max-old-space-size=4096" + # Ensure all required build arguments are set RUN \ : "${VITE_APP_ENV:?Build argument VITE_APP_ENV is not set}" && \ diff --git a/govtool/frontend/Dockerfile.qovery b/govtool/frontend/Dockerfile.qovery index 092754cf2..0f871462f 100644 --- a/govtool/frontend/Dockerfile.qovery +++ b/govtool/frontend/Dockerfile.qovery @@ -15,6 +15,8 @@ ARG VITE_IPFS_PROJECT_ID WORKDIR /src +ENV NODE_OPTIONS="--max-old-space-size=4096" + # Set npm configuration settings using environment variables RUN npm config set @intersect.mbo:registry "https://registry.npmjs.org/" --location=global RUN npm config set //registry.npmjs.org/:_authToken ${NPMRC_TOKEN} --location=global From 4aaac44b903aeabdc0d1e101b7dc0fe4864a6b77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Fri, 27 Dec 2024 10:43:15 +0100 Subject: [PATCH 27/30] fix(#2403): fix DRep link and description validation --- CHANGELOG.md | 1 + .../src/components/molecules/DRepDataForm.tsx | 30 +++++++++++++++++-- .../EditDRepInfoSteps/EditDRepForm.tsx | 7 ++++- .../RegisterAsDRepForm.tsx | 7 ++++- 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b074cb93..74962dffc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ changes. ### Fixed - Fix calculating DRep live voting power [Issue 2460](https://github.com/IntersectMBO/govtool/issues/2460) +- Fix link and description validation [Issue 2403](https://github.com/IntersectMBO/govtool/issues/2403) ### Changed diff --git a/govtool/frontend/src/components/molecules/DRepDataForm.tsx b/govtool/frontend/src/components/molecules/DRepDataForm.tsx index f1133b001..3ef89fdc1 100644 --- a/govtool/frontend/src/components/molecules/DRepDataForm.tsx +++ b/govtool/frontend/src/components/molecules/DRepDataForm.tsx @@ -3,6 +3,7 @@ import { Control, FieldErrors, UseFormRegister, + UseFormWatch, useFieldArray, } from "react-hook-form"; import { Box } from "@mui/material"; @@ -20,9 +21,10 @@ type Props = { control: Control; errors: FieldErrors; register: UseFormRegister; + watch: UseFormWatch; }; -export const DRepDataForm = ({ control, errors, register }: Props) => { +export const DRepDataForm = ({ control, errors, register, watch }: Props) => { const { t } = useTranslation(); const { isMobile } = useScreenDimension(); @@ -111,12 +113,14 @@ export const DRepDataForm = ({ control, errors, register }: Props) => { control={control} errors={errors} register={register} + watch={watch} />
@@ -176,6 +180,7 @@ type ReferencesSectionProps = { control: Control; errors: FieldErrors; register: UseFormRegister; + watch: UseFormWatch; }; const ReferencesSection = ({ @@ -183,6 +188,7 @@ const ReferencesSection = ({ control, errors, register, + watch, }: ReferencesSectionProps) => { const { fieldName, jsonldType } = (() => { // eslint-disable-next-line default-case @@ -237,7 +243,16 @@ const ReferencesSection = ({ helpfulTextDataTestId={`${type}-reference-description-${ index + 1 }-hint`} - rules={Rules.LINK_DESCRIPTION} + rules={{ + ...Rules.LINK_DESCRIPTION, + validate: (value) => { + const isLink = watch(`${fieldName}.${index}.uri`); + if (!value && Boolean(isLink)) { + return t("dRepData.required"); + } + return true; + }, + }} /> { + const isDescription = watch(`${fieldName}.${index}.label`); + if (!value && Boolean(isDescription)) { + return t("dRepData.required"); + } + return true; + }, + }} /> ))} diff --git a/govtool/frontend/src/components/organisms/EditDRepInfoSteps/EditDRepForm.tsx b/govtool/frontend/src/components/organisms/EditDRepInfoSteps/EditDRepForm.tsx index 562d91acc..5c1974c9f 100644 --- a/govtool/frontend/src/components/organisms/EditDRepInfoSteps/EditDRepForm.tsx +++ b/govtool/frontend/src/components/organisms/EditDRepInfoSteps/EditDRepForm.tsx @@ -67,7 +67,12 @@ export const EditDRepForm = ({ return ( - + - + Date: Fri, 27 Dec 2024 15:24:22 +0100 Subject: [PATCH 28/30] fix: count rewards with drep voting power --- CHANGELOG.md | 2 + .../sql/get-stake-key-voting-power.sql | 52 ++++++++++++++++--- govtool/backend/sql/get-voting-power.sql | 28 +++------- 3 files changed, 55 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 74962dffc..b33789fb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ changes. - Fix calculating DRep live voting power [Issue 2460](https://github.com/IntersectMBO/govtool/issues/2460) - Fix link and description validation [Issue 2403](https://github.com/IntersectMBO/govtool/issues/2403) +- Revert to drep_distr for providing active voting power +- Add rewards amount in the ada holder voting power ### Changed diff --git a/govtool/backend/sql/get-stake-key-voting-power.sql b/govtool/backend/sql/get-stake-key-voting-power.sql index abb0fd1af..a6cdbfe43 100644 --- a/govtool/backend/sql/get-stake-key-voting-power.sql +++ b/govtool/backend/sql/get-stake-key-voting-power.sql @@ -1,6 +1,46 @@ -SELECT COALESCE(SUM(utxo_view.value::numeric), 0), - encode(stake_address.hash_raw, 'hex') -FROM stake_address -JOIN utxo_view ON utxo_view.stake_address_id = stake_address.id -WHERE stake_address.hash_raw = decode(?, 'hex') -GROUP BY stake_address.hash_raw; +WITH RewardRest AS ( + SELECT + SUM(amount) AS amount, + addr_id + FROM + reward_rest + GROUP BY + addr_id +), +Reward AS ( + SELECT + SUM(amount) AS amount, + addr_id + FROM + reward + GROUP BY + addr_id +), +Balance AS ( + SELECT + COALESCE(SUM(uv.value), 0) AS amount, + sa.id AS addr_id, + encode(sa.hash_raw, 'hex') AS addr_raw + FROM + stake_address sa + JOIN utxo_view uv ON uv.stake_address_id = sa.id + GROUP BY + addr_id, + addr_raw +) +SELECT + (COALESCE(rr.amount, 0) + COALESCE(r.amount, 0) + COALESCE(b.amount, 0)) AS total_balance, + b.addr_raw +FROM + Balance b +LEFT JOIN + RewardRest rr ON rr.addr_id = b.addr_id +LEFT JOIN + Reward r ON r.addr_id = rr.addr_id +WHERE + b.addr_id = (SELECT id FROM stake_address WHERE hash_raw = decode(?, 'hex')) +GROUP BY + b.addr_raw, + rr.amount, + r.amount, + b.amount \ No newline at end of file diff --git a/govtool/backend/sql/get-voting-power.sql b/govtool/backend/sql/get-voting-power.sql index 2a39edf1d..a6b225f3e 100644 --- a/govtool/backend/sql/get-voting-power.sql +++ b/govtool/backend/sql/get-voting-power.sql @@ -1,21 +1,7 @@ -WITH LatestDelegationVote AS ( - SELECT - addr_id, - MAX(id) AS latest_vote_id - FROM - delegation_vote - GROUP BY - addr_id -) -SELECT - SUM(uv.value) AS total_value -FROM - utxo_view uv -JOIN - stake_address sa ON sa.id = uv.stake_address_id -JOIN - LatestDelegationVote ldv ON uv.stake_address_id = ldv.addr_id -JOIN - delegation_vote dv ON dv.id = ldv.latest_vote_id -WHERE - dv.drep_hash_id = (SELECT id FROM drep_hash WHERE raw = decode(?,'hex')) +SELECT + amount +FROM + drep_distr +WHERE + hash_id = (SELECT id FROM drep_hash WHERE raw = decode(?,'hex')) +ORDER BY epoch_no DESC LIMIT 1 \ No newline at end of file From af84ddce693f80154d6160bff9c7adc6a4222600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Mon, 30 Dec 2024 14:16:46 +0100 Subject: [PATCH 29/30] fix(#2509): fix nested @value in metadatas --- CHANGELOG.md | 1 + .../src/consts/governanceAction/fields.ts | 1 + govtool/frontend/src/context/featureFlag.tsx | 1 + .../src/context/governanceAction.test.tsx | 2 +- .../frontend/src/context/governanceAction.tsx | 3 +- .../forms/useCreateGovernanceActionForm.ts | 2 - .../src/hooks/forms/useEditDRepInfoForm.ts | 11 +---- .../src/hooks/forms/useRegisterAsdRepForm.tsx | 12 ++--- .../src/hooks/forms/useVoteContextForm.tsx | 5 +- govtool/frontend/src/utils/generateJsonld.ts | 9 ++-- .../src/utils/generateMetadataBody.ts | 19 +++----- .../utils/tests/generateMetadataBody.test.ts | 47 +++++++------------ 12 files changed, 37 insertions(+), 76 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b33789fb7..1e7e72fd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ changes. - Fix link and description validation [Issue 2403](https://github.com/IntersectMBO/govtool/issues/2403) - Revert to drep_distr for providing active voting power - Add rewards amount in the ada holder voting power +- Fix nested @value in jsonld metadatas [Issue 2509](https://github.com/IntersectMBO/govtool/issues/2509) ### Changed diff --git a/govtool/frontend/src/consts/governanceAction/fields.ts b/govtool/frontend/src/consts/governanceAction/fields.ts index 8e84841c5..259a72396 100644 --- a/govtool/frontend/src/consts/governanceAction/fields.ts +++ b/govtool/frontend/src/consts/governanceAction/fields.ts @@ -126,6 +126,7 @@ export const GOVERNANCE_ACTION_FIELDS: GovernanceActionFields = { } as const; export const GOVERNANCE_ACTION_CONTEXT = { + "@language": "en-us", CIP100: "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/README.md#", CIP108: diff --git a/govtool/frontend/src/context/featureFlag.tsx b/govtool/frontend/src/context/featureFlag.tsx index 9f69c595f..23b1a9ecd 100644 --- a/govtool/frontend/src/context/featureFlag.tsx +++ b/govtool/frontend/src/context/featureFlag.tsx @@ -127,6 +127,7 @@ const FeatureFlagProvider = ({ children }: PropsWithChildren) => { () => ({ isProposalDiscussionForumEnabled: import.meta.env.VITE_IS_PROPOSAL_DISCUSSION_FORUM_ENABLED === "true" || + import.meta.env.VITE_IS_PROPOSAL_DISCUSSION_FORUM_ENABLED === true || false, isVotingOnGovernanceActionEnabled, areDRepVoteTotalsDisplayed, diff --git a/govtool/frontend/src/context/governanceAction.test.tsx b/govtool/frontend/src/context/governanceAction.test.tsx index fad2ad813..3eb4e06b4 100644 --- a/govtool/frontend/src/context/governanceAction.test.tsx +++ b/govtool/frontend/src/context/governanceAction.test.tsx @@ -80,7 +80,7 @@ describe("GovernanceActionProvider", () => { const hash = await createHash(jsonld!); expect(hash).toBeDefined(); expect(hash).toBe( - "72b37e2f5e64e7de57b85558ba00885c848f700fbb37fbed3197e603873fa976", + "816b63124f5c5d5bdfc016ad0aea238baf374fecbdadd389eab2dab94bc2383c", ); }; test(); diff --git a/govtool/frontend/src/context/governanceAction.tsx b/govtool/frontend/src/context/governanceAction.tsx index d8f790b9c..c7bd22c18 100644 --- a/govtool/frontend/src/context/governanceAction.tsx +++ b/govtool/frontend/src/context/governanceAction.tsx @@ -10,7 +10,7 @@ import { NodeObject } from "jsonld"; import { blake2bHex } from "blakejs"; import * as Sentry from "@sentry/react"; -import { CIP_108, GOVERNANCE_ACTION_CONTEXT } from "@/consts"; +import { GOVERNANCE_ACTION_CONTEXT } from "@/consts"; import { generateJsonld, generateMetadataBody } from "@/utils"; type GovActionMetadata = { @@ -53,7 +53,6 @@ const GovernanceActionProvider = ({ children }: PropsWithChildren) => { const metadataBody = generateMetadataBody({ data: govActionMetadata, acceptedKeys: ["title", "abstract", "motivation", "rationale"], - standardReference: CIP_108, }); const jsonLD = await generateJsonld( diff --git a/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts b/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts index 0d6e13b39..867857240 100644 --- a/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts +++ b/govtool/frontend/src/hooks/forms/useCreateGovernanceActionForm.ts @@ -7,7 +7,6 @@ import { useTranslation } from "react-i18next"; import { NodeObject } from "jsonld"; import { - CIP_108, GOVERNANCE_ACTION_CONTEXT, PATHS, storageInformationErrorModals, @@ -104,7 +103,6 @@ export const useCreateGovernanceActionForm = ( const body = generateMetadataBody({ data: getValues(), acceptedKeys: ["title", "motivation", "abstract", "rationale"], - standardReference: CIP_108, }); const jsonld = await generateJsonld(body, GOVERNANCE_ACTION_CONTEXT); diff --git a/govtool/frontend/src/hooks/forms/useEditDRepInfoForm.ts b/govtool/frontend/src/hooks/forms/useEditDRepInfoForm.ts index 7dc1b6346..3d52255bf 100644 --- a/govtool/frontend/src/hooks/forms/useEditDRepInfoForm.ts +++ b/govtool/frontend/src/hooks/forms/useEditDRepInfoForm.ts @@ -6,12 +6,7 @@ import { blake2bHex } from "blakejs"; import * as Sentry from "@sentry/react"; import { NodeObject } from "jsonld"; -import { - CIP_119, - DREP_CONTEXT, - PATHS, - storageInformationErrorModals, -} from "@consts"; +import { DREP_CONTEXT, PATHS, storageInformationErrorModals } from "@consts"; import { useCardano, useModal, useAppContext } from "@context"; import { downloadJson, generateJsonld, generateMetadataBody } from "@utils"; import { MetadataValidationStatus } from "@models"; @@ -92,13 +87,11 @@ export const useEditDRepInfoForm = ( "motivations", "qualifications", "paymentAddress", - "references", "doNotList", ], - standardReference: CIP_119, }); - const jsonld = await generateJsonld(body, DREP_CONTEXT, CIP_119); + const jsonld = await generateJsonld(body, DREP_CONTEXT); const jsonHash = blake2bHex(JSON.stringify(jsonld, null, 2), undefined, 32); diff --git a/govtool/frontend/src/hooks/forms/useRegisterAsdRepForm.tsx b/govtool/frontend/src/hooks/forms/useRegisterAsdRepForm.tsx index 4d092afbe..e2de25f10 100644 --- a/govtool/frontend/src/hooks/forms/useRegisterAsdRepForm.tsx +++ b/govtool/frontend/src/hooks/forms/useRegisterAsdRepForm.tsx @@ -7,12 +7,7 @@ import * as Sentry from "@sentry/react"; import { NodeObject } from "jsonld"; import { CertificatesBuilder } from "@emurgo/cardano-serialization-lib-asmjs"; -import { - CIP_119, - DREP_CONTEXT, - PATHS, - storageInformationErrorModals, -} from "@consts"; +import { DREP_CONTEXT, PATHS, storageInformationErrorModals } from "@consts"; import { useCardano, useModal, useAppContext } from "@context"; import { MetadataValidationStatus } from "@models"; import { @@ -108,12 +103,11 @@ export const useRegisterAsdRepForm = ( "motivations", "qualifications", "paymentAddress", - "references", "doNotList", ], - standardReference: CIP_119, }); - const jsonld = await generateJsonld(body, DREP_CONTEXT, CIP_119); + + const jsonld = await generateJsonld(body, DREP_CONTEXT); const jsonHash = blake2bHex(JSON.stringify(jsonld, null, 2), undefined, 32); diff --git a/govtool/frontend/src/hooks/forms/useVoteContextForm.tsx b/govtool/frontend/src/hooks/forms/useVoteContextForm.tsx index 11779489d..1da1587c3 100644 --- a/govtool/frontend/src/hooks/forms/useVoteContextForm.tsx +++ b/govtool/frontend/src/hooks/forms/useVoteContextForm.tsx @@ -6,7 +6,7 @@ import { NodeObject } from "jsonld"; import { downloadJson, generateJsonld, generateMetadataBody } from "@utils"; import { MetadataValidationStatus } from "@models"; -import { CIP_100, CIP_100_CONTEXT } from "@/consts"; +import { CIP_100_CONTEXT } from "@/consts"; import { useValidateMutation } from "../mutations"; @@ -43,9 +43,8 @@ export const useVoteContextForm = ( comment: voteContextText, }, acceptedKeys: ["comment"], - standardReference: CIP_100, }); - const jsonld = await generateJsonld(body, CIP_100_CONTEXT, CIP_100); + const jsonld = await generateJsonld(body, CIP_100_CONTEXT); const jsonHash = blake2bHex(JSON.stringify(jsonld, null, 2), undefined, 32); diff --git a/govtool/frontend/src/utils/generateJsonld.ts b/govtool/frontend/src/utils/generateJsonld.ts index 24ba6187f..b2481c762 100644 --- a/govtool/frontend/src/utils/generateJsonld.ts +++ b/govtool/frontend/src/utils/generateJsonld.ts @@ -1,7 +1,5 @@ import * as jsonld from "jsonld"; -import { CIP_100, CIP_108 } from "@/consts"; - /** * Generates a JSON-LD document by compacting the given body and context. * @@ -17,12 +15,11 @@ export const generateJsonld = async < >( body: T, context: C, - bodyCip: string = CIP_108, ) => { const doc = { - [`${bodyCip}body`]: body, - [`${CIP_100}hashAlgorithm`]: "blake2b-256", - [`${CIP_100}authors`]: [], + "@context": context, + hashAlgorithm: "blake2b-256", + body, }; const json = await jsonld.compact(doc, context); diff --git a/govtool/frontend/src/utils/generateMetadataBody.ts b/govtool/frontend/src/utils/generateMetadataBody.ts index 798b74676..4176ada07 100644 --- a/govtool/frontend/src/utils/generateMetadataBody.ts +++ b/govtool/frontend/src/utils/generateMetadataBody.ts @@ -1,11 +1,6 @@ -import { CIP_100, CIP_108, CIP_119 } from "@/consts"; - -type StandardReference = typeof CIP_100 | typeof CIP_108 | typeof CIP_119; - type MetadataConfig = { data: Record; acceptedKeys: string[]; - standardReference: StandardReference; }; /** @@ -18,11 +13,10 @@ type MetadataConfig = { export const generateMetadataBody = ({ data, acceptedKeys, - standardReference, }: MetadataConfig) => { const filteredData = Object.entries(data) - .filter(([key]) => acceptedKeys.includes(key)) - .map(([key, value]) => [standardReference + key, value]); + .filter(([key, value]) => value && acceptedKeys.includes(key)) + .map(([key, value]) => [key, value]); const references = data?.references ? // uri should not be optional. It is just not yet supported on govtool @@ -30,15 +24,14 @@ export const generateMetadataBody = ({ .filter((link) => link.uri) .map((link) => ({ "@type": link["@type"] ?? "Other", - [`${CIP_100}reference-label`]: link.label || "Label", - [`${CIP_100}reference-uri`]: link.uri, + label: link.label || "Label", + uri: link.uri, })) : undefined; const body = Object.fromEntries(filteredData); - - if (references) { - body[`${standardReference}references`] = references; + if (references?.length) { + body.references = references; } return body; diff --git a/govtool/frontend/src/utils/tests/generateMetadataBody.test.ts b/govtool/frontend/src/utils/tests/generateMetadataBody.test.ts index 21bdd9129..8b1a94cf1 100644 --- a/govtool/frontend/src/utils/tests/generateMetadataBody.test.ts +++ b/govtool/frontend/src/utils/tests/generateMetadataBody.test.ts @@ -1,5 +1,3 @@ -import { CIP_108 } from "@consts"; - import { generateMetadataBody } from "../generateMetadataBody"; describe("generateMetadataBody", () => { @@ -10,18 +8,15 @@ describe("generateMetadataBody", () => { email: "johndoe@example.com", }; const acceptedKeys = ["name", "age"]; - const standardReference = CIP_108; const result = generateMetadataBody({ data, acceptedKeys, - standardReference, }); expect(result).toEqual({ - "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0108/README.md#name": - "John Doe", - "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0108/README.md#age": 30, + name: "John Doe", + age: 30, }); }); @@ -36,47 +31,37 @@ describe("generateMetadataBody", () => { ], }; const acceptedKeys = ["name", "age"]; - const standardReference = CIP_108; const result = generateMetadataBody({ data, acceptedKeys, - standardReference, }); expect(result).toEqual({ - "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0108/README.md#name": - "John Doe", - "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0108/README.md#age": 30, - "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0108/README.md#references": - [ - { - "@type": "Other", - "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/README.md#reference-label": - "Label", - "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/README.md#reference-uri": - "https://example.com/link1", - }, - { - "@type": "Other", - "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/README.md#reference-label": - "Label", - "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/README.md#reference-uri": - "https://example.com/link2", - }, - ], + name: "John Doe", + age: 30, + references: [ + { + "@type": "Other", + label: "Label", + uri: "https://example.com/link1", + }, + { + "@type": "Other", + label: "Label", + uri: "https://example.com/link2", + }, + ], }); }); it("generates metadata body with empty data", () => { const data = {}; const acceptedKeys = ["name", "age"]; - const standardReference = CIP_108; const result = generateMetadataBody({ data, acceptedKeys, - standardReference, }); expect(result).toEqual({}); From a2efecb625de58b2b83f7f04e03e10a61ec2390f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sza=C5=82owski?= Date: Mon, 30 Dec 2024 14:39:16 +0100 Subject: [PATCH 30/30] chore: bump GovTool to v2.0.3 --- CHANGELOG.md | 18 ++++++++++++++++++ govtool/backend/Dockerfile | 2 +- govtool/backend/Dockerfile.qovery | 2 +- govtool/backend/vva-be.cabal | 2 +- govtool/frontend/package-lock.json | 4 ++-- govtool/frontend/package.json | 4 ++-- govtool/metadata-validation/package-lock.json | 4 ++-- govtool/metadata-validation/package.json | 2 +- govtool/metadata-validation/src/main.ts | 2 +- 9 files changed, 29 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e7e72fd2..8394e9532 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,24 @@ changes. ### Fixed +- + +### Changed + +- + +### Removed + +- + +## [v2.0.3](https://github.com/IntersectMBO/govtool/releases/tag/v2.0.3) 2024-12-30 + +### Added + +- + +### Fixed + - Fix calculating DRep live voting power [Issue 2460](https://github.com/IntersectMBO/govtool/issues/2460) - Fix link and description validation [Issue 2403](https://github.com/IntersectMBO/govtool/issues/2403) - Revert to drep_distr for providing active voting power diff --git a/govtool/backend/Dockerfile b/govtool/backend/Dockerfile index a8104ebfd..3ee9f4e82 100644 --- a/govtool/backend/Dockerfile +++ b/govtool/backend/Dockerfile @@ -4,4 +4,4 @@ FROM $BASE_IMAGE_REPO:$BASE_IMAGE_TAG WORKDIR /src COPY . . RUN cabal build -RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-2.0.2/x/vva-be/build/vva-be/vva-be /usr/local/bin +RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-2.0.3/x/vva-be/build/vva-be/vva-be /usr/local/bin diff --git a/govtool/backend/Dockerfile.qovery b/govtool/backend/Dockerfile.qovery index 4afcdc862..0dd9bc89d 100644 --- a/govtool/backend/Dockerfile.qovery +++ b/govtool/backend/Dockerfile.qovery @@ -4,7 +4,7 @@ FROM $BASE_IMAGE_REPO:$BASE_IMAGE_TAG WORKDIR /src COPY . . RUN cabal build -RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-2.0.2/x/vva-be/build/vva-be/vva-be /usr/local/bin +RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.7/vva-be-2.0.3/x/vva-be/build/vva-be/vva-be /usr/local/bin # Expose the necessary port EXPOSE 9876 diff --git a/govtool/backend/vva-be.cabal b/govtool/backend/vva-be.cabal index 1e1d9b802..f5d7bc5c5 100644 --- a/govtool/backend/vva-be.cabal +++ b/govtool/backend/vva-be.cabal @@ -1,6 +1,6 @@ cabal-version: 3.6 name: vva-be -version: 2.0.2 +version: 2.0.3 -- A short (one-line) description of the package. -- synopsis: diff --git a/govtool/frontend/package-lock.json b/govtool/frontend/package-lock.json index 24d068e3d..4eea22d05 100644 --- a/govtool/frontend/package-lock.json +++ b/govtool/frontend/package-lock.json @@ -1,12 +1,12 @@ { "name": "@govtool/frontend", - "version": "2.0.2", + "version": "2.0.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@govtool/frontend", - "version": "2.0.2", + "version": "2.0.3", "hasInstallScript": true, "dependencies": { "@emotion/react": "^11.11.1", diff --git a/govtool/frontend/package.json b/govtool/frontend/package.json index 24171d4e7..734961b1c 100644 --- a/govtool/frontend/package.json +++ b/govtool/frontend/package.json @@ -1,7 +1,7 @@ { "name": "@govtool/frontend", "private": true, - "version": "2.0.2", + "version": "2.0.3", "type": "module", "scripts": { "build": "vite build", @@ -113,5 +113,5 @@ "nth-check": "^2.0.1", "postcss": "^8.4.31" }, - "_id": "govtool@2.0.2" + "_id": "govtool@2.0.3" } diff --git a/govtool/metadata-validation/package-lock.json b/govtool/metadata-validation/package-lock.json index e31f70cbf..657acb1f5 100644 --- a/govtool/metadata-validation/package-lock.json +++ b/govtool/metadata-validation/package-lock.json @@ -1,12 +1,12 @@ { "name": "@govtool/metadata-validation", - "version": "2.0.2", + "version": "2.0.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@govtool/metadata-validation", - "version": "2.0.2", + "version": "2.0.3", "license": "UNLICENSED", "dependencies": { "@nestjs/axios": "^3.0.2", diff --git a/govtool/metadata-validation/package.json b/govtool/metadata-validation/package.json index 58c67fd93..90838c945 100644 --- a/govtool/metadata-validation/package.json +++ b/govtool/metadata-validation/package.json @@ -1,6 +1,6 @@ { "name": "@govtool/metadata-validation", - "version": "2.0.2", + "version": "2.0.3", "description": "", "author": "", "private": true, diff --git a/govtool/metadata-validation/src/main.ts b/govtool/metadata-validation/src/main.ts index e68112e3a..f010743e6 100644 --- a/govtool/metadata-validation/src/main.ts +++ b/govtool/metadata-validation/src/main.ts @@ -13,7 +13,7 @@ async function bootstrap() { const config = new DocumentBuilder() .setTitle('Metadata Validation Tool') .setDescription('The Metadata Validation Tool API description') - .setVersion('2.0.2') + .setVersion('2.0.3') .build(); const document = SwaggerModule.createDocument(app, config);