diff --git a/apps/token-e2e/src/fixtures/proposals/new-asset.json b/apps/token-e2e/src/fixtures/proposals/new-asset.json new file mode 100644 index 000000000..ac7cade60 --- /dev/null +++ b/apps/token-e2e/src/fixtures/proposals/new-asset.json @@ -0,0 +1,13 @@ +{ + "changes": { + "name": "USDT Coin", + "symbol": "USDT", + "decimals": "18", + "quantum": "1", + "erc20": { + "contractAddress": "0xb404c51bbc10dcbe948077f18a4b8e553d160084", + "withdrawThreshold": "10", + "lifetimeLimit": "10" + } + } +} diff --git a/apps/token-e2e/src/fixtures/proposals/new-market.json b/apps/token-e2e/src/fixtures/proposals/new-market.json new file mode 100644 index 000000000..4e6093343 --- /dev/null +++ b/apps/token-e2e/src/fixtures/proposals/new-market.json @@ -0,0 +1,80 @@ +{ + "changes": { + "decimalPlaces": "5", + "positionDecimalPlaces": "5", + "instrument": { + "name": "Oranges Daily", + "code": "ORANGES.24h", + "future": { + "settlementAsset": "8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4", + "quoteName": "tEuro", + "settlementDataDecimals": 5, + "oracleSpecForSettlementPrice": { + "pubKeys": ["0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC"], + "filters": [ + { + "key": { + "name": "prices.BTC.value", + "type": "TYPE_INTEGER" + }, + "conditions": [ + { + "operator": "OPERATOR_GREATER_THAN", + "value": "0" + } + ] + } + ] + }, + "oracleSpecForTradingTermination": { + "pubKeys": ["0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC"], + "filters": [ + { + "key": { + "name": "vegaprotocol.builtin.timestamp", + "type": "TYPE_TIMESTAMP" + }, + "conditions": [ + { + "operator": "OPERATOR_GREATER_THAN_OR_EQUAL", + "value": "1648684800000000000" + } + ] + } + ] + }, + "oracleSpecBinding": { + "settlementPriceProperty": "prices.BTC.value", + "tradingTerminationProperty": "vegaprotocol.builtin.timestamp" + } + } + }, + "metadata": ["sector:food", "sector:materials", "source:docs.vega.xyz"], + "priceMonitoringParameters": { + "triggers": [ + { + "horizon": "43200", + "probability": "0.9999999", + "auctionExtension": "600" + } + ] + }, + "liquidityMonitoringParameters": { + "targetStakeParameters": { + "timeWindow": "3600", + "scalingFactor": 10 + }, + "triggeringRatio": 0.7, + "auctionExtension": "1" + }, + "logNormal": { + "tau": 0.0001140771161, + "riskAversionParameter": 0.001, + "params": { + "mu": 0, + "r": 0.016, + "sigma": 0.8 + } + } + } +} diff --git a/apps/token-e2e/src/fixtures/proposals/update-market.json b/apps/token-e2e/src/fixtures/proposals/update-market.json new file mode 100644 index 000000000..a307255cf --- /dev/null +++ b/apps/token-e2e/src/fixtures/proposals/update-market.json @@ -0,0 +1,69 @@ +{ + "marketId": "315a8e48db0a292c92b617264728048c82c20efc922c75fd292fc54e5c727c81", + "changes": { + "instrument": { + "code": "ORANGES.24h", + "future": { + "quoteName": "tEuro", + "settlementDataDecimals": 5, + "oracleSpecForSettlementPrice": { + "pubKeys": ["0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC"], + "filters": [ + { + "key": { + "name": "prices.BTC.value", + "type": "TYPE_INTEGER" + }, + "conditions": [ + { + "operator": "OPERATOR_GREATER_THAN", + "value": "0" + } + ] + } + ] + }, + "oracleSpecForTradingTermination": { + "pubKeys": ["0xfCEAdAFab14d46e20144F48824d0C09B1a03F2BC"], + "filters": [ + { + "key": { + "name": "vegaprotocol.builtin.timestamp", + "type": "TYPE_TIMESTAMP" + }, + "conditions": [ + { + "operator": "OPERATOR_GREATER_THAN_OR_EQUAL", + "value": "1648684800000000000" + } + ] + } + ] + }, + "oracleSpecBinding": { + "settlementPriceProperty": "prices.BTC.value", + "tradingTerminationProperty": "vegaprotocol.builtin.timestamp" + } + } + }, + "metadata": ["sector:energy", "sector:food", "source:docs.vega.xyz"], + "priceMonitoringParameters": { + "triggers": [ + { + "horizon": "43200", + "probability": "0.9999999", + "auctionExtension": "600" + } + ] + }, + "logNormal": { + "tau": 0.0001140771161, + "riskAversionParameter": 0.001, + "params": { + "mu": 0, + "r": 0.016, + "sigma": 0.3 + } + } + } +} diff --git a/apps/token-e2e/src/integration/flow/governance-flow.cy.js b/apps/token-e2e/src/integration/flow/governance-flow.cy.js index f6e7549de..73ee7f164 100644 --- a/apps/token-e2e/src/integration/flow/governance-flow.cy.js +++ b/apps/token-e2e/src/integration/flow/governance-flow.cy.js @@ -28,7 +28,11 @@ const changeVoteButton = '[data-testid="change-vote-button"]'; const proposalDetailsTitle = '[data-testid="proposal-title"]'; const proposalDetailsDescription = '[data-testid="proposal-description"]'; const proposalVoteDeadline = '[data-testid="proposal-vote-deadline"]'; +const minVoteButton = '[data-testid="min-vote"]'; +const maxVoteButton = '[data-testid="max-vote"]'; const voteButtons = '[data-testid="vote-buttons"]'; +const votingDate = '[data-testid="voting-date"]'; +const voteTwoMinExtraNote = '[data-testid="voting-2-mins-extra"]'; const voteStatus = '[data-testid="vote-status"]'; const rejectProposalsLink = '[href="/governance/rejected"]'; const feedbackError = '[data-testid="Error"]'; @@ -152,13 +156,17 @@ context( .and('have.text', 'There are no enacted or rejected proposals'); }); + // 1005-PROP-002 + // 1005-PROP-003 it('Submit a proposal form - shows how many vega tokens are required to make a proposal', function () { + // 1005-PROP-005 cy.go_to_make_new_proposal(governanceProposalType.NEW_MARKET); cy.contains( `You must have at least ${this.minProposerBalance} VEGA associated to make a proposal` ).should('be.visible'); }); + // 1005-PROP-011 it( 'Able to submit a valid freeform proposal - with minimum required tokens associated', { tags: '@smoke' }, @@ -166,20 +174,19 @@ context( cy.ensure_specified_unstaked_tokens_are_associated( this.minProposerBalance ); - cy.navigate_to_page_if_not_already_loaded('governance'); cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); + cy.get(minVoteButton).should('be.visible'); // 1005-PROP-008 + cy.get(maxVoteButton).should('be.visible'); + cy.get(votingDate).should('not.be.empty'); + cy.get(voteTwoMinExtraNote).should( + 'contain.text', + 'we add 2 minutes of extra time' + ); cy.enter_unique_freeform_proposal_body('50'); cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Confirm transaction in wallet', epochTimeout).should( - 'be.visible' - ); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should( - 'be.visible' - ); - cy.get(dialogCloseButton).click(); + // 1005-PROP-012 + // 1005-PROP-016 + cy.wait_for_proposal_submitted(); } ); @@ -209,54 +216,11 @@ context( cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); cy.enter_unique_freeform_proposal_body('50'); cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should('be.visible'); - cy.get(dialogCloseButton).click(); - }); - - it('Newly created freeform proposals list - able to filter by proposalID to show it in list', function () { - cy.ensure_specified_unstaked_tokens_are_associated( - this.minProposerBalance - ); - cy.navigate_to_page_if_not_already_loaded('governance'); - cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); - cy.enter_unique_freeform_proposal_body('50'); - cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should('be.visible'); - cy.get(dialogCloseButton).click(); - cy.wait_for_proposal_sync(); - cy.navigate_to('governance'); - cy.wait_for_spinner(); - cy.wait('@proposalSubmissionCompletion') - .its(proposalResponseProposalIdPath) - .then((proposalId) => { - cy.get('[data-testid="set-proposals-filter-visible"]').click(); - cy.get('[data-testid="filter-input"]').type(proposalId); - cy.get(`#${proposalId}`).should('contain', proposalId); - }); + cy.wait_for_proposal_submitted(); }); it('Newly created freeform proposals list - able to filter by proposerID to show it in list', function () { - cy.ensure_specified_unstaked_tokens_are_associated( - this.minProposerBalance - ); - cy.navigate_to_page_if_not_already_loaded('governance'); - cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); - cy.enter_unique_freeform_proposal_body('50'); - cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should('be.visible'); - cy.get(dialogCloseButton).click(); - cy.wait_for_proposal_sync(); - cy.navigate_to('governance'); - cy.wait_for_spinner(); + createFreeformProposal(this.minProposerBalance); cy.wait('@proposalSubmissionCompletion').then((proposal) => { let proposerId = proposal.request.body.variables.partyId; let proposalId = proposal.response.body.data.busEvents[0].event.id; @@ -267,21 +231,7 @@ context( }); it('Newly created freeform proposals list - shows title and portion of summary', function () { - cy.ensure_specified_unstaked_tokens_are_associated( - this.minProposerBalance - ); - cy.navigate_to_page_if_not_already_loaded('governance'); - cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); - cy.enter_unique_freeform_proposal_body('50').as('freeformProposal'); - cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should('be.visible'); - cy.get(dialogCloseButton).click(); - cy.wait_for_proposal_sync(); - cy.navigate_to('governance'); - cy.wait_for_spinner(); + createFreeformProposal(this.minProposerBalance); cy.wait('@proposalSubmissionCompletion') .its(proposalResponseProposalIdPath) .then((proposalId) => { @@ -306,31 +256,24 @@ context( it('Newly created freeform proposals list - shows open proposals in an open state', function () { // 1004-VOTE-004 // 1004-VOTE-035 - cy.ensure_specified_unstaked_tokens_are_associated( - this.minProposerBalance - ); - cy.navigate_to_page_if_not_already_loaded('governance'); - cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); - cy.enter_unique_freeform_proposal_body('50'); - cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should('be.visible'); - cy.get(dialogCloseButton).click(); - cy.wait_for_proposal_sync(); - cy.navigate_to('governance'); - cy.wait_for_spinner(); + createFreeformProposal(this.minProposerBalance); cy.wait('@proposalSubmissionCompletion') .its(proposalResponseProposalIdPath) .then((proposalId) => { cy.get(openProposals).within(() => { - // 1004-VOTE-035 - cy.get(`#${proposalId}`) - .should('contain', proposalId) - .and('contain', 'Open') - .and('be.visible'); + cy.get(`#${proposalId}`).within(() => { + cy.get(viewProposalButton).should('be.visible').click(); + }); }); + cy.get_proposal_information_from_table('ID') + .contains(proposalId) + .and('be.visible'); + cy.get_proposal_information_from_table('State') + .contains('STATE_OPEN') + .and('be.visible'); + cy.get_proposal_information_from_table('Type') + .contains('NewFreeform') + .and('be.visible'); }); }); @@ -346,18 +289,10 @@ context( (Number(this.minCloseHours) + 2).toString(), ]; for (var index = 0; index < proposalHours.length; index++) { - cy.navigate_to_page_if_not_already_loaded('governance'); cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); cy.enter_unique_freeform_proposal_body(proposalHours[index]); cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should( - 'be.visible' - ); - cy.get(dialogCloseButton).click(); - cy.wait_for_proposal_sync(); + cy.wait_for_proposal_submitted(); } }); // Ensuring that proposals are not posted in same order as sort order @@ -381,21 +316,7 @@ context( // Skipping test due to bug: #1320 it.skip('Newly created freeform proposals list - shows proposal parcipitation - both met and not', function () { - cy.ensure_specified_unstaked_tokens_are_associated( - this.minProposerBalance - ); - cy.navigate_to_page_if_not_already_loaded('governance'); - cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); - cy.enter_unique_freeform_proposal_body('50'); - cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should('be.visible'); - cy.get(dialogCloseButton).click(); - cy.wait_for_proposal_sync(); - cy.navigate_to('governance'); - cy.wait_for_spinner(); + createFreeformProposal(this.minProposerBalance); cy.get_submitted_proposal_from_proposal_list() .as('submittedProposal') .within(() => { @@ -430,20 +351,7 @@ context( // Skipping test due to bug - should be solved when #1223 released it.skip('Newly created freeform proposal details - shows proposal title and full description', function () { - cy.ensure_specified_unstaked_tokens_are_associated( - this.minProposerBalance - ); - cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); - cy.enter_unique_freeform_proposal_body('50').as('freeformProposal'); - cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should('be.visible'); - cy.get(dialogCloseButton).click(); - cy.wait_for_proposal_sync(); - cy.navigate_to('governance'); - cy.wait_for_spinner(); + createFreeformProposal(this.minProposerBalance); cy.wait('@proposalSubmissionCompletion') .its(proposalResponseProposalIdPath) .then((proposalId) => { @@ -464,23 +372,10 @@ context( }); }); + // 1005-todo-PROP-019 // Skipping test due to bug - should be solved when #1223 released it.skip('Newly created freeform proposal details - shows full link included in description', function () { - cy.ensure_specified_unstaked_tokens_are_associated( - this.minProposerBalance - ); - cy.navigate_to_page_if_not_already_loaded('governance'); - cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); - cy.enter_unique_freeform_proposal_body('50').as('freeformProposal'); - cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should('be.visible'); - cy.get(dialogCloseButton).click(); - cy.wait_for_proposal_sync(); - cy.navigate_to('governance'); - cy.wait_for_spinner(); + createFreeformProposal(this.minProposerBalance); cy.wait('@proposalSubmissionCompletion') .its(proposalResponseProposalIdPath) .then((proposalId) => { @@ -502,61 +397,18 @@ context( }); }); - it('Newly created freeform proposal details - shows open proposal in an open state', function () { - cy.ensure_specified_unstaked_tokens_are_associated( - this.minProposerBalance - ); - cy.navigate_to_page_if_not_already_loaded('governance'); - cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); - cy.enter_unique_freeform_proposal_body('50'); - cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should('be.visible'); - cy.get(dialogCloseButton).click(); - cy.wait_for_proposal_sync(); - cy.navigate_to('governance'); - cy.wait_for_spinner(); - cy.wait('@proposalSubmissionCompletion') - .its(proposalResponseProposalIdPath) - .then((proposalId) => { - cy.get(openProposals).within(() => { - cy.get(`#${proposalId}`).within(() => { - cy.get(viewProposalButton).should('be.visible').click(); - }); - }); - cy.get_proposal_information_from_table('ID') - .contains(proposalId) - .and('be.visible'); - cy.get_proposal_information_from_table('State') - .contains('STATE_OPEN') - .and('be.visible'); - cy.get_proposal_information_from_table('Type') - .contains('NewFreeform') - .and('be.visible'); - }); - }); - it('Newly created freeform proposal details - shows proposed and closing dates', function () { const closingVoteHrs = '72'; cy.ensure_specified_unstaked_tokens_are_associated( this.minProposerBalance ); - cy.navigate_to_page_if_not_already_loaded('governance'); cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); cy.create_ten_digit_unix_timestamp_for_specified_days('3').then( (closingDateTimestamp) => { cy.enter_unique_freeform_proposal_body(closingVoteHrs); cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should( - 'be.visible' - ); - cy.get(dialogCloseButton).click(); + cy.wait_for_proposal_submitted(); cy.wait_for_proposal_sync(); cy.navigate_to('governance'); cy.wait_for_spinner(); @@ -586,21 +438,7 @@ context( it('Newly created freeform proposal details - shows default status set to fail', function () { // 1004-VOTE-037 // 1004-VOTE-040 - cy.ensure_specified_unstaked_tokens_are_associated( - this.minProposerBalance - ); - cy.navigate_to_page_if_not_already_loaded('governance'); - cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); - cy.enter_unique_freeform_proposal_body('50'); - cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should('be.visible'); - cy.get(dialogCloseButton).click(); - cy.wait_for_proposal_sync(); - cy.navigate_to('governance'); - cy.wait_for_spinner(); + createFreeformProposal(this.minProposerBalance); cy.get_submitted_proposal_from_proposal_list().within(() => cy.get(viewProposalButton).click() ); @@ -622,21 +460,7 @@ context( }); it('Newly created freeform proposal details - ability to vote for proposal - with minimum required tokens associated', function () { - cy.ensure_specified_unstaked_tokens_are_associated( - this.minProposerBalance - ); - cy.navigate_to_page_if_not_already_loaded('governance'); - cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); - cy.enter_unique_freeform_proposal_body('50'); - cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should('be.visible'); - cy.get(dialogCloseButton).click(); - cy.wait_for_proposal_sync(); - cy.navigate_to('governance'); - cy.wait_for_spinner(); + createFreeformProposal(this.minProposerBalance); cy.get_submitted_proposal_from_proposal_list() .as('submittedProposal') .within(() => cy.get(viewProposalButton).click()); @@ -689,21 +513,7 @@ context( }); it('Newly created freeform proposal details - ability to vote against proposal - with minimum required tokens associated', function () { - cy.ensure_specified_unstaked_tokens_are_associated( - this.minProposerBalance - ); - cy.navigate_to_page_if_not_already_loaded('governance'); - cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); - cy.enter_unique_freeform_proposal_body('50'); - cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should('be.visible'); - cy.get(dialogCloseButton).click(); - cy.wait_for_proposal_sync(); - cy.navigate_to('governance'); - cy.wait_for_spinner(); + createFreeformProposal(this.minProposerBalance); cy.get_submitted_proposal_from_proposal_list() .as('submittedProposal') .within(() => cy.get(viewProposalButton).click()); @@ -750,21 +560,7 @@ context( }); it('Newly created freeform proposal details - ability to change vote from against to for - with minimum required tokens associated', function () { - cy.ensure_specified_unstaked_tokens_are_associated( - this.minProposerBalance - ); - cy.navigate_to_page_if_not_already_loaded('governance'); - cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); - cy.enter_unique_freeform_proposal_body('50'); - cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should('be.visible'); - cy.get(dialogCloseButton).click(); - cy.wait_for_proposal_sync(); - cy.navigate_to('governance'); - cy.wait_for_spinner(); + createFreeformProposal(this.minProposerBalance); cy.get_submitted_proposal_from_proposal_list() .as('submittedProposal') .within(() => cy.get(viewProposalButton).click()); @@ -804,21 +600,7 @@ context( }); it('Newly created freeform proposal details - ability to change vote from for to against - with minimum required tokens associated', function () { - cy.ensure_specified_unstaked_tokens_are_associated( - this.minProposerBalance - ); - cy.navigate_to_page_if_not_already_loaded('governance'); - cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); - cy.enter_unique_freeform_proposal_body('50'); - cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should('be.visible'); - cy.get(dialogCloseButton).click(); - cy.wait_for_proposal_sync(); - cy.navigate_to('governance'); - cy.wait_for_spinner(); + createFreeformProposal(this.minProposerBalance); cy.get_submitted_proposal_from_proposal_list() .as('submittedProposal') .within(() => cy.get(viewProposalButton).click()); @@ -856,21 +638,7 @@ context( }); it('Newly created freeform proposal details - ability to increase associated tokens - so that vote sways result', function () { - cy.ensure_specified_unstaked_tokens_are_associated( - this.minProposerBalance - ); - cy.navigate_to_page_if_not_already_loaded('governance'); - cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); - cy.enter_unique_freeform_proposal_body('50'); - cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should('be.visible'); - cy.get(dialogCloseButton).click(); - cy.wait_for_proposal_sync(); - cy.navigate_to('governance'); - cy.wait_for_spinner(); + createFreeformProposal(this.minProposerBalance); cy.get_submitted_proposal_from_proposal_list() .as('submittedProposal') .within(() => cy.get(viewProposalButton).click()); @@ -935,7 +703,6 @@ context( cy.ensure_specified_unstaked_tokens_are_associated( this.minProposerBalance ); - cy.navigate_to_page_if_not_already_loaded('governance'); cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); cy.enter_unique_freeform_proposal_body('40'); cy.get(newProposalSubmitButton).should('be.visible').click(); @@ -948,7 +715,6 @@ context( cy.ensure_specified_unstaked_tokens_are_associated( this.minProposerBalance ); - cy.navigate_to_page_if_not_already_loaded('governance'); cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); cy.enter_unique_freeform_proposal_body('100000'); cy.get(newProposalSubmitButton).should('be.visible').click(); @@ -962,7 +728,6 @@ context( cy.ensure_specified_unstaked_tokens_are_associated( this.minProposerBalance ); - cy.navigate_to_page_if_not_already_loaded('governance'); cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); cy.enter_unique_freeform_proposal_body('500000000'); cy.get(newProposalSubmitButton).should('be.visible').click(); @@ -1013,7 +778,6 @@ context( cy.ensure_specified_unstaked_tokens_are_associated( this.minProposerBalance - 0.000001 ); - cy.navigate_to_page_if_not_already_loaded('governance'); cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); cy.enter_unique_freeform_proposal_body('49'); cy.get(newProposalSubmitButton).should('be.visible').click(); @@ -1032,7 +796,6 @@ context( cy.ensure_specified_unstaked_tokens_are_associated( this.minProposerBalance ); - cy.navigate_to_page_if_not_already_loaded('governance'); cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); cy.create_ten_digit_unix_timestamp_for_specified_days('1').then( (closingDateTimestamp) => { @@ -1066,7 +829,6 @@ context( cy.ensure_specified_unstaked_tokens_are_associated( this.minProposerBalance ); - cy.navigate_to_page_if_not_already_loaded('governance'); cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); cy.create_ten_digit_unix_timestamp_for_specified_days('1').then( (closingDateTimestamp) => { @@ -1095,19 +857,15 @@ context( }); // Have to skip because #1326 bug doesn't handle below scenario + // 1005-todo-PROP-009 it.skip('Unable to vote on a freeform proposal - when some but not enough vega associated', function () { cy.ensure_specified_unstaked_tokens_are_associated( this.minProposerBalance ); - cy.navigate_to_page_if_not_already_loaded('governance'); cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); cy.enter_unique_freeform_proposal_body('50'); cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should('be.visible'); - cy.get(dialogCloseButton).click(); + cy.wait_for_proposal_submitted(); cy.wait_for_proposal_sync(); cy.staking_page_disassociate_tokens('0.0001'); cy.get(vegaWallet).within(() => { @@ -1127,20 +885,7 @@ context( }); it('Unable to vote on a freeform proposal - when vega wallet disconnected - option to connect from within', function () { - cy.ensure_specified_unstaked_tokens_are_associated( - this.minProposerBalance - ); - cy.navigate_to_page_if_not_already_loaded('governance'); - cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); - cy.enter_unique_freeform_proposal_body('50'); - cy.get(newProposalSubmitButton).should('be.visible').click(); - cy.contains('Awaiting network confirmation', epochTimeout).should( - 'be.visible' - ); - cy.contains('Proposal submitted', proposalTimeout).should('be.visible'); - cy.get(dialogCloseButton).click(); - cy.wait_for_proposal_sync(); - cy.navigate_to('governance'); + createFreeformProposal(this.minProposerBalance); cy.wait_for_spinner(); cy.get('[data-testid="manage-vega-wallet"]').click(); cy.get('[data-testid="disconnect"]').click(); @@ -1171,6 +916,17 @@ context( cy.contains('You voted: Against').should('be.visible'); }); + function createFreeformProposal(proposerBalance) { + cy.ensure_specified_unstaked_tokens_are_associated(proposerBalance); + cy.go_to_make_new_proposal(governanceProposalType.FREEFORM); + cy.enter_unique_freeform_proposal_body('50').as('freeformProposal'); + cy.get(newProposalSubmitButton).should('be.visible').click(); + cy.wait_for_proposal_submitted(); + cy.wait_for_proposal_sync(); + cy.navigate_to('governance'); + cy.wait_for_spinner(); + } + after( 'teardown environment to prevent test data bleeding into other tests', function () { diff --git a/apps/token-e2e/src/integration/flow/governance-forms-flow.cy.js b/apps/token-e2e/src/integration/flow/governance-forms-flow.cy.js new file mode 100644 index 000000000..14328d25e --- /dev/null +++ b/apps/token-e2e/src/integration/flow/governance-forms-flow.cy.js @@ -0,0 +1,176 @@ +const newProposalSubmitButton = '[data-testid="proposal-submit"]'; +const proposalVoteDeadline = '[data-testid="proposal-vote-deadline"]'; +const proposalValidationDeadline = + '[data-testid="proposal-validation-deadline"]'; +const proposalParameterSelect = '[data-testid="proposal-parameter-select"]'; +const proposalMarketSelect = '[data-testid="proposal-market-select"]'; +const newProposalTitle = '[data-testid="proposal-title"]'; +const newProposalDescription = '[data-testid="proposal-description"]'; +const newProposalTerms = '[data-testid="proposal-terms"]'; +const currentParameterValue = + '[data-testid="selected-proposal-param-current-value"]'; +const newProposedParameterValue = + '[data-testid="selected-proposal-param-new-value"]'; +const dialogCloseButton = '[data-testid="dialog-close"]'; +const inputError = '[data-testid="input-error-text"]'; +const epochTimeout = Cypress.env('epochTimeout'); +const proposalTimeout = { timeout: 14000 }; + +const governanceProposalType = { + NETWORK_PARAMETER: 'Network parameter', + NEW_MARKET: 'New market', + UPDATE_MARKET: 'Update market', + NEW_ASSET: 'New asset', + FREEFORM: 'Freeform', +}; + +context( + 'Governance flow - form validations for different governance proposals', + { tags: '@slow' }, + function () { + before('connect wallets and set approval limit', function () { + cy.vega_wallet_import(); + cy.visit('/'); + cy.verify_page_header('The $VEGA token'); + cy.vega_wallet_connect(); + cy.vega_wallet_set_specified_approval_amount('1000'); + cy.reload(); + cy.wait_for_spinner(); + cy.verify_page_header('The $VEGA token'); + cy.ethereum_wallet_connect(); + }); + + beforeEach('visit governance tab', function () { + cy.navigate_to('governance'); + cy.wait_for_spinner(); + cy.intercept('POST', '/query', (req) => { + if (req.body.operationName === 'ProposalEvent') { + req.alias = 'proposalSubmissionCompletion'; + } + }); + cy.ensure_specified_unstaked_tokens_are_associated('1'); + }); + + it('Able to submit valid update network parameter proposal', function () { + cy.navigate_to_page_if_not_already_loaded('governance'); + cy.go_to_make_new_proposal(governanceProposalType.NETWORK_PARAMETER); + // 1005-PROP-006 + cy.get(newProposalTitle).type('Test update network parameter proposal'); + // 1005-PROP-007 + cy.get(newProposalDescription).type('E2E test for proposals'); + + cy.get(proposalParameterSelect).find('option').should('have.length', 109); + cy.get(proposalParameterSelect).select( + 'governance_proposal_asset_minEnact' + ); + cy.get(currentParameterValue).should('have.value', '2s'); + cy.get(newProposedParameterValue).type('5s'); + cy.get(newProposalSubmitButton).should('be.visible').click(); + cy.wait_for_proposal_submitted(); + }); + + it('Unable to submit network parameter with missing/invalid fields', function () { + cy.navigate_to_page_if_not_already_loaded('governance'); + cy.go_to_make_new_proposal(governanceProposalType.NETWORK_PARAMETER); + cy.get(newProposalSubmitButton).should('be.visible').click(); + cy.get(inputError).should('have.length', 3); + cy.get(newProposalTitle).type( + 'Invalid update network parameter proposal' + ); + cy.get(newProposalDescription).type('E2E invalid test for proposals'); + cy.get(proposalParameterSelect).select( + 'spam_protection_proposal_min_tokens' + ); + cy.get(newProposedParameterValue).type('0'); + cy.get(proposalVoteDeadline).clear().type('0'); + cy.get(newProposalSubmitButton).click(); + cy.contains('Awaiting network confirmation', epochTimeout).should( + 'not.exist' + ); + cy.get(proposalVoteDeadline).clear().type('9000'); + cy.get(newProposalSubmitButton).click(); + cy.contains('Awaiting network confirmation', epochTimeout).should( + 'not.exist' + ); + }); + + it('Able to submit valid new market proposal', function () { + cy.go_to_make_new_proposal(governanceProposalType.NEW_MARKET); + cy.get(newProposalTitle).type('Test new market proposal'); + cy.get(newProposalDescription).type('E2E test for proposals'); + cy.fixture('/proposals/new-market').then((newMarketProposal) => { + let newMarketPayload = JSON.stringify(newMarketProposal); + cy.get(newProposalTerms).type(newMarketPayload, { + parseSpecialCharSequences: false, + delay: 2, + }); + }); + cy.get(newProposalSubmitButton).should('be.visible').click(); + cy.wait_for_proposal_submitted(); + }); + + it('Unable to submit new market proposal with missing/invalid fields', function () { + cy.go_to_make_new_proposal(governanceProposalType.NEW_MARKET); + cy.get(newProposalSubmitButton).should('be.visible').click(); + cy.get(inputError).should('have.length', 3); + }); + + // skipped because of bug #1605 + it.skip('Able to submit update market proposal', function () { + const marketId = + '315a8e48db0a292c92b617264728048c82c20efc922c75fd292fc54e5c727c81'; + cy.go_to_make_new_proposal(governanceProposalType.UPDATE_MARKET); + cy.get(newProposalTitle).type('Test update asset proposal'); + cy.get(newProposalDescription).type('E2E test for proposals'); + cy.get(proposalMarketSelect).select(marketId); + cy.get('[data-testid="update-market-details"]').within(() => { + cy.get('dd').eq(0).should('have.text', 'Oranges Daily'); + cy.get('dd').eq(1).should('have.text', 'ORANGES.24h'); + cy.get('dd').eq(2).should('have.text', marketId); + }); + cy.fixture('/proposals/update-market').then((updateMarketProposal) => { + let newUpdateMarketProposal = JSON.stringify(updateMarketProposal); + cy.get(newProposalTerms).type(newUpdateMarketProposal, { + parseSpecialCharSequences: false, + delay: 2, + }); + }); + cy.get(newProposalSubmitButton).should('be.visible').click(); + cy.wait_for_proposal_submitted(); + }); + + it('Able to submit new asset proposal', function () { + cy.go_to_make_new_proposal(governanceProposalType.NEW_ASSET); + cy.get(newProposalTitle).type('Test new asset proposal'); + cy.get(newProposalDescription).type('E2E test for proposals'); + cy.fixture('/proposals/new-asset').then((newAssetProposal) => { + let newAssetPayload = JSON.stringify(newAssetProposal); + cy.get(newProposalTerms).type(newAssetPayload, { + parseSpecialCharSequences: false, + delay: 2, + }); + }); + cy.get(newProposalSubmitButton).should('be.visible').click(); + cy.contains('Awaiting network confirmation', epochTimeout).should( + 'be.visible' + ); + cy.contains('Proposal waiting for node vote', proposalTimeout).should( + 'be.visible' + ); + cy.get(dialogCloseButton).click(); + }); + + it('Unable to submit new asset proposal with missing/invalid fields', function () { + cy.go_to_make_new_proposal(governanceProposalType.NEW_ASSET); + cy.get(newProposalSubmitButton).should('be.visible').click(); + cy.get(inputError).should('have.length', 3); + cy.get(newProposalTitle).type('Invalid new asset proposal'); + cy.get(newProposalDescription).type('Invalid E2E test for proposals'); + cy.get(proposalValidationDeadline).clear().type('2'); + cy.get(newProposalSubmitButton).click(); + cy.contains('Awaiting network confirmation', epochTimeout).should( + 'not.exist' + ); + }); + } +); diff --git a/apps/token-e2e/src/integration/view/governance.cy.js b/apps/token-e2e/src/integration/view/governance.cy.js index a52e4ec42..b950b3b3b 100644 --- a/apps/token-e2e/src/integration/view/governance.cy.js +++ b/apps/token-e2e/src/integration/view/governance.cy.js @@ -29,6 +29,7 @@ context( .and('have.attr', 'href') .and('equal', governanceDocsUrl); + // 1005-PROP-001 cy.request(governanceDocsUrl) .its('body') .then((body) => { diff --git a/apps/token-e2e/src/support/governance.functions.js b/apps/token-e2e/src/support/governance.functions.js index 9eb5887bc..d3bcaf7ad 100644 --- a/apps/token-e2e/src/support/governance.functions.js +++ b/apps/token-e2e/src/support/governance.functions.js @@ -7,6 +7,9 @@ const proposalResponseProposalIdPath = const voteButtons = '[data-testid="vote-buttons"]'; const txTimeout = Cypress.env('txTimeout'); const proposalVoteDeadline = '[data-testid="proposal-vote-deadline"]'; +const dialogCloseButton = '[data-testid="dialog-close"]'; +const epochTimeout = Cypress.env('epochTimeout'); +const proposalTimeout = { timeout: 14000 }; Cypress.Commands.add( 'convert_unix_timestamp_to_governance_data_table_date_format', @@ -165,6 +168,15 @@ Cypress.Commands.add('get_sort_order_of_supplied_array', (suppliedArray) => { }); Cypress.Commands.add('go_to_make_new_proposal', (proposalType) => { + cy.navigate_to_page_if_not_already_loaded('governance'); cy.get(newProposalButton).should('be.visible').click(); cy.get('li').contains(proposalType).click(); }); + +Cypress.Commands.add('wait_for_proposal_submitted', () => { + cy.contains('Awaiting network confirmation', epochTimeout).should( + 'be.visible' + ); + cy.contains('Proposal submitted', proposalTimeout).should('be.visible'); + cy.get(dialogCloseButton).click(); +}); diff --git a/apps/token-e2e/src/support/staking.functions.js b/apps/token-e2e/src/support/staking.functions.js index 0c9afa870..f64abd2f8 100644 --- a/apps/token-e2e/src/support/staking.functions.js +++ b/apps/token-e2e/src/support/staking.functions.js @@ -20,7 +20,7 @@ const vegaKeySelector = '#vega-key-selector'; const txTimeout = Cypress.env('txTimeout'); const epochTimeout = Cypress.env('epochTimeout'); -Cypress.Commands.add('wait_for_begining_of_epoch', () => { +Cypress.Commands.add('wait_for_beginning_of_epoch', () => { cy.contains('Waiting for next epoch to start', epochTimeout).should( 'not.exist' ); @@ -34,7 +34,7 @@ Cypress.Commands.add('staking_validator_page_add_stake', (stake) => { cy.wait_for_spinner(); cy.get(addStakeRadioButton, epochTimeout).click({ force: true }); cy.get(tokenAmountInputBox).type(stake); - cy.wait_for_begining_of_epoch(); + cy.wait_for_beginning_of_epoch(); cy.get(tokenSubmitButton, epochTimeout) .should('be.enabled') .and('contain', `Add ${stake} $VEGA tokens`) @@ -47,7 +47,7 @@ Cypress.Commands.add('staking_validator_page_remove_stake', (stake) => { cy.wait_for_spinner(); cy.get(removeStakeRadioButton, epochTimeout).click(); cy.get(tokenAmountInputBox).type(stake); - cy.wait_for_begining_of_epoch(); + cy.wait_for_beginning_of_epoch(); cy.get(tokenSubmitButton) .should('be.enabled', epochTimeout) .and('contain', `Remove ${stake} $VEGA tokens at the end of epoch`) @@ -151,7 +151,7 @@ Cypress.Commands.add( cy.wait_for_spinner(); cy.contains('Loading...', epochTimeout).should('not.exist'); cy.contains('Total stake this epoch').should('be.visible'); - cy.wait_for_begining_of_epoch(); + cy.wait_for_beginning_of_epoch(); // below is to ensure validator list is shown cy.get(stakeValidatorListName, { timeout: 10000 }).should('exist'); cy.get(stakeValidatorListPendingStake, txTimeout).should( @@ -180,7 +180,7 @@ Cypress.Commands.add( cy.wait_for_spinner(); cy.contains('Loading...', epochTimeout).should('not.exist'); cy.contains('Total stake this epoch').should('be.visible'); - cy.wait_for_begining_of_epoch(); + cy.wait_for_beginning_of_epoch(); cy.get(`[row-id="${positionOnList}"]`).within(() => { cy.get(stakeValidatorListName).should('have.text', expectedValidatorName); cy.get(stakeValidatorListTotalStake, epochTimeout).should(