From 46e2965fa24973507562679c7a4efe44d7b48c98 Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 8 Feb 2024 12:25:16 +0000 Subject: [PATCH 1/2] chore(trading): fix test teardown (#5769) --- .github/workflows/console-test-run.yml | 2 +- apps/trading/e2e/.env | 2 +- apps/trading/e2e/conftest.py | 29 ++- .../e2e/tests/deal_ticket/test_basic.py | 8 +- .../e2e/tests/deal_ticket/test_stop_order.py | 9 +- ...test_trading_deal_ticket_submit_account.py | 7 +- apps/trading/e2e/tests/fees/test_fees.py | 17 +- .../e2e/tests/get_started/test_get_started.py | 9 +- .../iceberg_orders/test_iceberg_orders.py | 53 +++--- .../test_liquidity_provision.py | 9 +- .../e2e/tests/market/test_closed_markets.py | 9 +- .../e2e/tests/market/test_market_info.py | 9 +- .../e2e/tests/market/test_markets_proposed.py | 8 +- ...itoring_auction_price_volatility_market.py | 8 +- .../e2e/tests/navigation/test_navigation.py | 9 +- .../e2e/tests/order/test_order_status.py | 7 +- .../e2e/tests/orderbook/test_orderbook.py | 9 +- .../e2e/tests/positions/test_collateral.py | 8 +- .../e2e/tests/referrals/test_referrals.py | 8 +- .../trading/e2e/tests/rewards/test_rewards.py | 8 +- .../rewards/test_rewards_activity_tier_0.py | 176 ++++++++++++++++++ .../e2e/tests/settings/test_settings.py | 9 +- apps/trading/e2e/tests/teams/test_teams.py | 14 +- 23 files changed, 324 insertions(+), 103 deletions(-) create mode 100644 apps/trading/e2e/tests/rewards/test_rewards_activity_tier_0.py diff --git a/.github/workflows/console-test-run.yml b/.github/workflows/console-test-run.yml index 9943ab54c..27573fa84 100644 --- a/.github/workflows/console-test-run.yml +++ b/.github/workflows/console-test-run.yml @@ -205,7 +205,7 @@ jobs: # run tests #---------------------------------------------- - name: Run tests - run: CONSOLE_IMAGE_NAME=ci/trading:local poetry run pytest -v --numprocesses 1 --dist loadfile --durations=45 + run: CONSOLE_IMAGE_NAME=ci/trading:local poetry run pytest -v --numprocesses 4 --dist loadfile --durations=45 working-directory: apps/trading/e2e #---------------------------------------------- # upload traces diff --git a/apps/trading/e2e/.env b/apps/trading/e2e/.env index 4c307ec14..e35db6531 100644 --- a/apps/trading/e2e/.env +++ b/apps/trading/e2e/.env @@ -1,3 +1,3 @@ CONSOLE_IMAGE_NAME=vegaprotocol/trading:latest -VEGA_VERSION=v0.74.0-preview.8 +VEGA_VERSION=v0.74.0-preview.10 LOCAL_SERVER=false diff --git a/apps/trading/e2e/conftest.py b/apps/trading/e2e/conftest.py index 8c3cafb3b..1574db6e9 100644 --- a/apps/trading/e2e/conftest.py +++ b/apps/trading/e2e/conftest.py @@ -111,6 +111,7 @@ def init_vega(request=None): f"Container {container.id} started", extra={"worker_id": os.environ.get("PYTEST_XDIST_WORKER")}, ) + vega.container = container yield vega except APIError as e: logger.info(f"Container creation failed.") @@ -177,10 +178,34 @@ def init_page(vega: VegaServiceNull, browser: Browser, request: pytest.FixtureRe @pytest.fixture def vega(request): - with init_vega(request) as vega: - yield vega + with init_vega(request) as vega_instance: + request.addfinalizer(lambda: cleanup_container(vega_instance)) + yield vega_instance + +def cleanup_container(vega_instance): + try: + # Attempt to stop the container if it's still running + if vega_instance.container.status == 'running': + print(f"Stopping container {vega_instance.container.id}") + vega_instance.container.stop() + else: + print(f"Container {vega_instance.container.id} is not running.") + except docker.errors.NotFound: + print(f"Container {vega_instance.container.id} not found, may have been stopped and removed.") + except Exception as e: + print(f"Error during cleanup: {str(e)}") + + try: + # Attempt to remove the container + vega_instance.container.remove() + print(f"Container {vega_instance.container.id} removed.") + except docker.errors.NotFound: + print(f"Container {vega_instance.container.id} not found, may have been removed.") + except Exception as e: + print(f"Error during container removal: {str(e)}") + @pytest.fixture def page(vega, browser, request): with init_page(vega, browser, request) as page_instance: diff --git a/apps/trading/e2e/tests/deal_ticket/test_basic.py b/apps/trading/e2e/tests/deal_ticket/test_basic.py index 21691e139..0a97dff71 100644 --- a/apps/trading/e2e/tests/deal_ticket/test_basic.py +++ b/apps/trading/e2e/tests/deal_ticket/test_basic.py @@ -2,7 +2,7 @@ import pytest from playwright.sync_api import Page, expect from vega_sim.null_service import VegaServiceNull from datetime import datetime, timedelta -from conftest import init_vega +from conftest import init_vega, cleanup_container from fixtures.market import setup_continuous_market from actions.utils import wait_for_toast_confirmation @@ -17,8 +17,10 @@ expire = "expire" @pytest.fixture(scope="module") def vega(request): - with init_vega(request) as vega: - yield vega + with init_vega(request) as vega_instance: + request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + yield vega_instance + @pytest.fixture(scope="module") diff --git a/apps/trading/e2e/tests/deal_ticket/test_stop_order.py b/apps/trading/e2e/tests/deal_ticket/test_stop_order.py index 34cbdc84b..6ae055806 100644 --- a/apps/trading/e2e/tests/deal_ticket/test_stop_order.py +++ b/apps/trading/e2e/tests/deal_ticket/test_stop_order.py @@ -3,7 +3,7 @@ from playwright.sync_api import Page, expect from vega_sim.null_service import VegaServiceNull from actions.vega import submit_order from datetime import datetime, timedelta -from conftest import init_vega +from conftest import init_vega, cleanup_container from fixtures.market import setup_continuous_market stop_order_btn = "order-type-Stop" @@ -259,9 +259,10 @@ def test_submit_stop_limit_order_cancel( class TestStopOcoValidation: @pytest.fixture(scope="class") - def vega(self, request): - with init_vega(request) as vega: - yield vega + def vega(request): + with init_vega(request) as vega_instance: + request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + yield vega_instance @pytest.fixture(scope="class") def continuous_market(self, vega): diff --git a/apps/trading/e2e/tests/deal_ticket/test_trading_deal_ticket_submit_account.py b/apps/trading/e2e/tests/deal_ticket/test_trading_deal_ticket_submit_account.py index 971c730c2..82a2f2b17 100644 --- a/apps/trading/e2e/tests/deal_ticket/test_trading_deal_ticket_submit_account.py +++ b/apps/trading/e2e/tests/deal_ticket/test_trading_deal_ticket_submit_account.py @@ -2,7 +2,7 @@ import pytest from playwright.sync_api import Page, expect from vega_sim.null_service import VegaServiceNull from actions.utils import change_keys -from conftest import init_vega +from conftest import init_vega, cleanup_container from fixtures.market import setup_continuous_market order_size = "order-size" @@ -14,8 +14,9 @@ deal_ticket_deposit_dialog_button = "deal-ticket-deposit-dialog-button" @pytest.fixture(scope="module") def vega(request): - with init_vega(request) as vega: - yield vega + with init_vega(request) as vega_instance: + request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + yield vega_instance @pytest.fixture(scope="module") diff --git a/apps/trading/e2e/tests/fees/test_fees.py b/apps/trading/e2e/tests/fees/test_fees.py index b8976869a..f6bd79a75 100644 --- a/apps/trading/e2e/tests/fees/test_fees.py +++ b/apps/trading/e2e/tests/fees/test_fees.py @@ -4,7 +4,7 @@ from playwright.sync_api import Page, expect from vega_sim.null_service import VegaServiceNull from actions.vega import submit_order from wallet_config import MM_WALLET -from conftest import init_vega, init_page, auth_setup +from conftest import init_vega, init_page, auth_setup, cleanup_container from actions.utils import next_epoch, change_keys, forward_time from fixtures.market import market_exists, setup_continuous_market @@ -82,31 +82,36 @@ def market_ids(): @pytest.fixture(scope="module") def vega_volume_discount_tier_1(request): with init_vega(request) as vega_volume_discount_tier_1: - yield vega_volume_discount_tier_1 + request.addfinalizer(lambda: cleanup_container(vega_volume_discount_tier_1)) # Register the cleanup function + yield vega_volume_discount_tier_1 @pytest.fixture(scope="module") def vega_volume_discount_tier_2(request): with init_vega(request) as vega_volume_discount_tier_2: - yield vega_volume_discount_tier_2 + request.addfinalizer(lambda: cleanup_container(vega_volume_discount_tier_2)) # Register the cleanup function + yield vega_volume_discount_tier_2 @pytest.fixture(scope="module") def vega_referral_discount_tier_1(request): with init_vega(request) as vega_referral_discount_tier_1: - yield vega_referral_discount_tier_1 + request.addfinalizer(lambda: cleanup_container(vega_referral_discount_tier_1)) # Register the cleanup function + yield vega_referral_discount_tier_1 @pytest.fixture(scope="module") def vega_referral_discount_tier_2(request): with init_vega(request) as vega_referral_discount_tier_2: - yield vega_referral_discount_tier_2 + request.addfinalizer(lambda: cleanup_container(vega_referral_discount_tier_2)) # Register the cleanup function + yield vega_referral_discount_tier_2 @pytest.fixture(scope="module") def vega_referral_and_volume_discount(request): with init_vega(request) as vega_referral_and_volume_discount: - yield vega_referral_and_volume_discount + request.addfinalizer(lambda: cleanup_container(vega_referral_and_volume_discount)) # Register the cleanup function + yield vega_referral_and_volume_discount @pytest.fixture diff --git a/apps/trading/e2e/tests/get_started/test_get_started.py b/apps/trading/e2e/tests/get_started/test_get_started.py index b18e72c0a..478e2e045 100644 --- a/apps/trading/e2e/tests/get_started/test_get_started.py +++ b/apps/trading/e2e/tests/get_started/test_get_started.py @@ -3,7 +3,7 @@ from playwright.sync_api import expect, Page import json from vega_sim.null_service import VegaServiceNull from fixtures.market import setup_simple_market -from conftest import init_vega +from conftest import init_vega, cleanup_container from actions.vega import submit_order from wallet_config import MM_WALLET, TERMINATE_WALLET, wallets import logging @@ -12,9 +12,10 @@ logger = logging.getLogger() @pytest.fixture(scope="class") -def vega(): - with init_vega() as vega: - yield vega +def vega(request): + with init_vega(request) as vega_instance: + request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + yield vega_instance @pytest.fixture(scope="class") diff --git a/apps/trading/e2e/tests/iceberg_orders/test_iceberg_orders.py b/apps/trading/e2e/tests/iceberg_orders/test_iceberg_orders.py index 139d9e834..2d6b139e0 100644 --- a/apps/trading/e2e/tests/iceberg_orders/test_iceberg_orders.py +++ b/apps/trading/e2e/tests/iceberg_orders/test_iceberg_orders.py @@ -2,8 +2,6 @@ import pytest from playwright.sync_api import expect, Page from vega_sim.null_service import VegaServiceNull from actions.vega import submit_order -from conftest import init_vega -from fixtures.market import setup_continuous_market from wallet_config import MM_WALLET2 def hover_and_assert_tooltip(page: Page, element_text): @@ -11,39 +9,30 @@ def hover_and_assert_tooltip(page: Page, element_text): element.hover() expect(page.get_by_role("tooltip")).to_be_visible() -class TestIcebergOrdersValidations: - @pytest.fixture(scope="class") - def vega(self, request): - with init_vega(request) as vega: - yield vega - @pytest.fixture(scope="class") - def continuous_market(self, vega): - return setup_continuous_market(vega) +@pytest.mark.usefixtures("auth", "risk_accepted") +def test_iceberg_submit(continuous_market, vega: VegaServiceNull, page: Page): + page.goto(f"/#/markets/{continuous_market}") + page.get_by_test_id("iceberg").click() + page.get_by_test_id("order-peak-size").type("2") + page.get_by_test_id("order-minimum-size").type("1") + page.get_by_test_id("order-size").type("3") + page.get_by_test_id("order-price").type("107") + page.get_by_test_id("place-order").click() - @pytest.mark.usefixtures("auth", "risk_accepted") - def test_iceberg_submit(self, continuous_market, vega: VegaServiceNull, page: Page): - page.goto(f"/#/markets/{continuous_market}") - page.get_by_test_id("iceberg").click() - page.get_by_test_id("order-peak-size").type("2") - page.get_by_test_id("order-minimum-size").type("1") - page.get_by_test_id("order-size").type("3") - page.get_by_test_id("order-price").type("107") - page.get_by_test_id("place-order").click() + expect(page.get_by_test_id("toast-content")).to_have_text( + "Awaiting confirmationPlease wait for your transaction to be confirmedView in block explorer" + ) - expect(page.get_by_test_id("toast-content")).to_have_text( - "Awaiting confirmationPlease wait for your transaction to be confirmedView in block explorer" - ) - - vega.wait_fn(1) - vega.wait_for_total_catchup() - expect(page.get_by_test_id("toast-content")).to_have_text( - "Order filledYour transaction has been confirmedView in block explorerSubmit order - filledBTC:DAI_2023+3 @ 107.00 tDAI" - ) - page.get_by_test_id("All").click() - expect( - (page.get_by_role("row").locator('[col-id="type"]')).nth(1) - ).to_have_text("Limit (Iceberg)") + vega.wait_fn(1) + vega.wait_for_total_catchup() + expect(page.get_by_test_id("toast-content")).to_have_text( + "Order filledYour transaction has been confirmedView in block explorerSubmit order - filledBTC:DAI_2023+3 @ 107.00 tDAI" + ) + page.get_by_test_id("All").click() + expect( + (page.get_by_role("row").locator('[col-id="type"]')).nth(1) + ).to_have_text("Limit (Iceberg)") @pytest.mark.usefixtures("auth", "risk_accepted") def test_iceberg_open_order(continuous_market, vega: VegaServiceNull, page: Page): diff --git a/apps/trading/e2e/tests/liquidity_provision/test_liquidity_provision.py b/apps/trading/e2e/tests/liquidity_provision/test_liquidity_provision.py index d798046a1..803f8e993 100644 --- a/apps/trading/e2e/tests/liquidity_provision/test_liquidity_provision.py +++ b/apps/trading/e2e/tests/liquidity_provision/test_liquidity_provision.py @@ -1,15 +1,16 @@ import pytest from playwright.sync_api import Page, expect from vega_sim.null_service import VegaServiceNull -from conftest import init_vega +from conftest import init_vega, cleanup_container from fixtures.market import setup_continuous_market from actions.utils import next_epoch, truncate_middle, change_keys - @pytest.fixture(scope="module") def vega(request): - with init_vega(request) as vega: - yield vega + with init_vega(request) as vega_instance: + request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + yield vega_instance + @pytest.fixture(scope="module") diff --git a/apps/trading/e2e/tests/market/test_closed_markets.py b/apps/trading/e2e/tests/market/test_closed_markets.py index 88067ec43..876fdfc9a 100644 --- a/apps/trading/e2e/tests/market/test_closed_markets.py +++ b/apps/trading/e2e/tests/market/test_closed_markets.py @@ -4,14 +4,15 @@ import vega_sim.api.governance as governance from vega_sim.null_service import VegaServiceNull from playwright.sync_api import Page, expect from fixtures.market import setup_continuous_market -from conftest import init_vega +from conftest import init_vega, cleanup_container from actions.utils import next_epoch @pytest.fixture(scope="class") -def vega(): - with init_vega() as vega: - yield vega +def vega(request): + with init_vega(request) as vega_instance: + request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + yield vega_instance @pytest.fixture(scope="class") diff --git a/apps/trading/e2e/tests/market/test_market_info.py b/apps/trading/e2e/tests/market/test_market_info.py index fdba2423d..e729efdf0 100644 --- a/apps/trading/e2e/tests/market/test_market_info.py +++ b/apps/trading/e2e/tests/market/test_market_info.py @@ -3,15 +3,16 @@ import pytest from playwright.sync_api import Page, expect from vega_sim.null_service import VegaServiceNull from fixtures.market import setup_continuous_market -from conftest import init_page, init_vega, risk_accepted_setup +from conftest import init_page, init_vega, risk_accepted_setup, cleanup_container market_title_test_id = "accordion-title" @pytest.fixture(scope="module") -def vega(): - with init_vega() as vega: - yield vega +def vega(request): + with init_vega(request) as vega_instance: + request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + yield vega_instance @pytest.fixture(scope="module") diff --git a/apps/trading/e2e/tests/market/test_markets_proposed.py b/apps/trading/e2e/tests/market/test_markets_proposed.py index dfca5f830..b1a48a67c 100644 --- a/apps/trading/e2e/tests/market/test_markets_proposed.py +++ b/apps/trading/e2e/tests/market/test_markets_proposed.py @@ -3,7 +3,7 @@ import vega_sim.api.governance as governance import re from playwright.sync_api import Page, expect from vega_sim.null_service import VegaServiceNull -from conftest import init_vega +from conftest import init_vega, cleanup_container from fixtures.market import setup_simple_market from wallet_config import MM_WALLET @@ -13,8 +13,10 @@ col_market_id = '[col-id="market"] [data-testid="stack-cell-primary"]' @pytest.fixture(scope="module") def vega(request): - with init_vega(request) as vega: - yield vega + with init_vega(request) as vega_instance: + request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + yield vega_instance + @pytest.fixture(scope="module") diff --git a/apps/trading/e2e/tests/market/test_monitoring_auction_price_volatility_market.py b/apps/trading/e2e/tests/market/test_monitoring_auction_price_volatility_market.py index 107e77887..d4287e747 100644 --- a/apps/trading/e2e/tests/market/test_monitoring_auction_price_volatility_market.py +++ b/apps/trading/e2e/tests/market/test_monitoring_auction_price_volatility_market.py @@ -3,7 +3,7 @@ from playwright.sync_api import Page, expect from vega_sim.null_service import VegaServiceNull from actions.vega import submit_order from fixtures.market import setup_simple_market -from conftest import init_vega +from conftest import init_vega, cleanup_container from actions.utils import wait_for_toast_confirmation, change_keys from wallet_config import MM_WALLET, MM_WALLET2 @@ -15,8 +15,10 @@ COL_ID_FEE = ".ag-center-cols-container [col-id='fee'] .ag-cell-value" @pytest.fixture(scope="module") def vega(request): - with init_vega(request) as vega: - yield vega + with init_vega(request) as vega_instance: + request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + yield vega_instance + @pytest.fixture(scope="module") diff --git a/apps/trading/e2e/tests/navigation/test_navigation.py b/apps/trading/e2e/tests/navigation/test_navigation.py index a4bfa8614..0044c105e 100644 --- a/apps/trading/e2e/tests/navigation/test_navigation.py +++ b/apps/trading/e2e/tests/navigation/test_navigation.py @@ -1,13 +1,14 @@ import pytest from playwright.sync_api import Page, expect, Locator -from conftest import init_page, init_vega +from conftest import init_page, init_vega, cleanup_container @pytest.fixture(scope="module") -def vega(): - with init_vega() as vega: - yield vega +def vega(request): + with init_vega(request) as vega_instance: + request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + yield vega_instance # we can reuse single page instance in all tests diff --git a/apps/trading/e2e/tests/order/test_order_status.py b/apps/trading/e2e/tests/order/test_order_status.py index 659ccb96c..5e11fbd23 100644 --- a/apps/trading/e2e/tests/order/test_order_status.py +++ b/apps/trading/e2e/tests/order/test_order_status.py @@ -2,7 +2,7 @@ import pytest from playwright.sync_api import Page, expect from vega_sim.service import PeggedOrder from vega_sim.null_service import VegaServiceNull -from conftest import auth_setup, init_page, init_vega, risk_accepted_setup +from conftest import auth_setup, init_page, init_vega, risk_accepted_setup, cleanup_container from fixtures.market import setup_continuous_market, setup_simple_market from actions.utils import wait_for_toast_confirmation @@ -11,8 +11,9 @@ order_tab = "tab-orders" @pytest.fixture(scope="module") def vega(request): - with init_vega(request) as vega: - yield vega + with init_vega(request) as vega_instance: + request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + yield vega_instance @pytest.fixture(scope="module", autouse=True) diff --git a/apps/trading/e2e/tests/orderbook/test_orderbook.py b/apps/trading/e2e/tests/orderbook/test_orderbook.py index 518fd4989..698292a3d 100644 --- a/apps/trading/e2e/tests/orderbook/test_orderbook.py +++ b/apps/trading/e2e/tests/orderbook/test_orderbook.py @@ -2,15 +2,16 @@ import pytest from playwright.sync_api import Page, expect from typing import List from actions.vega import submit_order, submit_liquidity, submit_multiple_orders -from conftest import init_vega +from conftest import init_vega, cleanup_container from fixtures.market import setup_simple_market from wallet_config import MM_WALLET, MM_WALLET2 @pytest.fixture(scope="module") -def vega(): - with init_vega() as vega: - yield vega +def vega(request): + with init_vega(request) as vega_instance: + request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + yield vega_instance @pytest.fixture(scope="module") diff --git a/apps/trading/e2e/tests/positions/test_collateral.py b/apps/trading/e2e/tests/positions/test_collateral.py index 5867b37b3..8fa86dfe0 100644 --- a/apps/trading/e2e/tests/positions/test_collateral.py +++ b/apps/trading/e2e/tests/positions/test_collateral.py @@ -1,7 +1,7 @@ import pytest from playwright.sync_api import Page, expect from vega_sim.null_service import VegaServiceNull -from conftest import init_vega +from conftest import init_vega, cleanup_container from fixtures.market import setup_continuous_market TOOLTIP_LABEL = "margin-health-tooltip-label" @@ -11,8 +11,10 @@ COL_ID_USED = ".ag-center-cols-container [col-id='used'] .ag-cell-value" @pytest.fixture(scope="module") def vega(request): - with init_vega(request) as vega: - yield vega + with init_vega(request) as vega_instance: + request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + yield vega_instance + @pytest.fixture(scope="module") diff --git a/apps/trading/e2e/tests/referrals/test_referrals.py b/apps/trading/e2e/tests/referrals/test_referrals.py index 1f81cae07..53f276df7 100644 --- a/apps/trading/e2e/tests/referrals/test_referrals.py +++ b/apps/trading/e2e/tests/referrals/test_referrals.py @@ -1,7 +1,7 @@ import pytest from playwright.sync_api import Page from vega_sim.null_service import VegaServiceNull -from conftest import init_vega +from conftest import init_vega, cleanup_container from fixtures.market import setup_continuous_market, setup_simple_market from actions.utils import change_keys, create_and_faucet_wallet, forward_time, selector_contains_text from actions.vega import submit_order, submit_liquidity @@ -14,8 +14,10 @@ BUY_ORDERS = [[1, 106], [1, 107], [1, 108]] @pytest.fixture(scope="module") def vega(request): - with init_vega(request) as vega: - yield vega + with init_vega(request) as vega_instance: + request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + yield vega_instance + @pytest.fixture(scope="module") diff --git a/apps/trading/e2e/tests/rewards/test_rewards.py b/apps/trading/e2e/tests/rewards/test_rewards.py index ea465ca73..df49fb13d 100644 --- a/apps/trading/e2e/tests/rewards/test_rewards.py +++ b/apps/trading/e2e/tests/rewards/test_rewards.py @@ -2,7 +2,7 @@ import pytest import vega_sim.proto.vega as vega_protos from playwright.sync_api import Page, expect -from conftest import init_vega, init_page, auth_setup +from conftest import init_vega, init_page, auth_setup, cleanup_container from fixtures.market import setup_continuous_market, market_exists from actions.utils import next_epoch, change_keys from wallet_config import MM_WALLET, PARTY_A, PARTY_B, PARTY_C, PARTY_D @@ -46,36 +46,42 @@ def market_ids(): @pytest.fixture(scope="module") def vega_activity_tier_0(request): with init_vega(request) as vega_activity_tier_0: + request.addfinalizer(lambda: cleanup_container(vega_activity_tier_0)) # Register the cleanup function yield vega_activity_tier_0 @pytest.fixture(scope="module") def vega_hoarder_tier_0(request): with init_vega(request) as vega_hoarder_tier_0: + request.addfinalizer(lambda: cleanup_container(vega_hoarder_tier_0)) # Register the cleanup function yield vega_hoarder_tier_0 @pytest.fixture(scope="module") def vega_combo_tier_0(request): with init_vega(request) as vega_combo_tier_0: + request.addfinalizer(lambda: cleanup_container(vega_combo_tier_0)) # Register the cleanup function yield vega_combo_tier_0 @pytest.fixture(scope="module") def vega_activity_tier_1(request): with init_vega(request) as vega_activity_tier_1: + request.addfinalizer(lambda: cleanup_container(vega_activity_tier_1)) # Register the cleanup function yield vega_activity_tier_1 @pytest.fixture(scope="module") def vega_hoarder_tier_1(request): with init_vega(request) as vega_hoarder_tier_1: + request.addfinalizer(lambda: cleanup_container(vega_hoarder_tier_1)) # Register the cleanup function yield vega_hoarder_tier_1 @pytest.fixture(scope="module") def vega_combo_tier_1(request): with init_vega(request) as vega_combo_tier_1: + request.addfinalizer(lambda: cleanup_container(vega_combo_tier_1)) # Register the cleanup function yield vega_combo_tier_1 diff --git a/apps/trading/e2e/tests/rewards/test_rewards_activity_tier_0.py b/apps/trading/e2e/tests/rewards/test_rewards_activity_tier_0.py new file mode 100644 index 000000000..119672e6f --- /dev/null +++ b/apps/trading/e2e/tests/rewards/test_rewards_activity_tier_0.py @@ -0,0 +1,176 @@ +import pytest +import vega_sim.proto.vega as vega_protos +from playwright.sync_api import Page, expect +from conftest import init_vega, init_page, auth_setup, risk_accepted_setup, cleanup_container +from fixtures.market import setup_continuous_market +from actions.utils import next_epoch, change_keys, create_and_faucet_wallet +from wallet_config import MM_WALLET, WalletConfig +from vega_sim.null_service import VegaServiceNull + +# region Constants +ACTIVITY = "activity" +HOARDER = "hoarder" +COMBO = "combo" + +REWARDS_URL = "/#/rewards" + +# test IDs +COMBINED_MULTIPLIERS = "combined-multipliers" +TOTAL_REWARDS = "total-rewards" +PRICE_TAKING_COL_ID = '[col-id="priceTaking"]' +TOTAL_COL_ID = '[col-id="total"]' +ROW = "row" +STREAK_REWARD_MULTIPLIER_VALUE = "streak-reward-multiplier-value" +HOARDER_REWARD_MULTIPLIER_VALUE = "hoarder-reward-multiplier-value" +HOARDER_BONUS_TOTAL_HOARDED = "hoarder-bonus-total-hoarded" +EARNED_BY_ME_BUTTON = "earned-by-me-button" +TRANSFER_AMOUNT = "transfer-amount" +EPOCH_STREAK = "epoch-streak" + +# endregion + +# Keys +PARTY_A = "PARTY_A" +PARTY_B = "PARTY_B" +PARTY_C = "PARTY_C" +PARTY_D = "PARTY_D" + + +@pytest.fixture(scope="module") +def vega(request): + with init_vega(request) as vega_instance: + request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + yield vega_instance + + + +@pytest.fixture(scope="module") +def page(vega, browser, request): + with init_page(vega, browser, request) as page: + risk_accepted_setup(page) + auth_setup(vega, page) + page.goto(REWARDS_URL) + change_keys(page, vega, PARTY_B) + yield page + + +@pytest.fixture(scope="module", autouse=True) +def setup_market_with_reward_program(vega: VegaServiceNull): + tDAI_market = setup_continuous_market(vega) + PARTY_A, PARTY_B, PARTY_C, PARTY_D = keys(vega) + tDAI_asset_id = vega.find_asset_id(symbol="tDAI") + vega.mint(key_name=PARTY_B.name, asset=tDAI_asset_id, amount=100000) + vega.mint(key_name=PARTY_C.name, asset=tDAI_asset_id, amount=100000) + vega.mint(key_name=PARTY_A.name, asset=tDAI_asset_id, amount=100000) + vega.mint(key_name=PARTY_D.name, asset=tDAI_asset_id, amount=100000) + next_epoch(vega=vega) + + vega.update_network_parameter( + proposal_key=MM_WALLET.name, + parameter="rewards.activityStreak.benefitTiers", + new_value=ACTIVITY_STREAKS, + ) + print("update_network_parameter activity done") + next_epoch(vega=vega) + + tDAI_asset_id = vega.find_asset_id(symbol="tDAI") + vega.update_network_parameter( + MM_WALLET.name, parameter="reward.asset", new_value=tDAI_asset_id + ) + + next_epoch(vega=vega) + vega.recurring_transfer( + from_key_name=PARTY_A.name, + from_account_type=vega_protos.vega.ACCOUNT_TYPE_GENERAL, + to_account_type=vega_protos.vega.ACCOUNT_TYPE_REWARD_MAKER_PAID_FEES, + asset=tDAI_asset_id, + reference="reward", + asset_for_metric=tDAI_asset_id, + metric=vega_protos.vega.DISPATCH_METRIC_MAKER_FEES_PAID, + amount=100, + factor=1.0, + ) + vega.submit_order( + trading_key=PARTY_B.name, + market_id=tDAI_market, + order_type="TYPE_MARKET", + time_in_force="TIME_IN_FORCE_IOC", + side="SIDE_BUY", + volume=1, + ) + vega.submit_order( + trading_key=PARTY_A.name, + market_id=tDAI_market, + order_type="TYPE_MARKET", + time_in_force="TIME_IN_FORCE_IOC", + side="SIDE_BUY", + volume=1, + ) + + vega.wait_for_total_catchup() + + next_epoch(vega=vega) + return tDAI_market, tDAI_asset_id + + +ACTIVITY_STREAKS = """ +{ + "tiers": [ + { + "minimum_activity_streak": 2, + "reward_multiplier": "2.0", + "vesting_multiplier": "1.1" + } + ] +} +""" + + +def keys(vega): + PARTY_A = WalletConfig("PARTY_A", "PARTY_A") + create_and_faucet_wallet(vega=vega, wallet=PARTY_A) + PARTY_B = WalletConfig("PARTY_B", "PARTY_B") + create_and_faucet_wallet(vega=vega, wallet=PARTY_B) + PARTY_C = WalletConfig("PARTY_C", "PARTY_C") + create_and_faucet_wallet(vega=vega, wallet=PARTY_C) + PARTY_D = WalletConfig("PARTY_D", "PARTY_D") + create_and_faucet_wallet(vega=vega, wallet=PARTY_D) + return PARTY_A, PARTY_B, PARTY_C, PARTY_D + + +@pytest.mark.xdist_group(name="test_rewards_activity_tier_0") +def test_network_reward_pot( + page: Page, +): + expect(page.get_by_test_id(TOTAL_REWARDS)).to_have_text("50.00 tDAI") + + +@pytest.mark.xdist_group(name="test_rewards_activity_tier_0") +def test_reward_multiplier( + page: Page, +): + expect(page.get_by_test_id(COMBINED_MULTIPLIERS)).to_have_text("1x") + expect(page.get_by_test_id(STREAK_REWARD_MULTIPLIER_VALUE)).to_have_text("1x") + expect(page.get_by_test_id(HOARDER_REWARD_MULTIPLIER_VALUE)).to_have_text("1x") + + +@pytest.mark.xdist_group(name="test_rewards_activity_tier_0") +def test_activity_streak( + page: Page, +): + expect(page.get_by_test_id(EPOCH_STREAK)).to_have_text( + "Active trader: 1 epochs so far " + ) + + +@pytest.mark.xdist_group(name="test_rewards_activity_tier_0") +def test_reward_history( + page: Page, +): + page.locator('[name="fromEpoch"]').fill("1") + expect((page.get_by_role(ROW).locator(PRICE_TAKING_COL_ID)).nth(1)).to_have_text( + "100.00100.00%" + ) + expect((page.get_by_role(ROW).locator(TOTAL_COL_ID)).nth(1)).to_have_text("100.00") + page.get_by_test_id(EARNED_BY_ME_BUTTON).click() + expect((page.get_by_role(ROW).locator(TOTAL_COL_ID)).nth(1)).to_have_text("50.00") diff --git a/apps/trading/e2e/tests/settings/test_settings.py b/apps/trading/e2e/tests/settings/test_settings.py index d929ccc32..ea052bc40 100644 --- a/apps/trading/e2e/tests/settings/test_settings.py +++ b/apps/trading/e2e/tests/settings/test_settings.py @@ -1,12 +1,13 @@ import pytest from playwright.sync_api import expect, Page -from conftest import init_vega +from conftest import init_vega, cleanup_container @pytest.fixture(scope="module") -def vega(): - with init_vega() as vega: - yield vega +def vega(request): + with init_vega(request) as vega_instance: + request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + yield vega_instance @pytest.mark.usefixtures("risk_accepted") diff --git a/apps/trading/e2e/tests/teams/test_teams.py b/apps/trading/e2e/tests/teams/test_teams.py index a22102ac3..56559d3ec 100644 --- a/apps/trading/e2e/tests/teams/test_teams.py +++ b/apps/trading/e2e/tests/teams/test_teams.py @@ -2,17 +2,17 @@ import pytest from playwright.sync_api import expect, Page import vega_sim.proto.vega as vega_protos from vega_sim.null_service import VegaServiceNull -from conftest import init_vega +from conftest import init_vega, cleanup_container from actions.utils import next_epoch, change_keys from fixtures.market import setup_continuous_market from conftest import auth_setup, init_page, init_vega, risk_accepted_setup from wallet_config import PARTY_A, PARTY_B, PARTY_C, PARTY_D, MM_WALLET - @pytest.fixture(scope="module") def vega(request): - with init_vega(request) as vega: - yield vega + with init_vega(request) as vega_instance: + request.addfinalizer(lambda: cleanup_container(vega_instance)) # Register the cleanup function + yield vega_instance @pytest.fixture(scope="module") @@ -237,12 +237,12 @@ def test_team_page_headline(team_page: Page, setup_teams_and_games): expect(team_page.get_by_test_id("team-name")).to_have_text(team_name) expect(team_page.get_by_test_id("members-count-stat")).to_have_text("4") - expect(team_page.get_by_test_id("total-games-stat")).to_have_text("2") + expect(team_page.get_by_test_id("total-games-stat")).to_have_text("1") # TODO this still seems wrong as its always 0 expect(team_page.get_by_test_id("total-volume-stat")).to_have_text("0") - expect(team_page.get_by_test_id("rewards-paid-stat")).to_have_text("214") + expect(team_page.get_by_test_id("rewards-paid-stat")).to_have_text("78") def test_switch_teams(team_page: Page, vega: VegaServiceNull): @@ -271,7 +271,7 @@ def test_leaderboard(competitions_page: Page, setup_teams_and_games): # FIXME: the numbers are different we need to clarify this with the backend # expect(competitions_page.get_by_test_id("earned-1")).to_have_text("160") - expect(competitions_page.get_by_test_id("games-1")).to_have_text("2") + expect(competitions_page.get_by_test_id("games-1")).to_have_text("1") # TODO still odd that this is 0 expect(competitions_page.get_by_test_id("volume-0")).to_have_text("-") From 76c07992d3422fa9ffc757625317812eb71461e0 Mon Sep 17 00:00:00 2001 From: "m.ray" <16125548+MadalinaRaicu@users.noreply.github.com> Date: Thu, 8 Feb 2024 15:24:48 +0200 Subject: [PATCH 2/2] feat(trading): update mobile layout (#5718) Co-authored-by: Matthew Russell --- apps/explorer/src/assets/manifest.json | 4 +- apps/governance/src/assets/manifest.json | 4 +- apps/static/src/index.html | 2 +- apps/trading/assets/manifest.json | 16 ++- .../market/market-header-stats.tsx | 3 +- .../client-pages/market/trade-panels.tsx | 113 +++++++++------ .../layouts/layout-with-sidebar.tsx | 12 +- .../trading/components/market-header/index.ts | 1 + .../market-header/mobile-market-header.tsx | 133 ++++++++++++++++++ apps/trading/components/navbar/index.tsx | 1 - apps/trading/components/navbar/nav-header.tsx | 81 ----------- apps/trading/components/navbar/navbar.tsx | 10 +- apps/trading/pages/_app.page.tsx | 15 +- apps/trading/pages/_document.page.tsx | 7 +- apps/trading/pages/client-router.tsx | 11 +- apps/trading/public/manifest.json | 22 +++ .../last-24h-price-change.tsx | 7 +- 17 files changed, 267 insertions(+), 175 deletions(-) create mode 100644 apps/trading/components/market-header/mobile-market-header.tsx delete mode 100644 apps/trading/components/navbar/nav-header.tsx create mode 100644 apps/trading/public/manifest.json diff --git a/apps/explorer/src/assets/manifest.json b/apps/explorer/src/assets/manifest.json index 949569331..4cbc76d39 100644 --- a/apps/explorer/src/assets/manifest.json +++ b/apps/explorer/src/assets/manifest.json @@ -1,6 +1,6 @@ { - "short_name": "Mainnet Stats", - "name": "Vega Mainnet statistics", + "short_name": "Explorer VEGA", + "name": "Vega Protocol - Explorer", "icons": [ { "src": "favicon.ico", diff --git a/apps/governance/src/assets/manifest.json b/apps/governance/src/assets/manifest.json index 949569331..4779dbc73 100644 --- a/apps/governance/src/assets/manifest.json +++ b/apps/governance/src/assets/manifest.json @@ -1,6 +1,6 @@ { - "short_name": "Mainnet Stats", - "name": "Vega Mainnet statistics", + "short_name": "Governance VEGA", + "name": "Vega Protocol - Governance", "icons": [ { "src": "favicon.ico", diff --git a/apps/static/src/index.html b/apps/static/src/index.html index 2ab0a6f71..b49517237 100644 --- a/apps/static/src/index.html +++ b/apps/static/src/index.html @@ -4,7 +4,7 @@ - Vega Protocol static asseets + Vega Protocol static assets diff --git a/apps/trading/assets/manifest.json b/apps/trading/assets/manifest.json index 949569331..37981d3d3 100644 --- a/apps/trading/assets/manifest.json +++ b/apps/trading/assets/manifest.json @@ -1,6 +1,12 @@ { - "short_name": "Mainnet Stats", - "name": "Vega Mainnet statistics", + "name": "Vega Protocol - Trading", + "short_name": "Console", + "description": "Vega Protocol - Trading dApp", + "start_url": "/", + "display": "standalone", + "orientation": "portrait", + "theme_color": "#000000", + "background_color": "#ffffff", "icons": [ { "src": "favicon.ico", @@ -12,9 +18,5 @@ "type": "image/png", "sizes": "192x192" } - ], - "start_url": ".", - "display": "standalone", - "theme_color": "#000000", - "background_color": "#ffffff" + ] } diff --git a/apps/trading/client-pages/market/market-header-stats.tsx b/apps/trading/client-pages/market/market-header-stats.tsx index 38952d49e..c9ee0dee6 100644 --- a/apps/trading/client-pages/market/market-header-stats.tsx +++ b/apps/trading/client-pages/market/market-header-stats.tsx @@ -56,6 +56,7 @@ export const MarketHeaderStats = ({ market }: MarketHeaderStatsProps) => { -} /> @@ -112,7 +113,7 @@ export const MarketHeaderStats = ({ market }: MarketHeaderStatsProps) => { heading={`${t('Funding Rate')} / ${t('Countdown')}`} testId="market-funding" > -
+
diff --git a/apps/trading/client-pages/market/trade-panels.tsx b/apps/trading/client-pages/market/trade-panels.tsx index 870a87509..759a56364 100644 --- a/apps/trading/client-pages/market/trade-panels.tsx +++ b/apps/trading/client-pages/market/trade-panels.tsx @@ -3,7 +3,6 @@ import { type Market } from '@vegaprotocol/markets'; // TODO: handle oracle banner // import { OracleBanner } from '@vegaprotocol/markets'; import { useState } from 'react'; -import AutoSizer from 'react-virtualized-auto-sizer'; import classNames from 'classnames'; import { Popover, @@ -12,21 +11,21 @@ import { VegaIconNames, } from '@vegaprotocol/ui-toolkit'; import { useT } from '../../lib/use-t'; -import { MarketBanner } from '../../components/market-banner'; import { ErrorBoundary } from '../../components/error-boundary'; import { type TradingView } from './trade-views'; import { TradingViews } from './trade-views'; - interface TradePanelsProps { market: Market; pinnedAsset?: PinnedAsset; } export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => { - const [view, setView] = useState('chart'); - const viewCfg = TradingViews[view]; + const [topView, setTopView] = useState('chart'); + const topViewCfg = TradingViews[topView]; + const [bottomView, setBottomView] = useState('positions'); + const bottomViewCfg = TradingViews[bottomView]; - const renderView = () => { + const renderView = (view: TradingView) => { const Component = TradingViews[view].component; if (!Component) { @@ -39,12 +38,13 @@ export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => { // so watch out for clashes in props return ( - ; + ); }; - const renderMenu = () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const renderMenu = (viewCfg: any) => { if ('menu' in viewCfg || 'settings' in viewCfg) { return (
@@ -69,55 +69,80 @@ export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => { }; return ( -
-
- -
-
{renderMenu()}
-
- - {({ width, height }) => ( -
- {renderView()} -
- )} -
-
-
- {Object.keys(TradingViews) - // filter to control available views for the current market - // eg only perps should get the funding views - .filter((_key) => { - const key = _key as TradingView; - const perpOnlyViews = ['funding', 'fundingPayments']; +
+
+
+ {['chart', 'orderbook', 'trades', 'liquidity', 'fundingPayments'] + // filter to control available views for the current market + // e.g. only perpetuals should get the funding views + .filter((_key) => { + const key = _key as TradingView; + const perpOnlyViews = ['funding', 'fundingPayments']; + + if ( + market?.tradableInstrument.instrument.product.__typename === + 'Perpetual' + ) { + return true; + } + + if (perpOnlyViews.includes(key)) { + return false; + } - if ( - market?.tradableInstrument.instrument.product.__typename === - 'Perpetual' - ) { return true; - } + }) + .map((_key) => { + const key = _key as TradingView; + const isActive = topView === key; + return ( + { + setTopView(key); + }} + /> + ); + })} +
+
+
{renderMenu(topViewCfg)}
+
{renderView(topView)}
+
+
- if (perpOnlyViews.includes(key)) { - return false; - } - - return true; - }) - .map((_key) => { +
+
+ {[ + 'positions', + 'activeOrders', + 'closedOrders', + 'rejectedOrders', + 'orders', + 'stopOrders', + 'collateral', + 'fills', + ].map((_key) => { const key = _key as TradingView; - const isActive = view === key; + const isActive = bottomView === key; return ( { - setView(key); + setBottomView(key); }} /> ); })} +
+
+
{renderMenu(bottomViewCfg)}
+
{renderView(bottomView)}
+
); @@ -157,7 +182,7 @@ const useViewLabel = (view: TradingView) => { depth: t('Depth'), liquidity: t('Liquidity'), funding: t('Funding'), - fundingPayments: t('Funding Payments'), + fundingPayments: t('Funding'), orderbook: t('Orderbook'), trades: t('Trades'), positions: t('Positions'), diff --git a/apps/trading/components/layouts/layout-with-sidebar.tsx b/apps/trading/components/layouts/layout-with-sidebar.tsx index eec996706..937113c62 100644 --- a/apps/trading/components/layouts/layout-with-sidebar.tsx +++ b/apps/trading/components/layouts/layout-with-sidebar.tsx @@ -3,7 +3,6 @@ import { Outlet } from 'react-router-dom'; import { Sidebar, SidebarContent, useSidebar } from '../sidebar'; import classNames from 'classnames'; import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id'; - export const LayoutWithSidebar = ({ header, sidebar, @@ -27,10 +26,13 @@ export const LayoutWithSidebar = ({
{header}
diff --git a/apps/trading/components/market-header/index.ts b/apps/trading/components/market-header/index.ts index fe42898da..54e3fbc3e 100644 --- a/apps/trading/components/market-header/index.ts +++ b/apps/trading/components/market-header/index.ts @@ -1 +1,2 @@ export * from './market-header'; +export * from './mobile-market-header'; diff --git a/apps/trading/components/market-header/mobile-market-header.tsx b/apps/trading/components/market-header/mobile-market-header.tsx new file mode 100644 index 000000000..3e2438882 --- /dev/null +++ b/apps/trading/components/market-header/mobile-market-header.tsx @@ -0,0 +1,133 @@ +import { VegaIcon, VegaIconNames } from '@vegaprotocol/ui-toolkit'; +import { MarketSelector } from '../market-selector'; +import { + Last24hPriceChange, + useMarket, + useMarketList, +} from '@vegaprotocol/markets'; +import { useParams } from 'react-router-dom'; +import * as PopoverPrimitive from '@radix-ui/react-popover'; +import { useState } from 'react'; +import { useT } from '../../lib/use-t'; +import classNames from 'classnames'; +import { MarketHeaderStats } from '../../client-pages/market/market-header-stats'; +import { MarketMarkPrice } from '../market-mark-price'; +/** + * This is only rendered for the mobile navigation + */ +export const MobileMarketHeader = () => { + const t = useT(); + const { marketId } = useParams(); + const { data } = useMarket(marketId); + const [openMarket, setOpenMarket] = useState(false); + const [openPrice, setOpenPrice] = useState(false); + + // Ensure that markets are kept cached so opening the list + // shows all markets instantly + useMarketList(); + + if (!marketId) return null; + + return ( +
+ { + setOpenMarket(x); + }} + trigger={ +

+ {data + ? data.tradableInstrument.instrument.code + : t('Select market')} + + + +

+ } + > + setOpenMarket(false)} + /> +
+ { + setOpenPrice(x); + }} + trigger={ + + {data && ( + <> + + + + + + + + + )} + + } + > + {data && ( +
+ +
+ )} +
+
+ ); +}; + +export interface PopoverProps extends PopoverPrimitive.PopoverProps { + trigger: React.ReactNode | string; +} + +export const FullScreenPopover = ({ + trigger, + children, + open, + onOpenChange, +}: PopoverProps) => { + return ( + + + {trigger} + + + + {children} + + + + ); +}; diff --git a/apps/trading/components/navbar/index.tsx b/apps/trading/components/navbar/index.tsx index 376d1c7c5..f5899d036 100644 --- a/apps/trading/components/navbar/index.tsx +++ b/apps/trading/components/navbar/index.tsx @@ -1,2 +1 @@ export * from './navbar'; -export * from './nav-header'; diff --git a/apps/trading/components/navbar/nav-header.tsx b/apps/trading/components/navbar/nav-header.tsx deleted file mode 100644 index 0715900a7..000000000 --- a/apps/trading/components/navbar/nav-header.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import { VegaIcon, VegaIconNames } from '@vegaprotocol/ui-toolkit'; -import { MarketSelector } from '../market-selector'; -import { useMarket, useMarketList } from '@vegaprotocol/markets'; -import { useParams } from 'react-router-dom'; -import * as PopoverPrimitive from '@radix-ui/react-popover'; -import { useState } from 'react'; -import { useT } from '../../lib/use-t'; -import classNames from 'classnames'; - -/** - * This is only rendered for the mobile navigation - */ -export const NavHeader = () => { - const t = useT(); - const { marketId } = useParams(); - const { data } = useMarket(marketId); - const [open, setOpen] = useState(false); - - // Ensure that markets are kept cached so opening the list - // shows all markets instantly - useMarketList(); - - if (!marketId) return null; - - return ( - { - setOpen(x); - }} - trigger={ -

- {data ? data.tradableInstrument.instrument.code : t('Select market')} - - - -

- } - > - setOpen(false)} - /> -
- ); -}; - -export interface PopoverProps extends PopoverPrimitive.PopoverProps { - trigger: React.ReactNode | string; -} - -export const FullScreenPopover = ({ - trigger, - children, - open, - onOpenChange, -}: PopoverProps) => { - return ( - - - {trigger} - - - - {children} - - - - ); -}; diff --git a/apps/trading/components/navbar/navbar.tsx b/apps/trading/components/navbar/navbar.tsx index b304df2d4..476e5465f 100644 --- a/apps/trading/components/navbar/navbar.tsx +++ b/apps/trading/components/navbar/navbar.tsx @@ -34,13 +34,7 @@ import { supportedLngs } from '../../lib/i18n'; type MenuState = 'wallet' | 'nav' | null; type Theme = 'system' | 'yellow'; -export const Navbar = ({ - children, - theme = 'system', -}: { - children?: ReactNode; - theme?: Theme; -}) => { +export const Navbar = ({ theme = 'system' }: { theme?: Theme }) => { const i18n = useI18n(); const t = useT(); // menu state for small screens @@ -75,8 +69,6 @@ export const Navbar = ({ > - {/* Left section */} -
{children}
{/* Used to show header in nav on mobile */}
setMenu(null)} /> diff --git a/apps/trading/pages/_app.page.tsx b/apps/trading/pages/_app.page.tsx index e2273fc90..e6913f4d2 100644 --- a/apps/trading/pages/_app.page.tsx +++ b/apps/trading/pages/_app.page.tsx @@ -14,7 +14,7 @@ import './styles.css'; import { usePageTitleStore } from '../stores'; import DialogsContainer from './dialogs-container'; import ToastsManager from './toasts-manager'; -import { HashRouter, useLocation, Route, Routes } from 'react-router-dom'; +import { HashRouter, useLocation } from 'react-router-dom'; import { Bootstrapper } from '../components/bootstrapper'; import { AnnouncementBanner } from '../components/banner'; import { Navbar } from '../components/navbar'; @@ -25,9 +25,7 @@ import { ProtocolUpgradeProposalNotification, } from '@vegaprotocol/proposals'; import { ViewingBanner } from '../components/viewing-banner'; -import { NavHeader } from '../components/navbar/nav-header'; import { Telemetry } from '../components/telemetry'; -import { Routes as AppRoutes } from '../lib/links'; import { SSRLoader } from './ssr-loader'; import { PartyActiveOrdersHandler } from './party-active-orders-handler'; import { MaybeConnectEagerly } from './maybe-connect-eagerly'; @@ -73,16 +71,7 @@ function AppBody({ Component }: AppProps) { <div className={gridClasses}> <AnnouncementBanner /> - <Navbar theme={VEGA_ENV === Networks.TESTNET ? 'yellow' : 'system'}> - <Routes> - <Route - path={AppRoutes.MARKETS} - // render nothing for markets/all, otherwise markets/:marketId will match with markets/all - element={null} - /> - <Route path={AppRoutes.MARKET} element={<NavHeader />} /> - </Routes> - </Navbar> + <Navbar theme={VEGA_ENV === Networks.TESTNET ? 'yellow' : 'system'} /> <div data-testid="banners"> <ProtocolUpgradeProposalNotification mode={ProtocolUpgradeCountdownMode.IN_ESTIMATED_TIME_REMAINING} diff --git a/apps/trading/pages/_document.page.tsx b/apps/trading/pages/_document.page.tsx index 80e28f715..4ddd0fa58 100644 --- a/apps/trading/pages/_document.page.tsx +++ b/apps/trading/pages/_document.page.tsx @@ -24,11 +24,14 @@ export default function Document() { {/* scripts */} <script src="/theme-setter.js" type="text/javascript" async /> + + {/* manifest */} + <link rel="manifest" href="/apps/trading/public/manifest.json" /> </Head> <Html> <body - // Nextjs will set body to display none until js runs. Because the entire app is client rendered - // and delivered via ipfs we override this to show a server side render loading animation until the + // Next.js will set body to display none until js runs. Because the entire app is client rendered + // and delivered via IPFS we override this to show a server side render loading animation until the // js is downloaded and react takes over rendering style={{ display: 'block' }} className="bg-white dark:bg-vega-cdark-900 text-default font-alpha" diff --git a/apps/trading/pages/client-router.tsx b/apps/trading/pages/client-router.tsx index 832e9a7cc..5db2ad224 100644 --- a/apps/trading/pages/client-router.tsx +++ b/apps/trading/pages/client-router.tsx @@ -23,7 +23,7 @@ import { NotFound as ReferralNotFound } from '../client-pages/referrals/error-bo import { compact } from 'lodash'; import { useFeatureFlags } from '@vegaprotocol/environment'; import { LiquidityHeader } from '../components/liquidity-header'; -import { MarketHeader } from '../components/market-header'; +import { MarketHeader, MobileMarketHeader } from '../components/market-header'; import { PortfolioSidebar } from '../client-pages/portfolio/portfolio-sidebar'; import { LiquiditySidebar } from '../client-pages/liquidity/liquidity-sidebar'; import { MarketsSidebar } from '../client-pages/markets/markets-sidebar'; @@ -33,6 +33,7 @@ import { CompetitionsTeams } from '../client-pages/competitions/competitions-tea import { CompetitionsTeam } from '../client-pages/competitions/competitions-team'; import { CompetitionsCreateTeam } from '../client-pages/competitions/competitions-create-team'; import { CompetitionsUpdateTeam } from '../client-pages/competitions/competitions-update-team'; +import { useScreenDimensions } from '@vegaprotocol/react-helpers'; // These must remain dynamically imported as pennant cannot be compiled by nextjs due to ESM // Using dynamic imports is a workaround for this until pennant is published as ESM @@ -50,6 +51,9 @@ const NotFound = () => { export const useRouterConfig = (): RouteObject[] => { const featureFlags = useFeatureFlags((state) => state.flags); + const { screenSize } = useScreenDimensions(); + const largeScreen = ['lg', 'xl', 'xxl', 'xxxl'].includes(screenSize); + const marketHeader = largeScreen ? <MarketHeader /> : <MobileMarketHeader />; const routeConfig = compact([ { index: true, @@ -151,10 +155,7 @@ export const useRouterConfig = (): RouteObject[] => { { path: 'markets/*', element: ( - <LayoutWithSidebar - header={<MarketHeader />} - sidebar={<MarketsSidebar />} - /> + <LayoutWithSidebar header={marketHeader} sidebar={<MarketsSidebar />} /> ), children: [ { diff --git a/apps/trading/public/manifest.json b/apps/trading/public/manifest.json new file mode 100644 index 000000000..77abf4cc7 --- /dev/null +++ b/apps/trading/public/manifest.json @@ -0,0 +1,22 @@ +{ + "name": "Vega Protocol - Trading", + "short_name": "Console", + "description": "Vega Protocol - Trading dApp", + "start_url": "/", + "display": "standalone", + "orientation": "portrait", + "theme_color": "#000000", + "background_color": "#ffffff", + "icons": [ + { + "src": "favicon.ico", + "sizes": "64x64 32x32 24x24 16x16", + "type": "image/x-icon" + }, + { + "src": "cover.png", + "type": "image/png", + "sizes": "192x192" + } + ] +} diff --git a/libs/markets/src/lib/components/last-24h-price-change/last-24h-price-change.tsx b/libs/markets/src/lib/components/last-24h-price-change/last-24h-price-change.tsx index 4a1afafab..828841bf4 100644 --- a/libs/markets/src/lib/components/last-24h-price-change/last-24h-price-change.tsx +++ b/libs/markets/src/lib/components/last-24h-price-change/last-24h-price-change.tsx @@ -18,12 +18,15 @@ interface Props { initialValue?: string[]; isHeader?: boolean; noUpdate?: boolean; + // render prop for no price change + fallback?: React.ReactNode; } export const Last24hPriceChange = ({ marketId, decimalPlaces, initialValue, + fallback, }: Props) => { const t = useT(); const { oneDayCandles, error, fiveDaysCandles } = useCandles({ @@ -48,13 +51,13 @@ export const Last24hPriceChange = ({ </span> } > - <span>-</span> + <span>{fallback}</span> </Tooltip> ); } if (error || !isNumeric(decimalPlaces)) { - return <span>-</span>; + return <span>{fallback}</span>; } const candles = oneDayCandles?.map((c) => c.close) || initialValue || [];