diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b16353ba..109302a79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ changes. ### Removed +- Remove additional canonicalization of the metadata [Issue 3591](https://github.com/IntersectMBO/govtool/issues/3591) + ## [v2.0.20](https://github.com/IntersectMBO/govtool/releases/tag/v2.0.20) 2025-04-16 ### Added diff --git a/gov-action-loader/README.md b/gov-action-loader/README.md new file mode 100644 index 000000000..0f851daf2 --- /dev/null +++ b/gov-action-loader/README.md @@ -0,0 +1,14 @@ +# Governance Action Loader + +This directory contains the platform for submitting governance action data transactions on-chain, supporting both individual and bulk submission methods. + +## šŸ“ Navigation + +- [Frontend](./frontend/) +- [Backend](./backend/) + +## Frontend +The Governance Action Loader frontend is a web application that communicates with the backend via a REST interface to facilitate the submission of on-chain governance data transactions. + +## Backend +The Governance Action Loader backend uses a predefined wallet to execute transactions for on-chain governance data. \ No newline at end of file diff --git a/govtool/frontend/package-lock.json b/govtool/frontend/package-lock.json index 435748478..5c4c47863 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": "1.4.1", "@intersect.mbo/intersectmbo.org-icons-set": "^1.0.8", - "@intersect.mbo/pdf-ui": "0.7.0-beta-25", + "@intersect.mbo/pdf-ui": "0.7.0-beta-26", "@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-25", - "resolved": "https://registry.npmjs.org/@intersect.mbo/pdf-ui/-/pdf-ui-0.7.0-beta-25.tgz", - "integrity": "sha512-TDeWjJVMvLOR6sgTT6bCoHspZbybiRH0C5OzDDaU1yLSFD7xKx1aW5eAVdG0uzxrO+C0X7ceBGFoN5ucHICdlg==", + "version": "0.7.0-beta-26", + "resolved": "https://registry.npmjs.org/@intersect.mbo/pdf-ui/-/pdf-ui-0.7.0-beta-26.tgz", + "integrity": "sha512-05HR82ZKpJzitH7MgdNEdGr/Rc9A8PNPfPF5bX/z4We2y+iSi5kEoZdflpaUUWG3fFDwiaQCKe2xMiNwbGMOIQ==", "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 c02cfeab5..e9ccec72c 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": "1.4.1", "@intersect.mbo/intersectmbo.org-icons-set": "^1.0.8", - "@intersect.mbo/pdf-ui": "0.7.0-beta-25", + "@intersect.mbo/pdf-ui": "0.7.0-beta-26", "@mui/icons-material": "^5.14.3", "@mui/material": "^5.14.4", "@rollup/plugin-babel": "^6.0.4", diff --git a/govtool/frontend/yarn.lock b/govtool/frontend/yarn.lock index 03cd99721..50798a422 100644 --- a/govtool/frontend/yarn.lock +++ b/govtool/frontend/yarn.lock @@ -1512,10 +1512,10 @@ resolved "https://registry.npmjs.org/@intersect.mbo/intersectmbo.org-icons-set/-/intersectmbo.org-icons-set-1.1.0.tgz" integrity sha512-sjKEtnK9eLYH/8kCD0YRQCms3byFA/tnSsei9NHTZbBYX9sBpeX6ErfR0sKYjOSxQOxl4FumX9D0X+vHIqxo8g== -"@intersect.mbo/pdf-ui@0.7.0-beta-25": - version "0.7.0-beta-25" - resolved "https://registry.npmjs.org/@intersect.mbo/pdf-ui/-/pdf-ui-0.7.0-beta-25.tgz" - integrity sha512-TDeWjJVMvLOR6sgTT6bCoHspZbybiRH0C5OzDDaU1yLSFD7xKx1aW5eAVdG0uzxrO+C0X7ceBGFoN5ucHICdlg== +"@intersect.mbo/pdf-ui@0.7.0-beta-26": + version "0.7.0-beta-26" + resolved "https://registry.npmjs.org/@intersect.mbo/pdf-ui/-/pdf-ui-0.7.0-beta-26.tgz" + integrity sha512-05HR82ZKpJzitH7MgdNEdGr/Rc9A8PNPfPF5bX/z4We2y+iSi5kEoZdflpaUUWG3fFDwiaQCKe2xMiNwbGMOIQ== dependencies: "@emurgo/cardano-serialization-lib-asmjs" "^12.0.0-beta.2" "@fontsource/poppins" "^5.0.14" diff --git a/govtool/metadata-validation/Dockerfile b/govtool/metadata-validation/Dockerfile index 4e203f44f..d5875cfe5 100644 --- a/govtool/metadata-validation/Dockerfile +++ b/govtool/metadata-validation/Dockerfile @@ -7,13 +7,13 @@ WORKDIR /dist COPY package*.json ./ -RUN yarn +RUN npm install COPY . /dist -RUN yarn build +RUN npm run build ENV IPFS_GATEWAY=$IPFS_GATEWAY ENV IPFS_PROJECT_ID=$IPFS_PROJECT_ID -ENTRYPOINT ["/bin/sh", "-c", "yarn start:prod"] \ No newline at end of file +ENTRYPOINT ["/bin/sh", "-c", "npm run start:prod"] \ No newline at end of file diff --git a/govtool/metadata-validation/src/app.service.ts b/govtool/metadata-validation/src/app.service.ts index cfb1bb0d0..449a716e9 100644 --- a/govtool/metadata-validation/src/app.service.ts +++ b/govtool/metadata-validation/src/app.service.ts @@ -2,7 +2,6 @@ import { Injectable, Logger } from '@nestjs/common'; import { catchError, finalize, firstValueFrom } from 'rxjs'; import { HttpService } from '@nestjs/axios'; import * as blake from 'blakejs'; -import * as jsonld from 'jsonld'; import { ValidateMetadataDTO } from '@dto'; import { LoggerMessage, MetadataValidationStatus } from '@enums'; @@ -81,29 +80,7 @@ export class AppService { const hashedMetadata = blake.blake2bHex(rawData, undefined, 32); if (hashedMetadata !== hash) { - // Optionally validate on a parsed metadata - const hashedParsedMetadata = blake.blake2bHex( - JSON.stringify(parsedData, null, 2), - undefined, - 32, - ); - if (hashedParsedMetadata !== hash) { - // Optional support for the canonized data hash - // Validate canonized data hash - const canonizedMetadata = await jsonld.canonize(JSON.parse(rawData), { - safe: false, - }); - - const hashedCanonizedMetadata = blake.blake2bHex( - canonizedMetadata, - undefined, - 32, - ); - - if (hashedCanonizedMetadata !== hash) { - throw MetadataValidationStatus.INVALID_HASH; - } - } + throw MetadataValidationStatus.INVALID_HASH; } } catch (error) { Logger.error(LoggerMessage.METADATA_VALIDATION_ERROR, error); diff --git a/tests/govtool-frontend/playwright/.env.example b/tests/govtool-frontend/playwright/.env.example index d233f6b20..18caf343a 100644 --- a/tests/govtool-frontend/playwright/.env.example +++ b/tests/govtool-frontend/playwright/.env.example @@ -1,6 +1,6 @@ HOST_URL=http://localhost:3000 -DOCS_URL=https://docs.gov.tools +DOCS_URL=https://docs.gov.tools/cardano-govtool #Blockfrost BLOCKFROST_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXX @@ -12,7 +12,9 @@ KUBER_API_KEY= TX_TIMEOUT=240000 # milliseconds # Metadata Bucket -METADATA_BUCKET_URL=https://metadata-govtool.cardanoapi.io +CARDANOAPI_METADATA_URL=https://metadata-govtool.cardanoapi.io + +NETWORK=preview FAUCET_ADDRESS= FAUCET_PAYMENT_PRIVATE= diff --git a/tests/govtool-frontend/playwright/README.md b/tests/govtool-frontend/playwright/README.md index 567219012..3dea35622 100644 --- a/tests/govtool-frontend/playwright/README.md +++ b/tests/govtool-frontend/playwright/README.md @@ -51,13 +51,13 @@ npx playwright install ### HOST URL -| Environment | URL | -| :---------- | :----------------------------------------------------------------------------------------------------------------------- | -| Development | [https://p80-z78acf3c2-zded6a792-gtw.z937eb260.rustrocks.fr](https://p80-z78acf3c2-zded6a792-gtw.z937eb260.rustrocks.fr) | -| QA | [https://govtool.cardanoapi.io](https://govtool.cardanoapi.io) | -| Preview | [https://preview.gov.tools](https://preview.gov.tools) | -| Pre-Prod | [https://pre-prod.gov.tools](https://pre-prod.gov.tools) | -| Mainnet | [https://gov.tools](https://gov.tools) | +| Environment | URL | Network | +| :---------- | :----------------------------------------------------------------------------------------------------------------------- | :------ | +| Development | [https://p80-z78acf3c2-zded6a792-gtw.z937eb260.rustrocks.fr](https://p80-z78acf3c2-zded6a792-gtw.z937eb260.rustrocks.fr) | Preview | +| QA | [https://govtool.cardanoapi.io](https://govtool.cardanoapi.io) | Preview | +| Preview | [https://preview.gov.tools](https://preview.gov.tools) | Preview | +| Pre-Prod | [https://pre-prod.gov.tools](https://pre-prod.gov.tools) | Preprod | +| Mainnet | [https://gov.tools](https://gov.tools) | Mainnet | --- @@ -66,16 +66,21 @@ npx playwright install ### Blockfrost API Key - To generate a Blockfrost API key (Project ID): - 1. Follow the instructions in the [Blockfrost documentation](https://blockfrost.dev/overview/getting-started). + + 1. Follow the instructions in the [Blockfrost documentation](https://blockfrost.dev/overview/getting-started) šŸ“š. 2. The **Project ID** you create there serves as your **Blockfrost API Key**. + 3. Copy the **Project ID** and set it as `BLOCKFROST_API_KEY`. + + šŸ” Note: Ensure you select the correct network for the **Project ID** that matches the host URL from the environment listed above. ### Kuber API Key - To generate a Kuber API Key: - 1. Visit [Kuberide](https://kuberide.com/). + 1. Visit [Kuberide](https://kuberide.com/) 🌐. 2. Log in using your Google or GitHub account. - 3. Navigate to **API Keys**. - 4. Click to **Generate API Key**. + 3. Navigate to **API Keys** āš™ļø. + 4. Click to **Generate API Key** ✨. + 5. Copy the API key and set it as `KUBER_API_KEY` --- @@ -127,15 +132,26 @@ FAUCET_ADDRESS= ### Step 3: Fund the Wallet -Ensure the wallet address has sufficient funds for your test runs. The required balance depends on the specific tests you plan to execute (refer to the test-specific test run details below). +Ensure your wallet has enough funds for your test runs. The required balance depends on the specific tests you plan to execute (see test-specific details below). + +To fund your wallet on the **Preview** or **Preprod** network: + +1. Use the Cardano Testnet Faucet: + [https://docs.cardano.org/cardano-testnets/tools/faucet](https://docs.cardano.org/cardano-testnets/tools/faucet) 🌐 + **Note**: There is a daily limit of **10,000 ADA** per wallet. + +2. If the funded amount is insufficient, transfer additional ADA from another wallet. šŸ’ø + +To check your wallet balance: -To check the wallet balance, visit: +Visit: ``` https://${network}.cardanoscan.io/address/ ``` -Replace `${network}` with the appropriate Cardano network (e.g.`preprod`, or `preview`) and `` with the generated address. +- Replace `${network}` with the appropriate network (e.g., `preprod` or `preview`). +- Replace `` with your wallet address. šŸ” **Example**: diff --git a/tests/govtool-frontend/playwright/generate_faucet_wallet.ts b/tests/govtool-frontend/playwright/generate_faucet_wallet.ts index f29d3bab5..c61b1137b 100644 --- a/tests/govtool-frontend/playwright/generate_faucet_wallet.ts +++ b/tests/govtool-frontend/playwright/generate_faucet_wallet.ts @@ -10,7 +10,7 @@ import { ShelleyWallet } from "./lib/helpers/crypto"; console.log("\nšŸŽ‰ Wallet generated successfully!"); console.log("-----------------------------------"); console.log("šŸ’¼ Wallet:", walletJson); - console.log(`šŸ”‘ Payment Private Key: ${walletJson.payment.private}`); + console.log(`\nšŸ”‘ Payment Private Key: ${walletJson.payment.private}`); console.log(`šŸ”— Stake Public Key Hash: ${walletJson.stake.pkh}`); console.log(`šŸ  Wallet Address: ${walletJson.address}`); console.log("-----------------------------------"); diff --git a/tests/govtool-frontend/playwright/lib/constants/auth.ts b/tests/govtool-frontend/playwright/lib/constants/auth.ts index e2d85b948..b853b7c2b 100644 --- a/tests/govtool-frontend/playwright/lib/constants/auth.ts +++ b/tests/govtool-frontend/playwright/lib/constants/auth.ts @@ -25,3 +25,4 @@ export const budgetProposal01AuthFile = ".auth/budgetProposal01.json"; export const budgetProposal02AuthFile = ".auth/budgetProposal02.json"; export const budgetProposal03AuthFile = ".auth/budgetProposal03.json"; export const budgetProposal04AuthFile = ".auth/budgetProposal04.json"; +export const budgetProposal05AuthFile = ".auth/budgetProposal05.json"; diff --git a/tests/govtool-frontend/playwright/lib/constants/staticWallets.ts b/tests/govtool-frontend/playwright/lib/constants/staticWallets.ts index 529551a51..396685bac 100644 --- a/tests/govtool-frontend/playwright/lib/constants/staticWallets.ts +++ b/tests/govtool-frontend/playwright/lib/constants/staticWallets.ts @@ -30,6 +30,7 @@ export const budgetProposal01Wallet: StaticWallet = staticWallets[19]; export const budgetProposal02Wallet: StaticWallet = staticWallets[20]; export const budgetProposal03Wallet: StaticWallet = staticWallets[21]; export const budgetProposal04Wallet: StaticWallet = staticWallets[22]; +export const budgetProposal05Wallet: StaticWallet = staticWallets[23]; export const adaHolderWallets = [ adaHolder01Wallet, diff --git a/tests/govtool-frontend/playwright/lib/forms/dRepForm.ts b/tests/govtool-frontend/playwright/lib/forms/dRepForm.ts index 86a644de1..b036726d8 100644 --- a/tests/govtool-frontend/playwright/lib/forms/dRepForm.ts +++ b/tests/govtool-frontend/playwright/lib/forms/dRepForm.ts @@ -13,6 +13,7 @@ const formErrors = { ], linkDescription: "max-80-characters-error", email: "invalid-email-address-error", + image: "invalid-image-url-error", links: { url: "link-reference-description-1-error", description: "link-reference-description-1-error", @@ -59,6 +60,9 @@ export default class DRepForm { readonly motivationsInput = this.form.getByTestId("motivations-input"); readonly qualificationsInput = this.form.getByTestId("qualifications-input"); readonly paymentAddressInput = this.form.getByTestId("payment-address-input"); + readonly imageInput = this.form.locator( + "div:nth-child(4) > div:nth-child(2) > input" + ); // BUG missing test id readonly doNotListCheckBox = this.form.getByRole("checkbox"); constructor(private readonly form: Page) {} @@ -149,6 +153,7 @@ export default class DRepForm { await this.motivationsInput.fill(dRepInfo.motivations); await this.qualificationsInput.fill(dRepInfo.qualifications); await this.paymentAddressInput.fill(dRepInfo.paymentAddress); + await this.imageInput.fill(dRepInfo.image); await this.linkRefrenceFirstUrlInput.fill( dRepInfo.linksReferenceLinks[0].url ); @@ -175,6 +180,9 @@ export default class DRepForm { const motivationsInputText = await this.motivationsInput.textContent(); const qualificationsInputText = await this.qualificationsInput.textContent(); + const isImageErrorVisible = await this.form + .getByTestId(formErrors.image) + .isVisible(); const isReferenceLinkErrorVisible = await this.form .getByTestId(formErrors.links.url) .isVisible(); @@ -202,6 +210,10 @@ export default class DRepForm { `${dRepInfo.qualifications} is not equal to ${qualificationsInputText}`, }).toEqual(dRepInfo.qualifications); + await expect(this.form.getByTestId(formErrors.image), { + message: isImageErrorVisible && `${dRepInfo.image} is an invalid image`, + }).toBeHidden(); + await expect(this.form.getByTestId(formErrors.links.url), { message: isReferenceLinkErrorVisible && @@ -246,6 +258,9 @@ export default class DRepForm { const motivationsInputText = await this.motivationsInput.textContent(); const qualificationsInputText = await this.qualificationsInput.textContent(); + const isImageErrorVisible = await this.form + .getByTestId(formErrors.image) + .isVisible(); const isReferenceLinkErrorVisible = await this.form .getByTestId(formErrors.links.url) .isVisible(); @@ -284,6 +299,12 @@ export default class DRepForm { `${dRepInfo.qualifications} is equal to ${qualificationsInputText}`, }).not.toEqual(dRepInfo.qualifications); + await expect(this.form.getByTestId(formErrors.image), { + message: !isImageErrorVisible && `${dRepInfo.image} is a valid image`, + }).toBeVisible({ + timeout: 60_000, + }); + await expect(this.form.getByTestId(formErrors.links.url), { message: !isReferenceLinkErrorVisible && diff --git a/tests/govtool-frontend/playwright/lib/helpers/dRep.ts b/tests/govtool-frontend/playwright/lib/helpers/dRep.ts index 8572e217f..262429552 100644 --- a/tests/govtool-frontend/playwright/lib/helpers/dRep.ts +++ b/tests/govtool-frontend/playwright/lib/helpers/dRep.ts @@ -1,10 +1,14 @@ import DRepDirectoryPage from "@pages/dRepDirectoryPage"; import { expect, Page } from "@playwright/test"; -import { IDRep } from "@types"; +import { IDRep, IDRepInfo } from "@types"; import { bech32 } from "bech32"; import * as crypto from "crypto"; import { functionWaitedAssert } from "./waitedLoop"; -import { invalid as mockInvalid, valid as mockValid } from "@mock/index"; +import { + invalid, + invalid as mockInvalid, + valid as mockValid, +} from "@mock/index"; import { faker } from "@faker-js/faker"; import { ShelleyWallet } from "./crypto"; import environments from "@constants/environments"; @@ -131,7 +135,7 @@ export function convertDRep( return { cip129: cip129DRep, cip105: cip105DRep }; } -export async function generateValidDRepInfo() { +export async function generateValidDRepInfo(): Promise { return { name: mockValid.name(), objectives: faker.lorem.paragraph(2), @@ -140,6 +144,7 @@ export async function generateValidDRepInfo() { paymentAddress: (await ShelleyWallet.generate()).addressBech32( environments.networkId ), + image: faker.image.avatarGitHub(), linksReferenceLinks: [ { url: faker.internet.url(), @@ -155,13 +160,14 @@ export async function generateValidDRepInfo() { }; } -export function generateInvalidDRepInfo() { +export function generateInvalidDRepInfo(): IDRepInfo { return { name: mockInvalid.name(), objectives: faker.lorem.paragraph(40), motivations: faker.lorem.paragraph(40), qualifications: faker.lorem.paragraph(40), paymentAddress: faker.string.alphanumeric(45), + image: invalid.url(), linksReferenceLinks: [ { url: mockInvalid.url(), diff --git a/tests/govtool-frontend/playwright/lib/pages/budgetDiscussionDetailsPage.ts b/tests/govtool-frontend/playwright/lib/pages/budgetDiscussionDetailsPage.ts index babcc07bb..7b578deb4 100644 --- a/tests/govtool-frontend/playwright/lib/pages/budgetDiscussionDetailsPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/budgetDiscussionDetailsPage.ts @@ -19,6 +19,7 @@ export default class BudgetDiscussionDetailsPage { ); readonly verifyIdentityBtn = this.page.getByTestId("verify-identity-button"); readonly readMoreBtn = this.page.getByTestId("read-more-button"); + readonly menuButton = this.page.getByTestId("menu-button"); // content readonly copyLinkText = this.page.getByTestId("copy-link-text"); @@ -139,7 +140,7 @@ export default class BudgetDiscussionDetailsPage { async deleteProposal() { await this.page.waitForTimeout(2_000); - await this.page.getByTestId("menu-button").click(); + await this.menuButton.click(); await this.page.getByTestId("delete-proposal").click(); await this.page.getByTestId("delete-proposal-yes-button").click(); } diff --git a/tests/govtool-frontend/playwright/lib/pages/budgetDiscussionPage.ts b/tests/govtool-frontend/playwright/lib/pages/budgetDiscussionPage.ts index 0d6264e8a..3ca0fa9db 100644 --- a/tests/govtool-frontend/playwright/lib/pages/budgetDiscussionPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/budgetDiscussionPage.ts @@ -13,6 +13,9 @@ export default class BudgetDiscussionPage { readonly verifyIdentityBtn = this.page.getByTestId("verify-identity-button"); readonly filterBtn = this.page.getByTestId("filter-button"); readonly sortBtn = this.page.getByTestId("sort-button"); + readonly myProposalBtn = this.page.getByTestId( + "My Proposals-owner-filter-option" + ); // input readonly searchInput = this.page.getByTestId("search-input"); @@ -49,7 +52,10 @@ export default class BudgetDiscussionPage { }); const proposalCards = await this.page.locator(proposalCardSelector).all(); - expect(true, "No budget proposals found.").toBeTruthy(); + expect( + true, + proposalCards.length === 0 && "No budget proposals found." + ).toBeTruthy(); return proposalCards; } diff --git a/tests/govtool-frontend/playwright/lib/types.ts b/tests/govtool-frontend/playwright/lib/types.ts index 2ea7c02a6..b336993e8 100644 --- a/tests/govtool-frontend/playwright/lib/types.ts +++ b/tests/govtool-frontend/playwright/lib/types.ts @@ -66,6 +66,7 @@ export type IDRepInfo = { objectives?: string; motivations?: string; qualifications?: string; + image?: string; paymentAddress?: string; identityReferenceLinks?: LinkType[]; linksReferenceLinks?: LinkType[]; diff --git a/tests/govtool-frontend/playwright/package.json b/tests/govtool-frontend/playwright/package.json index 62bdac42d..b0127afe7 100644 --- a/tests/govtool-frontend/playwright/package.json +++ b/tests/govtool-frontend/playwright/package.json @@ -44,7 +44,7 @@ "test:headless:usersnap": "npx playwright test userSnap.spec.ts", "test:headless:misc": "npx playwright test miscellaneous", "format": "prettier . --write", - "generate-wallets": "ts-node ./generate_wallets.ts 23", + "generate-wallets": "ts-node ./generate_wallets.ts 24", "generate-faucet-wallet": "ts-node ./generate_faucet_wallet.ts" }, "dependencies": { 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 a2c320b8f..ce5863062 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 @@ -3,18 +3,21 @@ import { budgetProposal02AuthFile, budgetProposal03AuthFile, budgetProposal04AuthFile, + budgetProposal05AuthFile, } from "@constants/auth"; import { budgetProposal01Wallet, budgetProposal02Wallet, budgetProposal03Wallet, budgetProposal04Wallet, + budgetProposal05Wallet, } from "@constants/staticWallets"; import { faker } from "@faker-js/faker"; import { test } from "@fixtures/budgetProposal"; import { setAllureEpic } from "@helpers/allure"; import { createNewPageWithWallet } from "@helpers/page"; import BudgetDiscussionDetailsPage from "@pages/budgetDiscussionDetailsPage"; +import BudgetDiscussionPage from "@pages/budgetDiscussionPage"; import BudgetDiscussionSubmissionPage from "@pages/budgetDiscussionSubmissionPage"; import { expect } from "@playwright/test"; import { @@ -305,7 +308,7 @@ test.describe("Budget proposal 01 wallet", () => { await budgetProposalSubmissionPage.currentPage .getByTestId(`${contractingType}-button`) .click(); - if (contractingType === "Other") { + if (contractingType === "other") { await budgetProposalSubmissionPage.otherDescriptionInput.fill( faker.lorem.paragraph(2) ); @@ -510,3 +513,36 @@ test("12I. Should submit a valid draft budget proposal", async ({ await budgetDiscussionDetailsPage.deleteProposal(); }); + +test("12J. Should verify created proposal appears in my proposals list", async ({ + browser, +}) => { + test.slow(); + const page = await createNewPageWithWallet(browser, { + storageState: budgetProposal05AuthFile, + wallet: budgetProposal05Wallet, + }); + + const budgetSubmissionPage = new BudgetDiscussionSubmissionPage(page); + await budgetSubmissionPage.goto(); + const { proposalDetails } = await budgetSubmissionPage.createBudgetProposal(); + const budgetDiscussionPage = new BudgetDiscussionPage(page); + await budgetDiscussionPage.goto(); + + await budgetDiscussionPage.filterBtn.click(); + await budgetDiscussionPage.myProposalBtn.click(); + + const proposalList = await budgetDiscussionPage.getAllProposals(); + + expect(proposalList.length).toBeGreaterThan(0); + + // Close the filter dropdown to ensure the proposals list is visible + await budgetDiscussionPage.sortBtn.click({ force: true }); + const budgetDiscussionDetailsPage = + await budgetDiscussionPage.viewFirstProposal(); + + await expect(budgetDiscussionDetailsPage.menuButton).toBeVisible(); + await budgetDiscussionDetailsPage.validateProposalDetails(proposalDetails); + + await budgetDiscussionDetailsPage.deleteProposal(); +}); diff --git a/tests/govtool-frontend/playwright/tests/proposal-budget.auth.setup.ts b/tests/govtool-frontend/playwright/tests/proposal-budget.auth.setup.ts index a4e24036b..6b0ab4ea8 100644 --- a/tests/govtool-frontend/playwright/tests/proposal-budget.auth.setup.ts +++ b/tests/govtool-frontend/playwright/tests/proposal-budget.auth.setup.ts @@ -3,6 +3,7 @@ import { budgetProposal02AuthFile, budgetProposal03AuthFile, budgetProposal04AuthFile, + budgetProposal05AuthFile, dRep03AuthFile, } from "@constants/auth"; import { @@ -10,6 +11,7 @@ import { budgetProposal02Wallet, budgetProposal03Wallet, budgetProposal04Wallet, + budgetProposal05Wallet, dRep03Wallet, } from "@constants/staticWallets"; import { test as setup } from "@fixtures/walletExtension"; @@ -42,6 +44,11 @@ const walletAuthPairs = [ auth: budgetProposal04AuthFile, name: "Budget Proposal 04", }, + { + wallet: budgetProposal05Wallet, + auth: budgetProposal05AuthFile, + name: "Budget Proposal 05", + }, ]; walletAuthPairs.forEach(({ wallet, auth, name }) => {