Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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