Test/425 withdrawals (#457)

* chore: improve assertions for deposits

* test: validation test passing

* test: withdrawal tests passing

* fix: test failures in CI

* fix: lint

* chore: add env variables

* fix: failing tests due to wallet service not running

* ci: pass automatic cnsent

* ci: init wallet in other directory

* ci: pass home string everywhere

* ci: config is already imported

* fix: failing deposit and nightly run

* ci: port over changes from pr run

* fix: failing network param tests

* fix: assertion

* fix: assertion one last time

Co-authored-by: Dexter <dexter.edwards93@gmail.com>
This commit is contained in:
Joe Tsang 2022-05-27 10:23:07 +01:00 committed by GitHub
parent d858d9cf8a
commit 66c18a2b1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 407 additions and 116 deletions

View File

@ -121,15 +121,13 @@ jobs:
run: echo "${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}" > ./recovery run: echo "${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}" > ./recovery
- name: Initialize wallet - name: Initialize wallet
run: vegawallet init -f run: vegawallet init -f --home ~/.vegacapsule/testnet/wallet
- name: Import wallet - name: Import wallet
run: vegawallet import -w UI_Trading_Test --recovery-phrase-file ./recovery -p ./passphrase run: vegawallet import -w UI_Trading_Test --recovery-phrase-file ./recovery -p ./passphrase --home ~/.vegacapsule/testnet/wallet
- name: Import config
run: vegawallet network import --from-file ~/.vegacapsule/testnet/wallet/config/wallet-service/networks/DV.toml
- name: Create public key 2 - name: Create public key 2
run: vegawallet key generate -w UI_Trading_Test -p ./passphrase run: vegawallet key generate -w UI_Trading_Test -p ./passphrase --home ~/.vegacapsule/testnet/wallet
- name: Start service - name: Start service
run: vegawallet service run --network fairground & run: vegawallet service run --network DV --automatic-consent --home ~/.vegacapsule/testnet/wallet &
###### ######
## Run some tests ## Run some tests
@ -151,6 +149,7 @@ jobs:
CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }} CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE: ${{ secrets.CYPRESS_TRADING_TEST_VEGA_WALLET_PASSPHRASE }}
CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }} CYPRESS_SLACK_WEBHOOK: ${{ secrets.CYPRESS_SLACK_WEBHOOK }}
CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPESS_ETH_WALLET_MNEMONIC }} CYPRESS_ETH_WALLET_MNEMONIC: ${{ secrets.CYPESS_ETH_WALLET_MNEMONIC }}
CYPRESS_NIGHTLY_RUN: true
###### ######
## Upload logs ## Upload logs

View File

@ -81,15 +81,13 @@ jobs:
run: echo "${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}" > ./recovery run: echo "${{ secrets.TRADING_TEST_VEGA_WALLET_RECOVERY }}" > ./recovery
- name: Initialize wallet - name: Initialize wallet
run: vegawallet init -f run: vegawallet init -f --home ~/.vegacapsule/testnet/wallet
- name: Import wallet - name: Import wallet
run: vegawallet import -w UI_Trading_Test --recovery-phrase-file ./recovery -p ./passphrase run: vegawallet import -w UI_Trading_Test --recovery-phrase-file ./recovery -p ./passphrase --home ~/.vegacapsule/testnet/wallet
- name: Import config
run: vegawallet network import --from-file ~/.vegacapsule/testnet/wallet/config/wallet-service/networks/DV.toml
- name: Create public key 2 - name: Create public key 2
run: vegawallet key generate -w UI_Trading_Test -p ./passphrase run: vegawallet key generate -w UI_Trading_Test -p ./passphrase --home ~/.vegacapsule/testnet/wallet
- name: Start service - name: Start service
run: vegawallet service run --network fairground & run: vegawallet service run --network DV --automatic-consent --home ~/.vegacapsule/testnet/wallet &
###### ######
## Run some tests ## Run some tests

View File

