feat: [console-lite] - market list - refactor filters query, int tests of long market list (#992)
* feat: [console-lite] - market list - refactor filters query * feat: [console-lite] - market list - refactor some unit tests * feat: [console-lite] - market list - refactor some unit tests * Update apps/simple-trading-app-e2e/src/integration/market-list.test.ts Co-authored-by: Sam Keen <samuel@vegaprotocol.io> * Update apps/simple-trading-app-e2e/src/integration/market-list.test.ts Co-authored-by: Sam Keen <samuel@vegaprotocol.io> * feat: [console-lite] - after feedbacks * feat: [console-lite] - enlarge loading times * feat: [console-lite] - adjust int test * feat: [console-lite] - adjust int test Co-authored-by: maciek <maciek@vegaprotocol.io> Co-authored-by: Sam Keen <samuel@vegaprotocol.io>
This commit is contained in:
parent
44c628332d
commit
46c4b9417e
@ -1,13 +1,14 @@
|
|||||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||||
import { generateSimpleMarkets } from '../support/mocks/generate-markets';
|
import {
|
||||||
import { generateFilters } from '../support/mocks/generate-filters';
|
generateLongListMarkets,
|
||||||
|
generateSimpleMarkets,
|
||||||
|
} from '../support/mocks/generate-markets';
|
||||||
|
|
||||||
describe('market list', () => {
|
describe('market list', () => {
|
||||||
describe('simple url', () => {
|
describe('simple url', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.mockGQL((req) => {
|
cy.mockGQL((req) => {
|
||||||
aliasQuery(req, 'SimpleMarkets', generateSimpleMarkets());
|
aliasQuery(req, 'SimpleMarkets', generateSimpleMarkets());
|
||||||
aliasQuery(req, 'MarketFilters', generateFilters());
|
|
||||||
});
|
});
|
||||||
cy.visit('/markets');
|
cy.visit('/markets');
|
||||||
});
|
});
|
||||||
@ -62,7 +63,6 @@ describe('market list', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cy.mockGQL((req) => {
|
cy.mockGQL((req) => {
|
||||||
aliasQuery(req, 'SimpleMarkets', generateSimpleMarkets());
|
aliasQuery(req, 'SimpleMarkets', generateSimpleMarkets());
|
||||||
aliasQuery(req, 'MarketFilters', generateFilters());
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ describe('market list', () => {
|
|||||||
|
|
||||||
it('last asset (if exists)', () => {
|
it('last asset (if exists)', () => {
|
||||||
cy.visit('/markets');
|
cy.visit('/markets');
|
||||||
cy.wait('@MarketFilters').then((filters) => {
|
cy.wait('@SimpleMarkets').then((filters) => {
|
||||||
if (filters?.response?.body?.data?.markets?.length) {
|
if (filters?.response?.body?.data?.markets?.length) {
|
||||||
const asset =
|
const asset =
|
||||||
filters.response.body.data.markets[0].tradableInstrument.instrument
|
filters.response.body.data.markets[0].tradableInstrument.instrument
|
||||||
@ -93,4 +93,73 @@ describe('market list', () => {
|
|||||||
.should('have.text', 'Future');
|
.should('have.text', 'Future');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('long list of results should be handled properly', () => {
|
||||||
|
it('handles 5000 markets', () => {
|
||||||
|
cy.viewport(1440, 900);
|
||||||
|
cy.mockGQL((req) => {
|
||||||
|
aliasQuery(req, 'SimpleMarkets', generateLongListMarkets(5000));
|
||||||
|
});
|
||||||
|
performance.mark('start-5k');
|
||||||
|
cy.visit('/markets');
|
||||||
|
cy.get('.ag-center-cols-container', { timeout: 50000 }).then(() => {
|
||||||
|
performance.mark('end-5k');
|
||||||
|
performance.measure('load-5k', 'start-5k', 'end-5k');
|
||||||
|
const measure = performance.getEntriesByName('load-5k')[0];
|
||||||
|
expect(measure.duration).lte(20000);
|
||||||
|
cy.log(`Ag-grid 5k load took ${measure.duration} milliseconds.`);
|
||||||
|
|
||||||
|
cy.get('.ag-root').should('have.attr', 'aria-rowcount', '5001');
|
||||||
|
cy.get('.ag-center-cols-container')
|
||||||
|
.find('[role="row"]')
|
||||||
|
.its('length')
|
||||||
|
.then((length) => expect(length).to.be.closeTo(21, 2));
|
||||||
|
cy.get('.ag-cell-label-container').eq(4).click();
|
||||||
|
for (let i = 0; i < 50; i++) {
|
||||||
|
cy.get('body').realPress('Tab');
|
||||||
|
}
|
||||||
|
cy.focused().parent('.ag-row').should('have.attr', 'row-index', '49');
|
||||||
|
cy.get('.ag-center-cols-container')
|
||||||
|
.find('[role="row"]')
|
||||||
|
.its('length')
|
||||||
|
.then((length) => expect(length).to.be.closeTo(31, 2));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('handles 50000 markets', () => {
|
||||||
|
cy.viewport(1440, 900);
|
||||||
|
cy.mockGQL(async (req) => {
|
||||||
|
aliasQuery(req, 'SimpleMarkets', generateLongListMarkets(50000));
|
||||||
|
});
|
||||||
|
performance.mark('start-50k');
|
||||||
|
cy.visit('/markets');
|
||||||
|
cy.get('.w-full.h-full.flex.items-center.justify-center').should(
|
||||||
|
'have.text',
|
||||||
|
'Loading...'
|
||||||
|
);
|
||||||
|
cy.get('.ag-center-cols-container', { timeout: 100000 }).then(() => {
|
||||||
|
performance.mark('end-50k');
|
||||||
|
performance.measure('load-50k', 'start-50k', 'end-50k');
|
||||||
|
const measure = performance.getEntriesByName('load-50k')[0];
|
||||||
|
expect(measure.duration).lte(85000);
|
||||||
|
cy.log(`Ag-grid 50k load took ${measure.duration} milliseconds.`);
|
||||||
|
|
||||||
|
cy.get('.ag-root').should('have.attr', 'aria-rowcount', '50001');
|
||||||
|
cy.get('.ag-center-cols-container')
|
||||||
|
.find('[role="row"]')
|
||||||
|
.its('length')
|
||||||
|
.then((length) => expect(length).to.be.closeTo(21, 2));
|
||||||
|
|
||||||
|
cy.get('.ag-cell-label-container').eq(4).click();
|
||||||
|
for (let i = 0; i < 50; i++) {
|
||||||
|
cy.get('body').realPress('Tab');
|
||||||
|
}
|
||||||
|
cy.focused().parent('.ag-row').should('have.attr', 'row-index', '49');
|
||||||
|
cy.get('.ag-center-cols-container')
|
||||||
|
.find('[role="row"]')
|
||||||
|
.its('length')
|
||||||
|
.then((length) => expect(length).to.be.closeTo(31, 2));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -14,5 +14,6 @@
|
|||||||
// ***********************************************************
|
// ***********************************************************
|
||||||
|
|
||||||
import '@vegaprotocol/cypress';
|
import '@vegaprotocol/cypress';
|
||||||
|
import 'cypress-real-events/support';
|
||||||
// Import commands.js using ES2015 syntax:
|
// Import commands.js using ES2015 syntax:
|
||||||
import './commands';
|
import './commands';
|
||||||
|
@ -1,84 +0,0 @@
|
|||||||
export const generateFilters = () => {
|
|
||||||
return {
|
|
||||||
markets: [
|
|
||||||
{
|
|
||||||
tradableInstrument: {
|
|
||||||
instrument: {
|
|
||||||
product: {
|
|
||||||
__typename: 'Future',
|
|
||||||
settlementAsset: { symbol: 'fDAI', __typename: 'Asset' },
|
|
||||||
},
|
|
||||||
__typename: 'Instrument',
|
|
||||||
},
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
},
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tradableInstrument: {
|
|
||||||
instrument: {
|
|
||||||
product: {
|
|
||||||
__typename: 'Future',
|
|
||||||
settlementAsset: { symbol: 'fBTC', __typename: 'Asset' },
|
|
||||||
},
|
|
||||||
__typename: 'Instrument',
|
|
||||||
},
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
},
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tradableInstrument: {
|
|
||||||
instrument: {
|
|
||||||
product: {
|
|
||||||
__typename: 'Future',
|
|
||||||
settlementAsset: { symbol: 'fDAI', __typename: 'Asset' },
|
|
||||||
},
|
|
||||||
__typename: 'Instrument',
|
|
||||||
},
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
},
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tradableInstrument: {
|
|
||||||
instrument: {
|
|
||||||
product: {
|
|
||||||
__typename: 'Future',
|
|
||||||
settlementAsset: { symbol: 'fDAI', __typename: 'Asset' },
|
|
||||||
},
|
|
||||||
__typename: 'Instrument',
|
|
||||||
},
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
},
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tradableInstrument: {
|
|
||||||
instrument: {
|
|
||||||
product: {
|
|
||||||
__typename: 'Future',
|
|
||||||
settlementAsset: { symbol: 'fUSDC', __typename: 'Asset' },
|
|
||||||
},
|
|
||||||
__typename: 'Instrument',
|
|
||||||
},
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
},
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tradableInstrument: {
|
|
||||||
instrument: {
|
|
||||||
product: {
|
|
||||||
__typename: 'Future',
|
|
||||||
settlementAsset: { symbol: 'fEURO', __typename: 'Asset' },
|
|
||||||
},
|
|
||||||
__typename: 'Instrument',
|
|
||||||
},
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
},
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
};
|
|
@ -1,116 +1,120 @@
|
|||||||
|
const protoCandles = [
|
||||||
|
{ open: '9556163', close: '9587028', __typename: 'Candle' },
|
||||||
|
{
|
||||||
|
open: '9587028',
|
||||||
|
close: '9769899',
|
||||||
|
__typename: 'Candle',
|
||||||
|
},
|
||||||
|
{ open: '9769899', close: '9586292', __typename: 'Candle' },
|
||||||
|
{
|
||||||
|
open: '9586292',
|
||||||
|
close: '9261774',
|
||||||
|
__typename: 'Candle',
|
||||||
|
},
|
||||||
|
{ open: '9261773', close: '9236369', __typename: 'Candle' },
|
||||||
|
{
|
||||||
|
open: '9236369',
|
||||||
|
close: '9226070',
|
||||||
|
__typename: 'Candle',
|
||||||
|
},
|
||||||
|
{ open: '9226077', close: '9233252', __typename: 'Candle' },
|
||||||
|
{
|
||||||
|
open: '9249854',
|
||||||
|
close: '9333038',
|
||||||
|
__typename: 'Candle',
|
||||||
|
},
|
||||||
|
{ open: '9333038', close: '9410371', __typename: 'Candle' },
|
||||||
|
{
|
||||||
|
open: '9410371',
|
||||||
|
close: '9626249',
|
||||||
|
__typename: 'Candle',
|
||||||
|
},
|
||||||
|
{ open: '9626247', close: '9493253', __typename: 'Candle' },
|
||||||
|
{
|
||||||
|
open: '9493253',
|
||||||
|
close: '9309054',
|
||||||
|
__typename: 'Candle',
|
||||||
|
},
|
||||||
|
{ open: '9309054', close: '9378428', __typename: 'Candle' },
|
||||||
|
{
|
||||||
|
open: '9378428',
|
||||||
|
close: '9352996',
|
||||||
|
__typename: 'Candle',
|
||||||
|
},
|
||||||
|
{ open: '9352996', close: '9451142', __typename: 'Candle' },
|
||||||
|
{
|
||||||
|
open: '9451142',
|
||||||
|
close: '9691070',
|
||||||
|
__typename: 'Candle',
|
||||||
|
},
|
||||||
|
{ open: '9691071', close: '9622031', __typename: 'Candle' },
|
||||||
|
{
|
||||||
|
open: '9622034',
|
||||||
|
close: '9519285',
|
||||||
|
__typename: 'Candle',
|
||||||
|
},
|
||||||
|
{ open: '9528904', close: '9671275', __typename: 'Candle' },
|
||||||
|
{
|
||||||
|
open: '9671275',
|
||||||
|
close: '9988454',
|
||||||
|
__typename: 'Candle',
|
||||||
|
},
|
||||||
|
{ open: '9982457', close: '10085537', __typename: 'Candle' },
|
||||||
|
{
|
||||||
|
open: '10085537',
|
||||||
|
close: '9967390',
|
||||||
|
__typename: 'Candle',
|
||||||
|
},
|
||||||
|
{ open: '9967390', close: '9974844', __typename: 'Candle' },
|
||||||
|
{
|
||||||
|
open: '9974844',
|
||||||
|
close: '9940706',
|
||||||
|
__typename: 'Candle',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const protoMarket = {
|
||||||
|
id: 'first-btcusd-id',
|
||||||
|
name: 'AAVEDAI Monthly (30 Jun 2022)',
|
||||||
|
data: {
|
||||||
|
market: {
|
||||||
|
id: 'first-btcusd-id',
|
||||||
|
state: 'Active',
|
||||||
|
__typename: 'Market',
|
||||||
|
},
|
||||||
|
__typename: 'MarketData',
|
||||||
|
},
|
||||||
|
tradableInstrument: {
|
||||||
|
instrument: {
|
||||||
|
code: 'AAVEDAI.MF21',
|
||||||
|
metadata: {
|
||||||
|
tags: [
|
||||||
|
'formerly:2839D9B2329C9E70',
|
||||||
|
'base:AAVE',
|
||||||
|
'quote:DAI',
|
||||||
|
'class:fx/crypto',
|
||||||
|
'monthly',
|
||||||
|
'sector:defi',
|
||||||
|
],
|
||||||
|
__typename: 'InstrumentMetadata',
|
||||||
|
},
|
||||||
|
product: {
|
||||||
|
__typename: 'Future',
|
||||||
|
quoteName: 'DAI',
|
||||||
|
settlementAsset: { symbol: 'tDAI', __typename: 'Asset' },
|
||||||
|
},
|
||||||
|
__typename: 'Instrument',
|
||||||
|
},
|
||||||
|
__typename: 'TradableInstrument',
|
||||||
|
},
|
||||||
|
candles: protoCandles,
|
||||||
|
__typename: 'Market',
|
||||||
|
};
|
||||||
|
|
||||||
export const generateSimpleMarkets = () => {
|
export const generateSimpleMarkets = () => {
|
||||||
return {
|
return {
|
||||||
markets: [
|
markets: [
|
||||||
{
|
{ ...protoMarket },
|
||||||
id: 'first-btcusd-id',
|
|
||||||
name: 'AAVEDAI Monthly (30 Jun 2022)',
|
|
||||||
data: {
|
|
||||||
market: {
|
|
||||||
id: 'first-btcusd-id',
|
|
||||||
state: 'Active',
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
__typename: 'MarketData',
|
|
||||||
},
|
|
||||||
tradableInstrument: {
|
|
||||||
instrument: {
|
|
||||||
code: 'AAVEDAI.MF21',
|
|
||||||
metadata: {
|
|
||||||
tags: [
|
|
||||||
'formerly:2839D9B2329C9E70',
|
|
||||||
'base:AAVE',
|
|
||||||
'quote:DAI',
|
|
||||||
'class:fx/crypto',
|
|
||||||
'monthly',
|
|
||||||
'sector:defi',
|
|
||||||
],
|
|
||||||
__typename: 'InstrumentMetadata',
|
|
||||||
},
|
|
||||||
product: {
|
|
||||||
__typename: 'Future',
|
|
||||||
quoteName: 'DAI',
|
|
||||||
settlementAsset: { symbol: 'tDAI', __typename: 'Asset' },
|
|
||||||
},
|
|
||||||
__typename: 'Instrument',
|
|
||||||
},
|
|
||||||
__typename: 'TradableInstrument',
|
|
||||||
},
|
|
||||||
candles: [
|
|
||||||
{ open: '9556163', close: '9587028', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9587028',
|
|
||||||
close: '9769899',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9769899', close: '9586292', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9586292',
|
|
||||||
close: '9261774',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9261773', close: '9236369', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9236369',
|
|
||||||
close: '9226070',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9226077', close: '9233252', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9249854',
|
|
||||||
close: '9333038',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9333038', close: '9410371', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9410371',
|
|
||||||
close: '9626249',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9626247', close: '9493253', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9493253',
|
|
||||||
close: '9309054',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9309054', close: '9378428', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9378428',
|
|
||||||
close: '9352996',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9352996', close: '9451142', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9451142',
|
|
||||||
close: '9691070',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9691071', close: '9622031', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9622034',
|
|
||||||
close: '9519285',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9528904', close: '9671275', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9671275',
|
|
||||||
close: '9988454',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9982457', close: '10085537', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '10085537',
|
|
||||||
close: '9967390',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
{ open: '9967390', close: '9974844', __typename: 'Candle' },
|
|
||||||
{
|
|
||||||
open: '9974844',
|
|
||||||
close: '9940706',
|
|
||||||
__typename: 'Candle',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
__typename: 'Market',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: '57fbaa322e97cfc8bb5f1de048c37e033c41b1ac1906d3aed9960912a067ef5a',
|
id: '57fbaa322e97cfc8bb5f1de048c37e033c41b1ac1906d3aed9960912a067ef5a',
|
||||||
name: 'CELUSD (June 2022)',
|
name: 'CELUSD (June 2022)',
|
||||||
@ -1067,3 +1071,20 @@ export const generateSimpleMarkets = () => {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const generateLongListMarkets = (count: number) => {
|
||||||
|
const markets = [];
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
const { id, name } = protoMarket;
|
||||||
|
markets.push({
|
||||||
|
...protoMarket,
|
||||||
|
id: id + i,
|
||||||
|
name: name + i,
|
||||||
|
data: {
|
||||||
|
...protoMarket.data,
|
||||||
|
id: id + i,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return { markets };
|
||||||
|
};
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"sourceMap": false,
|
"sourceMap": false,
|
||||||
"outDir": "../../dist/out-tsc",
|
"outDir": "../../dist/out-tsc",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"types": ["cypress", "node"]
|
"types": ["cypress", "node", "cypress-real-events"]
|
||||||
},
|
},
|
||||||
"include": ["src/**/*.ts", "src/**/*.js"]
|
"include": ["src/**/*.ts", "src/**/*.js"]
|
||||||
}
|
}
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
/* tslint:disable */
|
|
||||||
/* eslint-disable */
|
|
||||||
// @generated
|
|
||||||
// This file was automatically generated and should not be edited.
|
|
||||||
|
|
||||||
// ====================================================
|
|
||||||
// GraphQL query operation: MarketFilters
|
|
||||||
// ====================================================
|
|
||||||
|
|
||||||
export interface MarketFilters_markets_tradableInstrument_instrument_product_settlementAsset {
|
|
||||||
__typename: "Asset";
|
|
||||||
/**
|
|
||||||
* The symbol of the asset (e.g: GBP)
|
|
||||||
*/
|
|
||||||
symbol: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketFilters_markets_tradableInstrument_instrument_product {
|
|
||||||
__typename: "Future";
|
|
||||||
/**
|
|
||||||
* The name of the asset (string)
|
|
||||||
*/
|
|
||||||
settlementAsset: MarketFilters_markets_tradableInstrument_instrument_product_settlementAsset;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketFilters_markets_tradableInstrument_instrument {
|
|
||||||
__typename: "Instrument";
|
|
||||||
/**
|
|
||||||
* A reference to or instance of a fully specified product, including all required product parameters for that product (Product union)
|
|
||||||
*/
|
|
||||||
product: MarketFilters_markets_tradableInstrument_instrument_product;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketFilters_markets_tradableInstrument {
|
|
||||||
__typename: "TradableInstrument";
|
|
||||||
/**
|
|
||||||
* An instance of or reference to a fully specified instrument.
|
|
||||||
*/
|
|
||||||
instrument: MarketFilters_markets_tradableInstrument_instrument;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketFilters_markets {
|
|
||||||
__typename: "Market";
|
|
||||||
/**
|
|
||||||
* An instance of or reference to a tradable instrument.
|
|
||||||
*/
|
|
||||||
tradableInstrument: MarketFilters_markets_tradableInstrument;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface MarketFilters {
|
|
||||||
/**
|
|
||||||
* One or more instruments that are trading on the VEGA network
|
|
||||||
*/
|
|
||||||
markets: MarketFilters_markets[] | null;
|
|
||||||
}
|
|
@ -70,25 +70,6 @@ export const CANDLE_SUB = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const FILTERS_QUERY = gql`
|
|
||||||
query MarketFilters {
|
|
||||||
markets {
|
|
||||||
tradableInstrument {
|
|
||||||
instrument {
|
|
||||||
product {
|
|
||||||
__typename
|
|
||||||
... on Future {
|
|
||||||
settlementAsset {
|
|
||||||
symbol
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const update = (
|
const update = (
|
||||||
data: SimpleMarkets_markets[],
|
data: SimpleMarkets_markets[],
|
||||||
delta: SimpleMarketDataSub_marketData
|
delta: SimpleMarketDataSub_marketData
|
||||||
|
@ -12,12 +12,11 @@ import type { MockedResponse } from '@apollo/client/testing';
|
|||||||
import { BrowserRouter } from 'react-router-dom';
|
import { BrowserRouter } from 'react-router-dom';
|
||||||
import { MarketState } from '@vegaprotocol/types';
|
import { MarketState } from '@vegaprotocol/types';
|
||||||
import SimpleMarketList from './simple-market-list';
|
import SimpleMarketList from './simple-market-list';
|
||||||
import { FILTERS_QUERY, MARKETS_QUERY } from './data-provider';
|
import { MARKETS_QUERY } from './data-provider';
|
||||||
import type {
|
import type {
|
||||||
SimpleMarkets_markets,
|
SimpleMarkets_markets,
|
||||||
SimpleMarkets,
|
SimpleMarkets,
|
||||||
} from './__generated__/SimpleMarkets';
|
} from './__generated__/SimpleMarkets';
|
||||||
import type { MarketFilters } from './__generated__/MarketFilters';
|
|
||||||
|
|
||||||
const mockedNavigate = jest.fn();
|
const mockedNavigate = jest.fn();
|
||||||
|
|
||||||
@ -32,15 +31,6 @@ jest.mock('date-fns', () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
describe('SimpleMarketList', () => {
|
describe('SimpleMarketList', () => {
|
||||||
const filterMock: MockedResponse<MarketFilters> = {
|
|
||||||
request: {
|
|
||||||
query: FILTERS_QUERY,
|
|
||||||
},
|
|
||||||
result: {
|
|
||||||
data: { markets: [] },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
jest.clearAllMocks();
|
jest.clearAllMocks();
|
||||||
cleanup();
|
cleanup();
|
||||||
@ -60,8 +50,7 @@ describe('SimpleMarketList', () => {
|
|||||||
};
|
};
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
render(
|
render(
|
||||||
// @ts-ignore different versions of react types in apollo and app
|
<MockedProvider mocks={[mocks]}>
|
||||||
<MockedProvider mocks={[mocks, filterMock]}>
|
|
||||||
<SimpleMarketList />
|
<SimpleMarketList />
|
||||||
</MockedProvider>,
|
</MockedProvider>,
|
||||||
{ wrapper: BrowserRouter }
|
{ wrapper: BrowserRouter }
|
||||||
@ -130,8 +119,7 @@ describe('SimpleMarketList', () => {
|
|||||||
};
|
};
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
render(
|
render(
|
||||||
// @ts-ignore different versions of react types in apollo and app
|
<MockedProvider mocks={[mocks]}>
|
||||||
<MockedProvider mocks={[mocks, filterMock]}>
|
|
||||||
<SimpleMarketList />
|
<SimpleMarketList />
|
||||||
</MockedProvider>,
|
</MockedProvider>,
|
||||||
{ wrapper: BrowserRouter }
|
{ wrapper: BrowserRouter }
|
||||||
@ -143,8 +131,9 @@ describe('SimpleMarketList', () => {
|
|||||||
document.querySelector('.ag-center-cols-container')
|
document.querySelector('.ag-center-cols-container')
|
||||||
).toBeInTheDocument();
|
).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
await waitFor(() => {
|
||||||
const container = document.querySelector('.ag-center-cols-container');
|
const container = document.querySelector('.ag-center-cols-container');
|
||||||
expect(getAllByRole(container as HTMLDivElement, 'row')).toHaveLength(2);
|
expect(getAllByRole(container as HTMLDivElement, 'row')).toHaveLength(2);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -131,7 +131,7 @@ const SimpleMarketList = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-full grid grid-rows-[min-content,1fr]">
|
<div className="h-full grid grid-rows-[min-content,1fr]">
|
||||||
<SimpleMarketToolbar />
|
<SimpleMarketToolbar data={data || []} />
|
||||||
<AsyncRenderer loading={loading} error={error} data={localData}>
|
<AsyncRenderer loading={loading} error={error} data={localData}>
|
||||||
<AgGrid
|
<AgGrid
|
||||||
className="mb-32 min-h-[300px]"
|
className="mb-32 min-h-[300px]"
|
||||||
|
@ -3,46 +3,53 @@ import { useLocation, useRoutes, BrowserRouter } from 'react-router-dom';
|
|||||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
||||||
import { MockedProvider } from '@apollo/react-testing';
|
import { MockedProvider } from '@apollo/react-testing';
|
||||||
import SimpleMarketToolbar from './simple-market-toolbar';
|
import SimpleMarketToolbar from './simple-market-toolbar';
|
||||||
import type { MockedResponse } from '@apollo/client/testing';
|
import type { SimpleMarkets_markets } from './__generated__/SimpleMarkets';
|
||||||
import type { MarketFilters } from './__generated__/MarketFilters';
|
import { markets as filterData } from './mocks/market-filters.json';
|
||||||
import { FILTERS_QUERY } from './data-provider';
|
|
||||||
import filterData from './mocks/market-filters.json';
|
|
||||||
import { act } from 'react-dom/test-utils';
|
|
||||||
|
|
||||||
describe('SimpleMarketToolbar', () => {
|
describe('SimpleMarketToolbar', () => {
|
||||||
const filterMock: MockedResponse<MarketFilters> = {
|
|
||||||
request: {
|
|
||||||
query: FILTERS_QUERY,
|
|
||||||
},
|
|
||||||
result: {
|
|
||||||
data: filterData as unknown as MarketFilters,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const WrappedCompForTest = () => {
|
const WrappedCompForTest = () => {
|
||||||
const routes = useRoutes([
|
const routes = useRoutes([
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
element: <SimpleMarketToolbar />,
|
element: (
|
||||||
|
<SimpleMarketToolbar data={filterData as SimpleMarkets_markets[]} />
|
||||||
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'markets',
|
path: 'markets',
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: `:state`,
|
path: `:state`,
|
||||||
element: <SimpleMarketToolbar />,
|
element: (
|
||||||
|
<SimpleMarketToolbar
|
||||||
|
data={filterData as SimpleMarkets_markets[]}
|
||||||
|
/>
|
||||||
|
),
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: `:product`,
|
path: `:product`,
|
||||||
element: <SimpleMarketToolbar />,
|
element: (
|
||||||
|
<SimpleMarketToolbar
|
||||||
|
data={filterData as SimpleMarkets_markets[]}
|
||||||
|
/>
|
||||||
|
),
|
||||||
children: [
|
children: [
|
||||||
{ path: `:asset`, element: <SimpleMarketToolbar /> },
|
{
|
||||||
|
path: `:asset`,
|
||||||
|
element: (
|
||||||
|
<SimpleMarketToolbar
|
||||||
|
data={filterData as SimpleMarkets_markets[]}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
element: <SimpleMarketToolbar />,
|
element: (
|
||||||
|
<SimpleMarketToolbar data={filterData as SimpleMarkets_markets[]} />
|
||||||
|
),
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@ -59,74 +66,66 @@ describe('SimpleMarketToolbar', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should be properly rendered', async () => {
|
it('should be properly rendered', async () => {
|
||||||
act(async () => {
|
render(
|
||||||
render(
|
<MockedProvider mocks={[]} addTypename={false}>
|
||||||
// @ts-ignore different versions of react types in apollo and app
|
<WrappedCompForTest />
|
||||||
<MockedProvider mocks={[filterMock]} addTypename={false}>
|
</MockedProvider>,
|
||||||
<WrappedCompForTest />
|
{ wrapper: BrowserRouter }
|
||||||
</MockedProvider>,
|
);
|
||||||
{ wrapper: BrowserRouter }
|
await waitFor(() => {
|
||||||
|
expect(screen.getByText('Future')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
fireEvent.click(screen.getByText('Future'));
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(screen.getByTestId('market-products-menu').children).toHaveLength(
|
||||||
|
3
|
||||||
);
|
);
|
||||||
await waitFor(() => {
|
expect(screen.getByTestId('market-assets-menu').children).toHaveLength(6);
|
||||||
expect(screen.getByText('Future')).toBeInTheDocument();
|
});
|
||||||
});
|
fireEvent.click(screen.getByTestId('state-trigger'));
|
||||||
fireEvent.click(screen.getByText('Future'));
|
waitFor(() => {
|
||||||
await waitFor(() => {
|
expect(screen.getByRole('menu')).toBeInTheDocument();
|
||||||
expect(
|
expect(screen.getByRole('menu').children).toHaveLength(10);
|
||||||
screen.getByTestId('market-products-menu').children
|
|
||||||
).toHaveLength(3);
|
|
||||||
expect(screen.getByTestId('market-assets-menu').children).toHaveLength(
|
|
||||||
6
|
|
||||||
);
|
|
||||||
});
|
|
||||||
fireEvent.click(screen.getByTestId('state-trigger'));
|
|
||||||
waitFor(() => {
|
|
||||||
expect(screen.getByRole('menu')).toBeInTheDocument();
|
|
||||||
expect(screen.getByRole('menu').children).toHaveLength(10);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('navigation should work well', async () => {
|
it('navigation should work well', async () => {
|
||||||
act(async () => {
|
render(
|
||||||
render(
|
<MockedProvider mocks={[]} addTypename={false}>
|
||||||
// @ts-ignore different versions of react types in apollo and app
|
<WrappedCompForTest />
|
||||||
<MockedProvider mocks={[filterMock]} addTypename={false}>
|
</MockedProvider>,
|
||||||
<WrappedCompForTest />
|
{ wrapper: BrowserRouter }
|
||||||
</MockedProvider>,
|
);
|
||||||
{ wrapper: BrowserRouter }
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(screen.getByText('Future')).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
fireEvent.click(screen.getByText('Future'));
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(screen.getByTestId('location-display')).toHaveTextContent(
|
||||||
|
'/markets/Active/Future'
|
||||||
);
|
);
|
||||||
|
});
|
||||||
|
|
||||||
await waitFor(() => {
|
fireEvent.click(
|
||||||
expect(screen.getByText('Future')).toBeInTheDocument();
|
screen
|
||||||
});
|
.getByTestId('market-assets-menu')
|
||||||
fireEvent.click(screen.getByText('Future'));
|
.children[5].querySelector('a') as HTMLAnchorElement
|
||||||
|
);
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(screen.getByTestId('location-display')).toHaveTextContent(
|
expect(screen.getByTestId('location-display')).toHaveTextContent(
|
||||||
'/markets/Active/Future'
|
'/markets/Active/Future/tEURO'
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
fireEvent.click(
|
|
||||||
screen
|
|
||||||
.getByTestId('market-assets-menu')
|
|
||||||
.children[5].querySelector('a') as HTMLAnchorElement
|
|
||||||
);
|
);
|
||||||
await waitFor(() => {
|
});
|
||||||
expect(screen.getByTestId('location-display')).toHaveTextContent(
|
|
||||||
'/markets/Active/Future/tEURO'
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
fireEvent.click(screen.getByTestId('state-trigger'));
|
fireEvent.click(screen.getByTestId('state-trigger'));
|
||||||
waitFor(() => {
|
waitFor(() => {
|
||||||
expect(screen.getByRole('menu')).toBeInTheDocument();
|
expect(screen.getByRole('menu')).toBeInTheDocument();
|
||||||
fireEvent.click(screen.getByText('Pending'));
|
fireEvent.click(screen.getByText('Pending'));
|
||||||
expect(screen.getByTestId('location-display')).toHaveTextContent(
|
expect(screen.getByTestId('location-display')).toHaveTextContent(
|
||||||
'/markets/Pending/Future/tEURO'
|
'/markets/Pending/Future/tEURO'
|
||||||
);
|
);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -16,11 +16,16 @@ import {
|
|||||||
} from '@vegaprotocol/ui-toolkit';
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
import useMarketFiltersData from '../../hooks/use-markets-filter';
|
import useMarketFiltersData from '../../hooks/use-markets-filter';
|
||||||
import { STATES_FILTER } from './constants';
|
import { STATES_FILTER } from './constants';
|
||||||
|
import type { SimpleMarkets_markets } from './__generated__/SimpleMarkets';
|
||||||
|
|
||||||
const SimpleMarketToolbar = () => {
|
interface Props {
|
||||||
|
data: SimpleMarkets_markets[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const SimpleMarketToolbar = ({ data }: Props) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const { products, assetsPerProduct } = useMarketFiltersData();
|
const { products, assetsPerProduct } = useMarketFiltersData(data);
|
||||||
const [isOpen, setOpen] = useState(false);
|
const [isOpen, setOpen] = useState(false);
|
||||||
const [activeNumber, setActiveNumber] = useState(
|
const [activeNumber, setActiveNumber] = useState(
|
||||||
products?.length ? products.indexOf(params.product || '') + 1 : -1
|
products?.length ? products.indexOf(params.product || '') + 1 : -1
|
||||||
|
@ -1,20 +1,16 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useQuery } from '@apollo/client';
|
import type { SimpleMarkets_markets } from '../components/simple-market-list/__generated__/SimpleMarkets';
|
||||||
import { FILTERS_QUERY } from '../components/simple-market-list/data-provider';
|
|
||||||
import type { MarketFilters } from '../components/simple-market-list/__generated__/MarketFilters';
|
|
||||||
|
|
||||||
const useMarketFilters = () => {
|
const useMarketFilters = (data: SimpleMarkets_markets[]) => {
|
||||||
const [products, setProducts] = useState<string[]>([]);
|
const [products, setProducts] = useState<string[]>([]);
|
||||||
const [assetsPerProduct, setAssetsPerProduct] = useState<
|
const [assetsPerProduct, setAssetsPerProduct] = useState<
|
||||||
Record<string, string[]>
|
Record<string, string[]>
|
||||||
>({});
|
>({});
|
||||||
const { data } = useQuery<MarketFilters>(FILTERS_QUERY, {
|
|
||||||
pollInterval: 5000,
|
|
||||||
});
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const localProducts = new Set<string>();
|
const localProducts = new Set<string>();
|
||||||
const localAssetPerProduct: Record<string, Set<string>> = {};
|
const localAssetPerProduct: Record<string, Set<string>> = {};
|
||||||
data?.markets?.forEach((item) => {
|
data?.forEach((item) => {
|
||||||
const product = item.tradableInstrument.instrument.product.__typename;
|
const product = item.tradableInstrument.instrument.product.__typename;
|
||||||
const asset =
|
const asset =
|
||||||
item.tradableInstrument.instrument.product.settlementAsset.symbol;
|
item.tradableInstrument.instrument.product.settlementAsset.symbol;
|
||||||
|
@ -54,7 +54,6 @@ describe('useOrderCloseOut Hook', () => {
|
|||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
wrapper: ({ children }: { children: React.ReactNode }) => (
|
wrapper: ({ children }: { children: React.ReactNode }) => (
|
||||||
// @ts-ignore different versions of react types in apollo and app
|
|
||||||
<MockedProvider mocks={[]}>{children}</MockedProvider>
|
<MockedProvider mocks={[]}>{children}</MockedProvider>
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@ -72,7 +71,6 @@ describe('useOrderCloseOut Hook', () => {
|
|||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
wrapper: ({ children }: { children: React.ReactNode }) => (
|
wrapper: ({ children }: { children: React.ReactNode }) => (
|
||||||
// @ts-ignore different versions of react types in apollo and app
|
|
||||||
<MockedProvider mocks={[]}>{children}</MockedProvider>
|
<MockedProvider mocks={[]}>{children}</MockedProvider>
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@ -89,7 +87,6 @@ describe('useOrderCloseOut Hook', () => {
|
|||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
wrapper: ({ children }: { children: React.ReactNode }) => (
|
wrapper: ({ children }: { children: React.ReactNode }) => (
|
||||||
// @ts-ignore different versions of react types in apollo and app
|
|
||||||
<MockedProvider mocks={[]}>{children}</MockedProvider>
|
<MockedProvider mocks={[]}>{children}</MockedProvider>
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -133,6 +133,7 @@
|
|||||||
"babel-loader": "8.1.0",
|
"babel-loader": "8.1.0",
|
||||||
"cypress": "^10.2.0",
|
"cypress": "^10.2.0",
|
||||||
"cypress-cucumber-preprocessor": "^4.3.1",
|
"cypress-cucumber-preprocessor": "^4.3.1",
|
||||||
|
"cypress-real-events": "^1.7.1",
|
||||||
"dotenv": "^16.0.1",
|
"dotenv": "^16.0.1",
|
||||||
"eslint": "8.12.0",
|
"eslint": "8.12.0",
|
||||||
"eslint-config-next": "12.1.2",
|
"eslint-config-next": "12.1.2",
|
||||||
|
@ -10203,6 +10203,11 @@ cypress-cucumber-preprocessor@^4.3.1:
|
|||||||
minimist "^1.2.5"
|
minimist "^1.2.5"
|
||||||
through "^2.3.8"
|
through "^2.3.8"
|
||||||
|
|
||||||
|
cypress-real-events@^1.7.1:
|
||||||
|
version "1.7.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/cypress-real-events/-/cypress-real-events-1.7.1.tgz#8f430d67c29ea4f05b9c5b0311780120cbc9b935"
|
||||||
|
integrity sha512-/Bg15RgJ0SYsuXc6lPqH08x19z6j2vmhWN4wXfJqm3z8BTAFiK2MvipZPzxT8Z0jJP0q7kuniWrLIvz/i/8lCQ==
|
||||||
|
|
||||||
cypress@^10.2.0:
|
cypress@^10.2.0:
|
||||||
version "10.4.0"
|
version "10.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/cypress/-/cypress-10.4.0.tgz#bb5b3b6588ad49eff172fecf5778cc0da2980e4e"
|
resolved "https://registry.yarnpkg.com/cypress/-/cypress-10.4.0.tgz#bb5b3b6588ad49eff172fecf5778cc0da2980e4e"
|
||||||
|
Loading…
Reference in New Issue
Block a user