diff --git a/apps/token-e2e/cypress.config.js b/apps/token-e2e/cypress.config.js index efd954d0d..30daf6fee 100644 --- a/apps/token-e2e/cypress.config.js +++ b/apps/token-e2e/cypress.config.js @@ -23,6 +23,7 @@ module.exports = defineConfig({ chromeWebSecurity: false, viewportWidth: 1440, viewportHeight: 900, + numTestsKeptInMemory: 4, }, env: { ethProviderUrl: 'http://localhost:8545/', @@ -40,8 +41,8 @@ module.exports = defineConfig({ vegaWalletPublicKeyShort: '02ecea…2f65', vegaTokenContractAddress: '0xF41bD86d462D36b997C0bbb4D97a0a3382f205B7', vegaTokenAddress: '0x67175Da1D5e966e40D11c4B2519392B2058373de', - txTimeout: { timeout: 40000 }, - epochTimeout: { timeout: 10000 }, + txTimeout: { timeout: 70000 }, + epochTimeout: { timeout: 11000 }, blockConfirmations: 3, }, }); diff --git a/apps/token-e2e/src/integration/flow/staking-flow.cy.js b/apps/token-e2e/src/integration/flow/staking-flow.cy.js index 0d278ec75..574dae11c 100644 --- a/apps/token-e2e/src/integration/flow/staking-flow.cy.js +++ b/apps/token-e2e/src/integration/flow/staking-flow.cy.js @@ -55,7 +55,7 @@ context('Staking Tab - with eth and vega wallets connected', function () { ); // 1002-STKE-004 - it('Able to stake against a validator', function () { + it('Able to stake against a validator - using vega from wallet', function () { cy.staking_page_associate_tokens('3'); cy.get(vegaWalletUnstakedBalance, txTimeout).should( @@ -111,6 +111,113 @@ context('Staking Tab - with eth and vega wallets connected', function () { cy.validate_validator_list_total_stake_and_share('0', '', '2.00', '100%'); }); + it('Able to stake against a validator - using vega from vesting contract', function () { + cy.staking_page_associate_tokens('3', { type: 'contract' }); + + cy.get(vegaWalletUnstakedBalance, txTimeout).should( + 'contain', + 3.0, + txTimeout + ); + + cy.get(ethWalletTotalAssociatedBalance, txTimeout) + .contains('3.0', txTimeout) + .should('be.visible'); + + cy.get(ethWalletAssociatedBalances, txTimeout) + .contains(vegaWalletPublicKeyShort, txTimeout) + .parent() + .should('contain', 3.0, txTimeout); + + cy.get('button').contains('Select a validator to nominate').click(); + + cy.click_on_validator_from_list(0); + + cy.staking_validator_page_add_stake('2'); + + cy.get(vegaWalletUnstakedBalance, txTimeout).should( + 'contain', + 1.0, + txTimeout + ); + + cy.get(vegaWalletStakedBalances, txTimeout) + .should('contain', 2.0, txTimeout) + .and('contain', partValidatorId); + + cy.get(stakeNextEpochValue, epochTimeout) + .contains(2.0, epochTimeout) + .should('be.visible'); + + cy.get(stakeThisEpochValue, epochTimeout) + .contains(2.0, epochTimeout) + .should('be.visible'); + + cy.navigate_to('staking'); + + cy.validate_validator_list_total_stake_and_share('0', '', '2.00', '100%'); + }); + + it('Able to stake against a validator - using vega from both wallet and vesting contract', function () { + cy.staking_page_associate_tokens('3', { type: 'contract' }); + cy.navigate_to('staking'); + cy.staking_page_associate_tokens('4', { type: 'wallet' }); + + cy.get(vegaWalletUnstakedBalance, txTimeout).should( + 'contain', + 7.0, + txTimeout + ); + + cy.get(ethWalletTotalAssociatedBalance, txTimeout) + .contains('3.0', txTimeout) + .should('be.visible'); + + cy.get(ethWalletTotalAssociatedBalance, txTimeout) + .contains('4.0', txTimeout) + .should('be.visible'); + + cy.get(ethWalletAssociatedBalances, txTimeout).should( + 'contain', + 3.0, + txTimeout + ); + + cy.get(ethWalletAssociatedBalances, txTimeout).should( + 'contain', + 4.0, + txTimeout + ); + + cy.get('button').contains('Select a validator to nominate').click(); + + cy.click_on_validator_from_list(0); + + cy.staking_validator_page_add_stake('6'); + + cy.get(vegaWalletUnstakedBalance, txTimeout).should( + 'contain', + 1.0, + txTimeout + ); + + cy.get(vegaWalletStakedBalances, txTimeout) + .should('contain', 6.0, txTimeout) + .and('contain', partValidatorId); + + cy.get(stakeNextEpochValue, epochTimeout) + .contains(6.0, epochTimeout) + .should('be.visible'); + + cy.get(stakeThisEpochValue, epochTimeout) + .contains(6.0, epochTimeout) + .should('be.visible'); + + cy.navigate_to('staking'); + + cy.validate_validator_list_total_stake_and_share('0', '', '6.00', '100%'); + }); + it('Able to stake against multiple validators', function () { cy.staking_page_associate_tokens('5'); @@ -126,6 +233,12 @@ context('Staking Tab - with eth and vega wallets connected', function () { cy.staking_validator_page_add_stake('2'); + cy.get(vegaWalletUnstakedBalance, txTimeout).should( + 'contain', + 3.0, + txTimeout + ); + cy.get(vegaWalletStakedBalances, txTimeout) .parent() .should('contain', 2.0, txTimeout); @@ -136,6 +249,12 @@ context('Staking Tab - with eth and vega wallets connected', function () { cy.staking_validator_page_add_stake('1'); + cy.get(vegaWalletUnstakedBalance, txTimeout).should( + 'contain', + 2.0, + txTimeout + ); + cy.get(vegaWalletStakedBalances, txTimeout) .should('have.length', 2, txTimeout) .eq(0) @@ -145,13 +264,8 @@ context('Staking Tab - with eth and vega wallets connected', function () { .eq(1) .should('contain', 1.0, txTimeout); - cy.get(vegaWalletUnstakedBalance, txTimeout).should( - 'contain', - 2.0, - txTimeout - ); - cy.navigate_to('staking'); + cy.wait_for_spinner(); cy.get(`[row-id="${0}"]`).within(() => { cy.get(stakeValidatorListTotalStake) @@ -201,12 +315,6 @@ context('Staking Tab - with eth and vega wallets connected', function () { .contains(3.0, epochTimeout) .should('be.visible'); - cy.get(vegaWalletNextEpochBalances, txTimeout).should( - 'contain', - 3.0, - txTimeout - ); - cy.get(vegaWalletUnstakedBalance, txTimeout).should( 'contain', 1.0, @@ -254,9 +362,8 @@ context('Staking Tab - with eth and vega wallets connected', function () { .contains(2.0, epochTimeout) .should('be.visible'); - cy.get(totalStake).should('have.text', '2'); - - cy.get(stakeShare).should('have.text', '100%'); + cy.get(totalStake, epochTimeout).should('have.text', '2'); + cy.get(stakeShare, epochTimeout).should('have.text', '100%'); cy.navigate_to('staking'); @@ -300,12 +407,6 @@ context('Staking Tab - with eth and vega wallets connected', function () { txTimeout ); - cy.get(vegaWalletNextEpochBalances, txTimeout).should( - 'contain', - 0.0, - txTimeout - ); - cy.get(vegaWalletUnstakedBalance, txTimeout).should( 'contain', 3.0, @@ -320,9 +421,10 @@ context('Staking Tab - with eth and vega wallets connected', function () { .contains(0.0, epochTimeout) .should('be.visible'); - cy.get(vegaWalletStakedBalances, txTimeout) - .contains(partValidatorId, txTimeout) - .should('not.exist', txTimeout); + cy.get(vegaWalletStakedBalances, txTimeout).should( + 'not.exist', + txTimeout + ); cy.navigate_to('staking'); @@ -348,12 +450,6 @@ context('Staking Tab - with eth and vega wallets connected', function () { .contains(2.0, epochTimeout) .should('be.visible'); - cy.get(vegaWalletNextEpochBalances, txTimeout).should( - 'contain', - 2.0, - txTimeout - ); - cy.get(vegaWalletUnstakedBalance, txTimeout).should( 'contain', 3.0, @@ -395,10 +491,6 @@ context('Staking Tab - with eth and vega wallets connected', function () { .contains(2.0, epochTimeout) .should('be.visible'); - cy.get(vegaWalletNextEpochBalances, txTimeout) - .should('contain', 2.0, txTimeout) - .and('contain', partValidatorId); - cy.get(vegaWalletUnstakedBalance, txTimeout).should( 'contain', 1.0, @@ -421,7 +513,7 @@ context('Staking Tab - with eth and vega wallets connected', function () { .and('be.visible'); }); - it('Disassociating all tokens max - removes all staked tokens', function () { + it('Disassociating all wallet tokens max - removes all staked tokens', function () { cy.staking_page_associate_tokens('3'); cy.get(vegaWalletUnstakedBalance, txTimeout).should( @@ -448,9 +540,60 @@ context('Staking Tab - with eth and vega wallets connected', function () { txTimeout ); + cy.staking_page_disassociate_all_tokens('wallet'); + + cy.get(ethWalletContainer).within(() => { + cy.contains(vegaWalletPublicKeyShort, txTimeout).should('not.exist'); + }); + + cy.get(ethWalletTotalAssociatedBalance, txTimeout) + .contains('0.0', txTimeout) + .should('be.visible'); + + cy.get(vegaWalletAssociatedBalance, txTimeout).should( + 'contain', + '0.000000000000000000', + txTimeout + ); + + cy.get(vegaWalletStakedBalances, txTimeout).should( + 'not.exist', + txTimeout + ); + cy.navigate_to('staking'); - cy.staking_page_disassociate_all_tokens(); + cy.validate_validator_list_total_stake_and_share('0', '', '0.00', '-'); + }); + + it('Disassociating all vesting contract tokens max - removes all staked tokens', function () { + cy.staking_page_associate_tokens('3', { type: 'contract' }); + + cy.get(vegaWalletUnstakedBalance, txTimeout).should( + 'contain', + 3.0, + txTimeout + ); + + cy.get('button').contains('Select a validator to nominate').click(); + + cy.click_on_validator_from_list('1'); + + cy.staking_validator_page_add_stake('2'); + + cy.get(vegaWalletUnstakedBalance, txTimeout).should( + 'contain', + 1.0, + txTimeout + ); + + cy.get(vegaWalletStakedBalances, txTimeout).should( + 'contain', + 2.0, + txTimeout + ); + + cy.staking_page_disassociate_all_tokens('contract'); cy.get(ethWalletContainer).within(() => { cy.contains(vegaWalletPublicKeyShort, txTimeout).should('not.exist'); @@ -501,8 +644,6 @@ context('Staking Tab - with eth and vega wallets connected', function () { txTimeout ); - cy.navigate_to('staking'); - cy.staking_page_disassociate_tokens('1'); cy.get(ethWalletTotalAssociatedBalance, txTimeout) @@ -524,6 +665,166 @@ context('Staking Tab - with eth and vega wallets connected', function () { cy.validate_validator_list_total_stake_and_share('0', '', '2.00', '100%'); }); + it('Associating wallet tokens - when some already staked - auto stakes tokens to staked validator', function () { + cy.staking_page_associate_tokens('3'); + + cy.get(vegaWalletUnstakedBalance, txTimeout).should( + 'contain', + 3.0, + txTimeout + ); + + cy.get('button').contains('Select a validator to nominate').click(); + cy.click_on_validator_from_list(0); + + cy.staking_validator_page_add_stake('3'); + + cy.get(vegaWalletStakedBalances, txTimeout).should( + 'contain', + 3.0, + txTimeout + ); + + cy.staking_page_associate_tokens('4'); + + cy.get(vegaWalletUnstakedBalance, txTimeout).should( + 'contain', + 0.0, + txTimeout + ); + + cy.get(vegaWalletStakedBalances, txTimeout).should( + 'contain', + 7.0, + txTimeout + ); + }); + + it('Associating vesting contract tokens - when some already staked - auto stakes tokens to staked validator', function () { + cy.staking_page_associate_tokens('3', { type: 'contract' }); + + cy.get(vegaWalletUnstakedBalance, txTimeout).should( + 'contain', + 3.0, + txTimeout + ); + + cy.get('button').contains('Select a validator to nominate').click(); + cy.click_on_validator_from_list(0); + + cy.staking_validator_page_add_stake('3'); + + cy.get(vegaWalletStakedBalances, txTimeout).should( + 'contain', + 3.0, + txTimeout + ); + + cy.staking_page_associate_tokens('4', { type: 'contract' }); + + cy.get(vegaWalletUnstakedBalance, txTimeout).should( + 'contain', + 0.0, + txTimeout + ); + + cy.get(vegaWalletStakedBalances, txTimeout).should( + 'contain', + 7.0, + txTimeout + ); + }); + + it('Associating vesting contract tokens - when wallet tokens already staked - auto stakes tokens to staked validator', function () { + cy.staking_page_associate_tokens('3', { type: 'wallet' }); + + cy.get(vegaWalletUnstakedBalance, txTimeout).should( + 'contain', + 3.0, + txTimeout + ); + + cy.get('button').contains('Select a validator to nominate').click(); + cy.click_on_validator_from_list(0); + + cy.staking_validator_page_add_stake('3'); + + cy.get(vegaWalletStakedBalances, txTimeout).should( + 'contain', + 3.0, + txTimeout + ); + + cy.staking_page_associate_tokens('4', { type: 'contract' }); + + cy.get(vegaWalletUnstakedBalance, txTimeout).should( + 'contain', + 0.0, + txTimeout + ); + + cy.get(vegaWalletStakedBalances, txTimeout).should( + 'contain', + 7.0, + txTimeout + ); + }); + + it('Associating tokens - with multiple validators already staked - auto stakes to staked validators - abiding by existing stake ratio', function () { + cy.staking_page_associate_tokens('6'); + + cy.get(vegaWalletUnstakedBalance, txTimeout).should( + 'contain', + 6.0, + txTimeout + ); + + cy.get('button').contains('Select a validator to nominate').click(); + cy.click_on_validator_from_list(0); + + cy.staking_validator_page_add_stake('2'); + + cy.get(vegaWalletUnstakedBalance, txTimeout).should( + 'contain', + 0.0, + txTimeout + ); + + cy.navigate_to('staking'); + + cy.click_on_validator_from_list(1); + + cy.staking_validator_page_add_stake('4'); + + cy.get(vegaWalletUnstakedBalance, txTimeout).should( + 'contain', + 0.0, + txTimeout + ); + + cy.staking_page_associate_tokens('6'); + + cy.get(vegaWalletAssociatedBalance, txTimeout).should( + 'contain', + '12.000000000000000000', + txTimeout + ); + + cy.get(vegaWalletStakedBalances, txTimeout) + .should('contain', '4.0', txTimeout) + .and('contain', partValidatorId); + + cy.get(vegaWalletStakedBalances, txTimeout) + .should('contain', '8.0') + .and('contain', partValidatorId); + + cy.get(vegaWalletUnstakedBalance, txTimeout).should( + 'contain', + 0.0, + txTimeout + ); + }); + it('Selecting use maximum where tokens are already staked - suggests the unstaked token amount', function () { cy.staking_page_associate_tokens('3'); diff --git a/apps/token-e2e/src/support/common.functions.js b/apps/token-e2e/src/support/common.functions.js index 443528a60..434e17657 100644 --- a/apps/token-e2e/src/support/common.functions.js +++ b/apps/token-e2e/src/support/common.functions.js @@ -19,7 +19,7 @@ const navigation = { Cypress.Commands.add('navigate_to', (page) => { return cy.get(navigation.section, { timeout: 10000 }).within(() => { - cy.get(navigation[page]).click(); + cy.get(navigation[page]).click({ force: true }); }); }); diff --git a/apps/token-e2e/src/support/staking.functions.js b/apps/token-e2e/src/support/staking.functions.js index 7d31788a1..6b94425b6 100644 --- a/apps/token-e2e/src/support/staking.functions.js +++ b/apps/token-e2e/src/support/staking.functions.js @@ -29,7 +29,8 @@ Cypress.Commands.add('wait_for_begining_of_epoch', () => { Cypress.Commands.add('staking_validator_page_add_stake', (stake) => { cy.highlight(`Adding a stake of ${stake}`); - cy.get(addStakeRadioButton, { timeout: 8000 }).click({ force: true }); + cy.wait_for_spinner(); + cy.get(addStakeRadioButton, epochTimeout).click({ force: true }); cy.get(tokenAmountInputBox).type(stake); cy.wait_for_begining_of_epoch(); cy.get(tokenSubmitButton, epochTimeout) @@ -41,7 +42,8 @@ Cypress.Commands.add('staking_validator_page_add_stake', (stake) => { Cypress.Commands.add('staking_validator_page_remove_stake', (stake) => { cy.highlight(`Removing a stake of ${stake}`); - cy.get(removeStakeRadioButton, { timeout: 8000 }).click(); + cy.wait_for_spinner(); + cy.get(removeStakeRadioButton, epochTimeout).click(); cy.get(tokenAmountInputBox).type(stake); cy.wait_for_begining_of_epoch(); cy.get(tokenSubmitButton) @@ -55,7 +57,7 @@ Cypress.Commands.add('staking_page_associate_tokens', (amount, options) => { let approve = options && options.approve ? options.approve : false; let type = options && options.type ? options.type : 'wallet'; - cy.highlight(`Associating ${amount} tokens`); + cy.highlight(`Associating ${amount} tokens from ${type}`); cy.get(ethWalletAssociateButton).first().click(); if (type === 'wallet') { cy.get(associateWalletRadioButton, { timeout: 30000 }).click(); @@ -64,34 +66,34 @@ Cypress.Commands.add('staking_page_associate_tokens', (amount, options) => { } else { cy.highlight(`${type} is not association option`); } - cy.get(tokenAmountInputBox, { timeout: 10000 }).type(amount); + cy.get(tokenAmountInputBox, epochTimeout).type(amount); if (approve) { cy.get(tokenInputApprove, txTimeout).should('be.enabled').click(); cy.contains('Approve $VEGA Tokens for staking on Vega').should( 'be.visible' ); - cy.contains('Approve $VEGA Tokens for staking on Vega', { - timeout: 40000, - }).should('not.exist'); + cy.contains('Approve $VEGA Tokens for staking on Vega', txTimeout).should( + 'not.exist' + ); } cy.get(tokenSubmitButton, txTimeout).should('be.enabled').click(); cy.contains( `Associating with Vega key. Waiting for ${Cypress.env( 'blockConfirmations' )} more confirmations..`, - { - timeout: 8000, - } + epochTimeout + ).should('be.visible'); + cy.contains( + 'can now participate in governance and nominate a validator', + txTimeout ).should('be.visible'); - cy.contains('can now participate in governance and nominate a validator', { - timeout: 60000, - }).should('be.visible'); }); Cypress.Commands.add('staking_page_disassociate_tokens', (amount, options) => { let type = options && options.type ? options.type : 'wallet'; - - cy.highlight(`Disassociating ${amount} tokens via Staking Page`); + cy.highlight( + `Disassociating ${amount} tokens via Staking Page back to ${type}` + ); cy.get(ethWalletDissociateButton).first().click(); cy.get(vegaKeySelector) @@ -110,35 +112,44 @@ Cypress.Commands.add('staking_page_disassociate_tokens', (amount, options) => { if (type === 'wallet') { cy.contains( `${amount} $VEGA tokens have been returned to Ethereum wallet`, - { - timeout: 60000, - } + txTimeout ).should('be.visible'); } else if (type === 'contract') { cy.contains( `${amount} $VEGA tokens have been returned to Vesting contract`, - { - timeout: 60000, - } + txTimeout ).should('be.visible'); } }); -Cypress.Commands.add('staking_page_disassociate_all_tokens', () => { - cy.highlight(`Disassociating all tokens via Staking Page`); - cy.get(ethWalletDissociateButton).first().click(); - cy.get(stakeMaximumTokens, epochTimeout).click(); - cy.get(tokenSubmitButton, epochTimeout).click(); - cy.contains( - '$VEGA tokens have been returned to Ethereum wallet', - txTimeout - ).should('be.visible'); -}); +Cypress.Commands.add( + 'staking_page_disassociate_all_tokens', + (type = 'wallet') => { + cy.highlight(`Disassociating all tokens via Staking Page`); + cy.get(ethWalletDissociateButton).first().click(); + cy.get(stakeMaximumTokens, epochTimeout).click(); + cy.get(tokenSubmitButton, epochTimeout).click(); + if (type === 'wallet') { + cy.contains( + `$VEGA tokens have been returned to Ethereum wallet`, + txTimeout + ).should('be.visible'); + } else if (type === 'contract') { + cy.contains( + `$VEGA tokens have been returned to Vesting contract`, + txTimeout + ).should('be.visible'); + } + } +); Cypress.Commands.add( 'click_on_validator_from_list', (validatorNumber, validatorName = null) => { - cy.contains('Waiting for next epoch to start').should('not.exist'); + 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(); // below is to ensure validator list is shown cy.get(stakeValidatorListName, { timeout: 10000 }).should('exist'); cy.get(stakeValidatorListPendingStake, txTimeout).should( @@ -149,6 +160,7 @@ Cypress.Commands.add( cy.contains(validatorName).click(); } else { cy.get(`[row-id="${validatorNumber}"]`) + .should('be.visible') .find(stakeValidatorListName) .click(); } @@ -163,13 +175,17 @@ Cypress.Commands.add( expectedTotalStake, expectedTotalShare ) => { + 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.get(`[row-id="${positionOnList}"]`).within(() => { cy.get(stakeValidatorListName).should('have.text', expectedValidatorName); - cy.get(stakeValidatorListTotalStake).should( + cy.get(stakeValidatorListTotalStake, epochTimeout).should( 'have.text', expectedTotalStake ); - cy.get(stakeValidatorListTotalShare).should( + cy.get(stakeValidatorListTotalShare, epochTimeout).should( 'have.text', expectedTotalShare ); diff --git a/apps/token-e2e/src/support/wallet-teardown.functions.js b/apps/token-e2e/src/support/wallet-teardown.functions.js index 41972268c..f08793e93 100644 --- a/apps/token-e2e/src/support/wallet-teardown.functions.js +++ b/apps/token-e2e/src/support/wallet-teardown.functions.js @@ -17,7 +17,7 @@ const ethStakingBridgeContractAddress = Cypress.env( ); const ethProviderUrl = Cypress.env('ethProviderUrl'); const getAccount = (number = 0) => `m/44'/60'/0'/0/${number}`; -const transactionTimeout = '50000'; +const transactionTimeout = '90000'; before('Vega wallet teardown prep', function () { cy.wrap(new ethers.providers.JsonRpcProvider({ url: ethProviderUrl }), { @@ -46,8 +46,8 @@ Cypress.Commands.add('vega_wallet_teardown', function () { .invoke('text') .then((balance) => { if (balance != '0.000000000000000000') { - cy.vega_wallet_teardown_staking(this.stakingBridgeContract); cy.vega_wallet_teardown_vesting(this.vestingContract); + cy.vega_wallet_teardown_staking(this.stakingBridgeContract); } }); });