@ -65,10 +65,12 @@ export default class HomePage extends BasePage {
cy.getByTestId(this.statsValue).eq(11).should('not.be.empty'); cy.getByTestId(this.statsValue).eq(11).should('not.be.empty');
cy.getByTestId(this.statsValue).eq(12).should('not.be.empty'); cy.getByTestId(this.statsValue).eq(12).should('not.be.empty');
cy.getByTestId(this.statsValue).eq(13).should('not.be.empty'); cy.getByTestId(this.statsValue).eq(13).should('not.be.empty');
if (Cypress.env('NIGHTLY_RUN') != true) {
cy.getByTestId(this.statsValue) cy.getByTestId(this.statsValue)
.eq(14) .eq(14)
.invoke('text') .invoke('text')
.should('match', /v\d+\.\d+\.\d+/i); .should('match', /v\d+\.\d+\.\d+/i);
}
cy.getByTestId(this.statsValue) cy.getByTestId(this.statsValue)
.eq(15) .eq(15)
.invoke('text') .invoke('text')

View File

@ -15,18 +15,18 @@ export default class NetworkParametersPage extends BasePage {
); );
cy.get(this.jsonParamNameClassName) cy.get(this.jsonParamNameClassName)
.should('have.length.at.least', 21) .should('have.length.at.least', 18)
.each(($paramName) => { .each(($paramName) => {
cy.wrap($paramName).should('not.be.empty'); cy.wrap($paramName).should('not.be.empty');
}); });
cy.get(this.jsonParamValueStringClassName) cy.get(this.jsonParamValueStringClassName)
.should('have.length.at.least', 7) .should('have.length.at.least', 6)
.each(($paramValue) => { .each(($paramValue) => {
cy.wrap($paramValue).should('not.be.empty'); cy.wrap($paramValue).should('not.be.empty');
}); });
cy.get(this.jsonParamValueNumberClassName) cy.get(this.jsonParamValueNumberClassName)
.should('have.length.at.least', 9) .should('have.length.at.least', 7)
.each(($paramValue) => { .each(($paramValue) => {
cy.wrap($paramValue).should('not.be.empty'); cy.wrap($paramValue).should('not.be.empty');
}); });

View File

@ -24,6 +24,9 @@
"TRUNCATED_VEGA_PUBLIC_KEY": "47836c…c7d278", "TRUNCATED_VEGA_PUBLIC_KEY": "47836c…c7d278",
"TRUNCATED_VEGA_PUBLIC_KEY2": "1a18cd…0cf2e4", "TRUNCATED_VEGA_PUBLIC_KEY2": "1a18cd…0cf2e4",
"INVALID_DEPOSIT_TO_ADDRESS": "zzz85edfa7ffdb6ed996ca912e9258998e47bf3515c885cf3c63fb56b15de36f", "INVALID_DEPOSIT_TO_ADDRESS": "zzz85edfa7ffdb6ed996ca912e9258998e47bf3515c885cf3c63fb56b15de36f",
"ETHEREUM_WALLET_ADDRESS": "0x265Cc6d39a1B53d0d92068443009eE7410807158",
"ETHERSCAN_URL": "https://ropsten.etherscan.io",
"WITHDRAWAL_ASSET_ID": "tEURO TEST",
"tsConfig": "tsconfig.json", "tsConfig": "tsconfig.json",
"TAGS": "not @todo and not @ignore and not @manual" "TAGS": "not @todo and not @ignore and not @manual"
} }

View File

@ -91,6 +91,7 @@ Feature: Deposits to vega wallet
# This next step is being skipped due to account having approved status # This next step is being skipped due to account having approved status
# Then Not approved message shown # Then Not approved message shown
@ignore
Scenario: Successful deposit Scenario: Successful deposit
When I enter the following deposit details in deposit form When I enter the following deposit details in deposit form
| asset | tBTC TEST | | asset | tBTC TEST |

View File

