From ad557ddf6ffc61de162f3f54304accee151285de Mon Sep 17 00:00:00 2001 From: Nabin Kawan Date: Wed, 15 May 2024 16:03:40 +0545 Subject: [PATCH 01/11] fix: Delegation timeout --- .../playwright/lib/helpers/transaction.ts | 13 +- .../playwright/lib/lockInterceptor.ts | 8 -- .../playwright/lib/pages/delegationPage.ts | 6 +- .../lib/pages/governanceActionDetailsPage.ts | 36 ++++- .../playwright/lib/transaction.decorator.ts | 12 ++ .../playwright/package-lock.json | 14 +- .../govtool-frontend/playwright/package.json | 2 +- .../playwright/playwright.config.ts | 2 +- .../delegation.delegation.spec.ts | 8 +- .../proposalVisibility.dRep.spec.ts | 131 ++++++++++++++++++ 10 files changed, 204 insertions(+), 28 deletions(-) create mode 100644 tests/govtool-frontend/playwright/lib/transaction.decorator.ts create mode 100644 tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts diff --git a/tests/govtool-frontend/playwright/lib/helpers/transaction.ts b/tests/govtool-frontend/playwright/lib/helpers/transaction.ts index d85dc2efa..bf496ba8f 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/transaction.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/transaction.ts @@ -51,12 +51,23 @@ export async function pollTransaction( } } -export async function waitForTxConfirmation(page: Page) { +export async function waitForTxConfirmation( + page: Page, + triggerCallback?: () => Promise, +) { let transactionHash: string | undefined; const transactionStatusPromise = page.waitForRequest((request) => { return request.url().includes("/transaction/status/"); }); + await triggerCallback?.call(this); + await expect( + page + .getByTestId("alert-warning") + .getByText("Transaction in progress", { exact: false }), + ).toBeVisible({ + timeout: 10000, + }); const url = (await transactionStatusPromise).url(); const regex = /\/transaction\/status\/([^\/]+)$/; const match = url.match(regex); diff --git a/tests/govtool-frontend/playwright/lib/lockInterceptor.ts b/tests/govtool-frontend/playwright/lib/lockInterceptor.ts index a3b13cda7..a749d26c8 100644 --- a/tests/govtool-frontend/playwright/lib/lockInterceptor.ts +++ b/tests/govtool-frontend/playwright/lib/lockInterceptor.ts @@ -10,14 +10,6 @@ export interface LockInterceptorInfo { address: string; } -abstract class BaseLock { - abstract acquireLock(key: string, id?: string): Promise; - - abstract releaseLock(key: string, id?: string): Promise; - - abstract checkLock(key: string): Promise; -} - export class LockInterceptor { private static async acquireLock( address: string, diff --git a/tests/govtool-frontend/playwright/lib/pages/delegationPage.ts b/tests/govtool-frontend/playwright/lib/pages/delegationPage.ts index dc4d6b1ec..b0a818c40 100644 --- a/tests/govtool-frontend/playwright/lib/pages/delegationPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/delegationPage.ts @@ -1,5 +1,6 @@ -import { Page } from "@playwright/test"; +import { Page, expect } from "@playwright/test"; import environments from "lib/constants/environments"; +import { withTxConfirmation } from "lib/transaction.decorator"; export default class DelegationPage { readonly otherOptionsBtn = this.page.getByText("Other options"); @@ -37,8 +38,11 @@ export default class DelegationPage { ); } + @withTxConfirmation async delegateToDRep(dRepId: string) { await this.searchInput.fill(dRepId); + const delegateBtn = this.page.getByTestId(`${dRepId}-delegate-button`); + await expect(delegateBtn).toBeVisible(); await this.page.getByTestId(`${dRepId}-delegate-button`).click(); } diff --git a/tests/govtool-frontend/playwright/lib/pages/governanceActionDetailsPage.ts b/tests/govtool-frontend/playwright/lib/pages/governanceActionDetailsPage.ts index 89877b9c4..843a242c9 100644 --- a/tests/govtool-frontend/playwright/lib/pages/governanceActionDetailsPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/governanceActionDetailsPage.ts @@ -1,5 +1,8 @@ import environments from "@constants/environments"; -import { Page } from "@playwright/test"; +import { downloadMetadata } from "@helpers/metadata"; +import { Download, Page } from "@playwright/test"; +import metadataBucketService from "@services/metadataBucketService"; +import { withTxConfirmation } from "lib/transaction.decorator"; export default class GovernanceActionDetailsPage { readonly voteBtn = this.page.getByTestId("vote-button"); @@ -8,7 +11,7 @@ export default class GovernanceActionDetailsPage { readonly noVoteRadio = this.page.getByTestId("no-radio"); readonly abstainRadio = this.page.getByTestId("abstain-radio"); readonly governanceActionType = this.page.getByText( - "Governance Action Type:" + "Governance Action Type:", ); readonly submittedDate = this.page.getByTestId("submission-date"); readonly expiryDate = this.page.getByTestId("expiry-date"); @@ -19,7 +22,7 @@ export default class GovernanceActionDetailsPage { name: "Provide context about your", }); // BUG testId readonly viewOtherDetailsLink = this.page.getByTestId( - "view-other-details-button" + "view-other-details-button", ); readonly continueModalBtn = this.page.getByTestId("continue-modal-button"); @@ -37,12 +40,35 @@ export default class GovernanceActionDetailsPage { async goto(proposalId: string) { await this.page.goto( - `${environments.frontendUrl}/governance_actions/${proposalId}` + `${environments.frontendUrl}/governance_actions/${proposalId}`, ); } - async vote() { + @withTxConfirmation + async vote(context?: string) { await this.yesVoteRadio.click(); + + if (context) { + await this.contextBtn.click(); + await this.contextInput.fill(context); + await this.confirmModalBtn.click(); + await this.page.getByRole("checkbox").click(); + await this.confirmModalBtn.click(); + + this.page + .getByRole("button", { name: "download Vote_Context.jsonld" }) + .click(); + const voteMetadata = await this.downloadVoteMetadata(); + const url = await metadataBucketService.uploadMetadata( + voteMetadata.name, + voteMetadata.data, + ); + + await this.page.getByPlaceholder("URL").fill(url); + await this.confirmModalBtn.click(); + await this.page.getByTestId("go-to-vote-modal-button").click(); + } + await this.voteBtn.click(); } diff --git a/tests/govtool-frontend/playwright/lib/transaction.decorator.ts b/tests/govtool-frontend/playwright/lib/transaction.decorator.ts new file mode 100644 index 000000000..26074bb2d --- /dev/null +++ b/tests/govtool-frontend/playwright/lib/transaction.decorator.ts @@ -0,0 +1,12 @@ +import { waitForTxConfirmation } from "@helpers/transaction"; + +export function withTxConfirmation(value, { kind }) { + if (kind !== "method") return; + + return async function (...args: any) { + await waitForTxConfirmation( + this.page, + async () => await value.apply(this, args), + ); + }; +} diff --git a/tests/govtool-frontend/playwright/package-lock.json b/tests/govtool-frontend/playwright/package-lock.json index f229e2e72..6fed6820e 100644 --- a/tests/govtool-frontend/playwright/package-lock.json +++ b/tests/govtool-frontend/playwright/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "@cardanoapi/cardano-test-wallet": "^1.0.2", + "@cardanoapi/cardano-test-wallet": "^1.1.1", "@faker-js/faker": "^8.4.1", "@noble/curves": "^1.3.0", "@noble/ed25519": "^2.0.0", @@ -86,9 +86,9 @@ } }, "node_modules/@cardanoapi/cardano-test-wallet": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@cardanoapi/cardano-test-wallet/-/cardano-test-wallet-1.0.2.tgz", - "integrity": "sha512-ABOOSoB0DUggcIwl6nj1v4/IhzFKPPV6krGLAv9RRmX5trkiOBLqGuSNrOlFU+7XELJzagDDwYS1ykhyuVD/HA==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@cardanoapi/cardano-test-wallet/-/cardano-test-wallet-1.1.1.tgz", + "integrity": "sha512-bNseN0PY0vQ7o7FPKRQW3ZGhUgjQ9bavbbvUiIJ/oTTCwItAq1ds7CGRuVH4hDr8kPSUB76pHQMk8QvEXdMs5A==" }, "node_modules/@cbor-extract/cbor-extract-linux-x64": { "version": "2.2.0", @@ -3206,9 +3206,9 @@ "dev": true }, "@cardanoapi/cardano-test-wallet": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@cardanoapi/cardano-test-wallet/-/cardano-test-wallet-1.0.2.tgz", - "integrity": "sha512-ABOOSoB0DUggcIwl6nj1v4/IhzFKPPV6krGLAv9RRmX5trkiOBLqGuSNrOlFU+7XELJzagDDwYS1ykhyuVD/HA==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@cardanoapi/cardano-test-wallet/-/cardano-test-wallet-1.1.1.tgz", + "integrity": "sha512-bNseN0PY0vQ7o7FPKRQW3ZGhUgjQ9bavbbvUiIJ/oTTCwItAq1ds7CGRuVH4hDr8kPSUB76pHQMk8QvEXdMs5A==" }, "@cbor-extract/cbor-extract-linux-x64": { "version": "2.2.0", diff --git a/tests/govtool-frontend/playwright/package.json b/tests/govtool-frontend/playwright/package.json index 3cb14402e..23e5ab032 100644 --- a/tests/govtool-frontend/playwright/package.json +++ b/tests/govtool-frontend/playwright/package.json @@ -26,7 +26,7 @@ "format": "prettier . --write" }, "dependencies": { - "@cardanoapi/cardano-test-wallet": "^1.0.2", + "@cardanoapi/cardano-test-wallet": "^1.1.1", "@faker-js/faker": "^8.4.1", "@noble/curves": "^1.3.0", "@noble/ed25519": "^2.0.0", diff --git a/tests/govtool-frontend/playwright/playwright.config.ts b/tests/govtool-frontend/playwright/playwright.config.ts index a2adcef75..43a5cc701 100644 --- a/tests/govtool-frontend/playwright/playwright.config.ts +++ b/tests/govtool-frontend/playwright/playwright.config.ts @@ -90,7 +90,7 @@ export default defineConfig({ use: { ...devices["Desktop Chrome"] }, testMatch: "**/*.delegation.spec.ts", dependencies: process.env.CI ? ["auth setup", "dRep setup"] : [], - teardown: "cleanup delegation", + teardown: process.env.CI && "cleanup delegation", }, { name: "independent (desktop)", diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.delegation.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.delegation.spec.ts index 92811984f..82c008d20 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.delegation.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.delegation.spec.ts @@ -27,8 +27,9 @@ test.describe("Delegate to others", () => { const delegationPage = new DelegationPage(page); await delegationPage.goto(); - delegationPage.delegateToDRep(dRep01Wallet.dRepId); - await waitForTxConfirmation(page); + await delegationPage.delegateToDRep( + "drep1qzw234c0ly8csamxf8hrhfahvzwpllh2ckuzzvl38d22wwxxquu", + ); page.goto("/"); await expect(page.getByTestId("delegated-dRep-id")).toHaveText( @@ -81,8 +82,7 @@ test.describe("Change Delegation", () => { }) => { const delegationPage = new DelegationPage(page); await delegationPage.goto(); - delegationPage.delegateToDRep(dRep01Wallet.dRepId); - await waitForTxConfirmation(page); + await delegationPage.delegateToDRep(dRep01Wallet.dRepId); // await delegationPage.goto("/"); // await adaHolderPage.getByTestId("change-dRep-button").click(); 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 new file mode 100644 index 000000000..e9b680c1f --- /dev/null +++ b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts @@ -0,0 +1,131 @@ +import environments from "@constants/environments"; +import { dRep01Wallet } from "@constants/staticWallets"; +import { createTempDRepAuth } from "@datafactory/createAuth"; +import { faker } from "@faker-js/faker"; +import { test } from "@fixtures/walletExtension"; +import { lovelaceToAda } from "@helpers/cardano"; +import convertBufferToHex from "@helpers/convertBufferToHex"; +import { ShelleyWallet } from "@helpers/crypto"; +import { createNewPageWithWallet } from "@helpers/page"; +import { pollTransaction } from "@helpers/transaction"; +import GovernanceActionsPage from "@pages/governanceActionsPage"; +import { Page, expect } from "@playwright/test"; +import kuberService from "@services/kuberService"; +import { FilterOption, IProposal } from "@types"; + +test.describe("Logged in DRep", () => { + test.use({ storageState: ".auth/dRep01.json", wallet: dRep01Wallet }); + + test("4E. Should display DRep's voting power in governance actions page", async ({ + page, + }) => { + const votingPowerPromise = page.waitForResponse("**/get-voting-power/**"); + const governanceActionsPage = new GovernanceActionsPage(page); + await governanceActionsPage.goto(); + + const res = await votingPowerPromise; + const votingPower = await res.json(); + + await expect( + page.getByText(`₳ ${lovelaceToAda(votingPower)}`), + ).toBeVisible(); + }); + + test("4F. Should Disable DRep functionality upon wallet disconnection on governance page", async ({ + page, + }) => { + const governanceActionsPage = new GovernanceActionsPage(page); + await governanceActionsPage.goto(); + + await page.getByTestId("disconnect-button").click(); + + const govActionDetailsPage = + await governanceActionsPage.viewFirstProposal(); + await expect(govActionDetailsPage.voteBtn).not.toBeVisible(); + }); + + test("4G. Should display correct vote counts on governance details page for DRep", async ({ + page, + }) => { + const responsesPromise = Object.keys(FilterOption).map((filterKey) => + page.waitForResponse((response) => + response.url().includes(`&type[]=${FilterOption[filterKey]}`), + ), + ); + + const governanceActionsPage = new GovernanceActionsPage(page); + await governanceActionsPage.goto(); + const responses = await Promise.all(responsesPromise); + const proposals: IProposal[] = ( + await Promise.all( + responses.map(async (response) => { + const data = await response.json(); + return data.elements; + }), + ) + ).flat(); + + expect(proposals.length, "No proposals found!").toBeGreaterThan(0); + + const proposalToCheck = proposals[0]; + const govActionDetailsPage = + await governanceActionsPage.viewProposal(proposalToCheck); + await govActionDetailsPage.showVotesBtn.click(); + + await expect( + page + .getByText("yes₳") + .getByText(`₳ ${lovelaceToAda(proposalToCheck.yesVotes)}`), + ).toBeVisible(); + await expect( + page + .getByText("abstain₳") + .getByText(`₳ ${lovelaceToAda(proposalToCheck.abstainVotes)}`), + ).toBeVisible(); + await expect( + page + .getByText("no₳") + .getByText(`₳ ${lovelaceToAda(proposalToCheck.noVotes)}`), + ).toBeVisible(); + }); +}); + +test.describe("Temporary DReps", async () => { + let dRepPage: Page; + + test.beforeEach(async ({ page, browser }, testInfo) => { + test.setTimeout(testInfo.timeout + 2 * environments.txTimeOut); + + const wallet = await ShelleyWallet.generate(); + const registrationRes = await kuberService.dRepRegistration( + convertBufferToHex(wallet.stakeKey.private), + convertBufferToHex(wallet.stakeKey.pkh), + ); + await pollTransaction(registrationRes.txId, registrationRes.lockInfo); + + const res = await kuberService.transferADA( + [wallet.addressBech32(environments.networkId)], + 40, + ); + await pollTransaction(res.txId, registrationRes.lockInfo); + + const tempDRepAuth = await createTempDRepAuth(page, wallet); + + dRepPage = await createNewPageWithWallet(browser, { + storageState: tempDRepAuth, + wallet, + enableStakeSigning: true, + }); + }); + + test("4J. Should include metadata anchor in the vote transaction", async () => { + const govActionsPage = new GovernanceActionsPage(dRepPage); + await govActionsPage.goto(); + + const govActionDetailsPage = await govActionsPage.viewFirstProposal(); + await govActionDetailsPage.vote(faker.lorem.sentence(200)); + await govActionsPage.votedTab.click(); + await govActionsPage.viewFirstVotedProposal(); + expect(false, "No vote context displayed").toBe(true); + }); +}); From b0944b68c311ea8d7c5a5e3877f70e1715bb8160 Mon Sep 17 00:00:00 2001 From: Nabin Kawan Date: Wed, 15 May 2024 12:03:13 +0545 Subject: [PATCH 02/11] fix: prettier formatting --- .../playwright/lib/datafactory/createAuth.ts | 2 +- .../playwright/lib/fixtures/createWallet.ts | 2 +- .../playwright/lib/fixtures/importWallet.ts | 2 +- .../playwright/lib/fixtures/loadExtension.ts | 4 +- .../playwright/lib/helpers/page.ts | 2 +- .../playwright/lib/helpers/setupWallets.ts | 2 +- .../playwright/lib/helpers/transaction.ts | 8 +-- .../playwright/lib/lockInterceptor.ts | 20 +++--- .../lib/pages/dRepRegistrationPage.ts | 23 +++++-- .../playwright/lib/pages/delegationPage.ts | 12 ++-- .../lib/pages/governanceActionsPage.ts | 34 +++++----- .../playwright/lib/pages/loginPage.ts | 2 +- .../playwright/lib/services/faucetService.ts | 4 +- .../playwright/lib/services/kuberService.ts | 30 ++++----- .../1-wallet-connect/walletConnect.spec.ts | 2 +- .../delegation.delegation.spec.ts | 6 +- .../2-delegation/delegation.loggedin.spec.ts | 2 +- .../dRepRegistration.dRep.spec.ts | 50 ++++++++++++--- .../proposalVisibility.loggedin.spec.ts | 8 +-- .../proposalFunctionality.dRep.spec.ts | 62 ++++++++++++++++--- .../6-miscellaneous/miscellaneous.spec.ts | 2 +- .../playwright/tests/dRep.setup.ts | 2 +- .../playwright/tests/delegation.teardown.ts | 2 +- .../playwright/tests/wallet.bootstrap.ts | 4 +- 24 files changed, 191 insertions(+), 96 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/datafactory/createAuth.ts b/tests/govtool-frontend/playwright/lib/datafactory/createAuth.ts index 2525ed5dc..05da4e0e5 100644 --- a/tests/govtool-frontend/playwright/lib/datafactory/createAuth.ts +++ b/tests/govtool-frontend/playwright/lib/datafactory/createAuth.ts @@ -22,7 +22,7 @@ export async function createTempDRepAuth(page: Page, wallet: ShelleyWallet) { export async function createTempAdaHolderAuth( page: Page, - wallet: ShelleyWallet + wallet: ShelleyWallet, ) { await importWallet(page, wallet.json()); diff --git a/tests/govtool-frontend/playwright/lib/fixtures/createWallet.ts b/tests/govtool-frontend/playwright/lib/fixtures/createWallet.ts index 0ab7f1c04..3d6973292 100644 --- a/tests/govtool-frontend/playwright/lib/fixtures/createWallet.ts +++ b/tests/govtool-frontend/playwright/lib/fixtures/createWallet.ts @@ -7,7 +7,7 @@ import { Page } from "@playwright/test"; export default async function createWallet( page: Page, - config?: CardanoTestWalletConfig + config?: CardanoTestWalletConfig, ) { const wallet = (await ShelleyWallet.generate()).json(); diff --git a/tests/govtool-frontend/playwright/lib/fixtures/importWallet.ts b/tests/govtool-frontend/playwright/lib/fixtures/importWallet.ts index d825f8cf9..d04a58a71 100644 --- a/tests/govtool-frontend/playwright/lib/fixtures/importWallet.ts +++ b/tests/govtool-frontend/playwright/lib/fixtures/importWallet.ts @@ -4,7 +4,7 @@ import { StaticWallet } from "@types"; export async function importWallet( page: Page, - wallet: StaticWallet | CardanoTestWallet + wallet: StaticWallet | CardanoTestWallet, ) { await page.addInitScript((wallet) => { // @ts-ignore diff --git a/tests/govtool-frontend/playwright/lib/fixtures/loadExtension.ts b/tests/govtool-frontend/playwright/lib/fixtures/loadExtension.ts index 44cea5367..5634fa3a3 100644 --- a/tests/govtool-frontend/playwright/lib/fixtures/loadExtension.ts +++ b/tests/govtool-frontend/playwright/lib/fixtures/loadExtension.ts @@ -6,11 +6,11 @@ import path = require("path"); export default async function loadDemosExtension( page: Page, - enableStakeSigning = false + enableStakeSigning = false, ) { const demosBundleScriptPath = path.resolve( __dirname, - "../../node_modules/@cardanoapi/cardano-test-wallet/script.js" + "../../node_modules/@cardanoapi/cardano-test-wallet/script.js", ); let walletConfig: CardanoTestWalletConfig = { enableStakeSigning, diff --git a/tests/govtool-frontend/playwright/lib/helpers/page.ts b/tests/govtool-frontend/playwright/lib/helpers/page.ts index 7a20d6d80..8ab66186e 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/page.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/page.ts @@ -11,7 +11,7 @@ interface BrowserConfig { export async function createNewPageWithWallet( browser: Browser, - { storageState, wallet, enableStakeSigning }: BrowserConfig + { storageState, wallet, enableStakeSigning }: BrowserConfig, ): Promise { const context = await browser.newContext({ storageState: storageState, diff --git a/tests/govtool-frontend/playwright/lib/helpers/setupWallets.ts b/tests/govtool-frontend/playwright/lib/helpers/setupWallets.ts index b12684b3b..ad64c4c85 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/setupWallets.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/setupWallets.ts @@ -15,7 +15,7 @@ export default async function setupWallets(wallets: ShelleyWallet[]) { const { txId, address } = await kuberService.initializeWallets( faucetWallet.address, signingKey, - wallets + wallets, ); await pollTransaction(txId, address); diff --git a/tests/govtool-frontend/playwright/lib/helpers/transaction.ts b/tests/govtool-frontend/playwright/lib/helpers/transaction.ts index bf496ba8f..5d455dd6f 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/transaction.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/transaction.ts @@ -10,7 +10,7 @@ import { Logger } from "../../../cypress/lib/logger/logger"; */ export async function pollTransaction( txHash: string, - lockInfo?: LockInterceptorInfo + lockInfo?: LockInterceptorInfo, ) { try { Logger.info(`Waiting for tx completion: ${txHash}`); @@ -23,7 +23,7 @@ export async function pollTransaction( }, { timeout: environments.txTimeOut, - } + }, ) .toBeGreaterThan(0); @@ -34,7 +34,7 @@ export async function pollTransaction( await LockInterceptor.releaseLockForAddress( lockInfo.address, lockInfo.lockId, - `Task completed for:${lockInfo.lockId}` + `Task completed for:${lockInfo.lockId}`, ); } catch (err) { if (lockInfo) { @@ -43,7 +43,7 @@ export async function pollTransaction( await LockInterceptor.releaseLockForAddress( lockInfo.address, lockInfo.lockId, - `Task failure: \n${JSON.stringify(errorMessage)}` + `Task failure: \n${JSON.stringify(errorMessage)}`, ); } diff --git a/tests/govtool-frontend/playwright/lib/lockInterceptor.ts b/tests/govtool-frontend/playwright/lib/lockInterceptor.ts index a749d26c8..6e56e237f 100644 --- a/tests/govtool-frontend/playwright/lib/lockInterceptor.ts +++ b/tests/govtool-frontend/playwright/lib/lockInterceptor.ts @@ -13,13 +13,13 @@ export interface LockInterceptorInfo { export class LockInterceptor { private static async acquireLock( address: string, - lockId: string + lockId: string, ): Promise { const lockFilePath = path.resolve(__dirname, `../.lock-pool/${address}`); try { await log( - `Initiator: ${address} \n---------------------> acquiring lock for:${lockId}` + `Initiator: ${address} \n---------------------> acquiring lock for:${lockId}`, ); await new Promise((resolve, reject) => { lockfile.lock(lockFilePath, (err) => { @@ -31,7 +31,7 @@ export class LockInterceptor { }); }); await log( - `Initiator: ${address} \n---------------------> acquired lock for:${lockId}` + `Initiator: ${address} \n---------------------> acquired lock for:${lockId}`, ); } catch (err) { throw err; @@ -40,13 +40,13 @@ export class LockInterceptor { private static async releaseLock( address: string, - lockId: string + lockId: string, ): Promise { const lockFilePath = path.resolve(__dirname, `../.lock-pool/${address}`); try { await log( - `Initiator: ${address} \n---------------------> releasing lock for:${lockId}` + `Initiator: ${address} \n---------------------> releasing lock for:${lockId}`, ); await new Promise((resolve, reject) => { lockfile.unlock(lockFilePath, async (err) => { @@ -58,7 +58,7 @@ export class LockInterceptor { }); }); await log( - `Initiator: ${address} \n---------------------> released lock for:${lockId}\n` + `Initiator: ${address} \n---------------------> released lock for:${lockId}\n`, ); } catch (err) { throw err; @@ -67,13 +67,13 @@ export class LockInterceptor { private static async waitForReleaseLock( address: string, - lockId: string + lockId: string, ): Promise { const pollInterval = 4000; // 4 secs try { await log( - `Initiator: ${address} \n ---------------------> waiting lock for:${lockId}` + `Initiator: ${address} \n ---------------------> waiting lock for:${lockId}`, ); return new Promise((resolve, reject) => { const pollFn = () => { @@ -100,7 +100,7 @@ export class LockInterceptor { address: string, callbackFn: () => Promise, lockId: string, - provider: "local" | "server" = "local" + provider: "local" | "server" = "local", ): Promise { while (true) { const isAddressLocked = checkAddressLock(address); @@ -134,7 +134,7 @@ export class LockInterceptor { static async releaseLockForAddress( address: string, lockId: string, - message?: string + message?: string, ) { try { message && (await log(message)); diff --git a/tests/govtool-frontend/playwright/lib/pages/dRepRegistrationPage.ts b/tests/govtool-frontend/playwright/lib/pages/dRepRegistrationPage.ts index 4925124d7..766c95534 100644 --- a/tests/govtool-frontend/playwright/lib/pages/dRepRegistrationPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/dRepRegistrationPage.ts @@ -1,4 +1,6 @@ -import { Page } from "@playwright/test"; +import { downloadMetadata } from "@helpers/metadata"; +import { Download, Page } from "@playwright/test"; +import metadataBucketService from "@services/metadataBucketService"; import { IDRepInfo } from "@types"; import environments from "lib/constants/environments"; @@ -7,7 +9,7 @@ export default class DRepRegistrationPage { readonly skipBtn = this.page.getByTestId("skip-button"); readonly confirmBtn = this.page.getByTestId("confirm-modal-button"); readonly registrationSuccessModal = this.page.getByTestId( - "governance-action-submitted-modal" + "governance-action-submitted-modal", ); readonly continueBtn = this.page.getByTestId("retire-button"); // BUG testId -> continue-button readonly addLinkBtn = this.page.getByRole("button", { name: "+ Add link" }); // BUG: testId -> add-link-button @@ -40,13 +42,24 @@ export default class DRepRegistrationPage { } } + this.page + .getByRole("button", { name: "download Vote_Context.jsonld" }) + .click(); + const dRepMetadata = await this.downloadVoteMetadata(); + const url = await metadataBucketService.uploadMetadata( + dRepMetadata.name, + dRepMetadata.data, + ); await this.continueBtn.click(); // BUG: testId -> submit-button await this.page.getByRole("checkbox").click(); await this.continueBtn.click(); // BUG: testId -> submit-button - await this.page - .getByPlaceholder("URL") - .fill(`${environments.metadataBucketUrl}/Test_dRep`); + await this.page.getByPlaceholder("URL").fill(url); await this.continueBtn.click(); } + + async downloadVoteMetadata() { + const download: Download = await this.page.waitForEvent("download"); + return downloadMetadata(download); + } } diff --git a/tests/govtool-frontend/playwright/lib/pages/delegationPage.ts b/tests/govtool-frontend/playwright/lib/pages/delegationPage.ts index b0a818c40..50a0f8f1e 100644 --- a/tests/govtool-frontend/playwright/lib/pages/delegationPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/delegationPage.ts @@ -19,22 +19,22 @@ export default class DelegationPage { .filter({ hasText: "Signal No Confidence on Every" }) .nth(2); // BUG: testId -> signal-no-confidence-card readonly abstainDelegationCard = this.page.getByText( - "Abstain from Every VoteSelect this to vote ABSTAIN to every vote.Voting Power₳" - );// BUG: testId -> abstain-delegation-card + "Abstain from Every VoteSelect this to vote ABSTAIN to every vote.Voting Power₳", + ); // BUG: testId -> abstain-delegation-card readonly delegationErrorModal = this.page.getByTestId( - "delegation-transaction-error-modal" + "delegation-transaction-error-modal", ); readonly delegateBtns = this.page.locator( - '[data-testid$="-delegate-button"]' - ); + '[data-testid$="-delegate-button"]', + ); constructor(private readonly page: Page) {} async goto() { await this.page.goto( - `${environments.frontendUrl}/connected/dRep_directory` + `${environments.frontendUrl}/connected/dRep_directory`, ); } diff --git a/tests/govtool-frontend/playwright/lib/pages/governanceActionsPage.ts b/tests/govtool-frontend/playwright/lib/pages/governanceActionsPage.ts index a74a9c8d1..03cde5992 100644 --- a/tests/govtool-frontend/playwright/lib/pages/governanceActionsPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/governanceActionsPage.ts @@ -26,7 +26,7 @@ export default class GovernanceActionsPage { } async viewProposal( - proposal: IProposal + proposal: IProposal, ): Promise { const proposalId = `govaction-${proposal.txHash}#${proposal.index}-view-detail`; await this.page.getByTestId(proposalId).click(); @@ -51,7 +51,7 @@ export default class GovernanceActionsPage { } async viewVotedProposal( - proposal: IProposal + proposal: IProposal, ): Promise { const proposalId = `govaction-${proposal.txHash}#${proposal.index}-change-your-vote`; await this.page.getByTestId(proposalId).click(); @@ -73,19 +73,21 @@ export default class GovernanceActionsPage { } } + async getAllProposals() { + return this.page.locator('[data-test-id$="-card"]').all(); + } + async validateFilters(filters: string[]) { - const proposalCards = await this.page - .locator('[data-test-id$="-card"]') - .all(); + const proposalCards = await this.getAllProposals(); for (const proposalCard of proposalCards) { const hasFilter = await this._validateFiltersInProposalCard( proposalCard, - filters + filters, ); expect( hasFilter, - "A proposal card does not contain any of the filters" + "A proposal card does not contain any of the filters", ).toBe(true); } } @@ -97,21 +99,21 @@ export default class GovernanceActionsPage { async validateSort( sortOption: string, validationFn: (p1: IProposal, p2: IProposal) => boolean, - filterKeys = Object.keys(FilterOption) + filterKeys = Object.keys(FilterOption), ) { const responses = await Promise.all( filterKeys.map((filterKey) => this.page.waitForResponse((response) => response .url() - .includes(`&type[]=${FilterOption[filterKey]}&sort=${sortOption}`) - ) - ) + .includes(`&type[]=${FilterOption[filterKey]}&sort=${sortOption}`), + ), + ), ); const proposalData = await Promise.all( responses.map(async (response) => { return await response.json(); - }) + }), ); expect(proposalData.length, "No proposals to sort").toBeGreaterThan(0); @@ -129,8 +131,8 @@ export default class GovernanceActionsPage { // Frontend validation const proposalCards = await Promise.all( filterKeys.map((key) => - this.page.getByTestId(`govaction-${key}-card`).allInnerTexts() - ) + this.page.getByTestId(`govaction-${key}-card`).allInnerTexts(), + ), ); for (let dIdx = 0; dIdx <= proposalData.length - 1; dIdx++) { @@ -138,7 +140,7 @@ export default class GovernanceActionsPage { for (let i = 0; i <= proposals.length - 1; i++) { expect( proposalCards[dIdx][i].includes(proposals[i].txHash), - "Frontend validation failed" + "Frontend validation failed", ).toBe(true); } } @@ -146,7 +148,7 @@ export default class GovernanceActionsPage { async _validateFiltersInProposalCard( proposalCard: Locator, - filters: string[] + filters: string[], ): Promise { for (const filter of filters) { try { diff --git a/tests/govtool-frontend/playwright/lib/pages/loginPage.ts b/tests/govtool-frontend/playwright/lib/pages/loginPage.ts index 964b14ff8..1eaabc96f 100644 --- a/tests/govtool-frontend/playwright/lib/pages/loginPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/loginPage.ts @@ -47,7 +47,7 @@ export default class LoginPage { } return { stakeKeys, rewardAddresses }; - } + }, ); // Handle multiple stake keys diff --git a/tests/govtool-frontend/playwright/lib/services/faucetService.ts b/tests/govtool-frontend/playwright/lib/services/faucetService.ts index a2f9971e3..446ab78eb 100644 --- a/tests/govtool-frontend/playwright/lib/services/faucetService.ts +++ b/tests/govtool-frontend/playwright/lib/services/faucetService.ts @@ -10,11 +10,11 @@ interface IFaucetResponse { } export const loadAmountFromFaucet = async ( - walletAddress: string + walletAddress: string, ): Promise => { try { const res = await fetchClient( - `/send-money?type=default&action=funds&address=${walletAddress}&poolid=undefined&api_key=${environments.faucet.apiKey}` + `/send-money?type=default&action=funds&address=${walletAddress}&poolid=undefined&api_key=${environments.faucet.apiKey}`, ); const responseBody = await res.json(); // console.debug(`faucet response: ${JSON.stringify(responseBody)}`); diff --git a/tests/govtool-frontend/playwright/lib/services/kuberService.ts b/tests/govtool-frontend/playwright/lib/services/kuberService.ts index 65190100e..a1cdaea6d 100644 --- a/tests/govtool-frontend/playwright/lib/services/kuberService.ts +++ b/tests/govtool-frontend/playwright/lib/services/kuberService.ts @@ -77,7 +77,7 @@ class Kuber { const signedTx = this.signTx(tx); const signedTxBody = Uint8Array.from(cborxEncoder.encode(tx)); const lockId = Buffer.from( - blake.blake2b(signedTxBody, undefined, 32) + blake.blake2b(signedTxBody, undefined, 32), ).toString("hex"); const submitTxCallback = async () => { return this.submitTx(signedTx, lockId); @@ -87,18 +87,18 @@ class Kuber { async submitTx(signedTx: any, lockId?: string) { Logger.info( - `Submitting tx: ${JSON.stringify({ lock_id: lockId, tx: signedTx })}` + `Submitting tx: ${JSON.stringify({ lock_id: lockId, tx: signedTx })}`, ); const res = (await callKuber( `/api/${this.version}/tx?submit=true`, "POST", - JSON.stringify(signedTx) + JSON.stringify(signedTx), )) as any; let decodedTx = cborxDecoder.decode(Buffer.from(res.cborHex, "hex")); const submittedTxBody = Uint8Array.from(cborxEncoder.encode(decodedTx[0])); const submittedTxHash = Buffer.from( - blake.blake2b(submittedTxBody, undefined, 32) + blake.blake2b(submittedTxBody, undefined, 32), ).toString("hex"); Logger.success(`Tx submitted: ${submittedTxHash}`); @@ -113,7 +113,7 @@ const kuberService = { initializeWallets: ( senderAddress: string, signingKey: string, - wallets: ShelleyWallet[] + wallets: ShelleyWallet[], ) => { const kuber = new Kuber(senderAddress, signingKey); const outputs = []; @@ -134,8 +134,8 @@ const kuberService = { certificates.push( Kuber.generateCert( "registerstake", - convertBufferToHex(wallet.stakeKey.pkh) - ) + convertBufferToHex(wallet.stakeKey.pkh), + ), ); } return kuber.signAndSubmitTx({ @@ -195,7 +195,7 @@ const kuberService = { addr: string, signingKey: string, stakePrivateKey: string, - pkh: string + pkh: string, ) => { const kuber = new Kuber(addr, signingKey); const selections = [ @@ -218,7 +218,7 @@ const kuberService = { signingKey: string, stakePrivateKey: string, pkh: string, - dRep: string | "abstain" | "noconfidence" + dRep: string | "abstain" | "noconfidence", ) => { const kuber = new Kuber(addr, signingKey); const selections = [ @@ -245,7 +245,7 @@ const kuberService = { const utxos: any[] = await callKuber(`/api/v3/utxo?address=${addr}`); const balanceInLovelace = utxos.reduce( (acc, utxo) => acc + utxo.value.lovelace, - 0 + 0, ); return balanceInLovelace / 1000000; }, @@ -254,7 +254,7 @@ const kuberService = { stakePrivateKey: string, pkh: string, signingKey: string, - addr: string + addr: string, ) => { const kuber = new Kuber(addr, signingKey); const selections = [ @@ -315,7 +315,7 @@ const kuberService = { signingKey: string, voter: string, // dRepHash dRepStakePrivKey: string, - proposal: string + proposal: string, ) { const kuber = new Kuber(addr, signingKey); const req = { @@ -343,7 +343,7 @@ const kuberService = { abstainDelegations( stakePrivKeys: string[], - stakePkhs: string[] + stakePkhs: string[], ): Promise { const kuber = new Kuber(faucetWallet.address, faucetWallet.payment.private); const selections = stakePrivKeys.map((key) => { @@ -372,7 +372,7 @@ async function callKuber( path: any, method: "GET" | "POST" = "GET", body?: BodyInit, - contentType = "application/json" + contentType = "application/json", ) { const url = config.apiUrl + path; @@ -405,7 +405,7 @@ async function callKuber( err = Error( `KuberApi [Status ${res.status}] : ${ json.message ? json.message : txt - }` + }`, ); } else { err = Error(`KuberApi [Status ${res.status}] : ${txt}`); 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 ea33fdcb4..500786d0a 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 @@ -11,7 +11,7 @@ test("1A. Should connect wallet and choose stake-key to use @smoke @fast", async const shellyWallet = await ShelleyWallet.generate(); const extraPubStakeKey = convertBufferToHex(shellyWallet.stakeKey.public); const extraRewardAddress = convertBufferToHex( - shellyWallet.rewardAddressRawBytes(0) + shellyWallet.rewardAddressRawBytes(0), ); await createWallet(page, { diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.delegation.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.delegation.spec.ts index 82c008d20..88749ea26 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.delegation.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.delegation.spec.ts @@ -33,7 +33,7 @@ test.describe("Delegate to others", () => { page.goto("/"); await expect(page.getByTestId("delegated-dRep-id")).toHaveText( - dRep01Wallet.dRepId + dRep01Wallet.dRepId, ); }); }); @@ -48,7 +48,7 @@ test.describe("Delegate to myself", () => { const wallet = await ShelleyWallet.generate(); const txRes = await kuberService.transferADA( [wallet.addressBech32(environments.networkId)], - 600 + 600, ); await pollTransaction(txRes.txId, txRes.lockInfo); const dRepAuth = await createTempDRepAuth(page, wallet); @@ -61,7 +61,7 @@ test.describe("Delegate to myself", () => { await dRepPage.getByTestId("register-as-sole-voter-button").click(); await dRepPage.getByTestId("retire-button").click(); // BUG: Incorrect test-id , it should be continue-retirement await expect( - dRepPage.getByTestId("registration-transaction-submitted-modal") + dRepPage.getByTestId("registration-transaction-submitted-modal"), ).toBeVisible(); dRepPage.getByTestId("confirm-modal-button").click(); await waitForTxConfirmation(dRepPage); 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 969607c1f..6beb4a2ed 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 @@ -12,7 +12,7 @@ test("2B. Should access delegation to dRep page @smoke @fast", async ({ await page.getByTestId("delegate-button").click(); // BUG incorrect test ID await expect( - page.getByRole("navigation").getByText("DRep Directory") + page.getByRole("navigation").getByText("DRep Directory"), ).toBeVisible(); }); 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 2e633866d..d31e2a91a 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 @@ -1,6 +1,7 @@ import environments from "@constants/environments"; import { dRep01Wallet } from "@constants/staticWallets"; import { createTempDRepAuth } from "@datafactory/createAuth"; +import { faker } from "@faker-js/faker"; import { test } from "@fixtures/walletExtension"; import convertBufferToHex from "@helpers/convertBufferToHex"; import { ShelleyWallet } from "@helpers/crypto"; @@ -20,7 +21,7 @@ test.describe("Logged in DReps", () => { }) => { await page.goto("/"); await expect(page.getByTestId("dRep-id-display")).toContainText( - dRep01Wallet.dRepId + dRep01Wallet.dRepId, ); // BUG: testId -> dRep-id-display-dashboard (It is taking sidebar dRep-id) }); @@ -45,7 +46,7 @@ test.describe("Temporary DReps", () => { const wallet = await ShelleyWallet.generate(); const res = await kuberService.transferADA( [wallet.addressBech32(environments.networkId)], - 600 + 600, ); await pollTransaction(res.txId, res.lockInfo); @@ -58,11 +59,11 @@ test.describe("Temporary DReps", () => { const dRepRegistrationPage = new DRepRegistrationPage(dRepPage); await dRepRegistrationPage.goto(); - await dRepRegistrationPage.register({ name: "Test_dRep" }); + await dRepRegistrationPage.register({ name: faker.person.firstName() }); await expect(dRepRegistrationPage.registrationSuccessModal).toBeVisible(); await expect( - dRepRegistrationPage.registrationSuccessModal.getByText("this link") + dRepRegistrationPage.registrationSuccessModal.getByText("this link"), ).toBeVisible(); }); @@ -75,7 +76,7 @@ test.describe("Temporary DReps", () => { const wallet = await ShelleyWallet.generate(); const registrationRes = await kuberService.dRepRegistration( convertBufferToHex(wallet.stakeKey.private), - convertBufferToHex(wallet.stakeKey.pkh) + convertBufferToHex(wallet.stakeKey.pkh), ); await pollTransaction(registrationRes.txId, registrationRes.lockInfo); @@ -91,7 +92,7 @@ test.describe("Temporary DReps", () => { await dRepPage.getByTestId("retire-button").click(); // BUG testId -> continue-retire-button await expect( - dRepPage.getByTestId("retirement-transaction-error-modal") + dRepPage.getByTestId("retirement-transaction-error-modal"), ).toBeVisible(); }); @@ -104,7 +105,7 @@ test.describe("Temporary DReps", () => { const wallet = await ShelleyWallet.generate(); const registrationRes = await kuberService.dRepRegistration( convertBufferToHex(wallet.stakeKey.private), - convertBufferToHex(wallet.stakeKey.pkh) + convertBufferToHex(wallet.stakeKey.pkh), ); await pollTransaction(registrationRes.txId, registrationRes.lockInfo); @@ -124,7 +125,7 @@ test.describe("Temporary DReps", () => { await dRepPage.getByTestId("retire-button").click(); await dRepPage.getByTestId("retire-button").click(); // BUG: testId -> continue-retire-button await expect( - dRepPage.getByTestId("retirement-transaction-submitted-modal") + dRepPage.getByTestId("retirement-transaction-submitted-modal"), ).toBeVisible(); dRepPage.getByTestId("confirm-modal-button").click(); await waitForTxConfirmation(dRepPage); @@ -135,4 +136,37 @@ test.describe("Temporary DReps", () => { await governanceActionsPage.viewFirstProposal(); await expect(govActionDetailsPage.voteBtn).not.toBeVisible(); }); + + test("3K. Should display 'In Progress' status on dashboard until blockchain confirms DRep registration", async ({ + page, + browser, + }, testInfo) => { + test.setTimeout(testInfo.timeout + environments.txTimeOut); + + const wallet = await ShelleyWallet.generate(); + + const res = await kuberService.transferADA( + [wallet.addressBech32(environments.networkId)], + 600, + ); + await pollTransaction(res.txId, res.lockInfo); + + const dRepAuth = await createTempDRepAuth(page, wallet); + const dRepPage = await createNewPageWithWallet(browser, { + storageState: dRepAuth, + wallet, + enableStakeSigning: true, + }); + + const dRepRegistrationPage = new DRepRegistrationPage(dRepPage); + await dRepRegistrationPage.goto(); + await dRepRegistrationPage.register({ name: faker.person.firstName() }); + dRepRegistrationPage.registrationSuccessModal + .getByTestId("confirm-modal-button") + .click(); + + await expect( + dRepPage.locator("span").filter({ hasText: "In Progress" }), + ).toBeVisible(); // BUG add proper testId for dRep registration card + }); }); 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 d55c62514..3efed401f 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 @@ -85,19 +85,19 @@ test("4C.2: Should sort Governance Action Type on governance actions page @slow" govActionsPage.sortProposal(SortOption.SoonToExpire); await govActionsPage.validateSort( SortOption.SoonToExpire, - (p1, p2) => p1.expiryDate <= p2.expiryDate + (p1, p2) => p1.expiryDate <= p2.expiryDate, ); govActionsPage.sortProposal(SortOption.NewestFirst); await govActionsPage.validateSort( SortOption.NewestFirst, - (p1, p2) => p1.createdDate >= p2.createdDate + (p1, p2) => p1.createdDate >= p2.createdDate, ); govActionsPage.sortProposal(SortOption.HighestYesVotes); await govActionsPage.validateSort( SortOption.HighestYesVotes, - (p1, p2) => p1.yesVotes >= p2.yesVotes + (p1, p2) => p1.yesVotes >= p2.yesVotes, ); }); @@ -118,7 +118,7 @@ test("4D: Should filter and sort Governance Action Type on governance actions pa await govActionsPage.validateSort( SortOption.SoonToExpire, (p1, p2) => p1.expiryDate <= p2.expiryDate, - [removeAllSpaces(filterOptionNames[0])] + [removeAllSpaces(filterOptionNames[0])], ); await govActionsPage.validateFilters([filterOptionNames[0]]); }); 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 dd13ab19b..055f53925 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 @@ -86,7 +86,9 @@ test.describe("Proposal checks", () => { await expect(govActionDetailsPage.externalLinkModal).toBeVisible(); await expect( - govActionDetailsPage.currentPage.getByText("Be careful", { exact: false }) + govActionDetailsPage.currentPage.getByText("Be careful", { + exact: false, + }), ).toBeVisible(); }); @@ -110,13 +112,13 @@ test.describe("Perform voting", () => { const wallet = await ShelleyWallet.generate(); const registrationRes = await kuberService.dRepRegistration( convertBufferToHex(wallet.stakeKey.private), - convertBufferToHex(wallet.stakeKey.pkh) + convertBufferToHex(wallet.stakeKey.pkh), ); await pollTransaction(registrationRes.txId, registrationRes.lockInfo); const res = await kuberService.transferADA( [wallet.addressBech32(environments.networkId)], - 40 + 40, ); await pollTransaction(res.txId, registrationRes.lockInfo); @@ -141,12 +143,12 @@ test.describe("Perform voting", () => { await waitForTxConfirmation(govActionDetailsPage.currentPage); const governanceActionsPage = new GovernanceActionsPage( - govActionDetailsPage.currentPage + govActionDetailsPage.currentPage, ); await governanceActionsPage.goto(); await governanceActionsPage.votedTab.click(); await expect( - govActionDetailsPage.currentPage.getByTestId("my-vote").getByText("Yes") + govActionDetailsPage.currentPage.getByTestId("my-vote").getByText("Yes"), ).toBeVisible(); govActionDetailsPage = await governanceActionsPage.viewFirstVotedProposal(); @@ -155,7 +157,7 @@ test.describe("Perform voting", () => { await governanceActionsPage.votedTab.click(); await expect( - govActionDetailsPage.currentPage.getByTestId("my-vote").getByText("No") + govActionDetailsPage.currentPage.getByTestId("my-vote").getByText("No"), ).toBeVisible(); }); @@ -171,12 +173,56 @@ test.describe("Perform voting", () => { await waitForTxConfirmation(govActionDetailsPage.currentPage); const governanceActionsPage = new GovernanceActionsPage( - govActionDetailsPage.currentPage + govActionDetailsPage.currentPage, ); await governanceActionsPage.goto(); await governanceActionsPage.votedTab.click(); await expect( - govActionDetailsPage.currentPage.getByTestId("my-vote").getByText("Yes") + govActionDetailsPage.currentPage.getByTestId("my-vote").getByText("Yes"), ).toBeVisible(); }); }); + +test.describe("Check voting power", () => { + test("5K. Should return deposit on DRep retirement", async ({ + page, + browser, + }, testInfo) => { + test.setTimeout(testInfo.timeout + 2 * environments.txTimeOut); + + const wallet = await ShelleyWallet.generate(); + const registrationRes = await kuberService.dRepRegistration( + convertBufferToHex(wallet.stakeKey.private), + convertBufferToHex(wallet.stakeKey.pkh), + ); + await pollTransaction(registrationRes.txId, registrationRes.lockInfo); + + const res = await kuberService.transferADA( + [wallet.addressBech32(environments.networkId)], + 40, + ); + await pollTransaction(res.txId, registrationRes.lockInfo); + + const tempDRepAuth = await createTempDRepAuth(page, wallet); + + const dRepPage = await createNewPageWithWallet(browser, { + storageState: tempDRepAuth, + wallet, + enableStakeSigning: true, + }); + + await dRepPage.goto("/"); + await dRepPage.getByTestId("retire-button").click(); + await dRepPage.getByTestId("retire-button").click(); // BUG: testId -> continue-retire-button + await expect( + dRepPage.getByTestId("retirement-transaction-submitted-modal"), + ).toBeVisible(); + dRepPage.getByTestId("confirm-modal-button").click(); + await waitForTxConfirmation(dRepPage); + + const balance = await kuberService.getBalance( + wallet.addressBech32(environments.networkId), + ); + expect(balance, "Retirement deposit not returned").toBeGreaterThan(500); + }); +}); diff --git a/tests/govtool-frontend/playwright/tests/6-miscellaneous/miscellaneous.spec.ts b/tests/govtool-frontend/playwright/tests/6-miscellaneous/miscellaneous.spec.ts index d26feb683..0b9a7a33d 100644 --- a/tests/govtool-frontend/playwright/tests/6-miscellaneous/miscellaneous.spec.ts +++ b/tests/govtool-frontend/playwright/tests/6-miscellaneous/miscellaneous.spec.ts @@ -23,7 +23,7 @@ test("6C. Navigation within the dApp @smoke @fast", async ({ ]); await expect(guidesPage).toHaveURL( - `${environments.docsUrl}/about/what-is-sanchonet-govtool` + `${environments.docsUrl}/about/what-is-sanchonet-govtool`, ); if (isMobile(page)) { diff --git a/tests/govtool-frontend/playwright/tests/dRep.setup.ts b/tests/govtool-frontend/playwright/tests/dRep.setup.ts index 38c587663..5203f1e47 100644 --- a/tests/govtool-frontend/playwright/tests/dRep.setup.ts +++ b/tests/govtool-frontend/playwright/tests/dRep.setup.ts @@ -15,7 +15,7 @@ dRepWallets.forEach((wallet) => { try { const res = await kuberService.dRepRegistration( wallet.stake.private, - wallet.stake.pkh + wallet.stake.pkh, ); await pollTransaction(res.txId, res.lockInfo); diff --git a/tests/govtool-frontend/playwright/tests/delegation.teardown.ts b/tests/govtool-frontend/playwright/tests/delegation.teardown.ts index 986ab1a45..2831db009 100644 --- a/tests/govtool-frontend/playwright/tests/delegation.teardown.ts +++ b/tests/govtool-frontend/playwright/tests/delegation.teardown.ts @@ -12,7 +12,7 @@ cleanup(`Abstain delegation`, async () => { const { txId, lockInfo } = await kuberService.abstainDelegations( stakePrivKeys, - stakePkhs + stakePkhs, ); await pollTransaction(txId, lockInfo); }); diff --git a/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts b/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts index 1d7397fda..80c9848c2 100644 --- a/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts +++ b/tests/govtool-frontend/playwright/tests/wallet.bootstrap.ts @@ -32,7 +32,7 @@ for (const wallet of [...adaHolderWallets, ...dRepWallets]) { wallet.stake.private, wallet.stake.pkh, wallet.payment.private, - wallet.address + wallet.address, ); await pollTransaction(txId, lockInfo); } catch (err) { @@ -49,7 +49,7 @@ function saveWallets(wallets: ShelleyWallet[]) { const jsonWallets = []; for (let i = 0; i < wallets.length; i++) { const stakePublicKey = Buffer.from(wallets[i].stakeKey.public).toString( - "hex" + "hex", ); const { dRepIdBech32 } = extractDRepsFromStakePubKey(stakePublicKey); From d07fb9d1405ec662d2918ba623ee047ee6ebdfa5 Mon Sep 17 00:00:00 2001 From: Nabin Kawan Date: Wed, 15 May 2024 11:59:15 +0545 Subject: [PATCH 03/11] test: Metadata anchor in vote transaction --- .../playwright/lib/helpers/logger.ts | 13 +++++++++++ .../playwright/lib/helpers/metadata.ts | 13 +++++++++++ .../lib/pages/governanceActionDetailsPage.ts | 8 ++++++- .../lib/services/metadataBucketService.ts | 22 +++++++++++++++++++ .../proposalVisibility.dRep.spec.ts | 18 +++++++-------- 5 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 tests/govtool-frontend/playwright/lib/helpers/logger.ts create mode 100644 tests/govtool-frontend/playwright/lib/helpers/metadata.ts create mode 100644 tests/govtool-frontend/playwright/lib/services/metadataBucketService.ts diff --git a/tests/govtool-frontend/playwright/lib/helpers/logger.ts b/tests/govtool-frontend/playwright/lib/helpers/logger.ts new file mode 100644 index 000000000..282544bb5 --- /dev/null +++ b/tests/govtool-frontend/playwright/lib/helpers/logger.ts @@ -0,0 +1,13 @@ +export class Logger { + static success(msg: string) { + console.debug(`\x1b[32m✔ ${msg}\x1b[0m`); // Green color + } + + static fail(msg) { + console.debug(`\x1b[33m✖ ${msg}\x1b[0m`); // Orange color + } + + static info(msg: string) { + console.debug(`\x1b[36mℹ ${msg}\x1b[0m`); // Cyan color + } +} diff --git a/tests/govtool-frontend/playwright/lib/helpers/metadata.ts b/tests/govtool-frontend/playwright/lib/helpers/metadata.ts new file mode 100644 index 000000000..9c3657f95 --- /dev/null +++ b/tests/govtool-frontend/playwright/lib/helpers/metadata.ts @@ -0,0 +1,13 @@ +import { Download } from "@playwright/test"; +import * as fs from "fs"; + +export async function downloadMetadata(download: Download): Promise<{ + name: string; + data: JSON; +}> { + const path = `.download/${download.suggestedFilename()}`; + await download.saveAs(path); + const fileContent = fs.readFileSync(path, "utf-8"); + const jsonData = JSON.parse(fileContent); + return { name: download.suggestedFilename(), data: jsonData }; +} diff --git a/tests/govtool-frontend/playwright/lib/pages/governanceActionDetailsPage.ts b/tests/govtool-frontend/playwright/lib/pages/governanceActionDetailsPage.ts index 843a242c9..31fee6f1b 100644 --- a/tests/govtool-frontend/playwright/lib/pages/governanceActionDetailsPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/governanceActionDetailsPage.ts @@ -25,6 +25,7 @@ export default class GovernanceActionDetailsPage { "view-other-details-button", ); readonly continueModalBtn = this.page.getByTestId("continue-modal-button"); + readonly confirmModalBtn = this.page.getByTestId("confirm-modal-button"); readonly voteSuccessModal = this.page.getByTestId("alert-success"); readonly externalLinkModal = this.page.getByTestId("external-link-modal"); @@ -61,7 +62,7 @@ export default class GovernanceActionDetailsPage { const voteMetadata = await this.downloadVoteMetadata(); const url = await metadataBucketService.uploadMetadata( voteMetadata.name, - voteMetadata.data, + voteMetadata.data ); await this.page.getByPlaceholder("URL").fill(url); @@ -72,6 +73,11 @@ export default class GovernanceActionDetailsPage { await this.voteBtn.click(); } + async downloadVoteMetadata() { + const download: Download = await this.page.waitForEvent("download"); + return downloadMetadata(download); + } + async reVote() { await this.noVoteRadio.click(); await this.changeVoteBtn.click(); diff --git a/tests/govtool-frontend/playwright/lib/services/metadataBucketService.ts b/tests/govtool-frontend/playwright/lib/services/metadataBucketService.ts new file mode 100644 index 000000000..2765f09e6 --- /dev/null +++ b/tests/govtool-frontend/playwright/lib/services/metadataBucketService.ts @@ -0,0 +1,22 @@ +import environments from "@constants/environments"; +import { Logger } from "@helpers/logger"; + +import fetch = require("node-fetch"); + +const metadataBucketService = { + uploadMetadata: async (name: string, data: JSON) => { + try { + const res = await fetch(`${environments.metadataBucketUrl}/${name}`, { + method: "PUT", + body: JSON.stringify(data), + }); + Logger.success(`Uploaded ${name} metadata to bucket`); + return `${environments.metadataBucketUrl}/${name}`; + } catch (err) { + Logger.fail(`Failed to upload ${name} metadata: ${err}`); + throw err; + } + }, +}; + +export default metadataBucketService; 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 e9b680c1f..66c27eac7 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 @@ -27,7 +27,7 @@ test.describe("Logged in DRep", () => { const votingPower = await res.json(); await expect( - page.getByText(`₳ ${lovelaceToAda(votingPower)}`), + page.getByText(`₳ ${lovelaceToAda(votingPower)}`) ).toBeVisible(); }); @@ -49,8 +49,8 @@ test.describe("Logged in DRep", () => { }) => { const responsesPromise = Object.keys(FilterOption).map((filterKey) => page.waitForResponse((response) => - response.url().includes(`&type[]=${FilterOption[filterKey]}`), - ), + response.url().includes(`&type[]=${FilterOption[filterKey]}`) + ) ); const governanceActionsPage = new GovernanceActionsPage(page); @@ -61,7 +61,7 @@ test.describe("Logged in DRep", () => { responses.map(async (response) => { const data = await response.json(); return data.elements; - }), + }) ) ).flat(); @@ -75,17 +75,17 @@ test.describe("Logged in DRep", () => { await expect( page .getByText("yes₳") - .getByText(`₳ ${lovelaceToAda(proposalToCheck.yesVotes)}`), + .getByText(`₳ ${lovelaceToAda(proposalToCheck.yesVotes)}`) ).toBeVisible(); await expect( page .getByText("abstain₳") - .getByText(`₳ ${lovelaceToAda(proposalToCheck.abstainVotes)}`), + .getByText(`₳ ${lovelaceToAda(proposalToCheck.abstainVotes)}`) ).toBeVisible(); await expect( page .getByText("no₳") - .getByText(`₳ ${lovelaceToAda(proposalToCheck.noVotes)}`), + .getByText(`₳ ${lovelaceToAda(proposalToCheck.noVotes)}`) ).toBeVisible(); }); }); @@ -99,13 +99,13 @@ test.describe("Temporary DReps", async () => { const wallet = await ShelleyWallet.generate(); const registrationRes = await kuberService.dRepRegistration( convertBufferToHex(wallet.stakeKey.private), - convertBufferToHex(wallet.stakeKey.pkh), + convertBufferToHex(wallet.stakeKey.pkh) ); await pollTransaction(registrationRes.txId, registrationRes.lockInfo); const res = await kuberService.transferADA( [wallet.addressBech32(environments.networkId)], - 40, + 40 ); await pollTransaction(res.txId, registrationRes.lockInfo); From 63ee2d1417c7eee5f0b170fc1d0a23d0d5b71e26 Mon Sep 17 00:00:00 2001 From: Nabin Kawan Date: Mon, 13 May 2024 19:25:17 +0545 Subject: [PATCH 04/11] test: Expired governance actions should not be displayed --- .../lib/helpers/extractExpiryDateFromText.ts | 29 +++++++++++++++++++ .../proposalVisibility.loggedin.spec.ts | 19 ++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 tests/govtool-frontend/playwright/lib/helpers/extractExpiryDateFromText.ts diff --git a/tests/govtool-frontend/playwright/lib/helpers/extractExpiryDateFromText.ts b/tests/govtool-frontend/playwright/lib/helpers/extractExpiryDateFromText.ts new file mode 100644 index 000000000..833fe3064 --- /dev/null +++ b/tests/govtool-frontend/playwright/lib/helpers/extractExpiryDateFromText.ts @@ -0,0 +1,29 @@ +const monthNames = [ + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec", +]; + +export default function extractExpiryDateFromText(text: string): Date | null { + const regex = /(\d{1,2})th ([\w]{3}) (\d{4})/; + const match = text.match(regex); + + if (match) { + const day = parseInt(match[1]); + const month = match[2]; + const year = parseInt(match[3]); + + return new Date(year, monthNames.indexOf(month), day); + } else { + return null; + } +} 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 3efed401f..0432f37bd 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 @@ -1,5 +1,6 @@ import { user01Wallet } from "@constants/staticWallets"; import { test } from "@fixtures/walletExtension"; +import extractExpiryDateFromText from "@helpers/extractExpiryDateFromText"; import { isMobile, openDrawerLoggedIn } from "@helpers/mobile"; import removeAllSpaces from "@helpers/removeAllSpaces"; import GovernanceActionsPage from "@pages/governanceActionsPage"; @@ -122,3 +123,21 @@ test("4D: Should filter and sort Governance Action Type on governance actions pa ); await govActionsPage.validateFilters([filterOptionNames[0]]); }); + +test("4H. Should verify none of the displayed governance actions have expired", async ({ + page, +}) => { + const govActionsPage = new GovernanceActionsPage(page); + await govActionsPage.goto(); + + await page.waitForTimeout(4000); // BUG: Delay to load governance actions + const proposalCards = await govActionsPage.getAllProposals(); + + for (const proposalCard of proposalCards) { + const expiryDateEl = proposalCard.getByTestId("expiry-date"); + const expiryDateTxt = await expiryDateEl.innerText(); + const expiryDate = extractExpiryDateFromText(expiryDateTxt); + const today = new Date(); + expect(today <= expiryDate).toBeTruthy(); + } +}); From 2bc0272b9981ec6835ca4e7510aaff968be8ceee Mon Sep 17 00:00:00 2001 From: Nabin Kawan Date: Mon, 13 May 2024 12:11:43 +0545 Subject: [PATCH 05/11] test: Return deposit on DRep retirement --- .../proposalFunctionality.dRep.spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 055f53925..6729b8e09 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 @@ -193,13 +193,13 @@ test.describe("Check voting power", () => { const wallet = await ShelleyWallet.generate(); const registrationRes = await kuberService.dRepRegistration( convertBufferToHex(wallet.stakeKey.private), - convertBufferToHex(wallet.stakeKey.pkh), + convertBufferToHex(wallet.stakeKey.pkh) ); await pollTransaction(registrationRes.txId, registrationRes.lockInfo); const res = await kuberService.transferADA( [wallet.addressBech32(environments.networkId)], - 40, + 40 ); await pollTransaction(res.txId, registrationRes.lockInfo); @@ -215,13 +215,13 @@ test.describe("Check voting power", () => { await dRepPage.getByTestId("retire-button").click(); await dRepPage.getByTestId("retire-button").click(); // BUG: testId -> continue-retire-button await expect( - dRepPage.getByTestId("retirement-transaction-submitted-modal"), + dRepPage.getByTestId("retirement-transaction-submitted-modal") ).toBeVisible(); dRepPage.getByTestId("confirm-modal-button").click(); await waitForTxConfirmation(dRepPage); const balance = await kuberService.getBalance( - wallet.addressBech32(environments.networkId), + wallet.addressBech32(environments.networkId) ); expect(balance, "Retirement deposit not returned").toBeGreaterThan(500); }); From eb63afd543a1fe45fd105ec1df481e7792842f6c Mon Sep 17 00:00:00 2001 From: Nabin Kawan Date: Mon, 13 May 2024 10:09:41 +0545 Subject: [PATCH 06/11] test: Hide retirement option for non-DRep --- .../proposalFunctionality.loggedin.spec.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.loggedin.spec.ts diff --git a/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.loggedin.spec.ts new file mode 100644 index 000000000..17034e23e --- /dev/null +++ b/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.loggedin.spec.ts @@ -0,0 +1,12 @@ +import { user01Wallet } from "@constants/staticWallets"; +import { test } from "@fixtures/walletExtension"; +import { expect } from "@playwright/test"; + +test.use({ storageState: ".auth/user01.json", wallet: user01Wallet }); + +test("5J. Should hide retirement option for non-registered DRep", async ({ + page, +}) => { + await page.goto("/"); + await expect(page.getByTestId("retire-button")).not.toBeVisible(); +}); From e217ace2bbf7698a6c2d2c551413481170774c23 Mon Sep 17 00:00:00 2001 From: Nabin Kawan Date: Fri, 10 May 2024 22:41:07 +0545 Subject: [PATCH 07/11] Add util lovelace-to-ada conversion --- tests/govtool-frontend/playwright/lib/helpers/cardano.ts | 5 +++++ .../playwright/lib/pages/governanceActionDetailsPage.ts | 1 + .../4-proposal-visibility/proposalVisibility.dRep.spec.ts | 4 ++-- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 tests/govtool-frontend/playwright/lib/helpers/cardano.ts diff --git a/tests/govtool-frontend/playwright/lib/helpers/cardano.ts b/tests/govtool-frontend/playwright/lib/helpers/cardano.ts new file mode 100644 index 000000000..3718d13a3 --- /dev/null +++ b/tests/govtool-frontend/playwright/lib/helpers/cardano.ts @@ -0,0 +1,5 @@ +export function lovelaceToAda(lovelace: number) { + if (lovelace === 0) return 0; + + return lovelace / 1e6; +} diff --git a/tests/govtool-frontend/playwright/lib/pages/governanceActionDetailsPage.ts b/tests/govtool-frontend/playwright/lib/pages/governanceActionDetailsPage.ts index 31fee6f1b..49cffbe00 100644 --- a/tests/govtool-frontend/playwright/lib/pages/governanceActionDetailsPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/governanceActionDetailsPage.ts @@ -13,6 +13,7 @@ export default class GovernanceActionDetailsPage { readonly governanceActionType = this.page.getByText( "Governance Action Type:", ); + readonly showVotesBtn = this.page.getByTestId("show-votes-button"); readonly submittedDate = this.page.getByTestId("submission-date"); readonly expiryDate = this.page.getByTestId("expiry-date"); readonly externalModalBtn = this.page.getByTestId("external-modal-button"); 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 66c27eac7..f9ec27ab8 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 @@ -23,8 +23,8 @@ test.describe("Logged in DRep", () => { const governanceActionsPage = new GovernanceActionsPage(page); await governanceActionsPage.goto(); - const res = await votingPowerPromise; - const votingPower = await res.json(); + const res = await votingPowerPromise; + const votingPower = await res.json(); await expect( page.getByText(`₳ ${lovelaceToAda(votingPower)}`) From acd088e54e5d5f2a333f81fc6bcf1d2f68dd6647 Mon Sep 17 00:00:00 2001 From: Nabin Kawan Date: Fri, 10 May 2024 22:36:36 +0545 Subject: [PATCH 08/11] test: Display correct vote counts --- .../lib/pages/governanceActionsPage.ts | 12 +---- .../govtool-frontend/playwright/lib/types.ts | 10 +++++ .../proposalVisibility.dRep.spec.ts | 45 +++++++++++++++++++ 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/pages/governanceActionsPage.ts b/tests/govtool-frontend/playwright/lib/pages/governanceActionsPage.ts index 03cde5992..07bd1b603 100644 --- a/tests/govtool-frontend/playwright/lib/pages/governanceActionsPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/governanceActionsPage.ts @@ -1,19 +1,9 @@ import removeAllSpaces from "@helpers/removeAllSpaces"; import { Locator, Page, expect } from "@playwright/test"; -import { IProposal } from "@types"; +import { FilterOption, IProposal } from "@types"; import environments from "lib/constants/environments"; import GovernanceActionDetailsPage from "./governanceActionDetailsPage"; -enum FilterOption { - ProtocolParameterChange = "ParameterChange", - InfoAction = "InfoAction", - TreasuryWithdrawal = "TreasuryWithdrawals", - HardFork = "HardForkInitiation", - NoConfidence = "NoConfidence", - NewCommittee = "NewCommittee", - UpdatetotheConstitution = "NewConstitution", -} - export default class GovernanceActionsPage { readonly filterBtn = this.page.getByTestId("filters-button"); readonly sortBtn = this.page.getByTestId("sort-button"); diff --git a/tests/govtool-frontend/playwright/lib/types.ts b/tests/govtool-frontend/playwright/lib/types.ts index 7cfb36fc8..6cefe5543 100644 --- a/tests/govtool-frontend/playwright/lib/types.ts +++ b/tests/govtool-frontend/playwright/lib/types.ts @@ -29,6 +29,7 @@ export interface IProposal { references: any; yesVotes: number; noVotes: number; + abstainVotes: number; } export type IVote = { @@ -50,3 +51,12 @@ export type IDRepInfo = { bio?: string; extraContentLinks?: string[]; }; +export enum FilterOption { + ProtocolParameterChange = "ParameterChange", + InfoAction = "InfoAction", + TreasuryWithdrawal = "TreasuryWithdrawals", + HardFork = "HardForkInitiation", + NoConfidence = "NoConfidence", + NewCommittee = "NewCommittee", + UpdatetotheConstitution = "NewConstitution", +} 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 f9ec27ab8..6a03d23c3 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 @@ -129,3 +129,48 @@ test.describe("Temporary DReps", async () => { expect(false, "No vote context displayed").toBe(true); }); }); + +test("4G. Should display correct vote counts on governance details page for DRep", async ({ + page, +}) => { + const responsesPromise = Object.keys(FilterOption).map((filterKey) => + page.waitForResponse((response) => + response.url().includes(`&type[]=${FilterOption[filterKey]}`) + ) + ); + + const governanceActionsPage = new GovernanceActionsPage(page); + await governanceActionsPage.goto(); + const responses = await Promise.all(responsesPromise); + const proposals: IProposal[] = ( + await Promise.all( + responses.map(async (response) => { + const data = await response.json(); + return data.elements; + }) + ) + ).flat(); + + expect(proposals.length, "No proposals found!").toBeGreaterThan(0); + + const proposalToCheck = proposals[0]; + const govActionDetailsPage = + await governanceActionsPage.viewProposal(proposalToCheck); + await govActionDetailsPage.showVotesBtn.click(); + + await expect( + page + .getByText("yes₳") + .getByText(`₳ ${lovelaceToAda(proposalToCheck.yesVotes)}`) + ).toBeVisible(); + await expect( + page + .getByText("abstain₳") + .getByText(`₳ ${lovelaceToAda(proposalToCheck.abstainVotes)}`) + ).toBeVisible(); + await expect( + page + .getByText("no₳") + .getByText(`₳ ${lovelaceToAda(proposalToCheck.noVotes)}`) + ).toBeVisible(); +}); From 6b52800a5a9bc204353b8fee2837eb498aa94751 Mon Sep 17 00:00:00 2001 From: Nabin Kawan Date: Fri, 10 May 2024 15:37:07 +0545 Subject: [PATCH 09/11] test: Disable DRep functionality upon wallet disconnect on govactions page --- .../proposalVisibility.dRep.spec.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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 6a03d23c3..417eb6598 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 @@ -174,3 +174,15 @@ test("4G. Should display correct vote counts on governance details page for DRep .getByText(`₳ ${lovelaceToAda(proposalToCheck.noVotes)}`) ).toBeVisible(); }); + +test("4F. Should Disable DRep functionality upon wallet disconnection on governance page", async ({ + page, +}) => { + const governanceActionsPage = new GovernanceActionsPage(page); + await governanceActionsPage.goto(); + + await page.getByTestId("disconnect-button").click(); + + const govActionDetailsPage = await governanceActionsPage.viewFirstProposal(); + await expect(govActionDetailsPage.voteBtn).not.toBeVisible(); +}); From 36fab448a463cf6e25b61cc78ec2ec0d7663e30b Mon Sep 17 00:00:00 2001 From: Nabin Kawan Date: Fri, 10 May 2024 13:32:20 +0545 Subject: [PATCH 10/11] test: Display 'In Progress' status on transaction --- .../playwright/lib/pages/dRepRegistrationPage.ts | 2 +- .../tests/3-drep-registration/dRepRegistration.dRep.spec.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/govtool-frontend/playwright/lib/pages/dRepRegistrationPage.ts b/tests/govtool-frontend/playwright/lib/pages/dRepRegistrationPage.ts index 766c95534..124f2e560 100644 --- a/tests/govtool-frontend/playwright/lib/pages/dRepRegistrationPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/dRepRegistrationPage.ts @@ -27,7 +27,7 @@ export default class DRepRegistrationPage { await this.continueBtn.click(); // BUG: testId -> continue-register-button } - async register(dRepInfo: IDRepInfo) { + async register(dRepInfo: IDRepInfo = { name: "Test_dRep" }) { await this.nameInput.fill(dRepInfo.name); if (dRepInfo.email != null) { 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 d31e2a91a..e54e1c838 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 @@ -147,7 +147,7 @@ test.describe("Temporary DReps", () => { const res = await kuberService.transferADA( [wallet.addressBech32(environments.networkId)], - 600, + 600 ); await pollTransaction(res.txId, res.lockInfo); @@ -166,7 +166,7 @@ test.describe("Temporary DReps", () => { .click(); await expect( - dRepPage.locator("span").filter({ hasText: "In Progress" }), + dRepPage.locator("span").filter({ hasText: "In Progress" }) ).toBeVisible(); // BUG add proper testId for dRep registration card }); }); From d516bd6a09b5be90d9d9e9055fa61e1c149e06be Mon Sep 17 00:00:00 2001 From: Nabin Kawan Date: Thu, 9 May 2024 20:40:21 +0545 Subject: [PATCH 11/11] 1E. Should hide incompatible wallets when connecting --- .../tests/1-wallet-connect/walletConnect.spec.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) 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 500786d0a..980271dbc 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 @@ -38,7 +38,9 @@ test("1D. Should check correct network (Testnet/Mainnet) on connection @smoke @f page, }) => { const wrongNetworkId = 1; // mainnet network - await createWallet(page, { networkId: wrongNetworkId }); + await createWallet(page, { + networkId: wrongNetworkId, + }); const errors: Array = []; page.on("pageerror", (error) => { @@ -50,3 +52,15 @@ test("1D. Should check correct network (Testnet/Mainnet) on connection @smoke @f expect(errors).not.toHaveLength(0); }); + +test("1E. Should hide incompatible wallets when connecting", async ({ + page, +}) => { + // Disabling cip95 support for wallet + await createWallet(page, { supportedExtensions: [] }); + + await page.goto("/"); + await page.getByTestId("connect-wallet-button").click(); + + await expect(page.getByTestId("demos-wallet-button")).not.toBeVisible(); +});