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
5 changes: 3 additions & 2 deletions govtool/frontend/src/components/molecules/VoteActionForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ export const VoteActionForm = ({
border: !showWholeVoteContext ? "1px solid #E1E1E1" : "none",
borderRadius: "4px",
backgroundColor: !showWholeVoteContext ? fadedPurple.c50 : "transparent",
padding: 2,
padding: 2
}}
>
<Typography
Expand All @@ -292,6 +292,7 @@ export const VoteActionForm = ({
WebkitLineClamp: 2,
}),
}}
data-testid="vote-rationale-context"
>
{finalVoteContextText}
</Typography>
Expand All @@ -316,7 +317,7 @@ export const VoteActionForm = ({
}}
disableRipple
variant="text"
data-testid="external-modal-button"
data-testid="show-more-button"
>
<Typography
variant="body2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,15 @@ export const VoteContextChoice = ({
variant="outlined"
onClick={handleLetGovToolStore}
sx={{ width: isMobile ? "100%" : "259px", whiteSpace: "nowrap", height: "48px", fontWeight: "500" }}
data-testid="govtool-pins-data-to-ipfs-option-button"
>
{t("createGovernanceAction.govToolPinsDataToIPFS")}
</Button>
<Button
variant="outlined"
onClick={handleStoreItMyself}
sx={{ width: isMobile ? "100%" : "287px", whiteSpace: "nowrap", height: "48px", fontWeight: "500" }}
data-testid="download-and-store-yourself-option-button"
>
{t("createGovernanceAction.downloadAndStoreYourself")}
</Button>
Expand Down
5 changes: 3 additions & 2 deletions tests/govtool-frontend/playwright/lib/helpers/waitedLoop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export async function waitedLoop(
const startTime = Date.now();
while (Date.now() - startTime < timeout) {
if (await conditionFn()) return true;
Logger.info("Retring the function");
Logger.info("Retrying the function");
await new Promise((resolve) => setTimeout(resolve, interval));
}
return false;
Expand All @@ -36,9 +36,10 @@ export async function functionWaitedAssert(
} catch (error) {
if (Date.now() - startTime >= timeout) {
const errorMessage = options.message || error.message;
console.log(errorMessage);
expect(false, { message: errorMessage }).toBe(true);
}
Logger.info(`Retring the function ${name}`);
Logger.info(`Retrying the function ${name}`);
await new Promise((resolve) => setTimeout(resolve, interval));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export default class GovernanceActionDetailsPage {
readonly externalModalBtn = this.page.getByTestId("external-modal-button");
readonly governanceActionId = this.page.getByText("Governance Action ID:");

readonly contextBtn = this.page.getByTestId("provide-context-button");
readonly metadataDownloadBtn = this.page.getByTestId(
"metadata-download-button"
);
Expand All @@ -31,6 +30,9 @@ export default class GovernanceActionDetailsPage {
readonly continueModalBtn = this.page.getByTestId("continue-modal-button");
readonly confirmModalBtn = this.page.getByTestId("confirm-modal-button");

readonly downloadAndStoreYourselfOptionBtn = this.page.getByTestId("download-and-store-yourself-option-button")
readonly govtoolPinsDatatoIpfsBtn = this.page.getByTestId("govtool-pins-data-to-ipfs-option-button")

readonly voteSuccessModal = this.page.getByTestId("alert-success");
readonly externalLinkModal = this.page.getByTestId("external-link-modal");

Expand Down Expand Up @@ -76,37 +78,41 @@ export default class GovernanceActionDetailsPage {
}

@withTxConfirmation
async vote(context?: string, isAlreadyVoted: boolean = false) {
async vote(context?: string, isAlreadyVoted: boolean = false , useIPFSforStorage : boolean = false ){
if (!isAlreadyVoted) {
await this.yesVoteRadio.click();
}

await this.voteBtn.click()

if (context) {
await this.contextBtn.click();
await this.contextInput.fill(context);
await this.confirmModalBtn.click();
await this.page.getByRole("checkbox").click();
await this.confirmModalBtn.click();

this.metadataDownloadBtn.click();
const voteMetadata = await this.downloadVoteMetadata();
const url = await metadataBucketService.uploadMetadata(
voteMetadata.name,
voteMetadata.data
);

await this.metadataUrlInput.fill(url);
this.confirmModalBtn.click()

if (useIPFSforStorage) {
await this.govtoolPinsDatatoIpfsBtn.click()
} else {

await this.downloadAndStoreYourselfOptionBtn.click()
await this.page.getByRole("checkbox").click();
await this.confirmModalBtn.click();

this.metadataDownloadBtn.click();
const voteMetadata = await this.downloadVoteMetadata();
const url = await metadataBucketService.uploadMetadata(
voteMetadata.name,
voteMetadata.data
);
await this.metadataUrlInput.fill(url);
}
await this.confirmModalBtn.click();
await this.page.getByTestId("go-to-vote-modal-button").click();
}

const isVoteButtonEnabled = await this.voteBtn.isEnabled();

await expect(this.voteBtn, {
message: !isVoteButtonEnabled && "Vote button is not enabled",
}).toBeEnabled({ timeout: 60_000 });

await this.voteBtn.click();
}
else {
await this.confirmModalBtn.click()
}
}

async getDRepNotVoted(
Expand Down Expand Up @@ -165,5 +171,6 @@ export default class GovernanceActionDetailsPage {
async reVote() {
await this.noVoteRadio.click();
await this.changeVoteBtn.click();
await this.confirmModalBtn.click();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ export default class GovernanceActionsPage {
async viewFirstProposalByGovernanceAction(
governanceAction: GovernanceActionType
): Promise<GovernanceActionDetailsPage> {
const proposalCard = this.page
.getByTestId(`govaction-${governanceAction}-card`)
.first();
const proposalCard = this.page
.locator('[data-testid^="govaction-"][data-testid$="-card"]')
.first();

const isVisible = await proposalCard.isVisible();

Expand All @@ -76,6 +76,20 @@ export default class GovernanceActionsPage {
}
}

async getFirstProposal(
) {
await functionWaitedAssert(
async () => {
const proposalCard = this.page
.locator('[data-testid^="govaction-"][data-testid$="-card"]')
.first();

await expect(proposalCard
.locator('[data-testid^="govaction-"][data-testid$="-view-detail"]')
.first()).toBeVisible()
}, { name: "Retrying to get the first proposal" });
}

async viewVotedProposal(
proposal: IProposal
): Promise<GovernanceActionDetailsPage> {
Expand Down Expand Up @@ -122,7 +136,7 @@ export default class GovernanceActionsPage {
expect(
hasFilter,
hasFilter == false &&
`A proposal card does not contain any of the ${filters}`
`A proposal card does not contain any of the ${filters}`
).toBe(true);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,12 @@ test.describe("Logged in DReps", () => {
timeout: 60_000,
});

await expect(
page.getByTestId("dRep-id-display-card-dashboard")
).toContainText(dRep01Wallet.dRepId, { timeout: 60_000 });


const governanceActionsPage = new GovernanceActionsPage(page);

await governanceActionsPage.goto();

await expect(page.getByText(/info action/i).first()).toBeVisible({
timeout: 60_000,
});


await governanceActionsPage.getFirstProposal();
const governanceActionDetailsPage =
await governanceActionsPage.viewFirstProposalByGovernanceAction(
GovernanceActionType.InfoAction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,32 +106,47 @@ test.describe("Temporary DReps", async () => {

test.beforeEach(async ({ page, browser }) => {
const wallet = await walletManager.popWallet("registeredDRep");

const tempDRepAuth = await createTempDRepAuth(page, wallet);

dRepPage = await createNewPageWithWallet(browser, {
storageState: tempDRepAuth,
wallet,
enableDRepSigning: true,
});
});

test("4J. Should include metadata anchor in the vote transaction", async ({}, testInfo) => {
const verifyVoteWithMetadata = async (testInfo: any, useGovToolIPFS: boolean = false) => {
test.setTimeout(testInfo.timeout + environments.txTimeOut);

const govActionsPage = new GovernanceActionsPage(dRepPage);
await govActionsPage.goto();

const govActionDetailsPage = await govActionsPage.viewFirstProposal();
await govActionDetailsPage.vote(faker.lorem.sentence(200));

const fakerContext = faker.lorem.sentence(200);

if (useGovToolIPFS) {
await govActionDetailsPage.vote(fakerContext, false, true);
} else {
await govActionDetailsPage.vote(fakerContext);
}

await dRepPage.reload();
await dRepPage.waitForTimeout(5_000);

await govActionsPage.votedTab.click();
await govActionsPage.viewFirstVotedProposal();

const votedGovActionDetailsPage = await govActionsPage.viewFirstVotedProposal();
await votedGovActionDetailsPage.currentPage.getByTestId("show-more-button").click();
await votedGovActionDetailsPage.currentPage.waitForTimeout(2000);

const voteRationaleContext = await votedGovActionDetailsPage.currentPage.getByTestId("vote-rationale-context");
await expect(voteRationaleContext).toContainText(fakerContext);
};

test("4J. Should include metadata anchor in the vote transaction (Download and store yourself)", async ({}, testInfo) => {
await verifyVoteWithMetadata(testInfo, false);
});

// Vote context is not displayed in UI to validate
expect(false, "No vote context displayed").toBe(true);
test("4k. Should include metadata anchor in the vote transaction (GovTool pins data to IPFS)", async ({}, testInfo) => {
await verifyVoteWithMetadata(testInfo, true);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ test.describe("Proposal checks", () => {
currentPage.getByTestId(`${cip129GovActionId}-id`)
).toBeVisible();

await expect(govActionDetailsPage.contextBtn).toBeVisible();
await expect(govActionDetailsPage.showVotesBtn).toBeVisible();

await expect(govActionDetailsPage.voteBtn).toBeVisible();
Expand All @@ -87,20 +86,22 @@ test.describe("Proposal checks", () => {
await expect(govActionDetailsPage.noVoteRadio).toBeVisible();
await expect(govActionDetailsPage.abstainRadio).toBeVisible();

await govActionDetailsPage.contextBtn.click();
await govActionDetailsPage.yesVoteRadio.click();
await govActionDetailsPage.voteBtn.click();

await expect(govActionDetailsPage.contextInput).toBeVisible();
await govActionDetailsPage.cancelModalBtn.click();

await govActionDetailsPage.yesVoteRadio.click();
await expect(govActionDetailsPage.voteBtn).toBeEnabled();
});

test.describe("Validate provide context about vote", () => {
const characters =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
test("5D_1. Should accept valid data in provide context", async () => {
await govActionDetailsPage.contextBtn.click();

await govActionDetailsPage.yesVoteRadio.click()
await govActionDetailsPage.voteBtn.click()

await expect(govActionDetailsPage.contextInput).toBeVisible();

Expand All @@ -119,7 +120,8 @@ test.describe("Proposal checks", () => {
});

test("5D_2. Should reject invalid data in provide context", async () => {
await govActionDetailsPage.contextBtn.click();
await govActionDetailsPage.yesVoteRadio.click()
await govActionDetailsPage.voteBtn.click()

await expect(govActionDetailsPage.contextInput).toBeVisible();

Expand Down Expand Up @@ -245,32 +247,23 @@ test.describe("Perform voting", () => {
).toBeVisible();

govActionDetailsPage = await governanceActionsPage.viewFirstVotedProposal();
await govActionDetailsPage.vote(faker.lorem.sentence(200), true);

const fakerContext = faker.lorem.sentence(200)
await govActionDetailsPage.vote(fakerContext, true);

await govActionDetailsPage.currentPage.reload();

await governanceActionsPage.votedTab.click();

const isYesVoteVisible = await govActionDetailsPage.currentPage
.getByTestId("my-vote")
.getByText("Yes")
.isVisible();

const textContent = await govActionDetailsPage.currentPage
.getByTestId("my-vote")
.textContent();

await govActionDetailsPage.currentPage.evaluate(() =>
window.scrollTo(0, 500)
);
await expect(
govActionDetailsPage.currentPage.getByTestId("my-vote").getByText("Yes"),
{
message:
!isYesVoteVisible &&
`"Yes" vote not visible, current vote status: ${textContent.match(/My Vote:(Yes|No)/)[1]}`,
}
).toBeVisible({ timeout: 60_000 });
govActionDetailsPage = await governanceActionsPage.viewFirstVotedProposal();

await govActionDetailsPage.currentPage.getByTestId("yes-radio").isVisible();

await govActionDetailsPage.currentPage.getByTestId("show-more-button").click();
await govActionDetailsPage.currentPage.waitForTimeout(2000);

const voteRationaleContext = await govActionDetailsPage.currentPage.getByTestId("vote-rationale-context");
await expect(voteRationaleContext).toContainText(fakerContext);
});

test("5I. Should view the vote details,when viewing governance action already voted by the DRep", async ({}, testInfo) => {
Expand All @@ -282,7 +275,7 @@ test.describe("Perform voting", () => {
govActionDetailsPage.currentPage
);

await governanceActionsPage.currentPage.waitForTimeout(5_000);
await governanceActionsPage.getFirstProposal();

await governanceActionsPage.votedTab.click();
await expect(
Expand Down
4 changes: 3 additions & 1 deletion tests/govtool-frontend/playwright/tests/dRep.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import kuberService from "@services/kuberService";
import walletManager from "lib/walletManager";
import { functionWaitedAssert } from "@helpers/waitedLoop";
import { StaticWallet } from "@types";
import { Logger } from "@helpers/logger";

const REGISTER_DREP_WALLETS_COUNT = 6;
const DREP_WALLETS_COUNT = 10;
const DREP_WALLETS_COUNT = 11;

let dRepDeposit: number;

Expand Down Expand Up @@ -73,6 +74,7 @@ setup("Register DRep of static wallets", async () => {
});

setup("Setup temporary DRep wallets", async () => {

const totalRequiredBalanceForDRepSetup =
(DREP_WALLETS_COUNT + REGISTER_DREP_WALLETS_COUNT) *
(dRepDeposit / 1000000 + 22);
Expand Down