diff --git a/CHANGELOG.md b/CHANGELOG.md index 53a5dc973..6c28d95c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ changes. ### Fixed - Fix missing off chain references in DRep details [Issue 3490](https://github.com/IntersectMBO/govtool/issues/3490) +- Fix blank screen and type error on linkReferences when navigating to edit dRep page that has no links [Issue 3714](https://github.com/IntersectMBO/govtool/issues/3714) +- Fix adding two link input fields when editing the dRep form when no links are present initially [Issue 3709](https://github.com/IntersectMBO/govtool/issues/3709) ### Changed diff --git a/govtool/frontend/package-lock.json b/govtool/frontend/package-lock.json index 8fb6e4f8b..2492bd6d6 100644 --- a/govtool/frontend/package-lock.json +++ b/govtool/frontend/package-lock.json @@ -15,7 +15,7 @@ "@hookform/resolvers": "^3.3.1", "@intersect.mbo/govtool-outcomes-pillar-ui": "v1.4.3", "@intersect.mbo/intersectmbo.org-icons-set": "^1.0.8", - "@intersect.mbo/pdf-ui": "0.7.0-beta-33", + "@intersect.mbo/pdf-ui": "0.7.0-beta-35", "@mui/icons-material": "^5.14.3", "@mui/material": "^5.14.4", "@rollup/plugin-babel": "^6.0.4", @@ -3424,9 +3424,9 @@ "license": "ISC" }, "node_modules/@intersect.mbo/pdf-ui": { - "version": "0.7.0-beta-33", - "resolved": "https://registry.npmjs.org/@intersect.mbo/pdf-ui/-/pdf-ui-0.7.0-beta-33.tgz", - "integrity": "sha512-Jddj4txjkLm7ecrmhPHP2/I7n2lzfgT8mYAMQAPd/PvUQ/9QvXoWTvg7rF0xeh4VmgAiLONv1LKfRE2VJZcz8A==", + "version": "0.7.0-beta-35", + "resolved": "https://registry.npmjs.org/@intersect.mbo/pdf-ui/-/pdf-ui-0.7.0-beta-35.tgz", + "integrity": "sha512-S0HAl4pwJm+AqzGxEEHxQ59VsU6Tbvnn5w7F6jG0jd7zUHSCKJAt3PhJQ6VliA5FoOI4z43a2xm7J/9PK+Q9IA==", "dependencies": { "@emurgo/cardano-serialization-lib-asmjs": "^12.0.0-beta.2", "@fontsource/poppins": "^5.0.14", diff --git a/govtool/frontend/package.json b/govtool/frontend/package.json index c31b492ae..56e71b22e 100644 --- a/govtool/frontend/package.json +++ b/govtool/frontend/package.json @@ -29,7 +29,7 @@ "@hookform/resolvers": "^3.3.1", "@intersect.mbo/govtool-outcomes-pillar-ui": "v1.4.3", "@intersect.mbo/intersectmbo.org-icons-set": "^1.0.8", - "@intersect.mbo/pdf-ui": "0.7.0-beta-33", + "@intersect.mbo/pdf-ui": "0.7.0-beta-35", "@mui/icons-material": "^5.14.3", "@mui/material": "^5.14.4", "@rollup/plugin-babel": "^6.0.4", diff --git a/govtool/frontend/src/components/organisms/EditDRepInfoSteps/EditDRepForm.tsx b/govtool/frontend/src/components/organisms/EditDRepInfoSteps/EditDRepForm.tsx index d758c7398..268e8936d 100644 --- a/govtool/frontend/src/components/organisms/EditDRepInfoSteps/EditDRepForm.tsx +++ b/govtool/frontend/src/components/organisms/EditDRepInfoSteps/EditDRepForm.tsx @@ -4,6 +4,7 @@ import { Box } from "@mui/material"; import { useCardano } from "@context"; import { + defaultEditDRepInfoValues, useEditDRepInfoForm, useGetDRepDetailsQuery, useTranslation, @@ -44,15 +45,21 @@ export const EditDRepForm = ({ reset({ ...data, - objectives: data?.objectives ?? "", - motivations: data?.motivations ?? "", - qualifications: data?.qualifications ?? "", - paymentAddress: data?.paymentAddress ?? "", - image: data?.image ?? "", - linkReferences: data.linkReferences ?? [getEmptyReference("Link")], - identityReferences: data.identityReferences ?? [ - getEmptyReference("Identity"), - ], + objectives: data?.objectives ?? defaultEditDRepInfoValues.objectives, + motivations: data?.motivations ?? defaultEditDRepInfoValues.motivations, + qualifications: + data?.qualifications ?? defaultEditDRepInfoValues.qualifications, + paymentAddress: + data?.paymentAddress ?? defaultEditDRepInfoValues.paymentAddress, + image: data?.image ?? defaultEditDRepInfoValues.image, + linkReferences: + Array.isArray(data?.linkReferences) && data.linkReferences.length > 0 + ? data.linkReferences + : defaultEditDRepInfoValues.linkReferences, + identityReferences: + Array.isArray(data?.identityReferences) && data.identityReferences.length > 0 + ? data.identityReferences + : defaultEditDRepInfoValues.identityReferences, }); } }, [yourselfDRep, loadUserData]); @@ -74,9 +81,3 @@ export const EditDRepForm = ({ ); }; - -const getEmptyReference = (type: "Link" | "Identity") => ({ - "@type": type, - uri: "", - label: "", -}); diff --git a/tests/govtool-frontend/playwright/lib/helpers/auth.ts b/tests/govtool-frontend/playwright/lib/helpers/auth.ts index 980cfa4f6..44ef71661 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/auth.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/auth.ts @@ -2,7 +2,7 @@ import { importWallet } from "@fixtures/importWallet"; import { valid as mockValid } from "@mock/index"; import LoginPage from "@pages/loginPage"; import ProposalDiscussionPage from "@pages/proposalDiscussionPage"; -import { BrowserContext, Page } from "@playwright/test"; +import { BrowserContext, expect, Page } from "@playwright/test"; import { ProposalType, StaticWallet } from "@types"; import { ShelleyWallet } from "./crypto"; import convertBufferToHex from "./convertBufferToHex"; @@ -57,9 +57,16 @@ export async function createAuthWithUserName({ const proposalDiscussionPage = new ProposalDiscussionPage(page); await proposalDiscussionPage.goto(); - await proposalDiscussionPage.verifyIdentityBtn.click({ timeout: 15_000 }); - - await proposalDiscussionPage.setUsername(mockValid.username()); + await proposalDiscussionPage.verifyIdentityBtn.click({ timeout: 60_000 }); + try { + await expect(page.getByTestId("username-input")).toBeVisible({ + timeout: 10_000, + }); + await proposalDiscussionPage.setUsername(mockValid.username()); + } catch (error) { + // Ignore error if username is already set + console.log("Username is already set"); + } await context.storageState({ path: auth }); } diff --git a/tests/govtool-frontend/playwright/lib/helpers/cardano.ts b/tests/govtool-frontend/playwright/lib/helpers/cardano.ts index e4ff03501..582d2608a 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/cardano.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/cardano.ts @@ -50,7 +50,7 @@ export async function skipIfNotInfoAndBootstrapping(type: ProposalType) { export async function skipIfMainnet() { if (environments.networkId === 1) { await allure.description( - "Ada spendable features are not available on mainnet." + "Test skipped on mainnet to prevent affecting the production environment or using real ADA." ); test.skip(); } diff --git a/tests/govtool-frontend/playwright/lib/helpers/crypto.ts b/tests/govtool-frontend/playwright/lib/helpers/crypto.ts index 62442ac9f..13bcd9512 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/crypto.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/crypto.ts @@ -2,7 +2,12 @@ import environments from "../constants/environments"; import { ed25519 as ed } from "@noble/curves/ed25519"; import { bech32 } from "bech32"; import * as blake from "blakejs"; -import { rewardAddressBech32, rewardAddressRawBytes } from "./shellyWallet"; +import { + addressBech32, + addressRawBytes, + rewardAddressBech32, + rewardAddressRawBytes, +} from "./shellyWallet"; const KEY_HASH_LENGTH = 28; const ADDR_LENGTH = KEY_HASH_LENGTH * 2 + 1; @@ -103,20 +108,15 @@ export class ShelleyWallet { } addressBech32(networkId: number): string { - const prefix = networkId == 0 ? "addr_test" : "addr"; - return bech32.encode( - prefix, - bech32.toWords(Buffer.from(this.addressRawBytes(networkId))), - 200 - ); + const stakePkh = Buffer.from(this.stakeKey.pkh).toString("hex"); + const paymentPkh = Buffer.from(this.paymentKey.pkh).toString("hex"); + return addressBech32(networkId, paymentPkh, stakePkh); } addressRawBytes(networkId) { - const concatenatedArray1 = new Uint8Array(ADDR_LENGTH); - concatenatedArray1[0] = networkId; - concatenatedArray1.set(this.paymentKey.pkh, 1); - concatenatedArray1.set(this.stakeKey.pkh, KEY_HASH_LENGTH + 1); - return concatenatedArray1; + const stakePkh = Buffer.from(this.stakeKey.pkh).toString("hex"); + const paymentPkh = Buffer.from(this.paymentKey.pkh).toString("hex"); + return addressRawBytes(networkId, paymentPkh, stakePkh); } rewardAddressRawBytes(network: number) { diff --git a/tests/govtool-frontend/playwright/lib/helpers/shellyWallet.ts b/tests/govtool-frontend/playwright/lib/helpers/shellyWallet.ts index aa8001906..8c2e57082 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/shellyWallet.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/shellyWallet.ts @@ -2,7 +2,9 @@ import { bech32 } from "bech32"; import { blake2bHex } from "blakejs"; import convertBufferToHex from "./convertBufferToHex"; import { ShelleyWallet } from "./crypto"; + const KEY_HASH_LENGTH = 28; +const ADDR_LENGTH = KEY_HASH_LENGTH * 2 + 1; export default function extractDRepFromWallet(wallet: ShelleyWallet) { const dRepPubKey = convertBufferToHex(wallet.dRepKey.public); @@ -36,6 +38,36 @@ export function rewardAddressBech32( ); } +export function addressBech32( + networkId: number, + paymentPkh: string, + stakePkh: string +): string { + const prefix = networkId == 0 ? "addr_test" : "addr"; + return bech32.encode( + prefix, + bech32.toWords( + Buffer.from(addressRawBytes(networkId, paymentPkh, stakePkh)) + ), + 200 + ); +} + +export function addressRawBytes( + networkId: number, + paymentPkh: string, + stakePkh: string +) { + const concatenatedArray1 = new Uint8Array(ADDR_LENGTH); + concatenatedArray1[0] = networkId; + concatenatedArray1.set(Uint8Array.from(Buffer.from(paymentPkh, "hex")), 1); + concatenatedArray1.set( + Uint8Array.from(Buffer.from(stakePkh, "hex")), + KEY_HASH_LENGTH + 1 + ); + return concatenatedArray1; +} + export async function generateWallets(num: number) { return await Promise.all( Array.from({ length: num }, () => diff --git a/tests/govtool-frontend/playwright/lib/pages/outcomeDetailsPage.ts b/tests/govtool-frontend/playwright/lib/pages/outcomeDetailsPage.ts index dd94a1c6b..cbf39d9ca 100644 --- a/tests/govtool-frontend/playwright/lib/pages/outcomeDetailsPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/outcomeDetailsPage.ts @@ -106,6 +106,10 @@ export default class OutcomeDetailsPage { isLoggedIn ); + if (!govActionDetailsPage) { + return; + } + const outcomeResponse = await outcomeResponsePromise; const proposalToCheck = (await outcomeResponse.json())[0]; @@ -267,7 +271,7 @@ export default class OutcomeDetailsPage { { message: `CC "Abstain" vote count checked for ${currentPageUrl}`, } - ).toHaveText(`Abstain Votes${proposalToCheck.pool_abstain_votes}`); //BUG missing testIds + ).toHaveText(`Abstain Votes${proposalToCheck.cc_abstain_votes}`); //BUG missing testIds const noPercentage = 100 - parseFloat(yesPercentage.replace("%", "")); await expect(govActionDetailsPage.ccCommitteeNoVotes, { diff --git a/tests/govtool-frontend/playwright/lib/pages/outcomesPage.ts b/tests/govtool-frontend/playwright/lib/pages/outcomesPage.ts index bed26b0aa..915cb2c67 100644 --- a/tests/govtool-frontend/playwright/lib/pages/outcomesPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/outcomesPage.ts @@ -177,8 +177,7 @@ export default class OutComesPage { await this.page.getByTestId(this.getSortTestId(sortOption)).click(); const response = await responsePromise; - const data = await response.json(); - let outcomeProposalList: outcomeProposal[] = data.length != 0 ? data : null; + const outcomeProposalList: outcomeProposal[] = await response.json(); // API validation if (outcomeProposalList.length <= 1) return; @@ -456,10 +455,15 @@ export default class OutComesPage { async searchOutcomesById(governanceActionId: string) { await this.searchInput.fill(governanceActionId); - await expect( - this.page.getByRole("progressbar").getByRole("img") - ).toBeVisible(); + try { + await expect( + this.page.getByRole("progressbar").getByRole("img") + ).toBeVisible(); + } catch (error) { + // Handle the case where the progress bar is not visible + console.warn("Progress bar not visible, proceeding with search."); + } await functionWaitedAssert( async () => { const idSearchOutcomeCards = await this.getAllOutcomes(); @@ -480,9 +484,14 @@ export default class OutComesPage { async searchOutcomesByTitle(governanceActionTitle: string) { await this.searchInput.fill(governanceActionTitle); - await expect( - this.page.getByRole("progressbar").getByRole("img") - ).toBeVisible(); + try { + await expect( + this.page.getByRole("progressbar").getByRole("img") + ).toBeVisible(); + } catch (error) { + // Handle the case where the progress bar is not visible + console.warn("Progress bar not visible, proceeding with search."); + } await functionWaitedAssert( async () => { @@ -545,17 +554,26 @@ export default class OutComesPage { { timeout: 60_000 } ); - const metricsResponsePromise = page.waitForResponse( - (response) => response.url().includes(`/misc/network/metrics?epoch`), - { timeout: 60_000 } - ); - const outcomePage = new OutComesPage(page); await outcomePage.goto({ filter: filterKey }); const outcomeListResponse = await outcomeListResponsePromise; const proposals = await outcomeListResponse.json(); + if (proposals.length === 0) { + expect(true, "No proposals found!").toBeTruthy(); + return { + govActionDetailsPage: null, + outcomeResponsePromise: null, + metricsResponsePromise: null, + }; + } + + const metricsResponsePromise = page.waitForResponse( + (response) => response.url().includes(`/misc/network/metrics?epoch`), + { timeout: 60_000 } + ); + expect( proposals.length, proposals.length == 0 && "No proposals found!" diff --git a/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts b/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts index 07da72fda..c2c301c39 100644 --- a/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/proposalDiscussionPage.ts @@ -1,5 +1,10 @@ import { expect, Locator, Page } from "@playwright/test"; -import { ProposalCreateRequest, ProposalType, ProposedGovAction } from "@types"; +import { + ProposalCreateRequest, + ProposalDiscussionFilterTypes, + ProposalType, + ProposedGovAction, +} from "@types"; import environments from "lib/constants/environments"; import ProposalDiscussionDetailsPage from "./proposalDiscussionDetailsPage"; import { functionWaitedAssert, waitedLoop } from "@helpers/waitedLoop"; @@ -147,16 +152,30 @@ export default class ProposalDiscussionPage { } async sortAndValidate( - option: "asc" | "desc", + type: ProposalDiscussionFilterTypes, validationFn: (p1: ProposedGovAction, p2: ProposedGovAction) => boolean ) { + const sortMappings = { + "Name A-Z": "&sort[prop_name]=ASC", + "Name Z-A": "&sort[prop_name]=DESC", + "Most comments": "&sort[proposal][prop_comments_number]=DESC", + "Least comments": "&sort[proposal][prop_comments_number]=ASC", + "Most likes": "&sort[proposal][prop_likes]=DESC", + "Least likes": "&sort[proposal][prop_likes]=ASC", + "Most dislikes": "&sort[proposal][prop_dislikes]=DESC", + "Least dislikes": "&sort[proposal][prop_dislikes]=ASC", + Oldest: "&sort[createdAt]=ASC", + Newest: "&sort[createdAt]=DESC", + }; + + const urlParam = sortMappings[type]; + const populateParam = "&populate[0]=proposal_links"; const responsePromise = this.page.waitForResponse((response) => - response - .url() - .includes(`&sort[createdAt]=${option}&populate[0]=proposal_links`) + response.url().includes(`${urlParam}${populateParam}`) ); await this.sortBtn.click(); + await this.page.getByTestId(`${type}-sort-option`).click(); const response = await responsePromise; let proposals: ProposedGovAction[] = (await response.json()).data; diff --git a/tests/govtool-frontend/playwright/lib/services/kuberService.ts b/tests/govtool-frontend/playwright/lib/services/kuberService.ts index 07956b80d..d97e5e514 100644 --- a/tests/govtool-frontend/playwright/lib/services/kuberService.ts +++ b/tests/govtool-frontend/playwright/lib/services/kuberService.ts @@ -177,6 +177,7 @@ const kuberService = { })); const inputs = wallets.map((wallet) => wallet.address); + inputs.push(getWalletConfigForFaucet().address); return kuber.signAndSubmitTx({ inputs, selections, diff --git a/tests/govtool-frontend/playwright/lib/types.ts b/tests/govtool-frontend/playwright/lib/types.ts index 5ac7273ca..2ffdac42c 100644 --- a/tests/govtool-frontend/playwright/lib/types.ts +++ b/tests/govtool-frontend/playwright/lib/types.ts @@ -201,8 +201,17 @@ export type ProposedGovAction = { attributes: { gov_action_type_name: string; prop_comments_number: number; + prop_likes: number; + prop_dislikes: number; createdAt: string; updatedAt: string; + content: { + id: string; + attributes: { + proposal_id: string; + prop_name: string; + }; + }; creator: { data: { id: number; @@ -547,3 +556,15 @@ export type BudgetProposalFilterTypes = | "Name Z-A" | "Proposer A-Z" | "Proposer Z-A"; + +export type ProposalDiscussionFilterTypes = + | "Newest" + | "Oldest" + | "Most likes" + | "Least likes" + | "Most dislikes" + | "Least dislikes" + | "Most comments" + | "Least comments" + | "Name A-Z" + | "Name Z-A"; diff --git a/tests/govtool-frontend/playwright/package-lock.json b/tests/govtool-frontend/playwright/package-lock.json index 9f2a897ee..edbd65f52 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": "^3.3.1", + "@cardanoapi/cardano-test-wallet": "^3.3.2", "@faker-js/faker": "^8.4.1", "@noble/curves": "^1.3.0", "@noble/ed25519": "^2.0.0", @@ -43,9 +43,9 @@ } }, "node_modules/@cardanoapi/cardano-test-wallet": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@cardanoapi/cardano-test-wallet/-/cardano-test-wallet-3.3.1.tgz", - "integrity": "sha512-AOIDoEkVRYanW4O0pflfcJ2K4Pb3cUHf93cz8pJANU3qIZRQXW+ubGVM60s1WodTcJEmUccpxxXZJuuGRBGXCw==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@cardanoapi/cardano-test-wallet/-/cardano-test-wallet-3.3.2.tgz", + "integrity": "sha512-N80hAiw/9SkEQJyx8lYB0FqfnzCcWI+wzjPHgULzjz9C9b92irE0zvV6X1/GgN96OYLV+V1VCzgkJ7A1aGnCvQ==", "license": "MIT" }, "node_modules/@cbor-extract/cbor-extract-darwin-arm64": { diff --git a/tests/govtool-frontend/playwright/package.json b/tests/govtool-frontend/playwright/package.json index b0127afe7..91e185062 100644 --- a/tests/govtool-frontend/playwright/package.json +++ b/tests/govtool-frontend/playwright/package.json @@ -48,7 +48,7 @@ "generate-faucet-wallet": "ts-node ./generate_faucet_wallet.ts" }, "dependencies": { - "@cardanoapi/cardano-test-wallet": "^3.3.1", + "@cardanoapi/cardano-test-wallet": "^3.3.2", "@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 4e8757478..be00da55a 100644 --- a/tests/govtool-frontend/playwright/playwright.config.ts +++ b/tests/govtool-frontend/playwright/playwright.config.ts @@ -61,7 +61,6 @@ export default defineConfig({ { name: "dRep auth setup", testMatch: "**/dRep.auth.setup.ts", - dependencies: environments.ci ? ["dRep setup"] : [], }, { name: "proposal discussion auth setup", @@ -143,7 +142,7 @@ export default defineConfig({ use: { ...devices["Desktop Chrome"] }, testMatch: "**/*.dRep.spec.ts", dependencies: environments.ci - ? ["dRep auth setup"] + ? ["dRep auth setup" , "dRep setup"] : [], teardown: environments.ci && "cleanup artifacts", }, diff --git a/tests/govtool-frontend/playwright/tests/11-proposal-budget/proposalBudget.loggedin.pb.spec.ts b/tests/govtool-frontend/playwright/tests/11-proposal-budget/proposalBudget.loggedin.pb.spec.ts index d8747f469..ed705d51a 100644 --- a/tests/govtool-frontend/playwright/tests/11-proposal-budget/proposalBudget.loggedin.pb.spec.ts +++ b/tests/govtool-frontend/playwright/tests/11-proposal-budget/proposalBudget.loggedin.pb.spec.ts @@ -3,6 +3,7 @@ import { budgetProposal01Wallet } from "@constants/staticWallets"; import { faker } from "@faker-js/faker"; import { test } from "@fixtures/walletExtension"; import { setAllureEpic } from "@helpers/allure"; +import { skipIfMainnet } from "@helpers/cardano"; import BudgetDiscussionDetailsPage from "@pages/budgetDiscussionDetailsPage"; import BudgetDiscussionPage from "@pages/budgetDiscussionPage"; import { expect } from "@playwright/test"; @@ -50,6 +51,8 @@ test.describe("Budget proposal logged in state", () => { }); test("11I. Should comments on any proposal", async ({}) => { + await skipIfMainnet(); + const comment = faker.lorem.words(5); await budgetDiscussionDetailsPage.addComment(comment); await expect( @@ -60,6 +63,8 @@ test.describe("Budget proposal logged in state", () => { }); test("11J. Should reply to any comments", async ({}) => { + await skipIfMainnet(); + const randComment = faker.lorem.words(5); const randReply = faker.lorem.words(5); diff --git a/tests/govtool-frontend/playwright/tests/12-proposal-budget-submission/proposalBudgetSubmission.loggedin.pb.spec.ts b/tests/govtool-frontend/playwright/tests/12-proposal-budget-submission/proposalBudgetSubmission.loggedin.pb.spec.ts index c092f05d5..24f836706 100644 --- a/tests/govtool-frontend/playwright/tests/12-proposal-budget-submission/proposalBudgetSubmission.loggedin.pb.spec.ts +++ b/tests/govtool-frontend/playwright/tests/12-proposal-budget-submission/proposalBudgetSubmission.loggedin.pb.spec.ts @@ -15,6 +15,7 @@ import { import { faker } from "@faker-js/faker"; import { test } from "@fixtures/budgetProposal"; import { setAllureEpic } from "@helpers/allure"; +import { skipIfMainnet } from "@helpers/cardano"; import { createNewPageWithWallet } from "@helpers/page"; import BudgetDiscussionDetailsPage from "@pages/budgetDiscussionDetailsPage"; import BudgetDiscussionPage from "@pages/budgetDiscussionPage"; @@ -421,6 +422,7 @@ test.describe("Budget proposal 01 wallet", () => { }); test("12C. Should save and view draft proposal", async ({ browser }) => { + await skipIfMainnet(); const page = await createNewPageWithWallet(browser, { storageState: budgetProposal02AuthFile, wallet: budgetProposal02Wallet, @@ -469,6 +471,8 @@ test("12C. Should save and view draft proposal", async ({ browser }) => { }); test("12H. Should submit a valid budget proposal", async ({ browser }) => { + await skipIfMainnet(); + const page = await createNewPageWithWallet(browser, { storageState: budgetProposal03AuthFile, wallet: budgetProposal03Wallet, @@ -489,6 +493,7 @@ test("12H. Should submit a valid budget proposal", async ({ browser }) => { test("12I. Should submit a valid draft budget proposal", async ({ browser, }) => { + await skipIfMainnet(); test.slow(); const page = await createNewPageWithWallet(browser, { storageState: budgetProposal04AuthFile, @@ -517,6 +522,7 @@ test("12I. Should submit a valid draft budget proposal", async ({ test("12J. Should verify created proposal appears in my proposals list", async ({ browser, }) => { + await skipIfMainnet(); test.slow(); const page = await createNewPageWithWallet(browser, { storageState: budgetProposal05AuthFile, 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 782df6ada..383a43a89 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 @@ -2,7 +2,6 @@ import { dRep02Wallet } from "@constants/staticWallets"; import { faker } from "@faker-js/faker"; 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 { skipIfMainnet, @@ -10,7 +9,6 @@ import { } from "@helpers/cardano"; import EditDRepPage from "@pages/editDRepPage"; import { expect } from "@playwright/test"; -import environments from "@constants/environments"; import { dRep02AuthFile } from "@constants/auth"; import { generateInvalidDRepInfo, generateValidDRepInfo } from "@helpers/dRep"; diff --git a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts index fd75c0b1d..7e6623005 100644 --- a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts @@ -147,7 +147,11 @@ test.describe("Check vote count", () => { : GovernanceActionType; const responsesPromise = Object.keys(voteWhiteListOption).map((filterKey) => page.waitForResponse((response) => - response.url().includes(`&type[]=${voteWhiteListOption[filterKey]}`) + response + .url() + .includes( + `proposal/list?page=0&pageSize=7&type[]=${voteWhiteListOption[filterKey]}` + ) ) ); 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 dcc0fbaa3..7cd57efc1 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 @@ -38,14 +38,6 @@ Object.values(ProposalType).forEach((proposalType, index) => { const wallet = await walletManager.popWallet("proposalSubmission"); - const stakeKeys = await createKeyFromPrivateKeyHex( - environments.faucet.stake.private || "" - ); - const { pkh: stakePkh, public: stakePublic } = stakeKeys.json(); - wallet.stake.pkh = stakePkh; - wallet.stake.private = getWalletConfigForFaucet().stake.private; - wallet.stake.public = stakePublic; - await logWalletDetails(wallet.address); const tempUserAuth = await createTempUserAuth(page, wallet); @@ -73,7 +65,10 @@ Object.values(ProposalType).forEach((proposalType, index) => { await proposalSubmissionPage.proposalCreateBtn.click(); await proposalDiscussionPage.continueBtn.click(); - const rewardAddress = rewardAddressBech32(environments.networkId, stakePkh); + const rewardAddress = rewardAddressBech32( + environments.networkId, + wallet.stake.pkh + ); await proposalSubmissionPage.createProposal(rewardAddress, proposalType); @@ -129,6 +124,7 @@ test.describe("Proposed as a governance action", async () => { }); test.afterEach(async () => { + await skipIfMainnet(); // cleanup await proposalDiscussionDetailPage.goto(proposalId); diff --git a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.pd.spec.ts b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.pd.spec.ts index d7126799a..63ef2d23e 100644 --- a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.pd.spec.ts +++ b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.pd.spec.ts @@ -18,10 +18,11 @@ import { getDraftProposalWalletAndState } from "@helpers/auth"; import { skipIfNotInfoAndBootstrapping, isBootStrapingPhase, + skipIfMainnet, } from "@helpers/cardano"; import { ShelleyWallet } from "@helpers/crypto"; import { createNewPageWithWallet } from "@helpers/page"; -import { invalid, valid as mockValid } from "@mock/index"; +import { rewardAddressBech32 } from "@helpers/shellyWallet"; import ProposalDiscussionDetailsPage from "@pages/proposalDiscussionDetailsPage"; import ProposalSubmissionPage from "@pages/proposalSubmissionPage"; import { expect } from "@playwright/test"; @@ -132,6 +133,7 @@ test.describe("Proposal created logged state", () => { page, wallet, }) => { + await skipIfMainnet(); await skipIfNotInfoAndBootstrapping(type); const proposalSubmissionPage = new ProposalSubmissionPage(page); @@ -308,28 +310,42 @@ test.describe("Proposal created logged state", () => { test("7O. Should display insufficient balance modal when submitting proposal with insufficient funds", async ({ page, - proposalId, }) => { + await skipIfMainnet(); + const proposalCreationPage = new ProposalSubmissionPage(page); + await proposalCreationPage.goto(); + + const receiverAddress = rewardAddressBech32( + environments.networkId, + proposal01Wallet.stake.pkh + ); + + await proposalCreationPage.createProposal(receiverAddress); + const proposalDiscussionDetailsPage = new ProposalDiscussionDetailsPage( page ); - await proposalDiscussionDetailsPage.goto(proposalId); - await proposalDiscussionDetailsPage.verifyIdentityBtn.click(); - await proposalDiscussionDetailsPage.submitAsGABtn.click(); - - const proposalSubmissionPage = new ProposalSubmissionPage(page); - await expect( - proposalSubmissionPage.currentPage.getByText( - "Insufficient wallet balance", - { exact: true } - ) - ).toBeVisible(); // BUG missing test id + try { + await proposalDiscussionDetailsPage.submitAsGABtn.click(); + await expect( + proposalCreationPage.currentPage.getByTestId( + "insufficient-wallet-balance-title" + ) + ).toHaveText(/Insufficient wallet balance/); + + await proposalCreationPage.currentPage + .getByTestId("insufficient-wallet-balance-dialog-button") + .click(); + } finally { + await proposalDiscussionDetailsPage.deleteProposal(); + } }); }); test.describe("Proposal Draft", () => { test("7C. Should list unfinished Draft ", async ({ browser }) => { + await skipIfMainnet(); const page = await createNewPageWithWallet(browser, { storageState: proposal03AuthFile, wallet: proposal03Wallet, @@ -346,6 +362,7 @@ test.describe("Proposal Draft", () => { }); test("7L. Should save proposal as a draft", async ({ browser }) => { + await skipIfMainnet(); const page = await createNewPageWithWallet(browser, { storageState: proposal04AuthFile, wallet: proposal04Wallet, @@ -422,6 +439,7 @@ test.describe("Proposal Draft", () => { test(`7M_${index + 1}. Should edit a ${proposalType.toLowerCase()} proposal draft`, async ({ browser, }) => { + await skipIfMainnet(); test.slow(); const { storageState, wallet } = getDraftProposalWalletAndState(proposalType); @@ -496,6 +514,7 @@ test.describe("Proposal Draft", () => { }); test("7N. Should submit a draft proposal", async ({ browser }) => { + await skipIfMainnet(); const page = await createNewPageWithWallet(browser, { storageState: proposal06AuthFile, wallet: proposal06Wallet, diff --git a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.loggedin.pd.spec.ts b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.loggedin.pd.spec.ts index 98f4c4e36..40c725509 100644 --- a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.loggedin.pd.spec.ts +++ b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.loggedin.pd.spec.ts @@ -9,15 +9,16 @@ import { createNewPageWithWallet } from "@helpers/page"; import ProposalDiscussionDetailsPage from "@pages/proposalDiscussionDetailsPage"; import { Page, expect } from "@playwright/test"; import { setAllureEpic } from "@helpers/allure"; -import ProposalSubmissionPage from "@pages/proposalSubmissionPage"; import { proposal01AuthFile, proposal02AuthFile, user01AuthFile, } from "@constants/auth"; +import { skipIfMainnet } from "@helpers/cardano"; test.beforeEach(async () => { await setAllureEpic("8. Proposal Discussion Forum"); + await skipIfMainnet(); }); test.describe("Proposal created logged in state", () => { diff --git a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts index cdecc19cc..a895ecfa5 100644 --- a/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts +++ b/tests/govtool-frontend/playwright/tests/8-proposal-discussion/proposalDiscussion.spec.ts @@ -13,7 +13,11 @@ import { functionWaitedAssert } from "@helpers/waitedLoop"; import ProposalDiscussionDetailsPage from "@pages/proposalDiscussionDetailsPage"; import ProposalDiscussionPage from "@pages/proposalDiscussionPage"; import { expect } from "@playwright/test"; -import { ProposalType } from "@types"; +import { + ProposalDiscussionFilterTypes, + ProposalType, + ProposedGovAction, +} from "@types"; const mockProposal = require("../../lib/_mock/proposal.json"); const mockPoll = require("../../lib/_mock/proposalPoll.json"); @@ -65,15 +69,41 @@ test.describe("Filter and sort proposals", () => { }); test("8B_2. Should sort the list of proposed governance actions.", async () => { - await proposalDiscussionPage.sortAndValidate( - "asc", - (p1, p2) => p1.attributes.createdAt <= p2.attributes.createdAt - ); - - await proposalDiscussionPage.sortAndValidate( - "desc", - (p1, p2) => p1.attributes.createdAt >= p2.attributes.createdAt - ); + const sortOptions = { + Oldest: (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.createdAt <= p2.attributes.createdAt, + Newest: (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.createdAt >= p2.attributes.createdAt, + "Most likes": (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.prop_likes >= p2.attributes.prop_likes, + "Least likes": (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.prop_likes <= p2.attributes.prop_likes, + "Most dislikes": (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.prop_dislikes >= p2.attributes.prop_dislikes, + "Least dislikes": (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.prop_dislikes <= p2.attributes.prop_dislikes, + "Most comments": (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.prop_comments_number >= + p2.attributes.prop_comments_number, + "Least comments": (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.prop_comments_number <= + p2.attributes.prop_comments_number, + "Name A-Z": (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.content.attributes.prop_name.localeCompare( + p2.attributes.content.attributes.prop_name + ) <= 0, + "Name Z-A": (p1: ProposedGovAction, p2: ProposedGovAction) => + p1.attributes.content.attributes.prop_name.localeCompare( + p2.attributes.content.attributes.prop_name + ) >= 0, + }; + + for (const [sortOption, sortFunction] of Object.entries(sortOptions)) { + await proposalDiscussionPage.sortAndValidate( + sortOption as ProposalDiscussionFilterTypes, + sortFunction + ); + } }); }); diff --git a/tests/govtool-frontend/playwright/tests/dRep.auth.setup.ts b/tests/govtool-frontend/playwright/tests/dRep.auth.setup.ts index f1593d593..a5e22ad69 100644 --- a/tests/govtool-frontend/playwright/tests/dRep.auth.setup.ts +++ b/tests/govtool-frontend/playwright/tests/dRep.auth.setup.ts @@ -3,12 +3,10 @@ import { dRep01Wallet, dRep02Wallet } from "@constants/staticWallets"; import { test as setup } from "@fixtures/walletExtension"; import { setAllureEpic, setAllureStory } from "@helpers/allure"; import { createAuth } from "@helpers/auth"; -import { skipIfMainnet } from "@helpers/cardano"; setup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Authentication"); - await skipIfMainnet(); }); const drepAuthConfigs = [ diff --git a/tests/govtool-frontend/playwright/tests/proposal-submission.ga.auth.setup.ts b/tests/govtool-frontend/playwright/tests/proposal-submission.ga.auth.setup.ts index 171a2c20f..e88d7690e 100644 --- a/tests/govtool-frontend/playwright/tests/proposal-submission.ga.auth.setup.ts +++ b/tests/govtool-frontend/playwright/tests/proposal-submission.ga.auth.setup.ts @@ -3,10 +3,12 @@ import { test as setup } from "@fixtures/walletExtension"; import { createAuthWithUserName } from "@helpers/auth"; import walletManager from "lib/walletManager"; import { proposalSubmissionAuthFile } from "@constants/auth"; +import { skipIfMainnet } from "@helpers/cardano"; setup.beforeEach(async () => { await setAllureEpic("Setup"); await setAllureStory("Authentication"); + await skipIfMainnet(); }); setup( diff --git a/tests/govtool-frontend/playwright/tests/proposal.setup.ts b/tests/govtool-frontend/playwright/tests/proposal.setup.ts index 5087fd136..36ec41f0e 100644 --- a/tests/govtool-frontend/playwright/tests/proposal.setup.ts +++ b/tests/govtool-frontend/playwright/tests/proposal.setup.ts @@ -1,13 +1,14 @@ import environments from "@constants/environments"; import { setAllureEpic, setAllureStory } from "@helpers/allure"; import { skipIfBalanceIsInsufficient, skipIfMainnet } from "@helpers/cardano"; -import { generateWallets } from "@helpers/shellyWallet"; +import { addressBech32, generateWallets } from "@helpers/shellyWallet"; import { pollTransaction } from "@helpers/transaction"; import { test as setup } from "@fixtures/walletExtension"; import kuberService from "@services/kuberService"; import walletManager from "lib/walletManager"; import { functionWaitedAssert } from "@helpers/waitedLoop"; import { getWalletConfigForFaucet } from "@helpers/index"; +import { createKeyFromPrivateKeyHex } from "@helpers/crypto"; const PROPOSAL_WALLETS_COUNT = environments.isScheduled ? 1 : 5; @@ -33,20 +34,38 @@ setup.beforeEach(async () => { }); setup("Setup temporary proposal wallets", async () => { - setup.setTimeout(2 * environments.txTimeOut); + setup.setTimeout(environments.txTimeOut); const proposalWallets = await generateWallets(PROPOSAL_WALLETS_COUNT); - - // initialize wallets - const initializeRes = await kuberService.initializeWallets( - [...proposalWallets], - getWalletConfigForFaucet().address, - getWalletConfigForFaucet().payment.private + const stakeKeys = await createKeyFromPrivateKeyHex( + environments.faucet.stake.private || "" ); - await pollTransaction(initializeRes.txId, initializeRes.lockInfo); + const { pkh: stakePkh, public: stakePublic } = stakeKeys.json(); + + const enrichedProposalWallets = proposalWallets.map((wallet) => { + const stake = { + pkh: stakePkh, + private: environments.faucet.stake.private, + public: stakePublic, + }; + + const walletAddress = addressBech32( + environments.networkId, + wallet.payment.pkh, + stakePkh + ); + + return { + ...wallet, + address: walletAddress, + stake, + }; + }); + + proposalWallets.splice(0, proposalWallets.length, ...enrichedProposalWallets); const amountOutputs = proposalWallets.map((wallet) => { - return { address: wallet.address, value: govActionDeposit }; + return { address: wallet.address, value: govActionDeposit + 22000000 }; }); const transferRes = await kuberService.multipleTransferADA( amountOutputs,