From f609a67dea46e9cccc94eea52c5a6d02b3485390 Mon Sep 17 00:00:00 2001 From: Niraj Date: Fri, 30 May 2025 20:05:42 +0545 Subject: [PATCH 1/5] chore: split out generate-address from crypto --- .../playwright/lib/helpers/crypto.ts | 24 +++++++------- .../playwright/lib/helpers/shellyWallet.ts | 32 +++++++++++++++++++ 2 files changed, 44 insertions(+), 12 deletions(-) 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 }, () => From e0f016197e5d9c093d3aee172e6fac58259bce78 Mon Sep 17 00:00:00 2001 From: Niraj Date: Fri, 30 May 2025 20:08:05 +0545 Subject: [PATCH 2/5] chore: update stake and address on propsal wallet setup --- .../playwright/tests/proposal.setup.ts | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) 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, From fc139c5931b33ec813da5154df86363929bbe2e0 Mon Sep 17 00:00:00 2001 From: Niraj Date: Fri, 30 May 2025 20:08:30 +0545 Subject: [PATCH 3/5] refactor: remove redundant stake key creation in proposal submission tests --- .../proposalSubmission.ga.spec.ts | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) 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..a6a266581 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); From 7a9f768b227c10808d5e0593a33e48550a87fce2 Mon Sep 17 00:00:00 2001 From: Niraj Date: Fri, 30 May 2025 20:09:55 +0545 Subject: [PATCH 4/5] fix: Check if the input field is set; otherwise, skip the process on auth. --- .../playwright/lib/helpers/auth.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) 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 }); } From 8e464f327d9b5b51da77a82f0b21d38219a4888c Mon Sep 17 00:00:00 2001 From: Niraj Date: Fri, 30 May 2025 20:33:21 +0545 Subject: [PATCH 5/5] chore: update @cardanoapi/cardano-test-wallet to version 3.3.2 --- tests/govtool-frontend/playwright/package-lock.json | 8 ++++---- tests/govtool-frontend/playwright/package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) 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",