From 9dda3f712b969c72e033a6356ff8563ca8e877a2 Mon Sep 17 00:00:00 2001 From: Ben Date: Tue, 5 Dec 2023 10:29:01 +0000 Subject: [PATCH] chore(trading): market python tests to jest (#5346) Co-authored-by: Matthew Russell --- .../client-pages/markets/closed.spec.tsx | 117 +++++++++---- .../markets/open-markets.spec.tsx | 145 ++++++++++++++++ .../e2e/tests/market/test_markets_all.py | 160 ------------------ 3 files changed, 225 insertions(+), 197 deletions(-) create mode 100644 apps/trading/client-pages/markets/open-markets.spec.tsx delete mode 100644 apps/trading/e2e/tests/market/test_markets_all.py diff --git a/apps/trading/client-pages/markets/closed.spec.tsx b/apps/trading/client-pages/markets/closed.spec.tsx index 8c73201b7..84f5aa5a5 100644 --- a/apps/trading/client-pages/markets/closed.spec.tsx +++ b/apps/trading/client-pages/markets/closed.spec.tsx @@ -1,4 +1,5 @@ import { act, render, screen, waitFor, within } from '@testing-library/react'; +// import userEvent from '@testing-library/user-event'; import { MemoryRouter } from 'react-router-dom'; import { Closed } from './closed'; import { MarketStateMapping, PropertyKeyType } from '@vegaprotocol/types'; @@ -26,6 +27,7 @@ import { marketsDataQuery, createMarketsDataFragment, } from '@vegaprotocol/mock'; +import userEvent from '@testing-library/user-event'; describe('Closed', () => { let originalNow: typeof Date.now; @@ -168,14 +170,11 @@ describe('Closed', () => { Date.now = originalNow; }); - // eslint-disable-next-line jest/no-disabled-tests - it.skip('renders correctly formatted and filtered rows', async () => { + const renderComponent = async (mocks: MockedResponse[]) => { await act(async () => { render( - + @@ -185,6 +184,10 @@ describe('Closed', () => { ); }); + }; + + it('renders correct headers', async () => { + await renderComponent([marketsMock, marketsDataMock, oracleDataMock]); const headers = screen.getAllByRole('columnheader'); const expectedHeaders = [ @@ -200,6 +203,10 @@ describe('Closed', () => { ]; expect(headers).toHaveLength(expectedHeaders.length); expect(headers.map((h) => h.textContent?.trim())).toEqual(expectedHeaders); + }); + + it('renders correctly formatted and filtered rows', async () => { + await renderComponent([marketsMock, marketsDataMock, oracleDataMock]); const assetSymbol = getAsset(market).symbol; @@ -273,21 +280,8 @@ describe('Closed', () => { }, }, }; - await act(async () => { - render( - - - - - - - - ); - }); + + await renderComponent([mixedMarketsMock, marketsDataMock, oracleDataMock]); // check that the number of rows in datagrid is 2 const container = within( @@ -319,8 +313,67 @@ describe('Closed', () => { ); }); - // eslint-disable-next-line jest/no-disabled-tests - it.skip('successor marked should be visible', async () => { + it('display market actions', async () => { + // Use market with a succcessor Id as the actions dropdown will optionally + // show a link to the successor market + const marketsWithSuccessorAndParent = [ + { + __typename: 'MarketEdge' as const, + node: createMarketFragment({ + id: 'include-0', + state: MarketState.STATE_SETTLED, + successorMarketID: 'successor', + parentMarketID: 'parent', + }), + }, + ]; + const mockWithSuccessorAndParent: MockedResponse = { + request: { + query: MarketsDocument, + }, + result: { + data: { + marketsConnection: { + __typename: 'MarketConnection', + edges: marketsWithSuccessorAndParent, + }, + }, + }, + }; + await renderComponent([ + mockWithSuccessorAndParent, + marketsDataMock, + oracleDataMock, + ]); + + const actionCell = screen + .getAllByRole('gridcell') + .find((el) => el.getAttribute('col-id') === 'market-actions'); + + await userEvent.click( + within(actionCell as HTMLElement).getByTestId('dropdown-menu') + ); + + expect(screen.getByRole('menu')).toBeInTheDocument(); + + expect( + screen.getByRole('menuitem', { name: 'Copy Market ID' }) + ).toBeInTheDocument(); + expect( + screen.getByRole('menuitem', { name: 'View on Explorer' }) + ).toBeInTheDocument(); + expect( + screen.getByRole('menuitem', { name: 'View settlement asset details' }) + ).toBeInTheDocument(); + expect( + screen.getByRole('menuitem', { name: 'View parent market' }) + ).toBeInTheDocument(); + expect( + screen.getByRole('menuitem', { name: 'View successor market' }) + ).toBeInTheDocument(); + }); + + it('successor market should be visible', async () => { const marketsWithSuccessorID = [ { __typename: 'MarketEdge' as const, @@ -345,21 +398,11 @@ describe('Closed', () => { }, }; - await act(async () => { - render( - - - - - - - - ); - }); + await renderComponent([ + mockWithSuccessors, + marketsDataMock, + oracleDataMock, + ]); const container = within( document.querySelector('.ag-center-cols-container') as HTMLElement diff --git a/apps/trading/client-pages/markets/open-markets.spec.tsx b/apps/trading/client-pages/markets/open-markets.spec.tsx new file mode 100644 index 000000000..a7c76255e --- /dev/null +++ b/apps/trading/client-pages/markets/open-markets.spec.tsx @@ -0,0 +1,145 @@ +import { act, render, screen, within } from '@testing-library/react'; +import { MemoryRouter } from 'react-router-dom'; +import { OpenMarkets } from './open-markets'; +import { Interval } from '@vegaprotocol/types'; +import type { MockedResponse } from '@apollo/client/testing'; +import { MockedProvider } from '@apollo/client/testing'; +import type { + MarketsDataQuery, + MarketsQuery, + MarketCandlesQuery, + MarketFieldsFragment, +} from '@vegaprotocol/markets'; +import { + MarketsDataDocument, + MarketsDocument, + MarketsCandlesDocument, +} from '@vegaprotocol/markets'; +import type { VegaWalletContextShape } from '@vegaprotocol/wallet'; +import { VegaWalletContext } from '@vegaprotocol/wallet'; +import { + marketsQuery, + marketsDataQuery, + marketsCandlesQuery, +} from '@vegaprotocol/mock'; +import userEvent from '@testing-library/user-event'; + +describe('Open', () => { + let originalNow: typeof Date.now; + const mockNowTimestamp = 1672531200000; + const pubKey = 'pubKey'; + + const marketsQueryData = marketsQuery(); + const marketsMock: MockedResponse = { + request: { + query: MarketsDocument, + }, + result: { + data: marketsQueryData, + }, + }; + + const marketsCandlesQueryData = marketsCandlesQuery(); + const marketsCandlesMock: MockedResponse = { + request: { + query: MarketsCandlesDocument, + variables: { + interval: Interval.INTERVAL_I1H, + since: '2022-12-31T00:00:00.000Z', + }, + }, + result: { + data: marketsCandlesQueryData, + }, + }; + + const marketsDataQueryData = marketsDataQuery(); + + const marketsDataMock: MockedResponse = { + request: { + query: MarketsDataDocument, + }, + result: { + data: marketsDataQueryData, + }, + }; + + beforeAll(() => { + originalNow = Date.now; + Date.now = jest.fn().mockReturnValue(mockNowTimestamp); + }); + + afterAll(() => { + Date.now = originalNow; + }); + + const renderComponent = async () => { + await act(async () => { + render( + + + + + + + + ); + }); + }; + + it('renders correct headers', async () => { + await renderComponent(); + + const headers = screen.getAllByRole('columnheader'); + const expectedHeaders = [ + 'Market', + 'Description', + 'Settlement asset', + 'Trading mode', + 'Status', + 'Mark price', + '24h volume', + 'Open Interest', + 'Spread', + '', // Action row + ]; + expect(headers).toHaveLength(expectedHeaders.length); + expect(headers.map((h) => h.textContent?.trim())).toEqual(expectedHeaders); + }); + + it('sort columns', async () => { + await renderComponent(); + + const headers = screen.getAllByRole('columnheader'); + const marketHeader = headers.find( + (h) => h.getAttribute('col-id') === 'tradableInstrument.instrument.code' + ); + if (!marketHeader) { + throw new Error('No market header found'); + } + expect(marketHeader).toHaveAttribute('aria-sort', 'none'); + await userEvent.click(within(marketHeader).getByText(/market/i)); + // 6001-MARK-064 + expect(marketHeader).toHaveAttribute('aria-sort', 'ascending'); + }); + + // eslint-disable-next-line jest/no-disabled-tests, jest/expect-expect + it('renders row', async () => { + await renderComponent(); + + const container = within( + document.querySelector('.ag-center-cols-container') as HTMLElement + ); + + const markets = marketsQueryData.marketsConnection?.edges.map( + (e) => e.node + ) as MarketFieldsFragment[]; + + const rows = container.getAllByRole('row'); + expect(rows).toHaveLength(markets.length); + }); +}); diff --git a/apps/trading/e2e/tests/market/test_markets_all.py b/apps/trading/e2e/tests/market/test_markets_all.py deleted file mode 100644 index fee574f60..000000000 --- a/apps/trading/e2e/tests/market/test_markets_all.py +++ /dev/null @@ -1,160 +0,0 @@ -import pytest -from playwright.sync_api import Page, expect -from fixtures.market import setup_continuous_market - -from conftest import init_vega - -market_names = ["ETHBTC.QM21", "BTCUSD.MF21", "SOLUSD", "AAPL.MF21"] - - -@pytest.fixture(scope="module") -def vega(): - with init_vega() as vega: - yield vega - - -@pytest.fixture(scope="module") -def create_markets(vega): - for market_name in market_names: - setup_continuous_market(vega, custom_market_name=market_name) - - -@pytest.mark.usefixtures("risk_accepted") -def test_table_headers(page: Page, create_markets): - page.goto(f"/#/markets/all") - headers = [ - "Market", - "Description", - "Settlement asset", - "Trading mode", - "Status", - "Mark price", - "24h volume", - "Open Interest", - "Spread", - "", - ] - page.wait_for_selector('[data-testid="tab-open-markets"]', state="visible") - page_headers = ( - page.get_by_test_id("tab-open-markets").locator(".ag-header-cell-text").all() - ) - for i, header in enumerate(headers): - expect(page_headers[i]).to_have_text(header) - - -@pytest.mark.usefixtures("risk_accepted") -def test_markets_tab(page: Page, create_markets): - page.goto(f"/#/markets/all") - expect(page.get_by_test_id("Open markets")).to_have_attribute( - "data-state", "active" - ) - expect(page.get_by_test_id("Proposed markets")).to_have_attribute( - "data-state", "inactive" - ) - expect(page.get_by_test_id("Closed markets")).to_have_attribute( - "data-state", "inactive" - ) - - -@pytest.mark.usefixtures("risk_accepted") -def test_markets_content(page: Page, create_markets): - page.goto(f"/#/markets/all") - row_selector = page.locator( - '[data-testid="tab-open-markets"] .ag-center-cols-container .ag-row' - ).first - instrument_code_locator = '[col-id="tradableInstrument.instrument.code"] [data-testid="stack-cell-primary"]' - # 6001-MARK-035 - expect(row_selector.locator(instrument_code_locator)).to_have_text("ETHBTC.QM21") - - # 6001-MARK-073 - expect(row_selector.locator('[title="Future"]')).to_have_text("Futr") - - # 6001-MARK-036 - expect( - row_selector.locator('[col-id="tradableInstrument.instrument.name"]') - ).to_have_text("ETHBTC.QM21") - - # 6001-MARK-037 - expect(row_selector.locator('[col-id="tradingMode"]')).to_have_text("Continuous") - - # 6001-MARK-038 - expect(row_selector.locator('[col-id="state"]')).to_have_text("Active") - - # 6001-MARK-039 - expect(row_selector.locator('[col-id="data.markPrice"]')).to_have_text("107.50") - - # 6001-MARK-040 - expect(row_selector.locator('[col-id="data.candles"]')).to_have_text("0.00") - - # 6001-MARK-042 - expect( - row_selector.locator( - '[col-id="tradableInstrument.instrument.product.settlementAsset.symbol"]' - ) - ).to_have_text("tDAI") - - expect(row_selector.locator('[col-id="data.bestBidPrice"]')).to_have_text("2") - - # 6001-MARK-043 - row_selector.locator( - '[col-id="tradableInstrument.instrument.product.settlementAsset.symbol"] button' - ).click() - expect(page.get_by_test_id("dialog-title")).to_have_text("Asset details - tDAI") - # 6001-MARK-019 - page.get_by_test_id("close-asset-details-dialog").click() - - -@pytest.mark.usefixtures("risk_accepted") -def test_market_actions(page: Page, create_markets): - # 6001-MARK-044 - # 6001-MARK-045 - # 6001-MARK-046 - # 6001-MARK-047 - page.goto(f"/#/markets/all") - page.locator( - '.ag-pinned-right-cols-container [col-id="market-actions"]' - ).first.locator("button").click() - - actions = [ - "Copy Market ID", - "View on Explorer", - "View settlement asset details", - ] - action_elements = ( - page.get_by_test_id("market-actions-content").get_by_role("menuitem").all() - ) - - for i, action in enumerate(actions): - expect(action_elements[i]).to_have_text(action) - - -@pytest.mark.usefixtures("risk_accepted") -def test_sort_markets(page: Page, create_markets): - # 6001-MARK-064 - - page.goto(f"/#/markets/all") - sorted_market_names = [ - "AAPL.MF21", - "BTCUSD.MF21", - "ETHBTC.QM21", - "SOLUSD", - ] - page.locator('.ag-header-row [col-id="tradableInstrument.instrument.code"]').click() - for i, market_name in enumerate(sorted_market_names): - expect( - page.locator( - f'[row-index="{i}"] [col-id="tradableInstrument.instrument.name"]' - ) - ).to_have_text(market_name) - - -@pytest.mark.usefixtures("risk_accepted") -def test_drag_and_drop_column(page: Page, create_markets): - # 6001-MARK-065 - page.goto(f"/#/markets/all") - col_instrument_code = '.ag-header-row [col-id="tradableInstrument.instrument.code"]' - - page.locator(col_instrument_code).drag_to( - page.locator('.ag-header-row [col-id="data.bestBidPrice"]') - ) - expect(page.locator(col_instrument_code)).to_have_attribute("aria-colindex", "9")