test: added tests to cover submit orders ac (#1708)
* test: added tests to cover submit orders ac * fix: unit tests * fix: mock subscription fixed * fix: typo * fix: lint * fix(1593): remove ag-grid api presence check from providder update callbacks * fix: unit tests Co-authored-by: Bartłomiej Głownia <bglownia@gmail.com>
This commit is contained in:
parent
5152e3f603
commit
50df63c858
@ -22,15 +22,9 @@ const AccountsManager = () => {
|
|||||||
const variables = useMemo(() => ({ partyId }), [partyId]);
|
const variables = useMemo(() => ({ partyId }), [partyId]);
|
||||||
const update = useCallback(
|
const update = useCallback(
|
||||||
({ data }: { data: AccountFields[] | null }) => {
|
({ data }: { data: AccountFields[] | null }) => {
|
||||||
if (!gridRef.current?.api) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (dataRef.current?.length) {
|
|
||||||
dataRef.current = data;
|
dataRef.current = data;
|
||||||
gridRef.current.api.refreshInfiniteCache();
|
gridRef.current?.api.refreshInfiniteCache();
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
[gridRef]
|
[gridRef]
|
||||||
);
|
);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { MarketState, MarketTradingModeMapping } from '@vegaprotocol/types';
|
import { MarketState, MarketTradingModeMapping } from '@vegaprotocol/types';
|
||||||
import { mockTradingPage } from '../support/trading';
|
import { mockTradingPage } from '../support/trading';
|
||||||
|
import { connectVegaWallet } from '../support/vega-wallet';
|
||||||
|
|
||||||
const marketInfoBtn = 'Info';
|
const marketInfoBtn = 'Info';
|
||||||
const row = 'key-value-table-row';
|
const row = 'key-value-table-row';
|
||||||
@ -201,3 +202,45 @@ describe('market info is displayed', { tags: '@smoke' }, () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('market states', { tags: '@smoke' }, function () {
|
||||||
|
//7002-SORD-062
|
||||||
|
//7002-SORD-063
|
||||||
|
//7002-SORD-066
|
||||||
|
|
||||||
|
const states = [
|
||||||
|
MarketState.STATE_REJECTED,
|
||||||
|
MarketState.STATE_CANCELLED,
|
||||||
|
MarketState.STATE_CLOSED,
|
||||||
|
MarketState.STATE_SETTLED,
|
||||||
|
MarketState.STATE_TRADING_TERMINATED,
|
||||||
|
];
|
||||||
|
|
||||||
|
states.forEach((marketState) => {
|
||||||
|
describe(marketState, function () {
|
||||||
|
before(function () {
|
||||||
|
cy.mockGQL((req) => {
|
||||||
|
mockTradingPage(req, marketState);
|
||||||
|
});
|
||||||
|
cy.mockGQLSubscription();
|
||||||
|
cy.visit('/markets/market-0');
|
||||||
|
cy.wait('@Market');
|
||||||
|
connectVegaWallet();
|
||||||
|
});
|
||||||
|
it.skip('must display correct market state');
|
||||||
|
//7002-/SORD-/061 no state displayed
|
||||||
|
it('must display that market is not accepting orders', function () {
|
||||||
|
cy.getByTestId('dealticket-error-message').should(
|
||||||
|
'have.text',
|
||||||
|
`This market is ${marketState
|
||||||
|
.split('_')
|
||||||
|
.pop()
|
||||||
|
?.toLowerCase()} and not accepting orders`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('must have place order button disabled', function () {
|
||||||
|
cy.getByTestId('place-order').should('be.disabled');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -30,13 +30,15 @@ describe('markets table', { tags: '@regression' }, () => {
|
|||||||
cy.wait('@MarketsCandles');
|
cy.wait('@MarketsCandles');
|
||||||
openMarketDropDown();
|
openMarketDropDown();
|
||||||
cy.getByTestId('price').invoke('text').should('not.be.empty');
|
cy.getByTestId('price').invoke('text').should('not.be.empty');
|
||||||
cy.getByTestId('trading-mode').should('not.be.empty');
|
cy.getByTestId('trading-mode-col').should('not.be.empty');
|
||||||
cy.getByTestId('taker-fee').should('contain.text', '%');
|
cy.getByTestId('taker-fee').should('contain.text', '%');
|
||||||
cy.getByTestId('market-volume').should('not.be.empty');
|
cy.getByTestId('market-volume').should('not.be.empty');
|
||||||
cy.getByTestId('market-name').should('not.be.empty');
|
cy.getByTestId('market-name').should('not.be.empty');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Able to select market from dropdown', () => {
|
it('Able to select market from dropdown', () => {
|
||||||
|
// 7002-SORD-001
|
||||||
|
// 7002-SORD-002
|
||||||
cy.visit('/');
|
cy.visit('/');
|
||||||
cy.wait('@Markets');
|
cy.wait('@Markets');
|
||||||
cy.wait('@MarketsData');
|
cy.wait('@MarketsData');
|
||||||
@ -47,6 +49,7 @@ describe('markets table', { tags: '@regression' }, () => {
|
|||||||
cy.wait('@Market');
|
cy.wait('@Market');
|
||||||
cy.contains('ACTIVE MARKET');
|
cy.contains('ACTIVE MARKET');
|
||||||
cy.url().should('include', '/markets/market-0');
|
cy.url().should('include', '/markets/market-0');
|
||||||
|
cy.getByTestId('popover-trigger').should('not.be.empty');
|
||||||
verifyMarketSummaryDisplayed();
|
verifyMarketSummaryDisplayed();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -103,7 +106,7 @@ describe('markets table', { tags: '@regression' }, () => {
|
|||||||
cy.visit('/markets/market-0');
|
cy.visit('/markets/market-0');
|
||||||
cy.wait('@Market');
|
cy.wait('@Market');
|
||||||
|
|
||||||
cy.getByTestId('trading-mode').eq(0).realHover();
|
cy.getByTestId('trading-mode').realHover();
|
||||||
cy.getByTestId('tooltip-market-info').within(() => {
|
cy.getByTestId('tooltip-market-info').within(() => {
|
||||||
cy.get('span')
|
cy.get('span')
|
||||||
.eq(0)
|
.eq(0)
|
||||||
@ -141,6 +144,7 @@ describe('markets table', { tags: '@regression' }, () => {
|
|||||||
const tradingMode = 'trading-mode';
|
const tradingMode = 'trading-mode';
|
||||||
|
|
||||||
cy.getByTestId(marketSummaryBlock).within(() => {
|
cy.getByTestId(marketSummaryBlock).within(() => {
|
||||||
|
cy.getByTestId('trading-mode').should('not.be.empty');
|
||||||
cy.contains('Change (24h)');
|
cy.contains('Change (24h)');
|
||||||
cy.getByTestId(percentageValue).should('not.be.empty');
|
cy.getByTestId(percentageValue).should('not.be.empty');
|
||||||
cy.getByTestId(priceChangeValue).should('not.be.empty');
|
cy.getByTestId(priceChangeValue).should('not.be.empty');
|
||||||
|
@ -1,7 +1,56 @@
|
|||||||
import { MarketState } from '@vegaprotocol/types';
|
import {
|
||||||
|
MarketState,
|
||||||
|
MarketTradingMode,
|
||||||
|
AuctionTrigger,
|
||||||
|
} from '@vegaprotocol/types';
|
||||||
import { mockTradingPage } from '../support/trading';
|
import { mockTradingPage } from '../support/trading';
|
||||||
import { connectVegaWallet } from '../support/vega-wallet';
|
import { connectVegaWallet } from '../support/vega-wallet';
|
||||||
|
|
||||||
|
const orderSizeField = 'order-size';
|
||||||
|
const orderPriceField = 'order-price';
|
||||||
|
const orderTIFDropDown = 'order-tif';
|
||||||
|
const placeOrderBtn = 'place-order';
|
||||||
|
const dialogTitle = 'dialog-title';
|
||||||
|
const orderTransactionHash = 'tx-block-explorer';
|
||||||
|
const toggleShort = 'order-side-SIDE_SELL';
|
||||||
|
const toggleLong = 'order-side-SIDE_BUY';
|
||||||
|
const toggleLimit = 'order-type-TYPE_LIMIT';
|
||||||
|
const toggleMarket = 'order-type-TYPE_MARKET';
|
||||||
|
const errorMessage = 'dealticket-error-message';
|
||||||
|
|
||||||
|
const TIFlist = [
|
||||||
|
{
|
||||||
|
code: 'GTT',
|
||||||
|
value: 'TIME_IN_FORCE_GTT',
|
||||||
|
text: `Good 'til Time (GTT)`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'GTC',
|
||||||
|
value: 'TIME_IN_FORCE_GTC',
|
||||||
|
text: `Good 'til Cancelled (GTC)`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'IOC',
|
||||||
|
value: 'TIME_IN_FORCE_IOC',
|
||||||
|
text: `Immediate or Cancel (IOC)`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'FOK',
|
||||||
|
value: 'TIME_IN_FORCE_FOK',
|
||||||
|
text: `Fill or Kill (FOK)`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'GFN',
|
||||||
|
value: 'TIME_IN_FORCE_GFN',
|
||||||
|
text: `Good for Normal (GFN)`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 'GFA',
|
||||||
|
value: 'TIME_IN_FORCE_GFA',
|
||||||
|
text: `Good for Auction (GFA)`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
interface Order {
|
interface Order {
|
||||||
type: 'TYPE_MARKET' | 'TYPE_LIMIT';
|
type: 'TYPE_MARKET' | 'TYPE_LIMIT';
|
||||||
side: 'SIDE_BUY' | 'SIDE_SELL';
|
side: 'SIDE_BUY' | 'SIDE_SELL';
|
||||||
@ -27,7 +76,52 @@ const mockTx = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('deal ticket orders', { tags: '@smoke' }, () => {
|
const testOrder = (order: Order, expected?: Partial<Order>) => {
|
||||||
|
const { type, side, size, price, timeInForce, expiresAt } = order;
|
||||||
|
|
||||||
|
cy.getByTestId(`order-type-${type}`).click();
|
||||||
|
cy.getByTestId(`order-side-${side}`).click();
|
||||||
|
cy.getByTestId(orderSizeField).clear().type(size);
|
||||||
|
if (price) {
|
||||||
|
cy.getByTestId(orderPriceField).clear().type(price);
|
||||||
|
}
|
||||||
|
cy.getByTestId(orderTIFDropDown).select(timeInForce);
|
||||||
|
if (timeInForce === 'TIME_IN_FORCE_GTT') {
|
||||||
|
if (!expiresAt) {
|
||||||
|
throw new Error('Specify expiresAt if using GTT');
|
||||||
|
}
|
||||||
|
// select expiry
|
||||||
|
cy.getByTestId('date-picker-field').type(expiresAt);
|
||||||
|
}
|
||||||
|
cy.getByTestId(placeOrderBtn).click();
|
||||||
|
|
||||||
|
const expectedOrder = {
|
||||||
|
...order,
|
||||||
|
...expected,
|
||||||
|
};
|
||||||
|
|
||||||
|
cy.wait('@VegaCommandSync')
|
||||||
|
.its('request.body')
|
||||||
|
.should('deep.equal', {
|
||||||
|
pubKey: Cypress.env('VEGA_PUBLIC_KEY'),
|
||||||
|
propagate: true,
|
||||||
|
orderSubmission: {
|
||||||
|
marketId: 'market-0',
|
||||||
|
...expectedOrder,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
cy.getByTestId(dialogTitle).should(
|
||||||
|
'have.text',
|
||||||
|
'Awaiting network confirmation'
|
||||||
|
);
|
||||||
|
cy.getByTestId(orderTransactionHash)
|
||||||
|
.invoke('attr', 'href')
|
||||||
|
.should('include', 'https://explorer.fairground.wtf/txs/0xtest-tx-hash');
|
||||||
|
cy.getByTestId('dialog-close').click();
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('must submit order', { tags: '@smoke' }, () => {
|
||||||
|
// 7002-SORD-039
|
||||||
before(() => {
|
before(() => {
|
||||||
cy.mockGQL((req) => {
|
cy.mockGQL((req) => {
|
||||||
mockTradingPage(req, MarketState.STATE_ACTIVE);
|
mockTradingPage(req, MarketState.STATE_ACTIVE);
|
||||||
@ -39,6 +133,7 @@ describe('deal ticket orders', { tags: '@smoke' }, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('successfully places market buy order', () => {
|
it('successfully places market buy order', () => {
|
||||||
|
//7002-SORD-010
|
||||||
cy.mockVegaCommandSync(mockTx);
|
cy.mockVegaCommandSync(mockTx);
|
||||||
const order: Order = {
|
const order: Order = {
|
||||||
type: 'TYPE_MARKET',
|
type: 'TYPE_MARKET',
|
||||||
@ -61,6 +156,7 @@ describe('deal ticket orders', { tags: '@smoke' }, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('successfully places limit buy order', () => {
|
it('successfully places limit buy order', () => {
|
||||||
|
// 7002-SORD-017
|
||||||
cy.mockVegaCommandSync(mockTx);
|
cy.mockVegaCommandSync(mockTx);
|
||||||
const order: Order = {
|
const order: Order = {
|
||||||
type: 'TYPE_LIMIT',
|
type: 'TYPE_LIMIT',
|
||||||
@ -101,61 +197,10 @@ describe('deal ticket orders', { tags: '@smoke' }, () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const testOrder = (order: Order, expected?: Partial<Order>) => {
|
it.skip('must not allow to place an order if balance is 0 (no collateral)', function () {
|
||||||
const orderSizeField = 'order-size';
|
//7002-/SORD-/003
|
||||||
const orderPriceField = 'order-price';
|
// it will be covered in https://github.com/vegaprotocol/frontend-monorepo/issues/1660
|
||||||
const orderTIFDropDown = 'order-tif';
|
|
||||||
const placeOrderBtn = 'place-order';
|
|
||||||
const dialogTitle = 'dialog-title';
|
|
||||||
const orderTransactionHash = 'tx-block-explorer';
|
|
||||||
|
|
||||||
const { type, side, size, price, timeInForce, expiresAt } = order;
|
|
||||||
|
|
||||||
cy.get(`[name="order-type"][value="${type}"`).click({ force: true }); // force as input is hidden and displayed as a button
|
|
||||||
cy.get(`[name="order-side"][value="${side}"`).click({ force: true });
|
|
||||||
cy.getByTestId(orderSizeField).clear().type(size);
|
|
||||||
if (price) {
|
|
||||||
cy.getByTestId(orderPriceField).clear().type(price);
|
|
||||||
}
|
|
||||||
cy.getByTestId(orderTIFDropDown).select(timeInForce);
|
|
||||||
if (timeInForce === 'TIME_IN_FORCE_GTT') {
|
|
||||||
if (!expiresAt) {
|
|
||||||
throw new Error('Specify expiresAt if using GTT');
|
|
||||||
}
|
|
||||||
// select expiry
|
|
||||||
cy.getByTestId('date-picker-field').type(expiresAt);
|
|
||||||
}
|
|
||||||
cy.getByTestId(placeOrderBtn).click();
|
|
||||||
|
|
||||||
const expectedOrder = {
|
|
||||||
...order,
|
|
||||||
...expected,
|
|
||||||
};
|
|
||||||
|
|
||||||
cy.wait('@VegaCommandSync')
|
|
||||||
.its('request.body')
|
|
||||||
.should('deep.equal', {
|
|
||||||
pubKey: Cypress.env('VEGA_PUBLIC_KEY'),
|
|
||||||
propagate: true,
|
|
||||||
orderSubmission: {
|
|
||||||
marketId: 'market-0',
|
|
||||||
...expectedOrder,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
cy.getByTestId(dialogTitle).should(
|
|
||||||
'have.text',
|
|
||||||
'Awaiting network confirmation'
|
|
||||||
);
|
|
||||||
cy.getByTestId(orderTransactionHash)
|
|
||||||
.invoke('attr', 'href')
|
|
||||||
.should('include', 'https://explorer.fairground.wtf/txs/0xtest-tx-hash');
|
|
||||||
cy.getByTestId('dialog-close').click();
|
|
||||||
};
|
|
||||||
|
|
||||||
it.skip('cannot place an order if market is suspended');
|
|
||||||
it.skip('cannot place an order if size is 0');
|
|
||||||
it.skip('cannot place an order expiry date is invalid');
|
|
||||||
it.skip('unsuccessful order due to no collateral');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('deal ticket validation', { tags: '@smoke' }, () => {
|
describe('deal ticket validation', { tags: '@smoke' }, () => {
|
||||||
@ -164,13 +209,209 @@ describe('deal ticket validation', { tags: '@smoke' }, () => {
|
|||||||
mockTradingPage(req, MarketState.STATE_ACTIVE);
|
mockTradingPage(req, MarketState.STATE_ACTIVE);
|
||||||
});
|
});
|
||||||
cy.visit('/markets/market-0');
|
cy.visit('/markets/market-0');
|
||||||
|
cy.wait('@Market');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('cannot place an order if wallet is not connected', () => {
|
it('must not place an order if wallet is not connected', () => {
|
||||||
cy.getByTestId('connect-vega-wallet'); // Not connected
|
cy.getByTestId('connect-vega-wallet'); // Not connected
|
||||||
cy.getByTestId('place-order').should('be.disabled');
|
cy.getByTestId(placeOrderBtn).should('be.disabled');
|
||||||
cy.getByTestId('dealticket-error-message').contains(
|
cy.getByTestId(errorMessage).contains('No public key selected');
|
||||||
'No public key selected'
|
});
|
||||||
|
|
||||||
|
it('must be able to select order direction - long/short', function () {
|
||||||
|
//7002-SORD-004
|
||||||
|
cy.getByTestId(toggleShort).click().children('input').should('be.checked');
|
||||||
|
cy.getByTestId(toggleLong).click().children('input').should('be.checked');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('must be able to select order type - limit/market', function () {
|
||||||
|
//7002-SORD-005
|
||||||
|
//7002-SORD-006
|
||||||
|
//7002-SORD-007
|
||||||
|
cy.getByTestId(toggleLimit).click().children('input').should('be.checked');
|
||||||
|
cy.getByTestId(toggleMarket).click().children('input').should('be.checked');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('deal ticket size validation', { tags: '@smoke' }, function () {
|
||||||
|
before(() => {
|
||||||
|
cy.mockGQL((req) => {
|
||||||
|
mockTradingPage(req, MarketState.STATE_ACTIVE);
|
||||||
|
});
|
||||||
|
cy.visit('/markets/market-0');
|
||||||
|
cy.wait('@Market');
|
||||||
|
connectVegaWallet();
|
||||||
|
});
|
||||||
|
it('must warn if order size input has too many digits after the decimal place', function () {
|
||||||
|
//7002-SORD-016
|
||||||
|
cy.getByTestId(orderSizeField).clear().type('1.234');
|
||||||
|
cy.getByTestId(placeOrderBtn).should('be.disabled');
|
||||||
|
cy.getByTestId(errorMessage).should(
|
||||||
|
'have.text',
|
||||||
|
'Order sizes must be in whole numbers for this market'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('must warn if order size is set to 0', function () {
|
||||||
|
cy.getByTestId(orderSizeField).clear().type('0');
|
||||||
|
cy.getByTestId(placeOrderBtn).should('be.disabled');
|
||||||
|
cy.getByTestId(errorMessage).should(
|
||||||
|
'have.text',
|
||||||
|
'Size cannot be lower than "1"'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('limit order validations', { tags: '@smoke' }, () => {
|
||||||
|
before(() => {
|
||||||
|
cy.mockGQL((req) => {
|
||||||
|
mockTradingPage(req, MarketState.STATE_ACTIVE);
|
||||||
|
});
|
||||||
|
cy.visit('/markets/market-0');
|
||||||
|
cy.wait('@Market');
|
||||||
|
cy.getByTestId(toggleLimit).click();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('must see the price unit', function () {
|
||||||
|
//7002-SORD-018
|
||||||
|
cy.getByTestId(orderPriceField)
|
||||||
|
.siblings('label')
|
||||||
|
.should('have.text', 'Price (BTC)');
|
||||||
|
});
|
||||||
|
|
||||||
|
it.skip('must see warning when placing an order with expiry date in past', function () {
|
||||||
|
// Test to be created after the bug below is fixed
|
||||||
|
// https://github.com/vegaprotocol/frontend-monorepo/issues/1694
|
||||||
|
});
|
||||||
|
|
||||||
|
it.skip('must receive warning if price has too many digits after decimal place', function () {
|
||||||
|
//7002/-SORD-/059
|
||||||
|
// Skipped until https://github.com/vegaprotocol/frontend-monorepo/issues/1686 resolved
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('time in force validations', function () {
|
||||||
|
it('must have limit order set to GTC by default', function () {
|
||||||
|
//7002-SORD-031
|
||||||
|
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
|
||||||
|
'have.text',
|
||||||
|
TIFlist.filter((item) => item.code === 'GTC')[0].text
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const validTIF = TIFlist;
|
||||||
|
validTIF.forEach((tif) => {
|
||||||
|
//7002-SORD-023
|
||||||
|
//7002-SORD-024
|
||||||
|
//7002-SORD-025
|
||||||
|
//7002-SORD-026
|
||||||
|
//7002-SORD-027
|
||||||
|
//7002-SORD-028
|
||||||
|
|
||||||
|
it(`must be able to select ${tif.code}`, function () {
|
||||||
|
cy.getByTestId(orderTIFDropDown).select(tif.value);
|
||||||
|
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
|
||||||
|
'have.text',
|
||||||
|
tif.text
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('market order validations', { tags: '@smoke' }, () => {
|
||||||
|
before(() => {
|
||||||
|
cy.mockGQL((req) => {
|
||||||
|
mockTradingPage(req, MarketState.STATE_ACTIVE);
|
||||||
|
});
|
||||||
|
cy.visit('/markets/market-0');
|
||||||
|
cy.wait('@Market');
|
||||||
|
cy.getByTestId(toggleMarket).click();
|
||||||
|
});
|
||||||
|
it('must not see the price unit', function () {
|
||||||
|
//7002-SORD-019
|
||||||
|
cy.getByTestId(orderPriceField).should('not.exist');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('time in force validations', function () {
|
||||||
|
it('must have market order set up to IOC by default', function () {
|
||||||
|
//7002-SORD-031
|
||||||
|
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
|
||||||
|
'have.text',
|
||||||
|
TIFlist.filter((item) => item.code === 'IOC')[0].text
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const validTIF = TIFlist.filter((tif) => ['FOK', 'IOC'].includes(tif.code));
|
||||||
|
const invalidTIF = TIFlist.filter(
|
||||||
|
(tif) => !['FOK', 'IOC'].includes(tif.code)
|
||||||
|
);
|
||||||
|
|
||||||
|
validTIF.forEach((tif) => {
|
||||||
|
//7002-SORD-025
|
||||||
|
//7002-SORD-026
|
||||||
|
|
||||||
|
it(`must be able to select ${tif.code}`, function () {
|
||||||
|
cy.getByTestId(orderTIFDropDown).select(tif.value);
|
||||||
|
cy.get(`[data-testid=${orderTIFDropDown}] option:selected`).should(
|
||||||
|
'have.text',
|
||||||
|
tif.text
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
invalidTIF.forEach((tif) => {
|
||||||
|
//7002-SORD-023
|
||||||
|
//7002-SORD-024
|
||||||
|
//7002-SORD-027
|
||||||
|
//7002-SORD-028
|
||||||
|
it(`must not be able to select ${tif.code}`, function () {
|
||||||
|
cy.getByTestId(orderTIFDropDown).should('not.contain', tif.text);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('suspended market validation', { tags: '@regression' }, () => {
|
||||||
|
before(() => {
|
||||||
|
cy.mockGQL((req) => {
|
||||||
|
mockTradingPage(
|
||||||
|
req,
|
||||||
|
MarketState.STATE_SUSPENDED,
|
||||||
|
MarketTradingMode.TRADING_MODE_MONITORING_AUCTION,
|
||||||
|
AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY
|
||||||
|
);
|
||||||
|
});
|
||||||
|
cy.visit('/markets/market-0');
|
||||||
|
cy.wait('@Market');
|
||||||
|
connectVegaWallet();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show warning for market order', function () {
|
||||||
|
cy.getByTestId(toggleMarket).click();
|
||||||
|
cy.getByTestId(placeOrderBtn).should('be.disabled');
|
||||||
|
cy.getByTestId(errorMessage).should(
|
||||||
|
'have.text',
|
||||||
|
'This market is in auction until it reaches sufficient liquidity. Only limit orders are permitted when market is in auction'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
it('should show info for allowed TIF', function () {
|
||||||
|
cy.getByTestId(toggleLimit).click();
|
||||||
|
cy.getByTestId(placeOrderBtn).should('be.enabled');
|
||||||
|
cy.getByTestId(errorMessage).should(
|
||||||
|
'have.text',
|
||||||
|
'Any orders placed now will not trade until the auction ends'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should show warning for not allowed TIF', function () {
|
||||||
|
cy.getByTestId(toggleLimit).click();
|
||||||
|
cy.getByTestId(orderTIFDropDown).select(
|
||||||
|
TIFlist.filter((item) => item.code === 'FOK')[0].value
|
||||||
|
);
|
||||||
|
cy.getByTestId(placeOrderBtn).should('be.disabled');
|
||||||
|
cy.getByTestId(errorMessage).should(
|
||||||
|
'have.text',
|
||||||
|
'This market is in auction until it reaches sufficient liquidity. Until the auction ends, you can only place GFA, GTT, or GTC limit orders'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,34 +1,15 @@
|
|||||||
import { MarketState } from '@vegaprotocol/types';
|
import {
|
||||||
|
MarketState,
|
||||||
|
OrderRejectionReason,
|
||||||
|
OrderStatus,
|
||||||
|
} from '@vegaprotocol/types';
|
||||||
import { mockTradingPage } from '../support/trading';
|
import { mockTradingPage } from '../support/trading';
|
||||||
import type { onMessage } from '@vegaprotocol/cypress';
|
|
||||||
import type {
|
|
||||||
OrderSub as OrderSubData,
|
|
||||||
OrderSubVariables,
|
|
||||||
} from '@vegaprotocol/orders';
|
|
||||||
import { connectVegaWallet } from '../support/vega-wallet';
|
import { connectVegaWallet } from '../support/vega-wallet';
|
||||||
|
import {
|
||||||
|
updateOrder,
|
||||||
|
getSubscriptionMocks,
|
||||||
|
} from '../support/mocks/generate-ws-order-update';
|
||||||
|
|
||||||
const onOrderSub: onMessage<OrderSubData, OrderSubVariables> = function (send) {
|
|
||||||
send({
|
|
||||||
orders: [],
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const subscriptionMocks = { OrderSub: onOrderSub };
|
|
||||||
|
|
||||||
before(() => {
|
|
||||||
cy.spy(subscriptionMocks, 'OrderSub');
|
|
||||||
cy.mockGQL((req) => {
|
|
||||||
mockTradingPage(req, MarketState.STATE_ACTIVE);
|
|
||||||
});
|
|
||||||
cy.mockGQLSubscription(subscriptionMocks);
|
|
||||||
cy.visit('/markets/market-0');
|
|
||||||
cy.getByTestId('Orders').click();
|
|
||||||
cy.getByTestId('tab-orders').contains('Please connect Vega wallet');
|
|
||||||
|
|
||||||
connectVegaWallet();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('orders', { tags: '@smoke' }, () => {
|
|
||||||
const orderSymbol = 'market.tradableInstrument.instrument.code';
|
const orderSymbol = 'market.tradableInstrument.instrument.code';
|
||||||
const orderSize = 'size';
|
const orderSize = 'size';
|
||||||
const orderType = 'type';
|
const orderType = 'type';
|
||||||
@ -40,6 +21,22 @@ describe('orders', { tags: '@smoke' }, () => {
|
|||||||
const cancelOrderBtn = 'cancel';
|
const cancelOrderBtn = 'cancel';
|
||||||
const editOrderBtn = 'edit';
|
const editOrderBtn = 'edit';
|
||||||
|
|
||||||
|
describe('orders list', { tags: '@smoke' }, () => {
|
||||||
|
before(() => {
|
||||||
|
const subscriptionMocks = getSubscriptionMocks();
|
||||||
|
cy.spy(subscriptionMocks, 'OrderSub');
|
||||||
|
cy.mockGQL((req) => {
|
||||||
|
mockTradingPage(req, MarketState.STATE_ACTIVE);
|
||||||
|
});
|
||||||
|
cy.mockGQLSubscription(subscriptionMocks);
|
||||||
|
cy.visit('/markets/market-0');
|
||||||
|
cy.getByTestId('Orders').click();
|
||||||
|
cy.getByTestId('tab-orders').contains('Please connect Vega wallet');
|
||||||
|
connectVegaWallet();
|
||||||
|
cy.wait('@Orders').then(() => {
|
||||||
|
expect(subscriptionMocks.OrderSub).to.be.calledOnce;
|
||||||
|
});
|
||||||
|
});
|
||||||
it('renders orders', () => {
|
it('renders orders', () => {
|
||||||
cy.getByTestId('tab-orders').should('be.visible');
|
cy.getByTestId('tab-orders').should('be.visible');
|
||||||
|
|
||||||
@ -130,3 +127,141 @@ describe('orders', { tags: '@smoke' }, () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('subscribe orders', { tags: '@smoke' }, () => {
|
||||||
|
before(() => {
|
||||||
|
const subscriptionMocks = getSubscriptionMocks();
|
||||||
|
cy.spy(subscriptionMocks, 'OrderSub');
|
||||||
|
cy.mockGQL((req) => {
|
||||||
|
mockTradingPage(req, MarketState.STATE_ACTIVE);
|
||||||
|
});
|
||||||
|
cy.mockGQLSubscription(subscriptionMocks);
|
||||||
|
cy.visit('/markets/market-0');
|
||||||
|
cy.getByTestId('Orders').click();
|
||||||
|
cy.getByTestId('tab-orders').contains('Please connect Vega wallet');
|
||||||
|
connectVegaWallet();
|
||||||
|
cy.wait('@Orders').then(() => {
|
||||||
|
expect(subscriptionMocks.OrderSub).to.be.calledOnce;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
const orderId = '1234567890';
|
||||||
|
//7002-SORD-053
|
||||||
|
//7002-SORD-040
|
||||||
|
it('must see an active order', () => {
|
||||||
|
// 7002-SORD-041
|
||||||
|
updateOrder({
|
||||||
|
id: orderId,
|
||||||
|
status: OrderStatus.STATUS_ACTIVE,
|
||||||
|
});
|
||||||
|
cy.get(`[row-id=${orderId}]`)
|
||||||
|
.should('be.visible')
|
||||||
|
.within(() => {
|
||||||
|
cy.get(`[col-id=${orderStatus}]`).should('have.text', 'Active');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('must see an expired order', () => {
|
||||||
|
// 7002-SORD-042
|
||||||
|
updateOrder({
|
||||||
|
id: orderId,
|
||||||
|
status: OrderStatus.STATUS_EXPIRED,
|
||||||
|
});
|
||||||
|
cy.get(`[row-id=${orderId}]`)
|
||||||
|
.should('be.visible')
|
||||||
|
.within(() => {
|
||||||
|
cy.get(`[col-id=${orderStatus}]`).should('have.text', 'Expired');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('must see a cancelled order', () => {
|
||||||
|
// 7002-SORD-043
|
||||||
|
// NOT COVERED: see the txn that cancelled it and a link to the block explorer, if cancelled by a user transaction.
|
||||||
|
updateOrder({
|
||||||
|
id: orderId,
|
||||||
|
status: OrderStatus.STATUS_CANCELLED,
|
||||||
|
});
|
||||||
|
cy.get(`[row-id=${orderId}]`)
|
||||||
|
.should('be.visible')
|
||||||
|
.within(() => {
|
||||||
|
cy.get(`[col-id=${orderStatus}]`).should('have.text', 'Cancelled');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('must see a stopped order', () => {
|
||||||
|
// 7002-SORD-044
|
||||||
|
// NOT COVERED: see an explanation of why stopped
|
||||||
|
updateOrder({
|
||||||
|
id: orderId,
|
||||||
|
status: OrderStatus.STATUS_STOPPED,
|
||||||
|
});
|
||||||
|
cy.get(`[row-id=${orderId}]`)
|
||||||
|
.should('be.visible')
|
||||||
|
.within(() => {
|
||||||
|
cy.get(`[col-id=${orderStatus}]`).should('have.text', 'Stopped');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('must see a partially filled order', () => {
|
||||||
|
// 7002-SORD-045
|
||||||
|
updateOrder({
|
||||||
|
id: orderId,
|
||||||
|
status: OrderStatus.STATUS_PARTIALLY_FILLED,
|
||||||
|
size: '5',
|
||||||
|
remaining: '1',
|
||||||
|
});
|
||||||
|
cy.get(`[row-id=${orderId}]`)
|
||||||
|
.should('be.visible')
|
||||||
|
.within(() => {
|
||||||
|
cy.get(`[col-id=${orderStatus}]`).should(
|
||||||
|
'have.text',
|
||||||
|
'PartiallyFilled'
|
||||||
|
);
|
||||||
|
cy.get(`[col-id=${orderRemaining}]`).should('have.text', '4/5');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('must see a filled order', () => {
|
||||||
|
// 7002-SORD-046
|
||||||
|
// NOT COVERED: Must be able to see/link to all trades that were created from this order
|
||||||
|
updateOrder({
|
||||||
|
id: orderId,
|
||||||
|
status: OrderStatus.STATUS_FILLED,
|
||||||
|
});
|
||||||
|
cy.get(`[row-id=${orderId}]`)
|
||||||
|
.should('be.visible')
|
||||||
|
.within(() => {
|
||||||
|
cy.get(`[col-id=${orderStatus}]`).should('have.text', 'Filled');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('must see a rejected order', () => {
|
||||||
|
// 7002-SORD-047
|
||||||
|
updateOrder({
|
||||||
|
id: orderId,
|
||||||
|
status: OrderStatus.STATUS_REJECTED,
|
||||||
|
rejectionReason: OrderRejectionReason.ORDER_ERROR_INTERNAL_ERROR,
|
||||||
|
});
|
||||||
|
cy.get(`[row-id=${orderId}]`)
|
||||||
|
.should('be.visible')
|
||||||
|
.within(() => {
|
||||||
|
cy.get(`[col-id=${orderStatus}]`).should(
|
||||||
|
'have.text',
|
||||||
|
'Rejected: Internal error'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('must see a parked order', () => {
|
||||||
|
// 7002-SORD-048
|
||||||
|
// NOT COVERED: must see an explanation of why parked orders happen
|
||||||
|
updateOrder({
|
||||||
|
id: orderId,
|
||||||
|
status: OrderStatus.STATUS_PARKED,
|
||||||
|
});
|
||||||
|
cy.get(`[row-id=${orderId}]`)
|
||||||
|
.should('be.visible')
|
||||||
|
.within(() => {
|
||||||
|
cy.get(`[col-id=${orderStatus}]`).should('have.text', 'Parked');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
import merge from 'lodash/merge';
|
||||||
|
import type {
|
||||||
|
OrderSub as OrderSubData,
|
||||||
|
OrderSubVariables,
|
||||||
|
OrderSub_orders,
|
||||||
|
} from '@vegaprotocol/orders';
|
||||||
|
|
||||||
|
import type { onMessage } from '@vegaprotocol/cypress';
|
||||||
|
import {
|
||||||
|
OrderStatus,
|
||||||
|
OrderTimeInForce,
|
||||||
|
OrderType,
|
||||||
|
Side,
|
||||||
|
} from '@vegaprotocol/types';
|
||||||
|
import type { PartialDeep } from 'type-fest';
|
||||||
|
let sendOrderUpdate: (data: OrderSubData) => void;
|
||||||
|
const getOnOrderSub = () => {
|
||||||
|
const onOrderSub: onMessage<OrderSubData, OrderSubVariables> = (send) => {
|
||||||
|
sendOrderUpdate = send;
|
||||||
|
};
|
||||||
|
return onOrderSub;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getSubscriptionMocks = () => ({ OrderSub: getOnOrderSub() });
|
||||||
|
|
||||||
|
export function updateOrder(override?: PartialDeep<OrderSub_orders>): void {
|
||||||
|
const order: OrderSub_orders = {
|
||||||
|
__typename: 'OrderUpdate',
|
||||||
|
id: '1234567890',
|
||||||
|
marketId: 'market-0',
|
||||||
|
size: '10',
|
||||||
|
type: OrderType.TYPE_LIMIT,
|
||||||
|
status: OrderStatus.STATUS_FILLED,
|
||||||
|
rejectionReason: null,
|
||||||
|
side: Side.SIDE_BUY,
|
||||||
|
remaining: '0',
|
||||||
|
price: '20000000',
|
||||||
|
timeInForce: OrderTimeInForce.TIME_IN_FORCE_GTC,
|
||||||
|
createdAt: new Date(2020, 1, 30).toISOString(),
|
||||||
|
updatedAt: null,
|
||||||
|
expiresAt: null,
|
||||||
|
liquidityProvisionId: null,
|
||||||
|
peggedOrder: null,
|
||||||
|
};
|
||||||
|
const update: OrderSubData = {
|
||||||
|
orders: [merge(order, override)],
|
||||||
|
};
|
||||||
|
if (!sendOrderUpdate) {
|
||||||
|
throw new Error('OrderSub not called');
|
||||||
|
}
|
||||||
|
sendOrderUpdate(update);
|
||||||
|
}
|
@ -1,5 +1,9 @@
|
|||||||
import { aliasQuery } from '@vegaprotocol/cypress';
|
import { aliasQuery } from '@vegaprotocol/cypress';
|
||||||
import type { MarketState } from '@vegaprotocol/types';
|
import type {
|
||||||
|
MarketState,
|
||||||
|
MarketTradingMode,
|
||||||
|
AuctionTrigger,
|
||||||
|
} from '@vegaprotocol/types';
|
||||||
import type { CyHttpMessages } from 'cypress/types/net-stubbing';
|
import type { CyHttpMessages } from 'cypress/types/net-stubbing';
|
||||||
import { generateAccounts } from './mocks/generate-accounts';
|
import { generateAccounts } from './mocks/generate-accounts';
|
||||||
import { generateAsset, generateAssets } from './mocks/generate-assets';
|
import { generateAsset, generateAssets } from './mocks/generate-assets';
|
||||||
@ -20,7 +24,9 @@ import { generateTrades } from './mocks/generate-trades';
|
|||||||
|
|
||||||
export const mockTradingPage = (
|
export const mockTradingPage = (
|
||||||
req: CyHttpMessages.IncomingHttpRequest,
|
req: CyHttpMessages.IncomingHttpRequest,
|
||||||
state: MarketState
|
state: MarketState,
|
||||||
|
tradingMode?: MarketTradingMode,
|
||||||
|
trigger?: AuctionTrigger
|
||||||
) => {
|
) => {
|
||||||
aliasQuery(
|
aliasQuery(
|
||||||
req,
|
req,
|
||||||
@ -33,6 +39,7 @@ export const mockTradingPage = (
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
state: state,
|
state: state,
|
||||||
|
tradingMode: tradingMode,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -45,14 +52,34 @@ export const mockTradingPage = (
|
|||||||
aliasQuery(req, 'Accounts', generateAccounts());
|
aliasQuery(req, 'Accounts', generateAccounts());
|
||||||
aliasQuery(req, 'Positions', generatePositions());
|
aliasQuery(req, 'Positions', generatePositions());
|
||||||
aliasQuery(req, 'Margins', generateMargins());
|
aliasQuery(req, 'Margins', generateMargins());
|
||||||
aliasQuery(req, 'DealTicket', generateDealTicketQuery({ market: { state } }));
|
aliasQuery(
|
||||||
|
req,
|
||||||
|
'DealTicket',
|
||||||
|
generateDealTicketQuery({
|
||||||
|
market: {
|
||||||
|
state,
|
||||||
|
tradingMode: tradingMode,
|
||||||
|
data: {
|
||||||
|
trigger: trigger,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
aliasQuery(req, 'Assets', generateAssets());
|
aliasQuery(req, 'Assets', generateAssets());
|
||||||
aliasQuery(req, 'Asset', generateAsset());
|
aliasQuery(req, 'Asset', generateAsset());
|
||||||
|
|
||||||
aliasQuery(
|
aliasQuery(
|
||||||
req,
|
req,
|
||||||
'MarketInfoQuery',
|
'MarketInfoQuery',
|
||||||
generateMarketInfoQuery({ market: { state } })
|
generateMarketInfoQuery({
|
||||||
|
market: {
|
||||||
|
state,
|
||||||
|
tradingMode: tradingMode,
|
||||||
|
data: {
|
||||||
|
trigger: trigger,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
);
|
);
|
||||||
aliasQuery(req, 'Trades', generateTrades());
|
aliasQuery(req, 'Trades', generateTrades());
|
||||||
aliasQuery(req, 'Chart', generateChart());
|
aliasQuery(req, 'Chart', generateChart());
|
||||||
|
@ -290,7 +290,7 @@ export const columns = (
|
|||||||
: MarketTradingModeMapping[market.tradingMode],
|
: MarketTradingModeMapping[market.tradingMode],
|
||||||
className: `${cellClassNames} hidden lg:table-cell`,
|
className: `${cellClassNames} hidden lg:table-cell`,
|
||||||
onlyOnDetailed: true,
|
onlyOnDetailed: true,
|
||||||
dataTestId: 'trading-mode',
|
dataTestId: 'trading-mode-col',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
kind: ColumnKind.Volume,
|
kind: ColumnKind.Volume,
|
||||||
@ -471,7 +471,7 @@ export const columnsPositionMarkets = (
|
|||||||
: MarketTradingModeMapping[market.tradingMode],
|
: MarketTradingModeMapping[market.tradingMode],
|
||||||
className: `${cellClassNames} hidden lg:table-cell`,
|
className: `${cellClassNames} hidden lg:table-cell`,
|
||||||
onlyOnDetailed: true,
|
onlyOnDetailed: true,
|
||||||
dataTestId: 'trading-mode',
|
dataTestId: 'trading-mode-col',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
kind: ColumnKind.Volume,
|
kind: ColumnKind.Volume,
|
||||||
|
@ -26,15 +26,9 @@ export const AccountManager = ({
|
|||||||
const variables = useMemo(() => ({ partyId }), [partyId]);
|
const variables = useMemo(() => ({ partyId }), [partyId]);
|
||||||
const update = useCallback(
|
const update = useCallback(
|
||||||
({ data }: { data: AccountFields[] | null }) => {
|
({ data }: { data: AccountFields[] | null }) => {
|
||||||
if (!gridRef.current?.api) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (dataRef.current?.length) {
|
|
||||||
dataRef.current = data;
|
dataRef.current = data;
|
||||||
gridRef.current.api.refreshInfiniteCache();
|
gridRef.current?.api.refreshInfiniteCache();
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
[gridRef]
|
[gridRef]
|
||||||
);
|
);
|
||||||
|
@ -63,14 +63,14 @@ describe('DealTicket', () => {
|
|||||||
|
|
||||||
// Assert defaults are used
|
// Assert defaults are used
|
||||||
expect(
|
expect(
|
||||||
screen.getByTestId(`order-type-${Schema.OrderType.TYPE_MARKET}-selected`)
|
screen.getByTestId(`order-type-${Schema.OrderType.TYPE_MARKET}`)
|
||||||
).toBeInTheDocument();
|
).toBeInTheDocument();
|
||||||
expect(
|
expect(
|
||||||
screen.queryByTestId('order-side-SIDE_BUY-selected')
|
screen.queryByTestId('order-side-SIDE_BUY')?.querySelector('input')
|
||||||
).toBeInTheDocument();
|
).toBeChecked();
|
||||||
expect(
|
expect(
|
||||||
screen.queryByTestId('order-side-SIDE_SELL-selected')
|
screen.queryByTestId('order-side-SIDE_SELL')?.querySelector('input')
|
||||||
).not.toBeInTheDocument();
|
).not.toBeChecked();
|
||||||
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))
|
||||||
);
|
);
|
||||||
@ -91,7 +91,9 @@ describe('DealTicket', () => {
|
|||||||
render(generateJsx());
|
render(generateJsx());
|
||||||
|
|
||||||
// BUY is selected by default
|
// BUY is selected by default
|
||||||
screen.getByTestId('order-side-SIDE_BUY-selected');
|
expect(
|
||||||
|
screen.getByTestId('order-side-SIDE_BUY')?.querySelector('input')
|
||||||
|
).toBeChecked();
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
fireEvent.change(screen.getByTestId('order-size'), {
|
fireEvent.change(screen.getByTestId('order-size'), {
|
||||||
|
@ -27,10 +27,7 @@ export const useFillsList = ({ partyId, gridRef, scrolledToTop }: Props) => {
|
|||||||
totalCountRef.current += newRows.current;
|
totalCountRef.current += newRows.current;
|
||||||
}
|
}
|
||||||
newRows.current = 0;
|
newRows.current = 0;
|
||||||
if (!gridRef.current?.api) {
|
gridRef.current?.api.refreshInfiniteCache();
|
||||||
return;
|
|
||||||
}
|
|
||||||
gridRef.current.api.refreshInfiniteCache();
|
|
||||||
}, [gridRef]);
|
}, [gridRef]);
|
||||||
|
|
||||||
const update = useCallback(
|
const update = useCallback(
|
||||||
@ -41,9 +38,6 @@ export const useFillsList = ({ partyId, gridRef, scrolledToTop }: Props) => {
|
|||||||
data: (TradeEdge | null)[] | null;
|
data: (TradeEdge | null)[] | null;
|
||||||
delta?: Trade[];
|
delta?: Trade[];
|
||||||
}) => {
|
}) => {
|
||||||
if (!gridRef.current?.api) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (dataRef.current?.length) {
|
if (dataRef.current?.length) {
|
||||||
if (!scrolledToTop.current) {
|
if (!scrolledToTop.current) {
|
||||||
const createdAt = dataRef.current?.[0]?.node.createdAt;
|
const createdAt = dataRef.current?.[0]?.node.createdAt;
|
||||||
@ -54,7 +48,7 @@ export const useFillsList = ({ partyId, gridRef, scrolledToTop }: Props) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dataRef.current = data;
|
dataRef.current = data;
|
||||||
gridRef.current.api.refreshInfiniteCache();
|
gridRef.current?.api.refreshInfiniteCache();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
dataRef.current = data;
|
dataRef.current = data;
|
||||||
|
@ -33,17 +33,11 @@ export const useOrderListData = ({
|
|||||||
totalCountRef.current += newRows.current;
|
totalCountRef.current += newRows.current;
|
||||||
}
|
}
|
||||||
newRows.current = 0;
|
newRows.current = 0;
|
||||||
if (!gridRef.current?.api) {
|
gridRef.current?.api.refreshInfiniteCache();
|
||||||
return;
|
|
||||||
}
|
|
||||||
gridRef.current.api.refreshInfiniteCache();
|
|
||||||
}, [gridRef]);
|
}, [gridRef]);
|
||||||
|
|
||||||
const update = useCallback(
|
const update = useCallback(
|
||||||
({ data, delta }: { data: (OrderEdge | null)[]; delta?: Order[] }) => {
|
({ data, delta }: { data: (OrderEdge | null)[]; delta?: Order[] }) => {
|
||||||
if (!gridRef.current?.api) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (dataRef.current?.length) {
|
if (dataRef.current?.length) {
|
||||||
if (!scrolledToTop.current) {
|
if (!scrolledToTop.current) {
|
||||||
const createdAt = dataRef.current?.[0]?.node.createdAt;
|
const createdAt = dataRef.current?.[0]?.node.createdAt;
|
||||||
@ -54,7 +48,7 @@ export const useOrderListData = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dataRef.current = data;
|
dataRef.current = data;
|
||||||
gridRef.current.api.refreshInfiniteCache();
|
gridRef.current?.api.refreshInfiniteCache();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
dataRef.current = data;
|
dataRef.current = data;
|
||||||
|
@ -44,11 +44,8 @@ export const usePositionsData = (
|
|||||||
const dataRef = useRef<Position[] | null>(null);
|
const dataRef = useRef<Position[] | null>(null);
|
||||||
const update = useCallback(
|
const update = useCallback(
|
||||||
({ data }: { data: Position[] | null }) => {
|
({ data }: { data: Position[] | null }) => {
|
||||||
if (!gridRef.current?.api) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
dataRef.current = assetSymbol ? filter(data, { assetSymbol }) : data;
|
dataRef.current = assetSymbol ? filter(data, { assetSymbol }) : data;
|
||||||
gridRef.current.api.refreshInfiniteCache();
|
gridRef.current?.api.refreshInfiniteCache();
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
[assetSymbol, gridRef]
|
[assetSymbol, gridRef]
|
||||||
|
@ -49,11 +49,10 @@ export const makeInfiniteScrollGetRows =
|
|||||||
const rowsThisBlock = data.current
|
const rowsThisBlock = data.current
|
||||||
? data.current.slice(startRow, endRow).map((edge) => edge?.node)
|
? data.current.slice(startRow, endRow).map((edge) => edge?.node)
|
||||||
: [];
|
: [];
|
||||||
successCallback(
|
const lastRow =
|
||||||
rowsThisBlock,
|
|
||||||
getLastRow(startRow, endRow, rowsThisBlock.length, totalCount.current) -
|
getLastRow(startRow, endRow, rowsThisBlock.length, totalCount.current) -
|
||||||
newRows.current
|
newRows.current;
|
||||||
);
|
successCallback(rowsThisBlock, lastRow);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
failCallback();
|
failCallback();
|
||||||
}
|
}
|
||||||
|
@ -35,10 +35,7 @@ export const TradesContainer = ({ marketId }: TradesContainerProps) => {
|
|||||||
totalCountRef.current += newRows.current;
|
totalCountRef.current += newRows.current;
|
||||||
}
|
}
|
||||||
newRows.current = 0;
|
newRows.current = 0;
|
||||||
if (!gridRef.current?.api) {
|
gridRef.current?.api.refreshInfiniteCache();
|
||||||
return;
|
|
||||||
}
|
|
||||||
gridRef.current.api.refreshInfiniteCache();
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const update = useCallback(
|
const update = useCallback(
|
||||||
@ -49,9 +46,6 @@ export const TradesContainer = ({ marketId }: TradesContainerProps) => {
|
|||||||
data: (TradeEdge | null)[] | null;
|
data: (TradeEdge | null)[] | null;
|
||||||
delta?: Trade[];
|
delta?: Trade[];
|
||||||
}) => {
|
}) => {
|
||||||
if (!gridRef.current?.api) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (dataRef.current?.length) {
|
if (dataRef.current?.length) {
|
||||||
if (!scrolledToTop.current) {
|
if (!scrolledToTop.current) {
|
||||||
const createdAt = dataRef.current?.[0]?.node.createdAt;
|
const createdAt = dataRef.current?.[0]?.node.createdAt;
|
||||||
@ -62,7 +56,7 @@ export const TradesContainer = ({ marketId }: TradesContainerProps) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dataRef.current = data;
|
dataRef.current = data;
|
||||||
gridRef.current.api.refreshInfiniteCache();
|
gridRef.current?.api.refreshInfiniteCache();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
dataRef.current = data;
|
dataRef.current = data;
|
||||||
|
@ -42,9 +42,13 @@ export const Toggle = ({
|
|||||||
return (
|
return (
|
||||||
<fieldset className={fieldsetClasses} {...props}>
|
<fieldset className={fieldsetClasses} {...props}>
|
||||||
{toggles.map(({ label, value }, key) => {
|
{toggles.map(({ label, value }, key) => {
|
||||||
const isSelected = value === checkedValue;
|
|
||||||
return (
|
return (
|
||||||
<label key={key} className={labelClasses} htmlFor={label}>
|
<label
|
||||||
|
key={key}
|
||||||
|
className={labelClasses}
|
||||||
|
htmlFor={label}
|
||||||
|
data-testid={`${name}-${value}`}
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
type="radio"
|
type="radio"
|
||||||
id={label}
|
id={label}
|
||||||
@ -56,14 +60,7 @@ export const Toggle = ({
|
|||||||
}
|
}
|
||||||
className={radioClasses}
|
className={radioClasses}
|
||||||
/>
|
/>
|
||||||
<span
|
<span className={buttonClasses}>{label}</span>
|
||||||
className={buttonClasses}
|
|
||||||
data-testid={
|
|
||||||
isSelected ? `${name}-${value}-selected` : `${name}-${value}`
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{label}
|
|
||||||
</span>
|
|
||||||
</label>
|
</label>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
Loading…
Reference in New Issue
Block a user