Chore/Improve trading app mock queries (#582)
* fix: remove supreflous intercepts and use one intercept for all gql queries * fix: mock vega tx per test, beforeEach not working * fix: wait for both queries * fix: move MarketList wait back * fix: dont wait for MarketList query * fix: move assertion to actual test body so other tests can run * fix: ensure page rendered before checking url after redirect
This commit is contained in:
parent
40868bb98a
commit
a11efacba1
@ -1,15 +1,11 @@
|
||||
import { hasOperationName } from '../support';
|
||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||
import { generateDepositPage } from '../support/mocks/generate-deposit-page';
|
||||
|
||||
describe('deposit form validation', () => {
|
||||
beforeEach(() => {
|
||||
cy.mockWeb3Provider();
|
||||
cy.mockGQL('DepositPage', (req) => {
|
||||
if (hasOperationName(req, 'DepositPage')) {
|
||||
req.reply({
|
||||
body: { data: generateDepositPage() },
|
||||
});
|
||||
}
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'DepositPage', generateDepositPage());
|
||||
});
|
||||
cy.visit('/portfolio/deposit');
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||
import type { MarketList, MarketList_markets } from '@vegaprotocol/market-list';
|
||||
import { MarketState } from '@vegaprotocol/types';
|
||||
import { hasOperationName } from '../support';
|
||||
import { generateMarketList } from '../support/mocks/generate-market-list';
|
||||
import { generateMarkets } from '../support/mocks/generate-markets';
|
||||
import type { MarketsLanding } from '../support/mocks/generate-markets-landing';
|
||||
@ -23,30 +23,19 @@ describe('home', () => {
|
||||
);
|
||||
|
||||
// Mock markets query that is triggered by home page to find default market
|
||||
cy.mockGQL('MarketsLanding', (req) => {
|
||||
if (hasOperationName(req, 'MarketsLanding')) {
|
||||
req.reply({
|
||||
body: { data: marketsLanding },
|
||||
});
|
||||
}
|
||||
});
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'MarketsLanding', marketsLanding);
|
||||
aliasQuery(req, 'MarketList', marketList);
|
||||
|
||||
// Market market list for the dialog that opens on a trading page
|
||||
cy.mockGQL('MarketList', (req) => {
|
||||
if (hasOperationName(req, 'MarketList')) {
|
||||
req.reply({
|
||||
body: { data: marketList },
|
||||
});
|
||||
}
|
||||
// Mock all market page queries
|
||||
mockTradingPage(req, MarketState.Active);
|
||||
});
|
||||
|
||||
// Mock market page
|
||||
mockTradingPage(MarketState.Active);
|
||||
|
||||
cy.visit('/');
|
||||
cy.wait('@MarketsLanding');
|
||||
cy.wait('@GQL');
|
||||
|
||||
cy.get('main[data-testid="market"]').should('exist'); // Wait for page to be rendered to before checking url
|
||||
cy.url().should('include', `/markets/${oldestMarket.id}`); // Should redirect to oldest market
|
||||
cy.wait('@MarketList');
|
||||
});
|
||||
|
||||
it('redirects to a default market with the landing dialog open', () => {
|
||||
@ -115,40 +104,31 @@ describe('home', () => {
|
||||
describe('no default found', () => {
|
||||
it('redirects to a the market list page if no sensible default is found', () => {
|
||||
// Mock markets query that is triggered by home page to find default market
|
||||
cy.mockGQL('MarketsLanding', (req) => {
|
||||
if (hasOperationName(req, 'MarketsLanding')) {
|
||||
req.reply({
|
||||
body: {
|
||||
// Remove open timestamps so we can't calculate a sensible default market
|
||||
data: generateMarketsLanding({
|
||||
markets: [
|
||||
{
|
||||
marketTimestamps: {
|
||||
__typename: 'MarketTimestamps',
|
||||
open: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
marketTimestamps: {
|
||||
__typename: 'MarketTimestamps',
|
||||
open: '',
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(
|
||||
req,
|
||||
'MarketsLanding',
|
||||
generateMarketsLanding({
|
||||
markets: [
|
||||
{
|
||||
marketTimestamps: {
|
||||
__typename: 'MarketTimestamps',
|
||||
open: '',
|
||||
},
|
||||
},
|
||||
{
|
||||
marketTimestamps: {
|
||||
__typename: 'MarketTimestamps',
|
||||
open: '',
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
aliasQuery(req, 'Markets', generateMarkets());
|
||||
|
||||
cy.mockGQL('Markets', (req) => {
|
||||
if (hasOperationName(req, 'Markets')) {
|
||||
req.reply({
|
||||
body: {
|
||||
data: generateMarkets(),
|
||||
},
|
||||
});
|
||||
}
|
||||
// Mock all market page queries
|
||||
mockTradingPage(req, MarketState.Active);
|
||||
});
|
||||
|
||||
cy.visit('/');
|
||||
|
@ -1,16 +1,12 @@
|
||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||
import { MarketState } from '@vegaprotocol/types';
|
||||
import { hasOperationName } from '../support';
|
||||
import { generateMarkets } from '../support/mocks/generate-markets';
|
||||
import { mockTradingPage } from '../support/trading';
|
||||
|
||||
describe('markets table', () => {
|
||||
beforeEach(() => {
|
||||
cy.mockGQL('Markets', (req) => {
|
||||
if (hasOperationName(req, 'Markets')) {
|
||||
req.reply({
|
||||
body: { data: generateMarkets() },
|
||||
});
|
||||
}
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'Markets', generateMarkets());
|
||||
});
|
||||
cy.visit('/markets');
|
||||
});
|
||||
@ -64,7 +60,9 @@ describe('markets table', () => {
|
||||
cy.wait('@Markets');
|
||||
cy.get('.ag-root-wrapper').should('be.visible');
|
||||
|
||||
mockTradingPage(MarketState.Active);
|
||||
cy.mockGQL((req) => {
|
||||
mockTradingPage(req, MarketState.Active);
|
||||
});
|
||||
|
||||
// click on active market
|
||||
cy.get('[role="gridcell"][col-id=data]').should('be.visible');
|
||||
@ -79,7 +77,9 @@ describe('markets table', () => {
|
||||
cy.wait('@Markets');
|
||||
cy.get('.ag-root-wrapper').should('be.visible');
|
||||
|
||||
mockTradingPage(MarketState.Suspended);
|
||||
cy.mockGQL((req) => {
|
||||
mockTradingPage(req, MarketState.Suspended);
|
||||
});
|
||||
|
||||
// click on active market
|
||||
cy.get('[role="gridcell"][col-id=data]').should('be.visible');
|
||||
|
@ -3,7 +3,9 @@ import { mockTradingPage } from '../support/trading';
|
||||
import { connectVegaWallet } from '../support/vega-wallet';
|
||||
|
||||
beforeEach(() => {
|
||||
mockTradingPage(MarketState.Active);
|
||||
cy.mockGQL((req) => {
|
||||
mockTradingPage(req, MarketState.Active);
|
||||
});
|
||||
cy.visit('/markets/market-0');
|
||||
});
|
||||
|
||||
|
@ -17,6 +17,16 @@ interface Order {
|
||||
expiresAt?: string;
|
||||
}
|
||||
|
||||
const mockTx = {
|
||||
txHash: 'test-tx-hash',
|
||||
tx: {
|
||||
signature: {
|
||||
value:
|
||||
'd86138bba739bbc1069b3dc975d20b3a1517c2b9bdd401c70eeb1a0ecbc502ec268cf3129824841178b8b506b0b7d650c76644dbd96f524a6cb2158fb7121800',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
describe('deal ticket orders', () => {
|
||||
const orderSizeField = 'order-size';
|
||||
const orderPriceField = 'order-price';
|
||||
@ -26,24 +36,15 @@ describe('deal ticket orders', () => {
|
||||
const orderTransactionHash = 'tx-hash';
|
||||
|
||||
before(() => {
|
||||
mockTradingPage(MarketState.Active);
|
||||
cy.mockGQL((req) => {
|
||||
mockTradingPage(req, MarketState.Active);
|
||||
});
|
||||
cy.visit('/markets/market-0');
|
||||
connectVegaWallet();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
cy.mockVegaCommandSync({
|
||||
txHash: 'test-tx-hash',
|
||||
tx: {
|
||||
signature: {
|
||||
value:
|
||||
'd86138bba739bbc1069b3dc975d20b3a1517c2b9bdd401c70eeb1a0ecbc502ec268cf3129824841178b8b506b0b7d650c76644dbd96f524a6cb2158fb7121800',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('successfully places market buy order', () => {
|
||||
cy.mockVegaCommandSync(mockTx);
|
||||
const order: Order = {
|
||||
type: 'TYPE_MARKET',
|
||||
side: 'SIDE_BUY',
|
||||
@ -54,6 +55,7 @@ describe('deal ticket orders', () => {
|
||||
});
|
||||
|
||||
it('successfully places market sell order', () => {
|
||||
cy.mockVegaCommandSync(mockTx);
|
||||
const order: Order = {
|
||||
type: 'TYPE_MARKET',
|
||||
side: 'SIDE_SELL',
|
||||
@ -64,6 +66,7 @@ describe('deal ticket orders', () => {
|
||||
});
|
||||
|
||||
it('successfully places limit buy order', () => {
|
||||
cy.mockVegaCommandSync(mockTx);
|
||||
const order: Order = {
|
||||
type: 'TYPE_LIMIT',
|
||||
side: 'SIDE_BUY',
|
||||
@ -75,6 +78,7 @@ describe('deal ticket orders', () => {
|
||||
});
|
||||
|
||||
it('successfully places limit sell order', () => {
|
||||
cy.mockVegaCommandSync(mockTx);
|
||||
const order: Order = {
|
||||
type: 'TYPE_LIMIT',
|
||||
side: 'SIDE_SELL',
|
||||
@ -86,6 +90,7 @@ describe('deal ticket orders', () => {
|
||||
});
|
||||
|
||||
it('successfully places GTT limit buy order', () => {
|
||||
cy.mockVegaCommandSync(mockTx);
|
||||
const order: Order = {
|
||||
type: 'TYPE_LIMIT',
|
||||
side: 'SIDE_SELL',
|
||||
@ -152,7 +157,9 @@ describe('deal ticket orders', () => {
|
||||
|
||||
describe('deal ticket validation', () => {
|
||||
before(() => {
|
||||
mockTradingPage(MarketState.Active);
|
||||
cy.mockGQL((req) => {
|
||||
mockTradingPage(req, MarketState.Active);
|
||||
});
|
||||
cy.visit('/markets/market-0');
|
||||
});
|
||||
|
||||
|
@ -3,7 +3,9 @@ import { mockTradingPage } from '../support/trading';
|
||||
import { connectVegaWallet } from '../support/vega-wallet';
|
||||
|
||||
beforeEach(() => {
|
||||
mockTradingPage(MarketState.Active);
|
||||
cy.mockGQL((req) => {
|
||||
mockTradingPage(req, MarketState.Active);
|
||||
});
|
||||
cy.visit('/markets/market-0');
|
||||
});
|
||||
|
||||
|
@ -3,7 +3,9 @@ import { mockTradingPage } from '../support/trading';
|
||||
import { connectVegaWallet } from '../support/vega-wallet';
|
||||
|
||||
beforeEach(() => {
|
||||
mockTradingPage(MarketState.Active);
|
||||
cy.mockGQL((req) => {
|
||||
mockTradingPage(req, MarketState.Active);
|
||||
});
|
||||
cy.visit('/markets/market-0');
|
||||
});
|
||||
|
||||
|
@ -2,7 +2,9 @@ import { MarketState } from '@vegaprotocol/types';
|
||||
import { mockTradingPage } from '../support/trading';
|
||||
|
||||
beforeEach(() => {
|
||||
mockTradingPage(MarketState.Active);
|
||||
cy.mockGQL((req) => {
|
||||
mockTradingPage(req, MarketState.Active);
|
||||
});
|
||||
cy.visit('/markets/market-0');
|
||||
});
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { hasOperationName } from '../support';
|
||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||
import { connectEthereumWallet } from '../support/ethereum-wallet';
|
||||
import { generateWithdrawPageQuery } from '../support/mocks/generate-withdraw-page-query';
|
||||
import { connectVegaWallet } from '../support/vega-wallet';
|
||||
@ -13,12 +13,8 @@ describe('withdraw', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
cy.mockWeb3Provider();
|
||||
cy.mockGQL('WithdrawPageQuery', (req) => {
|
||||
if (hasOperationName(req, 'WithdrawPageQuery')) {
|
||||
req.reply({
|
||||
body: { data: generateWithdrawPageQuery() },
|
||||
});
|
||||
}
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'WithdrawPageQuery', generateWithdrawPageQuery());
|
||||
});
|
||||
cy.visit('/portfolio/withdraw');
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { hasOperationName } from '../support';
|
||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||
import { connectEthereumWallet } from '../support/ethereum-wallet';
|
||||
import { generateWithdrawals } from '../support/mocks/generate-withdrawals';
|
||||
import { connectVegaWallet } from '../support/vega-wallet';
|
||||
@ -6,12 +6,8 @@ import { connectVegaWallet } from '../support/vega-wallet';
|
||||
describe('withdrawals', () => {
|
||||
beforeEach(() => {
|
||||
cy.mockWeb3Provider();
|
||||
cy.mockGQL('Withdrawals', (req) => {
|
||||
if (hasOperationName(req, 'Withdrawals')) {
|
||||
req.reply({
|
||||
body: { data: generateWithdrawals() },
|
||||
});
|
||||
}
|
||||
cy.mockGQL((req) => {
|
||||
aliasQuery(req, 'Withdrawals', generateWithdrawals());
|
||||
});
|
||||
cy.visit('/portfolio/withdrawals');
|
||||
|
||||
|
@ -1,11 +1 @@
|
||||
import '@vegaprotocol/cypress';
|
||||
import type { CyHttpMessages } from 'cypress/types/net-stubbing';
|
||||
|
||||
// Utility to match GraphQL mutation based on the operation name
|
||||
export const hasOperationName = (
|
||||
req: CyHttpMessages.IncomingHttpRequest,
|
||||
operationName: string
|
||||
) => {
|
||||
const { body } = req;
|
||||
return 'operationName' in body && body.operationName === operationName;
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||
import type { MarketState } from '@vegaprotocol/types';
|
||||
import { hasOperationName } from '.';
|
||||
import type { CyHttpMessages } from 'cypress/types/net-stubbing';
|
||||
import { generateAccounts } from './mocks/generate-accounts';
|
||||
import { generateCandles } from './mocks/generate-candles';
|
||||
import { generateChart } from './mocks/generate-chart';
|
||||
@ -9,62 +10,28 @@ import { generateOrders } from './mocks/generate-orders';
|
||||
import { generatePositions } from './mocks/generate-positions';
|
||||
import { generateTrades } from './mocks/generate-trades';
|
||||
|
||||
export const mockTradingPage = (state: MarketState) => {
|
||||
cy.mockGQL('Market', (req) => {
|
||||
if (hasOperationName(req, 'Market')) {
|
||||
req.reply({
|
||||
body: {
|
||||
data: generateMarket({
|
||||
market: {
|
||||
name: `${state.toUpperCase()} MARKET`,
|
||||
},
|
||||
}),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (hasOperationName(req, 'Orders')) {
|
||||
req.reply({
|
||||
body: { data: generateOrders() },
|
||||
});
|
||||
}
|
||||
|
||||
if (hasOperationName(req, 'Accounts')) {
|
||||
req.reply({
|
||||
body: {
|
||||
data: generateAccounts(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (hasOperationName(req, 'Positions')) {
|
||||
req.reply({
|
||||
body: { data: generatePositions() },
|
||||
});
|
||||
}
|
||||
|
||||
if (hasOperationName(req, 'DealTicketQuery')) {
|
||||
req.reply({
|
||||
body: { data: generateDealTicketQuery({ market: { state } }) },
|
||||
});
|
||||
}
|
||||
|
||||
if (hasOperationName(req, 'Trades')) {
|
||||
req.reply({
|
||||
body: { data: generateTrades() },
|
||||
});
|
||||
}
|
||||
|
||||
if (hasOperationName(req, 'Chart')) {
|
||||
req.reply({
|
||||
body: { data: generateChart() },
|
||||
});
|
||||
}
|
||||
|
||||
if (hasOperationName(req, 'Candles')) {
|
||||
req.reply({
|
||||
body: { data: generateCandles() },
|
||||
});
|
||||
}
|
||||
});
|
||||
export const mockTradingPage = (
|
||||
req: CyHttpMessages.IncomingHttpRequest,
|
||||
state: MarketState
|
||||
) => {
|
||||
aliasQuery(
|
||||
req,
|
||||
'Market',
|
||||
generateMarket({
|
||||
market: {
|
||||
name: `${state.toUpperCase()} MARKET`,
|
||||
},
|
||||
})
|
||||
);
|
||||
aliasQuery(req, 'Orders', generateOrders());
|
||||
aliasQuery(req, 'Accounts', generateAccounts());
|
||||
aliasQuery(req, 'Positions', generatePositions());
|
||||
aliasQuery(
|
||||
req,
|
||||
'DealTicketQuery',
|
||||
generateDealTicketQuery({ market: { state } })
|
||||
);
|
||||
aliasQuery(req, 'Trades', generateTrades());
|
||||
aliasQuery(req, 'Chart', generateChart());
|
||||
aliasQuery(req, 'Candles', generateCandles());
|
||||
};
|
||||
|
@ -9,3 +9,5 @@ addSlackCommand();
|
||||
addMockGQLCommand();
|
||||
addMockVegaWalletCommands();
|
||||
addMockWeb3ProviderCommand();
|
||||
|
||||
export * from './lib/graphql-test-utils';
|
||||
|
@ -5,15 +5,15 @@ declare global {
|
||||
namespace Cypress {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
interface Chainable<Subject> {
|
||||
mockGQL(alias: string, handler: RouteHandler): void;
|
||||
mockGQL(handler: RouteHandler): void;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function addMockGQLCommand() {
|
||||
Cypress.Commands.add('mockGQL', (alias: string, handler: RouteHandler) => {
|
||||
Cypress.Commands.add('mockGQL', (handler: RouteHandler) => {
|
||||
cy.intercept('POST', 'https://lb.testnet.vega.xyz/query', handler).as(
|
||||
alias
|
||||
'GQL'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
26
libs/cypress/src/lib/graphql-test-utils.ts
Normal file
26
libs/cypress/src/lib/graphql-test-utils.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import type { CyHttpMessages } from 'cypress/types/net-stubbing';
|
||||
|
||||
export const hasOperationName = (
|
||||
req: CyHttpMessages.IncomingHttpRequest,
|
||||
operationName: string
|
||||
) => {
|
||||
const { body } = req;
|
||||
return 'operationName' in body && body.operationName === operationName;
|
||||
};
|
||||
|
||||
// Alias query if operationName matches
|
||||
export const aliasQuery = (
|
||||
req: CyHttpMessages.IncomingHttpRequest,
|
||||
operationName: string,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
data?: any
|
||||
) => {
|
||||
if (hasOperationName(req, operationName)) {
|
||||
req.alias = operationName;
|
||||
if (data !== undefined) {
|
||||
req.reply((res) => {
|
||||
res.body.data = data;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue
Block a user