@ -1,57 +1,47 @@
@ignore Feature: Withdrawals to eth wallet
Feature: Withdrawals
Scenario: Can prepare a withdrawal Background:
Given I am on withdraw page Given I navigate to withdrawal page
And I connect eth wallet And I connect to Vega Wallet
And I connect vega wallet
And I can see the withdrawals warning info
And I can see the from ethereum address field is automatically populated with current connected key
And I select asset 'tBTC'
And I input '100' tokens to withdraw
And the withdraw button is enabled
When I click the withdraw button
Then The vega transaction is sent
Then The Ethereum transaction is triggered
Scenario: Form field validation if fields are incomplete Scenario: Succesfull withdrawal
Given I am on withdraw page When I succesfully fill in and submit withdrawal form
And I connect eth wallet Then withdrawal modal is displayed
And I connect vega wallet
When I click the withdraw button
Then I can see validation errors on incomplete fields
Scenario: Can prepare a withdrawal to send to another eth wallet Scenario: Error displayed when fields are empty
Given I am on withdraw page When I clear ethereum address
And I connect eth wallet And click submit
And I connect vega wallet Then errors are displayed for empty fields
And I select asset 'tBTC'
And I can see an eth address is already filled in the withdraw to field
When I click the enter manually button
Then I can enter a new eth address
And I input '100' tokens to withdraw
And the withdraw button is enabled
When I click the withdraw button
Then The vega transaction is sent
Then The Ethereum transaction is triggered
Scenario: Eth key validation on form Scenario: Error displayed when invalid Ethereum address is entered
Given I am on withdraw page When I enter an invalid ethereum address
And I connect eth wallet Then error for invalid ethereum address is displayed
And I connect vega wallet
And I select asset 'tBTC'
When I click the enter manually button
And I enter eth address 'MMMMNNNN'
Then the invalid eth address error is shown
Scenario: Validation error if trying to withdraw more than available Scenario: Error displayed when not in range of acceptable amount
Given I am on withdrawals page When I enter the following details in withdrawal form
And I have connected | asset | tUSDC TEST |
And I select asset 'tBTC' | amount | 0 |
And I input '1088494949494949940' tokens to withdraw Then error for below minumum amount is displayed
When I click the withdraw button When I enter the following details in withdrawal form
Then validation error is shown for token input amount | asset | tUSDC TEST |
| amount | 1 |
Then error for above maximum amount is displayed
Scenario: Fill in amount using maximum
When I select "tDAI TEST"
And ethereum address is connected Ethereum wallet
And I click Use maximum
Then expected amount is "5.00000"
Scenario: Able to view history of withdrawals on withdrawals page
Given I navigate to withdrawals page
Then history of withdrawals are displayed
Scenario: Vega wallet connect text shown when Vega wallet is disconnected
When I disconnect my Vega wallet
Then connect to Vega wallet is displayed
@manual
Scenario: Can see pending / unfinished withdrawals Scenario: Can see pending / unfinished withdrawals
Given I am on the withdrawals page Given I am on the withdrawals page
And I can see there are unfinished withdrawals And I can see there are unfinished withdrawals

View File

