diff --git a/tests/govtool-frontend/playwright/lib/_mock/infoTypeProposal.json b/tests/govtool-frontend/playwright/lib/_mock/infoTypeProposal.json new file mode 100644 index 000000000..305369093 --- /dev/null +++ b/tests/govtool-frontend/playwright/lib/_mock/infoTypeProposal.json @@ -0,0 +1,372 @@ +{ + "page": 0, + "pageSize": 7, + "total": 20, + "elements": [ + { + "id": "81", + "txHash": "7a11d960c26700c8e480ab14bacb739180bb59c7be65c080e73c1597cec3ccdd", + "index": 0, + "type": "InfoAction", + "details": {}, + "expiryDate": "2024-06-06T06:59:21.477528Z", + "expiryEpochNo": 357, + "createdDate": "2024-05-31T14:22:33Z", + "createdEpochNo": 351, + "url": "https://bafkreiezyn2v5v5lhnvl6bckelvo7j5naowysq7jiiurqloqzasrjpio7q.ipfs.w3s.link", + "metadataHash": "6805152f22c80a395a19a2dd8e5f4e9b84287e6a621c184ccccb43c53c61f293", + "title": "hi", + "about": "hi", + "motivation": "hi", + "rationale": "hi", + "metadata": { + "@context": { + "@language": "en-us", + "CIP100": "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/README.md#", + "CIP108": "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0108/README.md#", + "authors": { + "@container": "@set", + "@context": { + "name": "http://xmlns.com/foaf/0.1/name", + "witness": { + "@context": { + "publicKey": "CIP100:publicKey", + "signature": "CIP100:signature", + "witnessAlgorithm": "CIP100:witnessAlgorithm" + }, + "@id": "CIP100:witness" + } + }, + "@id": "CIP100:authors" + }, + "body": { + "@context": { + "abstract": "CIP108:abstract", + "motivation": "CIP108:motivation", + "rationale": "CIP108:rationale", + "references": { + "@container": "@set", + "@context": { + "GovernanceMetadata": "CIP100:GovernanceMetadataReference", + "Other": "CIP100:OtherReference", + "label": "CIP100:reference-label", + "referenceHash": { + "@context": { + "hashAlgorithm": "CIP100:hashAlgorithm", + "hashDigest": "CIP108:hashDigest" + }, + "@id": "CIP108:referenceHash" + }, + "uri": "CIP100:reference-uri" + }, + "@id": "CIP108:references" + }, + "title": "CIP108:title" + }, + "@id": "CIP108:body" + }, + "hashAlgorithm": "CIP100:hashAlgorithm" + }, + "authors": [], + "body": { + "abstract": { + "@value": "hi" + }, + "motivation": { + "@value": "hi" + }, + "rationale": { + "@value": "hi" + }, + "references": [], + "title": { + "@value": "hi" + } + }, + "hashAlgorithm": { + "@value": "blake2b-256" + } + }, + "references": [], + "yesVotes": 0, + "noVotes": 50523999411, + "abstainVotes": 3434294559599, + "metadataStatus": { + "status": null, + "valid": false, + "raw": { + "valid": true + } + } + }, + { + "id": "73", + "txHash": "e79395f1b5e23e657486c6b3ce2fc528ffc090eb21ef6c6ab740c80a9226e6c8", + "index": 0, + "type": "InfoAction", + "details": {}, + "expiryDate": "2024-06-06T06:59:21.477528Z", + "expiryEpochNo": 357, + "createdDate": "2024-05-31T05:21:20Z", + "createdEpochNo": 351, + "url": "https://bit.ly/3zCH2HL", + "metadataHash": "1111111111111111111111111111111111111111111111111111111111111111", + "title": null, + "about": null, + "motivation": null, + "rationale": null, + "metadata": null, + "references": null, + "yesVotes": 0, + "noVotes": 50523999411, + "abstainVotes": 3434294559599, + "metadataStatus": { + "status": null, + "valid": false, + "raw": { + "valid": true + } + } + }, + { + "id": "84", + "txHash": "3c9d9224bf22014605a7f680708d2f44b549ca3416cb83cefc2e16e4696d8643", + "index": 0, + "type": "InfoAction", + "details": {}, + "expiryDate": "2024-06-09T06:50:31.910112Z", + "expiryEpochNo": 360, + "createdDate": "2024-06-03T22:39:50Z", + "createdEpochNo": 354, + "url": "https://raw.githubusercontent.com/mpawel79/testrepo/master/Info.jsonld", + "metadataHash": "eebfff0e2213ff0c5331e6d9d99d47a5a825dce7053671b6ed4daae4b4e0df5e", + "title": null, + "about": null, + "motivation": null, + "rationale": null, + "metadata": null, + "references": null, + "yesVotes": 0, + "noVotes": 50523999411, + "abstainVotes": 3434294559599, + "metadataStatus": { + "status": null, + "valid": false, + "raw": { + "metadata": { + "abstract": "test", + "motivation": "test", + "rationale": "test", + "references": ["https://test.com"], + "title": "test" + }, + "valid": true + } + } + }, + { + "id": "82", + "txHash": "8c92cfc2bd4e43b4c323f0ae1899b17787143eeb2b4f410b695fabfd9f5589fd", + "index": 0, + "type": "InfoAction", + "details": {}, + "expiryDate": "2024-06-06T06:59:21.477528Z", + "expiryEpochNo": 357, + "createdDate": "2024-05-31T14:24:23Z", + "createdEpochNo": 351, + "url": "https://raw.githubusercontent.com/mpawel79/testrepo/master/Info.jsonld", + "metadataHash": "eebfff0e2213ff0c5331e6d9d99d47a5a825dce7053671b6ed4daae4b4e0df5e", + "title": null, + "about": null, + "motivation": null, + "rationale": null, + "metadata": null, + "references": null, + "yesVotes": 0, + "noVotes": 50523999411, + "abstainVotes": 3434294559599, + "metadataStatus": { + "status": null, + "valid": false, + "raw": { + "metadata": { + "abstract": "test", + "motivation": "test", + "rationale": "test", + "references": ["https://test.com"], + "title": "test" + }, + "valid": true + } + } + }, + { + "id": "86", + "txHash": "79f95f77a980458a5532e70f1c74556557a2d8a4bd6172b316f19e9c4ec9b04f", + "index": 0, + "type": "InfoAction", + "details": {}, + "expiryDate": "2024-06-10T06:47:35.38764Z", + "expiryEpochNo": 361, + "createdDate": "2024-06-04T10:25:18Z", + "createdEpochNo": 355, + "url": "https://metadata.cardanoapi.io/data/Info", + "metadataHash": "44c9719997b1bb5d15ef0e3e3f235d2b088dcbed531780fee9aa4ab79d6767e9", + "title": " ", + "about": " ", + "motivation": " ", + "rationale": " ", + "metadata": { + "@context": { + "@language": "en-us", + "CIP100": "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/README.md#", + "CIP108": "https://github.com/cardano-foundation/CIPs/blob/master/CIP-0108/README.md#", + "authors": { + "@container": "@set", + "@context": { + "name": "http://xmlns.com/foaf/0.1/name", + "witness": { + "@context": { + "publicKey": "CIP100:publicKey", + "signature": "CIP100:signature", + "witnessAlgorithm": "CIP100:witnessAlgorithm" + }, + "@id": "CIP100:witness" + } + }, + "@id": "CIP100:authors" + }, + "body": { + "@context": { + "abstract": "CIP108:abstract", + "motivation": "CIP108:motivation", + "rationale": "CIP108:rationale", + "references": { + "@container": "@set", + "@context": { + "GovernanceMetadata": "CIP100:GovernanceMetadataReference", + "Other": "CIP100:OtherReference", + "label": "CIP100:reference-label", + "referenceHash": { + "@context": { + "hashAlgorithm": "CIP100:hashAlgorithm", + "hashDigest": "CIP108:hashDigest" + }, + "@id": "CIP108:referenceHash" + }, + "uri": "CIP100:reference-uri" + }, + "@id": "CIP108:references" + }, + "title": "CIP108:title" + }, + "@id": "CIP108:body" + }, + "hashAlgorithm": "CIP100:hashAlgorithm" + }, + "authors": [], + "body": { + "abstract": { + "@value": " " + }, + "motivation": { + "@value": " " + }, + "rationale": { + "@value": " " + }, + "references": [], + "title": { + "@value": " " + } + }, + "hashAlgorithm": { + "@value": "blake2b-256" + } + }, + "references": [], + "yesVotes": 0, + "noVotes": 50523999411, + "abstainVotes": 3434294559599, + "metadataStatus": { + "status": null, + "valid": false, + "raw": { + "metadata": { + "abstract": " ", + "motivation": " ", + "rationale": " ", + "references": [], + "title": " " + }, + "valid": true + } + } + }, + { + "id": "83", + "txHash": "9d28e20a0b406d81b2b50afc87c4cec0a46cd0acb6d820a8e79ff61673a3f4ff", + "index": 0, + "type": "InfoAction", + "details": {}, + "expiryDate": "2024-06-09T06:50:31.910112Z", + "expiryEpochNo": 360, + "createdDate": "2024-06-03T14:03:59Z", + "createdEpochNo": 354, + "url": "https://raw.githubusercontent.com/mpawel79/testrepo/master/InfoJune03.jsonld", + "metadataHash": "eebfff0e2213ff0c5331e6d9d99d47a5a825dce7053671b6ed4daae4b4e0df5e", + "title": null, + "about": null, + "motivation": null, + "rationale": null, + "metadata": null, + "references": null, + "yesVotes": 0, + "noVotes": 50523999411, + "abstainVotes": 3434294559599, + "metadataStatus": { + "status": null, + "valid": false, + "raw": { + "metadata": { + "abstract": "test", + "motivation": "test", + "rationale": "test", + "references": ["https://test.com"], + "title": "test" + }, + "valid": true + } + } + }, + { + "id": "77", + "txHash": "b61762d4c4f923a08a9c180f5783760bb98e36da6c314f97632ed64bda9545c2", + "index": 0, + "type": "InfoAction", + "details": {}, + "expiryDate": "2024-06-06T06:59:21.477528Z", + "expiryEpochNo": 357, + "createdDate": "2024-05-31T06:40:11Z", + "createdEpochNo": 351, + "url": "https://bit.ly/3zCH2HL", + "metadataHash": "1111111111111111111111111111111111111111111111111111111111111111", + "title": null, + "about": null, + "motivation": null, + "rationale": null, + "metadata": null, + "references": null, + "yesVotes": 0, + "noVotes": 50523999411, + "abstainVotes": 3434294559599, + "metadataStatus": { + "status": null, + "valid": false, + "raw": { + "valid": true + } + } + } + ] +} diff --git a/tests/govtool-frontend/playwright/lib/constants/staticWallets.ts b/tests/govtool-frontend/playwright/lib/constants/staticWallets.ts index cc929db8e..db324bccf 100644 --- a/tests/govtool-frontend/playwright/lib/constants/staticWallets.ts +++ b/tests/govtool-frontend/playwright/lib/constants/staticWallets.ts @@ -11,6 +11,7 @@ export const adaHolder02Wallet = staticWallets[4]; export const adaHolder03Wallet = staticWallets[6]; export const adaHolder04Wallet = staticWallets[7]; export const adaHolder05Wallet = staticWallets[8]; +export const adaHolder06Wallet = staticWallets[9]; // Does not takes part in transaction export const user01Wallet: StaticWallet = staticWallets[5]; diff --git a/tests/govtool-frontend/playwright/lib/forms/dRepForm.ts b/tests/govtool-frontend/playwright/lib/forms/dRepForm.ts new file mode 100644 index 000000000..0fbbdcaaa --- /dev/null +++ b/tests/govtool-frontend/playwright/lib/forms/dRepForm.ts @@ -0,0 +1,127 @@ +import { downloadMetadata } from "@helpers/metadata"; +import { Download, Page, expect } from "@playwright/test"; +import metadataBucketService from "@services/metadataBucketService"; +import { IDRepInfo } from "@types"; +import { withTxConfirmation } from "lib/transaction.decorator"; + +const formErrors = { + dRepName: [ + "max-80-characters-error", + "this-field-is-required-error", + "nickname-can-not-contain-whitespaces-error", + ], + email: "invalid-email-address-error", + link: "invalid-url-error", +}; + +export default class DRepForm { + readonly continueBtn = this.form.getByTestId("continue-button"); + readonly addLinkBtn = this.form.getByTestId("add-link-button"); + readonly metadataDownloadBtn = this.form.getByTestId( + "metadata-download-button" + ); + + // input fields + readonly nameInput = this.form.getByTestId("name-input"); + readonly emailInput = this.form.getByTestId("email-input"); + readonly bioInput = this.form.getByTestId("bio-input"); + readonly linkInput = this.form.getByTestId("link-1-input"); + readonly metadataUrlInput = this.form.getByTestId("metadata-url-input"); + + constructor(private readonly form: Page) {} + + @withTxConfirmation + async register(dRepInfo: IDRepInfo) { + await this.registerWithoutTxConfirmation(dRepInfo); + } + + async registerWithoutTxConfirmation(dRepInfo: IDRepInfo) { + await this.nameInput.fill(dRepInfo.name); + + if (dRepInfo.email != null) { + await this.emailInput.fill(dRepInfo.email); + } + if (dRepInfo.bio != null) { + await this.bioInput.fill(dRepInfo.bio); + } + if (dRepInfo.extraContentLinks != null) { + for (let i = 0; i < dRepInfo.extraContentLinks.length; i++) { + if (i > 0) { + await this.addLinkBtn.click(); + } + await this.linkInput.nth(i).fill(dRepInfo.extraContentLinks[i]); + } + } + await this.continueBtn.click(); + await this.form.getByRole("checkbox").click(); + await this.continueBtn.click(); + + this.metadataDownloadBtn.click(); + const dRepMetadata = await this.downloadVoteMetadata(); + const url = await metadataBucketService.uploadMetadata( + dRepMetadata.name, + dRepMetadata.data + ); + + await this.metadataUrlInput.fill(url); + await this.form.getByTestId("register-button").click(); + } + + async downloadVoteMetadata() { + const download: Download = await this.form.waitForEvent("download"); + return downloadMetadata(download); + } + + async validateForm(name: string, email: string, bio: string, link: string) { + await this.nameInput.fill(name); + await this.emailInput.fill(email); + await this.bioInput.fill(bio); + await this.linkInput.fill(link); + + for (const err of formErrors.dRepName) { + await expect(this.form.getByTestId(err)).toBeHidden(); + } + + await expect(this.form.getByTestId(formErrors.email)).toBeHidden(); + + expect(await this.bioInput.textContent()).toEqual(bio); + + await expect(this.form.getByTestId(formErrors.link)).toBeHidden(); + + await expect(this.continueBtn).toBeEnabled(); + } + + async inValidateForm(name: string, email: string, bio: string, link: string) { + await this.nameInput.fill(name); + await this.emailInput.fill(email); + await this.bioInput.fill(bio); + await this.linkInput.fill(link); + + function convertTestIdToText(testId: string) { + let text = testId.replace("-error", ""); + text = text.replace(/-/g, " "); + return text[0].toUpperCase() + text.substring(1); + } + + const regexPattern = new RegExp( + formErrors.dRepName.map(convertTestIdToText).join("|") + ); + + const nameErrors = await this.form + .locator('[data-testid$="-error"]') + .filter({ + hasText: regexPattern, + }) + .all(); + + expect(nameErrors.length).toEqual(1); + + await expect(this.form.getByTestId(formErrors.email)).toBeVisible(); + + expect(await this.bioInput.textContent()).not.toEqual(bio); + + await expect(this.form.getByTestId(formErrors.link)).toBeVisible(); + + await expect(this.continueBtn).toBeDisabled(); + } +} diff --git a/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts b/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts index 395cb9128..9b07aa783 100644 --- a/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/dRepDirectoryPage.ts @@ -11,6 +11,13 @@ export default class DRepDirectoryPage { readonly filterBtn = this.page.getByTestId("filters-button"); readonly sortBtn = this.page.getByTestId("sort-button"); readonly showMoreBtn = this.page.getByTestId("show-more-button"); + readonly abstainInfoButton = this.page.getByTestId( + "abstain-from-every-vote-info-button" + ); + + readonly signalNoConfidenceInfoButton = this.page.getByTestId( + "signal-no-confidence-on-every-vote-info-button" + ); readonly automaticDelegationOptionsDropdown = this.page.getByRole("button", { name: "Automated Voting Options arrow", diff --git a/tests/govtool-frontend/playwright/lib/pages/dRepRegistrationPage.ts b/tests/govtool-frontend/playwright/lib/pages/dRepRegistrationPage.ts index f4c7671f0..128a80e1a 100644 --- a/tests/govtool-frontend/playwright/lib/pages/dRepRegistrationPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/dRepRegistrationPage.ts @@ -1,135 +1,20 @@ -import { downloadMetadata } from "@helpers/metadata"; -import { Download, Page, expect } from "@playwright/test"; -import metadataBucketService from "@services/metadataBucketService"; -import { IDRepInfo } from "@types"; -import environments from "lib/constants/environments"; -import { withTxConfirmation } from "lib/transaction.decorator"; +import environments from "@constants/environments"; +import { Page } from "@playwright/test"; +import DRepForm from "../forms/dRepForm"; -const formErrors = { - dRepName: [ - "max-80-characters-error", - "this-field-is-required-error", - "nickname-can-not-contain-whitespaces-error", - ], - email: "invalid-email-address-error", - link: "invalid-url-error", -}; - -export default class DRepRegistrationPage { +export default class DRepRegistrationPage extends DRepForm { readonly registerBtn = this.page.getByTestId("register-button"); - readonly skipBtn = this.page.getByTestId("skip-button"); readonly confirmBtn = this.page.getByTestId("confirm-modal-button"); readonly registrationSuccessModal = this.page.getByTestId( "governance-action-submitted-modal" ); - readonly continueBtn = this.page.getByTestId("continue-button"); - readonly addLinkBtn = this.page.getByTestId("add-link-button"); - - // input fields - readonly nameInput = this.page.getByTestId("name-input"); - readonly emailInput = this.page.getByTestId("email-input"); - readonly bioInput = this.page.getByTestId("bio-input"); - readonly linkInput = this.page.getByTestId("link-1-input"); - constructor(private readonly page: Page) {} + constructor(private readonly page: Page) { + super(page); + } async goto() { await this.page.goto(`${environments.frontendUrl}/register_drep`); await this.continueBtn.click(); // BUG: testId -> continue-register-button } - - @withTxConfirmation - async register(dRepInfo: IDRepInfo) { - await this.registerWithoutTxConfirmation(dRepInfo); - } - - async registerWithoutTxConfirmation(dRepInfo: IDRepInfo) { - await this.nameInput.fill(dRepInfo.name); - - if (dRepInfo.email != null) { - await this.emailInput.fill(dRepInfo.email); - } - if (dRepInfo.bio != null) { - await this.bioInput.fill(dRepInfo.bio); - } - if (dRepInfo.extraContentLinks != null) { - for (let i = 0; i < dRepInfo.extraContentLinks.length; i++) { - if (i > 0) { - await this.addLinkBtn.click(); - } - await this.linkInput.nth(i).fill(dRepInfo.extraContentLinks[i]); - } - } - await this.continueBtn.click(); - await this.page.getByRole("checkbox").click(); - await this.continueBtn.click(); - - this.page.getByRole("button", { name: `${dRepInfo.name}.jsonld` }).click(); - const dRepMetadata = await this.downloadVoteMetadata(); - const url = await metadataBucketService.uploadMetadata( - dRepMetadata.name, - dRepMetadata.data - ); - - await this.page.getByPlaceholder("URL").fill(url); - await this.page.getByTestId("register-button").click(); - } - - async downloadVoteMetadata() { - const download: Download = await this.page.waitForEvent("download"); - return downloadMetadata(download); - } - - async validateForm(name: string, email: string, bio: string, link: string) { - await this.nameInput.fill(name); - await this.emailInput.fill(email); - await this.bioInput.fill(bio); - await this.linkInput.fill(link); - - for (const err of formErrors.dRepName) { - await expect(this.page.getByTestId(err)).toBeHidden(); - } - - await expect(this.page.getByTestId(formErrors.email)).toBeHidden(); - - expect(await this.bioInput.textContent()).toEqual(bio); - - await expect(this.page.getByTestId(formErrors.link)).toBeHidden(); - - await expect(this.continueBtn).toBeEnabled(); - } - - async inValidateForm(name: string, email: string, bio: string, link: string) { - await this.nameInput.fill(name); - await this.emailInput.fill(email); - await this.bioInput.fill(bio); - await this.linkInput.fill(link); - - function convertTestIdToText(testId: string) { - let text = testId.replace("-error", ""); - text = text.replace(/-/g, " "); - return text[0].toUpperCase() + text.substring(1); - } - - const regexPattern = new RegExp( - formErrors.dRepName.map(convertTestIdToText).join("|") - ); - - const nameErrors = await this.page - .locator('[data-testid$="-error"]') - .filter({ - hasText: regexPattern, - }) - .all(); - - expect(nameErrors.length).toEqual(1); - - await expect(this.page.getByTestId(formErrors.email)).toBeVisible(); - - expect(await this.bioInput.textContent()).not.toEqual(bio); - - await expect(this.page.getByTestId(formErrors.link)).toBeVisible(); - - await expect(this.continueBtn).toBeDisabled(); - } } diff --git a/tests/govtool-frontend/playwright/lib/pages/editDRepPage.ts b/tests/govtool-frontend/playwright/lib/pages/editDRepPage.ts new file mode 100644 index 000000000..ffbfe840e --- /dev/null +++ b/tests/govtool-frontend/playwright/lib/pages/editDRepPage.ts @@ -0,0 +1,19 @@ +import environments from "@constants/environments"; +import { Page } from "@playwright/test"; +import DRepForm from "../forms/dRepForm"; + +export default class EditDRepPage extends DRepForm { + readonly registerBtn = this.page.getByTestId("register-button"); + readonly confirmBtn = this.page.getByTestId("confirm-modal-button"); + readonly registrationSuccessModal = this.page.getByTestId( + "governance-action-submitted-modal" + ); + + constructor(private readonly page: Page) { + super(page); + } + + async goto() { + await this.page.goto(`${environments.frontendUrl}/edit_dRep`); + } +} diff --git a/tests/govtool-frontend/playwright/lib/pages/governanceActionsPage.ts b/tests/govtool-frontend/playwright/lib/pages/governanceActionsPage.ts index 98680483f..a815e4b80 100644 --- a/tests/govtool-frontend/playwright/lib/pages/governanceActionsPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/governanceActionsPage.ts @@ -65,7 +65,8 @@ export default class GovernanceActionsPage { } async getAllProposals() { - return this.page.locator('[data-test-id$="-card"]').all(); + await this.page.waitForTimeout(2_000); + return this.page.locator('[data-testid$="-card"]').all(); } async validateFilters(filters: string[]) { diff --git a/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts b/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts index 60133f545..3ba8c0331 100644 --- a/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts +++ b/tests/govtool-frontend/playwright/lib/pages/proposalSubmissionPage.ts @@ -35,10 +35,14 @@ export default class ProposalSubmissionPage { readonly addLinkBtn = this.page.getByRole("button", { name: "+ Add link" }); // BUG testid= add-link-button readonly infoRadioButton = this.page.getByTestId("Info-radio"); readonly treasuryRadioButton = this.page.getByTestId("Treasury-radio"); + readonly editSubmissionButton = this.page.getByTestId( + "edit-submission-button" + ); // input fields readonly titleInput = this.page.getByPlaceholder("A name for this Action"); // BUG testid = title-input readonly abstractInput = this.page.getByPlaceholder("Summary"); // BUG testid = abstract-input + readonly metadataUrlInput = this.page.getByTestId("metadata-url-input"); readonly motivationInput = this.page.getByPlaceholder( "Problem this GA will solve" ); // BUG testid = motivation-input @@ -77,7 +81,7 @@ export default class ProposalSubmissionPage { dRepMetadata.name, dRepMetadata.data ); - await this.page.getByPlaceholder("URL").fill(url); + await this.metadataUrlInput.fill(url); await this.continueBtn.click(); } diff --git a/tests/govtool-frontend/playwright/package.json b/tests/govtool-frontend/playwright/package.json index 56d315c53..a6799bc66 100644 --- a/tests/govtool-frontend/playwright/package.json +++ b/tests/govtool-frontend/playwright/package.json @@ -25,7 +25,7 @@ "allure:serve": "npx allure serve", "test": "npx playwright test", "format": "prettier . --write", - "generate-wallets": "ts-node ./generate_wallets.ts 9" + "generate-wallets": "ts-node ./generate_wallets.ts 10" }, "dependencies": { "@cardanoapi/cardano-test-wallet": "^1.1.2", diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts index 04c34f1e5..41c83d599 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegation.loggedin.spec.ts @@ -39,3 +39,33 @@ test("2D. Should show delegation options in connected state", async ({ 2 ); }); + +test("2X_1. Should include info button and voting power on the Abstain card", async ({ + page, +}) => { + const dRepDirectoryPage = new DRepDirectoryPage(page); + await dRepDirectoryPage.goto(); + + await dRepDirectoryPage.automaticDelegationOptionsDropdown.click(); + + await expect( + dRepDirectoryPage.abstainDelegationCard.getByText("₳") + ).toBeVisible(); + + await expect(dRepDirectoryPage.abstainInfoButton).toBeVisible(); +}); + +test("2X_2. Should include info button and voting power on the Signal-No-Confidence card", async ({ + page, +}) => { + const dRepDirectoryPage = new DRepDirectoryPage(page); + await dRepDirectoryPage.goto(); + + await dRepDirectoryPage.automaticDelegationOptionsDropdown.click(); + + await expect( + dRepDirectoryPage.signalNoConfidenceCard.getByText("₳") + ).toBeVisible(); + + await expect(dRepDirectoryPage.signalNoConfidenceInfoButton).toBeVisible(); +}); diff --git a/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts b/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts index 1a3afdbbd..c2b1f8e90 100644 --- a/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts +++ b/tests/govtool-frontend/playwright/tests/2-delegation/delegationFunctionality.delegation.spec.ts @@ -5,6 +5,7 @@ import { adaHolder03Wallet, adaHolder04Wallet, adaHolder05Wallet, + adaHolder06Wallet, dRep01Wallet, dRep02Wallet, } from "@constants/staticWallets"; @@ -292,3 +293,35 @@ test.describe("No confidence delegation", () => { ).toBeVisible(); }); }); + +test.describe("Delegated ADA visibility", () => { + test.use({ + storageState: ".auth/adaHolder06.json", + wallet: adaHolder06Wallet, + }); + + test("2W. Should show my delegated ADA to the DRep", async ({ + page, + }, testInfo) => { + test.setTimeout(testInfo.timeout + environments.txTimeOut); + + const dRepDirectoryPage = new DRepDirectoryPage(page); + await dRepDirectoryPage.goto(); + + await dRepDirectoryPage.delegateToDRep(dRep01Wallet.dRepId); + + const adaHolderVotingPower = await kuberService.getBalance( + adaHolder05Wallet.address + ); + await expect( + page.getByText(`You have delegated ₳ ${adaHolderVotingPower}`) + ).toBeVisible(); + + await page.goto("/"); + await expect( + page.getByText( + `Your Voting Power of ₳${adaHolderVotingPower} is Delegated to` + ) + ).toBeVisible(); + }); +}); diff --git a/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.dRep.spec.ts index 0b2d1f12d..10f0601cb 100644 --- a/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.dRep.spec.ts @@ -75,7 +75,9 @@ test.describe("Temporary DReps", () => { test("3G. Should show confirmation message with link to view transaction, when DRep registration txn is submitted", async ({ page, browser, - }) => { + }, testInfo) => { + test.setTimeout(testInfo.timeout + environments.txTimeOut); + const wallet = await walletManager.popWallet("registerDRep"); const tempDRepAuth = await createTempDRepAuth(page, wallet); @@ -96,6 +98,8 @@ test.describe("Temporary DReps", () => { }); test("3J. Should verify retire as DRep", async ({ page, browser }) => { + test.slow(); // Due to queue in pop wallets + const wallet = await walletManager.popWallet("registeredDRep"); const tempDRepAuth = await createTempDRepAuth(page, wallet); diff --git a/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.loggedin.spec.ts index 94ab385ac..2ee585c5e 100644 --- a/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.loggedin.spec.ts +++ b/tests/govtool-frontend/playwright/tests/3-drep-registration/dRepRegistration.loggedin.spec.ts @@ -35,7 +35,7 @@ test("3D. Verify DRep registration form", async ({ page }) => { }); test.describe("Validation of dRep Registration Form", () => { - test("3E.1 Should accept valid data in DRep form", async ({ page }) => { + test("3E_1 Should accept valid data in DRep form", async ({ page }) => { test.slow(); const dRepRegistrationPage = new DRepRegistrationPage(page); @@ -58,7 +58,7 @@ test.describe("Validation of dRep Registration Form", () => { await expect(dRepRegistrationPage.addLinkBtn).toBeHidden(); }); - test("3E.2. Should reject invalid data in DRep form", async ({ page }) => { + test("3E_2. Should reject invalid data in DRep form", async ({ page }) => { test.slow(); const dRepRegistrationPage = new DRepRegistrationPage(page); @@ -73,6 +73,56 @@ test.describe("Validation of dRep Registration Form", () => { ); } }); + + test("3L_1. Should accept valid metadata anchor on create dRep", async ({ + page, + }) => { + const dRepRegistrationPage = new DRepRegistrationPage(page); + await dRepRegistrationPage.goto(); + + const dRepName = "Test_DRep"; + await dRepRegistrationPage.nameInput.fill(dRepName); + + await dRepRegistrationPage.continueBtn.click(); + await page.getByRole("checkbox").click(); + await dRepRegistrationPage.continueBtn.click(); + + for (let i = 0; i < 100; i++) { + await dRepRegistrationPage.metadataUrlInput.fill(faker.internet.url()); + await expect(page.getByTestId("invalid-url-error")).toBeHidden(); + } + }); + + test("3L_2. Should reject invalid dRep metadata anchor on create dRep", async ({ + page, + }) => { + const dRepRegistrationPage = new DRepRegistrationPage(page); + await dRepRegistrationPage.goto(); + + const dRepName = "Test_DRep"; + await dRepRegistrationPage.nameInput.fill(dRepName); + + await dRepRegistrationPage.continueBtn.click(); + await page.getByRole("checkbox").click(); + await dRepRegistrationPage.continueBtn.click(); + + for (let i = 0; i < 100; i++) { + await dRepRegistrationPage.metadataUrlInput.fill(mockInvalid.url()); + await expect(page.getByTestId("invalid-url-error")).toBeVisible(); + } + + const sentenceWithoutSpace = faker.lorem + .sentence(128) + .replace(/[\s.]/g, ""); + const metadataAnchorGreaterThan128Bytes = + faker.internet.url({ appendSlash: true }) + sentenceWithoutSpace; + + await dRepRegistrationPage.metadataUrlInput.fill( + metadataAnchorGreaterThan128Bytes + ); + + await expect(page.getByTestId("invalid-url-error")).toBeVisible(); + }); }); test("3F. Should create proper DRep registration request, when registered with data", async ({ @@ -86,3 +136,25 @@ test("3F. Should create proper DRep registration request, when registered with d page.getByTestId("registration-transaction-error-modal") ).toBeVisible(); }); + +test("3O. Should reject invalid dRep registration metadata", async ({ + page, +}) => { + const dRepRegistrationPage = new DRepRegistrationPage(page); + await dRepRegistrationPage.goto(); + + const dRepName = "Test_DRep"; + await dRepRegistrationPage.nameInput.fill(dRepName); + + await dRepRegistrationPage.continueBtn.click(); + await page.getByRole("checkbox").click(); + await dRepRegistrationPage.continueBtn.click(); + + const invalidMetadataAnchor = "https://www.google.com"; + await dRepRegistrationPage.metadataUrlInput.fill(invalidMetadataAnchor); + await dRepRegistrationPage.registerBtn.click(); + + await expect( + page.getByTestId("registration-transaction-error-modal") + ).not.toHaveText(/utxo balance insufficient/i); +}); diff --git a/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts new file mode 100644 index 000000000..f543862e0 --- /dev/null +++ b/tests/govtool-frontend/playwright/tests/3-drep-registration/editDRep.dRep.spec.ts @@ -0,0 +1,124 @@ +import { dRep02Wallet } from "@constants/staticWallets"; +import { faker } from "@faker-js/faker"; +import { test } from "@fixtures/walletExtension"; +import { setAllureEpic } from "@helpers/allure"; +import { invalid as mockInvalid } from "@mock/index"; +import EditDRepPage from "@pages/editDRepPage"; +import { expect } from "@playwright/test"; + +test.beforeEach(async () => { + await setAllureEpic("3. DRep registration"); +}); + +test.use({ wallet: dRep02Wallet, storageState: ".auth/dRep02.json" }); + +test.describe("Validation of edit dRep Form", () => { + test("3M_1 Should accept valid data in edit dRep form", async ({ page }) => { + test.slow(); + + const editDRepPage = new EditDRepPage(page); + await editDRepPage.goto(); + + for (let i = 0; i < 100; i++) { + await editDRepPage.validateForm( + faker.internet.displayName(), + faker.internet.email(), + faker.lorem.paragraph(), + faker.internet.url() + ); + } + + for (let i = 0; i < 6; i++) { + await expect(editDRepPage.addLinkBtn).toBeVisible(); + await editDRepPage.addLinkBtn.click(); + } + + await expect(editDRepPage.addLinkBtn).toBeHidden(); + }); + + test("3M_2. Should reject invalid data in edit dRep form", async ({ + page, + }) => { + test.slow(); + + const editDRepPage = new EditDRepPage(page); + await editDRepPage.goto(); + + for (let i = 0; i < 100; i++) { + await editDRepPage.inValidateForm( + mockInvalid.name(), + mockInvalid.email(), + faker.lorem.paragraph(40), + mockInvalid.url() + ); + } + }); + + test("3N_1. Should accept valid metadata anchor on edit dRep", async ({ + page, + }) => { + const editDRepPage = new EditDRepPage(page); + await editDRepPage.goto(); + + const dRepName = "Test_DRep"; + await editDRepPage.nameInput.fill(dRepName); + + await editDRepPage.continueBtn.click(); + await page.getByRole("checkbox").click(); + await editDRepPage.continueBtn.click(); + + for (let i = 0; i < 100; i++) { + await editDRepPage.metadataUrlInput.fill(faker.internet.url()); + await expect(page.getByTestId("invalid-url-error")).toBeHidden(); + } + }); + + test("3N_2. Should reject invalid dRep metadata anchor on edit dRep", async ({ + page, + }) => { + const editDRepPage = new EditDRepPage(page); + await editDRepPage.goto(); + + const dRepName = "Test_DRep"; + await editDRepPage.nameInput.fill(dRepName); + + await editDRepPage.continueBtn.click(); + await page.getByRole("checkbox").click(); + await editDRepPage.continueBtn.click(); + + for (let i = 0; i < 100; i++) { + await editDRepPage.metadataUrlInput.fill(mockInvalid.url()); + await expect(page.getByTestId("invalid-url-error")).toBeVisible(); + } + + const sentenceWithoutSpace = faker.lorem + .sentence(128) + .replace(/[\s.]/g, ""); + const metadataAnchorGreaterThan128Bytes = + faker.internet.url({ appendSlash: true }) + sentenceWithoutSpace; + + await editDRepPage.metadataUrlInput.fill(metadataAnchorGreaterThan128Bytes); + + await expect(page.getByTestId("invalid-url-error")).toBeVisible(); + }); +}); + +test("3P. Should reject invalid edit dRep metadata", async ({ page }) => { + const editDRepPage = new EditDRepPage(page); + await editDRepPage.goto(); + + const dRepName = "Test_DRep"; + await editDRepPage.nameInput.fill(dRepName); + + await editDRepPage.continueBtn.click(); + await page.getByRole("checkbox").click(); + await editDRepPage.continueBtn.click(); + + const invalidMetadataAnchor = "https://www.google.com"; + await editDRepPage.metadataUrlInput.fill(invalidMetadataAnchor); + await editDRepPage.continueBtn.click(); + + await expect( + page.getByTestId("registration-transaction-error-modal") + ).toBeVisible(); +}); diff --git a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts index 8850fa85e..87917d374 100644 --- a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.dRep.spec.ts @@ -122,6 +122,8 @@ test("4F. Should Disable DRep functionality upon wallet disconnection on governa page, browser, }) => { + test.slow(); // Due to queue in pop wallets + const wallet = await walletManager.popWallet("registeredDRep"); const tempDRepAuth = await createTempDRepAuth(page, wallet); diff --git a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.loggedin.spec.ts index 3ab84ee79..4053ad471 100644 --- a/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.loggedin.spec.ts +++ b/tests/govtool-frontend/playwright/tests/4-proposal-visibility/proposalVisibility.loggedin.spec.ts @@ -7,6 +7,8 @@ import removeAllSpaces from "@helpers/removeAllSpaces"; import GovernanceActionsPage from "@pages/governanceActionsPage"; import { expect } from "@playwright/test"; +const infoTypeProposal = require("../../lib/_mock/infoTypeProposal.json"); + const filterOptionNames = [ "Protocol Parameter Change", "New Committee", @@ -29,7 +31,7 @@ test.beforeEach(async () => { await setAllureEpic("4. Proposal visibility"); }); -test("4A.1: Should access Governance Actions page with connecting wallet", async ({ +test("4A_1: Should access Governance Actions page with connecting wallet", async ({ page, }) => { await page.goto("/"); @@ -41,7 +43,7 @@ test("4A.1: Should access Governance Actions page with connecting wallet", async await expect(page.getByText(/Governance Actions/i)).toHaveCount(2); }); -test("4B.1: Should restrict voting for users who are not registered as DReps (with wallet connected)", async ({ +test("4B_1: Should restrict voting for users who are not registered as DReps (with wallet connected)", async ({ page, }) => { const govActionsPage = new GovernanceActionsPage(page); @@ -51,7 +53,7 @@ test("4B.1: Should restrict voting for users who are not registered as DReps (wi await expect(govActionDetailsPage.voteBtn).not.toBeVisible(); }); -test("4C.1: Should filter Governance Action Type on governance actions page", async ({ +test("4C_1: Should filter Governance Action Type on governance actions page", async ({ page, }) => { test.slow(); @@ -78,7 +80,7 @@ test("4C.1: Should filter Governance Action Type on governance actions page", as } }); -test("4C.2: Should sort Governance Action Type on governance actions page", async ({ +test("4C_2: Should sort Governance Action Type on governance actions page", async ({ page, }) => { test.slow(); @@ -104,7 +106,7 @@ test("4C.2: Should sort Governance Action Type on governance actions page", asyn ); }); -test("4C.3: Should filter and sort Governance Action Type on governance actions page", async ({ +test("4C_3: Should filter and sort Governance Action Type on governance actions page", async ({ page, }) => { test.slow(); @@ -126,6 +128,44 @@ test("4C.3: Should filter and sort Governance Action Type on governance actions await govActionsPage.validateFilters([filterOptionNames[0]]); }); +test("4L: Should search governance actions", async ({ page }) => { + const governanceActionTitle = "TreasuryTitle"; + const governanceActionPage = new GovernanceActionsPage(page); + + await governanceActionPage.goto(); + + await governanceActionPage.searchInput.fill(governanceActionTitle); + + const proposalCards = await governanceActionPage.getAllProposals(); + + for (const proposalCard of proposalCards) { + expect( + (await proposalCard.textContent()).includes(`${governanceActionTitle}`) + ).toBeTruthy(); + } +}); + +test("4M: Should show view-all categorized governance actions", async ({ + page, +}) => { + await page.route("**/proposal/list?**", async (route) => + route.fulfill({ + body: JSON.stringify(infoTypeProposal), + }) + ); + + const governanceActionPage = new GovernanceActionsPage(page); + await governanceActionPage.goto(); + + await page.getByRole("button", { name: "Show All" }).click(); + + const proposalCards = await governanceActionPage.getAllProposals(); + + for (const proposalCard of proposalCards) { + await expect(proposalCard.getByTestId("InfoAction-type")).toBeVisible(); + } +}); + test("4H. Should verify none of the displayed governance actions have expired", async ({ page, }) => { diff --git a/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.dRep.spec.ts b/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.dRep.spec.ts index 48628268f..411a5e8a4 100644 --- a/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.dRep.spec.ts +++ b/tests/govtool-frontend/playwright/tests/5-proposal-functionality/proposalFunctionality.dRep.spec.ts @@ -1,6 +1,7 @@ import environments from "@constants/environments"; import { dRep01Wallet } from "@constants/staticWallets"; import { createTempDRepAuth } from "@datafactory/createAuth"; +import { faker } from "@faker-js/faker"; import { test } from "@fixtures/walletExtension"; import { setAllureEpic } from "@helpers/allure"; import { createNewPageWithWallet } from "@helpers/page"; @@ -58,30 +59,36 @@ test.describe("Proposal checks", () => { await expect(govActionDetailsPage.voteBtn).toBeEnabled(); }); - // Skipped: No url/hash input to validate - test("5D. Should validate proposal voting", async () => { - test.skip(); - // const invalidURLs = ["testdotcom", "https://testdotcom", "https://test.c"]; - // invalidURLs.forEach(async (url) => { - // govActionDetailsPage.urlInput.fill(url); - // await expect(govActionDetailsPage.urlInputError).toBeVisible(); - // }); - // const validURLs = ["https://test.com"]; - // validURLs.forEach(async (url) => { - // govActionDetailsPage.urlInput.fill(url); - // await expect(govActionDetailsPage.urlInputError).not.toBeVisible(); - // }); - // const invalidHashes = [ - // randomBytes(20).toString("hex"), - // randomBytes(32).toString(), - // ]; - // invalidHashes.forEach(async (hash) => { - // govActionDetailsPage.hashInput.fill(hash); - // await expect(govActionDetailsPage.hashInputError).toBeVisible(); - // }); - // const validHash = randomBytes(32).toString("hex"); - // govActionDetailsPage.hashInput.fill(validHash); - // await expect(govActionDetailsPage.hashInputError).not.toBeVisible(); + test.describe("Validate provide context about vote", () => { + test("5D_1. Should accept valid data in provide context", async () => { + await govActionDetailsPage.contextBtn.click(); + + await expect(govActionDetailsPage.contextInput).toBeVisible(); + + for (let i = 0; i < 100; i++) { + const randomContext = faker.lorem.paragraph(2); + await govActionDetailsPage.contextInput.fill(randomContext); + expect(await govActionDetailsPage.contextInput.textContent()).toEqual( + randomContext + ); + + await expect(govActionDetailsPage.confirmModalBtn).toBeVisible(); + } + }); + + test("5D_2. Should reject invalid data in provide context", async () => { + await govActionDetailsPage.contextBtn.click(); + + await expect(govActionDetailsPage.contextInput).toBeVisible(); + + for (let i = 0; i < 100; i++) { + const randomContext = faker.lorem.paragraph(40); + await govActionDetailsPage.contextInput.fill(randomContext); + expect( + await govActionDetailsPage.contextInput.textContent() + ).not.toEqual(randomContext); + } + }); }); }); diff --git a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts index 58b3f5fb0..6a04169e3 100644 --- a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts +++ b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmission.loggedin.spec.ts @@ -1,7 +1,8 @@ -import environments from "@constants/environments"; import { user01Wallet } from "@constants/staticWallets"; +import { faker } from "@faker-js/faker"; import { test } from "@fixtures/walletExtension"; import { setAllureEpic } from "@helpers/allure"; +import { invalid } from "@mock/index"; import ProposalSubmissionPage from "@pages/proposalSubmissionPage"; import { expect } from "@playwright/test"; import { IProposalForm, ProposalType } from "@types"; @@ -15,10 +16,10 @@ test.beforeEach(async () => { test.describe("Accept valid data", () => { Object.values(ProposalType).map((type: ProposalType, index) => { - test(`7E.${index + 1} Should accept valid data in ${type.toLowerCase()} proposal form`, async ({ + test(`7E_${index + 1}. Should accept valid data in ${type.toLowerCase()} proposal form`, async ({ page, }) => { - test.slow(); // Brute-force testing with 100 random datas + test.slow(); // Brute-force testing with 100 random data const proposalSubmissionPage = new ProposalSubmissionPage(page); @@ -50,10 +51,10 @@ test.describe("Accept valid data", () => { test.describe("Reject invalid data", () => { Object.values(ProposalType).map((type: ProposalType, index) => { - test(`7F.${index + 1} Should reject invalid data in ${type.toLowerCase()} Proposal form`, async ({ + test(`7F_${index + 1}. Should reject invalid data in ${type.toLowerCase()} Proposal form`, async ({ page, }) => { - test.slow(); // Brute-force testing with 100 random datas + test.slow(); // Brute-force testing with 100 random data const proposalSubmissionPage = new ProposalSubmissionPage(page); @@ -73,7 +74,7 @@ test.describe("Reject invalid data", () => { test.describe("Review fillup form", () => { Object.values(ProposalType).map((type: ProposalType, index) => { - test(`7I.${index + 1} Should valid review submission in ${type.toLowerCase()} Proposal form`, async ({ + test(`7I_${index + 1}. Should valid review submission in ${type.toLowerCase()} Proposal form`, async ({ page, }) => { const proposalSubmissionPage = new ProposalSubmissionPage(page); @@ -109,3 +110,134 @@ test.describe("Review fillup form", () => { }); }); }); + +test("7I. Should reject invalid proposal metadata", async ({ page }) => { + const invalidMetadataAnchor = "https://www.google.com"; + + const proposalSubmissionPage = new ProposalSubmissionPage(page); + await proposalSubmissionPage.goto(); + ``; + await page.getByTestId(`${ProposalType.info}-radio`).click(); + await proposalSubmissionPage.continueBtn.click(); + + const proposal: IProposalForm = + proposalSubmissionPage.generateValidProposalFormFields(ProposalType.info); + + await proposalSubmissionPage.fillupForm(proposal); + await proposalSubmissionPage.continueBtn.click(); + await proposalSubmissionPage.continueBtn.click(); + await page.getByRole("checkbox").click(); + await proposalSubmissionPage.continueBtn.click(); + + await proposalSubmissionPage.metadataUrlInput.fill(invalidMetadataAnchor); + await proposalSubmissionPage.continueBtn.click(); + + await expect(proposalSubmissionPage.registrationErrorModal).not.toHaveText( + /utxo balance insufficient/i + ); +}); + +test.describe("Edit proposal form", () => { + Object.values(ProposalType).map((type: ProposalType, index) => { + test(`7J_${index + 1}. Should edit review submission in ${type.toLowerCase()} Proposal form`, async ({ + page, + }) => { + const proposalSubmissionPage = new ProposalSubmissionPage(page); + + await proposalSubmissionPage.goto(); + + await page.getByTestId(`${type}-radio`).click(); + await proposalSubmissionPage.continueBtn.click(); + + const randomBytes = new Uint8Array(10); + const bech32Address = bech32.encode("addr_test", randomBytes); + + const formFields: IProposalForm = + proposalSubmissionPage.generateValidProposalFormFields( + type, + bech32Address + ); + await proposalSubmissionPage.validateForm(formFields); + proposalSubmissionPage.continueBtn.click(); + + await proposalSubmissionPage.editSubmissionButton.click(); + + const newTitle = faker.person.firstName(); + + await proposalSubmissionPage.titleInput.fill(newTitle); + + await proposalSubmissionPage.continueBtn.click(); + + await expect(page.getByText(newTitle)).toBeVisible(); + await expect(page.getByText(formFields.abstract)).toBeVisible(); + await expect(page.getByText(formFields.motivation)).toBeVisible(); + await expect(page.getByText(formFields.rationale)).toBeVisible(); + await expect( + page.getByText(formFields.extraContentLinks[0]) + ).toBeVisible(); + + if (type === ProposalType.treasury) { + await expect(page.getByText(formFields.receivingAddress)).toBeVisible(); + await expect(page.getByText(formFields.amount)).toBeVisible(); + } + }); + }); +}); + +test("7K_1. Should accept valid anchor proposal metadata", async ({ page }) => { + const invalidMetadataAnchor = "https://www.google.com"; + + const proposalSubmissionPage = new ProposalSubmissionPage(page); + await proposalSubmissionPage.goto(); + ``; + await page.getByTestId(`${ProposalType.info}-radio`).click(); + await proposalSubmissionPage.continueBtn.click(); + + const proposal: IProposalForm = + proposalSubmissionPage.generateValidProposalFormFields(ProposalType.info); + + await proposalSubmissionPage.fillupForm(proposal); + await proposalSubmissionPage.continueBtn.click(); + await proposalSubmissionPage.continueBtn.click(); + await page.getByRole("checkbox").click(); + await proposalSubmissionPage.continueBtn.click(); + + for (let i = 0; i < 100; i++) { + await proposalSubmissionPage.metadataUrlInput.fill(faker.internet.url()); + await expect(page.getByTestId("invalid-url-error")).toBeHidden(); + } +}); + +test("7K_2. Should reject valid anchor proposal metadata", async ({ page }) => { + const invalidMetadataAnchor = "https://www.google.com"; + + const proposalSubmissionPage = new ProposalSubmissionPage(page); + await proposalSubmissionPage.goto(); + ``; + await page.getByTestId(`${ProposalType.info}-radio`).click(); + await proposalSubmissionPage.continueBtn.click(); + + const proposal: IProposalForm = + proposalSubmissionPage.generateValidProposalFormFields(ProposalType.info); + + await proposalSubmissionPage.fillupForm(proposal); + await proposalSubmissionPage.continueBtn.click(); + await proposalSubmissionPage.continueBtn.click(); + await page.getByRole("checkbox").click(); + await proposalSubmissionPage.continueBtn.click(); + + for (let i = 0; i < 100; i++) { + await proposalSubmissionPage.metadataUrlInput.fill(invalid.url()); + await expect(page.getByTestId("invalid-url-error")).toBeVisible(); + } + + const sentenceWithoutSpace = faker.lorem.sentence(128).replace(/[\s.]/g, ""); + const metadataAnchorGreaterThan128Bytes = + faker.internet.url({ appendSlash: true }) + sentenceWithoutSpace; + + await proposalSubmissionPage.metadataUrlInput.fill( + metadataAnchorGreaterThan128Bytes + ); + + await expect(page.getByTestId("invalid-url-error")).toBeVisible(); +}); diff --git a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmissionFunctionality.tx.spec.ts b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmissionFunctionality.tx.spec.ts index 542a790b8..c2ed11e8d 100644 --- a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmissionFunctionality.tx.spec.ts +++ b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmissionFunctionality.tx.spec.ts @@ -10,13 +10,15 @@ import { Page, expect } from "@playwright/test"; import { IProposalForm, ProposalType, StaticWallet } from "@types"; import walletManager from "lib/walletManager"; +test.beforeEach(async () => { + await setAllureEpic("7. Proposal submission"); +}); + test.describe("Proposal submission check", () => { let userPage: Page; let wallet: StaticWallet; test.beforeEach(async ({ browser, page }, testInfo) => { - await setAllureEpic("7. Proposal submission"); - wallet = await walletManager.popWallet("adaHolder"); const tempUserAuth = await createTempUserAuth(page, wallet); @@ -28,7 +30,7 @@ test.describe("Proposal submission check", () => { }); Object.values(ProposalType).map((type: ProposalType, index) => { - test(`7G.${index + 1}: Should open wallet connection popup, when registered with proper ${type.toLowerCase()} data`, async ({ + test(`7G_${index + 1}. Should open wallet connection popup, when registered with proper ${type.toLowerCase()} data`, async ({ page, browser, }, testInfo) => { @@ -57,7 +59,7 @@ test.describe("Proposal submission check", () => { }); }); -test("7H should submit a proposal", async ({ page, browser }, testInfo) => { +test("7H. should submit a proposal", async ({ page, browser }, testInfo) => { test.setTimeout(testInfo.timeout + environments.txTimeOut); const wallet = await walletManager.popWallet("proposalSubmission"); diff --git a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmissionVisibility.loggedin.spec.ts b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmissionVisibility.loggedin.spec.ts index f3bd8f210..b5e850130 100644 --- a/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmissionVisibility.loggedin.spec.ts +++ b/tests/govtool-frontend/playwright/tests/7-proposal-submission/proposalSubmissionVisibility.loggedin.spec.ts @@ -30,7 +30,7 @@ test("7C. Should list governance action types", async ({ page }) => { test.describe("Verify Proposal form", () => { Object.values(ProposalType).map((type: ProposalType, index) => { - test(`7D.${index + 1}: Verify ${type.toLocaleLowerCase()} proposal form`, async ({ + test(`7D_${index + 1}. Verify ${type.toLocaleLowerCase()} proposal form`, async ({ page, }) => { const proposalSubmissionPage = new ProposalSubmissionPage(page); diff --git a/tests/govtool-frontend/playwright/tests/auth.setup.ts b/tests/govtool-frontend/playwright/tests/auth.setup.ts index e62d7fa92..0edd09915 100644 --- a/tests/govtool-frontend/playwright/tests/auth.setup.ts +++ b/tests/govtool-frontend/playwright/tests/auth.setup.ts @@ -6,7 +6,9 @@ import { adaHolder03Wallet, adaHolder04Wallet, adaHolder05Wallet, + adaHolder06Wallet, dRep01Wallet, + dRep02Wallet, user01Wallet, } from "@constants/staticWallets"; import { importWallet } from "@fixtures/importWallet"; @@ -15,11 +17,14 @@ import { setAllureEpic, setAllureStory } from "@helpers/allure"; import LoginPage from "@pages/loginPage"; const dRep01AuthFile = ".auth/dRep01.json"; +const dRep02AuthFile = ".auth/dRep02.json"; + const adaHolder01AuthFile = ".auth/adaHolder01.json"; const adaHolder02AuthFile = ".auth/adaHolder02.json"; const adaHolder03AuthFile = ".auth/adaHolder03.json"; const adaHolder04AuthFile = ".auth/adaHolder04.json"; const adaHolder05AuthFile = ".auth/adaHolder05.json"; +const adaHolder06AuthFile = ".auth/adaHolder06.json"; const user01AuthFile = ".auth/user01.json"; @@ -38,6 +43,16 @@ setup("Create DRep 01 auth", async ({ page, context }) => { await context.storageState({ path: dRep01AuthFile }); }); +setup("Create DRep 02 auth", async ({ page, context }) => { + await importWallet(page, dRep02Wallet); + + const loginPage = new LoginPage(page); + await loginPage.login(); + await loginPage.isLoggedIn(); + + await context.storageState({ path: dRep02AuthFile }); +}); + setup("Create User 01 auth", async ({ page, context }) => { await importWallet(page, user01Wallet); @@ -97,3 +112,13 @@ setup("Create AdaHolder 05 auth", async ({ page, context }) => { await context.storageState({ path: adaHolder05AuthFile }); }); + +setup("Create AdaHolder 06 auth", async ({ page, context }) => { + await importWallet(page, adaHolder06Wallet); + + const loginPage = new LoginPage(page); + await loginPage.login(); + await loginPage.isLoggedIn(); + + await context.storageState({ path: adaHolder06AuthFile }); +});