Compare commits

..
Author SHA1 Message Date
asiaznik fa15af648f fix: add unit tests 2023-12-15 15:00:07 +01:00
asiaznik 702a17436d feat: desconnection toast 2023-12-15 15:00:07 +01:00
asiaznik aa29e60d0e feat(wallet): disconnect if wallet unreachable 2023-12-15 15:00:07 +01:00
152 changed files with 1040 additions and 2592 deletions
-1
View File
@@ -1,4 +1,3 @@
* text eol=lf
*.png binary
*.ico binary
*.woff2 binary
@@ -24,7 +24,7 @@ export const AssetsTable = ({ data }: AssetsTableProps) => {
const navigate = useNavigate();
const ref = useRef<AgGridReact>(null);
const showColumnsOnDesktop = () => {
ref.current?.api.setColumnsVisible(
ref.current?.columnApi.setColumnsVisible(
['id', 'type', 'status'],
window.innerWidth > BREAKPOINT_MD
);
@@ -29,7 +29,7 @@ export const MarketsTable = ({ data }: MarketsTableProps) => {
const gridRef = useRef<AgGridReact>(null);
useLayoutEffect(() => {
const showColumnsOnDesktop = () => {
gridRef.current?.api.setColumnsVisible(
gridRef.current?.columnApi.setColumnsVisible(
['id', 'state', 'asset'],
window.innerWidth > BREAKPOINT_MD
);
@@ -44,11 +44,11 @@ export const ProposalsTable = ({ data }: ProposalsTableProps) => {
const gridRef = useRef<AgGridReact>(null);
useLayoutEffect(() => {
const showColumnsOnDesktop = () => {
gridRef.current?.api.setColumnsVisible(
gridRef.current?.columnApi.setColumnsVisible(
['voting', 'cDate', 'eDate', 'type'],
window.innerWidth > BREAKPOINT_MD
);
gridRef.current?.api.setColumnWidth(
gridRef.current?.columnApi.setColumnWidth(
'actions',
window.innerWidth > BREAKPOINT_MD ? 221 : 80
);
@@ -54,7 +54,7 @@ const Block = () => {
</Button>
</Link>
</div>
{blockData && 'result' in blockData && (
{blockData && (
<>
<TableWithTbody className="mb-8">
<TableRow modifier="bordered">
+1 -1
View File
@@ -32,7 +32,7 @@ CYPRESS_FAIRGROUND=false
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
NX_METAMASK_SNAPS=true
NX_METAMASK_SNAPS=false
NX_PRODUCT_PERPETUALS=true
NX_UPDATE_MARKET_STATE=true
NX_REFERRALS=true
+1 -1
View File
@@ -23,7 +23,7 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
NX_METAMASK_SNAPS=true
NX_METAMASK_SNAPS=false
NX_PRODUCT_PERPETUALS=true
NX_UPDATE_MARKET_STATE=true
NX_REFERRALS=true
+1 -1
View File
@@ -22,7 +22,7 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://be.mainnet-mirror.vega.rocks/websocket
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
NX_METAMASK_SNAPS=true
NX_METAMASK_SNAPS=false
NX_PRODUCT_PERPETUALS=true
NX_UPDATE_MARKET_STATE=true
NX_REFERRALS=true
+1 -1
View File
@@ -21,7 +21,7 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.
# Cosmic elevator flags
NX_SUCCESSOR_MARKETS=true
NX_METAMASK_SNAPS=true
NX_METAMASK_SNAPS=false
NX_PRODUCT_PERPETUALS=true
NX_UPDATE_MARKET_STATE=true
NX_REFERRALS=true
@@ -281,8 +281,8 @@ describe('VoteBreakdown', () => {
});
it('Progress bar displays status - LP majority', () => {
const yesVotesLP = 0.8;
const noVotesLP = 0.2;
const yesVotesLP = 800;
const noVotesLP = 200;
const expectedProgress = (yesVotesLP / (yesVotesLP + noVotesLP)) * 100; // 80%
renderComponent(
@@ -105,6 +105,8 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
yesLPPercentage,
yesTokens,
noTokens,
yesEquityLikeShareWeight,
noEquityLikeShareWeight,
totalEquityLikeShareWeight,
requiredMajorityPercentage,
requiredMajorityLPPercentage,
@@ -133,7 +135,6 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
.multipliedBy(100),
new BigNumber(100)
);
const willPass = willPassByTokenVote || willPassByLPVote;
const updateMarketVotePassMethod = willPassByTokenVote
? t('byTokenVote')
@@ -201,24 +202,50 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
<div className="flex items-center gap-1">
<span>{t('liquidityProviderVotesFor')}:</span>
<Tooltip
description={
<span>{yesLPPercentage.toFixed(defaultDP)}%</span>
}
description={formatNumber(
yesEquityLikeShareWeight,
defaultDP
)}
>
<button>{yesLPPercentage.toFixed(1)}%</button>
<button>
<CompactVotes number={yesEquityLikeShareWeight} />
</button>
</Tooltip>
<span>
(
<Tooltip
description={
<span>{yesLPPercentage.toFixed(defaultDP)}%</span>
}
>
<button>{yesLPPercentage.toFixed(0)}%</button>
</Tooltip>
)
</span>
</div>
<div className="flex items-center gap-1">
<span>{t('liquidityProviderVotesAgainst')}:</span>
<Tooltip
description={formatNumber(
noEquityLikeShareWeight,
defaultDP
)}
>
<button>
<CompactVotes number={noEquityLikeShareWeight} />
</button>
</Tooltip>
<span>
(
<Tooltip
description={
<span>{noLPPercentage.toFixed(defaultDP)}%</span>
}
>
<button>{noLPPercentage.toFixed(1)}%</button>
<button>{noLPPercentage.toFixed(0)}%</button>
</Tooltip>
)
</span>
</div>
</div>
@@ -255,8 +282,13 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
defaultDP
)}
>
<span>{totalEquityLikeShareWeight.toFixed(1)}%</span>
<button>
<CompactVotes number={totalEquityLikeShareWeight} />
</button>
</Tooltip>
<span>
({totalEquityLikeShareWeight.toFixed(defaultDP)}%)
</span>
</div>
</div>
</section>
@@ -54,8 +54,8 @@ describe('use-vote-information', () => {
it('returns all required vote information', () => {
const yesVotes = 40;
const noVotes = 60;
const yesEquityLikeShareWeight = '0.30';
const noEquityLikeShareWeight = '0.70';
const yesEquityLikeShareWeight = '30';
const noEquityLikeShareWeight = '70';
// Note - giving a fixedTokenValue of 1 means a ratio of 1:1 votes to tokens, making sums easier :)
const fixedTokenValue = 1000000000000000000;
@@ -195,10 +195,10 @@ describe('use-vote-information', () => {
});
it('correctly shows whether an update market proposal will pass by token or LP vote - both failing', () => {
const yesVotes = 0.2;
const noVotes = 0.7;
const yesEquityLikeShareWeight = '0.30';
const noEquityLikeShareWeight = '0.60';
const yesVotes = 20;
const noVotes = 70;
const yesEquityLikeShareWeight = '30';
const noEquityLikeShareWeight = '60';
const fixedTokenValue = 1000000000000000000;
const proposal = generateProposal({
@@ -61,7 +61,7 @@ export const useVoteInformation = ({
const noEquityLikeShareWeight = !proposal?.votes.no
.totalEquityLikeShareWeight
? new BigNumber(0)
: new BigNumber(proposal.votes.no.totalEquityLikeShareWeight).times(100);
: new BigNumber(proposal.votes.no.totalEquityLikeShareWeight);
const yesTokens = new BigNumber(
addDecimal(proposal?.votes.yes.totalTokens ?? 0, decimals)
@@ -70,7 +70,7 @@ export const useVoteInformation = ({
const yesEquityLikeShareWeight = !proposal?.votes.yes
.totalEquityLikeShareWeight
? new BigNumber(0)
: new BigNumber(proposal.votes.yes.totalEquityLikeShareWeight).times(100);
: new BigNumber(proposal.votes.yes.totalEquityLikeShareWeight);
const totalTokensVoted = yesTokens.plus(noTokens);
@@ -81,7 +81,12 @@ export const useVoteInformation = ({
const yesPercentage = totalTokensVoted.isZero()
? new BigNumber(0)
: yesTokens.multipliedBy(100).dividedBy(totalTokensVoted);
const yesLPPercentage = yesEquityLikeShareWeight;
const yesLPPercentage = totalEquityLikeShareWeight.isZero()
? new BigNumber(0)
: yesEquityLikeShareWeight
.multipliedBy(100)
.dividedBy(totalEquityLikeShareWeight);
const noPercentage = totalTokensVoted.isZero()
? new BigNumber(0)
@@ -98,7 +103,9 @@ export const useVoteInformation = ({
);
const participationLPMet = requiredParticipationLP
? totalEquityLikeShareWeight.isGreaterThan(requiredParticipationLP)
? totalEquityLikeShareWeight.isGreaterThan(
totalSupply.multipliedBy(requiredParticipationLP)
)
: false;
const majorityMet = yesPercentage.isGreaterThanOrEqualTo(
@@ -113,7 +120,9 @@ export const useVoteInformation = ({
.multipliedBy(100)
.dividedBy(totalSupply);
const totalLPTokensPercentage = totalEquityLikeShareWeight;
const totalLPTokensPercentage = totalEquityLikeShareWeight
.multipliedBy(100)
.dividedBy(totalSupply);
const willPassByTokenVote =
participationMet &&
@@ -95,7 +95,7 @@ export const ProtocolUpgradeProposalContainer = () => {
time={
pending && time ? (
convertToCountdownString(time, '0:00:00:00')
) : blockInfo && 'result' in blockInfo && blockInfo?.result ? (
) : blockInfo?.result ? (
<span title={blockInfo.result.block.header.time}>
{formatDateWithLocalTimezone(
new Date(blockInfo.result.block.header.time)
@@ -116,8 +116,7 @@ export const generateYesVotes = (
fixedTokenValue?: number,
totalEquityLikeShareWeight?: string
): Votes => {
const votes = [];
for (let i = 0; i < numberOfVotes; i++) {
const votes = Array.from(Array(numberOfVotes)).map(() => {
const vote: Vote = {
__typename: 'Vote',
value: Schema.VoteValue.VALUE_YES,
@@ -153,9 +152,8 @@ export const generateYesVotes = (
datetime: faker.date.past().toISOString(),
};
votes.push(vote);
}
return vote;
});
return {
__typename: 'ProposalVoteSide',
totalNumber: votes.length.toString(),
@@ -174,8 +172,7 @@ export const generateNoVotes = (
fixedTokenValue?: number,
totalEquityLikeShareWeight?: string
): Votes => {
const votes = [];
for (let i = 0; i < numberOfVotes; i++) {
const votes = Array.from(Array(numberOfVotes)).map(() => {
const vote: Vote = {
__typename: 'Vote',
value: Schema.VoteValue.VALUE_NO,
@@ -210,9 +207,8 @@ export const generateNoVotes = (
},
datetime: faker.date.past().toISOString(),
};
votes.push(vote);
}
return vote;
});
return {
__typename: 'ProposalVoteSide',
totalNumber: votes.length.toString(),
-1
View File
@@ -25,4 +25,3 @@ NX_ICEBERG_ORDERS=true
# NX_PRODUCT_PERPETUALS
NX_METAMASK_SNAPS=true
NX_REFERRALS=true
NX_TEAM_COMPETITION=true
@@ -188,11 +188,12 @@ const useNow = () => {
return now;
};
const useEvery = (marketId: string, skip: boolean) => {
const useEvery = (marketId: string) => {
const { data: marketTradingMode } = useMarketTradingMode(marketId);
const { data: marketInfo } = useDataProvider({
dataProvider: marketInfoProvider,
variables: { marketId },
skip,
skip: !marketTradingMode || isMarketInAuction(marketTradingMode),
});
let every: number | undefined = undefined;
const sourceType =
@@ -210,10 +211,8 @@ const useEvery = (marketId: string, skip: boolean) => {
return every;
};
const useStartTime = (marketId: string, skip: boolean) => {
const useStartTime = (marketId: string) => {
const { data: fundingPeriods } = useFundingPeriodsQuery({
pollInterval: 5000,
skip,
variables: {
marketId: marketId,
pagination: { first: 1 },
@@ -247,10 +246,8 @@ const useFormatCountdown = (
export const FundingCountdown = ({ marketId }: { marketId: string }) => {
const now = useNow();
const { data: marketTradingMode } = useMarketTradingMode(marketId);
const skip = !marketTradingMode || isMarketInAuction(marketTradingMode);
const startTime = useStartTime(marketId, skip);
const every = useEvery(marketId, skip);
const startTime = useStartTime(marketId);
const every = useEvery(marketId);
return (
<div data-testid="funding-countdown">
@@ -90,11 +90,7 @@ const MainGrid = memo(
{market &&
market.tradableInstrument.instrument.product.__typename ===
'Perpetual' ? (
<Tab
id="funding-payments"
name={t('Funding payments')}
settings={<TradingViews.fundingPayments.settings />}
>
<Tab id="funding-payments" name={t('Funding payments')}>
<ErrorBoundary feature="funding-payments">
<TradingViews.fundingPayments.component
marketId={marketId}
@@ -116,11 +112,7 @@ const MainGrid = memo(
<TradingViews.orderbook.component marketId={marketId} />
</ErrorBoundary>
</Tab>
<Tab
id="trades"
name={t('Trades')}
settings={<TradingViews.trades.settings />}
>
<Tab id="trades" name={t('Trades')}>
<ErrorBoundary feature="trades">
<TradingViews.trades.component marketId={marketId} />
</ErrorBoundary>
@@ -141,7 +133,6 @@ const MainGrid = memo(
id="positions"
name={t('Positions')}
menu={<TradingViews.positions.menu />}
settings={<TradingViews.positions.settings />}
>
<ErrorBoundary feature="positions">
<TradingViews.positions.component />
@@ -151,26 +142,17 @@ const MainGrid = memo(
id="open-orders"
name={t('Open')}
menu={<TradingViews.activeOrders.menu />}
settings={<TradingViews.activeOrders.settings />}
>
<ErrorBoundary feature="activeOrders">
<TradingViews.activeOrders.component />
</ErrorBoundary>
</Tab>
<Tab
id="closed-orders"
name={t('Closed')}
settings={<TradingViews.closedOrders.settings />}
>
<Tab id="closed-orders" name={t('Closed')}>
<ErrorBoundary feature="closedOrders">
<TradingViews.closedOrders.component />
</ErrorBoundary>
</Tab>
<Tab
id="rejected-orders"
name={t('Rejected')}
settings={<TradingViews.rejectedOrders.settings />}
>
<Tab id="rejected-orders" name={t('Rejected')}>
<ErrorBoundary feature="rejectedOrders">
<TradingViews.rejectedOrders.component />
</ErrorBoundary>
@@ -179,35 +161,25 @@ const MainGrid = memo(
id="orders"
name={t('All')}
menu={<TradingViews.orders.menu />}
settings={<TradingViews.orders.settings />}
>
<ErrorBoundary feature="orders">
<TradingViews.orders.component />
</ErrorBoundary>
</Tab>
{featureFlags.STOP_ORDERS ? (
<Tab
id="stop-orders"
name={t('Stop orders')}
settings={<TradingViews.stopOrders.settings />}
>
<Tab id="stop-orders" name={t('Stop orders')}>
<ErrorBoundary feature="stop-orders">
<TradingViews.stopOrders.component />
</ErrorBoundary>
</Tab>
) : null}
<Tab
id="fills"
name={t('Fills')}
settings={<TradingViews.fills.settings />}
>
<Tab id="fills" name={t('Fills')}>
<TradingViews.fills.component />
</Tab>
<Tab
id="accounts"
name={t('Collateral')}
menu={<TradingViews.collateral.menu />}
settings={<TradingViews.collateral.settings />}
>
<ErrorBoundary feature="collateral">
<TradingViews.collateral.component
@@ -4,12 +4,7 @@ import { OracleBanner } from '@vegaprotocol/markets';
import { useState } from 'react';
import AutoSizer from 'react-virtualized-auto-sizer';
import classNames from 'classnames';
import {
Popover,
Splash,
VegaIcon,
VegaIconNames,
} from '@vegaprotocol/ui-toolkit';
import { Splash } from '@vegaprotocol/ui-toolkit';
import { useT } from '../../lib/use-t';
import {
MarketSuccessorBanner,
@@ -29,7 +24,6 @@ interface TradePanelsProps {
export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
const featureFlags = useFeatureFlags((state) => state.flags);
const [view, setView] = useState<TradingView>('chart');
const viewCfg = TradingViews[view];
const renderView = () => {
const Component = TradingViews[view].component;
@@ -50,27 +44,19 @@ export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
};
const renderMenu = () => {
if ('menu' in viewCfg || 'settings' in viewCfg) {
const viewCfg = TradingViews[view];
if ('menu' in viewCfg) {
const Menu = viewCfg.menu;
return (
<div className="flex items-center justify-end gap-1 p-1 bg-vega-clight-800 dark:bg-vega-cdark-800 border-b border-default">
{'menu' in viewCfg ? <viewCfg.menu /> : null}
{'settings' in viewCfg ? (
<Popover
align="end"
trigger={
<span className="ml-1 flex items-center justify-center h-6 w-6">
<VegaIcon name={VegaIconNames.COG} size={16} />
</span>
}
>
<div className="p-4 flex justify-end">
<viewCfg.settings />
</div>
</Popover>
) : null}
<Menu />
</div>
);
}
return null;
};
return (
@@ -86,7 +72,7 @@ export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
<OracleBanner marketId={market?.id || ''} />
</div>
<div>{renderMenu()}</div>
<div className="h-full relative">
<div className="h-full">
<AutoSizer>
{({ width, height }) => (
<div style={{ width, height }} className="overflow-auto">
@@ -124,9 +110,7 @@ export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
key={key}
view={key}
isActive={isActive}
onClick={() => {
setView(key);
}}
onClick={() => setView(key)}
/>
);
})}
@@ -1,36 +1,15 @@
import { DepthChartContainer } from '@vegaprotocol/market-depth';
import { Filter, OpenOrdersMenu } from '@vegaprotocol/orders';
import {
TradesContainer,
TradesSettings,
} from '../../components/trades-container';
import { TradesContainer } from '../../components/trades-container';
import { OrderbookContainer } from '../../components/orderbook-container';
import {
FillsContainer,
FillsSettings,
} from '../../components/fills-container';
import {
PositionsContainer,
PositionsSettings,
} from '../../components/positions-container';
import {
AccountsContainer,
AccountsSettings,
} from '../../components/accounts-container';
import { FillsContainer } from '../../components/fills-container';
import { PositionsContainer } from '../../components/positions-container';
import { AccountsContainer } from '../../components/accounts-container';
import { LiquidityContainer } from '../../components/liquidity-container';
import { FundingContainer } from '../../components/funding-container';
import {
FundingPaymentsContainer,
FundingPaymentsSettings,
} from '../../components/funding-payments-container';
import {
OrdersContainer,
OrdersSettings,
} from '../../components/orders-container';
import {
StopOrdersContainer,
StopOrdersSettings,
} from '../../components/stop-orders-container';
import { FundingPaymentsContainer } from '../../components/funding-payments-container';
import { OrdersContainer } from '../../components/orders-container';
import { StopOrdersContainer } from '../../components/stop-orders-container';
import { AccountsMenu } from '../../components/accounts-menu';
import { PositionsMenu } from '../../components/positions-menu';
import { ChartContainer, ChartMenu } from '../../components/chart-container';
@@ -53,46 +32,37 @@ export const TradingViews = {
},
fundingPayments: {
component: FundingPaymentsContainer,
settings: FundingPaymentsSettings,
},
orderbook: {
component: OrderbookContainer,
},
trades: {
component: TradesContainer,
settings: TradesSettings,
},
positions: {
component: PositionsContainer,
menu: PositionsMenu,
settings: PositionsSettings,
},
activeOrders: {
component: () => <OrdersContainer filter={Filter.Open} />,
menu: OpenOrdersMenu,
settings: () => <OrdersSettings filter={Filter.Open} />,
},
closedOrders: {
component: () => <OrdersContainer filter={Filter.Closed} />,
settings: () => <OrdersSettings filter={Filter.Closed} />,
},
rejectedOrders: {
component: () => <OrdersContainer filter={Filter.Rejected} />,
settings: () => <OrdersSettings filter={Filter.Rejected} />,
},
orders: {
component: OrdersContainer,
menu: OpenOrdersMenu,
settings: OrdersSettings,
},
stopOrders: {
component: StopOrdersContainer,
settings: StopOrdersSettings,
},
collateral: {
component: AccountsContainer,
menu: AccountsMenu,
settings: AccountsSettings,
},
fills: { component: FillsContainer, settings: FillsSettings },
fills: { component: FillsContainer },
} as const;
@@ -42,7 +42,7 @@ export const createDataGridSlice: StateCreator<DataGridSlice> = (set) => ({
},
});
export const useMarketsStore = create<DataGridSlice>()(
const useMarketsStore = create<DataGridSlice>()(
persist(createDataGridSlice, {
name: 'vega_market_list_store',
})
@@ -16,7 +16,6 @@ import {
} from '@vegaprotocol/environment';
import { useT } from '../../lib/use-t';
import { ErrorBoundary } from '../../components/error-boundary';
import { MarketsSettings } from './markets-settings';
export const MarketsPage = () => {
const t = useT();
@@ -35,11 +34,7 @@ export const MarketsPage = () => {
<div className="h-full pt-0.5 pb-3 px-1.5">
<div className="h-full my-1 border rounded-sm border-default">
<Tabs storageKey="console-markets">
<Tab
id="open-markets"
name={t('Open markets')}
settings={<MarketsSettings />}
>
<Tab id="open-markets" name={t('Open markets')}>
<ErrorBoundary feature="markets-open">
<OpenMarkets />
</ErrorBoundary>
@@ -47,7 +42,6 @@ export const MarketsPage = () => {
<Tab
id="proposed-markets"
name={t('Proposed markets')}
settings={<MarketsSettings />}
menu={
<TradingAnchorButton
size="extra-small"
@@ -62,11 +56,7 @@ export const MarketsPage = () => {
<Proposed />
</ErrorBoundary>
</Tab>
<Tab
id="closed-markets"
name={t('Closed markets')}
settings={<MarketsSettings />}
>
<Tab id="closed-markets" name={t('Closed markets')}>
<ErrorBoundary feature="markets-closed">
<Closed />
</ErrorBoundary>
@@ -1,8 +0,0 @@
import { GridSettings } from '../../components/grid-settings/grid-settings';
import { useMarketsStore } from './market-list-table';
export const MarketsSettings = () => (
<GridSettings
updateGridStore={useMarketsStore((store) => store.updateGridStore)}
/>
);
@@ -5,29 +5,14 @@ import { titlefy } from '@vegaprotocol/utils';
import { useIncompleteWithdrawals } from '@vegaprotocol/withdraws';
import { Tab, LocalStoragePersistTabs as Tabs } from '@vegaprotocol/ui-toolkit';
import { usePageTitleStore } from '../../stores';
import {
AccountsContainer,
AccountsSettings,
} from '../../components/accounts-container';
import { AccountsContainer } from '../../components/accounts-container';
import { DepositsContainer } from '../../components/deposits-container';
import {
FillsContainer,
FillsSettings,
} from '../../components/fills-container';
import {
FundingPaymentsContainer,
FundingPaymentsSettings,
} from '../../components/funding-payments-container';
import {
PositionsContainer,
PositionsSettings,
} from '../../components/positions-container';
import { FillsContainer } from '../../components/fills-container';
import { FundingPaymentsContainer } from '../../components/funding-payments-container';
import { PositionsContainer } from '../../components/positions-container';
import { PositionsMenu } from '../../components/positions-menu';
import { WithdrawalsContainer } from '../../components/withdrawals-container';
import {
OrdersContainer,
OrdersSettings,
} from '../../components/orders-container';
import { OrdersContainer } from '../../components/orders-container';
import { LedgerContainer } from '../../components/ledger-container';
import {
ResizableGrid,
@@ -91,27 +76,22 @@ export const Portfolio = () => {
id="positions"
name={t('Positions')}
menu={<PositionsMenu />}
settings={<PositionsSettings />}
>
<ErrorBoundary feature="portfolio-positions">
<PositionsContainer allKeys />
</ErrorBoundary>
</Tab>
<Tab id="orders" name={t('Orders')} settings={<OrdersSettings />}>
<Tab id="orders" name={t('Orders')}>
<ErrorBoundary feature="portfolio-orders">
<OrdersContainer />
</ErrorBoundary>
</Tab>
<Tab id="fills" name={t('Fills')} settings={<FillsSettings />}>
<Tab id="fills" name={t('Fills')}>
<ErrorBoundary feature="portfolio-fills">
<FillsContainer />
</ErrorBoundary>
</Tab>
<Tab
id="funding-payments"
name={t('Funding payments')}
settings={<FundingPaymentsSettings />}
>
<Tab id="funding-payments" name={t('Funding payments')}>
<ErrorBoundary feature="portfolio-funding-payments">
<FundingPaymentsContainer />
</ErrorBoundary>
@@ -134,7 +114,6 @@ export const Portfolio = () => {
<Tab
id="collateral"
name={t('Collateral')}
settings={<AccountsSettings />}
menu={<AccountsMenu />}
>
<ErrorBoundary feature="portfolio-accounts">
@@ -296,7 +296,7 @@ export const ApplyCodeForm = ({ onSuccess }: { onSuccess?: () => void }) => {
<>
<div
data-testid="referral-apply-code-form"
className="bg-vega-clight-800 dark:bg-vega-cdark-800 mx-auto md:w-2/3 max-w-md rounded-lg p-8"
className="bg-vega-clight-800 dark:bg-vega-cdark-800 mx-auto w-2/3 max-w-md rounded-lg p-8"
>
<h3 className="calt mb-4 text-center text-2xl">
{t('Apply a referral code')}
@@ -3,7 +3,7 @@ export const GRADIENT =
'bg-gradient-to-b from-vega-clight-800 dark:from-vega-cdark-800 to-transparent';
export const SKY_BACKGROUND =
'bg-[url(/sky-light.png)] dark:bg-[url(/sky-dark.png)] bg-[37%_0px] bg-[length:1440px] bg-no-repeat bg-local';
'bg-[url(/sky-light.png)] dark:bg-[url(/sky-dark.png)] bg-[40%_0px] bg-[length:1440px] bg-no-repeat bg-local';
// TODO: Update the links to use the correct referral related pages
export const REFERRAL_DOCS_LINK =
@@ -49,7 +49,7 @@ export const CreateCodeForm = () => {
return (
<div
data-testid="referral-create-code-form"
className="md:w-2/3 max-w-md mx-auto bg-vega-clight-800 dark:bg-vega-cdark-800 p-8 rounded-lg"
className="w-2/3 max-w-md mx-auto bg-vega-clight-800 dark:bg-vega-cdark-800 p-8 rounded-lg"
>
<h3 className="mb-4 text-2xl text-center calt">
{t('Create a referral code')}
@@ -2,7 +2,6 @@ import { removePaginationWrapper } from '@vegaprotocol/utils';
import { useCallback } from 'react';
import { useRefereesQuery } from './__generated__/Referees';
import compact from 'lodash/compact';
import pick from 'lodash/pick';
import type {
ReferralSetsQuery,
ReferralSetsQueryVariables,
@@ -123,66 +122,6 @@ export const useReferral = (args: UseReferralArgs) => {
};
};
type Referee = NonNullable<
NonNullable<ReturnType<typeof useReferral>['data']>['referee']
>;
type RefereeProperties = (keyof Referee)[];
const findReferee = (referee: Referee, referees: Referee[]) =>
referees.find((r) => r.refereeId === referee?.refereeId) || referee;
const updateReferee = (
referee: Referee,
referees: Referee[],
properties: RefereeProperties
) => ({
...referee,
...pick(findReferee(referee, referees), properties),
});
export const useUpdateReferees = (
referral: ReturnType<typeof useReferral>,
aggregationEpochs: number,
properties: RefereeProperties,
skip?: boolean
): ReturnType<typeof useReferral> => {
const { data, loading, error, refetch } = useRefereesQuery({
variables: {
code: referral?.data?.code as string,
aggregationEpochs,
},
skip: skip || !referral?.data?.code,
fetchPolicy: 'cache-and-network',
context: { isEnlargedTimeout: true },
});
const refetchAll = useCallback(() => {
refetch();
referral.refetch();
}, [refetch, referral]);
if (!referral.data || skip) {
return referral;
}
const referees = compact(
removePaginationWrapper(data?.referralSetReferees.edges)
);
return {
data: data && {
...referral.data,
referees: referral.data.referees.map((referee) =>
updateReferee(referee, referees, properties)
),
referee:
referral.data.referee &&
updateReferee(referral.data.referee, referees, properties),
},
loading: loading || referral.loading,
error: error || referral.error,
refetch: refetchAll,
};
};
const retrieveReferralSetData = (data: ReferralSetsQuery | undefined) =>
data?.referralSets.edges && data.referralSets.edges.length > 0
? data.referralSets.edges[0]?.node
@@ -1,5 +1,5 @@
import { useT } from '../../lib/use-t';
import { Table } from '../../components/table';
import { Table } from './table';
export const HowItWorksTable = () => {
const t = useT();
@@ -5,16 +5,16 @@ import { useT } from '../../lib/use-t';
export const LandingBanner = () => {
const t = useT();
return (
<div className={classNames('relative mb-10 lg:mb-20')}>
<div className={classNames('relative mb-20')}>
<div className="">
<div
aria-hidden
className="absolute top-20 right-[220px] md:right-[240px] max-sm:hidden"
className="absolute top-20 right-[120px] md:right-[240px] max-sm:hidden"
>
<AnimatedDudeWithWire />
</div>
<div className="pt-10 lg:pt-20 sm:w-[50%]">
<h1 className="text-3xl _text-[6vw] lg:!text-6xl leading-[1em] font-alpha calt mb-10">
<div className="pt-20 sm:w-[50%]">
<h1 className="text-6xl font-alpha calt mb-10">
{t('Vega community referrals')}
</h1>
<p className="text-lg mb-1">
@@ -22,7 +22,7 @@ export const LandingBanner = () => {
'Referral programs can be proposed and created via community governance.'
)}
</p>
<p className="text-lg mb-1">
<p className="text-lg mb-10">
{t(
'Once live, users can generate referral codes to share with their friends and earn commission on their trades, while referred traders can access fee discounts based on the running volume of the group.'
)}
@@ -13,7 +13,7 @@ export const Layout = ({
<div
className={classNames(
'max-w-[1440px]',
'mx-auto px-4 lg:px-32 pb-32',
'mx-auto px-16 md:px-32 pb-32',
'relative z-0',
className
)}
@@ -151,27 +151,6 @@ const MOCK_REFEREES: RefereesQuery = {
},
};
const MOCK_REFEREES_30: RefereesQuery = {
referralSetReferees: {
__typename: 'ReferralSetRefereeConnection',
edges: [
{
node: {
atEpoch: 1,
joinedAt: '2023-11-21T14:17:09.257235Z',
refereeId:
'0987654321098765432109876543210987654321098765432109876543219876',
referralSetId:
'3772e570fbab89e50e563036b01dd949c554e5b5fe7908449672dfce9a8adffa',
totalRefereeGeneratedRewards: '12340',
totalRefereeNotionalTakerVolume: '56780',
__typename: 'ReferralSetReferee',
},
},
],
},
};
const programMock: MockedResponse<ReferralProgramQuery> = {
request: {
query: ReferralProgramDocument,
@@ -283,19 +262,6 @@ const refereesMock: MockedResponse<RefereesQuery, RefereesQueryVariables> = {
},
};
const refereesMock30: MockedResponse<RefereesQuery, RefereesQueryVariables> = {
request: {
query: RefereesDocument,
variables: {
code: MOCK_REFERRER_SET.referralSets.edges[0]?.node.id as string,
aggregationEpochs: 30,
},
},
result: {
data: MOCK_REFEREES_30,
},
};
jest.mock('@vegaprotocol/wallet', () => {
return {
...jest.requireActual('@vegaprotocol/wallet'),
@@ -331,7 +297,6 @@ describe('ReferralStatistics', () => {
noReferralSetAsRefereeMock,
stakeAvailableMock,
refereesMock,
refereesMock30,
]}
showWarnings={false}
>
@@ -348,10 +313,6 @@ describe('ReferralStatistics', () => {
expect(queryByTestId('referral-statistics')?.dataset.as).toEqual(
'referrer'
);
// gets commision from 30 epochs query
expect(queryByTestId('total-commission-value')).toHaveTextContent(
'12,340'
);
});
});
@@ -4,17 +4,12 @@ import {
VegaIcon,
VegaIconNames,
truncateMiddle,
TextChildrenTooltip as Tooltip,
} from '@vegaprotocol/ui-toolkit';
import { useVegaWallet } from '@vegaprotocol/wallet';
import {
DEFAULT_AGGREGATION_DAYS,
useReferral,
useUpdateReferees,
} from './hooks/use-referral';
import { DEFAULT_AGGREGATION_DAYS, useReferral } from './hooks/use-referral';
import classNames from 'classnames';
import { Table } from '../../components/table';
import { Table } from './table';
import {
addDecimalsFormatNumber,
getDateFormat,
@@ -46,17 +41,11 @@ export const ReferralStatistics = () => {
role: 'referee',
aggregationEpochs: program.details?.windowLength,
});
const { data: referrer, refetch: referrerRefetch } = useUpdateReferees(
useReferral({
pubKey,
role: 'referrer',
aggregationEpochs: program.details?.windowLength,
}),
DEFAULT_AGGREGATION_DAYS,
['totalRefereeGeneratedRewards'],
DEFAULT_AGGREGATION_DAYS === program.details?.windowLength
);
const { data: referrer, refetch: referrerRefetch } = useReferral({
pubKey,
role: 'referrer',
aggregationEpochs: program.details?.windowLength,
});
const refetch = useCallback(() => {
refereeRefetch();
@@ -87,9 +76,11 @@ export const ReferralStatistics = () => {
export const useStats = ({
data,
program,
as,
}: {
data?: NonNullable<ReturnType<typeof useReferral>['data']>;
program: ReturnType<typeof useReferralProgram>;
as?: 'referrer' | 'referee';
}) => {
const { benefitTiers } = program;
const { data: epochData } = useCurrentEpochInfoQuery({
@@ -190,7 +181,7 @@ export const Statistics = ({
nextBenefitTierValue,
nextBenefitTierVolumeValue,
nextBenefitTierEpochsValue,
} = useStats({ data, program });
} = useStats({ data, program, as });
const isApplyCodePreview = useMemo(
() => data.referee === null,
@@ -302,27 +293,11 @@ export const Statistics = ({
.reduce((all, r) => all.plus(r), new BigNumber(0));
const totalCommissionTile = (
<StatTile
testId="total-commission"
title={
<Trans
i18nKey="totalCommission"
defaults="Total commission (<0>last {{count}} epochs</0>)"
values={{
count: DEFAULT_AGGREGATION_DAYS,
}}
components={[
<Tooltip
key="1"
description={t(
'Depending on data node retention you may not be able see the full 30 days'
)}
>
last 30 epochs
</Tooltip>,
]}
/>
}
title={t('totalCommission', 'Total commission (last {{count}} epochs)', {
count: details?.windowLength || DEFAULT_AGGREGATION_DAYS,
})}
description={<QUSDTooltip />}
testId="total-commission"
>
{getNumberFormat(0).format(Number(totalCommissionValue))}
</StatTile>
@@ -528,21 +503,12 @@ export const RefereesTable = ({
displayName: (
<Trans
i18nKey="referralStatisticsCommission"
defaults="Commission earned in <0>qUSD</0> (<1>last {{count}} epochs</1>)"
components={[
<QUSDTooltip key="0" />,
<Tooltip
key="1"
description={t(
'Depending on data node retention you may not be able see the full 30 days'
)}
>
last 30 epochs
</Tooltip>,
]}
defaults="Commission earned in <0>qUSD</0> (last {{count}} epochs)"
values={{
count: DEFAULT_AGGREGATION_DAYS,
count:
details?.windowLength || DEFAULT_AGGREGATION_DAYS,
}}
components={[<QUSDTooltip key="qusd" />]}
ns={ns}
/>
),
@@ -72,7 +72,7 @@ export const Referrals = () => {
{showNav && <Nav />}
<div
className={classNames({
'py-8 lg:py-16': showNav,
'py-16': showNav,
'h-[300px] relative': loading || error,
})}
>
@@ -1,17 +1,13 @@
import { Tooltip, VegaIcon, VegaIconNames } from '@vegaprotocol/ui-toolkit';
import classNames from 'classnames';
import { forwardRef, type ReactNode, type HTMLAttributes } from 'react';
export const BORDER_COLOR = 'border-vega-clight-500 dark:border-vega-cdark-500';
export const GRADIENT =
'bg-gradient-to-b from-vega-clight-800 dark:from-vega-cdark-800 to-transparent';
import { BORDER_COLOR, GRADIENT } from './constants';
type TableColumnDefinition = {
displayName?: ReactNode;
name: string;
tooltip?: string;
className?: string;
testId?: string;
};
type TableProps = {
@@ -46,7 +42,7 @@ export const Table = forwardRef<
key={name}
col-id={name}
className={classNames(
'px-5 py-3 text-xs text-vega-clight-100 dark:text-vega-cdark-100 font-normal',
'px-5 py-3 text-sm text-vega-clight-100 dark:text-vega-cdark-100 font-normal',
INNER_BORDER_STYLE
)}
>
@@ -70,7 +66,7 @@ export const Table = forwardRef<
ref={ref}
className={classNames(
'w-full',
'border-separate border rounded-md border-spacing-0 overflow-hidden',
'border-separate border rounded-md border-spacing-0',
BORDER_COLOR,
GRADIENT,
className
@@ -86,10 +82,10 @@ export const Table = forwardRef<
'max-md:flex flex-col w-full': !noCollapse,
})}
>
{columns.map(({ name, displayName, className, testId }, j) => (
{columns.map(({ name, displayName, className }, j) => (
<td
className={classNames(
'px-5 py-3',
'px-5 py-3 text-base',
{
'max-md:flex max-md:flex-col max-md:justify-between':
!noCollapse,
@@ -114,7 +110,7 @@ export const Table = forwardRef<
{displayName}
</span>
)}
<span data-testid={`${testId || name}-${i}`}>{d[name]}</span>
<span>{d[name]}</span>
</td>
))}
</tr>
@@ -2,15 +2,7 @@ import type { HTMLAttributes } from 'react';
import classNames from 'classnames';
type TagProps = {
color?:
| 'yellow'
| 'green'
| 'blue'
| 'purple'
| 'pink'
| 'orange'
| 'red'
| 'none';
color?: 'yellow' | 'green' | 'blue' | 'purple' | 'pink' | 'orange' | 'none';
};
export const Tag = ({
color = 'none',
+41 -24
View File
@@ -3,12 +3,11 @@ import {
getDateTimeFormat,
} from '@vegaprotocol/utils';
import { useReferralProgram } from './hooks/use-referral-program';
import { Table } from '../../components/table';
import { Table } from './table';
import classNames from 'classnames';
import { BORDER_COLOR, GRADIENT } from './constants';
import { Tag } from '../../components/helpers/tag';
import { getTierColor, getTierGradient } from '../../components/helpers/tiers';
import type { ReactNode } from 'react';
import { Tag } from './tag';
import type { ComponentProps, ReactNode } from 'react';
import { ExternalLink, truncateMiddle } from '@vegaprotocol/ui-toolkit';
import {
DApp,
@@ -20,6 +19,25 @@ import {
import { useT, ns } from '../../lib/use-t';
import { Trans } from 'react-i18next';
// rainbow-ish order
const TIER_COLORS: Array<ComponentProps<typeof Tag>['color']> = [
'pink',
'orange',
'yellow',
'green',
'blue',
'purple',
];
const getTierColor = (tier: number) => {
const tiers = Object.keys(TIER_COLORS).length;
let index = Math.abs(tier - 1);
if (tier >= tiers) {
index = index % tiers;
}
return TIER_COLORS[index];
};
const Loading = ({ variant }: { variant: 'large' | 'inline' }) => (
<div
className={classNames(
@@ -35,12 +53,10 @@ const StakingTier = ({
tier,
referralRewardMultiplier,
minimumStakedTokens,
max,
}: {
tier: number;
referralRewardMultiplier: string;
minimumStakedTokens: string;
max?: number;
}) => {
const t = useT();
const minimum = addDecimalsFormatNumber(minimumStakedTokens, 18);
@@ -81,7 +97,7 @@ const StakingTier = ({
)}
>
<div>
<Tag color={getTierColor(tier, max)}>
<Tag color={getTierColor(tier)}>
{t('Multiplier')} {referralRewardMultiplier}x
</Tag>
<p className="mt-1 text-sm text-vega-clight-100 dark:text-vega-cdark-100">
@@ -143,9 +159,7 @@ export const TiersContainer = () => {
return (
<>
<h2 className="text-3xl mt-10 font-alpha calt">
{t('Current program details')}
</h2>
<h2 className="text-3xl mt-10">{t('Current program details')}</h2>
{details?.id && (
<p>
<Trans
@@ -184,18 +198,7 @@ export const TiersContainer = () => {
</div>
{/* Container */}
<div
className={classNames(
'md:bg-vega-clight-800',
'md:dark:bg-vega-cdark-800',
'md:text-black',
'md:dark:text-white',
'md:rounded-lg',
'md:p-6',
'mt-1',
'mb-20'
)}
>
<div className="bg-vega-clight-800 dark:bg-vega-cdark-800 text-black dark:text-white rounded-lg p-6 mt-1 mb-20">
{/* Benefit tiers */}
<div className="flex flex-col mb-5">
<h3 className="text-2xl calt">{t('Benefit tiers')}</h3>
@@ -258,7 +261,6 @@ const StakingTiers = ({
<StakingTier
key={i}
tier={tier}
max={data.length}
referralRewardMultiplier={referralRewardMultiplier}
minimumStakedTokens={minimumStakedTokens}
/>
@@ -320,7 +322,22 @@ const TiersTable = ({
className="bg-white dark:bg-vega-cdark-900"
data={data.map((d) => ({
...d,
className: classNames(getTierGradient(d.tier, data.length)),
className: classNames({
'from-vega-yellow-400 dark:from-vega-yellow-600 to-20% bg-highlight':
'yellow' === getTierColor(d.tier),
'from-vega-green-400 dark:from-vega-green-600 to-20% bg-highlight':
'green' === getTierColor(d.tier),
'from-vega-blue-400 dark:from-vega-blue-600 to-20% bg-highlight':
'blue' === getTierColor(d.tier),
'from-vega-purple-400 dark:from-vega-purple-600 to-20% bg-highlight':
'purple' === getTierColor(d.tier),
'from-vega-pink-400 dark:from-vega-pink-600 to-20% bg-highlight':
'pink' === getTierColor(d.tier),
'from-vega-orange-400 dark:from-vega-orange-600 to-20% bg-highlight':
'orange' === getTierColor(d.tier),
'from-vega-clight-200 dark:from-vega-cdark-200 to-20% bg-highlight':
'none' === getTierColor(d.tier),
}),
}))}
/>
);
+7 -12
View File
@@ -19,11 +19,9 @@ export const Tile = ({
return (
<div
className={classNames(
'text-black dark:text-white',
'overflow-hidden relative',
'p-3 md:p-6',
'rounded-lg',
'bg-vega-clight-800 dark:bg-vega-cdark-800',
'rounded-lg overflow-hidden relative',
'bg-vega-clight-800 dark:bg-vega-cdark-800 text-black dark:text-white',
'p-6',
className
)}
>
@@ -33,7 +31,7 @@ export const Tile = ({
};
type StatTileProps = {
title: ReactNode;
title: string;
testId?: string;
description?: ReactNode;
children?: ReactNode;
@@ -57,10 +55,7 @@ export const StatTile = ({
>
{title}
</h3>
<div
data-testid={`${testId}-value`}
className="text-2xl lg:text-5xl text-left"
>
<div data-testid={`${testId}-value`} className="text-5xl text-left">
{children}
</div>
{description && (
@@ -75,7 +70,7 @@ export const StatTile = ({
export const NoProgramTile = ({ title }: Pick<StatTileProps, 'title'>) => {
const t = useT();
return (
<Tile>
<Tile title={title}>
<h3 className="mb-1 text-sm text-vega-clight-100 dark:text-vega-cdark-100 calt">
{title}
</h3>
@@ -124,7 +119,7 @@ export const CodeTile = ({
>
<div
className={classNames(
'relative bg-rainbow bg-clip-text text-transparent text-2xl lg:text-5xl overflow-hidden',
'relative bg-rainbow bg-clip-text text-transparent text-5xl overflow-hidden',
FADE_OUT_STYLE
)}
>
-1
View File
@@ -1 +0,0 @@
export { Teams } from './teams';
@@ -1,7 +0,0 @@
export const Teams = () => {
return (
<div>
<h1>Teams</h1>
</div>
);
};
@@ -73,7 +73,7 @@ export const AccountsContainer = ({
);
};
export const useAccountStore = create<DataGridSlice>()(
const useAccountStore = create<DataGridSlice>()(
persist(createDataGridSlice, {
name: 'vega_accounts_store',
})
@@ -1,8 +0,0 @@
import { GridSettings } from '../grid-settings/grid-settings';
import { useAccountStore } from './accounts-container';
export const AccountsSettings = () => (
<GridSettings
updateGridStore={useAccountStore((store) => store.updateGridStore)}
/>
);
@@ -1,2 +1 @@
export * from './accounts-container';
export * from './accounts-settings';
+3 -20
View File
@@ -8,42 +8,25 @@ export const Card = ({
className,
loading = false,
highlight = false,
testId,
noBackgroundOnMobile = false,
}: {
children: ReactNode;
title: string;
className?: string;
loading?: boolean;
highlight?: boolean;
testId?: string;
noBackgroundOnMobile?: boolean;
}) => {
return (
<div
data-testid={testId}
className={classNames(
'col-span-full lg:col-auto',
{
'rounded-lg bg-vega-clight-800 dark:bg-vega-cdark-800 p-0.5':
!noBackgroundOnMobile,
'mt-3 md:mt-0 md:rounded-lg md:bg-vega-clight-800 md:dark:bg-vega-cdark-800 md:p-0.5':
noBackgroundOnMobile,
},
'bg-vega-clight-800 dark:bg-vega-cdark-800 col-span-full p-0.5 lg:col-auto',
'rounded-lg',
{
'bg-rainbow': highlight,
},
className
)}
>
<div
className={classNames('h-full w-full', {
'bg-vega-clight-800 dark:bg-vega-cdark-800 rounded p-4':
!noBackgroundOnMobile,
'md:bg-vega-clight-800 md:dark:bg-vega-cdark-800 md:rounded md:p-4':
noBackgroundOnMobile,
})}
>
<div className="bg-vega-clight-800 dark:bg-vega-cdark-800 h-full w-full rounded p-4">
<h2 className="mb-3">{title}</h2>
{loading ? <CardLoader /> : children}
</div>
@@ -13,7 +13,7 @@ import { MarketFees } from './market-fees';
import { useVolumeStats } from './use-volume-stats';
import { useReferralStats } from './use-referral-stats';
import { formatPercentage, getAdjustedFee } from './utils';
import { Table as SimpleTable } from '../../components/table';
import { Table, Td, Th, THead, Tr } from './table';
import BigNumber from 'bignumber.js';
import { Links } from '../../lib/links';
import { Link } from 'react-router-dom';
@@ -24,8 +24,6 @@ import {
truncateMiddle,
} from '@vegaprotocol/ui-toolkit';
import { useT } from '../../lib/use-t';
import classNames from 'classnames';
import { getTierGradient } from '../helpers/tiers';
export const FeesContainer = () => {
const t = useT();
@@ -86,10 +84,7 @@ export const FeesContainer = () => {
);
return (
<div
className="grid auto-rows-min grid-cols-4 gap-3"
data-testid="fees-container"
>
<div className="grid auto-rows-min grid-cols-4 gap-3">
{isConnected && (
<>
<Card
@@ -129,10 +124,7 @@ export const FeesContainer = () => {
windowLength={volumeDiscountWindowLength}
/>
) : (
<p
className="text-muted pt-3 text-sm"
data-testid="no-volume-discount"
>
<p className="text-muted pt-3 text-sm">
{t('No volume discount program active')}
</p>
)}
@@ -141,22 +133,17 @@ export const FeesContainer = () => {
title={t('Referral benefits')}
className="sm:col-span-2"
loading={loading}
data-testid="referral-benefits-card"
>
{isReferrer ? (
<ReferrerInfo code={code} data-testid="referrer-info" />
<ReferrerInfo code={code} />
) : isReferralProgramRunning ? (
<ReferralBenefits
setRunningNotionalTakerVolume={referralVolumeInWindow}
epochsInSet={epochsInSet}
epochs={referralDiscountWindowLength}
data-testid="referral-benefits"
/>
) : (
<p
className="text-muted pt-3 text-sm"
data-testid="no-referral-program"
>
<p className="text-muted pt-3 text-sm">
{t('No referral program active')}
</p>
)}
@@ -167,8 +154,6 @@ export const FeesContainer = () => {
title={t('Volume discount')}
className="lg:col-span-full xl:col-span-2"
loading={loading}
data-testid="volume-discount-card"
noBackgroundOnMobile={true}
>
<VolumeTiers
tiers={volumeTiers}
@@ -181,23 +166,18 @@ export const FeesContainer = () => {
title={t('Referral discount')}
className="lg:col-span-full xl:col-span-2"
loading={loading}
data-testid="referral-discount-card"
noBackgroundOnMobile={true}
>
<ReferralTiers
tiers={referralTiers}
tierIndex={referralTierIndex}
epochsInSet={epochsInSet}
referralVolumeInWindow={referralVolumeInWindow}
referralDiscountWindowLength={referralDiscountWindowLength}
/>
</Card>
<Card
title={t('Fees by market')}
className="lg:col-span-full"
loading={marketsLoading}
data-testid="fees-by-market-card"
noBackgroundOnMobile={true}
>
<MarketFees
markets={markets}
@@ -265,7 +245,7 @@ export const TradingFees = ({
}
return (
<div className="pt-4" data-testid="trading-fees">
<div className="pt-4">
<div className="leading-none">
<p className="block text-3xl leading-none" data-testid="adjusted-fees">
{minAdjustedTotal !== undefined && maxAdjustedTotal !== undefined
@@ -275,7 +255,7 @@ export const TradingFees = ({
: `${formatPercentage(adjustedTotal)}%`}
</p>
<CardTable>
<tr className="text-default" data-testid="total-fee-before-discount">
<tr className="text-default">
<CardTableTH>{t('Total fee before discount')}</CardTableTH>
<CardTableTD>
{minTotal !== undefined && maxTotal !== undefined
@@ -285,7 +265,7 @@ export const TradingFees = ({
: `${formatPercentage(total.toNumber())}%`}
</CardTableTD>
</tr>
<tr data-testid="infrastructure-fees">
<tr>
<CardTableTH>{t('Infrastructure')}</CardTableTH>
<CardTableTD>
{formatPercentage(
@@ -294,14 +274,14 @@ export const TradingFees = ({
%
</CardTableTD>
</tr>
<tr data-testid="maker-fees">
<tr>
<CardTableTH>{t('Maker')}</CardTableTH>
<CardTableTD>
{formatPercentage(Number(params.market_fee_factors_makerFee))}%
</CardTableTD>
</tr>
{minLiq && maxLiq && (
<tr data-testid="liquidity-fees">
<tr>
<CardTableTH>{t('Liquidity')}</CardTableTH>
<CardTableTD>
{formatPercentage(Number(minLiq.fees.factors.liquidityFee))}%
@@ -337,19 +317,21 @@ export const CurrentVolume = ({
const currentVolume = new BigNumber(windowLengthVolume);
return (
<div className="flex flex-col gap-3 pt-4" data-testid="current-volume">
<div className="flex flex-col gap-3 pt-4">
<CardStat
value={formatNumberRounded(currentVolume)}
value={
currentVolume.isZero()
? `<${formatNumberRounded(requiredForNextTier)}`
: formatNumberRounded(currentVolume)
}
text={t('pastEpochs', 'Past {{count}} epochs', {
count: windowLength,
})}
testId="past-epochs-volume"
/>
{requiredForNextTier.isGreaterThan(0) && (
<CardStat
value={formatNumber(requiredForNextTier)}
text={t('Required for next tier')}
testId="required-for-next-tier"
/>
)}
</div>
@@ -367,7 +349,7 @@ const ReferralBenefits = ({
}) => {
const t = useT();
return (
<div className="flex flex-col gap-3 pt-4" data-testid="referral-benefits">
<div className="flex flex-col gap-3 pt-4">
<CardStat
// all sets volume (not just current party)
value={formatNumber(setRunningNotionalTakerVolume)}
@@ -378,13 +360,8 @@ const ReferralBenefits = ({
count: epochs,
}
)}
testId="running-notional-taker-volume"
/>
<CardStat
value={epochsInSet}
text={t('epochs in referral set')}
testId="epochs-in-referral-set"
/>
<CardStat value={epochsInSet} text={t('epochs in referral set')} />
</div>
);
};
@@ -412,7 +389,7 @@ const TotalDiscount = ({
);
return (
<div className="pt-4" data-testid="total-discount-card-stats">
<div className="pt-4">
<CardStat
description={
<>
@@ -422,10 +399,9 @@ const TotalDiscount = ({
}
value={formatPercentage(totalDiscount) + '%'}
highlight={true}
testId="total-discount"
/>
<CardTable>
<tr data-testid="volume-discount-row">
<tr>
<CardTableTH>{t('Volume discount')}</CardTableTH>
<CardTableTD>
{formatPercentage(volumeDiscount)}%
@@ -439,7 +415,7 @@ const TotalDiscount = ({
)}
</CardTableTD>
</tr>
<tr data-testid="referral-discount-row">
<tr>
<CardTableTH>{t('Referral discount')}</CardTableTH>
<CardTableTD>
{formatPercentage(referralDiscount)}%
@@ -483,65 +459,36 @@ const VolumeTiers = ({
return (
<div>
<SimpleTable
className="bg-white dark:bg-vega-cdark-900"
columns={[
{ name: 'tier', displayName: t('Tier'), testId: 'col-tier-value' },
{
name: 'discount',
displayName: t('Discount'),
testId: 'discount-value',
},
{
name: 'minTradingVolume',
displayName: t('Min. trading volume'),
testId: 'min-volume-value',
},
{
name: 'myVolume',
displayName: t('myVolume', 'My volume (last {{count}} epochs)', {
count: windowLength,
}),
testId: 'my-volume-value',
},
{
name: 'indicator',
className: 'max-md:hidden',
testId: 'your-tier',
},
]}
data={Array.from(tiers).map((tier, i) => {
const isUserTier = tierIndex === i;
const indicator = isUserTier ? (
<YourTier testId={`your-volume-tier-${i}`} />
) : null;
const tierIndicator = (
<div className="flex justify-between">
<span data-testid={`tier-value-${i}`}>{i + 1}</span>
<span className="md:hidden">{indicator}</span>
</div>
);
return {
tier: tierIndicator,
discount: (
<>{formatPercentage(Number(tier.volumeDiscountFactor))}%</>
),
minTradingVolume: (
<>{formatNumber(tier.minimumRunningNotionalTakerVolume)}</>
),
myVolume: isUserTier ? (
formatNumber(lastEpochVolume)
) : (
<span className="md:hidden">-</span>
),
indicator: indicator,
className: classNames(
getTierGradient(i + 1, tiers.length),
'text-xs'
),
};
})}
/>
<Table>
<THead>
<tr>
<Th>{t('Tier')}</Th>
<Th>{t('Discount')}</Th>
<Th>{t('Min. trading volume')}</Th>
<Th>
{t('myVolume', 'My volume (last {{count}} epochs)', {
count: windowLength,
})}
</Th>
<Th />
</tr>
</THead>
<tbody>
{Array.from(tiers).map((tier, i) => {
const isUserTier = tierIndex === i;
return (
<Tr key={i}>
<Td>{i + 1}</Td>
<Td>{formatPercentage(Number(tier.volumeDiscountFactor))}%</Td>
<Td>{formatNumber(tier.minimumRunningNotionalTakerVolume)}</Td>
<Td>{isUserTier ? formatNumber(lastEpochVolume) : ''}</Td>
<Td>{isUserTier ? <YourTier /> : null}</Td>
</Tr>
);
})}
</tbody>
</Table>
</div>
);
};
@@ -551,7 +498,6 @@ const ReferralTiers = ({
tierIndex,
epochsInSet,
referralVolumeInWindow,
referralDiscountWindowLength,
}: {
tiers: Array<{
referralDiscountFactor: string;
@@ -561,7 +507,6 @@ const ReferralTiers = ({
tierIndex: number;
epochsInSet: number;
referralVolumeInWindow: number;
referralDiscountWindowLength: number;
}) => {
const t = useT();
@@ -573,97 +518,55 @@ const ReferralTiers = ({
return (
<div>
<SimpleTable
className="bg-white dark:bg-vega-cdark-900"
columns={[
{ name: 'tier', displayName: t('Tier'), testId: 'col-tier-value' },
{
name: 'discount',
displayName: t('Discount'),
tooltip: t(
"The proportion of the referee's taker fees to be discounted"
),
testId: 'discount-value',
},
{
name: 'volume',
displayName: t(
'minTradingVolume',
'Min. trading volume (last {{count}} epochs)',
{
count: referralDiscountWindowLength,
}
),
tooltip: t(
'The minimum running notional for the given benefit tier'
),
testId: 'min-volume-value',
},
{
name: 'epochs',
displayName: t('Min. epochs'),
tooltip: t(
'The minimum number of epochs the party needs to be in the referral set to be eligible for the benefit'
),
testId: 'required-epochs-value',
},
{
name: 'indicator',
className: 'max-md:hidden',
testId: 'user-tier-or-unlocks',
},
]}
data={Array.from(tiers).map((tier, i) => {
const isUserTier = tierIndex === i;
const requiredVolume = Number(tier.minimumRunningNotionalTakerVolume);
<Table>
<THead>
<tr>
<Th>{t('Tier')}</Th>
<Th>{t('Discount')}</Th>
<Th>{t('Min. trading volume')}</Th>
<Th>{t('Required epochs')}</Th>
<Th />
</tr>
</THead>
<tbody>
{Array.from(tiers).map((t, i) => {
const isUserTier = tierIndex === i;
const indicator = isUserTier ? (
<YourTier testId={`your-referral-tier-${i}`} />
) : referralVolumeInWindow >= requiredVolume &&
epochsInSet < tier.minimumEpochs ? (
<span className="text-muted text-xs">
Unlocks in {tier.minimumEpochs - epochsInSet} epochs
</span>
) : null;
const requiredVolume = Number(t.minimumRunningNotionalTakerVolume);
let unlocksIn = null;
const tierIndicator = (
<div className="flex justify-between">
<span data-testid={`tier-value-${i}`}>{i + 1}</span>
<span className="md:hidden">{indicator}</span>
</div>
);
if (
referralVolumeInWindow >= requiredVolume &&
epochsInSet < t.minimumEpochs
) {
unlocksIn = (
<span className="text-muted">
Unlocks in {t.minimumEpochs - epochsInSet} epochs
</span>
);
}
return {
tier: tierIndicator,
discount: (
<>{formatPercentage(Number(tier.referralDiscountFactor))}%</>
),
volume: formatNumber(tier.minimumRunningNotionalTakerVolume),
epochs: tier.minimumEpochs,
indicator,
className: classNames(
getTierGradient(i + 1, tiers.length),
'text-xs'
),
};
})}
/>
return (
<Tr key={i}>
<Td>{i + 1}</Td>
<Td>{formatPercentage(Number(t.referralDiscountFactor))}%</Td>
<Td>{formatNumber(t.minimumRunningNotionalTakerVolume)}</Td>
<Td>{t.minimumEpochs}</Td>
<Td>{isUserTier ? <YourTier /> : unlocksIn}</Td>
</Tr>
);
})}
</tbody>
</Table>
</div>
);
};
interface YourTierProps {
testId?: string;
}
const YourTier = ({ testId }: YourTierProps) => {
const YourTier = () => {
const t = useT();
return (
<span
className="bg-rainbow whitespace-nowrap rounded-xl px-4 py-1.5 text-white text-xs"
data-testid={testId}
>
<span className="bg-rainbow whitespace-nowrap rounded-xl px-4 py-1.5 text-white">
{t('Your tier')}
</span>
);
@@ -8,53 +8,43 @@ import { useNavigateWithMeta } from '../../lib/hooks/use-market-click-handler';
import { Links } from '../../lib/links';
import { useT } from '../../lib/use-t';
import { useMemo } from 'react';
import { type ColDef } from 'ag-grid-community/dist/lib/entities/colDef';
const useFeesTableColumnDefs = (): ColDef[] => {
const useFeesTableColumnDefs = () => {
const t = useT();
return useMemo(
() =>
[
{
field: 'code',
cellRenderer: 'MarketCodeCell',
pinned: 'left',
width: 150,
},
{
field: 'liquidityFee',
valueFormatter: ({ value }: { value: number }) => value + '%',
},
{
field: 'feeAfterDiscount',
headerName: t('Total fee after discount'),
valueFormatter: ({ value }: { value: number }) => value + '%',
},
{
field: 'totalFee',
headerName: t('Total fee before discount'),
valueFormatter: ({ value }: { value: number }) => value + '%',
},
{
field: 'infraFee',
valueFormatter: ({ value }: { value: number }) => value + '%',
},
{
field: 'makerFee',
valueFormatter: ({ value }: { value: number }) => value + '%',
},
] as ColDef[],
() => [
{ field: 'code', cellRenderer: 'MarketCodeCell' },
{
field: 'feeAfterDiscount',
headerName: t('Total fee after discount'),
valueFormatter: ({ value }: { value: number }) => value + '%',
},
{
field: 'infraFee',
valueFormatter: ({ value }: { value: number }) => value + '%',
},
{
field: 'makerFee',
valueFormatter: ({ value }: { value: number }) => value + '%',
},
{
field: 'liquidityFee',
valueFormatter: ({ value }: { value: number }) => value + '%',
},
{
field: 'totalFee',
headerName: t('Total fee before discount'),
valueFormatter: ({ value }: { value: number }) => value + '%',
},
],
[t]
);
};
const feesTableDefaultColDef = {
flex: 1,
minWidth: 62,
resizable: true,
sortable: true,
suppressMovable: true,
pinned: false,
};
const components = {
@@ -72,8 +62,6 @@ export const MarketFees = ({
}) => {
const navigateWithMeta = useNavigateWithMeta();
const colDef = useFeesTableColumnDefs();
const rows = compact(markets || []).map((m) => {
const infraFee = new BigNumber(m.fees.factors.infrastructureFee);
const makerFee = new BigNumber(m.fees.factors.makerFee);
@@ -100,9 +88,9 @@ export const MarketFees = ({
});
return (
<div className="border rounded-lg md:rounded-sm overflow-hidden border-default">
<div className="border rounded-sm border-default">
<AgGrid
columnDefs={colDef}
columnDefs={useFeesTableColumnDefs()}
rowData={rows}
getRowId={({ data }) => data.id}
defaultColDef={feesTableDefaultColDef}
@@ -3,31 +3,21 @@ import type { ReactNode } from 'react';
const cellClass = 'px-4 py-2 text-xs font-normal text-left last:text-right';
export const Th = ({ children, ...props }: { children?: ReactNode }) => {
export const Th = ({ children }: { children?: ReactNode }) => {
return (
<th
className={classNames(cellClass, 'text-secondary leading-none py-3')}
{...props}
>
<th className={classNames(cellClass, 'text-secondary leading-none py-3')}>
{children}
</th>
);
};
export const Td = ({ children, ...props }: { children?: ReactNode }) => {
return (
<th className={cellClass} {...props}>
{children}
</th>
);
export const Td = ({ children }: { children?: ReactNode }) => {
return <th className={cellClass}>{children}</th>;
};
export const Tr = ({ children, ...props }: { children?: ReactNode }) => {
export const Tr = ({ children }: { children?: ReactNode }) => {
return (
<tr
className="hover:bg-vega-clight-600 dark:hover:bg-vega-cdark-700"
{...props}
>
<tr className="hover:bg-vega-clight-600 dark:hover:bg-vega-cdark-700">
{children}
</tr>
);
@@ -38,7 +38,7 @@ export const FillsContainer = () => {
);
};
export const useFillsStore = create<DataGridSlice>()(
const useFillsStore = create<DataGridSlice>()(
persist(createDataGridSlice, {
name: 'vega_fills_store',
})
@@ -1,8 +0,0 @@
import { GridSettings } from '../grid-settings/grid-settings';
import { useFillsStore } from './fills-container';
export const FillsSettings = () => (
<GridSettings
updateGridStore={useFillsStore((store) => store.updateGridStore)}
/>
);
@@ -1,2 +1 @@
export * from './fills-container';
export * from './fills-settings';
@@ -45,7 +45,7 @@ export const FundingPaymentsContainer = ({
);
};
export const useFundingPaymentsStore = create<DataGridSlice>()(
const useFundingPaymentsStore = create<DataGridSlice>()(
persist(createDataGridSlice, {
name: 'vega_funding_payments_store',
})
@@ -1,8 +0,0 @@
import { GridSettings } from '../grid-settings/grid-settings';
import { useFundingPaymentsStore } from './funding-payments-container';
export const FundingPaymentsSettings = () => (
<GridSettings
updateGridStore={useFundingPaymentsStore((store) => store.updateGridStore)}
/>
);
@@ -1,2 +1 @@
export * from './funding-payments-container';
export * from './funding-payments-settings';
@@ -1,24 +0,0 @@
import { useT } from '../../lib/use-t';
import type { DataGridStore } from '../../stores/datagrid-store-slice';
import { TradingButton as Button } from '@vegaprotocol/ui-toolkit';
export const GridSettings = ({
updateGridStore,
}: {
updateGridStore: (gridStore: DataGridStore) => void;
}) => {
const t = useT();
return (
<Button
onClick={() =>
updateGridStore({
columnState: undefined,
filterModel: undefined,
})
}
size="extra-small"
>
{t('Reset Columns')}
</Button>
);
};
-48
View File
@@ -1,48 +0,0 @@
import type { ComponentProps } from 'react';
import type { Tag } from './tag';
import classNames from 'classnames';
// rainbow-ish order
export const TIER_COLORS: Array<ComponentProps<typeof Tag>['color']> = [
'none', // worst tier if 8 tiers, otherwise relative to the best tier
'red',
'pink',
'orange',
'yellow',
'green',
'blue',
'purple', // best tier
];
export const getTierColor = (tier: number, max = TIER_COLORS.length) => {
const available =
max < TIER_COLORS.length
? TIER_COLORS.slice(TIER_COLORS.length - max)
: TIER_COLORS;
const tiers = Object.keys(available).length;
let index = Math.abs(tier - 1);
if (tier >= tiers) {
index = index % tiers;
}
return available[index];
};
export const getTierGradient = (tier: number, max = TIER_COLORS.length) =>
classNames({
'from-vega-yellow-400 dark:from-vega-yellow-600 to-20% bg-highlight':
'yellow' === getTierColor(tier, max),
'from-vega-green-400 dark:from-vega-green-600 to-20% bg-highlight':
'green' === getTierColor(tier, max),
'from-vega-blue-400 dark:from-vega-blue-600 to-20% bg-highlight':
'blue' === getTierColor(tier, max),
'from-vega-purple-400 dark:from-vega-purple-600 to-20% bg-highlight':
'purple' === getTierColor(tier, max),
'from-vega-pink-400 dark:from-vega-pink-600 to-20% bg-highlight':
'pink' === getTierColor(tier, max),
'from-vega-orange-400 dark:from-vega-orange-600 to-20% bg-highlight':
'orange' === getTierColor(tier, max),
'from-vega-red-400 dark:from-vega-red-600 to-20% bg-highlight':
'red' === getTierColor(tier, max),
'from-vega-clight-600 dark:from-vega-cdark-600 to-20% bg-highlight':
'none' === getTierColor(tier, max),
});
@@ -27,7 +27,7 @@ export const MarketHeader = () => {
title={
<Popover
open={open}
onOpenChange={setOpen}
onChange={setOpen}
trigger={
<HeaderTitle>
<span>
@@ -1,5 +1,9 @@
import { act, renderHook } from '@testing-library/react';
import { STORAGE_KEY, useOrderListGridState } from './orders-container';
import {
FilterStatusValue,
STORAGE_KEY,
useOrderListGridState,
} from './orders-container';
import { Filter } from '@vegaprotocol/orders';
import { OrderType } from '@vegaprotocol/types';
@@ -12,6 +16,31 @@ describe('useOrderListGridState', () => {
return renderHook(() => useOrderListGridState(filter));
};
it.each(Object.values(Filter))(
'providers correct AgGrid filter for %s',
(filter) => {
const { result } = setup(filter);
expect(typeof result.current.updateGridState).toBe('function');
expect(result.current.gridState).toEqual({
columnState: undefined,
filterModel: {
status: {
value: FilterStatusValue[filter],
},
},
});
}
);
it('provides correct AgGrid filter for all', () => {
const { result } = setup(undefined);
expect(typeof result.current.updateGridState).toBe('function');
expect(result.current.gridState).toEqual({
columnState: undefined,
filterModel: undefined,
});
});
it.each(Object.values(Filter))(
'sets and stores column state and filters for %s',
(filter) => {
@@ -30,7 +59,12 @@ describe('useOrderListGridState', () => {
expect(result.current.gridState).toEqual({
columnState: undefined,
filterModel,
filterModel: {
...filterModel,
status: {
value: FilterStatusValue[filter],
},
},
});
const columnState = [{ colId: 'status', width: 200 }];
@@ -43,7 +77,12 @@ describe('useOrderListGridState', () => {
expect(result.current.gridState).toEqual({
columnState,
filterModel,
filterModel: {
...filterModel,
status: {
value: FilterStatusValue[filter],
},
},
});
const storeKeyMap = {
@@ -9,7 +9,6 @@ import type { DataGridStore } from '../../stores/datagrid-store-slice';
import { OrderStatus } from '@vegaprotocol/types';
import { Links } from '../../lib/links';
import { useT } from '../../lib/use-t';
import { GridSettings } from '../grid-settings/grid-settings';
const resolveNoRowsMessage = (
filter: Filter | undefined,
@@ -39,24 +38,6 @@ export const FilterStatusValue = {
[Filter.Rejected]: [OrderStatus.STATUS_REJECTED],
};
export const DefaultFilterModel = {
[Filter.Open]: {
status: {
value: FilterStatusValue[Filter.Open],
},
},
[Filter.Closed]: {
status: {
value: FilterStatusValue[Filter.Closed],
},
},
[Filter.Rejected]: {
status: {
value: FilterStatusValue[Filter.Rejected],
},
},
};
export interface OrderContainerProps {
filter?: Filter;
}
@@ -73,8 +54,7 @@ export const OrdersContainer = ({ filter }: OrderContainerProps) => {
(newState) => {
updateGridState(filter, newState);
},
AUTO_SIZE_COLUMNS,
filter && DefaultFilterModel[filter]
AUTO_SIZE_COLUMNS
);
if (!pubKey) {
@@ -100,7 +80,7 @@ export const OrdersContainer = ({ filter }: OrderContainerProps) => {
};
export const STORAGE_KEY = 'vega_order_list_store';
export const useOrderListStore = create<{
const useOrderListStore = create<{
open: DataGridStore;
closed: DataGridStore;
rejected: DataGridStore;
@@ -169,19 +149,34 @@ export const useOrderListGridState = (filter: Filter | undefined) => {
case Filter.Open: {
return {
columnState: store.open.columnState,
filterModel: store.open.filterModel,
filterModel: {
...store.open.filterModel,
status: {
value: FilterStatusValue[Filter.Open],
},
},
};
}
case Filter.Closed: {
return {
columnState: store.closed.columnState,
filterModel: store.closed.filterModel,
filterModel: {
...store.closed.filterModel,
status: {
value: FilterStatusValue[Filter.Closed],
},
},
};
}
case Filter.Rejected: {
return {
columnState: store.rejected.columnState,
filterModel: store.rejected.filterModel,
filterModel: {
...store.rejected.filterModel,
status: {
value: FilterStatusValue[Filter.Rejected],
},
},
};
}
default: {
@@ -192,14 +187,3 @@ export const useOrderListGridState = (filter: Filter | undefined) => {
return { gridState, updateGridState };
};
export const OrdersSettings = ({ filter }: { filter?: Filter }) => {
const updateGridState = useOrderListStore((state) => state.update);
return (
<GridSettings
updateGridStore={(gridStore: DataGridStore) =>
updateGridState(filter, gridStore)
}
/>
);
};
@@ -1,2 +1 @@
export * from './positions-container';
export * from './positions-settings';
@@ -1,8 +0,0 @@
import { GridSettings } from '../grid-settings/grid-settings';
import { usePositionsStore } from './positions-container';
export const PositionsSettings = () => (
<GridSettings
updateGridStore={usePositionsStore((store) => store.updateGridStore)}
/>
);
@@ -69,13 +69,11 @@ describe('RewardPot', () => {
balance: '100',
asset: rewardAsset,
},
// should include this in total:
{
type: AccountType.ACCOUNT_TYPE_VESTED_REWARDS,
balance: '100',
asset: rewardAsset,
},
// should include this in total:
{
type: AccountType.ACCOUNT_TYPE_VESTED_REWARDS,
balance: '50',
@@ -140,20 +138,20 @@ describe('RewardPot', () => {
renderComponent(props);
expect(screen.getByTestId('total-rewards')).toHaveTextContent(
`7.00 ${rewardAsset.symbol}`
);
expect(screen.getByText(/Locked/).nextElementSibling).toHaveTextContent(
'2.50'
);
expect(screen.getByText(/Vesting/).nextElementSibling).toHaveTextContent(
'4.50'
);
expect(
screen.getByText(/Available to withdraw/).nextElementSibling
).toHaveTextContent('1.50');
// should be sum of the above
expect(screen.getByTestId('total-rewards')).toHaveTextContent(
`8.50 ${rewardAsset.symbol}`
);
});
});
@@ -62,10 +62,6 @@ export const RewardsContainer = () => {
},
// Inclusion of activity streak in query currently fails
errorPolicy: 'ignore',
// polling here so that as rewards are are moved to ACCOUNT_TYPE_VESTED_REWARDS the vesting stats information stays
// almost up to sync with accounts updating from subscriptions. There is a chance the data could be out
// of sync for 10s if you happen to be on the page at the end of an epoch
pollInterval: 10000,
});
if (!epochData?.epoch || !assetMap) return null;
@@ -231,7 +227,6 @@ export const RewardsContainer = () => {
title={t('Rewards history')}
className="lg:col-span-full"
loading={rewardsLoading}
noBackgroundOnMobile={true}
>
<RewardsHistoryContainer
epoch={Number(epochData?.epoch.id)}
@@ -300,9 +295,7 @@ export const RewardPot = ({
: [0];
const totalVesting = BigNumber.sum.apply(null, vestingBalances);
const totalRewards = totalLocked
.plus(totalVesting)
.plus(totalVestedRewardsByRewardAsset);
const totalRewards = totalLocked.plus(totalVesting);
let rewardAsset = undefined;
@@ -99,25 +99,16 @@ describe('RewardsHistoryTable', () => {
it('renders table with accounts summed up by asset', () => {
render(<RewardHistoryTable {...props} />);
const containerLeft = within(
document.querySelector('.ag-pinned-left-cols-container') as HTMLElement
);
const pinnedRows = containerLeft.getAllByRole('row');
const containerCenter = within(
const container = within(
document.querySelector('.ag-center-cols-container') as HTMLElement
);
const rows = containerCenter.getAllByRole('row');
const rows = container.getAllByRole('row');
expect(rows).toHaveLength(
Object.keys(groupBy(rewardSummaries, 'node.assetId')).length
);
let row = within(rows[0]);
let pinnedRow = within(pinnedRows[0]);
let cells = [
...pinnedRow.getAllByRole('gridcell'),
...row.getAllByRole('gridcell'),
];
let cells = row.getAllByRole('gridcell');
let assetCell = getCell(cells, 'asset.symbol');
expect(assetCell.getByTestId('stack-cell-primary')).toHaveTextContent(
@@ -149,11 +140,7 @@ describe('RewardsHistoryTable', () => {
// Second row
row = within(rows[1]);
pinnedRow = within(pinnedRows[1]);
cells = [
...pinnedRow.getAllByRole('gridcell'),
...row.getAllByRole('gridcell'),
];
cells = row.getAllByRole('gridcell');
assetCell = getCell(cells, 'asset.symbol');
expect(assetCell.getByTestId('stack-cell-primary')).toHaveTextContent(
@@ -93,7 +93,6 @@ export const RewardsHistoryContainer = ({
const defaultColDef = {
flex: 1,
minWidth: 62,
resizable: true,
sortable: true,
};
@@ -196,8 +195,6 @@ export const RewardHistoryTable = ({
return <StackedCell primary={value} secondary={data.asset.name} />;
},
sort: 'desc',
pinned: 'left',
width: 150,
},
{
field: 'infrastructureFees',
@@ -260,7 +257,7 @@ export const RewardHistoryTable = ({
return (
<div>
<div className="mb-2 flex flex-wrap items-center justify-between gap-2">
<div className="mb-2 flex items-center justify-between gap-2">
<h4 className="text-muted flex items-center gap-2 text-sm">
<label htmlFor="fromEpoch">{t('From epoch')}</label>
<EpochInput
@@ -332,17 +329,15 @@ export const RewardHistoryTable = ({
</TradingButton>
</div>
</div>
<div className="border rounded-lg md:rounded-sm overflow-hidden border-default">
<AgGrid
columnDefs={columnDefs}
defaultColDef={defaultColDef}
rowData={rowData}
rowHeight={45}
domLayout="autoHeight"
// Show loading message without wiping out the current rows
overlayNoRowsTemplate={loading ? t('Loading...') : t('No rows')}
/>
</div>
<AgGrid
columnDefs={columnDefs}
defaultColDef={defaultColDef}
rowData={rowData}
rowHeight={45}
domLayout="autoHeight"
// Show loading message without wiping out the current rows
overlayNoRowsTemplate={loading ? t('Loading...') : t('No rows')}
/>
</div>
);
};
@@ -1,3 +1 @@
export * from './stop-orders-container';
export * from './stop-orders-settings';
@@ -35,7 +35,7 @@ export const StopOrdersContainer = () => {
);
};
export const useStopOrdersStore = create<DataGridSlice>()(
const useStopOrdersStore = create<DataGridSlice>()(
persist(createDataGridSlice, {
name: 'vega_stop_orders_store',
})
@@ -1,8 +0,0 @@
import { GridSettings } from '../grid-settings/grid-settings';
import { useStopOrdersStore } from './stop-orders-container';
export const StopOrdersSettings = () => (
<GridSettings
updateGridStore={useStopOrdersStore((store) => store.updateGridStore)}
/>
);
-1
View File
@@ -1 +0,0 @@
export * from './table';
@@ -1,2 +1 @@
export * from './trades-container';
export * from './trades-settings';
@@ -17,7 +17,7 @@ export const TradesContainer = ({ marketId }: TradesContainerProps) => {
return <TradesManager marketId={marketId} gridProps={gridStoreCallbacks} />;
};
export const useTradesStore = create<DataGridSlice>()(
const useTradesStore = create<DataGridSlice>()(
persist(createDataGridSlice, {
name: 'vega_trades_store',
})
@@ -1,8 +0,0 @@
import { GridSettings } from '../grid-settings/grid-settings';
import { useTradesStore } from './trades-container';
export const TradesSettings = () => (
<GridSettings
updateGridStore={useTradesStore((store) => store.updateGridStore)}
/>
);
-1
View File
@@ -1,3 +1,2 @@
CONSOLE_IMAGE_NAME=vegaprotocol/trading:latest
VEGA_VERSION=v0.73.9
LOCAL_SERVER=false
-1
View File
@@ -1,3 +1,2 @@
CONSOLE_IMAGE_NAME=vegaprotocol/trading:main
VEGA_VERSION=v0.73.8
LOCAL_SERVER=false
+5 -7
View File
@@ -24,12 +24,6 @@ poetry shell
5. **Install python dependencies**
To make sure you are on the latest version of our market-sim branch.
```bash
poetry update vega-sim
```
```bash
poetry install
```
@@ -127,7 +121,11 @@ yarn nx serve trading
```
Once console is served you can update the .env file to have local_server to true.
Once console is served you can use the flag --local-server
```bash
poetry run pytest -k "test_name" -s --headed --local-server
```
## Running Tests in Parallel 🔢
+2 -3
View File
@@ -55,14 +55,14 @@ def change_keys(page: Page, vega: VegaServiceNull, key_name):
page.reload()
def forward_time(vega:VegaServiceNull, forward_epoch: bool = False):
def forward_time(vega: VegaServiceNull, forward_epoch: bool = False):
vega.wait_fn(1)
vega.wait_for_total_catchup()
if forward_epoch:
next_epoch(vega)
# This is for when the element will initially load but contain an outdated value. It will wait for the element to contain the expected text, returning False after a timeout or exception
def selector_contains_text(page: Page, selector, expected_text, timeout=5000):
try:
@@ -71,4 +71,3 @@ def selector_contains_text(page: Page, selector, expected_text, timeout=5000):
return True
except:
return False
+33 -36
View File
@@ -6,10 +6,9 @@ import requests
import time
import docker
import http.server
import sys
from dotenv import load_dotenv
from contextlib import contextmanager
from vega_sim.null_service import VegaServiceNull, Ports
from vega_sim.null_service import VegaServiceNull
from playwright.sync_api import Browser, Page
from config import console_image_name, vega_version
from datetime import datetime, timedelta
@@ -20,6 +19,7 @@ from fixtures.market import (
setup_perps_market,
)
import sys
# Workaround for current xdist issue with displaying live logs from multiple workers
# https://github.com/pytest-dev/pytest-xdist/issues/402
@@ -28,8 +28,6 @@ sys.stdout = sys.stderr
docker_client = docker.from_env()
logger = logging.getLogger()
load_dotenv()
@pytest.hookimpl(tryfirst=True)
def pytest_runtest_makereport(item, call):
@@ -51,24 +49,16 @@ def pytest_configure(config):
level=config.getini("log_file_level"),
)
class CustomHttpRequestHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
# Set the path to your website's directory here
if self.path == "/":
self.path = "dist/apps/trading/exported/index.html"
if self.path == '/':
self.path = 'dist/apps/trading/exported/index.html'
return http.server.SimpleHTTPRequestHandler.do_GET(self)
# Start VegaServiceNull
@contextmanager
def init_vega(request=None):
local_server = os.getenv("LOCAL_SERVER", "false").lower() == "true"
port_config = None
if local_server:
port_config = {
Ports.DATA_NODE_REST: 8001,
}
default_seconds = 1
seconds_per_block = default_seconds
if request and hasattr(request, "param"):
@@ -80,26 +70,21 @@ def init_vega(request=None):
)
logger.info(f"Using console image: {console_image_name}")
logger.info(f"Using vega version: {vega_version}")
vega_service_args = {
"run_with_console": False,
"launch_graphql": False,
"retain_log_files": True,
"use_full_vega_wallet": True,
"store_transactions": True,
"transactions_per_block": 1000,
"seconds_per_block": seconds_per_block,
"genesis_time": datetime.now() - timedelta(days=1),
}
if port_config is not None:
vega_service_args["port_config"] = port_config
with VegaServiceNull(**vega_service_args) as vega:
with VegaServiceNull(
run_with_console=False,
launch_graphql=False,
retain_log_files=True,
use_full_vega_wallet=True,
store_transactions=True,
transactions_per_block=1000,
seconds_per_block=seconds_per_block,
genesis_time= datetime.now() - timedelta(days=1),
) as vega:
try:
container = docker_client.containers.run(
console_image_name, detach=True, ports={"80/tcp": vega.console_port}
)
# docker setup
logger.info(
f"Container {container.id} started",
extra={"worker_id": os.environ.get("PYTEST_XDIST_WORKER")},
@@ -112,13 +97,23 @@ def init_vega(request=None):
finally:
logger.info(f"Stopping container {container.id}")
container.stop()
# Remove the container
logger.info(f"Removing container {container.id}")
container.remove()
def pytest_addoption(parser):
parser.addoption(
"--local-server", action="store_true", default=False,
help="Build and serve locally instead of using a container"
)
@pytest.fixture(scope="session")
def local_server(pytestconfig):
return pytestconfig.getoption("--local-server")
@contextmanager
def init_page(vega: VegaServiceNull, browser: Browser, request: pytest.FixtureRequest):
local_server = os.getenv("LOCAL_SERVER", "false").lower() == "true"
def init_page(vega: VegaServiceNull, browser: Browser, request: pytest.FixtureRequest, local_server: bool):
server_port = "4200" if local_server else str(vega.console_port)
with browser.new_context(
viewport={"width": 1920, "height": 1080},
@@ -130,7 +125,9 @@ def init_page(vega: VegaServiceNull, browser: Browser, request: pytest.FixtureRe
attempts = 0
while attempts < 100:
try:
code = requests.get(f"http://localhost:{server_port}/").status_code
code = requests.get(
f"http://localhost:{server_port}/"
).status_code
if code == 200:
break
except requests.exceptions.ConnectionError as e:
@@ -175,8 +172,8 @@ def vega(request):
@pytest.fixture
def page(vega, browser, request):
with init_page(vega, browser, request) as page_instance:
def page(vega, browser, request, local_server):
with init_page(vega, browser, request, local_server) as page_instance:
yield page_instance
-8
View File
@@ -245,11 +245,3 @@ def setup_perps_market(
vega.wait_for_total_catchup()
return market_id
def market_exists(vega: VegaService, market_id: str):
if market_id is None:
return False
all_markets = vega.all_markets()
market_ids = [market.id for market in all_markets]
return market_id in market_ids
+2 -2
View File
@@ -1,4 +1,4 @@
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
[[package]]
name = "certifi"
@@ -1161,7 +1161,7 @@ profile = ["pytest-profiling", "snakeviz"]
type = "git"
url = "https://github.com/vegaprotocol/vega-market-sim.git/"
reference = "fix/genesis_panic"
resolved_reference = "de30d2d4c7a1b81a830527ca76473e23ef59de12"
resolved_reference = "7ab04931924380db8000544b7f3d65fcb39b5467"
[[package]]
name = "websocket-client"
+8 -14
View File
@@ -56,12 +56,11 @@ label_value_tooltip_pairs = [
def tooltip(page: Page, index: int, test_id: str, tooltip: str):
page.locator(f"data-testid={index}_{test_id}").hover()
expect(page.locator('[role="tooltip"]').locator(
"div")).to_have_text(tooltip)
expect(page.locator('[role="tooltip"]').locator("div")).to_have_text(tooltip)
page.get_by_test_id("dialog-title").click()
@pytest.mark.usefixtures("continuous_market", "auth", "risk_accepted")
@pytest.mark.usefixtures("page", "continuous_market", "auth", "risk_accepted")
def test_asset_details(page: Page):
page.goto("/#/portfolio")
page.locator('[data-testid="tab-collateral"] >> text=tDAI').click()
@@ -74,22 +73,17 @@ def test_asset_details(page: Page):
value = pair.get("value", "")
label_tooltip = pair.get("labelTooltip", "")
value_tooltip = pair.get("valueToolTip", "")
if label == "ID":
expect(page.get_by_role(
"button", name="Copy id to clipboard")).to_be_visible()
asset_id_text = page.locator(
f"[data-testid='{index}_value']").inner_text()
expect(page.get_by_role("button", name="Copy id to clipboard")).to_be_visible()
asset_id_text = page.locator(f"[data-testid='{index}_value']").inner_text()
pattern = r"^[0-9a-f]{6}\u2026[0-9a-f]{4}"
assert re.match(
pattern, asset_id_text), f"Expected ID to match pattern but got {asset_id_text}"
assert re.match(pattern, asset_id_text), f"Expected ID to match pattern but got {asset_id_text}"
else:
expect(page.locator(
f"[data-testid='{index}_label']")).to_have_text(label)
expect(page.locator(
f"[data-testid='{index}_value']")).to_have_text(value)
expect(page.locator(f"[data-testid='{index}_label']")).to_have_text(label)
expect(page.locator(f"[data-testid='{index}_value']")).to_have_text(value)
if label_tooltip:
tooltip(page, index, "label", label_tooltip)
@@ -1,6 +1,6 @@
import pytest
from playwright.sync_api import Page, expect
from vega_sim.null_service import VegaServiceNull
from vega_sim.service import VegaService
from datetime import datetime, timedelta
from conftest import init_vega
from fixtures.market import setup_continuous_market
@@ -14,17 +14,20 @@ market_order = "order-type-Market"
tif = "order-tif"
expire = "expire"
@pytest.fixture(scope="module")
def vega(request):
with init_vega(request) as vega:
yield vega
@pytest.fixture(scope="module")
def continuous_market(vega):
return setup_continuous_market(vega)
@pytest.mark.usefixtures("auth", "risk_accepted")
def test_limit_buy_order_GTT(continuous_market, vega: VegaServiceNull, page: Page):
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
def test_limit_buy_order_GTT(continuous_market, vega: VegaService, page: Page):
page.goto(f"/#/markets/{continuous_market}")
page.get_by_test_id(tif).select_option("Good 'til Time (GTT)")
page.get_by_test_id(order_size).fill("10")
@@ -51,8 +54,9 @@ def test_limit_buy_order_GTT(continuous_market, vega: VegaServiceNull, page: Pag
"BTC:DAI_2023Futr10+10LimitFilled120.00GTT:"
)
@pytest.mark.usefixtures("auth", "risk_accepted")
def test_limit_buy_order(continuous_market, vega: VegaServiceNull, page: Page):
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
def test_limit_buy_order(continuous_market, vega: VegaService, page: Page):
page.goto(f"/#/markets/{continuous_market}")
page.get_by_test_id(order_size).fill("10")
@@ -68,8 +72,9 @@ def test_limit_buy_order(continuous_market, vega: VegaServiceNull, page: Page):
"BTC:DAI_2023Futr10+10LimitFilled120.00GTC"
)
@pytest.mark.usefixtures("auth", "risk_accepted")
def test_limit_sell_order(continuous_market, vega: VegaServiceNull, page: Page):
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
def test_limit_sell_order(continuous_market, vega: VegaService, page: Page):
page.goto(f"/#/markets/{continuous_market}")
page.get_by_test_id(order_size).fill("10")
page.get_by_test_id(order_price).fill("100")
@@ -92,8 +97,9 @@ def test_limit_sell_order(continuous_market, vega: VegaServiceNull, page: Page):
"BTC:DAI_2023Futr10-10LimitFilled100.00GFN"
)
@pytest.mark.usefixtures("auth", "risk_accepted")
def test_market_sell_order(continuous_market, vega: VegaServiceNull, page: Page):
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
def test_market_sell_order(continuous_market, vega: VegaService, page: Page):
page.goto(f"/#/markets/{continuous_market}")
page.get_by_test_id(market_order).click()
page.get_by_test_id(order_size).fill("10")
@@ -116,8 +122,9 @@ def test_market_sell_order(continuous_market, vega: VegaServiceNull, page: Page)
"BTC:DAI_2023Futr10-10MarketFilled-IOC"
)
@pytest.mark.usefixtures("auth", "risk_accepted")
def test_market_buy_order(continuous_market, vega: VegaServiceNull, page: Page):
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
def test_market_buy_order(continuous_market, vega: VegaService, page: Page):
page.goto(f"/#/markets/{continuous_market}")
page.get_by_test_id(market_order).click()
page.get_by_test_id(order_size).fill("10")
@@ -13,7 +13,7 @@ def continuous_market(vega):
return setup_continuous_market(vega)
@pytest.mark.skip("We currently can't approve wallet connection through Sim")
@pytest.mark.usefixtures("risk_accepted")
@pytest.mark.usefixtures("page", "risk_accepted")
def test_connect_vega_wallet(continuous_market, page: Page):
page.goto(f"/#/markets/{continuous_market}")
page.get_by_test_id("order-price").fill("101")
@@ -25,7 +25,7 @@ def test_connect_vega_wallet(continuous_market, page: Page):
expect(page.get_by_test_id("order-type-Limit")).to_be_checked()
expect(page.get_by_test_id("order-price")).to_have_value("101")
@pytest.mark.usefixtures("risk_accepted")
@pytest.mark.usefixtures("page", "risk_accepted")
def test_sidebar_should_be_open_after_reload(continuous_market, page: Page):
page.goto(f"/#/markets/{continuous_market}")
expect(page.get_by_test_id("deal-ticket-form")).to_be_visible()
@@ -1,6 +1,6 @@
import pytest
from playwright.sync_api import Page, expect
from vega_sim.null_service import VegaServiceNull
from vega_sim.service import VegaService
from actions.vega import submit_order
from actions.utils import wait_for_toast_confirmation
@@ -12,8 +12,8 @@ market_trading_mode = "market-trading-mode"
@pytest.mark.skip("tbd")
@pytest.mark.usefixtures("auth", "risk_accepted")
def test_margin_and_fees_estimations(continuous_market, vega: VegaServiceNull, page: Page):
@pytest.mark.usefixtures("page", "vega", "continuous_market", "auth", "risk_accepted")
def test_margin_and_fees_estimations(continuous_market, vega: VegaService, page: Page):
# setup continuous trading market with one user buy trade
market_id = continuous_market
page.goto(f"/#/markets/{market_id}")
@@ -1,6 +1,6 @@
import pytest
from playwright.sync_api import Page, expect
from vega_sim.null_service import VegaServiceNull
from vega_sim.service import VegaService
from actions.vega import submit_order
from datetime import datetime, timedelta
from conftest import init_vega
@@ -38,14 +38,15 @@ timeInForce_col = '[col-id="submission.timeInForce"]'
updatedAt_col = '[col-id="updatedAt"]'
close_toast = "toast-close"
def create_position(vega: VegaServiceNull, market_id):
def create_position(vega: VegaService, market_id):
submit_order(vega, "Key 1", market_id, "SIDE_SELL", 100, 110)
submit_order(vega, "Key 1", market_id, "SIDE_BUY", 100, 110)
vega.forward("10s")
vega.wait_fn(1)
vega.wait_for_total_catchup
@pytest.mark.usefixtures("auth", "risk_accepted")
@pytest.mark.usefixtures("page", "continuous_market", "auth", "risk_accepted")
def test_stop_order_form_error_validation(continuous_market, page: Page):
# 7002-SORD-032
page.goto(f"/#/markets/{continuous_market}")
@@ -68,8 +69,8 @@ def test_stop_order_form_error_validation(continuous_market, page: Page):
)
@pytest.mark.skip("core issue")
@pytest.mark.usefixtures("auth", "risk_accepted")
def test_submit_stop_order_rejected(continuous_market, vega: VegaServiceNull, page: Page):
@pytest.mark.usefixtures("page", "vega", "continuous_market", "auth", "risk_accepted")
def test_submit_stop_order_rejected(continuous_market, vega: VegaService, page: Page):
page.goto(f"/#/markets/{continuous_market}")
page.get_by_test_id(stop_orders_tab).click()
page.get_by_test_id(stop_order_btn).click()
@@ -106,9 +107,9 @@ def test_submit_stop_order_rejected(continuous_market, vega: VegaServiceNull, pa
).not_to_be_empty()
@pytest.mark.skip("core issue")
@pytest.mark.usefixtures("auth", "risk_accepted")
@pytest.mark.usefixtures("page", "vega", "continuous_market", "auth", "risk_accepted")
def test_submit_stop_market_order_triggered(
continuous_market, vega: VegaServiceNull, page: Page
continuous_market, vega: VegaService, page: Page
):
# 7002-SORD-071
# 7002-SORD-074
@@ -164,9 +165,9 @@ def test_submit_stop_market_order_triggered(
).not_to_be_empty()
@pytest.mark.skip("core issue")
@pytest.mark.usefixtures("auth", "risk_accepted")
@pytest.mark.usefixtures("continuous_market", "auth", "risk_accepted")
def test_submit_stop_limit_order_pending(
continuous_market, vega: VegaServiceNull, page: Page
continuous_market, vega: VegaService, page: Page
):
# 7002-SORD-071
# 7002-SORD-074
@@ -225,9 +226,9 @@ def test_submit_stop_limit_order_pending(
).not_to_be_empty()
@pytest.mark.skip("core issue")
@pytest.mark.usefixtures("auth", "risk_accepted")
@pytest.mark.usefixtures("continuous_market", "auth", "risk_accepted")
def test_submit_stop_limit_order_cancel(
continuous_market, vega: VegaServiceNull, page: Page
continuous_market, vega: VegaService, page: Page
):
page.goto(f"/#/markets/{continuous_market}")
page.get_by_test_id(stop_orders_tab).click()
@@ -269,7 +270,7 @@ class TestStopOcoValidation:
def continuous_market(self, vega):
return setup_continuous_market(vega)
@pytest.mark.usefixtures("auth", "risk_accepted")
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
def test_stop_market_order_form_validation(self, continuous_market, page: Page):
# 7002-SORD-052
# 7002-SORD-055
@@ -302,7 +303,7 @@ class TestStopOcoValidation:
expect(page.get_by_test_id(order_size)).to_be_empty
expect(page.get_by_test_id(order_price)).not_to_be_visible()
@pytest.mark.usefixtures("auth", "risk_accepted")
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
def test_stop_limit_order_form_validation(self, continuous_market, page: Page):
# 7002-SORD-020
# 7002-SORD-021
@@ -346,9 +347,9 @@ class TestStopOcoValidation:
expect(page.get_by_test_id(order_price)).to_be_empty()
@pytest.mark.skip("core issue")
@pytest.mark.usefixtures("auth", "risk_accepted")
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
def test_maximum_number_of_active_stop_orders(
self, continuous_market, vega: VegaServiceNull, page: Page
self, continuous_market, vega: VegaService, page: Page
):
page.goto(f"/#/markets/{continuous_market}")
page.get_by_test_id(stop_orders_tab).click()
@@ -1,9 +1,10 @@
import pytest
from playwright.sync_api import Page, expect
from vega_sim.null_service import VegaServiceNull
from vega_sim.service import VegaService
from actions.vega import submit_order
from actions.utils import wait_for_toast_confirmation
stop_order_btn = "order-type-Stop"
stop_limit_order_btn = "order-type-StopLimit"
stop_market_order_btn = "order-type-StopMarket"
@@ -42,16 +43,16 @@ trigger_price_oco = "triggerPrice-oco"
order_size_oco = "order-size-oco"
order_limit_price_oco = "order-price-oco"
def create_position(vega: VegaServiceNull, market_id):
def create_position(vega: VegaService, market_id):
submit_order(vega, "Key 1", market_id, "SIDE_SELL", 100, 110)
submit_order(vega, "Key 1", market_id, "SIDE_BUY", 100, 110)
vega.wait_fn(1)
vega.wait_for_total_catchup
@pytest.mark.usefixtures("auth", "risk_accepted")
@pytest.mark.usefixtures("page", "vega", "continuous_market", "auth", "risk_accepted")
def test_submit_stop_order_market_oco_rejected(
continuous_market, vega: VegaServiceNull, page: Page
continuous_market, vega: VegaService, page: Page
):
page.goto(f"/#/markets/{continuous_market}")
page.get_by_test_id(stop_orders_tab).click()
@@ -126,9 +127,9 @@ def test_submit_stop_order_market_oco_rejected(
assert trigger_price_list.sort() == trigger_value_list.sort()
@pytest.mark.usefixtures("auth", "risk_accepted")
@pytest.mark.usefixtures("page", "vega", "continuous_market", "auth", "risk_accepted")
def test_submit_stop_oco_market_order_triggered(
continuous_market, vega: VegaServiceNull, page: Page
continuous_market, vega: VegaService, page: Page
):
create_position(vega, continuous_market)
page.goto(f"/#/markets/{continuous_market}")
@@ -203,9 +204,9 @@ def test_submit_stop_oco_market_order_triggered(
assert trigger_price_list.sort() == trigger_value_list.sort()
@pytest.mark.usefixtures("auth", "risk_accepted")
@pytest.mark.usefixtures("page", "vega", "continuous_market", "auth", "risk_accepted")
def test_submit_stop_oco_market_order_pending(
continuous_market, vega: VegaServiceNull, page: Page
continuous_market, vega: VegaService, page: Page
):
create_position(vega, continuous_market)
page.goto(f"/#/markets/{continuous_market}")
@@ -235,9 +236,9 @@ def test_submit_stop_oco_market_order_pending(
"PendingOCO"
)
@pytest.mark.usefixtures("page", "continuous_market", "auth", "risk_accepted")
@pytest.mark.usefixtures("page", "vega", "continuous_market", "auth", "risk_accepted")
def test_submit_stop_oco_limit_order_pending(
continuous_market, vega: VegaServiceNull, page: Page
continuous_market, vega: VegaService, page: Page
):
create_position(vega, continuous_market)
page.goto(f"/#/markets/{continuous_market}")
@@ -286,9 +287,9 @@ def test_submit_stop_oco_limit_order_pending(
assert trigger_price_list.sort() == trigger_value_list.sort()
@pytest.mark.usefixtures("auth", "risk_accepted")
@pytest.mark.usefixtures("page", "vega", "continuous_market", "auth", "risk_accepted")
def test_submit_stop_oco_limit_order_cancel(
continuous_market, vega: VegaServiceNull, page: Page
continuous_market, vega: VegaService, page: Page
):
create_position(vega, continuous_market)
page.goto(f"/#/markets/{continuous_market}")
@@ -324,3 +325,5 @@ def test_submit_stop_oco_limit_order_cancel(
expect(
page.locator(".ag-center-cols-container").locator('[col-id="status"]').last
).to_have_text("CancelledOCO")
@@ -1,10 +1,12 @@
import pytest
from playwright.sync_api import Page, expect
from vega_sim.null_service import VegaServiceNull
from vega_sim.service import VegaService
from actions.utils import change_keys
from conftest import init_vega
from fixtures.market import setup_continuous_market
order_size = "order-size"
order_price = "order-price"
place_order = "place-order"
@@ -16,12 +18,13 @@ def vega(request):
with init_vega(request) as vega:
yield vega
@pytest.fixture(scope="module")
def continuous_market(vega):
return setup_continuous_market(vega)
@pytest.mark.usefixtures("auth", "risk_accepted")
def test_should_display_info_and_button_for_deposit(continuous_market, page: Page):
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
def test_should_display_info_and_button_for_deposit(continuous_market, vega: VegaService, page: Page):
page.goto(f"/#/markets/{continuous_market}")
page.get_by_test_id(order_size).fill("200000")
page.get_by_test_id(order_price).fill("20")
@@ -32,8 +35,8 @@ def test_should_display_info_and_button_for_deposit(continuous_market, page: Pag
page.get_by_test_id(deal_ticket_deposit_dialog_button).nth(0).click()
expect(page.get_by_test_id("sidebar-content")).to_contain_text("DepositFrom")
@pytest.mark.usefixtures("auth", "risk_accepted")
def test_should_show_an_error_if_your_balance_is_zero(continuous_market, vega: VegaServiceNull, page: Page):
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
def test_should_show_an_error_if_your_balance_is_zero(continuous_market, vega: VegaService, page: Page):
page.goto(f"/#/markets/{continuous_market}")
vega.create_key("key_empty")
change_keys(page, vega, "key_empty")
-686
View File
@@ -1,686 +0,0 @@
import pytest
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 actions.utils import next_epoch, change_keys, forward_time
from fixtures.market import market_exists, setup_continuous_market
# region Constants for test IDs
ADJUSTED_FEES = "adjusted-fees"
TOTAL_FEE_BEFORE_DISCOUNT = "total-fee-before-discount"
INFRASTRUCTURE_FEES = "infrastructure-fees"
MAKER_FEES = "maker-fees"
LIQUIDITY_FEES = "liquidity-fees"
TOTAL_DISCOUNT = "total-discount"
VOLUME_DISCOUNT_ROW = "volume-discount-row"
REFERRAL_DISCOUNT_ROW = "referral-discount-row"
PAST_EPOCHS_VOLUME = "past-epochs-volume"
REQUIRED_FOR_NEXT_TIER = "required-for-next-tier"
TIER_VALUE_0 = "tier-value-0"
TIER_VALUE_1 = "tier-value-1"
DISCOUNT_VALUE_0 = "discount-value-0"
DISCOUNT_VALUE_1 = "discount-value-1"
MIN_VOLUME_VALUE_0 = "min-volume-value-0"
MIN_VOLUME_VALUE_1 = "min-volume-value-1"
MY_VOLUME_VALUE_0 = "my-volume-value-0"
MY_VOLUME_VALUE_1 = "my-volume-value-1"
ORDER_SIZE = "order-size"
ORDER_PRICE = "order-price"
DISCOUNT_PILL = "discount-pill"
FEES_TEXT = "fees-text"
TOOLTIP_CONTENT = "tooltip-content"
INFRASTRUCTURE_FEE_FACTOR = "infrastructure-fee-factor"
INFRASTRUCTURE_FEE_VALUE = "infrastructure-fee-value"
LIQUIDITY_FEE_FACTOR = "liquidity-fee-factor"
LIQUIDITY_FEE_VALUE = "liquidity-fee-value"
MAKER_FEE_FACTOR = "maker-fee-factor"
MAKER_FEE_VALUE = "maker-fee-value"
SUBTOTAL_FEE_FACTOR = "subtotal-fee-factor"
SUBTOTAL_FEE_VALUE = "subtotal-fee-value"
DISCOUNT_FEE_FACTOR = "discount-fee-factor"
DISCOUNT_FEE_VALUE = "discount-fee-value"
TOTAL_FEE_VALUE = "total-fee-value"
RUNNING_NOTIONAL_TAKER_VOLUME = "running-notional-taker-volume"
EPOCHS_IN_REFERRAL_SET = "epochs-in-referral-set"
REQUIRED_EPOCHS_VALUE_0 = "required-epochs-value-0"
REQUIRED_EPOCHS_VALUE_1 = "required-epochs-value-1"
FILLS = "Fills"
TAB_FILLS = "tab-fills"
FEE_BREAKDOWN_TOOLTIP = "fee-breakdown-tooltip"
PINNED_ROW_LOCATOR = ".ag-pinned-left-cols-container .ag-row"
ROW_LOCATOR = ".ag-center-cols-container .ag-row"
# Col-Ids:
COL_INSTRUMENT_CODE = '[col-id="market.tradableInstrument.instrument.code"]'
COL_CODE = '[col-id="code"]'
COL_SIZE = '[col-id="size"]'
COL_PRICE = '[col-id="price"]'
COL_PRICE_1 = '[col-id="price_1"]'
COL_AGGRESSOR = '[col-id="aggressor"]'
COL_FEE = '[col-id="fee"]'
COL_FEE_DISCOUNT = '[col-id="fee-discount"]'
COL_FEE_AFTER_DISCOUNT = '[col-id="feeAfterDiscount"]'
COL_INFRA_FEE = '[col-id="infraFee"]'
COL_MAKER_FEE = '[col-id="makerFee"]'
COL_LIQUIDITY_FEE = '[col-id="liquidityFee"]'
COL_TOTAL_FEE = '[col-id="totalFee"]'
# endregion
@pytest.fixture(scope="module")
def market_ids():
return {
"tier_1_volume": "default_id",
"tier_2_volume": "default_id",
"tier_1_referral": "default_id",
"tier_2_referral": "default_id",
"combo": "default_id",
}
@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
@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
@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
@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
@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
@pytest.fixture
def page(vega_instance, browser, request):
with init_page(vega_instance, browser, request) as page_instance:
yield page_instance
@pytest.fixture
def vega_instance(
tier,
discount_program,
vega_volume_discount_tier_1,
vega_volume_discount_tier_2,
vega_referral_discount_tier_1,
vega_referral_discount_tier_2,
vega_referral_and_volume_discount,
):
if discount_program == "volume":
return vega_volume_discount_tier_1 if tier == 1 else vega_volume_discount_tier_2
elif discount_program == "referral":
return (
vega_referral_discount_tier_1
if tier == 1
else vega_referral_discount_tier_2
)
elif discount_program == "combo":
return vega_referral_and_volume_discount
@pytest.fixture
def auth(vega_instance, page):
return auth_setup(vega_instance, page)
def setup_market_with_volume_discount_program(vega: VegaServiceNull, tier: int):
market = setup_continuous_market(vega, custom_quantum=100000)
vega.update_volume_discount_program(
proposal_key=MM_WALLET.name,
benefit_tiers=[
{
"minimum_running_notional_taker_volume": 100,
"volume_discount_factor": 0.1,
},
{
"minimum_running_notional_taker_volume": 200,
"volume_discount_factor": 0.2,
},
],
window_length=7,
)
next_epoch(vega=vega)
order_count = 2 if tier == 1 else 3
for _ in range(order_count):
submit_order(vega, "Key 1", market, "SIDE_BUY", 1, 110)
forward_time(vega, True if _ < order_count - 1 else False)
return market
def setup_market_with_referral_discount_program(vega: VegaServiceNull, tier: int):
market = setup_continuous_market(vega, custom_quantum=100000)
vega.update_referral_program(
proposal_key=MM_WALLET.name,
benefit_tiers=[
{
"minimum_running_notional_taker_volume": 100,
"minimum_epochs": 1,
"referral_reward_factor": 0.1,
"referral_discount_factor": 0.1,
},
{
"minimum_running_notional_taker_volume": 200,
"minimum_epochs": 2,
"referral_reward_factor": 0.2,
"referral_discount_factor": 0.2,
},
],
staking_tiers=[
{"minimum_staked_tokens": 100, "referral_reward_multiplier": 1.1},
{"minimum_staked_tokens": 200, "referral_reward_multiplier": 1.2},
],
window_length=1,
)
vega.create_referral_set(key_name=MM_WALLET.name)
next_epoch(vega=vega)
referral_set_id = list(vega.list_referral_sets().keys())[0]
vega.apply_referral_code(key_name="Key 1", id=referral_set_id)
next_epoch(vega=vega)
order_count = 2
order_size = 1 if tier == 1 else 2
for _ in range(order_count):
submit_order(vega, "Key 1", market, "SIDE_BUY", order_size, 110)
forward_time(vega, True if _ < order_count - 1 else False)
return market
def setup_combined_market(vega: VegaServiceNull):
market = setup_continuous_market(vega, custom_quantum=100000)
vega.update_volume_discount_program(
proposal_key=MM_WALLET.name,
benefit_tiers=[
{
"minimum_running_notional_taker_volume": 100,
"volume_discount_factor": 0.1,
},
{
"minimum_running_notional_taker_volume": 200,
"volume_discount_factor": 0.2,
},
],
window_length=7,
)
next_epoch(vega=vega)
vega.update_referral_program(
proposal_key=MM_WALLET.name,
benefit_tiers=[
{
"minimum_running_notional_taker_volume": 100,
"minimum_epochs": 1,
"referral_reward_factor": 0.1,
"referral_discount_factor": 0.1,
},
{
"minimum_running_notional_taker_volume": 200,
"minimum_epochs": 2,
"referral_reward_factor": 0.2,
"referral_discount_factor": 0.2,
},
],
staking_tiers=[
{"minimum_staked_tokens": 100, "referral_reward_multiplier": 1.1},
{"minimum_staked_tokens": 200, "referral_reward_multiplier": 1.2},
],
window_length=1,
)
vega.create_referral_set(key_name=MM_WALLET.name)
next_epoch(vega=vega)
referral_set_id = list(vega.list_referral_sets().keys())[0]
vega.apply_referral_code(key_name="Key 1", id=referral_set_id)
next_epoch(vega=vega)
order_count = 2
order_size = 2
for _ in range(order_count):
submit_order(vega, "Key 1", market, "SIDE_BUY", order_size, 110)
forward_time(vega, True if _ < order_count - 1 else False)
return market
def set_market_volume_discount(vega, tier, discount_program, market_ids):
market_id_key = f"tier_{tier}_{discount_program}"
if discount_program == "combo":
market_id_key = "combo"
market_id = market_ids.get(market_id_key, "default_id")
print(f"Checking if market exists: {market_id}")
if not market_exists(vega, market_id):
print(
f"Market doesn't exist for {discount_program} tier {tier}. Setting up new market."
)
if discount_program == "volume":
market_id = setup_market_with_volume_discount_program(vega, tier)
elif discount_program == "referral":
market_id = setup_market_with_referral_discount_program(vega, tier)
elif discount_program == "combo":
market_id = setup_combined_market(vega)
market_ids[market_id_key] = market_id
print(f"Using market ID: {market_id}")
return market_ids
@pytest.mark.parametrize(
"tier, discount_program, expected_text",
[
(1, "volume", "9.045%-9.045%"),
(2, "volume", "8.04%-8.04%"),
(1, "referral", "9.045%-9.045%"),
(2, "referral", "8.04%-8.04%"),
(2, "combo", "6.432%-6.432%"),
],
)
@pytest.mark.usefixtures("risk_accepted", "auth", "market_ids")
def test_fees_page_discount_program_my_trading_fees(
tier, expected_text, discount_program, vega_instance, page: Page, market_ids
):
market_ids = set_market_volume_discount(
vega_instance, tier, discount_program, market_ids
)
page.goto("/#/fees")
expect(page.get_by_test_id(ADJUSTED_FEES)).to_have_text(expected_text)
expect(page.get_by_test_id(TOTAL_FEE_BEFORE_DISCOUNT)).to_have_text(
"Total fee before discount10.05%-10.05%"
)
expect(page.get_by_test_id(INFRASTRUCTURE_FEES)).to_have_text("Infrastructure0.05%")
expect(page.get_by_test_id(MAKER_FEES)).to_have_text("Maker10%")
expect(page.get_by_test_id(LIQUIDITY_FEES)).to_have_text("Liquidity0%-0%")
@pytest.mark.parametrize(
"tier, discount_program, volume_discount, total_discount, referral_discount",
[
(1, "volume", "Volume discount10%", "10%", "Referral discount0%"),
(2, "volume", "Volume discount20%", "20%", "Referral discount0%"),
(1, "referral", "Volume discount0%", "10%", "Referral discount10%"),
(2, "referral", "Volume discount0%", "20%", "Referral discount20%"),
(2, "combo", "Volume discount20%", "36%", "Referral discount20%"),
],
)
@pytest.mark.usefixtures("risk_accepted", "auth", "market_ids")
def test_fees_page_discount_program_total_discount(
tier,
discount_program,
volume_discount,
referral_discount,
total_discount,
vega_instance,
page: Page,
market_ids,
):
market_ids = set_market_volume_discount(
vega_instance, tier, discount_program, market_ids
)
page.goto("/#/fees")
expect(page.get_by_test_id(TOTAL_DISCOUNT)).to_have_text(total_discount)
expect(page.get_by_test_id(VOLUME_DISCOUNT_ROW)).to_have_text(volume_discount)
expect(page.get_by_test_id(REFERRAL_DISCOUNT_ROW)).to_have_text(referral_discount)
page.get_by_test_id(TOTAL_DISCOUNT).hover()
expect(page.get_by_test_id(TOOLTIP_CONTENT).nth(0)).to_have_text(
"The total discount is calculated according to the following formula: 1 - (1 - dvolume) ⋇ (1 - dreferral)"
)
@pytest.mark.parametrize(
"tier, discount_program, past_epochs_volume, required_for_next_tier",
[(1, "volume", "103", "97"), (2, "volume", "206", "")],
)
@pytest.mark.usefixtures("risk_accepted", "auth", "market_ids")
def test_fees_page_volume_discount_program_my_current_volume(
tier,
discount_program,
past_epochs_volume,
required_for_next_tier,
vega_instance,
page: Page,
market_ids,
):
market_ids = set_market_volume_discount(
vega_instance, tier, discount_program, market_ids
)
page.goto("/#/fees")
expect(page.get_by_test_id(PAST_EPOCHS_VOLUME)).to_have_text(past_epochs_volume)
if tier == 1:
expect(page.get_by_test_id(REQUIRED_FOR_NEXT_TIER)).to_have_text(
required_for_next_tier
)
else:
expect(page.get_by_test_id(REQUIRED_FOR_NEXT_TIER)).not_to_be_visible()
@pytest.mark.parametrize(
"tier, discount_program, notional_taker_volume, epochs_in_set",
[(1, "referral", "103", "1"), (2, "referral", "207", "1")],
)
@pytest.mark.usefixtures("risk_accepted", "auth", "market_ids")
def test_fees_page_referral_discount_program_referral_benefits(
tier,
vega_instance,
discount_program,
notional_taker_volume,
epochs_in_set,
page: Page,
market_ids,
):
market_ids = set_market_volume_discount(
vega_instance, tier, discount_program, market_ids
)
page.goto("/#/fees")
expect(page.get_by_test_id(RUNNING_NOTIONAL_TAKER_VOLUME)).to_have_text(
notional_taker_volume
)
expect(page.get_by_test_id(EPOCHS_IN_REFERRAL_SET)).to_have_text(epochs_in_set)
@pytest.mark.parametrize(
"tier, discount_program, my_volume_test_id, my_volume_value, your_tier",
[
(1, "volume", "my-volume-value-0", "103", "your-volume-tier-0"),
(2, "volume", "my-volume-value-1", "206", "your-volume-tier-1"),
(1, "referral", "my-volume-value-0", "103", "your-referral-tier-0"),
(2, "referral", "my-volume-value-1", "206", "your-referral-tier-1"),
],
)
@pytest.mark.usefixtures("risk_accepted", "auth", "market_ids")
def test_fees_page_discount_program_discount(
tier,
discount_program,
my_volume_test_id,
my_volume_value,
your_tier,
vega_instance,
page: Page,
market_ids,
):
market_ids = set_market_volume_discount(
vega_instance, tier, discount_program, market_ids
)
page.goto("/#/fees")
expect(page.get_by_test_id(TIER_VALUE_0)).to_have_text("1")
expect(page.get_by_test_id(TIER_VALUE_1)).to_have_text("2")
expect(page.get_by_test_id(DISCOUNT_VALUE_0)).to_have_text("10%")
expect(page.get_by_test_id(DISCOUNT_VALUE_1)).to_have_text("20%")
expect(page.get_by_test_id(MIN_VOLUME_VALUE_0)).to_have_text("100")
expect(page.get_by_test_id(MIN_VOLUME_VALUE_1)).to_have_text("200")
if discount_program == "volume":
expect(page.get_by_test_id(my_volume_test_id)).to_have_text(my_volume_value)
else:
expect(page.get_by_test_id(REQUIRED_EPOCHS_VALUE_0)).to_have_text("1")
expect(page.get_by_test_id(REQUIRED_EPOCHS_VALUE_1)).to_have_text("2")
expect(page.get_by_test_id(your_tier).nth(1)).to_be_visible()
expect(page.get_by_test_id(your_tier).nth(1)).to_have_text("Your tier")
@pytest.mark.parametrize(
"tier, discount_program, fees_after_discount",
[
(1, "volume", "9.045%"),
(2, "volume", "8.04%"),
(1, "referral", "9.045%"),
(2, "referral", "8.04%"),
(2, "combo", "6.432%"),
],
)
@pytest.mark.usefixtures("risk_accepted", "auth", "market_ids")
def test_fees_page_discount_program_fees_by_market(
tier, discount_program, fees_after_discount, vega_instance, page: Page, market_ids
):
market_ids = set_market_volume_discount(
vega_instance, tier, discount_program, market_ids
)
page.goto("/#/fees")
pinned = page.locator(PINNED_ROW_LOCATOR)
row = page.locator(ROW_LOCATOR)
expect(pinned.locator(COL_CODE)).to_have_text("BTC:DAI_2023Futr")
expect(row.locator(COL_FEE_AFTER_DISCOUNT)).to_have_text(fees_after_discount)
expect(row.locator(COL_INFRA_FEE)).to_have_text("0.05%")
expect(row.locator(COL_MAKER_FEE)).to_have_text("10%")
expect(row.locator(COL_LIQUIDITY_FEE)).to_have_text("0%")
expect(row.locator(COL_TOTAL_FEE)).to_have_text("10.05%")
@pytest.mark.parametrize(
"tier, discount_program, discount, discount_value, total_fee",
[
(1, "volume", "-10%", "-0.01005 tDAI", "0.09045 tDAI"),
(2, "volume", "-20%", "-0.0201 tDAI", "0.0804 tDAI"),
(1, "referral", "-10%", "-0.01005 tDAI", "0.09045 tDAI"),
(2, "referral", "-20%", "-0.0201 tDAI", "0.0804 tDAI"),
(2, "combo", "-36%", "-0.03618 tDAI", "0.06432 tDAI"),
],
)
@pytest.mark.usefixtures("risk_accepted", "auth", "market_ids")
def test_deal_ticket_discount_program(
tier,
discount_program,
discount,
discount_value,
total_fee,
vega_instance,
page: Page,
market_ids,
):
market_ids = set_market_volume_discount(
vega_instance, tier, discount_program, market_ids
)
market_id_key = f"tier_{tier}_{discount_program}"
if discount_program == "combo":
market_id_key = "combo"
market_id = market_ids.get(market_id_key)
page.goto(f"/#/markets/{market_id}")
page.get_by_test_id(ORDER_SIZE).fill("1")
page.get_by_test_id(ORDER_PRICE).fill("1")
expect(page.get_by_test_id(DISCOUNT_PILL)).to_have_text(discount)
page.get_by_test_id(FEES_TEXT).hover()
tooltip = page.get_by_test_id(TOOLTIP_CONTENT).first
expect(tooltip.get_by_test_id(INFRASTRUCTURE_FEE_FACTOR)).to_have_text("0.05%")
expect(tooltip.get_by_test_id(INFRASTRUCTURE_FEE_VALUE)).to_have_text("0.0005 tDAI")
expect(tooltip.get_by_test_id(LIQUIDITY_FEE_FACTOR)).to_have_text("0%")
expect(tooltip.get_by_test_id(LIQUIDITY_FEE_VALUE)).to_have_text("0.00 tDAI")
expect(tooltip.get_by_test_id(MAKER_FEE_FACTOR)).to_have_text("10%")
expect(tooltip.get_by_test_id(MAKER_FEE_VALUE)).to_have_text("0.10 tDAI")
expect(tooltip.get_by_test_id(SUBTOTAL_FEE_FACTOR)).to_have_text("10.05%")
expect(tooltip.get_by_test_id(SUBTOTAL_FEE_VALUE)).to_have_text("0.1005 tDAI")
expect(tooltip.get_by_test_id(DISCOUNT_FEE_FACTOR)).to_have_text(discount)
expect(tooltip.get_by_test_id(DISCOUNT_FEE_VALUE)).to_have_text(discount_value)
expect(tooltip.get_by_test_id(TOTAL_FEE_VALUE)).to_have_text(total_fee)
@pytest.mark.parametrize(
"tier, discount_program, fee, fee_discount, price_1, size",
[
(1, "volume", "9.36158 tDAI", "1.04017 tDAI", "103.50 tDAI", "+1"),
(2, "volume", "8.3214 tDAI", "2.08035 tDAI", "103.50 tDAI", "+1"),
(
1,
"referral",
"8.42543 tDAI ",
"1.04017 tDAI",
"103.50 tDAI",
"+1",
),
(
2,
"referral",
"13.31424 tDAI",
"4.1607 tDAI",
"207.00 tDAI",
"+2",
),
(2, "combo", "10.6514 tDAI ", "7.48926 tDAI", "207.00 tDAI", "+2"),
],
)
@pytest.mark.usefixtures("risk_accepted", "auth", "market_ids")
def test_fills_taker_discount_program(
tier,
discount_program,
fee,
fee_discount,
price_1,
size,
vega_instance,
page: Page,
market_ids,
):
market_ids = set_market_volume_discount(
vega_instance, tier, discount_program, market_ids
)
market_id_key = f"tier_{tier}_{discount_program}"
if discount_program == "combo":
market_id_key = "combo"
market_id = market_ids.get(market_id_key)
page.goto(f"/#/markets/{market_id}")
page.get_by_test_id(FILLS).click()
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
expect(row.locator(COL_INSTRUMENT_CODE)).to_have_text("BTC:DAI_2023Futr")
expect(row.locator(COL_SIZE)).to_have_text(size)
expect(row.locator(COL_PRICE)).to_have_text("103.50 tDAI")
expect(row.locator(COL_PRICE_1)).to_have_text(price_1)
expect(row.locator(COL_AGGRESSOR)).to_have_text("Taker")
expect(row.locator(COL_FEE)).to_have_text(fee)
expect(row.locator(COL_FEE_DISCOUNT)).to_have_text(fee_discount)
@pytest.mark.parametrize(
"tier, discount_program, fee, fee_discount, size, price_1",
[
(1, "volume", "-9.315 tDAI", "1.035 tDAI", "-1", "103.50 tDAI"),
(2, "volume", "-8.28 tDAI", "2.07 tDAI", "-1", "103.50 tDAI"),
(1, "referral", "-8.3835 tDAI", "1.035 tDAI", "-1", "103.50 tDAI"),
(2, "referral", "-13.248 tDAI", "4.14 tDAI", "-2", "207.00 tDAI"),
(2, "combo", "-10.5984 tDAI ", "7.452 tDAI", "-2", "207.00 tDAI"),
],
)
@pytest.mark.usefixtures("risk_accepted", "auth", "market_ids")
def test_fills_maker_discount_program(
tier,
discount_program,
vega_instance,
fee,
fee_discount,
size,
price_1,
page: Page,
market_ids,
):
market_ids = set_market_volume_discount(
vega_instance, tier, discount_program, market_ids
)
market_id_key = f"tier_{tier}_{discount_program}"
if discount_program == "combo":
market_id_key = "combo"
market_id = market_ids.get(market_id_key)
page.goto(f"/#/markets/{market_id}")
change_keys(page, vega_instance, MM_WALLET.name)
page.get_by_test_id(FILLS).click()
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
expect(row.locator(COL_INSTRUMENT_CODE)).to_have_text("BTC:DAI_2023Futr")
expect(row.locator(COL_SIZE)).to_have_text(size)
expect(row.locator(COL_PRICE)).to_have_text("103.50 tDAI")
expect(row.locator(COL_PRICE_1)).to_have_text(price_1)
expect(row.locator(COL_AGGRESSOR)).to_have_text("Maker")
expect(row.locator(COL_FEE)).to_have_text(fee)
expect(row.locator(COL_FEE_DISCOUNT)).to_have_text(fee_discount)
@pytest.mark.parametrize(
"tier, discount_program, fee",
[
(1, "volume", "9.315"),
(2, "volume", "8.28"),
(1, "referral", "8.3835"),
(2, "referral", "13.248"),
(2, "combo", "10.5984"),
],
)
@pytest.mark.usefixtures("risk_accepted", "auth", "market_ids")
def test_fills_maker_fee_tooltip_discount_program(
tier, discount_program, fee, vega_instance, page: Page, market_ids
):
market_ids = set_market_volume_discount(
vega_instance, tier, discount_program, market_ids
)
market_id_key = f"tier_{tier}_{discount_program}"
if discount_program == "combo":
market_id_key = "combo"
market_id = market_ids.get(market_id_key)
page.goto(f"/#/markets/{market_id}")
change_keys(page, vega_instance, MM_WALLET.name)
page.get_by_test_id(FILLS).click()
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
# tbd - tooltip is not visible without this wait
page.wait_for_timeout(1000)
row.locator(COL_FEE).hover()
expect(page.get_by_test_id(FEE_BREAKDOWN_TOOLTIP)).to_have_text(
f"If the market was activeFee revenue to be received by the maker, takers' fee discounts already applied.During continuous trading the maker pays no infrastructure and liquidity fees.Infrastructure fee0.00 tDAILiquidity fee0.00 tDAIMaker fee-{fee} tDAITotal fees-{fee} tDAI"
)
@pytest.mark.parametrize(
"tier, discount_program, maker_fee, total_fee, infra_fee",
[
(1, "volume", "9.315", "9.36158", "0.04658"),
(2, "volume", "8.28", "8.3214", "0.0414"),
(1, "referral", "8.3835", "8.42543", "0.04193"),
(2, "referral", "13.248", "13.31424", "0.06624"),
(2, "combo", "10.5984", "10.6514", "0.053"),
],
)
@pytest.mark.usefixtures("risk_accepted", "auth", "market_ids")
def test_fills_taker_fee_tooltip_discount_program(
tier,
discount_program,
vega_instance,
maker_fee,
total_fee,
infra_fee,
page: Page,
market_ids,
):
market_ids = set_market_volume_discount(
vega_instance, tier, discount_program, market_ids
)
market_id_key = f"tier_{tier}_{discount_program}"
if discount_program == "combo":
market_id_key = "combo"
market_id = market_ids.get(market_id_key)
page.goto(f"/#/markets/{market_id}")
page.get_by_test_id(FILLS).click()
row = page.get_by_test_id(TAB_FILLS).locator(ROW_LOCATOR).first
# tbd - tooltip is not visible without this wait
page.wait_for_timeout(1000)
row.locator(COL_FEE).hover()
expect(page.get_by_test_id(FEE_BREAKDOWN_TOOLTIP)).to_have_text(
f"If the market was activeFees to be paid by the taker; discounts are already applied.Infrastructure fee{infra_fee} tDAILiquidity fee0.00 tDAIMaker fee{maker_fee} tDAITotal fees{total_fee} tDAI"
)
@@ -1,7 +1,7 @@
import pytest
from playwright.sync_api import expect, Page
import json
from vega_sim.null_service import VegaServiceNull
from vega_sim.service import VegaService
from fixtures.market import setup_simple_market
from conftest import init_vega
from actions.vega import submit_order
@@ -10,17 +10,21 @@ import logging
logger = logging.getLogger()
@pytest.fixture(scope="class")
def vega():
with init_vega() as vega:
yield vega
# we can reuse vega market-sim service and market in almost all tests
@pytest.fixture(scope="class")
def simple_market(vega: VegaServiceNull):
def simple_market(vega: VegaService):
return setup_simple_market(vega)
class TestGetStarted:
def test_get_started_interactive(self, vega: VegaServiceNull, page: Page):
@pytest.mark.usefixtures("page")
def test_get_started_interactive(self, vega: VegaService, page: Page):
page.goto("/")
# 0007-FUGS-001
expect(page.get_by_test_id("order-connect-wallet")).to_be_visible
@@ -130,7 +134,8 @@ class TestGetStarted:
# Assert dialog isn't visible
expect(page.get_by_test_id("welcome-dialog")).not_to_be_visible()
@pytest.mark.usefixtures("risk_accepted")
@pytest.mark.usefixtures("page", "risk_accepted")
def test_get_started_seen_already(self, simple_market, page: Page):
page.goto(f"/#/markets/{simple_market}")
get_started_locator = page.get_by_test_id("connect-vega-wallet")
@@ -143,6 +148,8 @@ class TestGetStarted:
# 0007-FUGS-007
expect(page.get_by_test_id("dialog-content").nth(1)).to_be_visible()
@pytest.mark.usefixtures("page")
def test_browser_wallet_installed(self, simple_market, page: Page):
page.add_init_script("window.vega = {}")
page.goto(f"/#/markets/{simple_market}")
@@ -152,13 +159,14 @@ class TestGetStarted:
expect(locator).to_be_visible
expect(locator).to_have_text("Connect")
@pytest.mark.usefixtures("risk_accepted")
@pytest.mark.usefixtures("page", "risk_accepted")
def test_get_started_deal_ticket(self,simple_market, page: Page):
page.goto(f"/#/markets/{simple_market}")
expect(page.get_by_test_id("order-connect-wallet")).to_have_text("Connect wallet")
@pytest.mark.usefixtures("risk_accepted")
@pytest.mark.usefixtures("page", "risk_accepted")
def test_browser_wallet_installed_deal_ticket(simple_market, page: Page):
page.add_init_script("window.vega = {}")
page.goto(f"/#/markets/{simple_market}")
@@ -166,8 +174,8 @@ class TestGetStarted:
page.wait_for_selector('[data-testid="sidebar-content"]', state="visible")
expect(page.get_by_test_id("get-started-banner")).not_to_be_visible()
@pytest.mark.skip("tbd-market-sim")
def test_redirect_default_market(self, continuous_market, vega: VegaServiceNull, page: Page):
@pytest.mark.usefixtures("page")
def test_redirect_default_market(self, continuous_market, vega: VegaService, page: Page):
page.goto("/")
# 0007-FUGS-012
expect(page).to_have_url(
@@ -178,7 +186,8 @@ class TestGetStarted:
expect(page.get_by_test_id("welcome-dialog")).not_to_be_visible()
class TestBrowseAll:
def test_get_started_browse_all(self, simple_market, vega: VegaServiceNull, page: Page):
@pytest.mark.usefixtures("page")
def test_get_started_browse_all(self, simple_market, vega: VegaService, page: Page):
page.goto("/")
print(simple_market)
page.get_by_test_id("browse-markets-button").click()
@@ -1,6 +1,6 @@
import pytest
from playwright.sync_api import expect, Page
from vega_sim.null_service import VegaServiceNull
from vega_sim.service import VegaService
from actions.vega import submit_order
from conftest import init_vega
from fixtures.market import setup_continuous_market
@@ -11,6 +11,7 @@ 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):
@@ -21,8 +22,8 @@ class TestIcebergOrdersValidations:
def continuous_market(self, vega):
return setup_continuous_market(vega)
@pytest.mark.usefixtures("auth", "risk_accepted")
def test_iceberg_submit(self, continuous_market, vega: VegaServiceNull, page: Page):
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
def test_iceberg_submit(self, continuous_market, vega: VegaService, 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")
@@ -46,8 +47,8 @@ class TestIcebergOrdersValidations:
(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):
@pytest.mark.usefixtures("vega", "page", "continuous_market", "auth", "risk_accepted")
def test_iceberg_open_order(continuous_market, vega: VegaService, page: Page):
page.goto(f"/#/markets/{continuous_market}")
submit_order(vega, "Key 1", continuous_market, "SIDE_SELL", 102, 101, 2, 1)
@@ -65,17 +66,16 @@ def test_iceberg_open_order(continuous_market, vega: VegaServiceNull, page: Page
page.wait_for_selector(".ag-center-cols-container .ag-row")
expect(
page.locator(".ag-center-cols-container .ag-row [col-id='remaining']").first
page.locator(".ag-center-cols-container .ag-row [col-id='remaining']")
).to_have_text("99")
expect(
page.locator(".ag-center-cols-container .ag-row [col-id='size']").first
page.locator(".ag-center-cols-container .ag-row [col-id='size']")
).to_have_text("-102")
page.pause()
expect(
page.locator(".ag-center-cols-container .ag-row [col-id='type'] ").first
page.locator(".ag-center-cols-container .ag-row [col-id='type'] ")
).to_have_text("Limit (Iceberg)")
expect(
page.locator(".ag-center-cols-container .ag-row [col-id='status']").first
page.locator(".ag-center-cols-container .ag-row [col-id='status']")
).to_have_text("Active")
expect(page.get_by_test_id("price-10100000")).to_be_visible
expect(page.get_by_test_id("ask-vol-10100000")).to_have_text("3")
@@ -1,6 +1,6 @@
import pytest
from playwright.sync_api import Page, expect
from vega_sim.null_service import VegaServiceNull
from vega_sim.service import VegaService
from conftest import init_vega
from fixtures.market import setup_continuous_market
from actions.utils import next_epoch, truncate_middle, change_keys
@@ -17,34 +17,27 @@ def continuous_market(vega):
return setup_continuous_market(vega)
@pytest.mark.usefixtures("auth", "risk_accepted")
def test_liquidity_provision_amendment(continuous_market, vega: VegaServiceNull, page: Page):
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
def test_liquidity_provision_amendment(continuous_market, vega: VegaService, page: Page):
# TODO Refactor asserting the grid
page.goto(f"/#/liquidity/{continuous_market}")
change_keys(page, vega, "market_maker")
row = page.get_by_test_id(
"tab-myLP").locator(".ag-center-cols-container .ag-row").first
row = page.get_by_test_id("tab-myLP").locator(".ag-center-cols-container .ag-row").first
expect(row).to_contain_text(
"Active"
)
# 5002-LIQP-006
expect(page.get_by_test_id("target-stake")
).to_have_text("Target stake5.82757 tDAI")
expect(page.get_by_test_id("target-stake")).to_have_text("Target stake5.82757 tDAI")
# 5002-LIQP-007
expect(page.get_by_test_id("supplied-stake")
).to_have_text("Supplied stake10,000.00 tDAI")
expect(page.get_by_test_id("supplied-stake")).to_have_text("Supplied stake10,000.00 tDAI")
# 5002-LIQP-008
expect(page.get_by_test_id("liquidity-supplied")
).to_have_text("Liquidity supplied 171,598.11%")
expect(page.get_by_test_id("liquidity-supplied")).to_have_text("Liquidity supplied 171,598.11%")
expect(page.get_by_test_id("fees-paid")).to_have_text("Fees paid-")
# 5002-LIQP-009
expect(page.get_by_test_id("liquidity-market-id")
).to_have_text("Market ID" + truncate_middle(continuous_market))
expect(page.get_by_test_id("liquidity-learn-more")
).to_have_text("Learn moreProviding liquidity")
expect(page.get_by_test_id("liquidity-market-id")).to_have_text("Market ID" + truncate_middle(continuous_market))
expect(page.get_by_test_id("liquidity-learn-more")).to_have_text("Learn moreProviding liquidity")
# 002-LIQP-010
expect(page.get_by_test_id("liquidity-learn-more").get_by_test_id("external-link")
).to_have_attribute("href", "https://docs.vega.xyz/testnet/concepts/liquidity/provision")
expect(page.get_by_test_id("liquidity-learn-more").get_by_test_id("external-link")).to_have_attribute("href", "https://docs.vega.xyz/testnet/concepts/liquidity/provision")
vega.submit_simple_liquidity(
key_name="market_maker",
@@ -57,32 +50,26 @@ def test_liquidity_provision_amendment(continuous_market, vega: VegaServiceNull,
vega.wait_fn(1)
vega.wait_for_total_catchup()
page.reload()
row = page.get_by_test_id(
"tab-myLP").locator(".ag-center-cols-container .ag-row").first
row = page.get_by_test_id("tab-myLP").locator(".ag-center-cols-container .ag-row").first
expect(row).to_contain_text(
"Updating next epoch"
)
next_epoch(vega=vega)
page.reload()
expect(page.get_by_test_id("supplied-stake")
).to_have_text("Supplied stake1.00001 tDAI")
expect(page.get_by_test_id("liquidity-supplied")
).to_have_text("Liquidity supplied 17.16%")
row = page.get_by_test_id(
"tab-myLP").locator(".ag-center-cols-container .ag-row").first
expect(page.get_by_test_id("supplied-stake")).to_have_text("Supplied stake1.00001 tDAI")
expect(page.get_by_test_id("liquidity-supplied")).to_have_text("Liquidity supplied 17.16%")
row = page.get_by_test_id("tab-myLP").locator(".ag-center-cols-container .ag-row").first
expect(row).to_contain_text(
"Active"
)
@pytest.mark.skip("Waiting for the ability to cancel LP")
@pytest.mark.usefixtures("auth", "risk_accepted")
def test_liquidity_provision_inactive(continuous_market, vega: VegaServiceNull, page: Page):
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
def test_liquidity_provision_inactive(continuous_market, vega: VegaService, page: Page):
# TODO Refactor asserting the grid
page.goto(f"/#/liquidity/{continuous_market}")
change_keys(page, vega, "market_maker")
row = page.get_by_test_id(
"tab-myLP").locator(".ag-center-cols-container .ag-row").first
change_keys(page,vega, "market_maker")
row = page.get_by_test_id("tab-myLP").locator(".ag-center-cols-container .ag-row").first
expect(row).to_contain_text(
"Active"
)
@@ -95,3 +82,4 @@ def test_liquidity_provision_inactive(continuous_market, vega: VegaServiceNull,
)
vega.wait_fn(1)
vega.wait_for_total_catchup()
@@ -1,7 +1,7 @@
import pytest
import re
import vega_sim.api.governance as governance
from vega_sim.null_service import VegaServiceNull
from vega_sim.service import VegaService
from playwright.sync_api import Page, expect
from fixtures.market import setup_continuous_market
from conftest import init_vega
@@ -12,9 +12,8 @@ def vega():
with init_vega() as vega:
yield vega
@pytest.fixture(scope="class")
def create_settled_market(vega: VegaServiceNull):
def create_settled_market(vega: VegaService):
market_id = setup_continuous_market(vega)
vega.submit_termination_and_settlement_data(
settlement_key="FJMKnwfZdd48C8NqvYrG",
@@ -74,9 +73,8 @@ class TestSettledMarket:
# 6001-MARK-010
pattern = r"(\d+)\s+(months|hours|days)\s+ago"
date_text = row_selector.locator('[col-id="settlementDate"]').inner_text()
assert re.match(
pattern, date_text
), f"Expected text to match pattern but got {date_text}"
assert re.match(pattern, date_text), f"Expected text to match pattern but got {date_text}"
expected_pattern = re.compile(r"https://.*?/oracles/[a-f0-9]{64}")
actual_href = row_selector.locator(
@@ -89,12 +87,12 @@ class TestSettledMarket:
expect(row_selector.locator('[col-id="bestBidPrice"]')).to_have_text("0.00")
# 6001-MARK-012
expect(row_selector.locator('[col-id="bestOfferPrice"]')).to_have_text("0.00")
# 6001-MARK-013
# 6001-MARK-013
expect(row_selector.locator('[col-id="markPrice"]')).to_have_text("110.00")
# 6001-MARK-014
# 6001-MARK-015
# 6001-MARK-016
# tbd currently we have value unknown
#tbd currently we have value unknown
# expect(row_selector.locator('[col-id="settlementDataOracleId"]')).to_have_text(
# "110.00"
# )
@@ -109,13 +107,11 @@ class TestSettledMarket:
# 6001-MARK-018
expect(row_selector.locator('[col-id="settlementAsset"]')).to_have_text("tDAI")
# 6001-MARK-020
assert re.match(
pattern, date_text
), f"Expected text to match pattern but got {date_text}"
assert re.match(pattern, date_text), f"Expected text to match pattern but got {date_text}"
@pytest.mark.usefixtures("risk_accepted", "auth")
def test_terminated_market_no_settlement_date(page: Page, vega: VegaServiceNull):
def test_terminated_market_no_settlement_date(page: Page, vega: VegaService):
setup_continuous_market(vega)
print("I have started test_terminated_market_no_settlement_date")
governance.submit_oracle_data(
+15 -25
View File
@@ -1,6 +1,6 @@
import pytest
from playwright.sync_api import Page, expect
from vega_sim.null_service import VegaServiceNull
from vega_sim.service import VegaService
from actions.vega import submit_order
from actions.utils import change_keys
from wallet_config import MM_WALLET, MM_WALLET2
@@ -30,9 +30,9 @@ initial_volume: float = 1
initial_spread: float = 0.1
market_name = "BTC:DAI_2023"
@pytest.mark.skip("tbd")
@pytest.mark.usefixtures("risk_accepted", "auth")
def test_price_monitoring(simple_market, vega: VegaServiceNull, page: Page):
@pytest.mark.usefixtures("vega", "page", "simple_market", "risk_accepted", "auth")
def test_price_monitoring(simple_market, vega: VegaService, page: Page):
page.goto(f"/#/markets/all")
expect(page.locator(table_row_selector).locator(trading_mode_col)).to_have_text(
"Opening auction"
@@ -75,7 +75,7 @@ def test_price_monitoring(simple_market, vega: VegaServiceNull, page: Page):
time_in_force="TIME_IN_FORCE_GTC",
volume=99,
)
# 6002-MDET-009
#6002-MDET-009
expect(
page.get_by_test_id(liquidity_supplied).get_by_test_id(item_value)
).to_have_text("0.00 (0.00%)")
@@ -154,7 +154,7 @@ def test_price_monitoring(simple_market, vega: VegaServiceNull, page: Page):
vega.forward("10s")
vega.wait_fn(1)
vega.wait_for_total_catchup()
vega.wait_for_total_catchup()
expect(
page.get_by_test_id(price_monitoring_bounds_row).first.get_by_text(
"135.44204 BTC"
@@ -191,32 +191,22 @@ def test_price_monitoring(simple_market, vega: VegaServiceNull, page: Page):
)
# commented out because we have an issue #4233
# expect(page.get_by_text("Opening auction")).to_be_hidden()
# 6002-MDET-009
#6002-MDET-009
expect(
page.get_by_test_id(liquidity_supplied).get_by_test_id(item_value)
).to_have_text("50.00 (>100%)")
COL_ID_FEE = ".ag-center-cols-container [col-id='fee'] .ag-cell-value"
@pytest.mark.usefixtures("risk_accepted", "auth")
def test_auction_uncross_fees(continuous_market, vega: VegaServiceNull, page: Page):
@pytest.mark.usefixtures("vega", "page", "continuous_market", "risk_accepted", "auth")
def test_auction_uncross_fees(continuous_market, vega: VegaService, page: Page):
page.goto(f"/#/markets/{continuous_market}")
page.get_by_test_id("Fills").click()
expect(page.locator(COL_ID_FEE)).to_have_text("0.00 tDAI")
# tbd - tooltip is not visible without this wait
page.wait_for_timeout(1000)
page.get_by_role("gridcell", name="0.00 tDAI").nth(0).hover()
expect(page.get_by_test_id("fee-breakdown-tooltip")).to_have_text(
"If the market was suspendedDuring auction, half the infrastructure and liquidity fees will be paid.Infrastructure fee0.00 tDAILiquidity fee0.00 tDAIMaker fee0.00 tDAITotal fees0.00 tDAI"
)
change_keys(page, vega, "market_maker")
page.locator(COL_ID_FEE).hover()
expect(page.get_by_test_id("fee-breakdown-tooltip")).to_have_text("If the market was suspendedIf the market is in monitoring auction, half of the infrastructure and liquidity fees will be paid.Infrastructure fee0.00 tDAILiquidity fee0.00 tDAIMaker fee0.00 tDAITotal fees0.00 tDAI")
change_keys(page,vega, "market_maker")
expect(page.locator(COL_ID_FEE)).to_have_text("0.00 tDAI")
# tbd - tooltip is not visible without this wait
page.wait_for_timeout(1000)
page.get_by_role("gridcell", name="0.00 tDAI").nth(0).hover()
expect(page.get_by_test_id("fee-breakdown-tooltip")).to_have_text(
"If the market was suspendedDuring auction, half the infrastructure and liquidity fees will be paid.Infrastructure fee0.00 tDAILiquidity fee0.00 tDAIMaker fee0.00 tDAITotal fees0.00 tDAI"
)
page.locator(COL_ID_FEE).hover()
expect(page.get_by_test_id("fee-breakdown-tooltip")).to_have_text("If the market was suspendedIf the market is in monitoring auction, half of the infrastructure and liquidity fees will be paid.Infrastructure fee0.00 tDAILiquidity fee0.00 tDAIMaker fee0.00 tDAITotal fees0.00 tDAI")
@@ -1,8 +1,9 @@
import re
import pytest
from playwright.sync_api import Page, expect
from vega_sim.null_service import VegaServiceNull
from vega_sim.service import VegaService
from fixtures.market import setup_continuous_market
from conftest import init_page, init_vega, risk_accepted_setup
market_title_test_id = "accordion-title"
@@ -14,9 +15,10 @@ def vega():
yield vega
# setting up everything in this single fixture, as all of the tests need the same setup, so no point in creating separate ones
@pytest.fixture(scope="module")
def page(vega, browser, request):
with init_page(vega, browser, request) as page:
def page(vega, browser, request, local_server):
with init_page(vega, browser, request, local_server) as page:
setup_continuous_market(vega)
risk_accepted_setup(page)
page.goto("/")
@@ -42,7 +44,7 @@ def validate_info_section(page: Page, fields: [[str, str]]):
page.get_by_test_id("key-value-table-row").nth(rowNumber).locator("dd")
).to_contain_text(value)
@pytest.mark.skip("tbd-market-sim")
def test_market_info_current_fees(page: Page):
# 6002-MDET-101
page.get_by_test_id(market_title_test_id).get_by_text("Current fees").click()
@@ -54,7 +56,7 @@ def test_market_info_current_fees(page: Page):
]
validate_info_section(page, fields)
@pytest.mark.skip("tbd-market-sim")
def test_market_info_market_price(page: Page):
# 6002-MDET-102
page.get_by_test_id(market_title_test_id).get_by_text("Market price").click()
@@ -66,7 +68,7 @@ def test_market_info_market_price(page: Page):
]
validate_info_section(page, fields)
@pytest.mark.skip("tbd-market-sim")
def test_market_info_market_volume(page: Page):
# 6002-MDET-103
page.get_by_test_id(market_title_test_id).get_by_text("Market volume").click()
@@ -80,15 +82,15 @@ def test_market_info_market_volume(page: Page):
]
validate_info_section(page, fields)
@pytest.mark.skip("tbd-market-sim")
def test_market_info_insurance_pool(page: Page):
# 6002-MDET-104
page.get_by_test_id(market_title_test_id).get_by_text("Insurance pool").click()
fields = [["Balance", "0.00 tDAI"]]
validate_info_section(page, fields)
@pytest.mark.skip("tbd-market-sim")
def test_market_info_key_details(page: Page, vega: VegaServiceNull):
def test_market_info_key_details(page: Page, vega: VegaService):
# 6002-MDET-201
page.get_by_test_id(market_title_test_id).get_by_text("Key details").click()
market_id = vega.find_market_id("BTC:DAI_2023")
@@ -106,7 +108,7 @@ def test_market_info_key_details(page: Page, vega: VegaServiceNull):
]
validate_info_section(page, fields)
@pytest.mark.skip("tbd-market-sim")
def test_market_info_instrument(page: Page):
# 6002-MDET-202
page.get_by_test_id(market_title_test_id).get_by_text("Instrument").click()
@@ -120,9 +122,7 @@ def test_market_info_instrument(page: Page):
# @pytest.mark.skip("oracle test to be fixed")
@pytest.mark.skip("tbd-market-sim")
def test_market_info_oracle(page: Page):
def test_market_info_oracle(page: Page, vega: VegaService):
# 6002-MDET-203
page.get_by_test_id(market_title_test_id).get_by_text("Oracle").click()
expect(
@@ -135,8 +135,8 @@ def test_market_info_oracle(page: Page):
# "href", re.compile(rf'(\/oracles\/{vega.find_market_id("BTC:DAI_2023")})')
# )
@pytest.mark.skip("tbd-market-sim")
def test_market_info_settlement_asset(page: Page, vega: VegaServiceNull):
def test_market_info_settlement_asset(page: Page, vega: VegaService):
# 6002-MDET-206
page.get_by_test_id(market_title_test_id).get_by_text("Settlement asset").click()
tdai_id = vega.find_asset_id("tDAI")
@@ -155,7 +155,7 @@ def test_market_info_settlement_asset(page: Page, vega: VegaServiceNull):
]
validate_info_section(page, fields)
@pytest.mark.skip("tbd-market-sim")
def test_market_info_metadata(page: Page):
# 6002-MDET-207
page.get_by_test_id(market_title_test_id).get_by_text("Metadata").click()
@@ -164,7 +164,7 @@ def test_market_info_metadata(page: Page):
]
validate_info_section(page, fields)
@pytest.mark.skip("tbd-market-sim")
def test_market_info_risk_model(page: Page):
# 6002-MDET-208
page.get_by_test_id(market_title_test_id).get_by_text("Risk model").click()
@@ -175,7 +175,7 @@ def test_market_info_risk_model(page: Page):
]
validate_info_section(page, fields)
@pytest.mark.skip("tbd-market-sim")
def test_market_info_margin_scaling_factors(page: Page):
# 6002-MDET-209
page.get_by_test_id(market_title_test_id).get_by_text(
@@ -190,7 +190,7 @@ def test_market_info_margin_scaling_factors(page: Page):
]
validate_info_section(page, fields)
@pytest.mark.skip("tbd-market-sim")
def test_market_info_risk_factors(page: Page):
# 6002-MDET-210
page.get_by_test_id(market_title_test_id).get_by_text("Risk factors").click()
@@ -204,7 +204,7 @@ def test_market_info_risk_factors(page: Page):
]
validate_info_section(page, fields)
@pytest.mark.skip("tbd-market-sim")
def test_market_info_price_monitoring_bounds(page: Page):
# 6002-MDET-211
page.get_by_test_id(market_title_test_id).get_by_text(
@@ -220,7 +220,7 @@ def test_market_info_price_monitoring_bounds(page: Page):
]
validate_info_section(page, fields)
@pytest.mark.skip("tbd-market-sim")
def test_market_info_liquidity_monitoring_parameters(page: Page):
# 6002-MDET-212
page.get_by_test_id(market_title_test_id).get_by_text(
@@ -233,7 +233,7 @@ def test_market_info_liquidity_monitoring_parameters(page: Page):
]
validate_info_section(page, fields)
@pytest.mark.skip("tbd-market-sim")
# Liquidity resolves to 3 results
def test_market_info_liquidit(page: Page):
# 6002-MDET-213
@@ -246,7 +246,7 @@ def test_market_info_liquidit(page: Page):
]
validate_info_section(page, fields)
@pytest.mark.skip("tbd-market-sim")
def test_market_info_liquidity_price_range(page: Page):
# 6002-MDET-214
page.get_by_test_id(market_title_test_id).get_by_text(
@@ -259,8 +259,8 @@ def test_market_info_liquidity_price_range(page: Page):
]
validate_info_section(page, fields)
@pytest.mark.skip("tbd-market-sim")
def test_market_info_proposal(page: Page, vega: VegaServiceNull):
def test_market_info_proposal(page: Page, vega: VegaService):
# 6002-MDET-301
page.get_by_test_id(market_title_test_id).get_by_text("Proposal").click()
first_link = (
@@ -280,9 +280,8 @@ def test_market_info_proposal(page: Page, vega: VegaServiceNull):
"href", re.compile(r"(\/proposals\/propose\/update-market)")
)
@pytest.mark.skip("tbd-market-sim")
def test_market_info_succession_line(page: Page, vega: VegaServiceNull):
def test_market_info_succession_line(page: Page, vega: VegaService):
page.get_by_test_id(market_title_test_id).get_by_text("Succession line").click()
market_id = vega.find_market_id("BTC:DAI_2023")
succession_line = page.get_by_test_id("succession-line-item")
@@ -2,13 +2,14 @@ import pytest
from playwright.sync_api import expect, Page
@pytest.mark.usefixtures("auth", "risk_accepted")
@pytest.mark.usefixtures("page", "continuous_market", "auth", "risk_accepted")
def test_market_selector(continuous_market, page: Page):
page.goto(f"/#/markets/{continuous_market}")
expect(page.get_by_test_id("market-selector")).not_to_be_visible()
page.get_by_test_id("header-title").click()
# 6001-MARK-066
expect(page.get_by_test_id("market-selector")).to_be_visible()
# 6001-MARK-021
# 6001-MARK-022
# 6001-MARK-024
@@ -26,7 +27,7 @@ def test_market_selector(continuous_market, page: Page):
expect(btc_market.locator('[data-testid="sparkline-svg"]')).not_to_be_visible
@pytest.mark.usefixtures("simple_market", "auth", "risk_accepted")
@pytest.mark.usefixtures("page", "continuous_market", "simple_market", "auth", "risk_accepted")
@pytest.mark.parametrize(
"simple_market",
[
@@ -42,6 +43,7 @@ def test_market_selector_filter(continuous_market, page: Page):
page.goto(f"/#/markets/{continuous_market}")
page.get_by_test_id("header-title").click()
# 6001-MARK-027
page.get_by_test_id("product-Spot").click()
expect(page.get_by_test_id("market-selector-list")).to_contain_text(
"Spot markets coming soon."
@@ -1,5 +1,6 @@
import pytest
from playwright.sync_api import Page, expect
from vega_sim.service import VegaService
from conftest import init_page, init_vega, risk_accepted_setup
@@ -11,8 +12,8 @@ def vega(request):
@pytest.fixture(scope="module")
def page(vega, browser, request):
with init_page(vega, browser, request) as page:
def page(vega, browser, request, local_server):
with init_page(vega, browser, request, local_server) as page:
risk_accepted_setup(page)
page.goto("/#/markets/all")
yield page
@@ -2,10 +2,10 @@ import pytest
import vega_sim.api.governance as governance
import re
from playwright.sync_api import Page, expect
from vega_sim.null_service import VegaServiceNull
from vega_sim.service import VegaService
from conftest import init_vega
from fixtures.market import setup_simple_market
from wallet_config import MM_WALLET
from wallet_config import MM_WALLET, MM_WALLET2, TERMINATE_WALLET, wallets
row_selector = '[data-testid="tab-proposed-markets"] .ag-center-cols-container .ag-row'
col_market_id = '[col-id="market"] [data-testid="stack-cell-primary"]'
@@ -16,9 +16,8 @@ def vega(request):
with init_vega(request) as vega:
yield vega
@pytest.fixture(scope="module")
def proposed_market(vega: VegaServiceNull):
def proposed_market(vega: VegaService):
# setup market without liquidity provided
market_id = setup_simple_market(vega, approve_proposal=False)
# approve market
@@ -1,13 +1,12 @@
import pytest
from playwright.sync_api import Page, expect
from vega_sim.null_service import VegaServiceNull
from vega_sim.service import VegaService
from actions.vega import submit_order
from fixtures.market import setup_simple_market
from conftest import init_vega
from actions.utils import wait_for_toast_confirmation
from wallet_config import MM_WALLET, MM_WALLET2
@pytest.fixture(scope="module")
def vega(request):
with init_vega(request) as vega:
@@ -18,9 +17,8 @@ def vega(request):
def simple_market(vega):
return setup_simple_market(vega)
@pytest.fixture(scope="module")
def setup_market_monitoring_auction(vega: VegaServiceNull, simple_market):
def setup_market_monitoring_auction(vega: VegaService, simple_market):
vega.submit_liquidity(
key_name=MM_WALLET.name,
market_id=simple_market,
@@ -50,18 +48,12 @@ def setup_market_monitoring_auction(vega: VegaServiceNull, simple_market):
volume=99,
)
# add orders to provide liquidity
submit_order(vega, MM_WALLET.name, simple_market, "SIDE_BUY", 1, 1)
submit_order(vega, MM_WALLET.name, simple_market, "SIDE_SELL", 1, 1)
submit_order(
vega,
MM_WALLET.name,
simple_market,
"SIDE_BUY",
1,
1 + 0.1 / 2,
)
submit_order(vega, MM_WALLET.name, simple_market, "SIDE_SELL", 1, 1 + 0.1 / 2)
submit_order(vega,MM_WALLET.name,simple_market, "SIDE_BUY",1,1 + 0.1 / 2,)
submit_order(vega,MM_WALLET.name,simple_market,"SIDE_SELL",1,1 + 0.1 / 2)
submit_order(vega, MM_WALLET2.name, simple_market, "SIDE_SELL", 1, 1)
vega.forward("10s")
@@ -79,11 +71,9 @@ def setup_market_monitoring_auction(vega: VegaServiceNull, simple_market):
vega.wait_fn(1)
vega.wait_for_total_catchup()
@pytest.mark.usefixtures("risk_accepted", "auth", "setup_market_monitoring_auction")
def test_market_monitoring_auction_price_volatility_limit_order(
page: Page, simple_market, vega: VegaServiceNull
):
@pytest.mark.usefixtures("page", "risk_accepted", "simple_market", "auth", "setup_market_monitoring_auction")
def test_market_monitoring_auction_price_volatility_limit_order(page: Page, simple_market, vega: VegaService):
page.goto(f"/#/markets/{simple_market}")
page.get_by_test_id("order-size").clear()
page.get_by_test_id("order-size").type("1")
@@ -92,14 +82,10 @@ def test_market_monitoring_auction_price_volatility_limit_order(
page.get_by_test_id("order-tif").select_option("Fill or Kill (FOK)")
page.get_by_test_id("place-order").click()
expect(page.get_by_test_id("deal-ticket-error-message-tif")).to_have_text(
"This market is in auction due to high price volatility. Until the auction ends, you can only place GFA, GTT, or GTC limit orders."
)
expect(page.get_by_test_id("deal-ticket-error-message-tif")).to_have_text("This market is in auction due to high price volatility. Until the auction ends, you can only place GFA, GTT, or GTC limit orders.")
expect(page.get_by_test_id("deal-ticket-error-message-tif")).to_be_visible()
expect(page.get_by_test_id("deal-ticket-warning-auction")).to_have_text(
"Any orders placed now will not trade until the auction ends"
)
expect(page.get_by_test_id("deal-ticket-warning-auction")).to_have_text("Any orders placed now will not trade until the auction ends")
expect(page.get_by_test_id("deal-ticket-warning-auction")).to_be_visible()
page.get_by_test_id("order-tif").select_option("Good 'til Cancelled (GTC)")
@@ -117,11 +103,8 @@ def test_market_monitoring_auction_price_volatility_limit_order(
"BTC:DAI_2023Futr0+1LimitActive110.00GTC"
)
@pytest.mark.usefixtures("risk_accepted", "auth", "setup_market_monitoring_auction")
def test_market_monitoring_auction_price_volatility_market_order(
page: Page, simple_market
):
@pytest.mark.usefixtures("page", "risk_accepted", "simple_market", "auth", "setup_market_monitoring_auction")
def test_market_monitoring_auction_price_volatility_market_order(page: Page, simple_market):
page.goto(f"/#/markets/{simple_market}")
page.get_by_test_id("order-type-Market").click()
page.get_by_test_id("order-size").clear()
@@ -129,12 +112,8 @@ def test_market_monitoring_auction_price_volatility_market_order(
# 7002-SORD-060
page.get_by_test_id("place-order").click()
expect(page.get_by_test_id("deal-ticket-error-message-tif")).to_have_text(
"This market is in auction due to high price volatility. Until the auction ends, you can only place GFA, GTT, or GTC limit orders."
)
expect(page.get_by_test_id("deal-ticket-error-message-tif")).to_have_text("This market is in auction due to high price volatility. Until the auction ends, you can only place GFA, GTT, or GTC limit orders.")
expect(page.get_by_test_id("deal-ticket-error-message-tif")).to_be_visible()
expect(page.get_by_test_id("deal-ticket-error-message-type")).to_have_text(
"This market is in auction due to high price volatility. Only limit orders are permitted when market is in auction."
)
expect(page.get_by_test_id("deal-ticket-error-message-type")).to_have_text("This market is in auction due to high price volatility. Only limit orders are permitted when market is in auction.")
expect(page.get_by_test_id("deal-ticket-error-message-type")).to_be_visible()
@@ -2,16 +2,16 @@ import pytest
import re
import vega_sim.api.governance as governance
from playwright.sync_api import Page, expect
from vega_sim.null_service import VegaServiceNull
from vega_sim.service import PeggedOrder
from vega_sim.service import VegaService, PeggedOrder
import vega_sim.api.governance as governance
from actions.vega import submit_order
from actions.utils import next_epoch
from wallet_config import MM_WALLET, MM_WALLET2, GOVERNANCE_WALLET
@pytest.mark.usefixtures("risk_accepted")
def test_market_lifecycle(proposed_market, vega: VegaServiceNull, page: Page):
@pytest.mark.usefixtures("vega", "page", "proposed_market", "risk_accepted")
def test_market_lifecycle(proposed_market, vega: VegaService, page: Page):
# 7002-SORD-001
# 7002-SORD-002
trading_mode = page.get_by_test_id("market-trading-mode").get_by_test_id(
@@ -27,12 +27,8 @@ def test_market_lifecycle(proposed_market, vega: VegaServiceNull, page: Page):
# 6002-MDET-002
expect(page.get_by_test_id("market-expiry")).to_have_text("ExpiryNot time-based")
page.get_by_test_id("market-expiry").hover()
expect(page.get_by_test_id("expiry-tooltip").first).to_have_text(
"This market expires when triggered by its oracle, not on a set date.View oracle specification"
)
expect(
page.get_by_test_id("expiry-tooltip").first.get_by_test_id("link")
).to_have_attribute("href", re.compile(".*"))
expect(page.get_by_test_id("expiry-tooltip").first).to_have_text("This market expires when triggered by its oracle, not on a set date.View oracle specification")
expect(page.get_by_test_id("expiry-tooltip").first.get_by_test_id("link")).to_have_attribute("href", re.compile('.*'))
# 6002-MDET-003
expect(page.get_by_test_id("market-price")).to_have_text("Mark Price0.00")
# 6002-MDET-004
@@ -40,30 +36,18 @@ def test_market_lifecycle(proposed_market, vega: VegaServiceNull, page: Page):
# 6002-MDET-005
expect(page.get_by_test_id("market-volume")).to_have_text("Volume (24h)-")
# 6002-MDET-008
expect(page.get_by_test_id("market-settlement-asset")).to_have_text(
"Settlement assettDAI"
)
expect(page.get_by_test_id("liquidity-supplied")).to_have_text(
"Liquidity supplied 0.00 (0.00%)"
)
expect(page.get_by_test_id("market-settlement-asset")).to_have_text("Settlement assettDAI")
expect(page.get_by_test_id("liquidity-supplied")).to_have_text("Liquidity supplied 0.00 (0.00%)")
page.get_by_test_id("liquidity-supplied").hover()
expect(page.get_by_test_id("liquidity-supplied-tooltip").first).to_have_text(
"Supplied stake0.00Target stake0.00View liquidity provision tableLearn about providing liquidity"
)
expect(
page.get_by_test_id("liquidity-supplied-tooltip")
.first.get_by_test_id("link")
.first
).to_have_text("View liquidity provision table")
expect(page.get_by_test_id("liquidity-supplied-tooltip").first).to_have_text("Supplied stake0.00Target stake0.00View liquidity provision tableLearn about providing liquidity")
expect(page.get_by_test_id("liquidity-supplied-tooltip").first.get_by_test_id("link").first).to_have_text("View liquidity provision table")
# check that market is in proposed state
# 6002-MDET-006
# 6002-MDET-007
# 7002-SORD-061
expect(trading_mode).to_have_text("No trading")
trading_mode.hover()
expect(page.get_by_test_id("trading-mode-tooltip").first).to_have_text(
"No trading enabled for this market."
)
expect(page.get_by_test_id("trading-mode-tooltip").first).to_have_text("No trading enabled for this market.")
expect(market_state).to_have_text("Proposed")
# approve market
@@ -198,4 +182,4 @@ def test_market_closing_banners(page: Page, continuous_market, vega: VegaService
will_close_pattern = r"TRADING ON MARKET BTC:DAI_2023 WILL STOP ON \d+ \w+\nYou will no longer be able to hold a position on this market when it closes in \d+ days \d+ hours\. The final price will be 107\.00 BTC\."
match_result = re.fullmatch(will_close_pattern, page.locator(".grow").inner_text())
assert match_result is not None
"""
"""
@@ -12,8 +12,8 @@ def vega():
# we can reuse single page instance in all tests
@pytest.fixture(scope="module")
def page(vega, browser, request):
with init_page(vega, browser, request) as page:
def page(vega, browser, request, local_server):
with init_page(vega, browser, request, local_server) as page:
yield page
@@ -1,7 +1,7 @@
import pytest
import re
from playwright.sync_api import expect, Page
from vega_sim.null_service import VegaServiceNull
from vega_sim.service import VegaService
from actions.vega import submit_order
order_details = [
@@ -48,11 +48,10 @@ def verify_order_value(
else:
expect(element).to_have_text(expected_text)
@pytest.mark.skip("tbd")
@pytest.mark.usefixtures("auth", "risk_accepted")
@pytest.mark.usefixtures("vega", "page", "continuous_market", "auth", "risk_accepted")
def test_order_details_are_correctly_displayed(
continuous_market, vega: VegaServiceNull, page: Page
continuous_market, vega: VegaService, page: Page
):
page.goto(f"/#/markets/{continuous_market}")
submit_order(vega, "Key 1", vega.all_markets()[0].id, "SIDE_SELL", 102, 101, 2, 1)
@@ -2,13 +2,12 @@ import pytest
import re
import logging
from playwright.sync_api import expect, Page
from vega_sim.null_service import VegaServiceNull
from vega_sim.service import VegaService
from playwright.sync_api import expect
from actions.vega import submit_order
logger = logging.getLogger()
# Could be turned into a helper function in the future.
def verify_data_grid(page: Page, data_test_id, expected_pattern):
page.get_by_test_id(data_test_id).click()
@@ -16,11 +15,11 @@ def verify_data_grid(page: Page, data_test_id, expected_pattern):
expect(
page.locator(
f'[data-testid^="tab-{data_test_id.lower()}"] >> .ag-center-cols-container .ag-row-first'
).first
)
).to_be_visible()
actual_text = page.locator(
f'[data-testid^="tab-{data_test_id.lower()}"] >> .ag-center-cols-container .ag-row-first'
).first.text_content()
).text_content()
lines = actual_text.strip().split("\n")
for expected, actual in zip(expected_pattern, lines):
# We are using regex so that we can run tests in different timezones.
@@ -38,7 +37,7 @@ def verify_data_grid(page: Page, data_test_id, expected_pattern):
raise AssertionError(f"Pattern does not match: {expected} != {actual}")
def submit_order(vega: VegaServiceNull, wallet_name, market_id, side, volume, price):
def submit_order(vega: VegaService, wallet_name, market_id, side, volume, price):
vega.submit_order(
trading_key=wallet_name,
market_id=market_id,
@@ -50,9 +49,11 @@ def submit_order(vega: VegaServiceNull, wallet_name, market_id, side, volume, pr
)
@pytest.mark.usefixtures("auth", "risk_accepted")
@pytest.mark.usefixtures(
"vega", "page", "opening_auction_market", "auth", "risk_accepted"
)
def test_limit_order_trade_open_order(
opening_auction_market, vega: VegaServiceNull, page: Page
opening_auction_market, vega: VegaService, page: Page
):
market_id = opening_auction_market
submit_order(vega, "Key 1", market_id, "SIDE_BUY", 1, 110)
@@ -79,7 +80,7 @@ def test_limit_order_trade_open_order(
verify_data_grid(page, "Open", expected_open_order)
@pytest.mark.usefixtures("auth", "risk_accepted")
@pytest.mark.usefixtures("vega", "page", "continuous_market", "auth", "risk_accepted")
def test_limit_order_trade_open_position(continuous_market, page: Page):
page.goto(f"/#/markets/{continuous_market}")
@@ -147,7 +148,7 @@ def test_limit_order_trade_open_position(continuous_market, page: Page):
expect(unrealisedPNL).to_have_text(position["unrealised_pnl"])
@pytest.mark.usefixtures("auth", "risk_accepted")
@pytest.mark.usefixtures("vega", "page", "continuous_market", "auth", "risk_accepted")
def test_limit_order_trade_order_trade_away(continuous_market, page: Page):
page.goto(f"/#/markets/{continuous_market}")
# Assert that the order is no longer on the orderbook

Some files were not shown because too many files have changed in this diff Show More