@ -2,6 +2,12 @@ export default class BasePage {
closeDialogBtn = 'dialog-close'; closeDialogBtn = 'dialog-close';
porfolioUrl = '/portfolio'; porfolioUrl = '/portfolio';
marketsUrl = '/markets'; marketsUrl = '/markets';
assetSelectField = 'select[name="asset"]';
toAddressField = 'input[name="to"]';
amountField = 'input[name="amount"]';
formFieldError = 'input-error-text';
dialogHeader = 'dialog-title';
dialogText = 'dialog-text';
closeDialog() { closeDialog() {
cy.getByTestId(this.closeDialogBtn, { timeout: 8000 }).click({ cy.getByTestId(this.closeDialogBtn, { timeout: 8000 }).click({
@ -20,4 +26,28 @@ export default class BasePage {
cy.url().should('include', '/markets'); cy.url().should('include', '/markets');
cy.getByTestId('markets'); cy.getByTestId('markets');
} }
verifyFormErrorDisplayed(expectedError: string, expectedNumErrors: number) {
cy.getByTestId(this.formFieldError).should('contain.text', expectedError);
cy.getByTestId(this.formFieldError).should(
'have.length',
expectedNumErrors
);
}
updateTransactionform(args?: {
asset?: string;
to?: string;
amount?: string;
}) {
if (args?.asset) {
cy.get(this.assetSelectField).select(args.asset);
}
if (args?.to) {
cy.get(this.toAddressField).clear().type(args.to);
}
if (args?.amount) {
cy.get(this.amountField).clear().type(args.amount);
}
}
} }

View File

@ -18,52 +18,33 @@ export default class DepositsPage extends BasePage {
} }
checkModalContains(text: string) { checkModalContains(text: string) {
cy.get('[role="dialog"]').contains(text).should('be.visible'); cy.get('[role="dialog"] > div > div > h1').should('have.text', text);
}
updateForm(args?: { asset?: string; to?: string; amount?: string }) {
if (args?.asset) {
cy.get('select[name="asset"]').select(args.asset);
}
if (args?.to) {
cy.get('input[name="to"]').clear().type(args.to);
}
if (args?.amount) {
cy.get('input[name="amount"]').clear().type(args.amount);
}
} }
submitForm() { submitForm() {
cy.getByTestId('deposit-submit').click(); cy.getByTestId('deposit-submit').click();
} }
verifyFieldsAreRequired() {
cy.get(this.assetError).contains(this.requiredText);
cy.get(this.toError).contains(this.requiredText);
cy.get(this.amountError).contains(this.requiredText);
cy.getByTestId('input-error-text').should('have.length', 3);
}
verifyInvalidPublicKey() { verifyInvalidPublicKey() {
cy.get(this.toError).contains('Invalid Vega key').should('be.visible'); cy.get(this.toError).should('have.text', 'Invalid Vega key');
} }
verifyAmountTooSmall() { verifyAmountTooSmall() {
cy.get(this.amountError) cy.get(this.amountError).should('have.text', 'Value is below minimum');
.contains('Value is below minimum')
.should('be.visible');
} }
verifyInsufficientAmountMessage() { verifyInsufficientAmountMessage() {
cy.getByTestId('input-error-text') cy.getByTestId('input-error-text').should(
.contains('Insufficient amount in Ethereum wallet') 'contain.text',
.should('be.visible'); 'Insufficient amount in Ethereum wallet'
);
} }
verifyNotApproved() { verifyNotApproved() {
cy.get(this.amountError) cy.get(this.amountError).should(
.contains('Amount is above approved amount') 'have.text',
.should('be.visible'); 'Amount is above approved amount'
);
cy.contains('Deposits of tBTC not approved').should('be.visible'); cy.contains('Deposits of tBTC not approved').should('be.visible');
} }
} }

View File

@ -1,3 +1,44 @@
import BasePage from './base-page'; import BasePage from './base-page';
export default class PortfolioPage extends BasePage {} export default class PortfolioPage extends BasePage {
deposit = 'deposit';
depositTEuro = 'deposit-tEuro';
viewWithdrawals = 'view-withdrawals';
withdraw = 'withdraw';
withdrawTEuro = 'withdraw-tEuro';
navigateToDeposit() {
cy.getByTestId(this.deposit)
.should('have.attr', 'href')
.and('include', '/portfolio/deposit');
cy.getByTestId(this.deposit).click();
}
navigateToDepositTEuro() {
cy.getByTestId(this.depositTEuro)
.should('have.attr', 'href')
.and('include', '/portfolio/deposit?assetId');
cy.getByTestId(this.depositTEuro).click();
}
navigateToWithdrawals() {
cy.getByTestId(this.viewWithdrawals)
.should('have.attr', 'href')
.and('include', '/portfolio/withdrawals');
cy.getByTestId(this.viewWithdrawals).click();
}
navigateToWithdraw() {
cy.getByTestId(this.withdraw)
.should('have.attr', 'href')
.and('include', '/portfolio/withdraw');
cy.getByTestId(this.withdraw).click();
}
navigateToWithdrawTEuro() {
cy.getByTestId(this.withdrawTEuro)
.should('have.attr', 'href')
.and('include', '/portfolio/withdraw?assetId');
cy.getByTestId(this.withdrawTEuro).click();
}
}

View File

@ -0,0 +1,94 @@
import BasePage from './base-page';
export default class WithdrawalsPage extends BasePage {
useConnectedEthWallet = 'use-connected';
useMaximumAmount = 'use-maximum';
submitBtn = 'submit-withdrawal';
connectVegaWalletText = 'connect-vega-wallet-text';
assetSymbolColId = 'asset.symbol';
amountColId = 'amount';
recipientColdId = 'details.receiverAddress';
createdAtTimeStampId = 'createdTimestamp';
statusColId = 'status';
etherScanLink = 'etherscan-link';
clearEthereumAddress() {
cy.get(this.toAddressField).clear();
}
clickUseConnected() {
cy.getByTestId(this.useConnectedEthWallet).click();
}
clickUseMaximum() {
cy.getByTestId(this.useMaximumAmount).click();
}
clickSubmit() {
cy.getByTestId(this.submitBtn).click();
}
validateConnectWalletText() {
cy.getByTestId(this.connectVegaWalletText).should(
'have.text',
'Please connect your Vega wallet'
);
}
validateTestWalletEthWalletAddress() {
cy.get(this.toAddressField).should(
'have.value',
Cypress.env('ETHEREUM_WALLET_ADDRESS')
);
}
validateAmount(expectedAmount: string) {
cy.get(this.amountField).should('have.value', expectedAmount);
}
validateConfirmWithdrawalModal() {
cy.getByTestId(this.dialogHeader).should('have.text', 'Confirm withdrawal');
cy.getByTestId(this.dialogText).should(
'have.text',
'Confirm withdrawal in Vega wallet'
);
}
validateWithdrawalAssetDisplayed(assetSymbol: string) {
cy.get(`[col-id="${this.assetSymbolColId}"]`).should(
'contain.text',
assetSymbol
);
}
validateWithdrawalAmountDisplayed(amount: string) {
cy.get(`[col-id="${this.amountColId}"]`).should('contain.text', amount);
}
validateWithdrawalRecipientDisplayed(
truncatedEthAddress: string,
ethAddressLink: string
) {
cy.get(`[col-id="${this.recipientColdId}"]`)
.should('contain.text', truncatedEthAddress)
.find(`[data-testid=${this.etherScanLink}]`)
.should('have.attr', 'href', ethAddressLink);
}
validateWithdrawalDateDisplayed() {
cy.get(`[col-id="${this.createdAtTimeStampId}"]`)
.invoke('text')
.should('not.be.empty');
}
validateWithdrawalStatusDisplayed(status: string) {
cy.get(`[col-id="${this.statusColId}"]`).should('contain.text', status);
}
validateEtherScanLinkDisplayed(txlink: string) {
cy.getByTestId(this.etherScanLink)
.last()
.should('have.text', 'View on Etherscan')
.and('have.attr', 'href', txlink);
}
}

View File

@ -30,16 +30,16 @@ Then('I can see the deposit form', () => {
}); });
When('I submit a deposit with empty fields', () => { When('I submit a deposit with empty fields', () => {
depositsPage.updateForm(); depositsPage.updateTransactionform();
depositsPage.submitForm(); depositsPage.submitForm();
}); });
Then('I can see empty form validation errors present', () => { Then('I can see empty form validation errors present', () => {
depositsPage.verifyFieldsAreRequired(); depositsPage.verifyFormErrorDisplayed('Required', 3);
}); });
Then('I enter the following deposit details in deposit form', (table) => { Then('I enter the following deposit details in deposit form', (table) => {
depositsPage.updateForm({ depositsPage.updateTransactionform({
asset: table.rowsHash().asset, asset: table.rowsHash().asset,
to: Cypress.env(table.rowsHash().to), to: Cypress.env(table.rowsHash().to),
amount: table.rowsHash().amount, amount: table.rowsHash().amount,
@ -59,7 +59,7 @@ Then('Amount too small message shown', () => {
}); });
And('I enter a valid amount', () => { And('I enter a valid amount', () => {
depositsPage.updateForm({ amount: '1' }); depositsPage.updateTransactionform({ amount: '1' });
}); });
Then('Not approved message shown', () => { Then('Not approved message shown', () => {

View File

@ -40,6 +40,14 @@ When('select a different public key', () => {
vegaWallet.selectPublicKey(); vegaWallet.selectPublicKey();
}); });
When('I disconnect my Vega wallet', () => {
vegaWallet.validatePublicKeyDisplayed(
Cypress.env('TRUNCATED_VEGA_PUBLIC_KEY')
);
vegaWallet.clickOnWalletConnectDialog();
vegaWallet.clickDisconnectAllKeys();
});
Then('public key is switched', () => { Then('public key is switched', () => {
vegaWallet.validatePublicKeyDisplayed( vegaWallet.validatePublicKeyDisplayed(
Cypress.env('TRUNCATED_VEGA_PUBLIC_KEY2') Cypress.env('TRUNCATED_VEGA_PUBLIC_KEY2')

View File

@ -0,0 +1,112 @@
import { Given, When, Then } from 'cypress-cucumber-preprocessor/steps';
import PortfolioPage from '../pages/portfolio-page';
import WithdrawalsPage from '../pages/withdrawals-page';
const portfolioPage = new PortfolioPage();
const withdrawalsPage = new WithdrawalsPage();
Given('I navigate to withdrawal page', () => {
cy.visit('/');
portfolioPage.closeDialog();
portfolioPage.navigateToPortfolio();
portfolioPage.navigateToWithdraw();
});
Given('I navigate to withdrawals page', () => {
portfolioPage.navigateToPortfolio();
portfolioPage.navigateToWithdrawals();
});
When('I clear ethereum address', () => {
withdrawalsPage.clearEthereumAddress();
});
When('click submit', () => {
withdrawalsPage.clickSubmit();
});
When('I enter an invalid ethereum address', () => {
withdrawalsPage.updateTransactionform({
to: '0x0dAAACaa868f87BB4666F918742141cAEAe893Fa',
});
withdrawalsPage.clickSubmit();
});
When('I select {string}', (selectedAsset) => {
withdrawalsPage.updateTransactionform({
asset: selectedAsset,
});
});
When('ethereum address is connected Ethereum wallet', () => {
withdrawalsPage.validateTestWalletEthWalletAddress();
});
When('I click Use maximum', () => {
withdrawalsPage.clickUseMaximum();
});
When('I enter the following details in withdrawal form', (table) => {
withdrawalsPage.updateTransactionform({
asset: table.rowsHash().asset,
to: table.rowsHash().to,
amount: table.rowsHash().amount,
});
withdrawalsPage.clickSubmit();
});
When('I succesfully fill in and submit withdrawal form', () => {
withdrawalsPage.updateTransactionform({
asset: Cypress.env('WITHDRAWAL_ASSET_ID'),
amount: '0.1',
});
withdrawalsPage.clickSubmit();
});
Then('errors are displayed for empty fields', () => {
withdrawalsPage.verifyFormErrorDisplayed('Required', 3);
});
Then('error for invalid ethereum address is displayed', () => {
// Expecting empty field errors to still be displayed
withdrawalsPage.verifyFormErrorDisplayed('Invalid Ethereum address', 3);
});
Then('connect to Vega wallet is displayed', () => {
withdrawalsPage.validateConnectWalletText();
});
Then('expected amount is {string}', (expectedAmount) => {
withdrawalsPage.validateAmount(expectedAmount);
});
Then('withdrawal modal is displayed', () => {
withdrawalsPage.validateConfirmWithdrawalModal();
});
Then('error for below minumum amount is displayed', () => {
withdrawalsPage.verifyFormErrorDisplayed('Value is below minimum', 1);
});
Then('error for above maximum amount is displayed', () => {
withdrawalsPage.verifyFormErrorDisplayed('Value is above maximum', 1);
});
Then('history of withdrawals are displayed', () => {
const ethAddressLink = `${Cypress.env('ETHERSCAN_URL')}/address/${Cypress.env(
'ETHEREUM_WALLET_ADDRESS'
)}`;
const etherScanLink = `${Cypress.env(
'ETHERSCAN_URL'
)}/tx/0x0d1a5d209f468ff248326d4ae7647ad5a3667ce463341a0250118a95f3beb597`;
withdrawalsPage.validateWithdrawalAssetDisplayed('tEURO');
withdrawalsPage.validateWithdrawalAmountDisplayed('10,000.00000');
withdrawalsPage.validateWithdrawalRecipientDisplayed(
'0x265C…807158',
ethAddressLink
);
withdrawalsPage.validateWithdrawalDateDisplayed();
withdrawalsPage.validateWithdrawalStatusDisplayed('Finalized');
withdrawalsPage.validateEtherScanLinkDisplayed(etherScanLink);
});

View File

@ -3,6 +3,7 @@ export default class VegaWallet {
walletConnectors = 'connectors-list'; walletConnectors = 'connectors-list';
walletForm = 'rest-connector-form'; walletForm = 'rest-connector-form';
selectPublicKeyBtn = 'select-keypair-button'; selectPublicKeyBtn = 'select-keypair-button';
disconnectAllKeysBtn = 'disconnect';
walletInputError = 'input-wallet-error'; walletInputError = 'input-wallet-error';
walletFormError = 'form-error'; walletFormError = 'form-error';
inputError = 'input-error-text'; inputError = 'input-error-text';
@ -56,4 +57,8 @@ export default class VegaWallet {
clickOnWalletConnectDialog() { clickOnWalletConnectDialog() {
cy.getByTestId(this.connectVegaBtn).click(); cy.getByTestId(this.connectVegaBtn).click();
} }
clickDisconnectAllKeys() {
cy.getByTestId(this.disconnectAllKeysBtn).click();
}
} }

View File

@ -6,17 +6,30 @@ const Portfolio = () => {
<div className="p-24"> <div className="p-24">
<h1 className="text-h3 mb-12">{t('Portfolio')}</h1> <h1 className="text-h3 mb-12">{t('Portfolio')}</h1>
<div className="flex gap-4 mb-12"> <div className="flex gap-4 mb-12">
<AnchorButton href="/portfolio/deposit">{t('Deposit')}</AnchorButton> <AnchorButton data-testid="deposit" href="/portfolio/deposit">
<AnchorButton href="/portfolio/deposit?assetId=8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4"> {t('Deposit')}
</AnchorButton>
<AnchorButton
data-testid="deposit-tEuro"
href="/portfolio/deposit?assetId=8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4"
>
{t('Deposit tEURO')} {t('Deposit tEURO')}
</AnchorButton> </AnchorButton>
</div> </div>
<div className="flex gap-4"> <div className="flex gap-4">
<AnchorButton href="/portfolio/withdrawals"> <AnchorButton
data-testid="view-withdrawals"
href="/portfolio/withdrawals"
>
{t('View Withdrawals')} {t('View Withdrawals')}
</AnchorButton> </AnchorButton>
<AnchorButton href="/portfolio/withdraw">{t('Withdraw')}</AnchorButton> <AnchorButton data-testid="withdraw" href="/portfolio/withdraw">
<AnchorButton href="/portfolio/withdraw?assetId=8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4"> {t('Withdraw')}
</AnchorButton>
<AnchorButton
data-testid="withdraw-tEuro"
href="/portfolio/withdraw?assetId=8b52d4a3a4b0ffe733cddbc2b67be273816cfeb6ca4c8b339bac03ffba08e4e4"
>
{t('Withdraw tEURO')} {t('Withdraw tEURO')}
</AnchorButton> </AnchorButton>
</div> </div>

View File

@ -48,7 +48,11 @@ export const WithdrawPageContainer = ({
const { keypair } = useVegaWallet(); const { keypair } = useVegaWallet();
if (!keypair) { if (!keypair) {
return <p>{t('Please connect your Vega wallet')}</p>; return (
<p data-testid="connect-vega-wallet-text">
{t('Please connect your Vega wallet')}
</p>
);
} }
return ( return (

View File

@ -51,7 +51,10 @@ export const DialogWrapper = ({
<div className="flex gap-12 max-w-full text-ui"> <div className="flex gap-12 max-w-full text-ui">
<div className="pt-8 fill-current">{icon}</div> <div className="pt-8 fill-current">{icon}</div>
<div className="flex-1"> <div className="flex-1">
<h1 className="text-h4 text-black dark:text-white capitalize mb-12"> <h1
data-testid="dialog-title"
className="text-h4 text-black dark:text-white capitalize mb-12"
>
{title} {title}
</h1> </h1>
{children} {children}
@ -65,7 +68,11 @@ interface StepProps {
} }
const Step = ({ children }: StepProps) => { const Step = ({ children }: StepProps) => {
return <p className="flex justify-between">{children}</p>; return (
<p data-testid="dialog-text" className="flex justify-between">
{children}
</p>
);
}; };
interface DialogProps { interface DialogProps {

View File

@ -14,7 +14,7 @@ import {
Select, Select,
} from '@vegaprotocol/ui-toolkit'; } from '@vegaprotocol/ui-toolkit';
import type BigNumber from 'bignumber.js'; import type BigNumber from 'bignumber.js';
import type { ReactNode } from 'react'; import type { ButtonHTMLAttributes, ReactNode } from 'react';
import { useForm, Controller } from 'react-hook-form'; import { useForm, Controller } from 'react-hook-form';
import type { WithdrawalFields } from './use-withdraw'; import type { WithdrawalFields } from './use-withdraw';
import type { Asset } from './types'; import type { Asset } from './types';
@ -124,6 +124,7 @@ export const WithdrawForm = ({
)} )}
{ethereumAccount && ( {ethereumAccount && (
<UseButton <UseButton
data-testid="use-connected"
onClick={() => { onClick={() => {
setValue('to', ethereumAccount); setValue('to', ethereumAccount);
clearErrors('to'); clearErrors('to');
@ -154,6 +155,7 @@ export const WithdrawForm = ({
)} )}
{selectedAsset && ( {selectedAsset && (
<UseButton <UseButton
data-testid="use-maximum"
onClick={() => { onClick={() => {
setValue('amount', max.toFixed(selectedAsset.decimals)); setValue('amount', max.toFixed(selectedAsset.decimals));
clearErrors('amount'); clearErrors('amount');
@ -163,22 +165,23 @@ export const WithdrawForm = ({
</UseButton> </UseButton>
)} )}
</FormGroup> </FormGroup>
<Button type="submit">Submit</Button> <Button data-testid="submit-withdrawal" type="submit">
Submit
</Button>
</form> </form>
); );
}; };
interface UseButtonProps { interface UseButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
children: ReactNode; children: ReactNode;
onClick: () => void;
} }
const UseButton = ({ children, onClick }: UseButtonProps) => { const UseButton = ({ children, ...rest }: UseButtonProps) => {
return ( return (
<button <button
{...rest}
type="button" type="button"
className="ml-auto text-ui absolute top-0 right-0 underline" className="ml-auto text-ui absolute top-0 right-0 underline"
onClick={onClick}
> >
{children} {children}
</button> </button>