Merge branch 'master' of github.com:vegaprotocol/frontend-monorepo
This commit is contained in:
commit
e5efa417a0
@ -1,16 +1,13 @@
|
|||||||
const { defineConfig } = require('cypress');
|
const { defineConfig } = require('cypress');
|
||||||
const setupNodeEvents = require('./src/plugins/index.js');
|
|
||||||
|
|
||||||
module.exports = defineConfig({
|
module.exports = defineConfig({
|
||||||
projectId: 'et4snf',
|
projectId: 'et4snf',
|
||||||
|
|
||||||
e2e: {
|
e2e: {
|
||||||
setupNodeEvents,
|
|
||||||
baseUrl: 'http://localhost:3000',
|
baseUrl: 'http://localhost:3000',
|
||||||
fileServerFolder: '.',
|
fileServerFolder: '.',
|
||||||
fixturesFolder: false,
|
fixturesFolder: false,
|
||||||
specPattern: '**/*.feature',
|
specPattern: '**/*.cy.{js,jsx,ts,tsx}',
|
||||||
excludeSpecPattern: '**/*.js',
|
|
||||||
modifyObstructiveCode: false,
|
modifyObstructiveCode: false,
|
||||||
supportFile: './src/support/index.ts',
|
supportFile: './src/support/index.ts',
|
||||||
video: true,
|
video: true,
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
Feature: Asset Page
|
|
||||||
|
|
||||||
Scenario: Navigate to Asset Page
|
|
||||||
Given I am on the homepage
|
|
||||||
When I navigate to the asset page
|
|
||||||
Then asset page is correctly displayed
|
|
||||||
|
|
||||||
Scenario: Navigate to Asset Page using mobile
|
|
||||||
Given I am on mobile and open the toggle menu
|
|
||||||
When I navigate to the asset page
|
|
||||||
Then asset page is correctly displayed
|
|
20
apps/explorer-e2e/src/integration/asset.cy.js
Normal file
20
apps/explorer-e2e/src/integration/asset.cy.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import '../support/common.functions';
|
||||||
|
|
||||||
|
context('Asset page', function () {
|
||||||
|
describe('Verify elements on page', function () {
|
||||||
|
const assetsNavigation = 'a[href="/assets"]';
|
||||||
|
const assetHeader = '[data-testid="asset-header"]';
|
||||||
|
|
||||||
|
it('Assets page is displayed', function () {
|
||||||
|
cy.visit('/');
|
||||||
|
cy.get(assetsNavigation).click();
|
||||||
|
cy.common_validate_blocks_data_displayed(assetHeader);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Assets page displayed in mobile', function () {
|
||||||
|
cy.common_switch_to_mobile_and_click_toggle();
|
||||||
|
cy.get(assetsNavigation).click();
|
||||||
|
cy.common_validate_blocks_data_displayed(assetHeader);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -1,38 +0,0 @@
|
|||||||
Feature: Blocks Page
|
|
||||||
|
|
||||||
Scenario: Navigate to blocks page
|
|
||||||
Given I am on the homepage
|
|
||||||
When I navigate to the blocks page
|
|
||||||
Then blocks page is correctly displayed
|
|
||||||
|
|
||||||
Scenario: Navigate to blocks page using mobile
|
|
||||||
Given I am on mobile and open the toggle menu
|
|
||||||
When I navigate to the blocks page
|
|
||||||
Then blocks page is correctly displayed
|
|
||||||
|
|
||||||
Scenario: Navigate to block validator page
|
|
||||||
Given I am on the homepage
|
|
||||||
When I navigate to the blocks page
|
|
||||||
And I click on top block
|
|
||||||
Then validator block page is correctly displayed
|
|
||||||
|
|
||||||
Scenario: Navigate to previous block
|
|
||||||
Given I am on the homepage
|
|
||||||
When I navigate to the blocks page
|
|
||||||
And I click on top block
|
|
||||||
Then I am on the previous block when I click previous
|
|
||||||
|
|
||||||
Scenario: Previous button disabled on first block
|
|
||||||
Given I am on the homepage
|
|
||||||
When I navigate to the blocks page
|
|
||||||
And jump to first block
|
|
||||||
Then previous button is disabled
|
|
||||||
And I am on the second block when I click next
|
|
||||||
|
|
||||||
# Skipping these tests for time being - since blockchain in capsule
|
|
||||||
# is now too small to show historical data - re-enable once addressed
|
|
||||||
# Scenario: Infinite scroll shows at least 300 new blocks
|
|
||||||
# Given I am on the homepage
|
|
||||||
# When I navigate to the blocks page
|
|
||||||
# And I scroll down to the last block on the page
|
|
||||||
# Then I can expect to see at least 100 blocks if i scroll 7 times
|
|
132
apps/explorer-e2e/src/integration/blocks.cy.js
Normal file
132
apps/explorer-e2e/src/integration/blocks.cy.js
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
import '../support/common.functions';
|
||||||
|
|
||||||
|
context('Blocks page', function () {
|
||||||
|
before('visit token home page', function () {
|
||||||
|
cy.visit('/');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Verify elements on page', function () {
|
||||||
|
const blockNavigation = 'a[href="/blocks"]';
|
||||||
|
const blockHeight = '[data-testid="block-height"]';
|
||||||
|
const blockTime = '[data-testid="block-time"]';
|
||||||
|
const blockHeader = '[data-testid="block-header"]';
|
||||||
|
const previousBlockBtn = '[data-testid="previous-block"]';
|
||||||
|
const infiniteScrollWrapper = '[data-testid="infinite-scroll-wrapper"]';
|
||||||
|
|
||||||
|
beforeEach('navigate to blocks page', function () {
|
||||||
|
cy.get(blockNavigation).click();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Blocks page is displayed', function () {
|
||||||
|
validateBlocksDisplayed();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Blocks page is displayed on mobile', function () {
|
||||||
|
cy.common_switch_to_mobile_and_click_toggle();
|
||||||
|
cy.get(blockNavigation).click();
|
||||||
|
validateBlocksDisplayed();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Block validator page is displayed', function () {
|
||||||
|
waitForBlocksResponse();
|
||||||
|
cy.get(blockHeight).eq(0).click();
|
||||||
|
cy.get('[data-testid="block-validator"]').should('not.be.empty');
|
||||||
|
cy.get(blockTime).should('not.be.empty');
|
||||||
|
//TODO: Add assertion for transactions when txs are added
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Navigate to previous block', function () {
|
||||||
|
waitForBlocksResponse();
|
||||||
|
cy.get(blockHeight).eq(0).click();
|
||||||
|
cy.get(blockHeader)
|
||||||
|
.invoke('text')
|
||||||
|
.then(($blockHeaderTxt) => {
|
||||||
|
const blockHeight = parseInt($blockHeaderTxt.replace('BLOCK ', ''));
|
||||||
|
cy.get(previousBlockBtn).click();
|
||||||
|
cy.get(blockHeader)
|
||||||
|
.invoke('text')
|
||||||
|
.then(($newBlockHeaderTxt) => {
|
||||||
|
const newBlockHeight = parseInt(
|
||||||
|
$newBlockHeaderTxt.replace('BLOCK ', '')
|
||||||
|
);
|
||||||
|
expect(newBlockHeight).to.be.lessThan(blockHeight);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Previous button disabled on first block', function () {
|
||||||
|
cy.get('[data-testid="block-input"]').type('1');
|
||||||
|
cy.get('[data-testid="go-submit"]').click();
|
||||||
|
cy.get(previousBlockBtn).find('button').should('be.disabled');
|
||||||
|
cy.get(blockHeader)
|
||||||
|
.invoke('text')
|
||||||
|
.then(($blockHeaderTxt) => {
|
||||||
|
const blockHeight = parseInt($blockHeaderTxt.replace('BLOCK ', ''));
|
||||||
|
cy.get('[data-testid="next-block"]').click();
|
||||||
|
cy.get(blockHeader)
|
||||||
|
.invoke('text')
|
||||||
|
.then(($newBlockHeaderTxt) => {
|
||||||
|
const newBlockHeight = parseInt(
|
||||||
|
$newBlockHeaderTxt.replace('BLOCK ', '')
|
||||||
|
);
|
||||||
|
expect(newBlockHeight).to.be.greaterThan(blockHeight);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Skipping these tests for time being - since blockchain in capsule is now too small to show historical data - re-enable once addressed
|
||||||
|
it.skip('Infinite scroll shows at least 100 new blocks', function () {
|
||||||
|
const expectedBlocks = 100;
|
||||||
|
const scrollAttempts = 7;
|
||||||
|
|
||||||
|
waitForBlocksResponse();
|
||||||
|
cy.get(infiniteScrollWrapper).children().scrollTo('bottom');
|
||||||
|
|
||||||
|
cy.intercept('*blockchain?maxHeight*').as('blockchain_load');
|
||||||
|
cy.get(blockHeight)
|
||||||
|
.last()
|
||||||
|
.invoke('text')
|
||||||
|
.then(($initialLastBlockHeight) => {
|
||||||
|
for (let index = 0; index < scrollAttempts; index++) {
|
||||||
|
cy.get(infiniteScrollWrapper)
|
||||||
|
.children()
|
||||||
|
.children()
|
||||||
|
.invoke('css', 'height')
|
||||||
|
.then((scrollTarget) => {
|
||||||
|
cy.get(infiniteScrollWrapper)
|
||||||
|
.children()
|
||||||
|
.scrollTo(0, scrollTarget.toString(), { easing: 'linear' })
|
||||||
|
.wait('@blockchain_load');
|
||||||
|
|
||||||
|
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||||
|
cy.wait(50); // Need this as although network response has arrived it takes a few millisecs for the css height to expand
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
cy.get(blockHeight)
|
||||||
|
.last()
|
||||||
|
.invoke('text')
|
||||||
|
.then(($lastBlockHeight) => {
|
||||||
|
const totalBlocksLoadedSinceScrollBegan =
|
||||||
|
parseInt($initialLastBlockHeight) - parseInt($lastBlockHeight);
|
||||||
|
expect(totalBlocksLoadedSinceScrollBegan).to.be.at.least(
|
||||||
|
expectedBlocks
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function waitForBlocksResponse() {
|
||||||
|
cy.contains('Loading...').should('not.exist', { timeout: 18000 });
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateBlocksDisplayed() {
|
||||||
|
waitForBlocksResponse();
|
||||||
|
cy.get('[data-testid="block-row"]').should('have.length.above', 1);
|
||||||
|
cy.get(blockHeight).first().should('not.be.empty');
|
||||||
|
cy.get('[data-testid="num-txs"]').first().should('not.be.empty');
|
||||||
|
cy.get('[data-testid="validator-link"]').first().should('not.be.empty');
|
||||||
|
cy.get(blockTime).first().should('not.be.empty');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
@ -1,27 +0,0 @@
|
|||||||
Feature: Home page
|
|
||||||
|
|
||||||
Scenario: Stats page displayed correctly
|
|
||||||
Given I am on the homepage
|
|
||||||
Then the stats for deployed environment are correctly displayed
|
|
||||||
|
|
||||||
Scenario Outline: Succesfful search for specific id by <IdType>
|
|
||||||
Given I am on the homepage
|
|
||||||
When I search for '<Id>'
|
|
||||||
Then I am redirected to page containing id '<Id>'
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
| IdType | Id |
|
|
||||||
| Block Id | 973624 |
|
|
||||||
| Tx Hash | 9ED3718AA8308E7E08EC588EE7AADAF49711D2138860D8914B4D81A2054D9FB8 |
|
|
||||||
| Tx Id | 0x61DCCEBB955087F50D0B85382DAE138EDA9631BF1A4F92E563D528904AA38898 |
|
|
||||||
|
|
||||||
Scenario Outline: Error message displayed when invalid search by <invalidType>
|
|
||||||
Given I am on the homepage
|
|
||||||
When I search for '<Id>'
|
|
||||||
Then search error message "<errorMessage>" is displayed
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
| invalidType | Id | errorMessage |
|
|
||||||
| wrong string length | 9ED3718AA8308E7E08EC588EE7AADAF497D2138860D8914B4D81A2054D9FB8 | Something doesn't look right |
|
|
||||||
| invalid hash | 9ED3718AA8308E7E08ECht8EE753DAF49711D2138860D8914B4D81A2054D9FB8 | Transaction is not hexadecimal |
|
|
||||||
| empty search | | Search required |
|
|
141
apps/explorer-e2e/src/integration/home.cy.js
Normal file
141
apps/explorer-e2e/src/integration/home.cy.js
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
context('Home Page', function () {
|
||||||
|
before('visit home page', function () {
|
||||||
|
cy.visit('/');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Stats page', function () {
|
||||||
|
const statsValue = '[data-testid="stats-value"]';
|
||||||
|
|
||||||
|
it('Should show connected environment', function () {
|
||||||
|
const deployedEnv = Cypress.env('environment').toUpperCase();
|
||||||
|
cy.get('[data-testid="stats-environment"]').should(
|
||||||
|
'have.text',
|
||||||
|
`/ ${deployedEnv}`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show connected environment stats', function () {
|
||||||
|
const statTitles = {
|
||||||
|
0: 'Status',
|
||||||
|
1: 'Height',
|
||||||
|
2: 'Validating nodes',
|
||||||
|
3: 'Uptime',
|
||||||
|
4: 'Total nodes',
|
||||||
|
5: 'Inactive nodes',
|
||||||
|
6: 'Total staked',
|
||||||
|
7: 'Backlog',
|
||||||
|
8: 'Trades / second',
|
||||||
|
9: 'Orders / block',
|
||||||
|
10: 'Orders / second',
|
||||||
|
11: 'Transactions / block',
|
||||||
|
12: 'Block time',
|
||||||
|
13: 'Time',
|
||||||
|
14: 'App',
|
||||||
|
15: 'Tendermint',
|
||||||
|
16: 'Up since',
|
||||||
|
17: 'Chain ID',
|
||||||
|
};
|
||||||
|
|
||||||
|
cy.get('[data-testid="stats-title"]')
|
||||||
|
.each(($list, index) => {
|
||||||
|
cy.wrap($list).should('have.text', statTitles[index]);
|
||||||
|
})
|
||||||
|
.then(($list) => {
|
||||||
|
cy.wrap($list).should('have.length', 18);
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get(statsValue).eq(0).should('have.text', 'CONNECTED');
|
||||||
|
cy.get(statsValue).eq(1).should('not.be.empty');
|
||||||
|
cy.get(statsValue).eq(2).should('have.text', '2');
|
||||||
|
cy.get(statsValue)
|
||||||
|
.eq(3)
|
||||||
|
.invoke('text')
|
||||||
|
.should('match', /\d+d \d+h \d+m \d+s/i);
|
||||||
|
cy.get(statsValue).eq(4).should('have.text', '2');
|
||||||
|
cy.get(statsValue).eq(5).should('have.text', '0');
|
||||||
|
cy.get(statsValue).eq(6).should('have.text', '0.00');
|
||||||
|
cy.get(statsValue).eq(7).should('have.text', '0');
|
||||||
|
cy.get(statsValue).eq(8).should('have.text', '0');
|
||||||
|
cy.get(statsValue).eq(9).should('have.text', '0');
|
||||||
|
cy.get(statsValue).eq(10).should('have.text', '0');
|
||||||
|
cy.get(statsValue).eq(11).should('not.be.empty');
|
||||||
|
cy.get(statsValue).eq(12).should('not.be.empty');
|
||||||
|
cy.get(statsValue).eq(13).should('not.be.empty');
|
||||||
|
if (Cypress.env('NIGHTLY_RUN') != true) {
|
||||||
|
cy.get(statsValue)
|
||||||
|
.eq(14)
|
||||||
|
.invoke('text')
|
||||||
|
.should('match', /v\d+\.\d+\.\d+/i);
|
||||||
|
}
|
||||||
|
cy.get(statsValue)
|
||||||
|
.eq(15)
|
||||||
|
.invoke('text')
|
||||||
|
.should('match', /\d+\.\d+\.\d+/i);
|
||||||
|
cy.get(statsValue).eq(16).should('not.be.empty');
|
||||||
|
cy.get(statsValue).eq(17).should('not.be.empty');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Block height should be updating', function () {
|
||||||
|
cy.get(statsValue)
|
||||||
|
.eq(1)
|
||||||
|
.invoke('text')
|
||||||
|
.then((blockHeightTxt) => {
|
||||||
|
cy.get(statsValue)
|
||||||
|
.eq(1)
|
||||||
|
.invoke('text')
|
||||||
|
.should((newBlockHeightTxt) => {
|
||||||
|
expect(blockHeightTxt).not.to.eq(newBlockHeightTxt);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Search bar', function () {
|
||||||
|
it('Successful search for specific id by block id', function () {
|
||||||
|
const blockId = '973624';
|
||||||
|
search(blockId);
|
||||||
|
cy.url().should('include', blockId);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Successful search for specific id by tx hash', function () {
|
||||||
|
const txHash =
|
||||||
|
'9ED3718AA8308E7E08EC588EE7AADAF49711D2138860D8914B4D81A2054D9FB8';
|
||||||
|
search(txHash);
|
||||||
|
cy.url().should('include', txHash);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Successful search for specific id by tx id', function () {
|
||||||
|
const txId =
|
||||||
|
'0x61DCCEBB955087F50D0B85382DAE138EDA9631BF1A4F92E563D528904AA38898';
|
||||||
|
search(txId);
|
||||||
|
cy.url().should('include', txId);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Error message displayed when invalid search by wrong string length', function () {
|
||||||
|
search('9ED3718AA8308E7E08EC588EE7AADAF497D2138860D8914B4D81A2054D9FB8');
|
||||||
|
validateSearchError("Something doesn't look right");
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Error message displayed when invalid search by invalid hash', function () {
|
||||||
|
search(
|
||||||
|
'9ED3718AA8308E7E08ECht8EE753DAF49711D2138860D8914B4D81A2054D9FB8'
|
||||||
|
);
|
||||||
|
validateSearchError('Transaction is not hexadecimal');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Error message displayed when searching empty field', function () {
|
||||||
|
cy.get('[data-testid="search"]').clear();
|
||||||
|
cy.get('[data-testid="search-button"]').click();
|
||||||
|
validateSearchError('Search required');
|
||||||
|
});
|
||||||
|
|
||||||
|
function search(searchTxt) {
|
||||||
|
cy.get('[data-testid="search"]').clear().type(searchTxt);
|
||||||
|
cy.get('[data-testid="search-button"]').click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateSearchError(expectedError) {
|
||||||
|
cy.get('[data-testid="search-error"]').should('have.text', expectedError);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
21
apps/explorer-e2e/src/integration/market.cy.js
Normal file
21
apps/explorer-e2e/src/integration/market.cy.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import '../support/common.functions';
|
||||||
|
|
||||||
|
//Tests set to skip until market bug for capsule checkpoint is fixed
|
||||||
|
context.skip('Market page', function () {
|
||||||
|
describe('Verify elements on page', function () {
|
||||||
|
const marketHeaders = '[data-testid="markets-header"]';
|
||||||
|
const marketNavigation = 'a[href="/markets"]';
|
||||||
|
|
||||||
|
it('Markets page is displayed', function () {
|
||||||
|
cy.visit('/');
|
||||||
|
cy.get(marketNavigation).click();
|
||||||
|
cy.common_validate_blocks_data_displayed(marketHeaders);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Markets page displayed on mobile', function () {
|
||||||
|
cy.common_switch_to_mobile_and_click_toggle();
|
||||||
|
cy.get(marketNavigation).click();
|
||||||
|
cy.common_validate_blocks_data_displayed(marketHeaders);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -1,14 +0,0 @@
|
|||||||
@todo
|
|
||||||
Feature: Markets Page
|
|
||||||
|
|
||||||
@todo - Needs markets in capsule state
|
|
||||||
Scenario: Navigate to markets page
|
|
||||||
Given I am on the homepage
|
|
||||||
When I navigate to the markets page
|
|
||||||
Then markets page is correctly displayed
|
|
||||||
|
|
||||||
@todo
|
|
||||||
Scenario: Navigate to markets page using mobile
|
|
||||||
Given I am on mobile and open the toggle menu
|
|
||||||
When I navigate to the markets page
|
|
||||||
Then markets page is correctly displayed
|
|
@ -1,11 +0,0 @@
|
|||||||
Feature: Network parameters Page
|
|
||||||
|
|
||||||
Scenario: Navigate to network parameters page
|
|
||||||
Given I am on the homepage
|
|
||||||
When I navigate to network parameters page
|
|
||||||
Then network parameters page is correctly displayed
|
|
||||||
|
|
||||||
Scenario: Navigate to network parameters page using mobile
|
|
||||||
Given I am on mobile and open the toggle menu
|
|
||||||
When I navigate to network parameters page
|
|
||||||
Then network parameters page is correctly displayed
|
|
35
apps/explorer-e2e/src/integration/network.cy.js
Normal file
35
apps/explorer-e2e/src/integration/network.cy.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import '../support/common.functions';
|
||||||
|
|
||||||
|
context('Network parameters page', function () {
|
||||||
|
before('visit token home page', function () {
|
||||||
|
cy.visit('/');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Verify elements on page', function () {
|
||||||
|
const networkParametersNavigation = 'a[href="/network-parameters"]';
|
||||||
|
|
||||||
|
beforeEach('Navigate to network parameter page', function () {
|
||||||
|
cy.get(networkParametersNavigation).click();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Network paremeter page is displayed', function () {
|
||||||
|
verifyNetworkParametersPageDisplayed();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Network parameter page displayed on mobile', function () {
|
||||||
|
cy.common_switch_to_mobile_and_click_toggle();
|
||||||
|
cy.get(networkParametersNavigation).click();
|
||||||
|
verifyNetworkParametersPageDisplayed();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function verifyNetworkParametersPageDisplayed() {
|
||||||
|
cy.get('[data-testid="network-param-header"]').should(
|
||||||
|
'have.text',
|
||||||
|
'Network Parameters'
|
||||||
|
);
|
||||||
|
cy.common_verify_json_parameters(18);
|
||||||
|
cy.common_verify_json_string_values(6);
|
||||||
|
cy.common_verify_json_int_values(7);
|
||||||
|
}
|
||||||
|
});
|
@ -1,21 +0,0 @@
|
|||||||
@ignore
|
|
||||||
# tendermint times out getting txs on testnet atm
|
|
||||||
Feature: Transactions Page
|
|
||||||
|
|
||||||
Scenario: Navigate to transactions page
|
|
||||||
Given I am on the homepage
|
|
||||||
When I navigate to the transactions page
|
|
||||||
Then transactions page is correctly displayed
|
|
||||||
|
|
||||||
Scenario: Navigate to transaction details page
|
|
||||||
Given I am on the homepage
|
|
||||||
When I navigate to the transactions page
|
|
||||||
And I click on the top transaction
|
|
||||||
Then transaction details are displayed
|
|
||||||
|
|
||||||
Scenario: Navigate to transactions page using mobile
|
|
||||||
Given I am on mobile and open the toggle menu
|
|
||||||
When I navigate to the transactions page
|
|
||||||
Then transactions page is correctly displayed
|
|
||||||
When I click on the top transaction
|
|
||||||
Then transaction details are displayed
|
|
87
apps/explorer-e2e/src/integration/transactions.cy.js
Normal file
87
apps/explorer-e2e/src/integration/transactions.cy.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
//Tests set to skip until transactions are generated after capsule start up
|
||||||
|
context.skip('Transactions page', function () {
|
||||||
|
before('visit token home page', function () {
|
||||||
|
cy.visit('/');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Verify elements on page', function () {
|
||||||
|
const transactionNavigation = 'a[href="/txs"]';
|
||||||
|
const transactionRow = 'transaction-row';
|
||||||
|
const txHash = 'hash';
|
||||||
|
|
||||||
|
beforeEach('Navigate to transactions page', function () {
|
||||||
|
cy.get(transactionNavigation).click();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('transactions are displayed', function () {
|
||||||
|
cy.get(transactionRow).should('have.length.above', 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('transactions details page is displayed', function () {
|
||||||
|
clickTopTransaction();
|
||||||
|
validateTxDetailsAreDisplayed();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('transactions details page is displayed in mobile', function () {
|
||||||
|
cy.common_switch_to_mobile_and_click_toggle();
|
||||||
|
cy.get(transactionNavigation).click();
|
||||||
|
clickTopTransaction();
|
||||||
|
validateTxDetailsAreDisplayed();
|
||||||
|
});
|
||||||
|
|
||||||
|
function clickTopTransaction() {
|
||||||
|
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||||
|
cy.wait(1000); // Wait for transactions to load if there are any
|
||||||
|
cy.get('body').then(($body) => {
|
||||||
|
if ($body.find(transactionRow).length) {
|
||||||
|
cy.get(transactionRow)
|
||||||
|
.first()
|
||||||
|
.find('a')
|
||||||
|
.first()
|
||||||
|
.click({ force: true });
|
||||||
|
} else {
|
||||||
|
cy.slack('Unable to find any transactions on page');
|
||||||
|
cy.screenshot();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateTxDetailsAreDisplayed() {
|
||||||
|
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||||
|
cy.wait(1000); // Wait for transactions to load if there are any
|
||||||
|
cy.get('body').then(($body) => {
|
||||||
|
if ($body.find(txHash).length) {
|
||||||
|
cy.get(txHash).invoke('text').should('have.length', 64);
|
||||||
|
cy.get('submitted-by')
|
||||||
|
.find('a')
|
||||||
|
.then(($address) => {
|
||||||
|
cy.wrap($address).should('have.attr', 'href');
|
||||||
|
cy.wrap($address).invoke('text').should('have.length', 66);
|
||||||
|
});
|
||||||
|
cy.get('block').should('not.be.empty');
|
||||||
|
cy.get('encoded-tnx').should('not.be.empty');
|
||||||
|
cy.get('tx-type')
|
||||||
|
.should('not.be.empty')
|
||||||
|
.invoke('text')
|
||||||
|
.then((txTypeTxt) => {
|
||||||
|
if (txTypeTxt == 'Order Submission') {
|
||||||
|
cy.get('.hljs-attr')
|
||||||
|
.should('have.length.at.least', 8)
|
||||||
|
.each(($propertyName) => {
|
||||||
|
cy.wrap($propertyName).should('not.be.empty');
|
||||||
|
});
|
||||||
|
cy.get('.hljs-string')
|
||||||
|
.should('have.length.at.least', 8)
|
||||||
|
.each(($propertyValue) => {
|
||||||
|
cy.wrap($propertyValue).should('not.be.empty');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
cy.slack('Unable to find any transactions on page');
|
||||||
|
cy.screenshot();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
28
apps/explorer-e2e/src/integration/validator.cy.js
Normal file
28
apps/explorer-e2e/src/integration/validator.cy.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import '../support/common.functions';
|
||||||
|
|
||||||
|
context('Validator page', function () {
|
||||||
|
describe('Verify elements on page', function () {
|
||||||
|
const validatorNavigation = 'a[href="/validators"]';
|
||||||
|
|
||||||
|
it('Validator page is displayed', function () {
|
||||||
|
cy.visit('/');
|
||||||
|
cy.get(validatorNavigation).click();
|
||||||
|
validateValidatorsDisplayed();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Validator page is displayed on mobile', function () {
|
||||||
|
cy.common_switch_to_mobile_and_click_toggle();
|
||||||
|
cy.get(validatorNavigation).click();
|
||||||
|
validateValidatorsDisplayed();
|
||||||
|
});
|
||||||
|
|
||||||
|
function validateValidatorsDisplayed() {
|
||||||
|
cy.get('[data-testid="tendermint-header"]').should(
|
||||||
|
'have.text',
|
||||||
|
'Tendermint data'
|
||||||
|
);
|
||||||
|
cy.get('[data-testid="vega-header"]').should('have.text', 'Vega data');
|
||||||
|
cy.get('[data-testid="vega-data"]').should('not.be.empty');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
@ -1,11 +0,0 @@
|
|||||||
Feature: Validators Page
|
|
||||||
|
|
||||||
Scenario: Navigate to validators page
|
|
||||||
Given I am on the homepage
|
|
||||||
When I navigate to the validators page
|
|
||||||
Then validators page is correctly displayed
|
|
||||||
|
|
||||||
Scenario: Navigate to validators page using mobile
|
|
||||||
Given I am on mobile and open the toggle menu
|
|
||||||
When I navigate to the validators page
|
|
||||||
Then validators page is correctly displayed
|
|
@ -1,75 +0,0 @@
|
|||||||
/// <reference types="cypress" />
|
|
||||||
|
|
||||||
const webpackPreprocessor = require('@cypress/webpack-preprocessor');
|
|
||||||
const webpack = require('webpack');
|
|
||||||
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
|
|
||||||
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
|
|
||||||
const nodeExternals = require('webpack-node-externals');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {Cypress.PluginConfig}
|
|
||||||
*/
|
|
||||||
module.exports = (on, config) => {
|
|
||||||
on(
|
|
||||||
'file:preprocessor',
|
|
||||||
webpackPreprocessor({
|
|
||||||
webpackOptions: {
|
|
||||||
resolve: {
|
|
||||||
extensions: ['.ts', '.tsx', '.mjs', '.js', '.jsx'],
|
|
||||||
plugins: [
|
|
||||||
new TsconfigPathsPlugin({
|
|
||||||
configFile: config.env.tsConfig,
|
|
||||||
extensions: ['.ts', '.tsx', '.mjs', '.js', '.jsx'],
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
fallback: {
|
|
||||||
path: require.resolve('path-browserify'),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
module: {
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
test: /\.([jt])sx?$/,
|
|
||||||
loader: 'ts-loader',
|
|
||||||
exclude: [/node_modules/],
|
|
||||||
options: {
|
|
||||||
configFile: config.env.tsConfig,
|
|
||||||
// https://github.com/TypeStrong/ts-loader/pull/685
|
|
||||||
experimentalWatchApi: true,
|
|
||||||
transpileOnly: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.feature$/,
|
|
||||||
use: [
|
|
||||||
{
|
|
||||||
loader: 'cypress-cucumber-preprocessor/loader',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.features$/,
|
|
||||||
use: [
|
|
||||||
{
|
|
||||||
loader: 'cypress-cucumber-preprocessor/lib/featuresLoader',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
new ForkTsCheckerWebpackPlugin({
|
|
||||||
typescript: {
|
|
||||||
enabled: true,
|
|
||||||
configFile: config.env.tsConfig,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
new webpack.ProvidePlugin({
|
|
||||||
process: 'process/browser',
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
externals: [nodeExternals()],
|
|
||||||
},
|
|
||||||
})
|
|
||||||
);
|
|
||||||
};
|
|
53
apps/explorer-e2e/src/support/common.functions.js
Normal file
53
apps/explorer-e2e/src/support/common.functions.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
Cypress.Commands.add(
|
||||||
|
'common_validate_blocks_data_displayed',
|
||||||
|
function (headerTestId) {
|
||||||
|
cy.get(headerTestId).then(($assetHeaders) => {
|
||||||
|
const headersLength = Number($assetHeaders.length);
|
||||||
|
|
||||||
|
cy.wrap($assetHeaders).each(($header) => {
|
||||||
|
expect($header).to.not.be.empty;
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.get('.language-json')
|
||||||
|
.each(($asset) => {
|
||||||
|
expect($asset).to.not.be.empty;
|
||||||
|
})
|
||||||
|
.then(($list) => {
|
||||||
|
expect($list).to.have.length(headersLength);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Cypress.Commands.add('common_switch_to_mobile_and_click_toggle', function () {
|
||||||
|
cy.viewport('iphone-x');
|
||||||
|
cy.visit('/');
|
||||||
|
cy.get('[data-testid="open-menu"]').click();
|
||||||
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add('common_verify_json_parameters', function (expectedNum) {
|
||||||
|
cy.get('.hljs-attr')
|
||||||
|
.should('have.length.at.least', expectedNum)
|
||||||
|
.each(($paramName) => {
|
||||||
|
cy.wrap($paramName).should('not.be.empty');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add(
|
||||||
|
'common_verify_json_string_values',
|
||||||
|
function (expectedNum) {
|
||||||
|
cy.get('.hljs-string')
|
||||||
|
.should('have.length.at.least', expectedNum)
|
||||||
|
.each(($paramValue) => {
|
||||||
|
cy.wrap($paramValue).should('not.be.empty');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Cypress.Commands.add('common_verify_json_int_values', function (expectedNum) {
|
||||||
|
cy.get('.hljs-number')
|
||||||
|
.should('have.length.at.least', expectedNum)
|
||||||
|
.each(($paramValue) => {
|
||||||
|
cy.wrap($paramValue).should('not.be.empty');
|
||||||
|
});
|
||||||
|
});
|
2
apps/explorer-e2e/src/support/index.d.ts
vendored
Normal file
2
apps/explorer-e2e/src/support/index.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
// type definitions for Cypress object "cy"
|
||||||
|
/// <reference types="cypress" />
|
@ -1,9 +0,0 @@
|
|||||||
import BasePage from './base-page';
|
|
||||||
|
|
||||||
export default class AssetsPage extends BasePage {
|
|
||||||
assetHeader = 'asset-header';
|
|
||||||
|
|
||||||
validateAssetsDisplayed() {
|
|
||||||
this.validateBlockDataDisplayed(this.assetHeader);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,100 +0,0 @@
|
|||||||
export default class BasePage {
|
|
||||||
transactionsUrl = '/txs';
|
|
||||||
blocksUrl = '/blocks';
|
|
||||||
partiesUrl = '/parties';
|
|
||||||
assetsUrl = '/assets';
|
|
||||||
genesisUrl = '/genesis';
|
|
||||||
governanceUrl = '/governance';
|
|
||||||
marketsUrl = '/markets';
|
|
||||||
networkParametersUrl = '/network-parameters';
|
|
||||||
validatorsUrl = '/validators';
|
|
||||||
blockExplorerHeader = 'explorer-header';
|
|
||||||
searchField = 'search';
|
|
||||||
searchButton = 'search-button';
|
|
||||||
searchError = 'search-error';
|
|
||||||
openMobileMenuBtn = 'open-menu';
|
|
||||||
|
|
||||||
navigateToTxs() {
|
|
||||||
cy.get(`a[href='${this.transactionsUrl}']`).click();
|
|
||||||
}
|
|
||||||
|
|
||||||
navigateToBlocks() {
|
|
||||||
cy.get(`a[href='${this.blocksUrl}']`).click();
|
|
||||||
}
|
|
||||||
|
|
||||||
navigateToParties() {
|
|
||||||
cy.get(`a[href='${this.partiesUrl}']`).click();
|
|
||||||
}
|
|
||||||
|
|
||||||
navigateToAssets() {
|
|
||||||
cy.get(`a[href*='${this.assetsUrl}']`).click();
|
|
||||||
}
|
|
||||||
|
|
||||||
navigateToGenesis() {
|
|
||||||
cy.get(`a[href='${this.genesisUrl}']`).click();
|
|
||||||
}
|
|
||||||
|
|
||||||
navigateToGovernance() {
|
|
||||||
cy.get(`a[href='${this.governanceUrl}']`).click();
|
|
||||||
}
|
|
||||||
|
|
||||||
navigateToMarkets() {
|
|
||||||
cy.get(`a[href='${this.marketsUrl}']`).click();
|
|
||||||
}
|
|
||||||
|
|
||||||
navigateToNetworkParameters() {
|
|
||||||
cy.get(`a[href='${this.networkParametersUrl}']`).click();
|
|
||||||
}
|
|
||||||
|
|
||||||
navigateToValidators() {
|
|
||||||
cy.get(`a[href='${this.validatorsUrl}']`).click();
|
|
||||||
}
|
|
||||||
|
|
||||||
search(searchText: string) {
|
|
||||||
if (searchText) {
|
|
||||||
cy.getByTestId(this.searchField).type(searchText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clickSearch() {
|
|
||||||
cy.getByTestId(this.searchButton).click();
|
|
||||||
}
|
|
||||||
|
|
||||||
clickOnToggle() {
|
|
||||||
cy.getByTestId(this.openMobileMenuBtn).click({ force: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
validateUrl(expectedUrl: string) {
|
|
||||||
cy.url().should('include', expectedUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
validateSearchDisplayed() {
|
|
||||||
cy.getByTestId(this.blockExplorerHeader).should(
|
|
||||||
'have.text',
|
|
||||||
'Vega Explorer'
|
|
||||||
);
|
|
||||||
cy.getByTestId(this.searchField).should('be.visible');
|
|
||||||
}
|
|
||||||
|
|
||||||
validateSearchErrorDisplayed(errorMessage: string) {
|
|
||||||
cy.getByTestId(this.searchError).should('have.text', errorMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
validateBlockDataDisplayed(headerTestId: string) {
|
|
||||||
cy.getByTestId(headerTestId).then(($assetHeaders) => {
|
|
||||||
const headersAmount = Number($assetHeaders.length);
|
|
||||||
|
|
||||||
cy.wrap($assetHeaders).each(($header) => {
|
|
||||||
expect($header).to.not.be.empty;
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.get('.language-json')
|
|
||||||
.each(($asset) => {
|
|
||||||
expect($asset).to.not.be.empty;
|
|
||||||
})
|
|
||||||
.then(($list) => {
|
|
||||||
expect($list).to.have.length(headersAmount);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,146 +0,0 @@
|
|||||||
import BasePage from './base-page';
|
|
||||||
|
|
||||||
export default class BlocksPage extends BasePage {
|
|
||||||
blockRow = 'block-row';
|
|
||||||
transactionsRow = 'transaction-row';
|
|
||||||
blockHeight = 'block-height';
|
|
||||||
numberOfTransactions = 'num-txs';
|
|
||||||
validatorLink = 'validator-link';
|
|
||||||
blockTime = 'block-time';
|
|
||||||
refreshBtn = 'refresh';
|
|
||||||
blockHeader = 'block-header';
|
|
||||||
minedByValidator = 'block-validator';
|
|
||||||
previousBlockBtn = 'previous-block';
|
|
||||||
nextBlockBtn = 'next-block';
|
|
||||||
jumpToBlockInput = 'block-input';
|
|
||||||
jumpToBlockSubmit = 'go-submit';
|
|
||||||
infiniteScrollWrapper = 'infinite-scroll-wrapper';
|
|
||||||
|
|
||||||
private waitForBlocksResponse() {
|
|
||||||
cy.contains('Loading...').should('not.exist', { timeout: 18000 });
|
|
||||||
}
|
|
||||||
|
|
||||||
validateBlocksPageDisplayed() {
|
|
||||||
this.waitForBlocksResponse();
|
|
||||||
cy.getByTestId(this.blockRow).should('have.length.above', 1);
|
|
||||||
cy.getByTestId(this.blockHeight).first().should('not.be.empty');
|
|
||||||
cy.getByTestId(this.numberOfTransactions).first().should('not.be.empty');
|
|
||||||
cy.getByTestId(this.validatorLink).first().should('not.be.empty');
|
|
||||||
cy.getByTestId(this.blockTime).first().should('not.be.empty');
|
|
||||||
}
|
|
||||||
|
|
||||||
clickOnTopBlockHeight() {
|
|
||||||
this.waitForBlocksResponse();
|
|
||||||
cy.getByTestId(this.blockHeight).first().click();
|
|
||||||
}
|
|
||||||
|
|
||||||
validateBlockValidatorPage() {
|
|
||||||
cy.getByTestId(this.minedByValidator).should('not.be.empty');
|
|
||||||
cy.getByTestId(this.blockTime).should('not.be.empty');
|
|
||||||
cy.get('body').then(($body) => {
|
|
||||||
if ($body.find(`[data-testid=${this.transactionsRow}] > td`).length) {
|
|
||||||
cy.get(`[data-testid=${this.transactionsRow}] > td`).each(($cell) => {
|
|
||||||
cy.wrap($cell).should('not.be.empty');
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
cy.slack('Unable to find any transactions on page');
|
|
||||||
cy.screenshot();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
navigateToPreviousBlock() {
|
|
||||||
cy.getByTestId(this.blockHeader)
|
|
||||||
.invoke('text')
|
|
||||||
.then(($blockHeaderTxt) => {
|
|
||||||
const blockHeight = parseInt($blockHeaderTxt.replace('BLOCK ', ''));
|
|
||||||
this.clickPreviousBlock();
|
|
||||||
cy.getByTestId(this.blockHeader)
|
|
||||||
.invoke('text')
|
|
||||||
.then(($newBlockHeaderTxt) => {
|
|
||||||
const newBlockHeight = parseInt(
|
|
||||||
$newBlockHeaderTxt.replace('BLOCK ', '')
|
|
||||||
);
|
|
||||||
expect(newBlockHeight).to.be.lessThan(blockHeight);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
navigateToNextBlock() {
|
|
||||||
cy.getByTestId(this.blockHeader)
|
|
||||||
.invoke('text')
|
|
||||||
.then(($blockHeaderTxt) => {
|
|
||||||
const blockHeight = parseInt($blockHeaderTxt.replace('BLOCK ', ''));
|
|
||||||
this.clickNextBlock();
|
|
||||||
cy.getByTestId(this.blockHeader)
|
|
||||||
.invoke('text')
|
|
||||||
.then(($newBlockHeaderTxt) => {
|
|
||||||
const newBlockHeight = parseInt(
|
|
||||||
$newBlockHeaderTxt.replace('BLOCK ', '')
|
|
||||||
);
|
|
||||||
expect(newBlockHeight).to.be.greaterThan(blockHeight);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
navigateToLastBlockOnPage() {
|
|
||||||
this.waitForBlocksResponse();
|
|
||||||
cy.getByTestId(this.infiniteScrollWrapper).children().scrollTo('bottom');
|
|
||||||
}
|
|
||||||
|
|
||||||
navigateToOlderBlocksWithInfiniteScroll(
|
|
||||||
expectedBlocks: number,
|
|
||||||
scrollAttempts: number
|
|
||||||
) {
|
|
||||||
cy.intercept('*blockchain?maxHeight*').as('blockchain_load');
|
|
||||||
|
|
||||||
cy.getByTestId(this.blockHeight)
|
|
||||||
.last()
|
|
||||||
.invoke('text')
|
|
||||||
.then(($initialLastBlockHeight) => {
|
|
||||||
for (let index = 0; index < scrollAttempts; index++) {
|
|
||||||
cy.getByTestId(this.infiniteScrollWrapper)
|
|
||||||
.children()
|
|
||||||
.children()
|
|
||||||
.invoke('css', 'height')
|
|
||||||
.then((scrollTarget) => {
|
|
||||||
cy.getByTestId(this.infiniteScrollWrapper)
|
|
||||||
.children()
|
|
||||||
.scrollTo(0, scrollTarget.toString(), { easing: 'linear' })
|
|
||||||
.wait('@blockchain_load');
|
|
||||||
|
|
||||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
|
||||||
cy.wait(50); // Need this as although network response has arrived it takes a few millisecs for the css height to expand
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
cy.getByTestId(this.blockHeight)
|
|
||||||
.last()
|
|
||||||
.invoke('text')
|
|
||||||
.then(($lastBlockHeight) => {
|
|
||||||
const totalBlocksLoadedSinceScrollBegan =
|
|
||||||
parseInt($initialLastBlockHeight) - parseInt($lastBlockHeight);
|
|
||||||
expect(totalBlocksLoadedSinceScrollBegan).to.be.at.least(
|
|
||||||
expectedBlocks
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
clickPreviousBlock() {
|
|
||||||
cy.getByTestId(this.previousBlockBtn).click();
|
|
||||||
}
|
|
||||||
|
|
||||||
clickNextBlock() {
|
|
||||||
cy.getByTestId(this.nextBlockBtn).click();
|
|
||||||
}
|
|
||||||
|
|
||||||
jumpToBlock(blockNumber: string) {
|
|
||||||
cy.getByTestId(this.jumpToBlockInput).type(blockNumber);
|
|
||||||
cy.getByTestId(this.jumpToBlockSubmit).click();
|
|
||||||
}
|
|
||||||
|
|
||||||
verifyPreviousBtnDisabled() {
|
|
||||||
cy.getByTestId(this.previousBlockBtn).find('button').should('be.disabled');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
import BasePage from './base-page';
|
|
||||||
|
|
||||||
export default class GenesisPage extends BasePage {
|
|
||||||
genesisHeader = 'genesis-header';
|
|
||||||
|
|
||||||
genesisFieldsDisplayed() {
|
|
||||||
this.validateBlockDataDisplayed(this.genesisHeader);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,95 +0,0 @@
|
|||||||
import BasePage from './base-page';
|
|
||||||
export default class HomePage extends BasePage {
|
|
||||||
statsEnvironmentTitle = 'stats-environment';
|
|
||||||
statsTitle = 'stats-title';
|
|
||||||
statsValue = 'stats-value';
|
|
||||||
|
|
||||||
verifyStatsEnvironment() {
|
|
||||||
const deployedEnv = Cypress.env('environment').toUpperCase();
|
|
||||||
cy.getByTestId(this.statsEnvironmentTitle).should(
|
|
||||||
'have.text',
|
|
||||||
`/ ${deployedEnv}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
verifyStatsTitlesDisplayed() {
|
|
||||||
const statTitles = [
|
|
||||||
'Status',
|
|
||||||
'Height',
|
|
||||||
'Validating nodes',
|
|
||||||
'Uptime',
|
|
||||||
'Total nodes',
|
|
||||||
'Inactive nodes',
|
|
||||||
'Total staked',
|
|
||||||
'Backlog',
|
|
||||||
'Trades / second',
|
|
||||||
'Orders / block',
|
|
||||||
'Orders / second',
|
|
||||||
'Transactions / block',
|
|
||||||
'Block time',
|
|
||||||
'Time',
|
|
||||||
'App',
|
|
||||||
'Tendermint',
|
|
||||||
'Up since',
|
|
||||||
'Chain ID',
|
|
||||||
];
|
|
||||||
|
|
||||||
cy.getByTestId(this.statsTitle).then(($list) => {
|
|
||||||
cy.wrap($list).should('have.length', 18);
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.getByTestId(this.statsTitle)
|
|
||||||
.each(($title, index) => {
|
|
||||||
cy.wrap($title).should('have.text', statTitles[index]);
|
|
||||||
})
|
|
||||||
.then(($list) => {
|
|
||||||
cy.wrap($list).should('have.length', 18);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
verifyStatsValuesDisplayed() {
|
|
||||||
cy.getByTestId(this.statsValue).eq(0).should('have.text', 'CONNECTED');
|
|
||||||
cy.getByTestId(this.statsValue).eq(1).should('not.be.empty');
|
|
||||||
cy.getByTestId(this.statsValue).eq(2).should('have.text', '2');
|
|
||||||
cy.getByTestId(this.statsValue)
|
|
||||||
.eq(3)
|
|
||||||
.invoke('text')
|
|
||||||
.should('match', /\d+d \d+h \d+m \d+s/i);
|
|
||||||
cy.getByTestId(this.statsValue).eq(4).should('have.text', '2');
|
|
||||||
cy.getByTestId(this.statsValue).eq(5).should('have.text', '0');
|
|
||||||
cy.getByTestId(this.statsValue).eq(6).should('not.be.empty');
|
|
||||||
cy.getByTestId(this.statsValue).eq(7).should('have.text', '0');
|
|
||||||
cy.getByTestId(this.statsValue).eq(8).should('have.text', '0');
|
|
||||||
cy.getByTestId(this.statsValue).eq(9).should('have.text', '0');
|
|
||||||
cy.getByTestId(this.statsValue).eq(10).should('have.text', '0');
|
|
||||||
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(13).should('not.be.empty');
|
|
||||||
if (Cypress.env('NIGHTLY_RUN') != true) {
|
|
||||||
cy.getByTestId(this.statsValue)
|
|
||||||
.eq(14)
|
|
||||||
.invoke('text')
|
|
||||||
.should('match', /v\d+\.\d+\.\d+/i);
|
|
||||||
}
|
|
||||||
cy.getByTestId(this.statsValue)
|
|
||||||
.eq(15)
|
|
||||||
.invoke('text')
|
|
||||||
.should('match', /\d+\.\d+\.\d+/i);
|
|
||||||
cy.getByTestId(this.statsValue).eq(16).should('not.be.empty');
|
|
||||||
cy.getByTestId(this.statsValue).eq(17).should('not.be.empty');
|
|
||||||
}
|
|
||||||
|
|
||||||
verifyStatsBlockHeightUpdating() {
|
|
||||||
cy.getByTestId(this.statsValue)
|
|
||||||
.eq(1)
|
|
||||||
.invoke('text')
|
|
||||||
.then((blockHeightTxt) => {
|
|
||||||
cy.getByTestId(this.statsValue)
|
|
||||||
.eq(1)
|
|
||||||
.invoke('text')
|
|
||||||
.should((newBlockHeightTxt) => {
|
|
||||||
expect(blockHeightTxt).not.to.eq(newBlockHeightTxt);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
import BasePage from './base-page';
|
|
||||||
|
|
||||||
export default class MarketsPage extends BasePage {
|
|
||||||
marketHeaders = 'markets-header';
|
|
||||||
|
|
||||||
validateMarketDataDisplayed() {
|
|
||||||
this.validateBlockDataDisplayed(this.marketHeaders);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
import BasePage from './base-page';
|
|
||||||
|
|
||||||
export default class NetworkParametersPage extends BasePage {
|
|
||||||
networkParametersHeader = 'network-param-header';
|
|
||||||
parameters = 'parameters';
|
|
||||||
jsonParamNameClassName = '.hljs-attr';
|
|
||||||
jsonParamValueStringClassName = '.hljs-string';
|
|
||||||
jsonParamValueNumberClassName = '.hljs-number';
|
|
||||||
parameterKeyValueRow = 'key-value-table-row';
|
|
||||||
|
|
||||||
verifyNetworkParametersDisplayed() {
|
|
||||||
cy.getByTestId(this.networkParametersHeader).should(
|
|
||||||
'have.text',
|
|
||||||
'Network Parameters'
|
|
||||||
);
|
|
||||||
|
|
||||||
cy.get(this.jsonParamNameClassName)
|
|
||||||
.should('have.length.at.least', 18)
|
|
||||||
.each(($paramName) => {
|
|
||||||
cy.wrap($paramName).should('not.be.empty');
|
|
||||||
});
|
|
||||||
cy.get(this.jsonParamValueStringClassName)
|
|
||||||
.should('have.length.at.least', 6)
|
|
||||||
.each(($paramValue) => {
|
|
||||||
cy.wrap($paramValue).should('not.be.empty');
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.get(this.jsonParamValueNumberClassName)
|
|
||||||
.should('have.length.at.least', 7)
|
|
||||||
.each(($paramValue) => {
|
|
||||||
cy.wrap($paramValue).should('not.be.empty');
|
|
||||||
});
|
|
||||||
|
|
||||||
cy.getByTestId(this.parameterKeyValueRow).each(($row) => {
|
|
||||||
cy.wrap($row).find('dt').should('not.be.empty');
|
|
||||||
cy.wrap($row).find('dd').should('not.be.empty');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,85 +0,0 @@
|
|||||||
import BasePage from './base-page';
|
|
||||||
|
|
||||||
export default class TransactionsPage extends BasePage {
|
|
||||||
transactionsList = 'transactions-list';
|
|
||||||
transactionRow = 'transaction-row';
|
|
||||||
blockHeight = 'block-height';
|
|
||||||
numberOfTransactions = 'num-txs';
|
|
||||||
validatorLink = 'validator-link';
|
|
||||||
blockTime = 'block-time';
|
|
||||||
refreshBtn = 'refresh';
|
|
||||||
txHash = 'hash';
|
|
||||||
txSubmittedBy = 'submitted-by';
|
|
||||||
txBlock = 'block';
|
|
||||||
txEncodedTnx = 'encoded-tnx';
|
|
||||||
txType = 'tx-type';
|
|
||||||
|
|
||||||
validateTransactionsPagedisplayed() {
|
|
||||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
|
||||||
cy.wait(5000); // Wait for transactions to load if there are any
|
|
||||||
cy.getByTestId(this.transactionRow).should('have.length.above', 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
validateRefreshBtn() {
|
|
||||||
cy.intercept('GET', '**/blockchain').as('get-blockchain');
|
|
||||||
cy.getByTestId(this.refreshBtn).click();
|
|
||||||
cy.wait('@get-blockchain').its('response.statusCode').should('eq', 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
validateTxDetailsAreDisplayed() {
|
|
||||||
// TODO fail test when there are no txs once running with Capsule
|
|
||||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
|
||||||
cy.wait(1000); // Wait for transactions to load if there are any
|
|
||||||
cy.get('body').then(($body) => {
|
|
||||||
if ($body.find(`[data-testid=${this.txHash}]`).length) {
|
|
||||||
cy.getByTestId(this.txHash).invoke('text').should('have.length', 64);
|
|
||||||
cy.getByTestId(this.txSubmittedBy)
|
|
||||||
.find('a')
|
|
||||||
.then(($address) => {
|
|
||||||
cy.wrap($address).should('have.attr', 'href');
|
|
||||||
cy.wrap($address).invoke('text').should('have.length', 66);
|
|
||||||
});
|
|
||||||
cy.getByTestId(this.txBlock).should('not.be.empty');
|
|
||||||
cy.getByTestId(this.txEncodedTnx).should('not.be.empty');
|
|
||||||
cy.getByTestId(this.txType)
|
|
||||||
.should('not.be.empty')
|
|
||||||
.invoke('text')
|
|
||||||
.then((txTypeTxt) => {
|
|
||||||
if (txTypeTxt == 'Order Submission') {
|
|
||||||
cy.get('.hljs-attr')
|
|
||||||
.should('have.length.at.least', 8)
|
|
||||||
.each(($propertyName) => {
|
|
||||||
cy.wrap($propertyName).should('not.be.empty');
|
|
||||||
});
|
|
||||||
cy.get('.hljs-string')
|
|
||||||
.should('have.length.at.least', 8)
|
|
||||||
.each(($propertyValue) => {
|
|
||||||
cy.wrap($propertyValue).should('not.be.empty');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
cy.slack('Unable to find any transactions on page');
|
|
||||||
cy.screenshot();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
clickOnTopTransaction() {
|
|
||||||
// TODO fail test when there are no txs once running with Capsule
|
|
||||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
|
||||||
cy.wait(1000); // Wait for transactions to load if there are any
|
|
||||||
cy.get('body').then(($body) => {
|
|
||||||
if ($body.find(`[data-testid=${this.transactionRow}]`).length) {
|
|
||||||
cy.getByTestId(this.transactionRow)
|
|
||||||
.first()
|
|
||||||
.find('a')
|
|
||||||
.first()
|
|
||||||
.click({ force: true });
|
|
||||||
} else {
|
|
||||||
cy.slack('Unable to find any transactions on page');
|
|
||||||
cy.screenshot();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
import BasePage from './base-page';
|
|
||||||
|
|
||||||
export default class ValidatorPage extends BasePage {
|
|
||||||
tendermintHeader = 'tendermint-header';
|
|
||||||
vegaHeader = 'vega-header';
|
|
||||||
tendermintData = 'tendermint-data';
|
|
||||||
vegaData = 'vega-data';
|
|
||||||
|
|
||||||
validateValidatorsDisplayed() {
|
|
||||||
cy.getByTestId(this.tendermintHeader).should(
|
|
||||||
'have.text',
|
|
||||||
'Tendermint data'
|
|
||||||
);
|
|
||||||
cy.getByTestId(this.tendermintData).should('not.be.empty');
|
|
||||||
cy.getByTestId(this.vegaHeader).should('have.text', 'Vega data');
|
|
||||||
cy.getByTestId(this.vegaData).should('not.be.empty');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
import { Then, When } from 'cypress-cucumber-preprocessor/steps';
|
|
||||||
|
|
||||||
import AssetsPage from '../pages/assets-page';
|
|
||||||
const assetPage = new AssetsPage();
|
|
||||||
|
|
||||||
When('I navigate to the asset page', () => {
|
|
||||||
assetPage.navigateToAssets();
|
|
||||||
});
|
|
||||||
|
|
||||||
Then('asset page is correctly displayed', () => {
|
|
||||||
assetPage.validateAssetsDisplayed();
|
|
||||||
});
|
|
@ -1,50 +0,0 @@
|
|||||||
import { Then, When } from 'cypress-cucumber-preprocessor/steps';
|
|
||||||
|
|
||||||
import BlocksPage from '../pages/blocks-page';
|
|
||||||
const blocksPage = new BlocksPage();
|
|
||||||
|
|
||||||
When('I navigate to the blocks page', () => {
|
|
||||||
blocksPage.navigateToBlocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
When('I click on top block', () => {
|
|
||||||
blocksPage.clickOnTopBlockHeight();
|
|
||||||
});
|
|
||||||
|
|
||||||
When('jump to first block', () => {
|
|
||||||
blocksPage.jumpToBlock('1');
|
|
||||||
});
|
|
||||||
|
|
||||||
Then('blocks page is correctly displayed', () => {
|
|
||||||
blocksPage.validateBlocksPageDisplayed();
|
|
||||||
});
|
|
||||||
|
|
||||||
Then('validator block page is correctly displayed', () => {
|
|
||||||
blocksPage.validateBlockValidatorPage();
|
|
||||||
});
|
|
||||||
|
|
||||||
Then('I am on the previous block when I click previous', () => {
|
|
||||||
blocksPage.navigateToPreviousBlock();
|
|
||||||
});
|
|
||||||
|
|
||||||
Then('previous button is disabled', () => {
|
|
||||||
blocksPage.verifyPreviousBtnDisabled();
|
|
||||||
});
|
|
||||||
|
|
||||||
Then('I am on the second block when I click next', () => {
|
|
||||||
blocksPage.navigateToNextBlock();
|
|
||||||
});
|
|
||||||
|
|
||||||
Then('I scroll down to the last block on the page', () => {
|
|
||||||
blocksPage.navigateToLastBlockOnPage();
|
|
||||||
});
|
|
||||||
|
|
||||||
Then(
|
|
||||||
'I can expect to see at least {int} blocks if i scroll {int} times',
|
|
||||||
(expectedBlocks, scrollAttempts) => {
|
|
||||||
blocksPage.navigateToOlderBlocksWithInfiniteScroll(
|
|
||||||
expectedBlocks,
|
|
||||||
scrollAttempts
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,26 +0,0 @@
|
|||||||
import { Given, Then, When } from 'cypress-cucumber-preprocessor/steps';
|
|
||||||
import BasePage from '../pages/base-page';
|
|
||||||
const basePage = new BasePage();
|
|
||||||
|
|
||||||
Given('I am on mobile and open the toggle menu', () => {
|
|
||||||
cy.viewport('iphone-x');
|
|
||||||
cy.visit('/');
|
|
||||||
basePage.clickOnToggle();
|
|
||||||
});
|
|
||||||
|
|
||||||
Given('I am on the homepage', () => {
|
|
||||||
cy.visit('/');
|
|
||||||
});
|
|
||||||
|
|
||||||
When('I search for {string}', (searchText) => {
|
|
||||||
basePage.search(searchText);
|
|
||||||
basePage.clickSearch();
|
|
||||||
});
|
|
||||||
|
|
||||||
Then('I am redirected to page containing id {string}', (expectedUrl) => {
|
|
||||||
basePage.validateUrl(expectedUrl);
|
|
||||||
});
|
|
||||||
|
|
||||||
Then('search error message {string} is displayed', (expectedErrorMsg) => {
|
|
||||||
basePage.validateSearchErrorDisplayed(expectedErrorMsg);
|
|
||||||
});
|
|
@ -1,11 +0,0 @@
|
|||||||
import { Then } from 'cypress-cucumber-preprocessor/steps';
|
|
||||||
|
|
||||||
import HomePage from '../pages/home-page';
|
|
||||||
const homePage = new HomePage();
|
|
||||||
|
|
||||||
Then('the stats for deployed environment are correctly displayed', () => {
|
|
||||||
homePage.verifyStatsEnvironment();
|
|
||||||
homePage.verifyStatsTitlesDisplayed();
|
|
||||||
homePage.verifyStatsValuesDisplayed();
|
|
||||||
homePage.verifyStatsBlockHeightUpdating();
|
|
||||||
});
|
|
@ -1,12 +0,0 @@
|
|||||||
import { Then, When } from 'cypress-cucumber-preprocessor/steps';
|
|
||||||
|
|
||||||
import MarketsPage from '../pages/markets-page';
|
|
||||||
const marketsPage = new MarketsPage();
|
|
||||||
|
|
||||||
When('I navigate to the markets page', () => {
|
|
||||||
marketsPage.navigateToMarkets();
|
|
||||||
});
|
|
||||||
|
|
||||||
Then('markets page is correctly displayed', () => {
|
|
||||||
marketsPage.validateMarketDataDisplayed();
|
|
||||||
});
|
|
@ -1,11 +0,0 @@
|
|||||||
import { Then, When } from 'cypress-cucumber-preprocessor/steps';
|
|
||||||
import NetworkPage from '../pages/network-page';
|
|
||||||
const networkPage = new NetworkPage();
|
|
||||||
|
|
||||||
When('I navigate to network parameters page', () => {
|
|
||||||
networkPage.navigateToNetworkParameters();
|
|
||||||
});
|
|
||||||
|
|
||||||
Then('network parameters page is correctly displayed', () => {
|
|
||||||
networkPage.verifyNetworkParametersDisplayed();
|
|
||||||
});
|
|
@ -1,30 +0,0 @@
|
|||||||
import { Then, When } from 'cypress-cucumber-preprocessor/steps';
|
|
||||||
|
|
||||||
import TransactionsPage from '../pages/transactions-page';
|
|
||||||
const transactionsPage = new TransactionsPage();
|
|
||||||
|
|
||||||
When('I navigate to the transactions page', () => {
|
|
||||||
transactionsPage.navigateToTxs();
|
|
||||||
});
|
|
||||||
|
|
||||||
When('I navigate to the blocks page', () => {
|
|
||||||
transactionsPage.navigateToBlocks();
|
|
||||||
});
|
|
||||||
|
|
||||||
When('I click on the top transaction', () => {
|
|
||||||
transactionsPage.clickOnTopTransaction();
|
|
||||||
});
|
|
||||||
|
|
||||||
Then('transactions page is correctly displayed', () => {
|
|
||||||
transactionsPage.validateTransactionsPagedisplayed();
|
|
||||||
transactionsPage.validateRefreshBtn();
|
|
||||||
});
|
|
||||||
|
|
||||||
Then('blocks page is correctly displayed', () => {
|
|
||||||
transactionsPage.validateTransactionsPagedisplayed();
|
|
||||||
transactionsPage.validateRefreshBtn();
|
|
||||||
});
|
|
||||||
|
|
||||||
Then('transaction details are displayed', () => {
|
|
||||||
transactionsPage.validateTxDetailsAreDisplayed();
|
|
||||||
});
|
|
@ -1,12 +0,0 @@
|
|||||||
import { Then, When } from 'cypress-cucumber-preprocessor/steps';
|
|
||||||
|
|
||||||
import ValidatorPage from '../pages/validators-page';
|
|
||||||
const validatorsPage = new ValidatorPage();
|
|
||||||
|
|
||||||
When('I navigate to the validators page', () => {
|
|
||||||
validatorsPage.navigateToValidators();
|
|
||||||
});
|
|
||||||
|
|
||||||
Then('validators page is correctly displayed', () => {
|
|
||||||
validatorsPage.validateValidatorsDisplayed();
|
|
||||||
});
|
|
@ -0,0 +1,87 @@
|
|||||||
|
describe('market selector', () => {
|
||||||
|
let markets;
|
||||||
|
before(() => {
|
||||||
|
cy.intercept('POST', '/query', (req) => {
|
||||||
|
const { body } = req;
|
||||||
|
if (body.operationName === 'SimpleMarkets') {
|
||||||
|
req.alias = `gqlSimpleMarketsQuery`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cy.visit('/markets');
|
||||||
|
cy.wait('@gqlSimpleMarketsQuery').then((response) => {
|
||||||
|
if (response.response?.body?.data?.markets?.length) {
|
||||||
|
markets = response.response?.body?.data?.markets;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be properly rendered', () => {
|
||||||
|
if (markets) {
|
||||||
|
cy.visit(`/trading/${markets[0].id}`);
|
||||||
|
cy.get('input[placeholder="Search"]').should(
|
||||||
|
'have.value',
|
||||||
|
markets[0].name
|
||||||
|
);
|
||||||
|
cy.getByTestId('arrow-button').click();
|
||||||
|
cy.getByTestId('market-pane').should('be.visible');
|
||||||
|
cy.getByTestId('market-pane')
|
||||||
|
.children()
|
||||||
|
.find('[role="button"]')
|
||||||
|
.should('contain.text', markets[0].name);
|
||||||
|
cy.getByTestId('market-pane').children().find('[role="button"]').click();
|
||||||
|
cy.getByTestId('market-pane').should('not.be.visible');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('typing should change list', () => {
|
||||||
|
if (markets) {
|
||||||
|
cy.visit(`/trading/${markets[0].id}`);
|
||||||
|
cy.get('input[placeholder="Search"]').type('{backspace}');
|
||||||
|
cy.getByTestId('market-pane')
|
||||||
|
.children()
|
||||||
|
.find('[role="button"]')
|
||||||
|
.should('have.length', 1);
|
||||||
|
cy.get('input[placeholder="Search"]').clear();
|
||||||
|
cy.get('input[placeholder="Search"]').type('a');
|
||||||
|
const filtered = markets.filter((market) => market.name.match(/a/i));
|
||||||
|
cy.getByTestId('market-pane')
|
||||||
|
.children()
|
||||||
|
.find('[role="button"]')
|
||||||
|
.should('have.length', filtered.length);
|
||||||
|
cy.getByTestId('market-pane')
|
||||||
|
.children()
|
||||||
|
.find('[role="button"]')
|
||||||
|
.last()
|
||||||
|
.click();
|
||||||
|
cy.location('pathname').should(
|
||||||
|
'eq',
|
||||||
|
`/trading/${filtered[filtered.length - 1].id}`
|
||||||
|
);
|
||||||
|
cy.get('input[placeholder="Search"]').should(
|
||||||
|
'have.value',
|
||||||
|
filtered[filtered.length - 1].name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('mobile view', () => {
|
||||||
|
if (markets) {
|
||||||
|
cy.viewport('iphone-xr');
|
||||||
|
cy.visit(`/trading/${markets[0].id}`);
|
||||||
|
cy.get('[role="dialog"]').should('not.exist');
|
||||||
|
cy.getByTestId('arrow-button').click();
|
||||||
|
cy.get('[role="dialog"]').should('be.visible');
|
||||||
|
cy.get('input[placeholder="Search"]').clear();
|
||||||
|
cy.getByTestId('market-pane')
|
||||||
|
.children()
|
||||||
|
.find('[role="button"]')
|
||||||
|
.should('have.length', markets.length);
|
||||||
|
cy.pause();
|
||||||
|
cy.getByTestId('dialog-close').click();
|
||||||
|
cy.get('input[placeholder="Search"]').should(
|
||||||
|
'have.value',
|
||||||
|
markets[0].name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
@ -2,30 +2,45 @@ import * as React from 'react';
|
|||||||
import { useForm, Controller } from 'react-hook-form';
|
import { useForm, Controller } from 'react-hook-form';
|
||||||
import Box from '@mui/material/Box';
|
import Box from '@mui/material/Box';
|
||||||
import { Stepper } from '../stepper';
|
import { Stepper } from '../stepper';
|
||||||
import type { DealTicketQuery_market, Order } from '@vegaprotocol/deal-ticket';
|
import type { DealTicketQuery_market } from '@vegaprotocol/deal-ticket';
|
||||||
import { Button, InputError } from '@vegaprotocol/ui-toolkit';
|
import { Button, InputError } from '@vegaprotocol/ui-toolkit';
|
||||||
import {
|
import {
|
||||||
ExpirySelector,
|
ExpirySelector,
|
||||||
SideSelector,
|
SideSelector,
|
||||||
TimeInForceSelector,
|
TimeInForceSelector,
|
||||||
TypeSelector,
|
TypeSelector,
|
||||||
getDefaultOrder,
|
|
||||||
useOrderValidation,
|
|
||||||
useOrderSubmit,
|
|
||||||
DealTicketAmount,
|
DealTicketAmount,
|
||||||
|
MarketSelector,
|
||||||
} from '@vegaprotocol/deal-ticket';
|
} from '@vegaprotocol/deal-ticket';
|
||||||
|
import type { Order } from '@vegaprotocol/orders';
|
||||||
import {
|
import {
|
||||||
OrderTimeInForce,
|
VegaWalletOrderTimeInForce as OrderTimeInForce,
|
||||||
OrderType,
|
VegaWalletOrderType as OrderType,
|
||||||
VegaTxStatus,
|
VegaTxStatus,
|
||||||
} from '@vegaprotocol/wallet';
|
} from '@vegaprotocol/wallet';
|
||||||
import { t, addDecimal, toDecimal } from '@vegaprotocol/react-helpers';
|
import { t, addDecimal, toDecimal } from '@vegaprotocol/react-helpers';
|
||||||
|
import {
|
||||||
|
getDefaultOrder,
|
||||||
|
useOrderValidation,
|
||||||
|
useOrderSubmit,
|
||||||
|
} from '@vegaprotocol/orders';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import MarketNameRenderer from '../simple-market-list/simple-market-renderer';
|
||||||
|
|
||||||
interface DealTicketMarketProps {
|
interface DealTicketMarketProps {
|
||||||
market: DealTicketQuery_market;
|
market: DealTicketQuery_market;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const setMarket = useCallback(
|
||||||
|
(marketId) => {
|
||||||
|
navigate(`/trading/${marketId}`);
|
||||||
|
},
|
||||||
|
[navigate]
|
||||||
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
control,
|
control,
|
||||||
@ -70,7 +85,13 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
|||||||
{
|
{
|
||||||
label: 'Select Asset',
|
label: 'Select Asset',
|
||||||
description: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.`,
|
description: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.`,
|
||||||
component: <h1 className="font-bold mb-16">{market.name}</h1>,
|
component: (
|
||||||
|
<MarketSelector
|
||||||
|
market={market}
|
||||||
|
setMarket={setMarket}
|
||||||
|
ItemRenderer={MarketNameRenderer}
|
||||||
|
/>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Select Order Type',
|
label: 'Select Order Type',
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type { SimpleMarkets_markets } from './__generated__/SimpleMarkets';
|
import type { MarketNames_markets } from '@vegaprotocol/deal-ticket';
|
||||||
import SimpleMarketExpires from './simple-market-expires';
|
import SimpleMarketExpires from './simple-market-expires';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
data: SimpleMarkets_markets;
|
market: MarketNames_markets;
|
||||||
}
|
}
|
||||||
|
|
||||||
const MarketNameRenderer = ({ data }: Props) => {
|
const MarketNameRenderer = ({ market }: Props) => {
|
||||||
return (
|
return (
|
||||||
<div className="flex h-full items-center grid grid-rows-2 grid-flow-col gap-x-8 gap-y-0 grid-cols-[min-content,1fr,1fr]">
|
<div className="flex h-full items-center grid grid-rows-2 grid-flow-col gap-x-8 gap-y-0 grid-cols-[min-content,1fr,1fr]">
|
||||||
<div className="w-60 row-span-2 bg-pink rounded-full w-44 h-44 bg-gradient-to-br from-white-60 to--white-80 opacity-30" />
|
<div className="w-60 row-span-2 bg-pink rounded-full w-44 h-44 bg-gradient-to-br from-white-60 to--white-80 opacity-30" />
|
||||||
<div className="col-span-2 uppercase justify-start text-black dark:text-white text-market self-end">
|
<div className="col-span-2 uppercase justify-start text-black dark:text-white text-market self-end">
|
||||||
{data.name}{' '}
|
{market.name}{' '}
|
||||||
<SimpleMarketExpires
|
<SimpleMarketExpires
|
||||||
tags={data.tradableInstrument.instrument.metadata.tags}
|
tags={market.tradableInstrument.instrument.metadata.tags}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-2 ui-small text-deemphasise dark:text-midGrey self-start leading-3">
|
<div className="col-span-2 text-ui-small text-deemphasise dark:text-midGrey self-start leading-3">
|
||||||
{data.tradableInstrument.instrument.product.quoteName}
|
{market.tradableInstrument.instrument.product.quoteName}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -21,7 +21,7 @@ const useColumnDefinitions = ({ onClick }: Props) => {
|
|||||||
minWidth: 300,
|
minWidth: 300,
|
||||||
field: 'name',
|
field: 'name',
|
||||||
cellRenderer: ({ data }: { data: SimpleMarketsType }) => (
|
cellRenderer: ({ data }: { data: SimpleMarketsType }) => (
|
||||||
<MarketNameRenderer data={data} />
|
<MarketNameRenderer market={data} />
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -2,6 +2,7 @@ const { join } = require('path');
|
|||||||
const { createGlobPatternsForDependencies } = require('@nrwl/next/tailwind');
|
const { createGlobPatternsForDependencies } = require('@nrwl/next/tailwind');
|
||||||
const theme = require('../../libs/tailwindcss-config/src/theme-lite');
|
const theme = require('../../libs/tailwindcss-config/src/theme-lite');
|
||||||
const vegaCustomClasses = require('../../libs/tailwindcss-config/src/vega-custom-classes');
|
const vegaCustomClasses = require('../../libs/tailwindcss-config/src/vega-custom-classes');
|
||||||
|
const vegaCustomClassesLite = require('../../libs/tailwindcss-config/src/vega-custom-classes-lite');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
content: [
|
content: [
|
||||||
@ -11,5 +12,5 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
darkMode: 'class',
|
darkMode: 'class',
|
||||||
theme,
|
theme,
|
||||||
plugins: [vegaCustomClasses],
|
plugins: [vegaCustomClasses, vegaCustomClassesLite],
|
||||||
};
|
};
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -38,7 +38,7 @@
|
|||||||
"tranche_end": "2022-11-26T13:48:10.000Z",
|
"tranche_end": "2022-11-26T13:48:10.000Z",
|
||||||
"total_added": "100",
|
"total_added": "100",
|
||||||
"total_removed": "0",
|
"total_removed": "0",
|
||||||
"locked_amount": "38.375643708777274",
|
"locked_amount": "37.074508498224257",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "100",
|
"amount": "100",
|
||||||
@ -242,7 +242,7 @@
|
|||||||
"tranche_end": "2022-10-12T00:53:20.000Z",
|
"tranche_end": "2022-10-12T00:53:20.000Z",
|
||||||
"total_added": "1100",
|
"total_added": "1100",
|
||||||
"total_removed": "673.04388635",
|
"total_removed": "673.04388635",
|
||||||
"locked_amount": "284.894035388127847",
|
"locked_amount": "270.58154807204466",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "1000",
|
"amount": "1000",
|
||||||
|
@ -69,7 +69,7 @@
|
|||||||
"tranche_end": "2022-10-12T00:53:20.000Z",
|
"tranche_end": "2022-10-12T00:53:20.000Z",
|
||||||
"total_added": "1010.000000000000000001",
|
"total_added": "1010.000000000000000001",
|
||||||
"total_removed": "668.4622323651",
|
"total_removed": "668.4622323651",
|
||||||
"locked_amount": "261.58452340182647770025899457762557077",
|
"locked_amount": "248.4430577752410060002459832255200406",
|
||||||
"deposits": [
|
"deposits": [
|
||||||
{
|
{
|
||||||
"amount": "1000",
|
"amount": "1000",
|
||||||
|
@ -18,6 +18,7 @@ module.exports = defineConfig({
|
|||||||
env: {
|
env: {
|
||||||
ethProviderUrl: 'http://localhost:8545/',
|
ethProviderUrl: 'http://localhost:8545/',
|
||||||
ethWalletPublicKey: '0xEe7D375bcB50C26d52E1A4a472D8822A2A22d94F',
|
ethWalletPublicKey: '0xEe7D375bcB50C26d52E1A4a472D8822A2A22d94F',
|
||||||
|
ethWalletPublicKeyTruncated: '0xEe7D…d94F',
|
||||||
ethStakingBridgeContractAddress:
|
ethStakingBridgeContractAddress:
|
||||||
'0x9135f5afd6F055e731bca2348429482eE614CFfA',
|
'0x9135f5afd6F055e731bca2348429482eE614CFfA',
|
||||||
vegaWalletName: 'capsule_wallet',
|
vegaWalletName: 'capsule_wallet',
|
||||||
|
@ -1,31 +1,28 @@
|
|||||||
/// <reference types="cypress" />
|
const pageSpinner = 'splash-loader';
|
||||||
import navigation from '../../locators/navigation.locators';
|
const menuBar = 'nav';
|
||||||
import staking from '../../locators/staking.locators';
|
const validatorList = '[data-testid="node-list-item-name"]';
|
||||||
import wallet from '../../locators/wallet.locators';
|
const removeStakeRadioButton = '[data-testid="remove-stake-radio"]';
|
||||||
import '../../support/staking.functions';
|
const tokenAmountInputBox = '[data-testid="token-amount-input"]';
|
||||||
import '../../support/vega-wallet.functions';
|
const tokenSubmitButton = '[data-testid="token-input-submit-button"]';
|
||||||
import '../../support/eth-wallet.functions';
|
const stakeNextEpochValue = '[data-testid="stake-next-epoch"]';
|
||||||
import '../../support/wallet-teardown.functions';
|
const vegaWalletContainer = '[data-testid="vega-wallet"]';
|
||||||
|
|
||||||
const vegaWalletPublicKeyShort = Cypress.env('vegaWalletPublicKeyShort');
|
const vegaWalletPublicKeyShort = Cypress.env('vegaWalletPublicKeyShort');
|
||||||
|
|
||||||
context('Staking Tab - with eth and vega wallets connected', function () {
|
context('Staking Flow - with eth and vega wallets connected', function () {
|
||||||
before('visit staking tab and connect vega wallet', function () {
|
before('visit staking tab and connect vega wallet', function () {
|
||||||
cy.vega_wallet_import();
|
cy.vega_wallet_import();
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
cy.get(navigation.section, { timeout: 20000 }).should('be.visible');
|
cy.get(menuBar, { timeout: 20000 }).should('be.visible');
|
||||||
cy.vega_wallet_connect();
|
cy.vega_wallet_connect();
|
||||||
cy.vega_wallet_set_specified_approval_amount('1000');
|
cy.vega_wallet_set_specified_approval_amount('1000');
|
||||||
cy.reload();
|
cy.reload();
|
||||||
cy.get(navigation.section, { timeout: 20000 }).should('be.visible');
|
cy.get(menuBar, { timeout: 20000 }).should('be.visible');
|
||||||
cy.ethereum_wallet_connect();
|
cy.ethereum_wallet_connect();
|
||||||
cy.get(navigation.staking).first().click();
|
cy.navigate_to('staking');
|
||||||
cy.get(navigation.spinner, { timeout: 20000 }).should('not.exist');
|
cy.get(pageSpinner, { timeout: 20000 }).should('not.exist');
|
||||||
cy.get(staking.validatorNames).first().invoke('text').as('validatorName');
|
cy.get(validatorList).first().invoke('text').as('validatorName');
|
||||||
cy.get(staking.validatorNames)
|
cy.get(validatorList).last().invoke('text').as('otherValidatorName');
|
||||||
.last()
|
|
||||||
.invoke('text')
|
|
||||||
.as('otherValidatorName');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Eth wallet - contains VEGA tokens', function () {
|
describe('Eth wallet - contains VEGA tokens', function () {
|
||||||
@ -33,7 +30,7 @@ context('Staking Tab - with eth and vega wallets connected', function () {
|
|||||||
'teardown wallet & drill into a specific validator',
|
'teardown wallet & drill into a specific validator',
|
||||||
function () {
|
function () {
|
||||||
cy.vega_wallet_teardown();
|
cy.vega_wallet_teardown();
|
||||||
cy.get(navigation.staking).first().click();
|
cy.navigate_to('staking');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -47,37 +44,37 @@ context('Staking Tab - with eth and vega wallets connected', function () {
|
|||||||
);
|
);
|
||||||
|
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
cy.get(staking.validatorNames).contains(this.validatorName).click();
|
cy.get(validatorList).contains(this.validatorName).click();
|
||||||
|
|
||||||
cy.staking_validator_page_add_stake('2');
|
cy.staking_validator_page_add_stake('2');
|
||||||
cy.vega_wallet_check_validator_stake_next_epoch_value_is(
|
vega_wallet_check_validator_stake_next_epoch_value_is(
|
||||||
this.validatorName,
|
this.validatorName,
|
||||||
'2.000000000000000000'
|
'2.000000000000000000'
|
||||||
);
|
);
|
||||||
cy.vega_wallet_check_unstaked_value_is('1.000000000000000000');
|
cy.vega_wallet_check_unstaked_value_is('1.000000000000000000');
|
||||||
cy.vega_wallet_check_validator_staked_value_is(
|
vega_wallet_check_validator_staked_value_is(
|
||||||
this.validatorName,
|
this.validatorName,
|
||||||
'2.000000000000000000'
|
'2.000000000000000000'
|
||||||
);
|
);
|
||||||
cy.staking_validator_page_check_stake_next_epoch_value('2.0');
|
staking_validator_page_check_stake_next_epoch_value('2.0');
|
||||||
cy.staking_validator_page_check_stake_this_epoch_value('2.0');
|
staking_validator_page_check_stake_this_epoch_value('2.0');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to stake against mulitple validators', function () {
|
it('Able to stake against mulitple validators', function () {
|
||||||
cy.staking_page_associate_tokens('5');
|
cy.staking_page_associate_tokens('5');
|
||||||
cy.vega_wallet_check_unstaked_value_is('5.000000000000000000');
|
cy.vega_wallet_check_unstaked_value_is('5.000000000000000000');
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
cy.get(staking.validatorNames).contains(this.validatorName).click();
|
cy.get(validatorList).contains(this.validatorName).click();
|
||||||
|
|
||||||
cy.staking_validator_page_add_stake('2');
|
cy.staking_validator_page_add_stake('2');
|
||||||
cy.vega_wallet_check_validator_staked_value_is(
|
vega_wallet_check_validator_staked_value_is(
|
||||||
this.validatorName,
|
this.validatorName,
|
||||||
'2.000000000000000000'
|
'2.000000000000000000'
|
||||||
);
|
);
|
||||||
cy.get(navigation.staking).first().click();
|
cy.navigate_to('staking');
|
||||||
cy.get(staking.validatorNames).contains(this.otherValidatorName).click();
|
cy.get(validatorList).contains(this.otherValidatorName).click();
|
||||||
cy.staking_validator_page_add_stake('1');
|
cy.staking_validator_page_add_stake('1');
|
||||||
cy.vega_wallet_check_validator_staked_value_is(
|
vega_wallet_check_validator_staked_value_is(
|
||||||
this.otherValidatorName,
|
this.otherValidatorName,
|
||||||
'1.000000000000000000'
|
'1.000000000000000000'
|
||||||
);
|
);
|
||||||
@ -89,37 +86,37 @@ context('Staking Tab - with eth and vega wallets connected', function () {
|
|||||||
cy.vega_wallet_check_unstaked_value_is('4.000000000000000000');
|
cy.vega_wallet_check_unstaked_value_is('4.000000000000000000');
|
||||||
|
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
cy.get(staking.validatorNames).contains(this.validatorName).click();
|
cy.get(validatorList).contains(this.validatorName).click();
|
||||||
|
|
||||||
cy.staking_validator_page_add_stake('3');
|
cy.staking_validator_page_add_stake('3');
|
||||||
cy.staking_validator_page_check_stake_next_epoch_value('3.0');
|
staking_validator_page_check_stake_next_epoch_value('3.0');
|
||||||
cy.vega_wallet_check_validator_stake_next_epoch_value_is(
|
vega_wallet_check_validator_stake_next_epoch_value_is(
|
||||||
this.validatorName,
|
this.validatorName,
|
||||||
'3.000000000000000000'
|
'3.000000000000000000'
|
||||||
);
|
);
|
||||||
cy.vega_wallet_check_unstaked_value_is('1.000000000000000000');
|
cy.vega_wallet_check_unstaked_value_is('1.000000000000000000');
|
||||||
|
|
||||||
cy.get(navigation.staking).first().click();
|
cy.navigate_to('staking');
|
||||||
cy.get(staking.validatorNames).contains(this.validatorName).click();
|
cy.get(validatorList).contains(this.validatorName).click();
|
||||||
|
|
||||||
cy.staking_validator_page_removeStake('1');
|
cy.staking_validator_page_removeStake('1');
|
||||||
cy.staking_validator_page_check_stake_next_epoch_value('2.0');
|
staking_validator_page_check_stake_next_epoch_value('2.0');
|
||||||
cy.staking_validator_page_check_stake_this_epoch_value('3.0');
|
staking_validator_page_check_stake_this_epoch_value('3.0');
|
||||||
cy.vega_wallet_check_validator_stake_next_epoch_value_is(
|
vega_wallet_check_validator_stake_next_epoch_value_is(
|
||||||
this.validatorName,
|
this.validatorName,
|
||||||
'2.000000000000000000'
|
'2.000000000000000000'
|
||||||
);
|
);
|
||||||
cy.vega_wallet_check_validator_stake_this_epoch_value_is(
|
vega_wallet_check_validator_stake_this_epoch_value_is(
|
||||||
this.validatorName,
|
this.validatorName,
|
||||||
'3.000000000000000000'
|
'3.000000000000000000'
|
||||||
);
|
);
|
||||||
cy.vega_wallet_check_unstaked_value_is('2.000000000000000000');
|
cy.vega_wallet_check_unstaked_value_is('2.000000000000000000');
|
||||||
cy.vega_wallet_check_validator_staked_value_is(
|
vega_wallet_check_validator_staked_value_is(
|
||||||
this.validatorName,
|
this.validatorName,
|
||||||
'2.000000000000000000'
|
'2.000000000000000000'
|
||||||
);
|
);
|
||||||
cy.staking_validator_page_check_stake_next_epoch_value('2.0');
|
staking_validator_page_check_stake_next_epoch_value('2.0');
|
||||||
cy.staking_validator_page_check_stake_this_epoch_value('2.0');
|
staking_validator_page_check_stake_this_epoch_value('2.0');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to remove a full stake against a validator', function () {
|
it('Able to remove a full stake against a validator', function () {
|
||||||
@ -127,33 +124,33 @@ context('Staking Tab - with eth and vega wallets connected', function () {
|
|||||||
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
|
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
|
||||||
|
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
cy.get(staking.validatorNames).contains(this.validatorName).click();
|
cy.get(validatorList).contains(this.validatorName).click();
|
||||||
|
|
||||||
cy.staking_validator_page_add_stake('1');
|
cy.staking_validator_page_add_stake('1');
|
||||||
cy.vega_wallet_check_validator_stake_next_epoch_value_is(
|
vega_wallet_check_validator_stake_next_epoch_value_is(
|
||||||
this.validatorName,
|
this.validatorName,
|
||||||
'1.000000000000000000'
|
'1.000000000000000000'
|
||||||
);
|
);
|
||||||
cy.vega_wallet_check_unstaked_value_is('2.000000000000000000');
|
cy.vega_wallet_check_unstaked_value_is('2.000000000000000000');
|
||||||
|
|
||||||
cy.get(navigation.staking).first().click();
|
cy.navigate_to('staking');
|
||||||
cy.get(staking.validatorNames).contains(this.validatorName).click();
|
cy.get(validatorList).contains(this.validatorName).click();
|
||||||
|
|
||||||
cy.staking_validator_page_removeStake('1');
|
cy.staking_validator_page_removeStake('1');
|
||||||
cy.staking_validator_page_check_stake_next_epoch_value('0.0');
|
staking_validator_page_check_stake_next_epoch_value('0.0');
|
||||||
|
|
||||||
cy.vega_wallet_check_validator_stake_this_epoch_value_is(
|
vega_wallet_check_validator_stake_this_epoch_value_is(
|
||||||
this.validatorName,
|
this.validatorName,
|
||||||
'1.000000000000000000'
|
'1.000000000000000000'
|
||||||
);
|
);
|
||||||
cy.vega_wallet_check_validator_stake_next_epoch_value_is(
|
vega_wallet_check_validator_stake_next_epoch_value_is(
|
||||||
this.validatorName,
|
this.validatorName,
|
||||||
'0.000000000000000000'
|
'0.000000000000000000'
|
||||||
);
|
);
|
||||||
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
|
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
|
||||||
cy.staking_validator_page_check_stake_next_epoch_value('0.0');
|
staking_validator_page_check_stake_next_epoch_value('0.0');
|
||||||
cy.staking_validator_page_check_stake_this_epoch_value('0.0');
|
staking_validator_page_check_stake_this_epoch_value('0.0');
|
||||||
cy.vega_wallet_check_validator_no_longer_showing(this.validatorName);
|
vega_wallet_check_validator_no_longer_showing(this.validatorName);
|
||||||
});
|
});
|
||||||
|
|
||||||
it.skip('Unable to remove a stake with a negative value for a validator', function () {
|
it.skip('Unable to remove a stake with a negative value for a validator', function () {
|
||||||
@ -161,22 +158,22 @@ context('Staking Tab - with eth and vega wallets connected', function () {
|
|||||||
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
|
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
|
||||||
|
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
cy.get(staking.validatorNames).contains(this.validatorName).click();
|
cy.get(validatorList).contains(this.validatorName).click();
|
||||||
|
|
||||||
cy.staking_validator_page_add_stake('2');
|
cy.staking_validator_page_add_stake('2');
|
||||||
cy.staking_validator_page_check_stake_next_epoch_value('2.0');
|
staking_validator_page_check_stake_next_epoch_value('2.0');
|
||||||
cy.vega_wallet_check_validator_stake_next_epoch_value_is(
|
vega_wallet_check_validator_stake_next_epoch_value_is(
|
||||||
this.validatorName,
|
this.validatorName,
|
||||||
'2.000000000000000000'
|
'2.000000000000000000'
|
||||||
);
|
);
|
||||||
cy.vega_wallet_check_unstaked_value_is('1.000000000000000000');
|
cy.vega_wallet_check_unstaked_value_is('1.000000000000000000');
|
||||||
|
|
||||||
cy.get(navigation.staking).first().click();
|
cy.navigate_to('staking');
|
||||||
cy.get(staking.validatorNames).contains(this.validatorName).click();
|
cy.get(validatorList).contains(this.validatorName).click();
|
||||||
cy.get(staking.removeStakeRadioButton).click({ force: true });
|
cy.get(removeStakeRadioButton).click({ force: true });
|
||||||
cy.get(staking.tokenAmountInput).type('-0.1');
|
cy.get(tokenAmountInputBox).type('-0.1');
|
||||||
cy.contains('Waiting for next epoch to start', { timeout: 10000 });
|
cy.contains('Waiting for next epoch to start', { timeout: 10000 });
|
||||||
cy.get(staking.tokenInputSubmit)
|
cy.get(tokenSubmitButton)
|
||||||
.should('be.disabled', { timeout: 8000 })
|
.should('be.disabled', { timeout: 8000 })
|
||||||
.and('contain', `Remove -0.1 $VEGA tokens at the end of epoch`)
|
.and('contain', `Remove -0.1 $VEGA tokens at the end of epoch`)
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
@ -187,22 +184,22 @@ context('Staking Tab - with eth and vega wallets connected', function () {
|
|||||||
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
|
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
|
||||||
|
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
cy.get(staking.validatorNames).contains(this.validatorName).click();
|
cy.get(validatorList).contains(this.validatorName).click();
|
||||||
|
|
||||||
cy.staking_validator_page_add_stake('2');
|
cy.staking_validator_page_add_stake('2');
|
||||||
cy.staking_validator_page_check_stake_next_epoch_value('2.0');
|
staking_validator_page_check_stake_next_epoch_value('2.0');
|
||||||
cy.vega_wallet_check_validator_stake_next_epoch_value_is(
|
vega_wallet_check_validator_stake_next_epoch_value_is(
|
||||||
this.validatorName,
|
this.validatorName,
|
||||||
'2.000000000000000000'
|
'2.000000000000000000'
|
||||||
);
|
);
|
||||||
cy.vega_wallet_check_unstaked_value_is('1.000000000000000000');
|
cy.vega_wallet_check_unstaked_value_is('1.000000000000000000');
|
||||||
|
|
||||||
cy.get(navigation.staking).first().click();
|
cy.navigate_to('staking');
|
||||||
cy.get(staking.validatorNames).contains(this.validatorName).click();
|
cy.get(validatorList).contains(this.validatorName).click();
|
||||||
cy.get(staking.removeStakeRadioButton).click({ force: true });
|
cy.get(removeStakeRadioButton).click({ force: true });
|
||||||
cy.get(staking.tokenAmountInput).type(4);
|
cy.get(tokenAmountInputBox).type(4);
|
||||||
cy.contains('Waiting for next epoch to start', { timeout: 10000 });
|
cy.contains('Waiting for next epoch to start', { timeout: 10000 });
|
||||||
cy.get(staking.tokenInputSubmit)
|
cy.get(tokenSubmitButton)
|
||||||
.should('be.disabled', { timeout: 8000 })
|
.should('be.disabled', { timeout: 8000 })
|
||||||
.and('contain', `Remove 4 $VEGA tokens at the end of epoch`)
|
.and('contain', `Remove 4 $VEGA tokens at the end of epoch`)
|
||||||
.and('be.visible');
|
.and('be.visible');
|
||||||
@ -213,22 +210,22 @@ context('Staking Tab - with eth and vega wallets connected', function () {
|
|||||||
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
|
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
|
||||||
|
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
cy.get(staking.validatorNames).contains(this.validatorName).click();
|
cy.get(validatorList).contains(this.validatorName).click();
|
||||||
|
|
||||||
cy.staking_validator_page_add_stake('2');
|
cy.staking_validator_page_add_stake('2');
|
||||||
cy.vega_wallet_check_unstaked_value_is('1.000000000000000000');
|
cy.vega_wallet_check_unstaked_value_is('1.000000000000000000');
|
||||||
cy.vega_wallet_check_validator_staked_value_is(
|
vega_wallet_check_validator_staked_value_is(
|
||||||
this.validatorName,
|
this.validatorName,
|
||||||
'2.000000000000000000'
|
'2.000000000000000000'
|
||||||
);
|
);
|
||||||
cy.get(navigation.staking).first().click();
|
cy.navigate_to('staking');
|
||||||
cy.staking_page_disassociate_all_tokens();
|
cy.staking_page_disassociate_all_tokens();
|
||||||
cy.ethereum_wallet_check_associated_vega_key_is_no_longer_showing(
|
cy.ethereum_wallet_check_associated_vega_key_is_no_longer_showing(
|
||||||
vegaWalletPublicKeyShort
|
vegaWalletPublicKeyShort
|
||||||
);
|
);
|
||||||
cy.ethereum_wallet_check_associated_value_is('0.0');
|
cy.ethereum_wallet_check_associated_value_is('0.0');
|
||||||
cy.vega_wallet_check_associated_value_is('0.000000000000000000');
|
cy.vega_wallet_check_associated_value_is('0.000000000000000000');
|
||||||
cy.vega_wallet_check_validator_no_longer_showing(this.validatorName);
|
vega_wallet_check_validator_no_longer_showing(this.validatorName);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Disassociating some tokens - prioritizes unstaked tokens', function () {
|
it('Disassociating some tokens - prioritizes unstaked tokens', function () {
|
||||||
@ -236,19 +233,19 @@ context('Staking Tab - with eth and vega wallets connected', function () {
|
|||||||
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
|
cy.vega_wallet_check_unstaked_value_is('3.000000000000000000');
|
||||||
|
|
||||||
cy.get('button').contains('Select a validator to nominate').click();
|
cy.get('button').contains('Select a validator to nominate').click();
|
||||||
cy.get(staking.validatorNames).contains(this.validatorName).click();
|
cy.get(validatorList).contains(this.validatorName).click();
|
||||||
|
|
||||||
cy.staking_validator_page_add_stake('2');
|
cy.staking_validator_page_add_stake('2');
|
||||||
cy.vega_wallet_check_unstaked_value_is('1.000000000000000000');
|
cy.vega_wallet_check_unstaked_value_is('1.000000000000000000');
|
||||||
cy.vega_wallet_check_validator_staked_value_is(
|
vega_wallet_check_validator_staked_value_is(
|
||||||
this.validatorName,
|
this.validatorName,
|
||||||
'2.000000000000000000'
|
'2.000000000000000000'
|
||||||
);
|
);
|
||||||
cy.get(navigation.staking).first().click();
|
cy.navigate_to('staking');
|
||||||
cy.staking_page_disassociate_tokens('1');
|
cy.staking_page_disassociate_tokens('1');
|
||||||
cy.ethereum_wallet_check_associated_value_is('2.0');
|
cy.ethereum_wallet_check_associated_value_is('2.0');
|
||||||
cy.vega_wallet_check_associated_value_is('2.000000000000000000');
|
cy.vega_wallet_check_associated_value_is('2.000000000000000000');
|
||||||
cy.vega_wallet_check_validator_staked_value_is(
|
vega_wallet_check_validator_staked_value_is(
|
||||||
this.validatorName,
|
this.validatorName,
|
||||||
'2.000000000000000000'
|
'2.000000000000000000'
|
||||||
);
|
);
|
||||||
@ -261,78 +258,78 @@ context('Staking Tab - with eth and vega wallets connected', function () {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
cy.staking_validator_page_check_stake_next_epoch_value = (expectedVal) => {
|
function staking_validator_page_check_stake_next_epoch_value(expectedVal) {
|
||||||
cy.highlight(
|
cy.highlight(
|
||||||
`Checking Staking Page - Validator Stake Next Epoch Value is ${expectedVal}`
|
`Checking Staking Page - Validator Stake Next Epoch Value is ${expectedVal}`
|
||||||
);
|
);
|
||||||
cy.get(staking.stakeNextEpochValue, { timeout: 10000 })
|
cy.get(stakeNextEpochValue, { timeout: 10000 })
|
||||||
.contains(expectedVal, { timeout: 10000 })
|
.contains(expectedVal, { timeout: 10000 })
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
};
|
}
|
||||||
|
|
||||||
cy.staking_validator_page_check_stake_this_epoch_value = (expectedVal) => {
|
function staking_validator_page_check_stake_this_epoch_value(expectedVal) {
|
||||||
cy.highlight(
|
cy.highlight(
|
||||||
`Checking Staking Page - Validator Stake This Epoch Value is ${expectedVal}`
|
`Checking Staking Page - Validator Stake This Epoch Value is ${expectedVal}`
|
||||||
);
|
);
|
||||||
cy.get(staking.stakeThisEpochValue, { timeout: 10000 })
|
cy.get(stakeNextEpochValue, { timeout: 10000 })
|
||||||
.contains(expectedVal, { timeout: 10000 })
|
.contains(expectedVal, { timeout: 10000 })
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
};
|
}
|
||||||
|
|
||||||
cy.vega_wallet_check_validator_stake_next_epoch_value_is = (
|
function vega_wallet_check_validator_stake_next_epoch_value_is(
|
||||||
validatorName,
|
validatorName,
|
||||||
expectedVal
|
expectedVal
|
||||||
) => {
|
) {
|
||||||
cy.highlight(
|
cy.highlight(
|
||||||
`Checking vega wallet - Stake Next Epoch Value for ${validatorName} is ${expectedVal}`
|
`Checking vega wallet - Stake Next Epoch Value for ${validatorName} is ${expectedVal}`
|
||||||
);
|
);
|
||||||
cy.get(wallet.vegawallet).within(() => {
|
cy.get(vegaWalletContainer).within(() => {
|
||||||
cy.contains(`${validatorName} (Next epoch)`, { timeout: 40000 })
|
cy.contains(`${validatorName} (Next epoch)`, { timeout: 40000 })
|
||||||
.siblings()
|
.siblings()
|
||||||
.contains(expectedVal, { timeout: 40000 })
|
.contains(expectedVal, { timeout: 40000 })
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
cy.vega_wallet_check_validator_stake_this_epoch_value_is = (
|
function vega_wallet_check_validator_stake_this_epoch_value_is(
|
||||||
validatorName,
|
validatorName,
|
||||||
expectedVal
|
expectedVal
|
||||||
) => {
|
) {
|
||||||
cy.highlight(
|
cy.highlight(
|
||||||
`Checking vega wallet - Stake This Epoch Value for ${validatorName} is ${expectedVal}`
|
`Checking vega wallet - Stake This Epoch Value for ${validatorName} is ${expectedVal}`
|
||||||
);
|
);
|
||||||
cy.get(wallet.vegawallet).within(() => {
|
cy.get(vegaWalletContainer).within(() => {
|
||||||
cy.contains(`${validatorName} (This Epoch)`, { timeout: 40000 })
|
cy.contains(`${validatorName} (This Epoch)`, { timeout: 40000 })
|
||||||
.siblings()
|
.siblings()
|
||||||
.contains(expectedVal, { timeout: 40000 })
|
.contains(expectedVal, { timeout: 40000 })
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
cy.vega_wallet_check_validator_no_longer_showing = (validatorName) => {
|
function vega_wallet_check_validator_no_longer_showing(validatorName) {
|
||||||
cy.highlight(
|
cy.highlight(
|
||||||
`Checking Validator and therefore stake removed for ${validatorName}`
|
`Checking Validator and therefore stake removed for ${validatorName}`
|
||||||
);
|
);
|
||||||
cy.get(wallet.vegawallet).within(() => {
|
cy.get(vegaWalletContainer).within(() => {
|
||||||
cy.contains(`${validatorName}`, { timeout: 40000 }).should('not.exist', {
|
cy.contains(`${validatorName}`, { timeout: 40000 }).should('not.exist', {
|
||||||
timeout: 40000,
|
timeout: 40000,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
cy.vega_wallet_check_validator_staked_value_is = (
|
function vega_wallet_check_validator_staked_value_is(
|
||||||
validatorName,
|
validatorName,
|
||||||
expectedVal
|
expectedVal
|
||||||
) => {
|
) {
|
||||||
cy.highlight(
|
cy.highlight(
|
||||||
`Checking Validator Stake Value for ${validatorName} is ${expectedVal}`
|
`Checking Validator Stake Value for ${validatorName} is ${expectedVal}`
|
||||||
);
|
);
|
||||||
cy.get(wallet.vegawallet).within(() => {
|
cy.get(vegaWalletContainer).within(() => {
|
||||||
cy.contains(`${validatorName}`, { timeout: 40000 })
|
cy.contains(`${validatorName}`, { timeout: 40000 })
|
||||||
.siblings()
|
.siblings()
|
||||||
.contains(expectedVal, { timeout: 40000 })
|
.contains(expectedVal, { timeout: 40000 })
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
});
|
|
||||||
|
@ -1,27 +1,24 @@
|
|||||||
/// <reference types="cypress" />
|
const pageSpinner = 'splash-loader';
|
||||||
import navigation from '../../locators/navigation.locators';
|
const menuBar = 'nav';
|
||||||
import staking from '../../locators/staking.locators';
|
const validatorList = '[data-testid="node-list-item-name"]';
|
||||||
import wallet from '../../locators/wallet.locators';
|
|
||||||
import '../../support/staking.functions';
|
|
||||||
import '../../support/vega-wallet.functions';
|
|
||||||
import '../../support/eth-wallet.functions';
|
|
||||||
import '../../support/wallet-teardown.functions';
|
|
||||||
|
|
||||||
const vegaWalletPublicKeyShort = Cypress.env('vegaWalletPublicKeyShort');
|
const vegaWalletPublicKeyShort = Cypress.env('vegaWalletPublicKeyShort');
|
||||||
|
|
||||||
context('Staking Tab - with eth and vega wallets connected', function () {
|
context(
|
||||||
|
'Token association flow - with eth and vega wallets connected',
|
||||||
|
function () {
|
||||||
before('visit staking tab and connect vega wallet', function () {
|
before('visit staking tab and connect vega wallet', function () {
|
||||||
cy.vega_wallet_import();
|
cy.vega_wallet_import();
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
cy.get(navigation.section, { timeout: 20000 }).should('be.visible');
|
cy.get(menuBar, { timeout: 20000 }).should('be.visible');
|
||||||
cy.vega_wallet_connect();
|
cy.vega_wallet_connect();
|
||||||
cy.vega_wallet_set_specified_approval_amount('1000');
|
cy.vega_wallet_set_specified_approval_amount('1000');
|
||||||
cy.reload();
|
cy.reload();
|
||||||
cy.get(navigation.section, { timeout: 20000 }).should('be.visible');
|
cy.get(menuBar, { timeout: 20000 }).should('be.visible');
|
||||||
cy.ethereum_wallet_connect();
|
cy.ethereum_wallet_connect();
|
||||||
cy.get(navigation.staking).first().click();
|
cy.navigate_to('staking');
|
||||||
cy.get(navigation.spinner, { timeout: 20000 }).should('not.exist');
|
cy.get(pageSpinner, { timeout: 20000 }).should('not.exist');
|
||||||
cy.get(staking.validatorNames).first().invoke('text').as('validatorName');
|
cy.get(validatorList).first().invoke('text').as('validatorName');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Eth wallet - contains VEGA tokens', function () {
|
describe('Eth wallet - contains VEGA tokens', function () {
|
||||||
@ -29,12 +26,12 @@ context('Staking Tab - with eth and vega wallets connected', function () {
|
|||||||
'teardown wallet & drill into a specific validator',
|
'teardown wallet & drill into a specific validator',
|
||||||
function () {
|
function () {
|
||||||
cy.vega_wallet_teardown();
|
cy.vega_wallet_teardown();
|
||||||
cy.get(navigation.staking).first().click();
|
cy.navigate_to('staking');
|
||||||
cy.get(navigation.spinner, { timeout: 20000 }).should('not.exist');
|
cy.get(pageSpinner, { timeout: 20000 }).should('not.exist');
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
it('Able to associate tokens - from staking page', function () {
|
it('Able to associate tokens', function () {
|
||||||
cy.staking_page_associate_tokens('2');
|
cy.staking_page_associate_tokens('2');
|
||||||
cy.ethereum_wallet_check_associated_vega_key_value_is(
|
cy.ethereum_wallet_check_associated_vega_key_value_is(
|
||||||
vegaWalletPublicKeyShort,
|
vegaWalletPublicKeyShort,
|
||||||
@ -45,7 +42,7 @@ context('Staking Tab - with eth and vega wallets connected', function () {
|
|||||||
cy.vega_wallet_check_unstaked_value_is('2.000000000000000000');
|
cy.vega_wallet_check_unstaked_value_is('2.000000000000000000');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to disassociate tokens - from staking page', function () {
|
it('Able to disassociate tokens', function () {
|
||||||
cy.staking_page_associate_tokens('2');
|
cy.staking_page_associate_tokens('2');
|
||||||
cy.ethereum_wallet_check_associated_vega_key_value_is(
|
cy.ethereum_wallet_check_associated_vega_key_value_is(
|
||||||
vegaWalletPublicKeyShort,
|
vegaWalletPublicKeyShort,
|
||||||
@ -62,24 +59,6 @@ context('Staking Tab - with eth and vega wallets connected', function () {
|
|||||||
cy.vega_wallet_check_associated_value_is('1.000000000000000000');
|
cy.vega_wallet_check_associated_value_is('1.000000000000000000');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to access associate token form - from eth wallet', function () {
|
|
||||||
cy.get(wallet.ethWallet).within(() =>
|
|
||||||
cy.get(wallet.ethWalletAssociate).click()
|
|
||||||
);
|
|
||||||
cy.get(staking.stakeAssociateWalletRadio, { timeout: 30000 }).should(
|
|
||||||
'be.enabled'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Able to access disassociate token form - from eth wallet', function () {
|
|
||||||
cy.get(wallet.ethWallet).within(() =>
|
|
||||||
cy.get(wallet.ethWalletDisassociate).click()
|
|
||||||
);
|
|
||||||
cy.get(staking.stakeAssociateWalletRadio, { timeout: 30000 }).should(
|
|
||||||
'be.enabled'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Able to associate more tokens than the approved amount of 1000 - requires re-approval', function () {
|
it('Able to associate more tokens than the approved amount of 1000 - requires re-approval', function () {
|
||||||
cy.staking_page_associate_tokens('1001', true);
|
cy.staking_page_associate_tokens('1001', true);
|
||||||
cy.ethereum_wallet_check_associated_vega_key_value_is(
|
cy.ethereum_wallet_check_associated_vega_key_value_is(
|
||||||
@ -115,4 +94,5 @@ context('Staking Tab - with eth and vega wallets connected', function () {
|
|||||||
cy.vega_wallet_check_associated_value_is('0.000000000000000000');
|
cy.vega_wallet_check_associated_value_is('0.000000000000000000');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
@ -1,30 +1,21 @@
|
|||||||
import navigation from '../locators/navigation.locators';
|
const noProposals = '[data-testid="no-proposals"]';
|
||||||
import governance from '../locators/governance.locators';
|
|
||||||
|
|
||||||
context('Governance Page - verify elements on page', function () {
|
context('Governance Page - verify elements on page', function () {
|
||||||
before('navigate to governance page', function () {
|
before('navigate to governance page', function () {
|
||||||
cy.visit('/')
|
cy.visit('/').navigate_to('governance');
|
||||||
.get(navigation.section)
|
|
||||||
.within(() => {
|
|
||||||
cy.get(navigation.governance).click();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with no network change proposals', function () {
|
describe('with no network change proposals', function () {
|
||||||
it('should have governance tab highlighted', function () {
|
it('should have governance tab highlighted', function () {
|
||||||
cy.get(navigation.section).within(() => {
|
cy.verify_tab_highlighted('governance');
|
||||||
cy.get(navigation.governance).should('have.attr', 'aria-current');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have GOVERNANCE header visible', function () {
|
it('should have GOVERNANCE header visible', function () {
|
||||||
cy.get(governance.pageHeader)
|
cy.verify_page_header('Governance');
|
||||||
.should('be.visible')
|
|
||||||
.and('have.text', 'Governance');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have information box visible', function () {
|
it('should have information box visible', function () {
|
||||||
cy.get(governance.noProposals)
|
cy.get(noProposals)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.and('have.text', 'There are no active network change proposals');
|
.and('have.text', 'There are no active network change proposals');
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,24 @@
|
|||||||
import navigation from '../locators/navigation.locators';
|
const navSection = 'nav';
|
||||||
import home from '../locators/home.locators';
|
const navHome = '[href="/"]';
|
||||||
|
const navVesting = '[href="/vesting"]';
|
||||||
|
const navStaking = '[href="/staking"]';
|
||||||
|
const navRewards = '[href="/rewards"]';
|
||||||
|
const navWithdraw = '[href="/withdraw"]';
|
||||||
|
const navGovernance = '[href="/governance"]';
|
||||||
|
|
||||||
|
const tokenDetailsTable = '.token-details';
|
||||||
|
const address = '[data-testid="token-address"]';
|
||||||
|
const contract = '[data-testid="token-contract"]';
|
||||||
|
const totalSupply = '[data-testid="total-supply"]';
|
||||||
|
const circulatingSupply = '[data-testid="circulating-supply"]';
|
||||||
|
const staked = '[data-testid="staked"]';
|
||||||
|
const tranchesLink = '[data-testid="tranches-link"]';
|
||||||
|
const redeemBtn = '[data-testid="check-vesting-page-btn"]';
|
||||||
|
const getVegaWalletLink = '[data-testid="get-vega-wallet-link"]';
|
||||||
|
const associateVegaLink =
|
||||||
|
'[data-testid="associate-vega-tokens-link-on-homepage"]';
|
||||||
|
const stakingBtn = '[data-testid="staking-button-on-homepage"]';
|
||||||
|
const governanceBtn = '[data-testid="governance-button-on-homepage"]';
|
||||||
|
|
||||||
const vegaTokenAddress = Cypress.env('vegaTokenAddress');
|
const vegaTokenAddress = Cypress.env('vegaTokenAddress');
|
||||||
const vegaTokenContractAddress = Cypress.env('vegaTokenContractAddress');
|
const vegaTokenContractAddress = Cypress.env('vegaTokenContractAddress');
|
||||||
@ -11,111 +30,111 @@ context('Home Page - verify elements on page', function () {
|
|||||||
|
|
||||||
describe('with wallets disconnected', function () {
|
describe('with wallets disconnected', function () {
|
||||||
before('wait for page to load', function () {
|
before('wait for page to load', function () {
|
||||||
cy.get(navigation.section, { timeout: 10000 }).should('be.visible');
|
cy.get(navSection, { timeout: 10000 }).should('be.visible');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Navigation tabs', function () {
|
describe('Navigation tabs', function () {
|
||||||
it('should have HOME tab', function () {
|
it('should have HOME tab', function () {
|
||||||
cy.get(navigation.section).within(() => {
|
cy.get(navSection).within(() => {
|
||||||
cy.get(navigation.home).should('be.visible');
|
cy.get(navHome).should('be.visible');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should have VESTING tab', function () {
|
it('should have VESTING tab', function () {
|
||||||
cy.get(navigation.section).within(() => {
|
cy.get(navSection).within(() => {
|
||||||
cy.get(navigation.vesting).should('be.visible');
|
cy.get(navVesting).should('be.visible');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should have STAKING tab', function () {
|
it('should have STAKING tab', function () {
|
||||||
cy.get(navigation.section).within(() => {
|
cy.get(navSection).within(() => {
|
||||||
cy.get(navigation.staking).should('be.visible');
|
cy.get(navStaking).should('be.visible');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should have REWARDS tab', function () {
|
it('should have REWARDS tab', function () {
|
||||||
cy.get(navigation.section).within(() => {
|
cy.get(navSection).within(() => {
|
||||||
cy.get(navigation.rewards).should('be.visible');
|
cy.get(navRewards).should('be.visible');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should have WITHDRAW tab', function () {
|
it('should have WITHDRAW tab', function () {
|
||||||
cy.get(navigation.section).within(() => {
|
cy.get(navSection).within(() => {
|
||||||
cy.get(navigation.withdraw).should('be.visible');
|
cy.get(navWithdraw).should('be.visible');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should have GOVERNANCE tab', function () {
|
it('should have GOVERNANCE tab', function () {
|
||||||
cy.get(navigation.section).within(() => {
|
cy.get(navSection).within(() => {
|
||||||
cy.get(navigation.governance).should('be.visible');
|
cy.get(navGovernance).should('be.visible');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('THE $VEGA TOKEN table', function () {
|
describe('THE $VEGA TOKEN table', function () {
|
||||||
it('should have TOKEN ADDRESS', function () {
|
it('should have TOKEN ADDRESS', function () {
|
||||||
cy.get(home.tokenDetailsTable).within(() => {
|
cy.get(tokenDetailsTable).within(() => {
|
||||||
cy.get(home.address)
|
cy.get(address)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.invoke('text')
|
.invoke('text')
|
||||||
.should('be.equal', vegaTokenAddress);
|
.should('be.equal', vegaTokenAddress);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should have VESTING CONTRACT', function () {
|
it('should have VESTING CONTRACT', function () {
|
||||||
cy.get(home.tokenDetailsTable).within(() => {
|
cy.get(tokenDetailsTable).within(() => {
|
||||||
cy.get(home.contract)
|
cy.get(contract)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.invoke('text')
|
.invoke('text')
|
||||||
.should('be.equal', vegaTokenContractAddress);
|
.should('be.equal', vegaTokenContractAddress);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should have TOTAL SUPPLY', function () {
|
it('should have TOTAL SUPPLY', function () {
|
||||||
cy.get(home.tokenDetailsTable).within(() => {
|
cy.get(tokenDetailsTable).within(() => {
|
||||||
cy.get(home.totalSupply).should('be.visible');
|
cy.get(totalSupply).should('be.visible');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should have CIRCULATING SUPPLY', function () {
|
it('should have CIRCULATING SUPPLY', function () {
|
||||||
cy.get(home.tokenDetailsTable).within(() => {
|
cy.get(tokenDetailsTable).within(() => {
|
||||||
cy.get(home.circulatingSupply).should('be.visible');
|
cy.get(circulatingSupply).should('be.visible');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it('should have STAKED $VEGA', function () {
|
it('should have STAKED $VEGA', function () {
|
||||||
cy.get(home.tokenDetailsTable).within(() => {
|
cy.get(tokenDetailsTable).within(() => {
|
||||||
cy.get(home.staked).should('be.visible');
|
cy.get(staked).should('be.visible');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('links and buttons', function () {
|
describe('links and buttons', function () {
|
||||||
it('should have TRANCHES link', function () {
|
it('should have TRANCHES link', function () {
|
||||||
cy.get(home.tranchesLink)
|
cy.get(tranchesLink)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.and('have.attr', 'href')
|
.and('have.attr', 'href')
|
||||||
.and('equal', '/tranches');
|
.and('equal', '/tranches');
|
||||||
});
|
});
|
||||||
it('should have REDEEM button', function () {
|
it('should have REDEEM button', function () {
|
||||||
cy.get(home.redeemBtn)
|
cy.get(redeemBtn)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.parent()
|
.parent()
|
||||||
.should('have.attr', 'href')
|
.should('have.attr', 'href')
|
||||||
.and('equal', '/vesting');
|
.and('equal', '/vesting');
|
||||||
});
|
});
|
||||||
it('should have GET VEGA WALLET link', function () {
|
it('should have GET VEGA WALLET link', function () {
|
||||||
cy.get(home.getVegaWalletLink)
|
cy.get(getVegaWalletLink)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.and('have.attr', 'href')
|
.and('have.attr', 'href')
|
||||||
.and('equal', 'https://vega.xyz/wallet');
|
.and('equal', 'https://vega.xyz/wallet');
|
||||||
});
|
});
|
||||||
it('should have ASSOCIATE VEGA TOKENS link', function () {
|
it('should have ASSOCIATE VEGA TOKENS link', function () {
|
||||||
cy.get(home.associateVegaLink)
|
cy.get(associateVegaLink)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.and('have.attr', 'href')
|
.and('have.attr', 'href')
|
||||||
.and('equal', '/staking/associate');
|
.and('equal', '/staking/associate');
|
||||||
});
|
});
|
||||||
it('should have STAKING button', function () {
|
it('should have STAKING button', function () {
|
||||||
cy.get(home.stakingBtn)
|
cy.get(stakingBtn)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.parent()
|
.parent()
|
||||||
.should('have.attr', 'href')
|
.should('have.attr', 'href')
|
||||||
.and('equal', '/staking');
|
.and('equal', '/staking');
|
||||||
});
|
});
|
||||||
it('should have GOVERNANCE button', function () {
|
it('should have GOVERNANCE button', function () {
|
||||||
cy.get(home.governanceBtn)
|
cy.get(governanceBtn)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.parent()
|
.parent()
|
||||||
.should('have.attr', 'href')
|
.should('have.attr', 'href')
|
||||||
|
@ -1,30 +1,22 @@
|
|||||||
import navigation from '../locators/navigation.locators';
|
const connectToVegaBtn = '[data-testid="connect-to-vega-wallet-btn"]';
|
||||||
import rewards from '../locators/rewards.locators';
|
const warning = '[data-testid="callout"]';
|
||||||
|
|
||||||
context('Rewards Page - verify elements on page', function () {
|
context('Rewards Page - verify elements on page', function () {
|
||||||
before('navigate to rewards page', function () {
|
before('navigate to rewards page', function () {
|
||||||
cy.visit('/')
|
cy.visit('/').navigate_to('rewards');
|
||||||
.get(navigation.section)
|
|
||||||
.within(() => {
|
|
||||||
cy.get(navigation.rewards).click();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with wallets disconnected', function () {
|
describe('with wallets disconnected', function () {
|
||||||
it('should have REWARDS tab highlighted', function () {
|
it('should have REWARDS tab highlighted', function () {
|
||||||
cy.get(navigation.section).within(() => {
|
cy.verify_tab_highlighted('rewards');
|
||||||
cy.get(navigation.rewards).should('have.attr', 'aria-current');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have rewards header visible', function () {
|
it('should have rewards header visible', function () {
|
||||||
cy.get(rewards.pageHeader)
|
cy.verify_page_header('Rewards');
|
||||||
.should('be.visible')
|
|
||||||
.and('have.text', 'Rewards');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have epoch warning', function () {
|
it('should have epoch warning', function () {
|
||||||
cy.get(rewards.warning)
|
cy.get(warning)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.and(
|
.and(
|
||||||
'have.text',
|
'have.text',
|
||||||
@ -33,7 +25,7 @@ context('Rewards Page - verify elements on page', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should have connect Vega wallet button', function () {
|
it('should have connect Vega wallet button', function () {
|
||||||
cy.get(rewards.connectToVegaBtn)
|
cy.get(connectToVegaBtn)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.and('have.text', 'Connect Vega wallet');
|
.and('have.text', 'Connect Vega wallet');
|
||||||
});
|
});
|
||||||
|
@ -1,31 +1,30 @@
|
|||||||
import navigation from '../locators/navigation.locators';
|
const guideLink = '[data-testid="staking-guide-link"]';
|
||||||
import staking from '../locators/staking.locators';
|
const step1 = '[data-testid="staking-step-1"]';
|
||||||
|
const step2 = '[data-testid="staking-step-2"]';
|
||||||
|
const step3 = '[data-testid="staking-step-3"]';
|
||||||
|
const sectionHeader = 'h2';
|
||||||
|
const connectToEthBtn = '[data-testid="connect-to-eth-btn"]';
|
||||||
|
const connectToVegaBtn = '[data-testid="connect-to-vega-wallet-btn"]';
|
||||||
|
const link = '[data-testid="link"]';
|
||||||
|
const warning = '[data-testid="callout"]';
|
||||||
|
|
||||||
context('Staking Page - verify elements on page', function () {
|
context('Staking Page - verify elements on page', function () {
|
||||||
before('navigate to staking page', function () {
|
before('navigate to staking page', function () {
|
||||||
cy.visit('/')
|
cy.visit('/').navigate_to('staking');
|
||||||
.get(navigation.section)
|
|
||||||
.within(() => {
|
|
||||||
cy.get(navigation.staking).click();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with wallets disconnected', function () {
|
describe('with wallets disconnected', function () {
|
||||||
describe('description section', function () {
|
describe('description section', function () {
|
||||||
it('should have staking tab highlighted', function () {
|
it('should have staking tab highlighted', function () {
|
||||||
cy.get(navigation.section).within(() => {
|
cy.verify_tab_highlighted('staking');
|
||||||
cy.get(navigation.staking).should('have.attr', 'aria-current');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have STAKING ON VEGA header visible', function () {
|
it('should have STAKING ON VEGA header visible', function () {
|
||||||
cy.get(staking.pageHeader)
|
cy.verify_page_header('Staking on Vega');
|
||||||
.should('be.visible')
|
|
||||||
.and('have.text', 'Staking on Vega');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have Staking Guide link visible', function () {
|
it('should have Staking Guide link visible', function () {
|
||||||
cy.get(staking.guideLink)
|
cy.get(guideLink)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.and('have.text', 'Read more about staking on Vega')
|
.and('have.text', 'Read more about staking on Vega')
|
||||||
.and(
|
.and(
|
||||||
@ -38,16 +37,16 @@ context('Staking Page - verify elements on page', function () {
|
|||||||
|
|
||||||
describe('step 1 section', function () {
|
describe('step 1 section', function () {
|
||||||
it('should have header visible', function () {
|
it('should have header visible', function () {
|
||||||
cy.get(staking.step1).within(() => {
|
cy.get(step1).within(() => {
|
||||||
cy.get(staking.sectionHeader)
|
cy.get(sectionHeader)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.and('have.text', 'Step 1. Connect to a Vega Wallet');
|
.and('have.text', 'Step 1. Connect to a Vega Wallet');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have text visible', function () {
|
it('should have text visible', function () {
|
||||||
cy.get(staking.step1).within(() => {
|
cy.get(step1).within(() => {
|
||||||
cy.get(staking.link)
|
cy.get(link)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.and('have.text', 'Vega Wallet')
|
.and('have.text', 'Vega Wallet')
|
||||||
.and('have.attr', 'href', 'https://vega.xyz/wallet');
|
.and('have.attr', 'href', 'https://vega.xyz/wallet');
|
||||||
@ -55,16 +54,16 @@ context('Staking Page - verify elements on page', function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should have connect to eth button visible', function () {
|
it('should have connect to eth button visible', function () {
|
||||||
cy.get(staking.step1).within(() => {
|
cy.get(step1).within(() => {
|
||||||
cy.get(staking.connectToEthBtn)
|
cy.get(connectToEthBtn)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.and('have.text', 'Connect Ethereum wallet');
|
.and('have.text', 'Connect Ethereum wallet');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have connect to vega button visible', function () {
|
it('should have connect to vega button visible', function () {
|
||||||
cy.get(staking.step1).within(() => {
|
cy.get(step1).within(() => {
|
||||||
cy.get(staking.connectToVegaBtn)
|
cy.get(connectToVegaBtn)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.and('have.text', 'Connect Vega wallet');
|
.and('have.text', 'Connect Vega wallet');
|
||||||
});
|
});
|
||||||
@ -73,16 +72,16 @@ context('Staking Page - verify elements on page', function () {
|
|||||||
|
|
||||||
describe('step 2 section', function () {
|
describe('step 2 section', function () {
|
||||||
it('should have header visible', function () {
|
it('should have header visible', function () {
|
||||||
cy.get(staking.step2).within(() => {
|
cy.get(step2).within(() => {
|
||||||
cy.get(staking.sectionHeader)
|
cy.get(sectionHeader)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.and('have.text', 'Step 2. Associate tokens with a Vega Wallet');
|
.and('have.text', 'Step 2. Associate tokens with a Vega Wallet');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have warning visible', function () {
|
it('should have warning visible', function () {
|
||||||
cy.get(staking.step2).within(() => {
|
cy.get(step2).within(() => {
|
||||||
cy.get(staking.warning)
|
cy.get(warning)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.and(
|
.and(
|
||||||
'have.text',
|
'have.text',
|
||||||
@ -94,8 +93,8 @@ context('Staking Page - verify elements on page', function () {
|
|||||||
|
|
||||||
describe('step 3 section', function () {
|
describe('step 3 section', function () {
|
||||||
it('should have header visible', function () {
|
it('should have header visible', function () {
|
||||||
cy.get(staking.step3).within(() => {
|
cy.get(step3).within(() => {
|
||||||
cy.get(staking.sectionHeader)
|
cy.get(sectionHeader)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.and(
|
.and(
|
||||||
'have.text',
|
'have.text',
|
||||||
|
@ -1,34 +1,26 @@
|
|||||||
import navigation from '../locators/navigation.locators';
|
const connectPrompt = '[data-testid="eth-connect-prompt"]';
|
||||||
import vesting from '../locators/vesting.locators';
|
const connectButton = '[data-testid="connect-to-eth-btn"]';
|
||||||
|
|
||||||
context('Vesting Page - verify elements on page', function () {
|
context('Vesting Page - verify elements on page', function () {
|
||||||
before('navigate to vesting page', function () {
|
before('navigate to vesting page', function () {
|
||||||
cy.visit('/')
|
cy.visit('/').navigate_to('vesting');
|
||||||
.get(navigation.section)
|
|
||||||
.within(() => {
|
|
||||||
cy.get(navigation.vesting).click();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with wallets disconnected', function () {
|
describe('with wallets disconnected', function () {
|
||||||
it('should have vesting tab highlighted', function () {
|
it('should have vesting tab highlighted', function () {
|
||||||
cy.get(navigation.section).within(() => {
|
cy.verify_tab_highlighted('vesting');
|
||||||
cy.get(navigation.vesting).should('have.attr', 'aria-current');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have VESTING header visible', function () {
|
it('should have VESTING header visible', function () {
|
||||||
cy.get(vesting.pageHeader)
|
cy.verify_page_header('Vesting');
|
||||||
.should('be.visible')
|
|
||||||
.and('have.text', 'Vesting');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have connect Eth wallet info', function () {
|
it('should have connect Eth wallet info', function () {
|
||||||
cy.get(vesting.connectPrompt).should('be.visible');
|
cy.get(connectPrompt).should('be.visible');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have connect Eth wallet button', function () {
|
it('should have connect Eth wallet button', function () {
|
||||||
cy.get(vesting.connectButton)
|
cy.get(connectButton)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.and('have.text', 'Connect Ethereum wallet');
|
.and('have.text', 'Connect Ethereum wallet');
|
||||||
});
|
});
|
||||||
|
251
apps/token-e2e/src/integration/wallet-eth.cy.js
Normal file
251
apps/token-e2e/src/integration/wallet-eth.cy.js
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
const walletContainer = '[data-testid="ethereum-wallet"]';
|
||||||
|
const walletHeader = '[data-testid="wallet-header"] h1';
|
||||||
|
const connectToEthButton = '[data-testid="connect-to-eth-wallet-button"]';
|
||||||
|
const connectorList = '[data-testid="web3-connector-list"]';
|
||||||
|
const associate = '[href="/staking/associate"]';
|
||||||
|
const disassociate = '[href="/staking/disassociate"]';
|
||||||
|
const disconnect = '[data-testid="disconnect-from-eth-wallet-button"]';
|
||||||
|
const accountNo = '[data-testid="ethereum-account-truncated"]';
|
||||||
|
const currencyTitle = '[data-testid="currency-title"]';
|
||||||
|
const currencyValue = '[data-testid="currency-value"]';
|
||||||
|
const vegaInVesting = '[data-testid="vega-in-vesting-contract"]';
|
||||||
|
const vegaInWallet = '[data-testid="vega-in-wallet"]';
|
||||||
|
const progressBar = '[data-testid="progress-bar"]';
|
||||||
|
const currencyLocked = '[data-testid="currency-locked"]';
|
||||||
|
const currencyUnlocked = '[data-testid="currency-unlocked"]';
|
||||||
|
const dialog = '[role="dialog"]';
|
||||||
|
const dialogHeader = '[data-testid="dialog-title"]';
|
||||||
|
const dialogCloseBtn = '[data-testid="dialog-close"]';
|
||||||
|
|
||||||
|
context('Ethereum Wallet - verify elements on widget', function () {
|
||||||
|
before('visit token home page', function () {
|
||||||
|
cy.visit('/');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with wallets disconnected', function () {
|
||||||
|
before('wait for widget to load', function () {
|
||||||
|
cy.get(walletContainer, { timeout: 10000 }).should('be.visible');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have ETHEREUM KEY header visible', function () {
|
||||||
|
cy.get(walletContainer).within(() => {
|
||||||
|
cy.get(walletHeader)
|
||||||
|
.should('be.visible')
|
||||||
|
.and('have.text', 'Ethereum key');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have Connect Ethereum button visible', function () {
|
||||||
|
cy.get(walletContainer).within(() => {
|
||||||
|
cy.get(connectToEthButton)
|
||||||
|
.should('be.visible')
|
||||||
|
.and('have.text', 'Connect Ethereum wallet to associate $VEGA');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when Connect Ethereum clicked', function () {
|
||||||
|
before('', function () {
|
||||||
|
cy.get(connectToEthButton).click();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have Connect Ethereum header visible', function () {
|
||||||
|
cy.get(dialog).within(() => {
|
||||||
|
cy.get(dialogHeader)
|
||||||
|
.should('be.visible')
|
||||||
|
.and('have.text', 'Connect to your Ethereum wallet');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have connector list visible', function () {
|
||||||
|
const connectList = [
|
||||||
|
'Unknown',
|
||||||
|
'MetaMask, Brave or other injected web wallet',
|
||||||
|
'WalletConnect',
|
||||||
|
];
|
||||||
|
cy.get(connectorList).within(() => {
|
||||||
|
cy.get('button').each(($btn, i) => {
|
||||||
|
cy.wrap($btn).should('be.visible').and('have.text', connectList[i]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
after('close popup', function () {
|
||||||
|
cy.get(dialog)
|
||||||
|
.within(() => {
|
||||||
|
cy.get(dialogCloseBtn).click();
|
||||||
|
})
|
||||||
|
.should('not.exist');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when Ethereum wallet connected', function () {
|
||||||
|
before('connect to Ethereum wallet', function () {
|
||||||
|
cy.ethereum_wallet_connect();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have ETHEREUM KEY header visible', function () {
|
||||||
|
cy.get(walletContainer).within(() => {
|
||||||
|
cy.get(walletHeader)
|
||||||
|
.should('be.visible')
|
||||||
|
.and('have.text', 'Ethereum key');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have account number visible', function () {
|
||||||
|
cy.get(walletContainer).within(() => {
|
||||||
|
cy.get(accountNo)
|
||||||
|
.should('be.visible')
|
||||||
|
.and('have.text', Cypress.env('ethWalletPublicKeyTruncated'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have Associate button visible', function () {
|
||||||
|
cy.get(walletContainer).within(() => {
|
||||||
|
cy.get(associate).should('be.visible').and('have.text', 'Associate');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have Disassociate button visible', function () {
|
||||||
|
cy.get(walletContainer).within(() => {
|
||||||
|
cy.get(disassociate)
|
||||||
|
.should('be.visible')
|
||||||
|
.and('have.text', 'Disassociate');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have Disconnect button visible', function () {
|
||||||
|
cy.get(walletContainer).within(() => {
|
||||||
|
cy.get(disconnect).should('be.visible').and('have.text', 'Disconnect');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('VEGA IN VESTING CONTRACT', function () {
|
||||||
|
it('should have currency title visible', function () {
|
||||||
|
cy.get(vegaInVesting).within(() => {
|
||||||
|
cy.get(currencyTitle)
|
||||||
|
.should('be.visible')
|
||||||
|
.and('have.text', 'VEGAIn vesting contract');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have currency value visible', function () {
|
||||||
|
cy.get(vegaInVesting).within(() => {
|
||||||
|
cy.get(currencyValue)
|
||||||
|
.should('be.visible')
|
||||||
|
.invoke('text')
|
||||||
|
.should('match', /\d{0,3}(,\d{3})*\.\d{18}$/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have progress bar visible', function () {
|
||||||
|
cy.get(vegaInVesting).within(() => {
|
||||||
|
cy.get(progressBar).should('be.visible');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have locked currency visible', function () {
|
||||||
|
cy.get(vegaInVesting).within(() => {
|
||||||
|
cy.get(currencyLocked)
|
||||||
|
.should('be.visible')
|
||||||
|
.invoke('text')
|
||||||
|
.should('match', /\d{0,3}(,\d{3})*\.\d{2}$/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have unlocked currency visible', function () {
|
||||||
|
cy.get(vegaInVesting).within(() => {
|
||||||
|
cy.get(currencyUnlocked)
|
||||||
|
.should('be.visible')
|
||||||
|
.invoke('text')
|
||||||
|
.should('match', /\d{0,3}(,\d{3})*\.\d{2}$/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should match total & locked/unlocked currency value', function () {
|
||||||
|
cy.get(vegaInVesting)
|
||||||
|
.within(() => {
|
||||||
|
cy.get(currencyValue)
|
||||||
|
.invoke('text')
|
||||||
|
.convert_token_value_to_number()
|
||||||
|
.as('value');
|
||||||
|
cy.get(currencyLocked)
|
||||||
|
.invoke('text')
|
||||||
|
.convert_token_value_to_number()
|
||||||
|
.as('locked');
|
||||||
|
cy.get(currencyUnlocked)
|
||||||
|
.invoke('text')
|
||||||
|
.convert_token_value_to_number()
|
||||||
|
.as('unlocked');
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
expect(this.value).to.equal(this.locked + this.unlocked);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('VEGA IN WALLET', function () {
|
||||||
|
it('should have currency title visible', function () {
|
||||||
|
cy.get(vegaInWallet).within(() => {
|
||||||
|
cy.get(currencyTitle)
|
||||||
|
.should('be.visible')
|
||||||
|
.and('have.text', 'VEGAIn Wallet');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have currency value visible', function () {
|
||||||
|
cy.get(vegaInWallet).within(() => {
|
||||||
|
cy.get(currencyValue)
|
||||||
|
.should('be.visible')
|
||||||
|
.invoke('text')
|
||||||
|
.should('match', /\d{0,3}(,\d{3})*\.\d{18}$/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have progress bar visible', function () {
|
||||||
|
cy.get(vegaInWallet).within(() => {
|
||||||
|
cy.get(progressBar).should('be.visible');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have locked currency visible', function () {
|
||||||
|
cy.get(vegaInWallet).within(() => {
|
||||||
|
cy.get(currencyLocked)
|
||||||
|
.should('be.visible')
|
||||||
|
.invoke('text')
|
||||||
|
.should('match', /\d{0,3}(,\d{3})*\.\d{2}$/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have unlocked currency visible', function () {
|
||||||
|
cy.get(vegaInWallet).within(() => {
|
||||||
|
cy.get(currencyUnlocked)
|
||||||
|
.should('be.visible')
|
||||||
|
.invoke('text')
|
||||||
|
.should('match', /\d{0,3}(,\d{3})*\.\d{2}$/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should match total & locked/unlocked currency value', function () {
|
||||||
|
cy.get(vegaInWallet)
|
||||||
|
.within(() => {
|
||||||
|
cy.get(currencyValue)
|
||||||
|
.invoke('text')
|
||||||
|
.convert_token_value_to_number()
|
||||||
|
.as('value');
|
||||||
|
cy.get(currencyLocked)
|
||||||
|
.invoke('text')
|
||||||
|
.convert_token_value_to_number()
|
||||||
|
.as('locked');
|
||||||
|
cy.get(currencyUnlocked)
|
||||||
|
.invoke('text')
|
||||||
|
.convert_token_value_to_number()
|
||||||
|
.as('unlocked');
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
expect(this.value).to.equal(this.locked + this.unlocked);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -1,36 +1,28 @@
|
|||||||
import navigation from '../locators/navigation.locators';
|
const connectToVegaBtn = '[data-testid="connect-to-vega-wallet-btn"]';
|
||||||
import withdraw from '../locators/withdraw.locators';
|
const warning = '[data-testid="callout"]';
|
||||||
|
|
||||||
context('Withdraw Page - verify elements on page', function () {
|
context('Withdraw Page - verify elements on page', function () {
|
||||||
before('navigate to withdraw page', function () {
|
before('navigate to withdraw page', function () {
|
||||||
cy.visit('/')
|
cy.visit('/').navigate_to('withdraw');
|
||||||
.get(navigation.section)
|
|
||||||
.within(() => {
|
|
||||||
cy.get(navigation.withdraw).click();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with wallets disconnected', function () {
|
describe('with wallets disconnected', function () {
|
||||||
it('should have withdraw tab highlighted', function () {
|
it('should have withdraw tab highlighted', function () {
|
||||||
cy.get(navigation.section).within(() => {
|
cy.verify_tab_highlighted('withdraw');
|
||||||
cy.get(navigation.withdraw).should('have.attr', 'aria-current');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have WITHDRAW header visible', function () {
|
it('should have WITHDRAW header visible', function () {
|
||||||
cy.get(withdraw.pageHeader)
|
cy.verify_page_header('Withdraw');
|
||||||
.should('be.visible')
|
|
||||||
.and('have.text', 'Withdraw');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have connect Vega wallet button', function () {
|
it('should have connect Vega wallet button', function () {
|
||||||
cy.get(withdraw.connectToVegaBtn)
|
cy.get(connectToVegaBtn)
|
||||||
.should('be.visible')
|
.should('be.visible')
|
||||||
.and('have.text', 'Connect Vega wallet');
|
.and('have.text', 'Connect Vega wallet');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should have withdraw information box', function () {
|
it('should have withdraw information box', function () {
|
||||||
cy.get(withdraw.warning).should('be.visible');
|
cy.get(warning).should('be.visible');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
export default {
|
|
||||||
pageHeader: 'header h1',
|
|
||||||
sectionHeader: 'h2',
|
|
||||||
link: '[data-testid="link"]',
|
|
||||||
warning: '[data-testid="callout"]',
|
|
||||||
connectToVegaBtn: '[data-testid="connect-to-vega-wallet-btn"]',
|
|
||||||
};
|
|
@ -1,6 +0,0 @@
|
|||||||
import common from './common.locators';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
...common,
|
|
||||||
noProposals: '[data-testid="no-proposals"]',
|
|
||||||
};
|
|
@ -1,15 +0,0 @@
|
|||||||
export default {
|
|
||||||
tokenDetailsTable: '.token-details',
|
|
||||||
address: '[data-testid="token-address"]',
|
|
||||||
contract: '[data-testid="token-contract"]',
|
|
||||||
totalSupply: '[data-testid="total-supply"]',
|
|
||||||
circulatingSupply: '[data-testid="circulating-supply"]',
|
|
||||||
staked: '[data-testid="staked"]',
|
|
||||||
|
|
||||||
tranchesLink: '[data-testid="tranches-link"]',
|
|
||||||
redeemBtn: '[data-testid="check-vesting-page-btn"]',
|
|
||||||
getVegaWalletLink: '[data-testid="get-vega-wallet-link"]',
|
|
||||||
associateVegaLink: '[data-testid="associate-vega-tokens-link-on-homepage"]',
|
|
||||||
stakingBtn: '[data-testid="staking-button-on-homepage"]',
|
|
||||||
governanceBtn: '[data-testid="governance-button-on-homepage"]',
|
|
||||||
};
|
|
@ -1,13 +0,0 @@
|
|||||||
import common from './common.locators';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
...common,
|
|
||||||
section: 'nav',
|
|
||||||
home: '[href="/"]',
|
|
||||||
vesting: '[href="/vesting"]',
|
|
||||||
staking: '[href="/staking"]',
|
|
||||||
rewards: '[href="/rewards"]',
|
|
||||||
withdraw: '[href="/withdraw"]',
|
|
||||||
governance: '[href="/governance"]',
|
|
||||||
spinner: 'splash-loader',
|
|
||||||
};
|
|
@ -1,5 +0,0 @@
|
|||||||
import common from './common.locators';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
...common,
|
|
||||||
};
|
|
@ -1,26 +0,0 @@
|
|||||||
import common from './common.locators';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
...common,
|
|
||||||
guideLink: '[data-testid="staking-guide-link"]',
|
|
||||||
step1: '[data-testid="staking-step-1"]',
|
|
||||||
step2: '[data-testid="staking-step-2"]',
|
|
||||||
step3: '[data-testid="staking-step-3"]',
|
|
||||||
connectToEthBtn: '[data-testid="connect-to-eth-btn"]',
|
|
||||||
connectToVegaBtn: '[data-testid="connect-to-vega-wallet-btn"]',
|
|
||||||
validatorNames: '[data-testid="node-list-item-name"]',
|
|
||||||
epochEndingText: '[data-testid="epoch-countdown"]',
|
|
||||||
addStakeRadioButton: '[data-testid="add-stake-radio"]',
|
|
||||||
removeStakeRadioButton: '[data-testid="remove-stake-radio"]',
|
|
||||||
tokenAmountInput: '[data-testid="token-amount-input"]',
|
|
||||||
tokenInputApprove: '[data-testid="token-input-approve-button"]',
|
|
||||||
tokenInputSubmit: '[data-testid="token-input-submit-button"]',
|
|
||||||
stakedAmounts: '[data-testid="staked-validator-item"]',
|
|
||||||
stakeNextEpochValue: '[data-testid="stake-next-epoch"]',
|
|
||||||
stakeThisEpochValue: '[data-testid="stake-this-epoch"]',
|
|
||||||
stakeMaximumTokens: '[data-testid="token-amount-use-maximum"]',
|
|
||||||
stakeAssociateWalletRadio: '[data-testid="associate-radio-wallet"]',
|
|
||||||
disassociateButton: '[data-testid="disassociate-tokens-btn"]',
|
|
||||||
associateMoreTokensButton: '[data-testid="associate-more-tokens-btn"]',
|
|
||||||
associateButton: '[data-testid="associate-tokens-btn"]',
|
|
||||||
};
|
|
@ -1,7 +0,0 @@
|
|||||||
import common from './common.locators';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
...common,
|
|
||||||
connectPrompt: '[data-testid="eth-connect-prompt"]',
|
|
||||||
connectButton: '[data-testid="connect-to-eth-btn"]',
|
|
||||||
};
|
|
@ -1,14 +0,0 @@
|
|||||||
import common from './common.locators';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
...common,
|
|
||||||
connectRestForm: '[data-testid="rest-connector-form"]',
|
|
||||||
name: '#wallet',
|
|
||||||
passphrase: '#passphrase',
|
|
||||||
vegawallet: '[data-testid="vega-wallet"]',
|
|
||||||
ethWallet: '[data-testid="ethereum-wallet"]',
|
|
||||||
ethWalletConnectToEth: '[data-testid="connect-to-eth-wallet-button"]',
|
|
||||||
ethWalletConnect: '[data-testid="web3-connector-Unknown"]',
|
|
||||||
ethWalletAssociate: '[href="/staking/associate"]',
|
|
||||||
ethWalletDisassociate: '[href="/staking/disassociate"]',
|
|
||||||
};
|
|
@ -1,5 +0,0 @@
|
|||||||
import common from './common.locators';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
...common,
|
|
||||||
};
|
|
33
apps/token-e2e/src/support/common.functions.js
Normal file
33
apps/token-e2e/src/support/common.functions.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
Cypress.Commands.add(
|
||||||
|
'convert_token_value_to_number',
|
||||||
|
{ prevSubject: true },
|
||||||
|
(subject) => {
|
||||||
|
return parseFloat(subject.replace(/,/g, ''));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const navigation = {
|
||||||
|
section: 'nav',
|
||||||
|
home: '[href="/"]',
|
||||||
|
vesting: '[href="/vesting"]',
|
||||||
|
staking: '[href="/staking"]',
|
||||||
|
rewards: '[href="/rewards"]',
|
||||||
|
withdraw: '[href="/withdraw"]',
|
||||||
|
governance: '[href="/governance"]',
|
||||||
|
};
|
||||||
|
|
||||||
|
Cypress.Commands.add('navigate_to', (page) => {
|
||||||
|
return cy.get(navigation.section).within(() => {
|
||||||
|
cy.get(navigation[page]).click();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add('verify_tab_highlighted', (page) => {
|
||||||
|
return cy.get(navigation.section).within(() => {
|
||||||
|
cy.get(navigation[page]).should('have.attr', 'aria-current');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add('verify_page_header', (text) => {
|
||||||
|
return cy.get('header h1').should('be.visible').and('have.text', text);
|
||||||
|
});
|
@ -1,51 +0,0 @@
|
|||||||
import wallet from '../locators/wallet.locators';
|
|
||||||
|
|
||||||
cy.ethereum_wallet_connect = () => {
|
|
||||||
cy.highlight('Connecting Eth Wallet');
|
|
||||||
cy.get(wallet.ethWalletConnectToEth).within(() => {
|
|
||||||
cy.contains('Connect Ethereum wallet to associate $VEGA')
|
|
||||||
.should('be.visible')
|
|
||||||
.click();
|
|
||||||
});
|
|
||||||
cy.get(wallet.ethWalletConnect).click();
|
|
||||||
cy.get(wallet.ethWalletConnect, { timeout: 60000 }).should('not.exist');
|
|
||||||
cy.get(wallet.ethWallet).within(() => {
|
|
||||||
// this check is required since it ensures the wallet is fully (not partially) loaded
|
|
||||||
cy.contains('Locked', { timeout: 15000 }).should('be.visible');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
cy.ethereum_wallet_check_associated_value_is = (expectedVal) => {
|
|
||||||
cy.highlight(`Checking Eth Wallet - Associated Value is ${expectedVal}`);
|
|
||||||
cy.get(wallet.ethWallet).within(() => {
|
|
||||||
cy.contains('Associated', { timeout: 20000 })
|
|
||||||
.parent()
|
|
||||||
.siblings()
|
|
||||||
.contains(expectedVal, { timeout: 40000 })
|
|
||||||
.should('be.visible');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
cy.ethereum_wallet_check_associated_vega_key_value_is = (
|
|
||||||
vegaShortPublicKey,
|
|
||||||
expectedVal
|
|
||||||
) => {
|
|
||||||
cy.highlight(
|
|
||||||
`Checking Eth Wallet - Vega Key Associated Value is ${expectedVal} for key ${vegaShortPublicKey}`
|
|
||||||
);
|
|
||||||
cy.get(wallet.ethWallet).within(() => {
|
|
||||||
cy.contains(vegaShortPublicKey, { timeout: 20000 })
|
|
||||||
.parent()
|
|
||||||
.contains(expectedVal, { timeout: 40000 })
|
|
||||||
.should('be.visible');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
cy.ethereum_wallet_check_associated_vega_key_is_no_longer_showing = (
|
|
||||||
vegaShortPublicKey
|
|
||||||
) => {
|
|
||||||
cy.highlight('Checking Eth Wallet - Vega Key Associated is not showing');
|
|
||||||
cy.get(wallet.ethWallet).within(() => {
|
|
||||||
cy.contains(vegaShortPublicKey, { timeout: 20000 }).should('not.exist');
|
|
||||||
});
|
|
||||||
};
|
|
@ -1,5 +1,11 @@
|
|||||||
import '@vegaprotocol/cypress';
|
import '@vegaprotocol/cypress';
|
||||||
|
|
||||||
|
import './common.functions.js';
|
||||||
|
import './staking.functions.js';
|
||||||
|
import './wallet-eth.functions.js';
|
||||||
|
import './wallet-teardown.functions.js';
|
||||||
|
import './wallet-vega.functions.js';
|
||||||
|
|
||||||
// Hide fetch/XHR requests - They create a lot of noise in command log
|
// Hide fetch/XHR requests - They create a lot of noise in command log
|
||||||
const app = window.top;
|
const app = window.top;
|
||||||
if (!app.document.head.querySelector('[data-hide-command-log-request]')) {
|
if (!app.document.head.querySelector('[data-hide-command-log-request]')) {
|
||||||
|
@ -1,11 +1,27 @@
|
|||||||
import staking from '../locators/staking.locators';
|
const tokenAmountInputBox = '[data-testid="token-amount-input"]';
|
||||||
|
const tokenSubmitButton = '[data-testid="token-input-submit-button"]';
|
||||||
|
const tokenInputApprove = '[data-testid="token-input-approve-button"]';
|
||||||
|
const addStakeRadioButton = '[data-testid="add-stake-radio"]';
|
||||||
|
const removeStakeRadioButton = '[data-testid="remove-stake-radio"]';
|
||||||
|
const ethWalletAssociateButton = '[href="/staking/associate"]';
|
||||||
|
const ethWalletDissociateButton = '[href="/staking/disassociate"]';
|
||||||
|
const associateWalletRadioButton = '[data-testid="associate-radio-wallet"]';
|
||||||
|
const stakeMaximumTokens = '[data-testid="token-amount-use-maximum"]';
|
||||||
|
|
||||||
cy.staking_validator_page_add_stake = (stake) => {
|
Cypress.Commands.add('wait_for_begining_of_epoch', () => {
|
||||||
|
cy.highlight(`Waiting for next epoch to start`);
|
||||||
|
cy.contains('Waiting for next epoch to start', { timeout: 10000 }).should(
|
||||||
|
'not.exist'
|
||||||
|
);
|
||||||
|
cy.contains('Waiting for next epoch to start', { timeout: 20000 });
|
||||||
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add('staking_validator_page_add_stake', (stake) => {
|
||||||
cy.highlight(`Adding a stake of ${stake}`);
|
cy.highlight(`Adding a stake of ${stake}`);
|
||||||
cy.get(staking.addStakeRadioButton).click({ force: true });
|
cy.get(addStakeRadioButton).click({ force: true });
|
||||||
cy.get(staking.tokenAmountInput).type(stake);
|
cy.get(tokenAmountInputBox).type(stake);
|
||||||
cy.contains('Waiting for next epoch to start', { timeout: 10000 });
|
cy.wait_for_begining_of_epoch();
|
||||||
cy.get(staking.tokenInputSubmit, { timeout: 8000 })
|
cy.get(tokenSubmitButton, { timeout: 8000 })
|
||||||
.should('be.enabled')
|
.should('be.enabled')
|
||||||
.and('contain', `Add ${stake} $VEGA tokens`)
|
.and('contain', `Add ${stake} $VEGA tokens`)
|
||||||
.and('be.visible')
|
.and('be.visible')
|
||||||
@ -14,14 +30,14 @@ cy.staking_validator_page_add_stake = (stake) => {
|
|||||||
'At the beginning of the next epoch your $VEGA will be nominated to the validator',
|
'At the beginning of the next epoch your $VEGA will be nominated to the validator',
|
||||||
{ timeout: 20000 }
|
{ timeout: 20000 }
|
||||||
).should('be.visible');
|
).should('be.visible');
|
||||||
};
|
});
|
||||||
|
|
||||||
cy.staking_validator_page_removeStake = (stake) => {
|
Cypress.Commands.add('staking_validator_page_removeStake', (stake) => {
|
||||||
cy.highlight(`Removing a stake of ${stake}`);
|
cy.highlight(`Removing a stake of ${stake}`);
|
||||||
cy.get(staking.removeStakeRadioButton).click({ force: true });
|
cy.get(removeStakeRadioButton).click({ force: true });
|
||||||
cy.get(staking.tokenAmountInput).type(stake);
|
cy.get(tokenAmountInputBox).type(stake);
|
||||||
cy.contains('Waiting for next epoch to start', { timeout: 10000 });
|
cy.wait_for_begining_of_epoch();
|
||||||
cy.get(staking.tokenInputSubmit)
|
cy.get(tokenSubmitButton)
|
||||||
.should('be.enabled', { timeout: 8000 })
|
.should('be.enabled', { timeout: 8000 })
|
||||||
.and('contain', `Remove ${stake} $VEGA tokens at the end of epoch`)
|
.and('contain', `Remove ${stake} $VEGA tokens at the end of epoch`)
|
||||||
.and('be.visible')
|
.and('be.visible')
|
||||||
@ -29,15 +45,17 @@ cy.staking_validator_page_removeStake = (stake) => {
|
|||||||
cy.contains(`${stake} $VEGA has been removed from validator`).should(
|
cy.contains(`${stake} $VEGA has been removed from validator`).should(
|
||||||
'be.visible'
|
'be.visible'
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
cy.staking_page_associate_tokens = (amount, approve = false) => {
|
Cypress.Commands.add(
|
||||||
|
'staking_page_associate_tokens',
|
||||||
|
(amount, approve = false) => {
|
||||||
cy.highlight(`Associating ${amount} tokens`);
|
cy.highlight(`Associating ${amount} tokens`);
|
||||||
cy.get(staking.associateButton).click();
|
cy.get(ethWalletAssociateButton).first().click();
|
||||||
cy.get(staking.stakeAssociateWalletRadio, { timeout: 30000 }).click();
|
cy.get(associateWalletRadioButton, { timeout: 30000 }).click();
|
||||||
cy.get(staking.tokenAmountInput, { timeout: 10000 }).type(amount);
|
cy.get(tokenAmountInputBox, { timeout: 10000 }).type(amount);
|
||||||
if (approve) {
|
if (approve) {
|
||||||
cy.get(staking.tokenInputApprove, { timeout: 40000 })
|
cy.get(tokenInputApprove, { timeout: 40000 })
|
||||||
.should('be.enabled')
|
.should('be.enabled')
|
||||||
.click();
|
.click();
|
||||||
cy.contains('Approve $VEGA Tokens for staking on Vega').should(
|
cy.contains('Approve $VEGA Tokens for staking on Vega').should(
|
||||||
@ -47,35 +65,32 @@ cy.staking_page_associate_tokens = (amount, approve = false) => {
|
|||||||
timeout: 40000,
|
timeout: 40000,
|
||||||
}).should('not.exist');
|
}).should('not.exist');
|
||||||
}
|
}
|
||||||
cy.get(staking.tokenInputSubmit, { timeout: 40000 })
|
cy.get(tokenSubmitButton, { timeout: 40000 }).should('be.enabled').click();
|
||||||
.should('be.enabled')
|
|
||||||
.click();
|
|
||||||
cy.contains('can now participate in governance and nominate a validator', {
|
cy.contains('can now participate in governance and nominate a validator', {
|
||||||
timeout: 60000,
|
timeout: 60000,
|
||||||
}).should('be.visible');
|
}).should('be.visible');
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
||||||
cy.staking_page_disassociate_tokens = (amount) => {
|
Cypress.Commands.add('staking_page_disassociate_tokens', (amount) => {
|
||||||
cy.highlight(`Disassociating ${amount} tokens via Staking Page`);
|
cy.highlight(`Disassociating ${amount} tokens via Staking Page`);
|
||||||
cy.get(staking.disassociateButton).click();
|
cy.get(ethWalletDissociateButton).first().click();
|
||||||
cy.get(staking.stakeAssociateWalletRadio, { timeout: 30000 }).click();
|
cy.get(associateWalletRadioButton, { timeout: 30000 }).click();
|
||||||
cy.get(staking.tokenAmountInput, { timeout: 10000 }).type(amount);
|
cy.get(tokenAmountInputBox, { timeout: 10000 }).type(amount);
|
||||||
|
|
||||||
cy.get(staking.tokenInputSubmit, { timeout: 40000 })
|
cy.get(tokenSubmitButton, { timeout: 40000 }).should('be.enabled').click();
|
||||||
.should('be.enabled')
|
|
||||||
.click();
|
|
||||||
cy.contains(`${amount} $VEGA tokens have been returned to Ethereum wallet`, {
|
cy.contains(`${amount} $VEGA tokens have been returned to Ethereum wallet`, {
|
||||||
timeout: 60000,
|
timeout: 60000,
|
||||||
}).should('be.visible');
|
}).should('be.visible');
|
||||||
};
|
});
|
||||||
|
|
||||||
cy.staking_page_disassociate_all_tokens = () => {
|
Cypress.Commands.add('staking_page_disassociate_all_tokens', () => {
|
||||||
cy.highlight(`Disassociating all tokens via Staking Page`);
|
cy.highlight(`Disassociating all tokens via Staking Page`);
|
||||||
cy.get(staking.disassociateButton).click();
|
cy.get(ethWalletDissociateButton).first().click();
|
||||||
cy.get(staking.stakeAssociateWalletRadio, { timeout: 20000 }).click();
|
cy.get(associateWalletRadioButton, { timeout: 20000 }).click();
|
||||||
cy.get(staking.stakeMaximumTokens, { timeout: 60000 }).click();
|
cy.get(stakeMaximumTokens, { timeout: 60000 }).click();
|
||||||
cy.get(staking.tokenInputSubmit, { timeout: 10000 }).click();
|
cy.get(tokenSubmitButton, { timeout: 10000 }).click();
|
||||||
cy.contains('$VEGA tokens have been returned to Ethereum wallet', {
|
cy.contains('$VEGA tokens have been returned to Ethereum wallet', {
|
||||||
timeout: 60000,
|
timeout: 60000,
|
||||||
}).should('be.visible');
|
}).should('be.visible');
|
||||||
};
|
});
|
||||||
|
57
apps/token-e2e/src/support/wallet-eth.functions.js
Normal file
57
apps/token-e2e/src/support/wallet-eth.functions.js
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
const ethWalletContainer = '[data-testid="ethereum-wallet"]';
|
||||||
|
const connectToEthButton = '[data-testid="connect-to-eth-wallet-button"]';
|
||||||
|
const capsuleWalletConnectButton = '[data-testid="web3-connector-Unknown"]';
|
||||||
|
|
||||||
|
Cypress.Commands.add('ethereum_wallet_connect', () => {
|
||||||
|
cy.highlight('Connecting Eth Wallet');
|
||||||
|
cy.get(connectToEthButton).within(() => {
|
||||||
|
cy.contains('Connect Ethereum wallet to associate $VEGA')
|
||||||
|
.should('be.visible')
|
||||||
|
.click();
|
||||||
|
});
|
||||||
|
cy.get(capsuleWalletConnectButton).click();
|
||||||
|
cy.get(capsuleWalletConnectButton, { timeout: 60000 }).should('not.exist');
|
||||||
|
cy.get(ethWalletContainer).within(() => {
|
||||||
|
// this check is required since it ensures the wallet is fully (not partially) loaded
|
||||||
|
cy.contains('Locked', { timeout: 15000 }).should('be.visible');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
Cypress.Commands.add(
|
||||||
|
'ethereum_wallet_check_associated_value_is',
|
||||||
|
(expectedVal) => {
|
||||||
|
cy.highlight(`Checking Eth Wallet - Associated Value is ${expectedVal}`);
|
||||||
|
cy.get(ethWalletContainer).within(() => {
|
||||||
|
cy.contains('Associated', { timeout: 20000 })
|
||||||
|
.parent()
|
||||||
|
.siblings()
|
||||||
|
.contains(expectedVal, { timeout: 40000 })
|
||||||
|
.should('be.visible');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Cypress.Commands.add(
|
||||||
|
'ethereum_wallet_check_associated_vega_key_value_is',
|
||||||
|
(vegaShortPublicKey, expectedVal) => {
|
||||||
|
cy.highlight(
|
||||||
|
`Checking Eth Wallet - Vega Key Associated Value is ${expectedVal} for key ${vegaShortPublicKey}`
|
||||||
|
);
|
||||||
|
cy.get(ethWalletContainer).within(() => {
|
||||||
|
cy.contains(vegaShortPublicKey, { timeout: 20000 })
|
||||||
|
.parent()
|
||||||
|
.contains(expectedVal, { timeout: 40000 })
|
||||||
|
.should('be.visible');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Cypress.Commands.add(
|
||||||
|
'ethereum_wallet_check_associated_vega_key_is_no_longer_showing',
|
||||||
|
(vegaShortPublicKey) => {
|
||||||
|
cy.highlight('Checking Eth Wallet - Vega Key Associated is not showing');
|
||||||
|
cy.get(ethWalletContainer).within(() => {
|
||||||
|
cy.contains(vegaShortPublicKey, { timeout: 20000 }).should('not.exist');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
@ -64,7 +64,9 @@ Cypress.Commands.add(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.vega_wallet_teardown_staking = (stakingBridgeContract) => {
|
Cypress.Commands.add(
|
||||||
|
'vega_wallet_teardown_staking',
|
||||||
|
(stakingBridgeContract) => {
|
||||||
cy.highlight('Tearing down staking tokens from vega wallet if present');
|
cy.highlight('Tearing down staking tokens from vega wallet if present');
|
||||||
cy.wrap(
|
cy.wrap(
|
||||||
stakingBridgeContract.stakeBalance(ethWalletPubKey, vegaWalletPubKey),
|
stakingBridgeContract.stakeBalance(ethWalletPubKey, vegaWalletPubKey),
|
||||||
@ -82,9 +84,10 @@ cy.vega_wallet_teardown_staking = (stakingBridgeContract) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
||||||
cy.vega_wallet_teardown_vesting = (vestingContract) => {
|
Cypress.Commands.add('vega_wallet_teardown_vesting', (vestingContract) => {
|
||||||
cy.highlight('Tearing down vesting tokens from vega wallet if present');
|
cy.highlight('Tearing down vesting tokens from vega wallet if present');
|
||||||
cy.wrap(vestingContract.stakeBalance(ethWalletPubKey, vegaWalletPubKey), {
|
cy.wrap(vestingContract.stakeBalance(ethWalletPubKey, vegaWalletPubKey), {
|
||||||
timeout: transactionTimeout,
|
timeout: transactionTimeout,
|
||||||
@ -99,8 +102,8 @@ cy.vega_wallet_teardown_vesting = (vestingContract) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
});
|
||||||
|
|
||||||
cy.wait_for_transaction = (tx) => {
|
Cypress.Commands.add('wait_for_transaction', (tx) => {
|
||||||
cy.wrap(tx.wait(1).catch(cy.log), { timeout: transactionTimeout });
|
cy.wrap(tx.wait(1).catch(cy.log), { timeout: transactionTimeout });
|
||||||
};
|
});
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import wallet from '../locators/wallet.locators';
|
const vegaWalletContainer = '[data-testid="vega-wallet"]';
|
||||||
|
const restConnectorForm = '[data-testid="rest-connector-form"]';
|
||||||
const vegaWalletName = Cypress.env('vegaWalletName');
|
const vegaWalletName = Cypress.env('vegaWalletName');
|
||||||
const vegaWalletLocation = Cypress.env('vegaWalletLocation');
|
const vegaWalletLocation = Cypress.env('vegaWalletLocation');
|
||||||
const vegaWalletPassphrase = Cypress.env('vegaWalletPassphrase');
|
const vegaWalletPassphrase = Cypress.env('vegaWalletPassphrase');
|
||||||
|
|
||||||
cy.vega_wallet_import = () => {
|
Cypress.Commands.add('vega_wallet_import', () => {
|
||||||
cy.highlight(`Importing Vega Wallet ${vegaWalletName}`);
|
cy.highlight(`Importing Vega Wallet ${vegaWalletName}`);
|
||||||
cy.exec(`vegawallet init -f --home ${vegaWalletLocation}`);
|
cy.exec(`vegawallet init -f --home ${vegaWalletLocation}`);
|
||||||
cy.exec(
|
cy.exec(
|
||||||
@ -14,11 +14,11 @@ cy.vega_wallet_import = () => {
|
|||||||
cy.exec(
|
cy.exec(
|
||||||
`vegawallet service run --network DV --automatic-consent --home ${vegaWalletLocation}`
|
`vegawallet service run --network DV --automatic-consent --home ${vegaWalletLocation}`
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
cy.vega_wallet_connect = () => {
|
Cypress.Commands.add('vega_wallet_connect', () => {
|
||||||
cy.highlight('Connecting Vega Wallet');
|
cy.highlight('Connecting Vega Wallet');
|
||||||
cy.get(wallet.vegawallet).within(() => {
|
cy.get(vegaWalletContainer).within(() => {
|
||||||
cy.get('button')
|
cy.get('button')
|
||||||
.contains('Connect Vega wallet to use associated $VEGA')
|
.contains('Connect Vega wallet to use associated $VEGA')
|
||||||
.should('be.enabled')
|
.should('be.enabled')
|
||||||
@ -26,31 +26,31 @@ cy.vega_wallet_connect = () => {
|
|||||||
.click({ force: true });
|
.click({ force: true });
|
||||||
});
|
});
|
||||||
cy.get('button').contains('rest provider').click();
|
cy.get('button').contains('rest provider').click();
|
||||||
cy.get(wallet.connectRestForm).within(() => {
|
cy.get(restConnectorForm).within(() => {
|
||||||
cy.get(wallet.name).click().type(vegaWalletName);
|
cy.get('#wallet').click().type(vegaWalletName);
|
||||||
cy.get(wallet.passphrase).click().type(vegaWalletPassphrase);
|
cy.get('#passphrase').click().type(vegaWalletPassphrase);
|
||||||
cy.get('button').contains('Connect').click();
|
cy.get('button').contains('Connect').click();
|
||||||
});
|
});
|
||||||
cy.contains(`${vegaWalletName} key`, { timeout: 20000 }).should('be.visible');
|
cy.contains(`${vegaWalletName} key`, { timeout: 20000 }).should('be.visible');
|
||||||
};
|
});
|
||||||
|
|
||||||
cy.vega_wallet_check_unstaked_value_is = (expectedVal) => {
|
Cypress.Commands.add('vega_wallet_check_unstaked_value_is', (expectedVal) => {
|
||||||
cy.highlight(`Checking vega wallet - Unstaked Value is ${expectedVal}`);
|
cy.highlight(`Checking vega wallet - Unstaked Value is ${expectedVal}`);
|
||||||
cy.get(wallet.vegawallet).within(() => {
|
cy.get(vegaWalletContainer).within(() => {
|
||||||
cy.contains('Unstaked', { timeout: 40000 })
|
cy.contains('Unstaked', { timeout: 40000 })
|
||||||
.siblings()
|
.siblings()
|
||||||
.contains(expectedVal, { timeout: 40000 })
|
.contains(expectedVal, { timeout: 40000 })
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
});
|
});
|
||||||
};
|
});
|
||||||
|
|
||||||
cy.vega_wallet_check_associated_value_is = (expectedVal) => {
|
Cypress.Commands.add('vega_wallet_check_associated_value_is', (expectedVal) => {
|
||||||
cy.highlight(`Checking vega wallet - Associated Value is ${expectedVal}`);
|
cy.highlight(`Checking vega wallet - Associated Value is ${expectedVal}`);
|
||||||
cy.get(wallet.vegawallet).within(() => {
|
cy.get(vegaWalletContainer).within(() => {
|
||||||
cy.contains('Associated', { timeout: 40000 })
|
cy.contains('Associated', { timeout: 40000 })
|
||||||
.parent()
|
.parent()
|
||||||
.siblings()
|
.siblings()
|
||||||
.contains(expectedVal, { timeout: 40000 })
|
.contains(expectedVal, { timeout: 40000 })
|
||||||
.should('be.visible');
|
.should('be.visible');
|
||||||
});
|
});
|
||||||
};
|
});
|
@ -128,7 +128,7 @@ const ConnectedKey = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{totalVestedBalance.plus(totalLockedBalance).isEqualTo(0) ? null : (
|
{totalVestedBalance.plus(totalLockedBalance).isEqualTo(0) ? null : (
|
||||||
<>
|
<section data-testid="vega-in-vesting-contract">
|
||||||
<WalletCardAsset
|
<WalletCardAsset
|
||||||
image={vegaVesting}
|
image={vegaVesting}
|
||||||
decimals={appState.decimals}
|
decimals={appState.decimals}
|
||||||
@ -145,7 +145,7 @@ const ConnectedKey = () => {
|
|||||||
rightLabel={t('Unlocked')}
|
rightLabel={t('Unlocked')}
|
||||||
light={false}
|
light={false}
|
||||||
/>
|
/>
|
||||||
</>
|
</section>
|
||||||
)}
|
)}
|
||||||
{!Object.keys(appState.associationBreakdown.vestingAssociations)
|
{!Object.keys(appState.associationBreakdown.vestingAssociations)
|
||||||
.length ? null : (
|
.length ? null : (
|
||||||
@ -154,6 +154,7 @@ const ConnectedKey = () => {
|
|||||||
notAssociated={notAssociatedInContract}
|
notAssociated={notAssociatedInContract}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
<section data-testid="vega-in-wallet">
|
||||||
<WalletCardAsset
|
<WalletCardAsset
|
||||||
image={vegaWhite}
|
image={vegaWhite}
|
||||||
decimals={appState.decimals}
|
decimals={appState.decimals}
|
||||||
@ -170,6 +171,7 @@ const ConnectedKey = () => {
|
|||||||
notAssociated={walletBalance}
|
notAssociated={walletBalance}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
</section>
|
||||||
<WalletCardActions>
|
<WalletCardActions>
|
||||||
<Link
|
<Link
|
||||||
className={getButtonClasses('flex-1 mr-4', 'secondary')}
|
className={getButtonClasses('flex-1 mr-4', 'secondary')}
|
||||||
@ -201,7 +203,12 @@ export const EthWallet = () => {
|
|||||||
<h1 className="text-h3 uppercase">{t('ethereumKey')}</h1>
|
<h1 className="text-h3 uppercase">{t('ethereumKey')}</h1>
|
||||||
{account && (
|
{account && (
|
||||||
<div className="px-4 text-right">
|
<div className="px-4 text-right">
|
||||||
<div className="font-mono">{truncateMiddle(account)}</div>
|
<div
|
||||||
|
className="font-mono"
|
||||||
|
data-testid="ethereum-account-truncated"
|
||||||
|
>
|
||||||
|
{truncateMiddle(account)}
|
||||||
|
</div>
|
||||||
{pendingTxs && (
|
{pendingTxs && (
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
@ -245,6 +252,7 @@ export const EthWallet = () => {
|
|||||||
<button
|
<button
|
||||||
className="mt-4 underline"
|
className="mt-4 underline"
|
||||||
onClick={() => connector.deactivate()}
|
onClick={() => connector.deactivate()}
|
||||||
|
data-testid="disconnect-from-eth-wallet-button"
|
||||||
>
|
>
|
||||||
{t('disconnect')}
|
{t('disconnect')}
|
||||||
</button>
|
</button>
|
||||||
|
@ -99,6 +99,7 @@ export const LockedProgress = ({
|
|||||||
'border-black': light,
|
'border-black': light,
|
||||||
'border-white': !light,
|
'border-white': !light,
|
||||||
})}
|
})}
|
||||||
|
data-testid="progress-bar"
|
||||||
>
|
>
|
||||||
<ProgressBar percentage={lockedPercentage} bgColor={leftColor} />
|
<ProgressBar percentage={lockedPercentage} bgColor={leftColor} />
|
||||||
<ProgressBar percentage={unlockedPercentage} bgColor={rightColor} />
|
<ProgressBar percentage={unlockedPercentage} bgColor={rightColor} />
|
||||||
@ -119,8 +120,12 @@ export const LockedProgress = ({
|
|||||||
</ProgressContents>
|
</ProgressContents>
|
||||||
|
|
||||||
<ProgressContents light={light}>
|
<ProgressContents light={light}>
|
||||||
<span>{formatNumber(locked, decimals)}</span>
|
<span data-testid="currency-locked">
|
||||||
<span>{formatNumber(unlocked, decimals)}</span>
|
{formatNumber(locked, decimals)}
|
||||||
|
</span>
|
||||||
|
<span data-testid="currency-unlocked">
|
||||||
|
{formatNumber(unlocked, decimals)}
|
||||||
|
</span>
|
||||||
</ProgressContents>
|
</ProgressContents>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -47,7 +47,10 @@ interface WalletCardHeaderProps {
|
|||||||
|
|
||||||
export const WalletCardHeader = ({ children }: WalletCardHeaderProps) => {
|
export const WalletCardHeader = ({ children }: WalletCardHeaderProps) => {
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-[auto_1fr] gap-4">
|
<div
|
||||||
|
className="grid grid-cols-1 sm:grid-cols-[auto_1fr] gap-4"
|
||||||
|
data-testid="wallet-header"
|
||||||
|
>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -151,7 +154,10 @@ export const WalletCardAsset = ({
|
|||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<div className="flex font-medium align-center">
|
<div
|
||||||
|
className="flex font-medium align-center"
|
||||||
|
data-testid="currency-title"
|
||||||
|
>
|
||||||
<h1
|
<h1
|
||||||
className={`text-h5 mb-0 px-8 uppercase leading-none ${
|
className={`text-h5 mb-0 px-8 uppercase leading-none ${
|
||||||
dark ? 'text-white' : 'text-black'
|
dark ? 'text-white' : 'text-black'
|
||||||
@ -167,7 +173,10 @@ export const WalletCardAsset = ({
|
|||||||
{subheading || symbol}
|
{subheading || symbol}
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div className="px-8 text-h5 basis-full font-mono">
|
<div
|
||||||
|
className="px-8 text-h5 basis-full font-mono"
|
||||||
|
data-testid="currency-value"
|
||||||
|
>
|
||||||
<span>{integers}.</span>
|
<span>{integers}.</span>
|
||||||
<span className={dark ? 'text-white-60' : 'text-black-60'}>
|
<span className={dark ? 'text-white-60' : 'text-black-60'}>
|
||||||
{decimalsPlaces}
|
{decimalsPlaces}
|
||||||
|
@ -68,7 +68,7 @@ export const Web3Content = ({ children, appChainId }: Web3ContentProps) => {
|
|||||||
return (
|
return (
|
||||||
<Splash>
|
<Splash>
|
||||||
<div className="flex flex-col items-center gap-12">
|
<div className="flex flex-col items-center gap-12">
|
||||||
<p>Something went wrong: {error.message}</p>
|
<p className="text-white">Something went wrong: {error.message}</p>
|
||||||
<Button onClick={() => connector.deactivate()}>Disconnect</Button>
|
<Button onClick={() => connector.deactivate()}>Disconnect</Button>
|
||||||
</div>
|
</div>
|
||||||
</Splash>
|
</Splash>
|
||||||
@ -79,7 +79,9 @@ export const Web3Content = ({ children, appChainId }: Web3ContentProps) => {
|
|||||||
return (
|
return (
|
||||||
<Splash>
|
<Splash>
|
||||||
<div className="flex flex-col items-center gap-12">
|
<div className="flex flex-col items-center gap-12">
|
||||||
<p>This app only works on chain ID: {appChainId}</p>
|
<p className="text-white">
|
||||||
|
This app only works on chain ID: {appChainId}
|
||||||
|
</p>
|
||||||
<Button onClick={() => connector.deactivate()}>Disconnect</Button>
|
<Button onClick={() => connector.deactivate()}>Disconnect</Button>
|
||||||
</div>
|
</div>
|
||||||
</Splash>
|
</Splash>
|
||||||
|
@ -18,21 +18,25 @@ describe('accounts', () => {
|
|||||||
|
|
||||||
cy.getByTestId('tab-accounts').should('be.visible');
|
cy.getByTestId('tab-accounts').should('be.visible');
|
||||||
cy.getByTestId('tab-accounts')
|
cy.getByTestId('tab-accounts')
|
||||||
|
.should('be.visible')
|
||||||
.get(`[row-id='General-tEURO-null']`)
|
.get(`[row-id='General-tEURO-null']`)
|
||||||
.find('[col-id="asset.symbol"]')
|
.find('[col-id="asset.symbol"]')
|
||||||
.should('have.text', 'tEURO');
|
.should('have.text', 'tEURO');
|
||||||
|
|
||||||
cy.getByTestId('tab-accounts')
|
cy.getByTestId('tab-accounts')
|
||||||
|
.should('be.visible')
|
||||||
.get(`[row-id='General-tEURO-null']`)
|
.get(`[row-id='General-tEURO-null']`)
|
||||||
.find('[col-id="type"]')
|
.find('[col-id="type"]')
|
||||||
.should('have.text', 'General');
|
.should('have.text', 'General');
|
||||||
|
|
||||||
cy.getByTestId('tab-accounts')
|
cy.getByTestId('tab-accounts')
|
||||||
|
.should('be.visible')
|
||||||
.get(`[row-id='General-tEURO-null']`)
|
.get(`[row-id='General-tEURO-null']`)
|
||||||
.find('[col-id="market.name"]')
|
.find('[col-id="market.name"]')
|
||||||
.should('have.text', '—');
|
.should('have.text', '—');
|
||||||
|
|
||||||
cy.getByTestId('tab-accounts')
|
cy.getByTestId('tab-accounts')
|
||||||
|
.should('be.visible')
|
||||||
.get(`[row-id='General-tEURO-null']`)
|
.get(`[row-id='General-tEURO-null']`)
|
||||||
.find('[col-id="balance"]')
|
.find('[col-id="balance"]')
|
||||||
.should('have.text', '1,000.00000');
|
.should('have.text', '1,000.00000');
|
||||||
|
@ -33,7 +33,7 @@ describe('deal ticket orders', () => {
|
|||||||
const orderTIFDropDown = 'order-tif';
|
const orderTIFDropDown = 'order-tif';
|
||||||
const placeOrderBtn = 'place-order';
|
const placeOrderBtn = 'place-order';
|
||||||
const orderStatusHeader = 'order-status-header';
|
const orderStatusHeader = 'order-status-header';
|
||||||
const orderTransactionHash = 'tx-hash';
|
const orderTransactionHash = 'tx-block-explorer';
|
||||||
|
|
||||||
before(() => {
|
before(() => {
|
||||||
cy.mockGQL((req) => {
|
cy.mockGQL((req) => {
|
||||||
|
@ -19,6 +19,7 @@ describe('positions', () => {
|
|||||||
cy.getByTestId('tab-positions').should('be.visible');
|
cy.getByTestId('tab-positions').should('be.visible');
|
||||||
cy.getByTestId('tab-positions')
|
cy.getByTestId('tab-positions')
|
||||||
.get('[col-id="market.tradableInstrument.instrument.code"]')
|
.get('[col-id="market.tradableInstrument.instrument.code"]')
|
||||||
|
.should('be.visible')
|
||||||
.each(($marketSymbol) => {
|
.each(($marketSymbol) => {
|
||||||
cy.wrap($marketSymbol).invoke('text').should('not.be.empty');
|
cy.wrap($marketSymbol).invoke('text').should('not.be.empty');
|
||||||
});
|
});
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import merge from 'lodash/merge';
|
import merge from 'lodash/merge';
|
||||||
import type { PartialDeep } from 'type-fest';
|
import type { PartialDeep } from 'type-fest';
|
||||||
import type { Orders, Orders_party_orders } from '@vegaprotocol/order-list';
|
import type { Orders, Orders_party_orders } from '@vegaprotocol/orders';
|
||||||
import {
|
import {
|
||||||
OrderStatus,
|
OrderStatus,
|
||||||
OrderTimeInForce,
|
OrderTimeInForce,
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// @generated
|
// @generated
|
||||||
// This file was automatically generated and should not be edited.
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
import { MarketTradingMode } from "@vegaprotocol/types";
|
import { MarketTradingMode, MarketState } from "@vegaprotocol/types";
|
||||||
|
|
||||||
// ====================================================
|
// ====================================================
|
||||||
// GraphQL query operation: MarketsLanding
|
// GraphQL query operation: MarketsLanding
|
||||||
@ -27,6 +27,10 @@ export interface MarketsLanding_markets {
|
|||||||
* Current mode of execution of the market
|
* Current mode of execution of the market
|
||||||
*/
|
*/
|
||||||
tradingMode: MarketTradingMode;
|
tradingMode: MarketTradingMode;
|
||||||
|
/**
|
||||||
|
* Current state of the market
|
||||||
|
*/
|
||||||
|
state: MarketState;
|
||||||
/**
|
/**
|
||||||
* timestamps for state changes in the market
|
* timestamps for state changes in the market
|
||||||
*/
|
*/
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { gql, useQuery } from '@apollo/client';
|
import { gql, useQuery } from '@apollo/client';
|
||||||
import { MarketTradingMode } from '@vegaprotocol/types';
|
import { MarketTradingMode } from '@vegaprotocol/types';
|
||||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||||
import sortBy from 'lodash/sortBy';
|
import orderBy from 'lodash/orderBy';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useGlobalStore } from '../stores';
|
import { useGlobalStore } from '../stores';
|
||||||
@ -12,6 +12,7 @@ const MARKETS_QUERY = gql`
|
|||||||
markets {
|
markets {
|
||||||
id
|
id
|
||||||
tradingMode
|
tradingMode
|
||||||
|
state
|
||||||
marketTimestamps {
|
marketTimestamps {
|
||||||
open
|
open
|
||||||
}
|
}
|
||||||
@ -20,13 +21,13 @@ const MARKETS_QUERY = gql`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const marketList = ({ markets }: MarketsLanding) =>
|
const marketList = ({ markets }: MarketsLanding) =>
|
||||||
sortBy(
|
orderBy(
|
||||||
markets?.filter(
|
markets?.filter(
|
||||||
({ marketTimestamps, tradingMode }) =>
|
({ marketTimestamps, tradingMode }) =>
|
||||||
marketTimestamps.open && tradingMode === MarketTradingMode.Continuous
|
marketTimestamps.open && tradingMode === MarketTradingMode.Continuous
|
||||||
) || [],
|
) || [],
|
||||||
'marketTimestamps.open',
|
['state', 'marketTimestamps.open', 'id'],
|
||||||
'id'
|
['asc', 'asc', 'asc']
|
||||||
);
|
);
|
||||||
|
|
||||||
export function Index() {
|
export function Index() {
|
||||||
|
@ -81,6 +81,7 @@ const MarketPage = ({ id }: { id?: string }) => {
|
|||||||
return (
|
return (
|
||||||
<PageQueryContainer<Market, MarketVariables>
|
<PageQueryContainer<Market, MarketVariables>
|
||||||
query={MARKET_QUERY}
|
query={MARKET_QUERY}
|
||||||
|
data-testid="market"
|
||||||
options={{
|
options={{
|
||||||
variables: {
|
variables: {
|
||||||
marketId,
|
marketId,
|
||||||
|
@ -6,7 +6,7 @@ import {
|
|||||||
DealTicketContainer,
|
DealTicketContainer,
|
||||||
MarketInfoContainer,
|
MarketInfoContainer,
|
||||||
} from '@vegaprotocol/deal-ticket';
|
} from '@vegaprotocol/deal-ticket';
|
||||||
import { OrderListContainer } from '@vegaprotocol/order-list';
|
import { OrderListContainer } from '@vegaprotocol/orders';
|
||||||
import { TradesContainer } from '@vegaprotocol/trades';
|
import { TradesContainer } from '@vegaprotocol/trades';
|
||||||
import { PositionsContainer } from '@vegaprotocol/positions';
|
import { PositionsContainer } from '@vegaprotocol/positions';
|
||||||
import { OrderbookContainer } from '@vegaprotocol/market-depth';
|
import { OrderbookContainer } from '@vegaprotocol/market-depth';
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { Web3Container } from '../../components/web3-container';
|
import { Web3Container } from '../../components/web3-container';
|
||||||
import { t } from '@vegaprotocol/react-helpers';
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
import { PositionsContainer } from '@vegaprotocol/positions';
|
import { PositionsContainer } from '@vegaprotocol/positions';
|
||||||
import { OrderListContainer } from '@vegaprotocol/order-list';
|
import { OrderListContainer } from '@vegaprotocol/orders';
|
||||||
import { AccountsContainer } from '@vegaprotocol/accounts';
|
import { AccountsContainer } from '@vegaprotocol/accounts';
|
||||||
import { AnchorButton, Tab, Tabs } from '@vegaprotocol/ui-toolkit';
|
import { AnchorButton, Tab, Tabs } from '@vegaprotocol/ui-toolkit';
|
||||||
import { WithdrawalsContainer } from './withdrawals/withdrawals-container';
|
import { WithdrawalsContainer } from './withdrawals/withdrawals-container';
|
||||||
|
67
libs/deal-ticket/src/components/__generated__/MarketNames.ts
generated
Normal file
67
libs/deal-ticket/src/components/__generated__/MarketNames.ts
generated
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
// @generated
|
||||||
|
// This file was automatically generated and should not be edited.
|
||||||
|
|
||||||
|
// ====================================================
|
||||||
|
// GraphQL query operation: MarketNames
|
||||||
|
// ====================================================
|
||||||
|
|
||||||
|
export interface MarketNames_markets_tradableInstrument_instrument_metadata {
|
||||||
|
__typename: "InstrumentMetadata";
|
||||||
|
/**
|
||||||
|
* An arbitrary list of tags to associated to associate to the Instrument (string list)
|
||||||
|
*/
|
||||||
|
tags: string[] | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketNames_markets_tradableInstrument_instrument_product {
|
||||||
|
__typename: "Future";
|
||||||
|
/**
|
||||||
|
* String representing the quote (e.g. BTCUSD -> USD is quote)
|
||||||
|
*/
|
||||||
|
quoteName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketNames_markets_tradableInstrument_instrument {
|
||||||
|
__typename: "Instrument";
|
||||||
|
/**
|
||||||
|
* Metadata for this instrument
|
||||||
|
*/
|
||||||
|
metadata: MarketNames_markets_tradableInstrument_instrument_metadata;
|
||||||
|
/**
|
||||||
|
* A reference to or instance of a fully specified product, including all required product parameters for that product (Product union)
|
||||||
|
*/
|
||||||
|
product: MarketNames_markets_tradableInstrument_instrument_product;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketNames_markets_tradableInstrument {
|
||||||
|
__typename: "TradableInstrument";
|
||||||
|
/**
|
||||||
|
* An instance of or reference to a fully specified instrument.
|
||||||
|
*/
|
||||||
|
instrument: MarketNames_markets_tradableInstrument_instrument;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketNames_markets {
|
||||||
|
__typename: "Market";
|
||||||
|
/**
|
||||||
|
* Market ID
|
||||||
|
*/
|
||||||
|
id: string;
|
||||||
|
/**
|
||||||
|
* Market full name
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
/**
|
||||||
|
* An instance of or reference to a tradable instrument.
|
||||||
|
*/
|
||||||
|
tradableInstrument: MarketNames_markets_tradableInstrument;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarketNames {
|
||||||
|
/**
|
||||||
|
* One or more instruments that are trading on the VEGA network
|
||||||
|
*/
|
||||||
|
markets: MarketNames_markets[] | null;
|
||||||
|
}
|
@ -1,2 +1,3 @@
|
|||||||
export * from './DealTicketQuery';
|
export * from './DealTicketQuery';
|
||||||
export * from './MarketInfoQuery';
|
export * from './MarketInfoQuery';
|
||||||
|
export * from './MarketNames';
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import type { UseFormRegister } from 'react-hook-form';
|
import type { UseFormRegister } from 'react-hook-form';
|
||||||
import { OrderType } from '@vegaprotocol/wallet';
|
import { VegaWalletOrderType } from '@vegaprotocol/wallet';
|
||||||
import type { Order } from '../utils/get-default-order';
|
import type { Order } from '@vegaprotocol/orders';
|
||||||
import { DealTicketMarketAmount } from './deal-ticket-market-amount';
|
import { DealTicketMarketAmount } from './deal-ticket-market-amount';
|
||||||
import { DealTicketLimitAmount } from './deal-ticket-limit-amount';
|
import { DealTicketLimitAmount } from './deal-ticket-limit-amount';
|
||||||
|
|
||||||
export interface DealTicketAmountProps {
|
export interface DealTicketAmountProps {
|
||||||
orderType: OrderType;
|
orderType: VegaWalletOrderType;
|
||||||
step: number;
|
step: number;
|
||||||
register: UseFormRegister<Order>;
|
register: UseFormRegister<Order>;
|
||||||
quoteName: string;
|
quoteName: string;
|
||||||
@ -17,9 +17,9 @@ export const DealTicketAmount = ({
|
|||||||
...props
|
...props
|
||||||
}: DealTicketAmountProps) => {
|
}: DealTicketAmountProps) => {
|
||||||
switch (orderType) {
|
switch (orderType) {
|
||||||
case OrderType.Market:
|
case VegaWalletOrderType.Market:
|
||||||
return <DealTicketMarketAmount {...props} />;
|
return <DealTicketMarketAmount {...props} />;
|
||||||
case OrderType.Limit:
|
case VegaWalletOrderType.Limit:
|
||||||
return <DealTicketLimitAmount {...props} />;
|
return <DealTicketLimitAmount {...props} />;
|
||||||
default: {
|
default: {
|
||||||
throw new Error('Invalid ticket type');
|
throw new Error('Invalid ticket type');
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { FormGroup, Input } from '@vegaprotocol/ui-toolkit';
|
import { FormGroup, Input } from '@vegaprotocol/ui-toolkit';
|
||||||
import { t } from '@vegaprotocol/react-helpers';
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
import { validateSize } from '../utils/validate-size';
|
import { validateSize } from '@vegaprotocol/orders';
|
||||||
import type { DealTicketAmountProps } from './deal-ticket-amount';
|
import type { DealTicketAmountProps } from './deal-ticket-amount';
|
||||||
|
|
||||||
export type DealTicketLimitAmountProps = Omit<
|
export type DealTicketLimitAmountProps = Omit<
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import { useEffect, useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Dialog, Intent } from '@vegaprotocol/ui-toolkit';
|
import { VegaTransactionDialog, VegaTxStatus } from '@vegaprotocol/wallet';
|
||||||
import { OrderStatus } from '@vegaprotocol/types';
|
|
||||||
import { VegaOrderTransactionDialog, VegaTxStatus } from '@vegaprotocol/wallet';
|
|
||||||
import { DealTicket } from './deal-ticket';
|
import { DealTicket } from './deal-ticket';
|
||||||
import { useOrderSubmit } from '../hooks/use-order-submit';
|
|
||||||
import type { DealTicketQuery_market } from './__generated__/DealTicketQuery';
|
import type { DealTicketQuery_market } from './__generated__/DealTicketQuery';
|
||||||
|
import { useOrderSubmit } from '@vegaprotocol/orders';
|
||||||
|
import { OrderStatus } from '@vegaprotocol/types';
|
||||||
|
|
||||||
export interface DealTicketManagerProps {
|
export interface DealTicketManagerProps {
|
||||||
market: DealTicketQuery_market;
|
market: DealTicketQuery_market;
|
||||||
@ -18,43 +17,20 @@ export const DealTicketManager = ({
|
|||||||
}: DealTicketManagerProps) => {
|
}: DealTicketManagerProps) => {
|
||||||
const [orderDialogOpen, setOrderDialogOpen] = useState(false);
|
const [orderDialogOpen, setOrderDialogOpen] = useState(false);
|
||||||
const { submit, transaction, finalizedOrder, reset } = useOrderSubmit(market);
|
const { submit, transaction, finalizedOrder, reset } = useOrderSubmit(market);
|
||||||
|
const getDialogTitle = (status?: string) => {
|
||||||
const getDialogIntent = (status: VegaTxStatus) => {
|
switch (status) {
|
||||||
if (finalizedOrder) {
|
case OrderStatus.Active:
|
||||||
if (
|
return 'Order submitted';
|
||||||
finalizedOrder.status === OrderStatus.Active ||
|
case OrderStatus.Filled:
|
||||||
finalizedOrder.status === OrderStatus.Filled ||
|
return 'Order filled';
|
||||||
finalizedOrder.status === OrderStatus.PartiallyFilled
|
case OrderStatus.PartiallyFilled:
|
||||||
) {
|
return 'Order partially filled';
|
||||||
return Intent.Success;
|
case OrderStatus.Parked:
|
||||||
|
return 'Order parked';
|
||||||
|
default:
|
||||||
|
return 'Submission failed';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (finalizedOrder.status === OrderStatus.Parked) {
|
|
||||||
return Intent.Warning;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Intent.Danger;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === VegaTxStatus.Requested) {
|
|
||||||
return Intent.Warning;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === VegaTxStatus.Error) {
|
|
||||||
return Intent.Danger;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Intent.None;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (transaction.status !== VegaTxStatus.Default || finalizedOrder) {
|
|
||||||
setOrderDialogOpen(true);
|
|
||||||
} else {
|
|
||||||
setOrderDialogOpen(false);
|
|
||||||
}
|
|
||||||
}, [finalizedOrder, transaction.status]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{children || (
|
{children || (
|
||||||
@ -69,23 +45,15 @@ export const DealTicketManager = ({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<Dialog
|
<VegaTransactionDialog
|
||||||
open={orderDialogOpen}
|
key={`submit-order-dialog-${transaction.txHash}`}
|
||||||
onChange={(isOpen) => {
|
orderDialogOpen={orderDialogOpen}
|
||||||
setOrderDialogOpen(isOpen);
|
setOrderDialogOpen={setOrderDialogOpen}
|
||||||
|
|
||||||
// If closing reset
|
|
||||||
if (!isOpen) {
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
intent={getDialogIntent(transaction.status)}
|
|
||||||
>
|
|
||||||
<VegaOrderTransactionDialog
|
|
||||||
transaction={transaction}
|
|
||||||
finalizedOrder={finalizedOrder}
|
finalizedOrder={finalizedOrder}
|
||||||
|
transaction={transaction}
|
||||||
|
reset={reset}
|
||||||
|
title={getDialogTitle(finalizedOrder?.status)}
|
||||||
/>
|
/>
|
||||||
</Dialog>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { FormGroup, Input } from '@vegaprotocol/ui-toolkit';
|
import { FormGroup, Input } from '@vegaprotocol/ui-toolkit';
|
||||||
import { t } from '@vegaprotocol/react-helpers';
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
import { validateSize } from '../utils/validate-size';
|
import { validateSize } from '@vegaprotocol/orders';
|
||||||
import type { DealTicketAmountProps } from './deal-ticket-amount';
|
import type { DealTicketAmountProps } from './deal-ticket-amount';
|
||||||
|
|
||||||
export type DealTicketMarketAmountProps = Omit<
|
export type DealTicketMarketAmountProps = Omit<
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {
|
import {
|
||||||
VegaWalletContext,
|
VegaWalletContext,
|
||||||
OrderTimeInForce,
|
VegaWalletOrderTimeInForce,
|
||||||
OrderType,
|
VegaWalletOrderType,
|
||||||
} from '@vegaprotocol/wallet';
|
} from '@vegaprotocol/wallet';
|
||||||
import { addDecimal } from '@vegaprotocol/react-helpers';
|
import { addDecimal } from '@vegaprotocol/react-helpers';
|
||||||
import { fireEvent, render, screen, act } from '@testing-library/react';
|
import { fireEvent, render, screen, act } from '@testing-library/react';
|
||||||
@ -64,7 +64,7 @@ it('Displays ticket defaults', () => {
|
|||||||
|
|
||||||
// Assert defaults are used
|
// Assert defaults are used
|
||||||
expect(
|
expect(
|
||||||
screen.getByTestId(`order-type-${OrderType.Market}-selected`)
|
screen.getByTestId(`order-type-${VegaWalletOrderType.Market}-selected`)
|
||||||
).toBeInTheDocument();
|
).toBeInTheDocument();
|
||||||
expect(
|
expect(
|
||||||
screen.queryByTestId('order-side-SIDE_BUY-selected')
|
screen.queryByTestId('order-side-SIDE_BUY-selected')
|
||||||
@ -75,7 +75,9 @@ it('Displays ticket defaults', () => {
|
|||||||
expect(screen.getByTestId('order-size')).toHaveDisplayValue(
|
expect(screen.getByTestId('order-size')).toHaveDisplayValue(
|
||||||
String(1 / Math.pow(10, market.positionDecimalPlaces))
|
String(1 / Math.pow(10, market.positionDecimalPlaces))
|
||||||
);
|
);
|
||||||
expect(screen.getByTestId('order-tif')).toHaveValue(OrderTimeInForce.IOC);
|
expect(screen.getByTestId('order-tif')).toHaveValue(
|
||||||
|
VegaWalletOrderTimeInForce.IOC
|
||||||
|
);
|
||||||
|
|
||||||
// Assert last price is shown
|
// Assert last price is shown
|
||||||
expect(screen.getByTestId('last-price')).toHaveTextContent(
|
expect(screen.getByTestId('last-price')).toHaveTextContent(
|
||||||
@ -101,9 +103,11 @@ it('Can edit deal ticket', async () => {
|
|||||||
expect(screen.getByTestId('order-size')).toHaveDisplayValue('200');
|
expect(screen.getByTestId('order-size')).toHaveDisplayValue('200');
|
||||||
|
|
||||||
fireEvent.change(screen.getByTestId('order-tif'), {
|
fireEvent.change(screen.getByTestId('order-tif'), {
|
||||||
target: { value: OrderTimeInForce.IOC },
|
target: { value: VegaWalletOrderTimeInForce.IOC },
|
||||||
});
|
});
|
||||||
expect(screen.getByTestId('order-tif')).toHaveValue(OrderTimeInForce.IOC);
|
expect(screen.getByTestId('order-tif')).toHaveValue(
|
||||||
|
VegaWalletOrderTimeInForce.IOC
|
||||||
|
);
|
||||||
|
|
||||||
// Switch to limit order
|
// Switch to limit order
|
||||||
fireEvent.click(screen.getByTestId('order-type-TYPE_LIMIT'));
|
fireEvent.click(screen.getByTestId('order-type-TYPE_LIMIT'));
|
||||||
@ -113,7 +117,7 @@ it('Can edit deal ticket', async () => {
|
|||||||
|
|
||||||
// Check all TIF options shown
|
// Check all TIF options shown
|
||||||
expect(screen.getByTestId('order-tif').children).toHaveLength(
|
expect(screen.getByTestId('order-tif').children).toHaveLength(
|
||||||
Object.keys(OrderTimeInForce).length
|
Object.keys(VegaWalletOrderTimeInForce).length
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -130,26 +134,34 @@ it('Handles TIF select box dependent on order type', () => {
|
|||||||
// Switch to limit order and check all TIF options shown
|
// Switch to limit order and check all TIF options shown
|
||||||
fireEvent.click(screen.getByTestId('order-type-TYPE_LIMIT'));
|
fireEvent.click(screen.getByTestId('order-type-TYPE_LIMIT'));
|
||||||
expect(screen.getByTestId('order-tif').children).toHaveLength(
|
expect(screen.getByTestId('order-tif').children).toHaveLength(
|
||||||
Object.keys(OrderTimeInForce).length
|
Object.keys(VegaWalletOrderTimeInForce).length
|
||||||
);
|
);
|
||||||
|
|
||||||
// Change to GTC
|
// Change to GTC
|
||||||
fireEvent.change(screen.getByTestId('order-tif'), {
|
fireEvent.change(screen.getByTestId('order-tif'), {
|
||||||
target: { value: OrderTimeInForce.GTC },
|
target: { value: VegaWalletOrderTimeInForce.GTC },
|
||||||
});
|
});
|
||||||
expect(screen.getByTestId('order-tif')).toHaveValue(OrderTimeInForce.GTC);
|
expect(screen.getByTestId('order-tif')).toHaveValue(
|
||||||
|
VegaWalletOrderTimeInForce.GTC
|
||||||
|
);
|
||||||
|
|
||||||
// Switch back to market order and TIF should now be IOC
|
// Switch back to market order and TIF should now be IOC
|
||||||
fireEvent.click(screen.getByTestId('order-type-TYPE_MARKET'));
|
fireEvent.click(screen.getByTestId('order-type-TYPE_MARKET'));
|
||||||
expect(screen.getByTestId('order-tif')).toHaveValue(OrderTimeInForce.IOC);
|
expect(screen.getByTestId('order-tif')).toHaveValue(
|
||||||
|
VegaWalletOrderTimeInForce.IOC
|
||||||
|
);
|
||||||
|
|
||||||
// Switch tif to FOK
|
// Switch tif to FOK
|
||||||
fireEvent.change(screen.getByTestId('order-tif'), {
|
fireEvent.change(screen.getByTestId('order-tif'), {
|
||||||
target: { value: OrderTimeInForce.FOK },
|
target: { value: VegaWalletOrderTimeInForce.FOK },
|
||||||
});
|
});
|
||||||
expect(screen.getByTestId('order-tif')).toHaveValue(OrderTimeInForce.FOK);
|
expect(screen.getByTestId('order-tif')).toHaveValue(
|
||||||
|
VegaWalletOrderTimeInForce.FOK
|
||||||
|
);
|
||||||
|
|
||||||
// Change back to limit and check we are still on FOK
|
// Change back to limit and check we are still on FOK
|
||||||
fireEvent.click(screen.getByTestId('order-type-TYPE_LIMIT'));
|
fireEvent.click(screen.getByTestId('order-type-TYPE_LIMIT'));
|
||||||
expect(screen.getByTestId('order-tif')).toHaveValue(OrderTimeInForce.FOK);
|
expect(screen.getByTestId('order-tif')).toHaveValue(
|
||||||
|
VegaWalletOrderTimeInForce.FOK
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
import { useForm, Controller } from 'react-hook-form';
|
import { useForm, Controller } from 'react-hook-form';
|
||||||
import { OrderType, OrderTimeInForce } from '@vegaprotocol/wallet';
|
import {
|
||||||
|
VegaWalletOrderType,
|
||||||
|
VegaWalletOrderTimeInForce,
|
||||||
|
} from '@vegaprotocol/wallet';
|
||||||
import { t, addDecimal, toDecimal } from '@vegaprotocol/react-helpers';
|
import { t, addDecimal, toDecimal } from '@vegaprotocol/react-helpers';
|
||||||
import { Button, InputError } from '@vegaprotocol/ui-toolkit';
|
import { Button, InputError } from '@vegaprotocol/ui-toolkit';
|
||||||
import { TypeSelector } from './type-selector';
|
import { TypeSelector } from './type-selector';
|
||||||
import { SideSelector } from './side-selector';
|
import { SideSelector } from './side-selector';
|
||||||
import { DealTicketAmount } from './deal-ticket-amount';
|
import { DealTicketAmount } from './deal-ticket-amount';
|
||||||
import { TimeInForceSelector } from './time-in-force-selector';
|
import { TimeInForceSelector } from './time-in-force-selector';
|
||||||
import { useOrderValidation } from '../hooks/use-order-validation';
|
|
||||||
import type { DealTicketQuery_market } from './__generated__/DealTicketQuery';
|
import type { DealTicketQuery_market } from './__generated__/DealTicketQuery';
|
||||||
import type { Order } from '../utils/get-default-order';
|
|
||||||
import { getDefaultOrder } from '../utils/get-default-order';
|
|
||||||
import { ExpirySelector } from './expiry-selector';
|
import { ExpirySelector } from './expiry-selector';
|
||||||
|
import type { Order } from '@vegaprotocol/orders';
|
||||||
|
import { getDefaultOrder, useOrderValidation } from '@vegaprotocol/orders';
|
||||||
|
|
||||||
export type TransactionStatus = 'default' | 'pending';
|
export type TransactionStatus = 'default' | 'pending';
|
||||||
|
|
||||||
@ -97,8 +99,8 @@ export const DealTicket = ({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
{orderType === OrderType.Limit &&
|
{orderType === VegaWalletOrderType.Limit &&
|
||||||
orderTimeInForce === OrderTimeInForce.GTT && (
|
orderTimeInForce === VegaWalletOrderTimeInForce.GTT && (
|
||||||
<Controller
|
<Controller
|
||||||
name="expiration"
|
name="expiration"
|
||||||
control={control}
|
control={control}
|
||||||
|
@ -10,3 +10,4 @@ export * from './info-market';
|
|||||||
export * from './side-selector';
|
export * from './side-selector';
|
||||||
export * from './time-in-force-selector';
|
export * from './time-in-force-selector';
|
||||||
export * from './type-selector';
|
export * from './type-selector';
|
||||||
|
export * from './market-selector';
|
||||||
|
292
libs/deal-ticket/src/components/market-selector.tsx
Normal file
292
libs/deal-ticket/src/components/market-selector.tsx
Normal file
@ -0,0 +1,292 @@
|
|||||||
|
import React, {
|
||||||
|
useCallback,
|
||||||
|
useState,
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
useMemo,
|
||||||
|
} from 'react';
|
||||||
|
import { gql, useQuery } from '@apollo/client';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import type { DealTicketQuery_market } from './__generated__';
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Dialog,
|
||||||
|
Icon,
|
||||||
|
Input,
|
||||||
|
Loader,
|
||||||
|
Splash,
|
||||||
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
|
import {
|
||||||
|
t,
|
||||||
|
useScreenDimensions,
|
||||||
|
useOutsideClick,
|
||||||
|
} from '@vegaprotocol/react-helpers';
|
||||||
|
import type {
|
||||||
|
MarketNames,
|
||||||
|
MarketNames_markets,
|
||||||
|
} from './__generated__/MarketNames';
|
||||||
|
import { IconNames } from '@blueprintjs/icons';
|
||||||
|
|
||||||
|
export const MARKET_NAMES_QUERY = gql`
|
||||||
|
query MarketNames {
|
||||||
|
markets {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
tradableInstrument {
|
||||||
|
instrument {
|
||||||
|
metadata {
|
||||||
|
tags
|
||||||
|
}
|
||||||
|
product {
|
||||||
|
... on Future {
|
||||||
|
quoteName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
market: DealTicketQuery_market;
|
||||||
|
setMarket: (marketId: string) => void;
|
||||||
|
ItemRenderer?: React.FC<{ market: MarketNames_markets }>;
|
||||||
|
}
|
||||||
|
|
||||||
|
function escapeRegExp(str: string) {
|
||||||
|
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MarketSelector = ({ market, setMarket, ItemRenderer }: Props) => {
|
||||||
|
const { isMobile } = useScreenDimensions();
|
||||||
|
const contRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||||
|
const arrowButtonRef = useRef<HTMLButtonElement | null>(null);
|
||||||
|
const [skip, setSkip] = useState(true);
|
||||||
|
const [results, setResults] = useState<MarketNames_markets[]>([]);
|
||||||
|
const [showPane, setShowPane] = useState(false);
|
||||||
|
const [lookup, setLookup] = useState(market.name || '');
|
||||||
|
const [dialogContent, setDialogContent] = useState<React.ReactNode | null>(
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
const { data, loading, error } = useQuery<MarketNames>(MARKET_NAMES_QUERY, {
|
||||||
|
skip,
|
||||||
|
});
|
||||||
|
|
||||||
|
const outsideClickCb = useCallback(() => {
|
||||||
|
if (!isMobile) {
|
||||||
|
setShowPane(false);
|
||||||
|
}
|
||||||
|
}, [setShowPane, isMobile]);
|
||||||
|
|
||||||
|
useOutsideClick({ refs: [contRef, arrowButtonRef], func: outsideClickCb });
|
||||||
|
|
||||||
|
const handleOnChange = useCallback(
|
||||||
|
(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const {
|
||||||
|
target: { value },
|
||||||
|
} = event;
|
||||||
|
setLookup(value);
|
||||||
|
setShowPane(true);
|
||||||
|
if (value) {
|
||||||
|
setSkip(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[setLookup, setShowPane, setSkip]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleMarketSelect = useCallback(
|
||||||
|
({ id, name }) => {
|
||||||
|
setLookup(name);
|
||||||
|
setShowPane(false);
|
||||||
|
setMarket(id);
|
||||||
|
inputRef.current?.focus();
|
||||||
|
},
|
||||||
|
[setLookup, setShowPane, setMarket, inputRef]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleItemKeyDown = useCallback(
|
||||||
|
(
|
||||||
|
event: React.KeyboardEvent,
|
||||||
|
market: MarketNames_markets,
|
||||||
|
index: number
|
||||||
|
) => {
|
||||||
|
switch (event.key) {
|
||||||
|
case 'ArrowDown':
|
||||||
|
if (index < results.length - 1) {
|
||||||
|
(contRef.current?.children[index + 1] as HTMLDivElement).focus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'ArrowUp':
|
||||||
|
if (!index) {
|
||||||
|
inputRef.current?.focus();
|
||||||
|
inputRef.current?.setSelectionRange(
|
||||||
|
inputRef.current?.value.length,
|
||||||
|
inputRef.current?.value.length
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
(contRef.current?.children[index - 1] as HTMLDivElement).focus();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'Enter':
|
||||||
|
handleMarketSelect(market);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[results, handleMarketSelect]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleInputKeyDown = useCallback(
|
||||||
|
(event: React.KeyboardEvent) => {
|
||||||
|
if (event.key === 'ArrowDown') {
|
||||||
|
(contRef.current?.children[0] as HTMLDivElement).focus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[contRef]
|
||||||
|
);
|
||||||
|
|
||||||
|
const handleOnBlur = useCallback(() => {
|
||||||
|
console.log('lookup, showPane', lookup, showPane);
|
||||||
|
if (!lookup && !showPane) {
|
||||||
|
console.log(
|
||||||
|
'2 lookup, showPane, market.name',
|
||||||
|
lookup,
|
||||||
|
showPane,
|
||||||
|
market.name
|
||||||
|
);
|
||||||
|
setLookup(market.name);
|
||||||
|
}
|
||||||
|
}, [market, lookup, showPane, setLookup]);
|
||||||
|
|
||||||
|
const openPane = useCallback(() => {
|
||||||
|
setShowPane(!showPane);
|
||||||
|
setSkip(false);
|
||||||
|
inputRef.current?.focus();
|
||||||
|
}, [showPane, setShowPane, setSkip, inputRef]);
|
||||||
|
|
||||||
|
const handleDialogOnchange = useCallback(
|
||||||
|
(isOpen) => {
|
||||||
|
setShowPane(isOpen);
|
||||||
|
if (!isOpen) {
|
||||||
|
setLookup(lookup || market.name);
|
||||||
|
inputRef.current?.focus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[setShowPane, lookup, setLookup, market.name, inputRef]
|
||||||
|
);
|
||||||
|
|
||||||
|
const selectorContent = useMemo(() => {
|
||||||
|
return (
|
||||||
|
<div className="relative flex flex-col">
|
||||||
|
<div className="relative w-full min-h-[30px] dark:bg-black">
|
||||||
|
<Input
|
||||||
|
className="h-[30px] w-[calc(100%-20px)] border-none dark:bg-black"
|
||||||
|
ref={inputRef}
|
||||||
|
tabIndex={0}
|
||||||
|
value={lookup}
|
||||||
|
placeholder={t('Search')}
|
||||||
|
onChange={handleOnChange}
|
||||||
|
onKeyDown={handleInputKeyDown}
|
||||||
|
onBlur={handleOnBlur}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
className="absolute self-end top-[7px] right-0 z-10"
|
||||||
|
variant="inline-link"
|
||||||
|
onClick={openPane}
|
||||||
|
ref={arrowButtonRef}
|
||||||
|
data-testid="arrow-button"
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
name={IconNames.ARROW_DOWN}
|
||||||
|
className={classNames('fill-current transition-transform', {
|
||||||
|
'rotate-180': showPane,
|
||||||
|
})}
|
||||||
|
size={16}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<hr className="md:hidden mb-5" />
|
||||||
|
<div
|
||||||
|
className={classNames(
|
||||||
|
'md:absolute flex flex-col top-[30px] z-10 md:drop-shadow-md md:border-1 md:border-black md:dark:border-white bg-white dark:bg-black text-black dark:text-white min-w-full md:max-h-[200px] overflow-y-auto',
|
||||||
|
showPane ? 'block' : 'hidden'
|
||||||
|
)}
|
||||||
|
data-testid="market-pane"
|
||||||
|
>
|
||||||
|
{loading && <Loader />}
|
||||||
|
{error && (
|
||||||
|
<Splash>{t(`Something went wrong: ${error.message}`)}</Splash>
|
||||||
|
)}
|
||||||
|
<div ref={contRef} className="w-full">
|
||||||
|
{results.map((market, i) => (
|
||||||
|
<div
|
||||||
|
role="button"
|
||||||
|
tabIndex={0}
|
||||||
|
key={market.id}
|
||||||
|
className="cursor-pointer focus:bg-white-95 focus:outline-0 dark:focus:bg-black-80 px-20 py-5"
|
||||||
|
onClick={() => handleMarketSelect(market)}
|
||||||
|
onKeyDown={(e) => handleItemKeyDown(e, market, i)}
|
||||||
|
>
|
||||||
|
{ItemRenderer ? <ItemRenderer market={market} /> : market.name}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}, [
|
||||||
|
ItemRenderer,
|
||||||
|
error,
|
||||||
|
handleInputKeyDown,
|
||||||
|
handleItemKeyDown,
|
||||||
|
handleMarketSelect,
|
||||||
|
handleOnBlur,
|
||||||
|
handleOnChange,
|
||||||
|
loading,
|
||||||
|
lookup,
|
||||||
|
openPane,
|
||||||
|
results,
|
||||||
|
showPane,
|
||||||
|
]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setResults(
|
||||||
|
data?.markets?.filter((item: MarketNames_markets) =>
|
||||||
|
item.name.match(new RegExp(escapeRegExp(lookup), 'i'))
|
||||||
|
) || []
|
||||||
|
);
|
||||||
|
}, [data, lookup]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
inputRef.current?.focus();
|
||||||
|
}, [inputRef]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (showPane && isMobile) {
|
||||||
|
setDialogContent(selectorContent);
|
||||||
|
inputRef.current?.focus();
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
} else {
|
||||||
|
setDialogContent(null);
|
||||||
|
}
|
||||||
|
}, [selectorContent, showPane, isMobile, setDialogContent]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{!dialogContent && selectorContent}
|
||||||
|
<Dialog
|
||||||
|
titleClassNames="uppercase font-alpha"
|
||||||
|
contentClassNames="left-[0px] top-[99px] h-[calc(100%-99px)] border-0 translate-x-[0] translate-y-[0] border-none overflow-y-auto"
|
||||||
|
title={t('Select Market')}
|
||||||
|
open={Boolean(dialogContent)}
|
||||||
|
onChange={handleDialogOnchange}
|
||||||
|
>
|
||||||
|
{dialogContent}
|
||||||
|
</Dialog>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
@ -1,16 +1,16 @@
|
|||||||
import { FormGroup } from '@vegaprotocol/ui-toolkit';
|
import { FormGroup } from '@vegaprotocol/ui-toolkit';
|
||||||
import { OrderSide } from '@vegaprotocol/wallet';
|
import { VegaWalletOrderSide } from '@vegaprotocol/wallet';
|
||||||
import { Toggle } from '@vegaprotocol/ui-toolkit';
|
import { Toggle } from '@vegaprotocol/ui-toolkit';
|
||||||
import { t } from '@vegaprotocol/react-helpers';
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
|
|
||||||
interface SideSelectorProps {
|
interface SideSelectorProps {
|
||||||
value: OrderSide;
|
value: VegaWalletOrderSide;
|
||||||
onSelect: (side: OrderSide) => void;
|
onSelect: (side: VegaWalletOrderSide) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SideSelector = ({ value, onSelect }: SideSelectorProps) => {
|
export const SideSelector = ({ value, onSelect }: SideSelectorProps) => {
|
||||||
const toggles = Object.entries(OrderSide).map(([label, value]) => ({
|
const toggles = Object.entries(VegaWalletOrderSide).map(([label, value]) => ({
|
||||||
label,
|
label: label === 'Buy' ? 'Long' : 'Short',
|
||||||
value,
|
value,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ export const SideSelector = ({ value, onSelect }: SideSelectorProps) => {
|
|||||||
name="order-side"
|
name="order-side"
|
||||||
toggles={toggles}
|
toggles={toggles}
|
||||||
checkedValue={value}
|
checkedValue={value}
|
||||||
onChange={(e) => onSelect(e.target.value as OrderSide)}
|
onChange={(e) => onSelect(e.target.value as VegaWalletOrderSide)}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
);
|
);
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
import { FormGroup, Select } from '@vegaprotocol/ui-toolkit';
|
import { FormGroup, Select } from '@vegaprotocol/ui-toolkit';
|
||||||
import { OrderTimeInForce, OrderType } from '@vegaprotocol/wallet';
|
import {
|
||||||
|
VegaWalletOrderTimeInForce,
|
||||||
|
VegaWalletOrderType,
|
||||||
|
} from '@vegaprotocol/wallet';
|
||||||
import { t } from '@vegaprotocol/react-helpers';
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
|
|
||||||
interface TimeInForceSelectorProps {
|
interface TimeInForceSelectorProps {
|
||||||
value: OrderTimeInForce;
|
value: VegaWalletOrderTimeInForce;
|
||||||
orderType: OrderType;
|
orderType: VegaWalletOrderType;
|
||||||
onSelect: (tif: OrderTimeInForce) => void;
|
onSelect: (tif: VegaWalletOrderTimeInForce) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TimeInForceSelector = ({
|
export const TimeInForceSelector = ({
|
||||||
@ -14,12 +17,12 @@ export const TimeInForceSelector = ({
|
|||||||
onSelect,
|
onSelect,
|
||||||
}: TimeInForceSelectorProps) => {
|
}: TimeInForceSelectorProps) => {
|
||||||
const options =
|
const options =
|
||||||
orderType === OrderType.Limit
|
orderType === VegaWalletOrderType.Limit
|
||||||
? Object.entries(OrderTimeInForce)
|
? Object.entries(VegaWalletOrderTimeInForce)
|
||||||
: Object.entries(OrderTimeInForce).filter(
|
: Object.entries(VegaWalletOrderTimeInForce).filter(
|
||||||
([_, timeInForce]) =>
|
([_, timeInForce]) =>
|
||||||
timeInForce === OrderTimeInForce.FOK ||
|
timeInForce === VegaWalletOrderTimeInForce.FOK ||
|
||||||
timeInForce === OrderTimeInForce.IOC
|
timeInForce === VegaWalletOrderTimeInForce.IOC
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -27,7 +30,7 @@ export const TimeInForceSelector = ({
|
|||||||
<Select
|
<Select
|
||||||
id="select-time-in-force"
|
id="select-time-in-force"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={(e) => onSelect(e.target.value as OrderTimeInForce)}
|
onChange={(e) => onSelect(e.target.value as VegaWalletOrderTimeInForce)}
|
||||||
className="w-full"
|
className="w-full"
|
||||||
data-testid="order-tif"
|
data-testid="order-tif"
|
||||||
>
|
>
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import { FormGroup } from '@vegaprotocol/ui-toolkit';
|
import { FormGroup } from '@vegaprotocol/ui-toolkit';
|
||||||
import { t } from '@vegaprotocol/react-helpers';
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
import { OrderType } from '@vegaprotocol/wallet';
|
import { VegaWalletOrderType } from '@vegaprotocol/wallet';
|
||||||
import { Toggle } from '@vegaprotocol/ui-toolkit';
|
import { Toggle } from '@vegaprotocol/ui-toolkit';
|
||||||
|
|
||||||
interface TypeSelectorProps {
|
interface TypeSelectorProps {
|
||||||
value: OrderType;
|
value: VegaWalletOrderType;
|
||||||
onSelect: (type: OrderType) => void;
|
onSelect: (type: VegaWalletOrderType) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const toggles = Object.entries(OrderType).map(([label, value]) => ({
|
const toggles = Object.entries(VegaWalletOrderType).map(([label, value]) => ({
|
||||||
label,
|
label,
|
||||||
value,
|
value,
|
||||||
}));
|
}));
|
||||||
@ -21,7 +21,7 @@ export const TypeSelector = ({ value, onSelect }: TypeSelectorProps) => {
|
|||||||
name="order-type"
|
name="order-type"
|
||||||
toggles={toggles}
|
toggles={toggles}
|
||||||
checkedValue={value}
|
checkedValue={value}
|
||||||
onChange={(e) => onSelect(e.target.value as OrderType)}
|
onChange={(e) => onSelect(e.target.value as VegaWalletOrderType)}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
);
|
);
|
||||||
|
114
libs/deal-ticket/src/hooks/__generated__/OrderEvent.ts
generated
114
libs/deal-ticket/src/hooks/__generated__/OrderEvent.ts
generated
@ -1,114 +0,0 @@
|
|||||||
/* tslint:disable */
|
|
||||||
/* eslint-disable */
|
|
||||||
// @generated
|
|
||||||
// This file was automatically generated and should not be edited.
|
|
||||||
|
|
||||||
import { BusEventType, OrderType, OrderStatus, OrderRejectionReason } from "@vegaprotocol/types";
|
|
||||||
|
|
||||||
// ====================================================
|
|
||||||
// GraphQL subscription operation: OrderEvent
|
|
||||||
// ====================================================
|
|
||||||
|
|
||||||
export interface OrderEvent_busEvents_event_TimeUpdate {
|
|
||||||
__typename: "TimeUpdate" | "MarketEvent" | "TransferResponses" | "PositionResolution" | "Trade" | "Account" | "Party" | "MarginLevels" | "Proposal" | "Vote" | "MarketData" | "NodeSignature" | "LossSocialization" | "SettlePosition" | "Market" | "Asset" | "MarketTick" | "SettleDistressed" | "AuctionEvent" | "RiskFactor" | "Deposit" | "Withdrawal" | "OracleSpec" | "LiquidityProvision";
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface OrderEvent_busEvents_event_Order_market {
|
|
||||||
__typename: "Market";
|
|
||||||
/**
|
|
||||||
* Market full name
|
|
||||||
*/
|
|
||||||
name: string;
|
|
||||||
/**
|
|
||||||
* decimalPlaces indicates the number of decimal places that an integer must be shifted by in order to get a correct
|
|
||||||
* number denominated in the currency of the Market. (uint64)
|
|
||||||
*
|
|
||||||
* Examples:
|
|
||||||
* Currency Balance decimalPlaces Real Balance
|
|
||||||
* GBP 100 0 GBP 100
|
|
||||||
* GBP 100 2 GBP 1.00
|
|
||||||
* GBP 100 4 GBP 0.01
|
|
||||||
* GBP 1 4 GBP 0.0001 ( 0.01p )
|
|
||||||
*
|
|
||||||
* GBX (pence) 100 0 GBP 1.00 (100p )
|
|
||||||
* GBX (pence) 100 2 GBP 0.01 ( 1p )
|
|
||||||
* GBX (pence) 100 4 GBP 0.0001 ( 0.01p )
|
|
||||||
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
|
|
||||||
*/
|
|
||||||
decimalPlaces: number;
|
|
||||||
/**
|
|
||||||
* positionDecimalPlaces indicated the number of decimal places that an integer must be shifted in order to get a correct size (uint64).
|
|
||||||
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
|
|
||||||
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
|
|
||||||
*/
|
|
||||||
positionDecimalPlaces: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface OrderEvent_busEvents_event_Order {
|
|
||||||
__typename: "Order";
|
|
||||||
/**
|
|
||||||
* Type the order type (defaults to PARTY)
|
|
||||||
*/
|
|
||||||
type: OrderType | null;
|
|
||||||
/**
|
|
||||||
* Hash of the order data
|
|
||||||
*/
|
|
||||||
id: string;
|
|
||||||
/**
|
|
||||||
* The status of an order, for example 'Active'
|
|
||||||
*/
|
|
||||||
status: OrderStatus;
|
|
||||||
/**
|
|
||||||
* Reason for the order to be rejected
|
|
||||||
*/
|
|
||||||
rejectionReason: OrderRejectionReason | null;
|
|
||||||
/**
|
|
||||||
* RFC3339Nano formatted date and time for when the order was created (timestamp)
|
|
||||||
*/
|
|
||||||
createdAt: string;
|
|
||||||
/**
|
|
||||||
* Total number of contracts that may be bought or sold (immutable) (uint64)
|
|
||||||
*/
|
|
||||||
size: string;
|
|
||||||
/**
|
|
||||||
* The worst price the order will trade at (e.g. buy for price or less, sell for price or more) (uint64)
|
|
||||||
*/
|
|
||||||
price: string;
|
|
||||||
/**
|
|
||||||
* The market the order is trading on (probably stored internally as a hash of the market details)
|
|
||||||
*/
|
|
||||||
market: OrderEvent_busEvents_event_Order_market | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type OrderEvent_busEvents_event = OrderEvent_busEvents_event_TimeUpdate | OrderEvent_busEvents_event_Order;
|
|
||||||
|
|
||||||
export interface OrderEvent_busEvents {
|
|
||||||
__typename: "BusEvent";
|
|
||||||
/**
|
|
||||||
* the id for this event
|
|
||||||
*/
|
|
||||||
eventId: string;
|
|
||||||
/**
|
|
||||||
* the block hash
|
|
||||||
*/
|
|
||||||
block: string;
|
|
||||||
/**
|
|
||||||
* the type of event we're dealing with
|
|
||||||
*/
|
|
||||||
type: BusEventType;
|
|
||||||
/**
|
|
||||||
* the payload - the wrapped event
|
|
||||||
*/
|
|
||||||
event: OrderEvent_busEvents_event;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface OrderEvent {
|
|
||||||
/**
|
|
||||||
* Subscribe to event data from the event bus
|
|
||||||
*/
|
|
||||||
busEvents: OrderEvent_busEvents[] | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface OrderEventVariables {
|
|
||||||
partyId: string;
|
|
||||||
}
|
|
@ -1,176 +0,0 @@
|
|||||||
import { MockedProvider } from '@apollo/client/testing';
|
|
||||||
import { act, renderHook } from '@testing-library/react-hooks';
|
|
||||||
import type { Order } from '../utils/get-default-order';
|
|
||||||
import type {
|
|
||||||
VegaKeyExtended,
|
|
||||||
VegaWalletContextShape,
|
|
||||||
} from '@vegaprotocol/wallet';
|
|
||||||
import { VegaTxStatus, VegaWalletContext } from '@vegaprotocol/wallet';
|
|
||||||
import { OrderSide, OrderTimeInForce, OrderType } from '@vegaprotocol/wallet';
|
|
||||||
import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
|
|
||||||
import type { ReactNode } from 'react';
|
|
||||||
import { useOrderSubmit } from './use-order-submit';
|
|
||||||
import type { DealTicketQuery_market } from '../components/__generated__/DealTicketQuery';
|
|
||||||
|
|
||||||
const defaultMarket: DealTicketQuery_market = {
|
|
||||||
__typename: 'Market',
|
|
||||||
id: 'market-id',
|
|
||||||
decimalPlaces: 2,
|
|
||||||
positionDecimalPlaces: 1,
|
|
||||||
tradingMode: MarketTradingMode.Continuous,
|
|
||||||
state: MarketState.Active,
|
|
||||||
tradableInstrument: {
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
instrument: {
|
|
||||||
__typename: 'Instrument',
|
|
||||||
product: {
|
|
||||||
__typename: 'Future',
|
|
||||||
quoteName: 'quote-name',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
depth: {
|
|
||||||
__typename: 'MarketDepth',
|
|
||||||
lastTrade: {
|
|
||||||
__typename: 'Trade',
|
|
||||||
price: '100',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const defaultWalletContext = {
|
|
||||||
keypair: null,
|
|
||||||
keypairs: [],
|
|
||||||
sendTx: jest.fn().mockReturnValue(Promise.resolve(null)),
|
|
||||||
connect: jest.fn(),
|
|
||||||
disconnect: jest.fn(),
|
|
||||||
selectPublicKey: jest.fn(),
|
|
||||||
connector: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
function setup(
|
|
||||||
context?: Partial<VegaWalletContextShape>,
|
|
||||||
market = defaultMarket
|
|
||||||
) {
|
|
||||||
const wrapper = ({ children }: { children: ReactNode }) => (
|
|
||||||
<MockedProvider>
|
|
||||||
<VegaWalletContext.Provider
|
|
||||||
value={{ ...defaultWalletContext, ...context }}
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</VegaWalletContext.Provider>
|
|
||||||
</MockedProvider>
|
|
||||||
);
|
|
||||||
return renderHook(() => useOrderSubmit(market), { wrapper });
|
|
||||||
}
|
|
||||||
|
|
||||||
it('Has the correct default state', () => {
|
|
||||||
const { result } = setup();
|
|
||||||
expect(typeof result.current.submit).toEqual('function');
|
|
||||||
expect(typeof result.current.reset).toEqual('function');
|
|
||||||
expect(result.current.transaction.status).toEqual(VegaTxStatus.Default);
|
|
||||||
expect(result.current.transaction.txHash).toEqual(null);
|
|
||||||
expect(result.current.transaction.error).toEqual(null);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should not sendTx if no keypair', async () => {
|
|
||||||
const mockSendTx = jest.fn();
|
|
||||||
const { result } = setup({ sendTx: mockSendTx, keypairs: [], keypair: null });
|
|
||||||
await act(async () => {
|
|
||||||
result.current.submit({} as Order);
|
|
||||||
});
|
|
||||||
expect(mockSendTx).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should not sendTx side is not specified', async () => {
|
|
||||||
const mockSendTx = jest.fn();
|
|
||||||
const keypair = {
|
|
||||||
pub: '0x123',
|
|
||||||
} as VegaKeyExtended;
|
|
||||||
const { result } = setup({
|
|
||||||
sendTx: mockSendTx,
|
|
||||||
keypairs: [keypair],
|
|
||||||
keypair,
|
|
||||||
});
|
|
||||||
await act(async () => {
|
|
||||||
result.current.submit({} as Order);
|
|
||||||
});
|
|
||||||
expect(mockSendTx).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Create an Id if a signature is returned', async () => {
|
|
||||||
const signature =
|
|
||||||
'597a7706491e6523c091bab1e4d655b62c45a224e80f6cd92ac366aa5dd9a070cc7dd3c6919cb07b81334b876c662dd43bdbe5e827c8baa17a089feb654fab0b';
|
|
||||||
const expectedId =
|
|
||||||
'2fe09b0e2e6ed35f8883802629c7d609d3cc2fc9ce3cec0b7824a0d581bd3747';
|
|
||||||
const successObj = {
|
|
||||||
tx: {
|
|
||||||
inputData: 'input-data',
|
|
||||||
signature: {
|
|
||||||
algo: 'algo',
|
|
||||||
version: 1,
|
|
||||||
value: signature,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
txHash: '0x123',
|
|
||||||
};
|
|
||||||
const mockSendTx = jest.fn().mockReturnValue(Promise.resolve(successObj));
|
|
||||||
const keypair = {
|
|
||||||
pub: '0x123',
|
|
||||||
} as VegaKeyExtended;
|
|
||||||
const { result } = setup({
|
|
||||||
sendTx: mockSendTx,
|
|
||||||
keypairs: [keypair],
|
|
||||||
keypair,
|
|
||||||
});
|
|
||||||
await act(async () => {
|
|
||||||
result.current.submit({
|
|
||||||
type: OrderType.Market,
|
|
||||||
side: OrderSide.Buy,
|
|
||||||
size: '1',
|
|
||||||
timeInForce: OrderTimeInForce.FOK,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
expect(result.current.id).toEqual(expectedId);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('Should submit a correctly formatted order', async () => {
|
|
||||||
const mockSendTx = jest.fn().mockReturnValue(Promise.resolve({}));
|
|
||||||
const keypair = {
|
|
||||||
pub: '0x123',
|
|
||||||
} as VegaKeyExtended;
|
|
||||||
const { result } = setup(
|
|
||||||
{
|
|
||||||
sendTx: mockSendTx,
|
|
||||||
keypairs: [keypair],
|
|
||||||
keypair,
|
|
||||||
},
|
|
||||||
defaultMarket
|
|
||||||
);
|
|
||||||
|
|
||||||
const order: Order = {
|
|
||||||
type: OrderType.Limit,
|
|
||||||
size: '10',
|
|
||||||
timeInForce: OrderTimeInForce.GTT,
|
|
||||||
side: OrderSide.Buy,
|
|
||||||
price: '1234567.89',
|
|
||||||
expiration: new Date('2022-01-01'),
|
|
||||||
};
|
|
||||||
await act(async () => {
|
|
||||||
result.current.submit(order);
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(mockSendTx).toHaveBeenCalledWith({
|
|
||||||
pubKey: keypair.pub,
|
|
||||||
propagate: true,
|
|
||||||
orderSubmission: {
|
|
||||||
type: OrderType.Limit,
|
|
||||||
marketId: defaultMarket.id, // Market provided from hook arugment
|
|
||||||
size: '100', // size adjusted based on positionDecimalPlaces
|
|
||||||
side: OrderSide.Buy,
|
|
||||||
timeInForce: OrderTimeInForce.GTT,
|
|
||||||
price: '123456789', // Decimal removed
|
|
||||||
expiresAt: order.expiration?.getTime() + '000000', // Nanoseconds appened
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,102 +0,0 @@
|
|||||||
import { useCallback, useState } from 'react';
|
|
||||||
import { useSubscription } from '@apollo/client';
|
|
||||||
import type { Order } from '../utils/get-default-order';
|
|
||||||
import type {
|
|
||||||
OrderEvent,
|
|
||||||
OrderEventVariables,
|
|
||||||
OrderEvent_busEvents_event_Order,
|
|
||||||
} from '@vegaprotocol/wallet';
|
|
||||||
import {
|
|
||||||
OrderType,
|
|
||||||
useVegaWallet,
|
|
||||||
ORDER_EVENT_SUB,
|
|
||||||
} from '@vegaprotocol/wallet';
|
|
||||||
import { determineId, removeDecimal } from '@vegaprotocol/react-helpers';
|
|
||||||
import { useVegaTransaction } from '@vegaprotocol/wallet';
|
|
||||||
import type { DealTicketQuery_market } from '../components/__generated__/DealTicketQuery';
|
|
||||||
|
|
||||||
export const useOrderSubmit = (market: DealTicketQuery_market) => {
|
|
||||||
const { keypair } = useVegaWallet();
|
|
||||||
const { send, transaction, reset: resetTransaction } = useVegaTransaction();
|
|
||||||
const [id, setId] = useState('');
|
|
||||||
const [finalizedOrder, setFinalizedOrder] =
|
|
||||||
useState<OrderEvent_busEvents_event_Order | null>(null);
|
|
||||||
|
|
||||||
// Start a subscription looking for the newly created order
|
|
||||||
useSubscription<OrderEvent, OrderEventVariables>(ORDER_EVENT_SUB, {
|
|
||||||
variables: { partyId: keypair?.pub || '' },
|
|
||||||
skip: !id,
|
|
||||||
onSubscriptionData: ({ subscriptionData }) => {
|
|
||||||
if (!subscriptionData.data?.busEvents?.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No types available for the subscription result
|
|
||||||
const matchingOrderEvent = subscriptionData.data.busEvents.find((e) => {
|
|
||||||
if (e.event.__typename !== 'Order') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return e.event.id === id;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (
|
|
||||||
matchingOrderEvent &&
|
|
||||||
matchingOrderEvent.event.__typename === 'Order'
|
|
||||||
) {
|
|
||||||
setFinalizedOrder(matchingOrderEvent.event);
|
|
||||||
resetTransaction();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const submit = useCallback(
|
|
||||||
async (order: Order) => {
|
|
||||||
if (!keypair || !order.side) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setFinalizedOrder(null);
|
|
||||||
|
|
||||||
const res = await send({
|
|
||||||
pubKey: keypair.pub,
|
|
||||||
propagate: true,
|
|
||||||
orderSubmission: {
|
|
||||||
marketId: market.id,
|
|
||||||
price:
|
|
||||||
order.type === OrderType.Limit && order.price
|
|
||||||
? removeDecimal(order.price, market.decimalPlaces)
|
|
||||||
: undefined,
|
|
||||||
size: removeDecimal(order.size, market.positionDecimalPlaces),
|
|
||||||
type: order.type,
|
|
||||||
side: order.side,
|
|
||||||
timeInForce: order.timeInForce,
|
|
||||||
expiresAt: order.expiration
|
|
||||||
? // Wallet expects timestamp in nanoseconds, we don't have that level of accuracy so
|
|
||||||
// just append 6 zeroes
|
|
||||||
order.expiration.getTime().toString() + '000000'
|
|
||||||
: undefined,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (res?.signature) {
|
|
||||||
setId(determineId(res.signature));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[market, keypair, send]
|
|
||||||
);
|
|
||||||
|
|
||||||
const reset = useCallback(() => {
|
|
||||||
resetTransaction();
|
|
||||||
setFinalizedOrder(null);
|
|
||||||
setId('');
|
|
||||||
}, [resetTransaction]);
|
|
||||||
|
|
||||||
return {
|
|
||||||
transaction,
|
|
||||||
finalizedOrder,
|
|
||||||
id,
|
|
||||||
submit,
|
|
||||||
reset,
|
|
||||||
};
|
|
||||||
};
|
|
@ -1,4 +1 @@
|
|||||||
export * from './components';
|
export * from './components';
|
||||||
export * from './utils/get-default-order';
|
|
||||||
export * from './hooks/use-order-submit';
|
|
||||||
export * from './hooks/use-order-validation';
|
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
import { OrderTimeInForce, OrderType, OrderSide } from '@vegaprotocol/wallet';
|
|
||||||
import { toDecimal } from '@vegaprotocol/react-helpers';
|
|
||||||
import type { DealTicketQuery_market } from '../components/__generated__/DealTicketQuery';
|
|
||||||
|
|
||||||
export type Order =
|
|
||||||
| {
|
|
||||||
size: string;
|
|
||||||
type: OrderType.Market;
|
|
||||||
timeInForce: OrderTimeInForce;
|
|
||||||
side: OrderSide;
|
|
||||||
price?: never;
|
|
||||||
expiration?: never;
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
size: string;
|
|
||||||
type: OrderType.Limit;
|
|
||||||
timeInForce: OrderTimeInForce;
|
|
||||||
side: OrderSide;
|
|
||||||
price?: string;
|
|
||||||
expiration?: Date;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getDefaultOrder = (market: DealTicketQuery_market): Order => ({
|
|
||||||
type: OrderType.Market,
|
|
||||||
side: OrderSide.Buy,
|
|
||||||
timeInForce: OrderTimeInForce.IOC,
|
|
||||||
size: String(toDecimal(market.positionDecimalPlaces)),
|
|
||||||
});
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user