Skip to content

Commit

Permalink
Merge pull request #2970 from IntersectMBO/tests/constitution-type-pr…
Browse files Browse the repository at this point in the history
…oposal

Tests: constitution type proposal
  • Loading branch information
mesudip authored Feb 13, 2025
2 parents 624e32c + 96fcaf8 commit 16be6c9
Show file tree
Hide file tree
Showing 13 changed files with 248 additions and 37 deletions.
9 changes: 9 additions & 0 deletions tests/govtool-frontend/playwright/lib/_mock/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ export const invalid = {
return " ";
},

constitutionUrl: () => {
const choice = faker.number.int({ min: 1, max: 2 });
if (choice === 1) {
return invalid.url();
}
// empty invalid
return " ";
},

paragraph: (maxCharacter: number) => {
const choice = faker.number.int({ min: 1, max: 2 });
if (choice === 1) {
Expand Down
9 changes: 9 additions & 0 deletions tests/govtool-frontend/playwright/lib/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,12 @@ export const SECURITY_RELEVANT_PARAMS_MAP: Record<string, string> = {
govActionDeposit: "gov_action_deposit",
minFeeRefScriptCostPerByte: "min_fee_ref_script_cost_per_byte",
};

export const PROPOSAL_TYPE_FILTERS = [
"Info Action",
"Treasury requests",
"Updates to the Constitution",
];
export const BOOTSTRAP_PROPOSAL_TYPE_FILTERS = ["Info Action"];

export const PROPOSAL_STATUS_FILTER = ["Submitted for vote", "Active proposal"];
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const proposal04Wallet: StaticWallet = staticWallets[13];
export const proposal05Wallet: StaticWallet = staticWallets[14];
export const proposal06Wallet: StaticWallet = staticWallets[15];
export const proposal07Wallet: StaticWallet = staticWallets[16];
export const proposal08Wallet: StaticWallet = staticWallets[17];

export const adaHolderWallets = [
adaHolder01Wallet,
Expand All @@ -46,6 +47,7 @@ export const proposalWallets = [
proposal05Wallet,
proposal06Wallet,
proposal07Wallet,
proposal08Wallet,
];

export const allStaticWallets = [
Expand Down
4 changes: 2 additions & 2 deletions tests/govtool-frontend/playwright/lib/helpers/cardano.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ export async function isBootStrapingPhase() {
return protocolParameterMajorVersion === 9;
}

export async function skipIfTreasuryAndBootstrapping(type: ProposalType) {
export async function skipIfNotInfoAndBootstrapping(type: ProposalType) {
const isBootStraping = await isBootStrapingPhase();
if (type === ProposalType.treasury && isBootStraping) {
if (type !== ProposalType.info && isBootStraping) {
await allure.description(
"This Features will be available only after hardfork."
);
Expand Down
9 changes: 7 additions & 2 deletions tests/govtool-frontend/playwright/lib/helpers/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ export async function downloadMetadata(download: Download): Promise<{
return { name: download.suggestedFilename(), data: jsonData };
}

export function calculateHash(data: string) {
const buffer = Buffer.from(data, "utf8");
const hexDigest = blake.blake2bHex(buffer, null, 32);
return hexDigest;
}

async function calculateMetadataHash() {
try {
const paymentAddress = (await ShelleyWallet.generate()).addressBech32(
Expand All @@ -39,8 +45,7 @@ async function calculateMetadataHash() {
2
);

const buffer = Buffer.from(data, "utf8");
const hexDigest = blake.blake2bHex(buffer, null, 32);
const hexDigest = calculateHash(data);

const jsonData = JSON.parse(data);
return { hexDigest, jsonData };
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { faker } from "@faker-js/faker";
import { generateWalletAddress } from "@helpers/cardano";
import { extractProposalIdFromUrl } from "@helpers/string";
import { expect, Locator, Page } from "@playwright/test";
import { ProposalCreateRequest, ProposedGovAction } from "@types";
import environments from "lib/constants/environments";
import ProposalDiscussionDetailsPage from "./proposalDiscussionDetailsPage";
import { isMobile } from "@helpers/mobile";
import { PROPOSAL_TYPE_FILTERS } from "@constants/index";

export default class ProposalDiscussionPage {
// Buttons
Expand All @@ -19,8 +16,10 @@ export default class ProposalDiscussionPage {
readonly showAllBtn = this.page.getByTestId("show-all-button").first(); //this.page.getByTestId("show-all-button");
readonly verifyIdentityBtn = this.page.getByTestId("verify-identity-button");
readonly addLinkBtn = this.page.getByTestId("add-link-button");
readonly infoRadio = this.page.getByTestId("Info-radio-wrapper");
readonly treasuryRadio = this.page.getByTestId("Treasury-radio-wrapper");
readonly infoRadio = this.page.getByTestId("info action-radio-wrapper");
readonly treasuryRadio = this.page.getByTestId(
"treasury requests-radio-wrapper"
);
readonly activeProposalWrapper = this.page.getByTestId(
"active-proposal-radio-wrapper"
);
Expand Down Expand Up @@ -112,10 +111,10 @@ export default class ProposalDiscussionPage {

async clickRadioButtonsByNames(names: string[]) {
for (const name of names) {
const replaceSpaceWithUnderScore = name.toLowerCase().replace(/ /g, "-");
await this.page
.getByTestId(`${replaceSpaceWithUnderScore}-radio`)
.click();
const testId = PROPOSAL_TYPE_FILTERS.includes(name)
? name.toLowerCase()
: name.toLowerCase().replace(/ /g, "-");
await this.page.getByTestId(`${testId}-radio`).click();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { faker } from "@faker-js/faker";
import { isBootStrapingPhase } from "@helpers/cardano";
import { ShelleyWallet } from "@helpers/crypto";
import { expectWithInfo } from "@helpers/exceptionHandler";
import { downloadMetadata } from "@helpers/metadata";
import { calculateHash, downloadMetadata } from "@helpers/metadata";
import { extractProposalIdFromUrl } from "@helpers/string";
import { invalid } from "@mock/index";
import { Download, Locator, Page, expect } from "@playwright/test";
Expand All @@ -23,6 +23,8 @@ const formErrors = {
rationale: "rationale-helper-error",
receivingAddress: "receiving-address-0-text-error",
amount: "amount-0-text-error",
constitutionalUrl: "prop=constitution-url-text-error", // BUG wrong test id
guardrailsScriptUrl: "prop-guardrails-script-url-input-error",
link: "link-0-url-input-error",
};

Expand All @@ -47,8 +49,11 @@ export default class ProposalSubmissionPage {
readonly addWithdrawalAddressBtn = this.page.getByTestId(
"add-withdrawal-link-button"
);
readonly infoBtn = this.page.getByTestId("info-button");
readonly treasuryBtn = this.page.getByTestId("treasury-button");
readonly infoBtn = this.page.getByTestId("info action-button");
readonly treasuryBtn = this.page.getByTestId("treasury requests-button");
readonly updateTheConstitutionBtn = this.page.getByTestId(
"updates to the constitution-button"
);
readonly editSubmissionButton = this.page.getByTestId(
"edit-submission-button"
);
Expand All @@ -61,6 +66,9 @@ export default class ProposalSubmissionPage {
readonly createNewProposalBtn = this.page.getByTestId(
"create-new-proposal-button"
);
readonly guardrailsScriptCheckbox = this.page.getByLabel(
"Do you want to provide new"
); // BUG missing test id

// input fields
readonly titleInput = this.page.getByTestId("title-input");
Expand All @@ -72,6 +80,15 @@ export default class ProposalSubmissionPage {
"receiving-address-0-text-input"
);
readonly amountInput = this.page.getByTestId("amount-0-text-input");
readonly constitutionUrlInput = this.page.getByTestId(
"prop_constitution_url"
);
readonly guardrailsScriptUrlInput = this.page.getByTestId(
"prop-guardrails-script-url-input"
);
readonly guardrailsScriptHashInput = this.page.getByTestId(
"prop-guardrails-script-hash-input"
);
readonly closeDraftSuccessModalBtn = this.page.getByTestId("close-button");
readonly linkTextInput = this.page.getByTestId("link-0-text-input");
readonly linkUrlInput = this.page.getByTestId("link-0-url-input");
Expand All @@ -88,6 +105,15 @@ export default class ProposalSubmissionPage {
"receiving-address-0-content"
);
readonly amountContent = this.page.getByTestId("amount-0-content");
readonly constitutionUrlContent = this.page.getByTestId(
"new-constitution-url-content"
);
readonly guardrailsScriptUrlContent = this.page.getByTestId(
"guardrails-script-url-content"
);
readonly guardrailsScriptHashContent = this.page.getByTestId(
"guardrails-script-hash-content"
);
readonly linkTextContent = this.page.getByTestId("link-0-text-content");
readonly linkUrlContent = this.page.getByTestId("link-0-url-content");

Expand Down Expand Up @@ -128,6 +154,10 @@ export default class ProposalSubmissionPage {
await this.fillTreasuryFields(governanceProposal);
}

if (governanceProposal.gov_action_type_id === 2) {
await this.fillUpdateTheConstitutionFields(governanceProposal);
}

if (governanceProposal.proposal_links != null) {
await this.fillProposalLinks(governanceProposal.proposal_links);
}
Expand All @@ -138,9 +168,13 @@ export default class ProposalSubmissionPage {

if (governanceProposal.gov_action_type_id === 0) {
await this.infoBtn.click();
} else {
} else if (governanceProposal.gov_action_type_id === 1) {
await this.treasuryBtn.click();
} else {
await this.updateTheConstitutionBtn.click();
await this.guardrailsScriptCheckbox.click();
}

await this.fillupFormWithTypeSelected(governanceProposal);
}

Expand All @@ -158,6 +192,21 @@ export default class ProposalSubmissionPage {
await this.amountInput.fill(governanceProposal.prop_amount);
}

async fillUpdateTheConstitutionFields(
governanceProposal: ProposalCreateRequest
) {
await this.constitutionUrlInput.fill(
governanceProposal.prop_constitution_url
);

await this.guardrailsScriptUrlInput.fill(
governanceProposal.prop_guardrails_script_url
);
await this.guardrailsScriptHashInput.fill(
governanceProposal.prop_guardrails_script_hash
);
}

async fillProposalLinks(proposal_links: Array<ProposalLink>) {
for (let i = 0; i < proposal_links.length; i++) {
if (i > 0) {
Expand Down Expand Up @@ -232,6 +281,16 @@ export default class ProposalSubmissionPage {
}
}

if (governanceProposal.gov_action_type_id === 2) {
await expect(
this.page.getByTestId(formErrors.constitutionalUrl)
).toBeHidden();

await expect(
this.page.getByTestId(formErrors.guardrailsScriptUrl)
).toBeHidden();
}

await expect(this.page.getByTestId(formErrors.link)).toBeHidden();

await expect(this.continueBtn).toBeEnabled();
Expand Down Expand Up @@ -286,6 +345,16 @@ export default class ProposalSubmissionPage {
await expect(this.page.getByTestId(formErrors.amount)).toBeVisible();
}

if (governanceProposal.gov_action_type_id === 2) {
await expect(
this.page.getByTestId(formErrors.constitutionalUrl)
).toBeVisible();

await expect(
this.page.getByTestId(formErrors.guardrailsScriptUrl)
).toBeVisible();
}

await expect(this.continueBtn).toBeDisabled();
}

Expand All @@ -306,7 +375,7 @@ export default class ProposalSubmissionPage {
prop_link_text: faker.internet.domainWord(),
},
],
gov_action_type_id: proposalType === ProposalType.info ? 0 : 1,
gov_action_type_id: Object.values(ProposalType).indexOf(proposalType),
is_draft: !!is_draft,
};

Expand All @@ -316,6 +385,13 @@ export default class ProposalSubmissionPage {
.int({ min: 100, max: 1000 })
.toString());
}
if (proposalType === ProposalType.updatesToTheConstitution) {
proposal.prop_constitution_url = faker.internet.url();
proposal.prop_guardrails_script_url = faker.internet.url();
proposal.prop_guardrails_script_hash = calculateHash(
faker.lorem.paragraph()
);
}
return proposal;
}

Expand All @@ -332,20 +408,28 @@ export default class ProposalSubmissionPage {
prop_link_text: invalid.name(),
},
],
gov_action_type_id: proposalType === ProposalType.info ? 0 : 1,
gov_action_type_id: Object.values(ProposalType).indexOf(proposalType),
is_draft: false,
};

if (proposalType === ProposalType.treasury) {
(proposal.prop_receiving_address = faker.location.streetAddress()),
(proposal.prop_amount = invalid.amount());
}

if (proposalType === ProposalType.updatesToTheConstitution) {
proposal.prop_constitution_url = invalid.constitutionUrl();
proposal.prop_guardrails_script_url = invalid.url();
proposal.prop_guardrails_script_hash = faker.string.alphanumeric(64);
}
return proposal;
}

async createProposal(
wallet: StaticWallet,
proposalType: ProposalType = ProposalType.treasury
proposalType: ProposalType = Object.values(ProposalType)[
Math.floor(Math.random() * Object.values(ProposalType).length)
]
): Promise<number> {
await this.addLinkBtn.click();
const receivingAddr = ShelleyWallet.fromJson(wallet).rewardAddressBech32(
Expand Down
8 changes: 6 additions & 2 deletions tests/govtool-frontend/playwright/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,9 @@ export type LinkType = {
};

export enum ProposalType {
info = "Info",
treasury = "Treasury",
info = "Info Action",
treasury = "Treasury requests",
updatesToTheConstitution = "Updates to the Constitution",
}

export enum BootstrapGovernanceActionType {
Expand Down Expand Up @@ -159,6 +160,9 @@ export type ProposalCreateRequest = {
prop_rationale: string;
prop_receiving_address?: string;
prop_amount?: string;
prop_constitution_url?: string;
prop_guardrails_script_url?: string;
prop_guardrails_script_hash?: string;
is_draft: boolean;
};

Expand Down
2 changes: 1 addition & 1 deletion tests/govtool-frontend/playwright/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"allure:serve": "npx allure serve",
"test": "npx playwright test",
"format": "prettier . --write",
"generate-wallets": "ts-node ./generate_wallets.ts 17"
"generate-wallets": "ts-node ./generate_wallets.ts 18"
},
"dependencies": {
"@cardanoapi/cardano-test-wallet": "^3.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ test("4A_2. Should access Governance Actions page without connecting wallet", as
await page.goto("/");
await page.getByTestId("move-to-governance-actions-button").click();

await expect(page.getByText(/Governance actions/i)).toHaveCount(2);
await expect(page.getByText(/Governance actions/i)).toHaveCount(1);
});

test("4B_2. Should restrict voting for users who are not registered as DReps (without wallet connected)", async ({
Expand Down
Loading

0 comments on commit 16be6c9

Please sign in to comment.