diff --git a/apps/governance-e2e/src/integration/flow/proposal-details.cy.ts b/apps/governance-e2e/src/integration/flow/proposal-details.cy.ts index 53f0918e7..4cf6ec0b6 100644 --- a/apps/governance-e2e/src/integration/flow/proposal-details.cy.ts +++ b/apps/governance-e2e/src/integration/flow/proposal-details.cy.ts @@ -34,19 +34,20 @@ import { formatDateWithLocalTimezone } from '@vegaprotocol/utils'; import { createSuccessorMarketProposalTxBody } from '../../support/proposal.functions'; const proposalListItem = '[data-testid="proposals-list-item"]'; -const proposalVoteProgressForPercentage = - 'vote-progress-indicator-percentage-for'; -const proposalVoteProgressAgainstPercentage = - 'vote-progress-indicator-percentage-against'; -const proposalVoteProgressForTokens = 'vote-progress-indicator-tokens-for'; -const proposalVoteProgressAgainstTokens = - 'vote-progress-indicator-tokens-against'; +const participationNotMet = 'token-participation-not-met'; +const voteStatus = 'vote-status'; +const voteMajorityNotMet = 'token-majority-not-met'; +const numberOfVotesFor = 'num-votes-for'; +const votesForPercentage = 'votes-for-percentage'; +const numberOfVotesAgainst = 'num-votes-against'; +const votesAgainstPercentage = 'votes-against-percentage'; +const totalVotedNumber = 'total-voted'; +const totalVotedPercentage = 'total-voted-percentage'; const changeVoteButton = 'change-vote-button'; const proposalDetailsTitle = 'proposal-title'; const proposalDetailsDescription = 'proposal-description'; const openProposals = 'open-proposals'; const viewProposalButton = 'view-proposal-btn'; -const voteBreakdownToggle = 'vote-breakdown-toggle'; const proposalTermsToggle = 'proposal-json-toggle'; const marketDataToggle = 'proposal-market-data-toggle'; @@ -150,29 +151,32 @@ describe( // 3001-VOTE-037 // 3001-VOTE-040 // 3001-VOTE-067 + // 3001-VOTE-023 createRawProposal(); cy.get('@rawProposal').then((rawProposal) => { getProposalFromTitle(rawProposal.rationale.title).within(() => cy.getByTestId(viewProposalButton).click() ); }); - cy.contains('Participation: Not Met 0.00 0.00%(0.00% Required)').should( - 'be.visible' + cy.getByTestId(participationNotMet).should( + 'have.text', + '0.000000000000000000000015% participation threshold not met' + ); + cy.getByTestId(voteMajorityNotMet).should( + 'have.text', + '66% majority threshold not met' + ); + cy.getByTestId(voteStatus).should( + 'have.text', + 'Currently expected to fail' ); - cy.getByTestId(voteBreakdownToggle).click(); - getProposalInformationFromTable('Expected to pass') - .contains('👎') - .should('be.visible'); // 3001-VOTE-062 // 3001-VOTE-040 // 3001-VOTE-070 - getProposalInformationFromTable('Token majority met') - .contains('👎') - .should('be.visible'); // 3001-VOTE-068 - getProposalInformationFromTable('Token participation met') - .contains('👎') - .should('be.visible'); + cy.getByTestId(numberOfVotesFor).should('have.text', '0.0M'); + cy.getByTestId(numberOfVotesAgainst).should('have.text', '0.0M'); + cy.getByTestId(totalVotedNumber).should('have.text', '0.0M'); }); // 3001-VOTE-080 3001-VOTE-090 3001-VOTE-069 3001-VOTE-072 3001-VOTE-073 @@ -197,43 +201,16 @@ describe( .contains(votedDate) .should('be.visible'); }); - cy.getByTestId(proposalVoteProgressForPercentage) // 3001-VOTE-072 - .contains('100.00%') - .and('be.visible'); - cy.getByTestId(proposalVoteProgressAgainstPercentage) - .contains('0.00%') - .and('be.visible'); - cy.getByTestId(proposalVoteProgressForTokens) - .contains('1.00') - .and('be.visible'); - cy.getByTestId(proposalVoteProgressAgainstTokens) - .contains('0.00') - .and('be.visible'); - cy.getByTestId(voteBreakdownToggle).click(); - getProposalInformationFromTable('Tokens for proposal') - .should('have.text', (1).toFixed(2)) - .and('be.visible'); - getProposalInformationFromTable('Tokens against proposal') - .should('have.text', '0.00') - .and('be.visible'); - // 3001-VOTE-061 - getProposalInformationFromTable('Participation required') - .contains('0.00%') - .should('be.visible'); - // 3001-VOTE-066 - getProposalInformationFromTable('Majority Required') // 3001-VOTE-073 - .contains(`${(66).toFixed(2)}%`) - .should('be.visible'); - getProposalInformationFromTable('Number of voting parties') - .should('have.text', '1') - .and('be.visible'); + cy.getByTestId(votesForPercentage) // 3001-VOTE-072 + .should('have.text', '100%'); + cy.getByTestId(votesAgainstPercentage).should('have.text', '0%'); + cy.getByTestId('token-majority-progress') + .should('have.attr', 'style') + .and('eq', 'width: 100%;'); // 3001-VOTE-024 cy.getByTestId(changeVoteButton).should('be.visible').click(); voteForProposal('for'); // 3001-VOTE-064 cy.getByTestId('user-voted-yes').should('exist'); - getProposalInformationFromTable('Tokens for proposal') - .should('have.text', (1).toFixed(2)) - .and('be.visible'); navigateTo(navigation.proposals); cy.get('@rawProposal').then((rawProposal) => { getProposalFromTitle(rawProposal.rationale.title).within(() => { @@ -244,16 +221,7 @@ describe( }); cy.getByTestId(changeVoteButton).should('be.visible').click(); voteForProposal('against'); - cy.getByTestId(proposalVoteProgressAgainstPercentage) - .contains('100.00%') - .and('be.visible'); - cy.getByTestId(voteBreakdownToggle).click(); - getProposalInformationFromTable('Tokens against proposal') - .should('have.text', (1).toFixed(2)) - .and('be.visible'); - getProposalInformationFromTable('Number of voting parties') - .should('have.text', '1') - .and('be.visible'); + cy.getByTestId(votesAgainstPercentage).should('have.text', '100%'); navigateTo(navigation.proposals); cy.get('@rawProposal').then((rawProposal) => { getProposalFromTitle(rawProposal.rationale.title).within(() => { @@ -265,6 +233,7 @@ describe( // 3001-VOTE-042, 3001-VOTE-057, 3001-VOTE-058, 3001-VOTE-059, 3001-VOTE-060 it('Newly created proposal details - ability to increase associated tokens - by voting again after association', function () { + ensureSpecifiedUnstakedTokensAreAssociated('1'); vegaWalletSetSpecifiedApprovalAmount('1000'); createRawProposal(); cy.get('@rawProposal').then((rawProposal) => { @@ -275,69 +244,28 @@ describe( voteForProposal('for'); // 3001-VOTE-079 cy.contains('You voted: For').should('be.visible'); - cy.getByTestId(proposalVoteProgressForTokens) - .contains('1') - .and('be.visible'); - cy.getByTestId(voteBreakdownToggle).click(); - getProposalInformationFromTable('Total Supply') - .invoke('text') - .then((totalSupply) => { - const tokensRequiredToAchieveResult = ( - (Number(totalSupply.replace(/,/g, '')) * 0.001) / - 100 - ).toFixed(2); - ethereumWalletConnect(); - ensureSpecifiedUnstakedTokensAreAssociated( - tokensRequiredToAchieveResult - ); - navigateTo(navigation.proposals); - cy.get('@rawProposal').then((rawProposal) => { - getProposalFromTitle(rawProposal.rationale.title).within(() => - cy.getByTestId(viewProposalButton).click() - ); - }); - cy.getByTestId(proposalVoteProgressForPercentage) - .contains('100.00%') - .and('be.visible'); - cy.getByTestId(proposalVoteProgressAgainstPercentage) - .contains('0.00%') - .and('be.visible'); - // 3001-VOTE-065 - cy.getByTestId(changeVoteButton).should('be.visible').click(); - voteForProposal('for'); - cy.getByTestId(proposalVoteProgressForTokens) - .contains(tokensRequiredToAchieveResult) - .and('be.visible'); - cy.getByTestId(proposalVoteProgressAgainstTokens) - .contains('0.00') - .and('be.visible'); - cy.getByTestId(voteBreakdownToggle).click(); - getProposalInformationFromTable('Total tokens voted percentage') - .should('have.text', '0.00%') - .and('be.visible'); - getProposalInformationFromTable('Tokens for proposal') - .should('have.text', tokensRequiredToAchieveResult) - .and('be.visible'); - getProposalInformationFromTable('Tokens against proposal') - .should('have.text', '0.00') - .and('be.visible'); - getProposalInformationFromTable('Number of voting parties') - .should('have.text', '1') - .and('be.visible'); - getProposalInformationFromTable('Expected to pass') - .contains('👍') - .should('be.visible'); - // 3001-VOTE-062 - getProposalInformationFromTable('Token majority met') - .contains('👍') - .should('be.visible'); - getProposalInformationFromTable('Token participation met') - .contains('👍') - .should('be.visible'); - getProposalInformationFromTable('Tokens for proposal') - .contains(tokensRequiredToAchieveResult) - .and('be.visible'); - }); + cy.getByTestId(numberOfVotesFor).should('have.text', '0.0M'); + cy.getByTestId(votesForPercentage).should('have.text', '100%'); + cy.getByTestId(totalVotedNumber).should('have.text', '0.0M'); + cy.getByTestId(totalVotedPercentage).should('have.text', '(0.00%)'); + ethereumWalletConnect(); + stakingPageAssociateTokens('1000000', { approve: true }); + navigateTo(navigation.proposals); + cy.get('@rawProposal').then((rawProposal) => { + getProposalFromTitle(rawProposal.rationale.title).within(() => + cy.getByTestId(viewProposalButton).click() + ); + }); + cy.getByTestId(votesForPercentage).should('have.text', '100%'); + cy.getByTestId(numberOfVotesFor).should('have.text', '0.0M'); + cy.getByTestId(totalVotedNumber).should('have.text', '0.0M'); + cy.getByTestId(totalVotedPercentage).should('have.text', '(0.00%)'); + // 3001-VOTE-065 + cy.getByTestId(changeVoteButton).should('be.visible').click(); + voteForProposal('for'); + cy.getByTestId(numberOfVotesFor).should('have.text', '1.0M'); + cy.getByTestId(totalVotedNumber).should('have.text', '1.0M'); + cy.getByTestId(totalVotedPercentage).should('have.text', '(1.54%)'); }); it('Able to vote for proposal twice by switching public key', function () { @@ -360,10 +288,6 @@ describe( voteForProposal('against'); cy.contains('You voted: Against').should('be.visible'); switchVegaWalletPubKey(); - cy.getByTestId(proposalVoteProgressForTokens).should( - 'contain.text', - '1.00' - ); // Checking vote status for different public keys is displayed correctly cy.contains('You voted: For').should('be.visible'); }); diff --git a/apps/governance-e2e/src/integration/flow/proposal-enacted.cy.ts b/apps/governance-e2e/src/integration/flow/proposal-enacted.cy.ts index 435e429d3..f43d06989 100644 --- a/apps/governance-e2e/src/integration/flow/proposal-enacted.cy.ts +++ b/apps/governance-e2e/src/integration/flow/proposal-enacted.cy.ts @@ -22,12 +22,10 @@ const proposalListItem = '[data-testid="proposals-list-item"]'; const closedProposals = 'closed-proposals'; const proposalStatus = 'proposal-status'; const viewProposalButton = 'view-proposal-btn'; -const votesTable = 'votes-table'; +const votesTable = 'user-vote'; const openProposals = 'open-proposals'; -const proposalVoteProgressForPercentage = - 'vote-progress-indicator-percentage-for'; -const majorityVoteReached = 'majority-reached'; -const minParticipationReached = 'participation-reached'; +const majorityVoteReached = 'token-majority-met'; +const minParticipationReached = 'token-participation-met'; const proposalTimeout = { timeout: 8000 }; context( @@ -70,7 +68,6 @@ context( cy.getByTestId('proposal-type').should('have.text', 'New market'); cy.getByTestId(proposalStatus).should('have.text', 'Enacted'); cy.getByTestId(votesTable).within(() => { - cy.contains('Vote passed.').should('be.visible'); cy.contains('Voting has ended.').should('be.visible'); }); }); @@ -92,7 +89,7 @@ context( // 3001-VOTE-019 time to vote is highlighted red cy.getByTestId('vote-details') .find('span') - .should('have.class', 'text-vega-pink'); + .should('have.class', 'text-vega-orange'); cy.getByTestId(viewProposalButton).click(); }); }); @@ -109,12 +106,9 @@ context( ); }); cy.getByTestId(votesTable).within(() => { - cy.contains('Vote passed.').should('be.visible'); cy.contains('Voting has ended.').should('be.visible'); }); - cy.getByTestId(proposalVoteProgressForPercentage) - .contains('100.00%') - .and('be.visible'); + cy.getByTestId('votes-for-percentage').should('have.text', '100%'); navigateTo(navigation.proposals); cy.contains(proposalTitle) .parentsUntil(proposalListItem) diff --git a/apps/governance-e2e/src/integration/flow/proposal-flow.cy.ts b/apps/governance-e2e/src/integration/flow/proposal-flow.cy.ts index 6b15e7f81..4b16a2793 100644 --- a/apps/governance-e2e/src/integration/flow/proposal-flow.cy.ts +++ b/apps/governance-e2e/src/integration/flow/proposal-flow.cy.ts @@ -298,9 +298,6 @@ context( getProposalFromTitle(proposalTitle).within(() => cy.getByTestId(viewProposalButton).click() ); - cy.contains('Vote breakdown').should('be.visible', { - timeout: 10000, - }); cy.getByTestId(voteButtons).should('not.exist'); cy.getByTestId('min-proposal-requirements').should( 'have.text', diff --git a/apps/governance-e2e/src/integration/flow/proposal-forms.cy.ts b/apps/governance-e2e/src/integration/flow/proposal-forms.cy.ts index f78a688e3..2b3eeed26 100644 --- a/apps/governance-e2e/src/integration/flow/proposal-forms.cy.ts +++ b/apps/governance-e2e/src/integration/flow/proposal-forms.cy.ts @@ -52,8 +52,6 @@ const enactmentDeadlineError = 'enactment-before-voting-deadline'; const proposalDownloadBtn = 'proposal-download-json'; const feedbackError = '[data-testid="Error"]'; const viewProposalBtn = 'view-proposal-btn'; -const liquidityVoteStatus = 'liquidity-votes-status'; -const tokenVoteStatus = 'token-votes-status'; const proposalJsonToggle = 'proposal-json-toggle'; const proposalJsonSection = 'proposal-json'; const vegaWalletPublicKey = Cypress.env('vegaWalletPublicKey'); @@ -421,27 +419,28 @@ context( cy.getByTestId(viewProposalBtn).click(); }); }); - cy.getByTestId(liquidityVoteStatus).should( - 'contain.text', - 'Currently expected to fail' + cy.getByTestId('lp-majority-not-met').should( + 'have.text', + '66% majority threshold not met' ); - cy.getByTestId(tokenVoteStatus).should( - 'contain.text', - 'Currently expected to fail' + + cy.getByTestId('token-majority-not-met').should( + 'have.text', + '66% majority threshold not met' ); voteForProposal('for'); - cy.getByTestId(liquidityVoteStatus).should( - 'contain.text', - 'Currently expected to pass' + cy.getByTestId('lp-majority-met').should( + 'have.text', + '66% majority threshold met' ); - cy.getByTestId(tokenVoteStatus).should( - 'contain.text', - 'Currently expected to pass' + cy.getByTestId('token-majority-met').should( + 'have.text', + '66% majority threshold met' + ); + cy.getByTestId('vote-status').should( + 'have.text', + 'Currently expected to pass by token vote' ); - cy.getByTestId('vote-breakdown-toggle').click(); - getProposalInformationFromTable('Expected to pass') - .contains('👍 by token vote') - .should('be.visible'); }); // 3001-VOTE-026 3001-VOTE-027 3001-VOTE-028 3001-VOTE-095 3001-VOTE-096 3005-PASN-001 diff --git a/apps/governance-e2e/src/integration/flow/proposal-list.cy.ts b/apps/governance-e2e/src/integration/flow/proposal-list.cy.ts index 6bd4093ea..8afa08eb4 100644 --- a/apps/governance-e2e/src/integration/flow/proposal-list.cy.ts +++ b/apps/governance-e2e/src/integration/flow/proposal-list.cy.ts @@ -11,7 +11,6 @@ import { enterRawProposalBody, generateFreeFormProposalTitle, getProposalFromTitle, - getProposalInformationFromTable, goToMakeNewProposal, governanceProposalType, submitUniqueRawProposal, @@ -30,7 +29,9 @@ const proposalType = 'proposal-type'; const proposalStatus = 'proposal-status'; const proposalClosingDate = 'vote-details'; const viewProposalButton = 'view-proposal-btn'; -const voteBreakDownToggle = 'vote-breakdown-toggle'; +const voteMajorityNotMet = 'token-majority-not-met'; +const voteMajorityMet = 'token-majority-met'; +const votesForPercentage = 'votes-for-percentage'; describe('Governance flow for proposal list', { tags: '@slow' }, function () { before('connect wallets and set approval limit', function () { @@ -121,10 +122,15 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () { submitUniqueRawProposal({ proposalTitle: proposalTitle }); getProposalFromTitle(proposalTitle).within(() => { // 3001-VOTE-039 - cy.getByTestId('participation-not-reached').should( + cy.getByTestId(voteMajorityNotMet).should( 'have.text', - 'Min. participation not reached' + '66% majority threshold not met' ); + cy.getByTestId('token-participation-not-met').should( + 'have.text', + '0.000000000000000000000015% participation threshold not met' + ); + cy.getByTestId(votesForPercentage).should('have.text', '0%'); cy.getByTestId(viewProposalButton).click(); }); voteForProposal('for'); @@ -134,16 +140,15 @@ describe('Governance flow for proposal list', { tags: '@slow' }, function () { 'have.text', 'Currently expected to pass' ); - cy.getByTestId('user-voted-yes').should('exist'); - cy.getByTestId('participation-reached').should( + cy.getByTestId(voteMajorityMet).should( 'have.text', - 'Min. participation reached' + '66% majority threshold met' + ); + cy.getByTestId(votesForPercentage).should('have.text', '100%'); + cy.getByTestId('token-participation-met').should( + 'have.text', + '0.000000000000000000000015% participation threshold met' ); - cy.getByTestId(viewProposalButton).click(); }); - cy.getByTestId(voteBreakDownToggle).click(); - getProposalInformationFromTable('Token participation met') - .contains('👍') - .should('be.visible'); }); }); diff --git a/apps/governance-e2e/src/support/governance.functions.ts b/apps/governance-e2e/src/support/governance.functions.ts index e4654c6eb..bee89d97d 100644 --- a/apps/governance-e2e/src/support/governance.functions.ts +++ b/apps/governance-e2e/src/support/governance.functions.ts @@ -146,7 +146,7 @@ export function getProposalInformationFromTable(heading: string) { } export function voteForProposal(vote: string) { - cy.contains('Vote breakdown').should('be.visible', { timeout: 10000 }); + cy.get(voteButtons).should('be.visible', { timeout: 10000 }); cy.get(voteButtons).contains(vote).click(); cy.get(dialogTitle, proposalTimeout).should( 'have.text', diff --git a/apps/governance-e2e/src/support/staking.functions.ts b/apps/governance-e2e/src/support/staking.functions.ts index cd198783d..e8ad75851 100644 --- a/apps/governance-e2e/src/support/staking.functions.ts +++ b/apps/governance-e2e/src/support/staking.functions.ts @@ -219,7 +219,9 @@ export function ensureSpecifiedUnstakedTokensAreAssociated( .eq(1) .invoke('text') .then((unstakedBalance) => { - if (parseFloat(unstakedBalance) != parseFloat(tokenAmount)) { + const tokenFloat = parseFloat(tokenAmount); + const unstakedFloat = parseFloat(unstakedBalance.replace(/,/g, '')); + if (tokenFloat != unstakedFloat) { vegaWalletTeardown(); cy.get(vegaWalletAssociatedBalance, txTimeout).contains( '0.00', diff --git a/apps/governance/src/routes/proposals/components/vote-breakdown/vote-breakdown.tsx b/apps/governance/src/routes/proposals/components/vote-breakdown/vote-breakdown.tsx index 6f0e36e00..7342b3e1e 100644 --- a/apps/governance/src/routes/proposals/components/vote-breakdown/vote-breakdown.tsx +++ b/apps/governance/src/routes/proposals/components/vote-breakdown/vote-breakdown.tsx @@ -308,7 +308,7 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
{t('tokenVotesFor')}: - @@ -317,7 +317,9 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => { {yesPercentage.toFixed(defaultDP)}%} > - + ) @@ -326,7 +328,7 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
{t('tokenVotesAgainst')}: - @@ -335,7 +337,9 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => { {noPercentage.toFixed(defaultDP)}%} > - + ) @@ -364,11 +368,13 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
{t('totalTokensVoted')}: - - ({totalTokensPercentage.toFixed(defaultDP)}%) + + ({totalTokensPercentage.toFixed(defaultDP)}%) +
diff --git a/specs/3001-VOTE-vote.md b/specs/3001-VOTE-vote.md index 703948e3e..ca4b24845 100644 --- a/specs/3001-VOTE-vote.md +++ b/specs/3001-VOTE-vote.md @@ -162,6 +162,8 @@ When looking to vote on the proposal, I... - **must** trigger a transaction that needs to be confirmed in users wallet (3001-VOTE-013) - **must** see that I need to confirm the transaction in my wallet to continue (3001-VOTE-014) - **must** see option to change my vote (vote again in same or different direction) (3001-VOTE-090) + - **must** see two vote status bars, one showing majority voting yes/no, and the other showing participation progress. The maximum value for the progress bar should be the threshold for that proposal type. (3001-VOTE-023) + - **must** see when the participation bar reaches 100% (i.e. the network param threshold is met) the indicator text on top of it reads "[network param]% participation threshold met". Otherwise it says "[network param]% participation threshold not met". (3001-VOTE-024) For open market change proposals, all of the above and: