Compare commits
34
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80fff35b39 | ||
|
|
c16c65975f | ||
|
|
4c731d98c9 | ||
|
|
f0a33672f1 | ||
|
|
51dbd45ca9 | ||
|
|
1a0d4a5ed9 | ||
|
|
137580cfa2 | ||
|
|
4adaeea40a | ||
|
|
d47d894147 | ||
|
|
515932d401 | ||
|
|
723ff2805d | ||
|
|
424cced4be | ||
|
|
b2c7ee82c5 | ||
|
|
4cc63be4f9 | ||
|
|
9fbb7a13e6 | ||
|
|
1874095222 | ||
|
|
e459e92127 | ||
|
|
4dd65b4923 | ||
|
|
5d792d2458 | ||
|
|
59b2f75b13 | ||
|
|
95775679ca | ||
|
|
4cffee29f8 | ||
|
|
bd70b0c233 | ||
|
|
145792f216 | ||
|
|
10add7c236 | ||
|
|
362a2031c7 | ||
|
|
5aaeb87059 | ||
|
|
d240dddab5 | ||
|
|
0af1d0ba82 | ||
|
|
665ab6693a | ||
|
|
902ee2696c | ||
|
|
3beeb0140c | ||
|
|
4b208e90bf | ||
|
|
ec837854cf |
@@ -1,3 +1,4 @@
|
||||
* text eol=lf
|
||||
*.png binary
|
||||
*.ico binary
|
||||
*.woff2 binary
|
||||
|
||||
@@ -54,7 +54,7 @@ const Block = () => {
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
{blockData && (
|
||||
{blockData && 'result' in blockData && (
|
||||
<>
|
||||
<TableWithTbody className="mb-8">
|
||||
<TableRow modifier="bordered">
|
||||
|
||||
@@ -32,7 +32,7 @@ CYPRESS_FAIRGROUND=false
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=true
|
||||
NX_METAMASK_SNAPS=false
|
||||
NX_METAMASK_SNAPS=true
|
||||
NX_PRODUCT_PERPETUALS=true
|
||||
NX_UPDATE_MARKET_STATE=true
|
||||
NX_REFERRALS=true
|
||||
|
||||
@@ -23,7 +23,7 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://be.vega.community/websocket
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=true
|
||||
NX_METAMASK_SNAPS=false
|
||||
NX_METAMASK_SNAPS=true
|
||||
NX_PRODUCT_PERPETUALS=true
|
||||
NX_UPDATE_MARKET_STATE=true
|
||||
NX_REFERRALS=true
|
||||
|
||||
@@ -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=false
|
||||
NX_METAMASK_SNAPS=true
|
||||
NX_PRODUCT_PERPETUALS=true
|
||||
NX_UPDATE_MARKET_STATE=true
|
||||
NX_REFERRALS=true
|
||||
|
||||
@@ -21,7 +21,7 @@ NX_TENDERMINT_WEBSOCKET_URL=wss://be.validators-testnet.vega.
|
||||
|
||||
# Cosmic elevator flags
|
||||
NX_SUCCESSOR_MARKETS=true
|
||||
NX_METAMASK_SNAPS=false
|
||||
NX_METAMASK_SNAPS=true
|
||||
NX_PRODUCT_PERPETUALS=true
|
||||
NX_UPDATE_MARKET_STATE=true
|
||||
NX_REFERRALS=true
|
||||
|
||||
+2
-2
@@ -281,8 +281,8 @@ describe('VoteBreakdown', () => {
|
||||
});
|
||||
|
||||
it('Progress bar displays status - LP majority', () => {
|
||||
const yesVotesLP = 800;
|
||||
const noVotesLP = 200;
|
||||
const yesVotesLP = 0.8;
|
||||
const noVotesLP = 0.2;
|
||||
const expectedProgress = (yesVotesLP / (yesVotesLP + noVotesLP)) * 100; // 80%
|
||||
|
||||
renderComponent(
|
||||
|
||||
@@ -105,8 +105,6 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
|
||||
yesLPPercentage,
|
||||
yesTokens,
|
||||
noTokens,
|
||||
yesEquityLikeShareWeight,
|
||||
noEquityLikeShareWeight,
|
||||
totalEquityLikeShareWeight,
|
||||
requiredMajorityPercentage,
|
||||
requiredMajorityLPPercentage,
|
||||
@@ -135,6 +133,7 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
|
||||
.multipliedBy(100),
|
||||
new BigNumber(100)
|
||||
);
|
||||
|
||||
const willPass = willPassByTokenVote || willPassByLPVote;
|
||||
const updateMarketVotePassMethod = willPassByTokenVote
|
||||
? t('byTokenVote')
|
||||
@@ -202,50 +201,24 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
|
||||
<div className="flex items-center gap-1">
|
||||
<span>{t('liquidityProviderVotesFor')}:</span>
|
||||
<Tooltip
|
||||
description={formatNumber(
|
||||
yesEquityLikeShareWeight,
|
||||
defaultDP
|
||||
)}
|
||||
description={
|
||||
<span>{yesLPPercentage.toFixed(defaultDP)}%</span>
|
||||
}
|
||||
>
|
||||
<button>
|
||||
<CompactVotes number={yesEquityLikeShareWeight} />
|
||||
</button>
|
||||
<button>{yesLPPercentage.toFixed(1)}%</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(0)}%</button>
|
||||
<button>{noLPPercentage.toFixed(1)}%</button>
|
||||
</Tooltip>
|
||||
)
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -282,13 +255,8 @@ export const VoteBreakdown = ({ proposal }: VoteBreakdownProps) => {
|
||||
defaultDP
|
||||
)}
|
||||
>
|
||||
<button>
|
||||
<CompactVotes number={totalEquityLikeShareWeight} />
|
||||
</button>
|
||||
<span>{totalEquityLikeShareWeight.toFixed(1)}%</span>
|
||||
</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 = '30';
|
||||
const noEquityLikeShareWeight = '70';
|
||||
const yesEquityLikeShareWeight = '0.30';
|
||||
const noEquityLikeShareWeight = '0.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 = 20;
|
||||
const noVotes = 70;
|
||||
const yesEquityLikeShareWeight = '30';
|
||||
const noEquityLikeShareWeight = '60';
|
||||
const yesVotes = 0.2;
|
||||
const noVotes = 0.7;
|
||||
const yesEquityLikeShareWeight = '0.30';
|
||||
const noEquityLikeShareWeight = '0.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);
|
||||
: new BigNumber(proposal.votes.no.totalEquityLikeShareWeight).times(100);
|
||||
|
||||
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);
|
||||
: new BigNumber(proposal.votes.yes.totalEquityLikeShareWeight).times(100);
|
||||
|
||||
const totalTokensVoted = yesTokens.plus(noTokens);
|
||||
|
||||
@@ -81,12 +81,7 @@ export const useVoteInformation = ({
|
||||
const yesPercentage = totalTokensVoted.isZero()
|
||||
? new BigNumber(0)
|
||||
: yesTokens.multipliedBy(100).dividedBy(totalTokensVoted);
|
||||
|
||||
const yesLPPercentage = totalEquityLikeShareWeight.isZero()
|
||||
? new BigNumber(0)
|
||||
: yesEquityLikeShareWeight
|
||||
.multipliedBy(100)
|
||||
.dividedBy(totalEquityLikeShareWeight);
|
||||
const yesLPPercentage = yesEquityLikeShareWeight;
|
||||
|
||||
const noPercentage = totalTokensVoted.isZero()
|
||||
? new BigNumber(0)
|
||||
@@ -103,9 +98,7 @@ export const useVoteInformation = ({
|
||||
);
|
||||
|
||||
const participationLPMet = requiredParticipationLP
|
||||
? totalEquityLikeShareWeight.isGreaterThan(
|
||||
totalSupply.multipliedBy(requiredParticipationLP)
|
||||
)
|
||||
? totalEquityLikeShareWeight.isGreaterThan(requiredParticipationLP)
|
||||
: false;
|
||||
|
||||
const majorityMet = yesPercentage.isGreaterThanOrEqualTo(
|
||||
@@ -120,9 +113,7 @@ export const useVoteInformation = ({
|
||||
.multipliedBy(100)
|
||||
.dividedBy(totalSupply);
|
||||
|
||||
const totalLPTokensPercentage = totalEquityLikeShareWeight
|
||||
.multipliedBy(100)
|
||||
.dividedBy(totalSupply);
|
||||
const totalLPTokensPercentage = totalEquityLikeShareWeight;
|
||||
|
||||
const willPassByTokenVote =
|
||||
participationMet &&
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ export const ProtocolUpgradeProposalContainer = () => {
|
||||
time={
|
||||
pending && time ? (
|
||||
convertToCountdownString(time, '0:00:00:00')
|
||||
) : blockInfo?.result ? (
|
||||
) : blockInfo && 'result' in blockInfo && blockInfo?.result ? (
|
||||
<span title={blockInfo.result.block.header.time}>
|
||||
{formatDateWithLocalTimezone(
|
||||
new Date(blockInfo.result.block.header.time)
|
||||
|
||||
@@ -116,7 +116,8 @@ export const generateYesVotes = (
|
||||
fixedTokenValue?: number,
|
||||
totalEquityLikeShareWeight?: string
|
||||
): Votes => {
|
||||
const votes = Array.from(Array(numberOfVotes)).map(() => {
|
||||
const votes = [];
|
||||
for (let i = 0; i < numberOfVotes; i++) {
|
||||
const vote: Vote = {
|
||||
__typename: 'Vote',
|
||||
value: Schema.VoteValue.VALUE_YES,
|
||||
@@ -152,8 +153,9 @@ export const generateYesVotes = (
|
||||
datetime: faker.date.past().toISOString(),
|
||||
};
|
||||
|
||||
return vote;
|
||||
});
|
||||
votes.push(vote);
|
||||
}
|
||||
|
||||
return {
|
||||
__typename: 'ProposalVoteSide',
|
||||
totalNumber: votes.length.toString(),
|
||||
@@ -172,7 +174,8 @@ export const generateNoVotes = (
|
||||
fixedTokenValue?: number,
|
||||
totalEquityLikeShareWeight?: string
|
||||
): Votes => {
|
||||
const votes = Array.from(Array(numberOfVotes)).map(() => {
|
||||
const votes = [];
|
||||
for (let i = 0; i < numberOfVotes; i++) {
|
||||
const vote: Vote = {
|
||||
__typename: 'Vote',
|
||||
value: Schema.VoteValue.VALUE_NO,
|
||||
@@ -207,8 +210,9 @@ export const generateNoVotes = (
|
||||
},
|
||||
datetime: faker.date.past().toISOString(),
|
||||
};
|
||||
return vote;
|
||||
});
|
||||
votes.push(vote);
|
||||
}
|
||||
|
||||
return {
|
||||
__typename: 'ProposalVoteSide',
|
||||
totalNumber: votes.length.toString(),
|
||||
|
||||
@@ -188,12 +188,11 @@ const useNow = () => {
|
||||
return now;
|
||||
};
|
||||
|
||||
const useEvery = (marketId: string) => {
|
||||
const { data: marketTradingMode } = useMarketTradingMode(marketId);
|
||||
const useEvery = (marketId: string, skip: boolean) => {
|
||||
const { data: marketInfo } = useDataProvider({
|
||||
dataProvider: marketInfoProvider,
|
||||
variables: { marketId },
|
||||
skip: !marketTradingMode || isMarketInAuction(marketTradingMode),
|
||||
skip,
|
||||
});
|
||||
let every: number | undefined = undefined;
|
||||
const sourceType =
|
||||
@@ -211,8 +210,10 @@ const useEvery = (marketId: string) => {
|
||||
return every;
|
||||
};
|
||||
|
||||
const useStartTime = (marketId: string) => {
|
||||
const useStartTime = (marketId: string, skip: boolean) => {
|
||||
const { data: fundingPeriods } = useFundingPeriodsQuery({
|
||||
pollInterval: 5000,
|
||||
skip,
|
||||
variables: {
|
||||
marketId: marketId,
|
||||
pagination: { first: 1 },
|
||||
@@ -246,8 +247,10 @@ const useFormatCountdown = (
|
||||
|
||||
export const FundingCountdown = ({ marketId }: { marketId: string }) => {
|
||||
const now = useNow();
|
||||
const startTime = useStartTime(marketId);
|
||||
const every = useEvery(marketId);
|
||||
const { data: marketTradingMode } = useMarketTradingMode(marketId);
|
||||
const skip = !marketTradingMode || isMarketInAuction(marketTradingMode);
|
||||
const startTime = useStartTime(marketId, skip);
|
||||
const every = useEvery(marketId, skip);
|
||||
|
||||
return (
|
||||
<div data-testid="funding-countdown">
|
||||
|
||||
@@ -9,8 +9,6 @@ import { TradeGrid } from './trade-grid';
|
||||
import { TradePanels } from './trade-panels';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { Links } from '../../lib/links';
|
||||
import { ViewType, useSidebar } from '../../components/sidebar';
|
||||
import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id';
|
||||
import { useT, ns } from '../../lib/use-t';
|
||||
import { Trans } from 'react-i18next';
|
||||
|
||||
@@ -61,9 +59,6 @@ export const MarketPage = () => {
|
||||
const t = useT();
|
||||
const { marketId } = useParams();
|
||||
const navigate = useNavigate();
|
||||
const currentRouteId = useGetCurrentRouteId();
|
||||
const { setViews, getView } = useSidebar();
|
||||
const view = getView(currentRouteId);
|
||||
const { screenSize } = useScreenDimensions();
|
||||
const largeScreen = ['lg', 'xl', 'xxl', 'xxxl'].includes(screenSize);
|
||||
const update = useGlobalStore((store) => store.update);
|
||||
@@ -77,12 +72,6 @@ export const MarketPage = () => {
|
||||
}
|
||||
}, [update, lastMarketId, data?.id]);
|
||||
|
||||
useEffect(() => {
|
||||
if (largeScreen && view === undefined) {
|
||||
setViews({ type: ViewType.Order }, currentRouteId);
|
||||
}
|
||||
}, [setViews, view, currentRouteId, largeScreen]);
|
||||
|
||||
const pinnedAsset = data && getAsset(data);
|
||||
|
||||
const tradeView = useMemo(() => {
|
||||
|
||||
@@ -4,7 +4,12 @@ import { OracleBanner } from '@vegaprotocol/markets';
|
||||
import { useState } from 'react';
|
||||
import AutoSizer from 'react-virtualized-auto-sizer';
|
||||
import classNames from 'classnames';
|
||||
import { Splash, VegaIcon, VegaIconNames } from '@vegaprotocol/ui-toolkit';
|
||||
import {
|
||||
Popover,
|
||||
Splash,
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import {
|
||||
MarketSuccessorBanner,
|
||||
@@ -24,7 +29,6 @@ interface TradePanelsProps {
|
||||
export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
|
||||
const featureFlags = useFeatureFlags((state) => state.flags);
|
||||
const [view, setView] = useState<TradingView>('chart');
|
||||
const [settingsOpened, setSettingsOpened] = useState(false);
|
||||
const viewCfg = TradingViews[view];
|
||||
|
||||
const renderView = () => {
|
||||
@@ -51,12 +55,18 @@ export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
|
||||
<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 ? (
|
||||
<button
|
||||
className="ml-1 flex items-center justify-center h-6 w-6"
|
||||
onClick={() => setSettingsOpened((v) => !v)}
|
||||
<Popover
|
||||
align="end"
|
||||
trigger={
|
||||
<span className="ml-1 flex items-center justify-center h-6 w-6">
|
||||
<VegaIcon name={VegaIconNames.COG} size={16} />
|
||||
</span>
|
||||
}
|
||||
>
|
||||
<VegaIcon name={VegaIconNames.COG} size={16} />
|
||||
</button>
|
||||
<div className="p-4 flex justify-end">
|
||||
<viewCfg.settings />
|
||||
</div>
|
||||
</Popover>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
@@ -64,7 +74,7 @@ export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="h-full grid grid-rows-[min-content_1fr_min-content]">
|
||||
<div className="h-full grid grid-rows-[min-content_min-content_1fr_min-content]">
|
||||
<div>
|
||||
{featureFlags.SUCCESSOR_MARKETS && (
|
||||
<>
|
||||
@@ -75,36 +85,15 @@ export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
|
||||
<MarketTerminationBanner market={market} />
|
||||
<OracleBanner marketId={market?.id || ''} />
|
||||
</div>
|
||||
<div className="h-full grid grid-rows-[min-content_1fr] relative">
|
||||
<div>{renderMenu()}</div>
|
||||
<div className="h-full">
|
||||
<AutoSizer>
|
||||
{({ width, height }) => (
|
||||
<div style={{ width, height }} className="overflow-auto">
|
||||
{renderView()}
|
||||
</div>
|
||||
)}
|
||||
</AutoSizer>
|
||||
</div>
|
||||
{settingsOpened && 'settings' in viewCfg ? (
|
||||
<div className="absolute right-0 top-0 bottom-0 w-[280px] max-w-full bg-vega-clight-700 dark:bg-vega-cdark-700 z-10">
|
||||
<div className="grid grid-rows-[32px_1fr]">
|
||||
<div className="flex justify-end p-1">
|
||||
<button
|
||||
type="button"
|
||||
data-testid="settings-close"
|
||||
onClick={() => setSettingsOpened(false)}
|
||||
className="flex items-center justify-center h-6 w-6"
|
||||
>
|
||||
<VegaIcon name={VegaIconNames.CROSS} size={12} />
|
||||
</button>
|
||||
</div>
|
||||
<div className="relative h-full overflow-auto p-2">
|
||||
<viewCfg.settings />
|
||||
</div>
|
||||
<div>{renderMenu()}</div>
|
||||
<div className="h-full relative">
|
||||
<AutoSizer>
|
||||
{({ width, height }) => (
|
||||
<div style={{ width, height }} className="overflow-auto">
|
||||
{renderView()}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
)}
|
||||
</AutoSizer>
|
||||
</div>
|
||||
<div className="flex flex-nowrap overflow-x-auto max-w-full border-t border-default">
|
||||
{Object.keys(TradingViews)
|
||||
@@ -136,7 +125,6 @@ export const TradePanels = ({ market, pinnedAsset }: TradePanelsProps) => {
|
||||
view={key}
|
||||
isActive={isActive}
|
||||
onClick={() => {
|
||||
setSettingsOpened(false);
|
||||
setView(key);
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -42,7 +42,7 @@ export const createDataGridSlice: StateCreator<DataGridSlice> = (set) => ({
|
||||
},
|
||||
});
|
||||
|
||||
const useMarketsStore = create<DataGridSlice>()(
|
||||
export const useMarketsStore = create<DataGridSlice>()(
|
||||
persist(createDataGridSlice, {
|
||||
name: 'vega_market_list_store',
|
||||
})
|
||||
|
||||
@@ -16,6 +16,7 @@ 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();
|
||||
@@ -34,7 +35,11 @@ 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')}>
|
||||
<Tab
|
||||
id="open-markets"
|
||||
name={t('Open markets')}
|
||||
settings={<MarketsSettings />}
|
||||
>
|
||||
<ErrorBoundary feature="markets-open">
|
||||
<OpenMarkets />
|
||||
</ErrorBoundary>
|
||||
@@ -42,6 +47,7 @@ export const MarketsPage = () => {
|
||||
<Tab
|
||||
id="proposed-markets"
|
||||
name={t('Proposed markets')}
|
||||
settings={<MarketsSettings />}
|
||||
menu={
|
||||
<TradingAnchorButton
|
||||
size="extra-small"
|
||||
@@ -56,7 +62,11 @@ export const MarketsPage = () => {
|
||||
<Proposed />
|
||||
</ErrorBoundary>
|
||||
</Tab>
|
||||
<Tab id="closed-markets" name={t('Closed markets')}>
|
||||
<Tab
|
||||
id="closed-markets"
|
||||
name={t('Closed markets')}
|
||||
settings={<MarketsSettings />}
|
||||
>
|
||||
<ErrorBoundary feature="markets-closed">
|
||||
<Closed />
|
||||
</ErrorBoundary>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import { GridSettings } from '../../components/grid-settings/grid-settings';
|
||||
import { useMarketsStore } from './market-list-table';
|
||||
|
||||
export const MarketsSettings = () => (
|
||||
<GridSettings
|
||||
updateGridStore={useMarketsStore((store) => store.updateGridStore)}
|
||||
/>
|
||||
);
|
||||
@@ -4,9 +4,26 @@ import {
|
||||
SidebarButton,
|
||||
SidebarDivider,
|
||||
ViewType,
|
||||
useSidebar,
|
||||
} from '../../components/sidebar';
|
||||
import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id';
|
||||
import { useT } from '../../lib/use-t';
|
||||
import { useScreenDimensions } from '@vegaprotocol/react-helpers';
|
||||
import { useEffect } from 'react';
|
||||
|
||||
const ViewInitializer = () => {
|
||||
const currentRouteId = useGetCurrentRouteId();
|
||||
const { setViews, getView } = useSidebar();
|
||||
const view = getView(currentRouteId);
|
||||
const { screenSize } = useScreenDimensions();
|
||||
const largeScreen = ['lg', 'xl', 'xxl', 'xxxl'].includes(screenSize);
|
||||
useEffect(() => {
|
||||
if (largeScreen && view === undefined) {
|
||||
setViews({ type: ViewType.Order }, currentRouteId);
|
||||
}
|
||||
}, [setViews, view, currentRouteId, largeScreen]);
|
||||
return null;
|
||||
};
|
||||
|
||||
export const MarketsSidebar = () => {
|
||||
const t = useT();
|
||||
@@ -37,6 +54,7 @@ export const MarketsSidebar = () => {
|
||||
path=":marketId"
|
||||
element={
|
||||
<>
|
||||
<ViewInitializer />
|
||||
<SidebarDivider />
|
||||
<SidebarButton
|
||||
view={ViewType.Order}
|
||||
|
||||
@@ -54,11 +54,21 @@ const WithdrawalsIndicator = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export const Portfolio = () => {
|
||||
const t = useT();
|
||||
const SidebarViewInitializer = () => {
|
||||
const currentRouteId = useGetCurrentRouteId();
|
||||
const { getView, setViews } = useSidebar();
|
||||
const view = getView(currentRouteId);
|
||||
// Make transfer sidebar open by default
|
||||
useEffect(() => {
|
||||
if (view === undefined) {
|
||||
setViews({ type: ViewType.Transfer }, currentRouteId);
|
||||
}
|
||||
}, [view, setViews, currentRouteId]);
|
||||
return null;
|
||||
};
|
||||
|
||||
export const Portfolio = () => {
|
||||
const t = useT();
|
||||
|
||||
const { updateTitle } = usePageTitleStore((store) => ({
|
||||
updateTitle: store.updateTitle,
|
||||
@@ -68,17 +78,11 @@ export const Portfolio = () => {
|
||||
updateTitle(titlefy([t('Portfolio')]));
|
||||
}, [updateTitle, t]);
|
||||
|
||||
// Make transfer sidebar open by default
|
||||
useEffect(() => {
|
||||
if (view === undefined) {
|
||||
setViews({ type: ViewType.Transfer }, currentRouteId);
|
||||
}
|
||||
}, [view, setViews, currentRouteId]);
|
||||
|
||||
const [sizes, handleOnLayoutChange] = usePaneLayout({ id: 'portfolio' });
|
||||
const wrapperClasses = 'p-0.5 h-full max-h-full flex flex-col';
|
||||
return (
|
||||
<div className={wrapperClasses}>
|
||||
<SidebarViewInitializer />
|
||||
<ResizableGrid vertical onChange={handleOnLayoutChange}>
|
||||
<ResizableGridPanel minSize={75}>
|
||||
<PortfolioGridChild>
|
||||
|
||||
@@ -2,6 +2,7 @@ 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,
|
||||
@@ -122,6 +123,66 @@ 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
|
||||
|
||||
@@ -151,6 +151,27 @@ 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,
|
||||
@@ -262,6 +283,19 @@ 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'),
|
||||
@@ -297,6 +331,7 @@ describe('ReferralStatistics', () => {
|
||||
noReferralSetAsRefereeMock,
|
||||
stakeAvailableMock,
|
||||
refereesMock,
|
||||
refereesMock30,
|
||||
]}
|
||||
showWarnings={false}
|
||||
>
|
||||
@@ -313,6 +348,10 @@ 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,10 +4,15 @@ import {
|
||||
VegaIcon,
|
||||
VegaIconNames,
|
||||
truncateMiddle,
|
||||
TextChildrenTooltip as Tooltip,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { DEFAULT_AGGREGATION_DAYS, useReferral } from './hooks/use-referral';
|
||||
import {
|
||||
DEFAULT_AGGREGATION_DAYS,
|
||||
useReferral,
|
||||
useUpdateReferees,
|
||||
} from './hooks/use-referral';
|
||||
import classNames from 'classnames';
|
||||
import { Table } from './table';
|
||||
import {
|
||||
@@ -41,11 +46,17 @@ export const ReferralStatistics = () => {
|
||||
role: 'referee',
|
||||
aggregationEpochs: program.details?.windowLength,
|
||||
});
|
||||
const { data: referrer, refetch: referrerRefetch } = useReferral({
|
||||
pubKey,
|
||||
role: 'referrer',
|
||||
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 refetch = useCallback(() => {
|
||||
refereeRefetch();
|
||||
@@ -76,11 +87,9 @@ 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({
|
||||
@@ -181,7 +190,7 @@ export const Statistics = ({
|
||||
nextBenefitTierValue,
|
||||
nextBenefitTierVolumeValue,
|
||||
nextBenefitTierEpochsValue,
|
||||
} = useStats({ data, program, as });
|
||||
} = useStats({ data, program });
|
||||
|
||||
const isApplyCodePreview = useMemo(
|
||||
() => data.referee === null,
|
||||
@@ -293,11 +302,27 @@ export const Statistics = ({
|
||||
.reduce((all, r) => all.plus(r), new BigNumber(0));
|
||||
const totalCommissionTile = (
|
||||
<StatTile
|
||||
title={t('totalCommission', 'Total commission (last {{count}} epochs)', {
|
||||
count: details?.windowLength || DEFAULT_AGGREGATION_DAYS,
|
||||
})}
|
||||
description={<QUSDTooltip />}
|
||||
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>,
|
||||
]}
|
||||
/>
|
||||
}
|
||||
description={<QUSDTooltip />}
|
||||
>
|
||||
{getNumberFormat(0).format(Number(totalCommissionValue))}
|
||||
</StatTile>
|
||||
@@ -503,12 +528,21 @@ export const RefereesTable = ({
|
||||
displayName: (
|
||||
<Trans
|
||||
i18nKey="referralStatisticsCommission"
|
||||
defaults="Commission earned in <0>qUSD</0> (last {{count}} epochs)"
|
||||
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>,
|
||||
]}
|
||||
values={{
|
||||
count:
|
||||
details?.windowLength || DEFAULT_AGGREGATION_DAYS,
|
||||
count: DEFAULT_AGGREGATION_DAYS,
|
||||
}}
|
||||
components={[<QUSDTooltip key="qusd" />]}
|
||||
ns={ns}
|
||||
/>
|
||||
),
|
||||
|
||||
@@ -31,7 +31,7 @@ export const Tile = ({
|
||||
};
|
||||
|
||||
type StatTileProps = {
|
||||
title: string;
|
||||
title: ReactNode;
|
||||
testId?: string;
|
||||
description?: ReactNode;
|
||||
children?: ReactNode;
|
||||
@@ -70,7 +70,7 @@ export const StatTile = ({
|
||||
export const NoProgramTile = ({ title }: Pick<StatTileProps, 'title'>) => {
|
||||
const t = useT();
|
||||
return (
|
||||
<Tile title={title}>
|
||||
<Tile>
|
||||
<h3 className="mb-1 text-sm text-vega-clight-100 dark:text-vega-cdark-100 calt">
|
||||
{title}
|
||||
</h3>
|
||||
|
||||
@@ -8,15 +8,18 @@ export const Card = ({
|
||||
className,
|
||||
loading = false,
|
||||
highlight = false,
|
||||
testId,
|
||||
}: {
|
||||
children: ReactNode;
|
||||
title: string;
|
||||
className?: string;
|
||||
loading?: boolean;
|
||||
highlight?: boolean;
|
||||
testId?: string;
|
||||
}) => {
|
||||
return (
|
||||
<div
|
||||
data-testid={testId}
|
||||
className={classNames(
|
||||
'bg-vega-clight-800 dark:bg-vega-cdark-800 col-span-full p-0.5 lg:col-auto',
|
||||
'rounded-lg',
|
||||
|
||||
@@ -84,7 +84,10 @@ export const FeesContainer = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="grid auto-rows-min grid-cols-4 gap-3">
|
||||
<div
|
||||
className="grid auto-rows-min grid-cols-4 gap-3"
|
||||
data-testid="fees-container"
|
||||
>
|
||||
{isConnected && (
|
||||
<>
|
||||
<Card
|
||||
@@ -124,7 +127,10 @@ export const FeesContainer = () => {
|
||||
windowLength={volumeDiscountWindowLength}
|
||||
/>
|
||||
) : (
|
||||
<p className="text-muted pt-3 text-sm">
|
||||
<p
|
||||
className="text-muted pt-3 text-sm"
|
||||
data-testid="no-volume-discount"
|
||||
>
|
||||
{t('No volume discount program active')}
|
||||
</p>
|
||||
)}
|
||||
@@ -133,17 +139,22 @@ export const FeesContainer = () => {
|
||||
title={t('Referral benefits')}
|
||||
className="sm:col-span-2"
|
||||
loading={loading}
|
||||
data-testid="referral-benefits-card"
|
||||
>
|
||||
{isReferrer ? (
|
||||
<ReferrerInfo code={code} />
|
||||
<ReferrerInfo code={code} data-testid="referrer-info" />
|
||||
) : isReferralProgramRunning ? (
|
||||
<ReferralBenefits
|
||||
setRunningNotionalTakerVolume={referralVolumeInWindow}
|
||||
epochsInSet={epochsInSet}
|
||||
epochs={referralDiscountWindowLength}
|
||||
data-testid="referral-benefits"
|
||||
/>
|
||||
) : (
|
||||
<p className="text-muted pt-3 text-sm">
|
||||
<p
|
||||
className="text-muted pt-3 text-sm"
|
||||
data-testid="no-referral-program"
|
||||
>
|
||||
{t('No referral program active')}
|
||||
</p>
|
||||
)}
|
||||
@@ -154,6 +165,7 @@ export const FeesContainer = () => {
|
||||
title={t('Volume discount')}
|
||||
className="lg:col-span-full xl:col-span-2"
|
||||
loading={loading}
|
||||
data-testid="volume-discount-card"
|
||||
>
|
||||
<VolumeTiers
|
||||
tiers={volumeTiers}
|
||||
@@ -166,6 +178,7 @@ export const FeesContainer = () => {
|
||||
title={t('Referral discount')}
|
||||
className="lg:col-span-full xl:col-span-2"
|
||||
loading={loading}
|
||||
data-testid="referral-discount-card"
|
||||
>
|
||||
<ReferralTiers
|
||||
tiers={referralTiers}
|
||||
@@ -178,6 +191,7 @@ export const FeesContainer = () => {
|
||||
title={t('Fees by market')}
|
||||
className="lg:col-span-full"
|
||||
loading={marketsLoading}
|
||||
data-testid="fees-by-market-card"
|
||||
>
|
||||
<MarketFees
|
||||
markets={markets}
|
||||
@@ -245,7 +259,7 @@ export const TradingFees = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="pt-4">
|
||||
<div className="pt-4" data-testid="trading-fees">
|
||||
<div className="leading-none">
|
||||
<p className="block text-3xl leading-none" data-testid="adjusted-fees">
|
||||
{minAdjustedTotal !== undefined && maxAdjustedTotal !== undefined
|
||||
@@ -255,7 +269,7 @@ export const TradingFees = ({
|
||||
: `${formatPercentage(adjustedTotal)}%`}
|
||||
</p>
|
||||
<CardTable>
|
||||
<tr className="text-default">
|
||||
<tr className="text-default" data-testid="total-fee-before-discount">
|
||||
<CardTableTH>{t('Total fee before discount')}</CardTableTH>
|
||||
<CardTableTD>
|
||||
{minTotal !== undefined && maxTotal !== undefined
|
||||
@@ -265,7 +279,7 @@ export const TradingFees = ({
|
||||
: `${formatPercentage(total.toNumber())}%`}
|
||||
</CardTableTD>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr data-testid="infrastructure-fees">
|
||||
<CardTableTH>{t('Infrastructure')}</CardTableTH>
|
||||
<CardTableTD>
|
||||
{formatPercentage(
|
||||
@@ -274,14 +288,14 @@ export const TradingFees = ({
|
||||
%
|
||||
</CardTableTD>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr data-testid="maker-fees">
|
||||
<CardTableTH>{t('Maker')}</CardTableTH>
|
||||
<CardTableTD>
|
||||
{formatPercentage(Number(params.market_fee_factors_makerFee))}%
|
||||
</CardTableTD>
|
||||
</tr>
|
||||
{minLiq && maxLiq && (
|
||||
<tr>
|
||||
<tr data-testid="liquidity-fees">
|
||||
<CardTableTH>{t('Liquidity')}</CardTableTH>
|
||||
<CardTableTD>
|
||||
{formatPercentage(Number(minLiq.fees.factors.liquidityFee))}%
|
||||
@@ -317,21 +331,19 @@ export const CurrentVolume = ({
|
||||
const currentVolume = new BigNumber(windowLengthVolume);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-3 pt-4">
|
||||
<div className="flex flex-col gap-3 pt-4" data-testid="current-volume">
|
||||
<CardStat
|
||||
value={
|
||||
currentVolume.isZero()
|
||||
? `<${formatNumberRounded(requiredForNextTier)}`
|
||||
: formatNumberRounded(currentVolume)
|
||||
}
|
||||
value={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>
|
||||
@@ -349,7 +361,7 @@ const ReferralBenefits = ({
|
||||
}) => {
|
||||
const t = useT();
|
||||
return (
|
||||
<div className="flex flex-col gap-3 pt-4">
|
||||
<div className="flex flex-col gap-3 pt-4" data-testid="referral-benefits">
|
||||
<CardStat
|
||||
// all sets volume (not just current party)
|
||||
value={formatNumber(setRunningNotionalTakerVolume)}
|
||||
@@ -360,8 +372,13 @@ 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>
|
||||
);
|
||||
};
|
||||
@@ -389,7 +406,7 @@ const TotalDiscount = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="pt-4">
|
||||
<div className="pt-4" data-testid="total-discount-card-stats">
|
||||
<CardStat
|
||||
description={
|
||||
<>
|
||||
@@ -399,9 +416,10 @@ const TotalDiscount = ({
|
||||
}
|
||||
value={formatPercentage(totalDiscount) + '%'}
|
||||
highlight={true}
|
||||
testId="total-discount"
|
||||
/>
|
||||
<CardTable>
|
||||
<tr>
|
||||
<tr data-testid="volume-discount-row">
|
||||
<CardTableTH>{t('Volume discount')}</CardTableTH>
|
||||
<CardTableTD>
|
||||
{formatPercentage(volumeDiscount)}%
|
||||
@@ -415,7 +433,7 @@ const TotalDiscount = ({
|
||||
)}
|
||||
</CardTableTD>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr data-testid="referral-discount-row">
|
||||
<CardTableTH>{t('Referral discount')}</CardTableTH>
|
||||
<CardTableTD>
|
||||
{formatPercentage(referralDiscount)}%
|
||||
@@ -461,29 +479,37 @@ const VolumeTiers = ({
|
||||
<div>
|
||||
<Table>
|
||||
<THead>
|
||||
<tr>
|
||||
<Th>{t('Tier')}</Th>
|
||||
<Th>{t('Discount')}</Th>
|
||||
<Th>{t('Min. trading volume')}</Th>
|
||||
<Th>
|
||||
<Tr>
|
||||
<Th data-testid="tier-header">{t('Tier')}</Th>
|
||||
<Th data-testid="discount-header">{t('Discount')}</Th>
|
||||
<Th data-testid="min-volume-header">{t('Min. trading volume')}</Th>
|
||||
<Th data-testid="my-volume-header">
|
||||
{t('myVolume', 'My volume (last {{count}} epochs)', {
|
||||
count: windowLength,
|
||||
})}
|
||||
</Th>
|
||||
<Th />
|
||||
</tr>
|
||||
<Th data-testid="actions-header" />
|
||||
</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 key={i} data-testid={`tier-row-${i}`}>
|
||||
<Td data-testid={`tier-value-${i}`}>{i + 1}</Td>
|
||||
<Td data-testid={`discount-value-${i}`}>
|
||||
{formatPercentage(Number(tier.volumeDiscountFactor))}%
|
||||
</Td>
|
||||
<Td data-testid={`min-volume-value-${i}`}>
|
||||
{formatNumber(tier.minimumRunningNotionalTakerVolume)}
|
||||
</Td>
|
||||
<Td data-testid={`my-volume-value-${i}`}>
|
||||
{isUserTier ? formatNumber(lastEpochVolume) : ''}
|
||||
</Td>
|
||||
<Td data-testid={`your-tier-${i}`}>
|
||||
{isUserTier ? <YourTier /> : null}
|
||||
</Td>
|
||||
</Tr>
|
||||
);
|
||||
})}
|
||||
@@ -520,39 +546,53 @@ const ReferralTiers = ({
|
||||
<div>
|
||||
<Table>
|
||||
<THead>
|
||||
<tr>
|
||||
<Th>{t('Tier')}</Th>
|
||||
<Th>{t('Discount')}</Th>
|
||||
<Th>{t('Min. trading volume')}</Th>
|
||||
<Th>{t('Required epochs')}</Th>
|
||||
<Th />
|
||||
</tr>
|
||||
<Tr>
|
||||
<Th data-testid="tier-header">{t('Tier')}</Th>
|
||||
<Th data-testid="discount-header">{t('Discount')}</Th>
|
||||
<Th data-testid="min-volume-header">{t('Min. trading volume')}</Th>
|
||||
<Th data-testid="required-epochs-header">{t('Required epochs')}</Th>
|
||||
<Th data-testid="extra-header" />
|
||||
</Tr>
|
||||
</THead>
|
||||
<tbody>
|
||||
{Array.from(tiers).map((t, i) => {
|
||||
{Array.from(tiers).map((tier, i) => {
|
||||
const isUserTier = tierIndex === i;
|
||||
|
||||
const requiredVolume = Number(t.minimumRunningNotionalTakerVolume);
|
||||
const requiredVolume = Number(
|
||||
tier.minimumRunningNotionalTakerVolume
|
||||
);
|
||||
let unlocksIn = null;
|
||||
|
||||
if (
|
||||
referralVolumeInWindow >= requiredVolume &&
|
||||
epochsInSet < t.minimumEpochs
|
||||
epochsInSet < tier.minimumEpochs
|
||||
) {
|
||||
unlocksIn = (
|
||||
<span className="text-muted">
|
||||
Unlocks in {t.minimumEpochs - epochsInSet} epochs
|
||||
Unlocks in {tier.minimumEpochs - epochsInSet} epochs
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
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 key={i} data-testid={`tier-row-${i}`}>
|
||||
<Td data-testid={`tier-value-${i}`}>{i + 1}</Td>
|
||||
<Td data-testid={`discount-value-${i}`}>
|
||||
{formatPercentage(Number(tier.referralDiscountFactor))}%
|
||||
</Td>
|
||||
<Td data-testid={`min-volume-value-${i}`}>
|
||||
{formatNumber(tier.minimumRunningNotionalTakerVolume)}
|
||||
</Td>
|
||||
<Td data-testid={`required-epochs-value-${i}`}>
|
||||
{tier.minimumEpochs}
|
||||
</Td>
|
||||
<Td data-testid={`user-tier-or-unlocks-${i}`}>
|
||||
{isUserTier ? (
|
||||
<YourTier testId={`your-tier-${i}`} />
|
||||
) : (
|
||||
unlocksIn
|
||||
)}
|
||||
</Td>
|
||||
</Tr>
|
||||
);
|
||||
})}
|
||||
@@ -562,11 +602,18 @@ const ReferralTiers = ({
|
||||
);
|
||||
};
|
||||
|
||||
const YourTier = () => {
|
||||
interface YourTierProps {
|
||||
testId?: string;
|
||||
}
|
||||
|
||||
const YourTier = ({ testId }: YourTierProps) => {
|
||||
const t = useT();
|
||||
|
||||
return (
|
||||
<span className="bg-rainbow whitespace-nowrap rounded-xl px-4 py-1.5 text-white">
|
||||
<span
|
||||
className="bg-rainbow whitespace-nowrap rounded-xl px-4 py-1.5 text-white"
|
||||
data-testid={testId}
|
||||
>
|
||||
{t('Your tier')}
|
||||
</span>
|
||||
);
|
||||
|
||||
@@ -3,21 +3,31 @@ import type { ReactNode } from 'react';
|
||||
|
||||
const cellClass = 'px-4 py-2 text-xs font-normal text-left last:text-right';
|
||||
|
||||
export const Th = ({ children }: { children?: ReactNode }) => {
|
||||
export const Th = ({ children, ...props }: { children?: ReactNode }) => {
|
||||
return (
|
||||
<th className={classNames(cellClass, 'text-secondary leading-none py-3')}>
|
||||
<th
|
||||
className={classNames(cellClass, 'text-secondary leading-none py-3')}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</th>
|
||||
);
|
||||
};
|
||||
|
||||
export const Td = ({ children }: { children?: ReactNode }) => {
|
||||
return <th className={cellClass}>{children}</th>;
|
||||
export const Td = ({ children, ...props }: { children?: ReactNode }) => {
|
||||
return (
|
||||
<th className={cellClass} {...props}>
|
||||
{children}
|
||||
</th>
|
||||
);
|
||||
};
|
||||
|
||||
export const Tr = ({ children }: { children?: ReactNode }) => {
|
||||
export const Tr = ({ children, ...props }: { children?: ReactNode }) => {
|
||||
return (
|
||||
<tr className="hover:bg-vega-clight-600 dark:hover:bg-vega-cdark-700">
|
||||
<tr
|
||||
className="hover:bg-vega-clight-600 dark:hover:bg-vega-cdark-700"
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</tr>
|
||||
);
|
||||
|
||||
@@ -27,7 +27,7 @@ export const MarketHeader = () => {
|
||||
title={
|
||||
<Popover
|
||||
open={open}
|
||||
onChange={setOpen}
|
||||
onOpenChange={setOpen}
|
||||
trigger={
|
||||
<HeaderTitle>
|
||||
<span>
|
||||
|
||||
@@ -69,11 +69,13 @@ 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',
|
||||
@@ -138,20 +140,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,6 +62,10 @@ 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;
|
||||
@@ -295,7 +299,9 @@ export const RewardPot = ({
|
||||
: [0];
|
||||
const totalVesting = BigNumber.sum.apply(null, vestingBalances);
|
||||
|
||||
const totalRewards = totalLocked.plus(totalVesting);
|
||||
const totalRewards = totalLocked
|
||||
.plus(totalVesting)
|
||||
.plus(totalVestedRewardsByRewardAsset);
|
||||
|
||||
let rewardAsset = undefined;
|
||||
|
||||
|
||||
@@ -24,7 +24,13 @@ import classNames from 'classnames';
|
||||
import { useGetCurrentRouteId } from '../../lib/hooks/use-get-current-route-id';
|
||||
import { useT } from '../../lib/use-t';
|
||||
|
||||
export const VegaWalletConnectButton = () => {
|
||||
export const VegaWalletConnectButton = ({
|
||||
intent = Intent.None,
|
||||
onClick,
|
||||
}: {
|
||||
intent?: Intent;
|
||||
onClick?: () => void;
|
||||
}) => {
|
||||
const t = useT();
|
||||
const [dropdownOpen, setDropdownOpen] = useState(false);
|
||||
const openVegaWalletDialog = useVegaWalletDialogStore(
|
||||
@@ -117,9 +123,12 @@ export const VegaWalletConnectButton = () => {
|
||||
return (
|
||||
<Button
|
||||
data-testid="connect-vega-wallet"
|
||||
onClick={openVegaWalletDialog}
|
||||
onClick={() => {
|
||||
onClick?.();
|
||||
openVegaWalletDialog();
|
||||
}}
|
||||
size="small"
|
||||
intent={Intent.None}
|
||||
intent={intent}
|
||||
icon={<VegaIcon name={VegaIconNames.ARROW_RIGHT} size={14} />}
|
||||
>
|
||||
<span className="whitespace-nowrap uppercase">
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
CONSOLE_IMAGE_NAME=vegaprotocol/trading:latest
|
||||
VEGA_VERSION=v0.73.9
|
||||
LOCAL_SERVER=false
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
CONSOLE_IMAGE_NAME=vegaprotocol/trading:main
|
||||
VEGA_VERSION=v0.73.8
|
||||
LOCAL_SERVER=false
|
||||
@@ -24,6 +24,12 @@ 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
|
||||
```
|
||||
@@ -121,11 +127,7 @@ yarn nx serve trading
|
||||
|
||||
```
|
||||
|
||||
Once console is served you can use the flag --local-server
|
||||
|
||||
```bash
|
||||
poetry run pytest -k "test_name" -s --headed --local-server
|
||||
```
|
||||
Once console is served you can update the .env file to have local_server to true.
|
||||
|
||||
## Running Tests in Parallel 🔢
|
||||
|
||||
|
||||
@@ -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,3 +71,4 @@ def selector_contains_text(page: Page, selector, expected_text, timeout=5000):
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
@@ -6,9 +6,10 @@ 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
|
||||
from vega_sim.null_service import VegaServiceNull, Ports
|
||||
from playwright.sync_api import Browser, Page
|
||||
from config import console_image_name, vega_version
|
||||
from datetime import datetime, timedelta
|
||||
@@ -19,7 +20,6 @@ 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,6 +28,8 @@ sys.stdout = sys.stderr
|
||||
docker_client = docker.from_env()
|
||||
logger = logging.getLogger()
|
||||
|
||||
load_dotenv()
|
||||
|
||||
|
||||
@pytest.hookimpl(tryfirst=True)
|
||||
def pytest_runtest_makereport(item, call):
|
||||
@@ -49,16 +51,24 @@ 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"):
|
||||
@@ -70,21 +80,26 @@ def init_vega(request=None):
|
||||
)
|
||||
logger.info(f"Using console image: {console_image_name}")
|
||||
logger.info(f"Using vega version: {vega_version}")
|
||||
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:
|
||||
|
||||
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:
|
||||
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")},
|
||||
@@ -97,23 +112,13 @@ 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: bool):
|
||||
def init_page(vega: VegaServiceNull, browser: Browser, request: pytest.FixtureRequest):
|
||||
local_server = os.getenv("LOCAL_SERVER", "false").lower() == "true"
|
||||
server_port = "4200" if local_server else str(vega.console_port)
|
||||
with browser.new_context(
|
||||
viewport={"width": 1920, "height": 1080},
|
||||
@@ -125,9 +130,7 @@ 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:
|
||||
@@ -172,8 +175,8 @@ def vega(request):
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def page(vega, browser, request, local_server):
|
||||
with init_page(vega, browser, request, local_server) as page_instance:
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page_instance:
|
||||
yield page_instance
|
||||
|
||||
|
||||
|
||||
@@ -245,3 +245,11 @@ 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
|
||||
|
||||
Generated
+2
-2
@@ -1,4 +1,4 @@
|
||||
# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry 1.7.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 = "7ab04931924380db8000544b7f3d65fcb39b5467"
|
||||
resolved_reference = "de30d2d4c7a1b81a830527ca76473e23ef59de12"
|
||||
|
||||
[[package]]
|
||||
name = "websocket-client"
|
||||
|
||||
@@ -56,11 +56,12 @@ 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("page", "continuous_market", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("continuous_market", "auth", "risk_accepted")
|
||||
def test_asset_details(page: Page):
|
||||
page.goto("/#/portfolio")
|
||||
page.locator('[data-testid="tab-collateral"] >> text=tDAI').click()
|
||||
@@ -73,17 +74,22 @@ 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.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from datetime import datetime, timedelta
|
||||
from conftest import init_vega
|
||||
from fixtures.market import setup_continuous_market
|
||||
@@ -14,20 +14,17 @@ 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("page", "auth", "risk_accepted")
|
||||
def test_limit_buy_order_GTT(continuous_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_limit_buy_order_GTT(continuous_market, vega: VegaServiceNull, 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")
|
||||
@@ -54,9 +51,8 @@ def test_limit_buy_order_GTT(continuous_market, vega: VegaService, page: Page):
|
||||
"BTC:DAI_2023Futr10+10LimitFilled120.00GTT:"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
|
||||
def test_limit_buy_order(continuous_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_limit_buy_order(continuous_market, vega: VegaServiceNull, page: Page):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
|
||||
page.get_by_test_id(order_size).fill("10")
|
||||
@@ -72,9 +68,8 @@ def test_limit_buy_order(continuous_market, vega: VegaService, page: Page):
|
||||
"BTC:DAI_2023Futr10+10LimitFilled120.00GTC"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
|
||||
def test_limit_sell_order(continuous_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_limit_sell_order(continuous_market, vega: VegaServiceNull, 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")
|
||||
@@ -97,9 +92,8 @@ def test_limit_sell_order(continuous_market, vega: VegaService, page: Page):
|
||||
"BTC:DAI_2023Futr10-10LimitFilled100.00GFN"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
|
||||
def test_market_sell_order(continuous_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_market_sell_order(continuous_market, vega: VegaServiceNull, 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")
|
||||
@@ -122,9 +116,8 @@ def test_market_sell_order(continuous_market, vega: VegaService, page: Page):
|
||||
"BTC:DAI_2023Futr10-10MarketFilled-IOC"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
|
||||
def test_market_buy_order(continuous_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_market_buy_order(continuous_market, vega: VegaServiceNull, 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("page", "risk_accepted")
|
||||
@pytest.mark.usefixtures("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("page", "risk_accepted")
|
||||
@pytest.mark.usefixtures("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.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
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("page", "vega", "continuous_market", "auth", "risk_accepted")
|
||||
def test_margin_and_fees_estimations(continuous_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_margin_and_fees_estimations(continuous_market, vega: VegaServiceNull, 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.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from actions.vega import submit_order
|
||||
from datetime import datetime, timedelta
|
||||
from conftest import init_vega
|
||||
@@ -38,15 +38,14 @@ timeInForce_col = '[col-id="submission.timeInForce"]'
|
||||
updatedAt_col = '[col-id="updatedAt"]'
|
||||
close_toast = "toast-close"
|
||||
|
||||
|
||||
def create_position(vega: VegaService, market_id):
|
||||
def create_position(vega: VegaServiceNull, 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("page", "continuous_market", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_stop_order_form_error_validation(continuous_market, page: Page):
|
||||
# 7002-SORD-032
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
@@ -69,8 +68,8 @@ def test_stop_order_form_error_validation(continuous_market, page: Page):
|
||||
)
|
||||
|
||||
@pytest.mark.skip("core issue")
|
||||
@pytest.mark.usefixtures("page", "vega", "continuous_market", "auth", "risk_accepted")
|
||||
def test_submit_stop_order_rejected(continuous_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_submit_stop_order_rejected(continuous_market, vega: VegaServiceNull, 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()
|
||||
@@ -107,9 +106,9 @@ def test_submit_stop_order_rejected(continuous_market, vega: VegaService, page:
|
||||
).not_to_be_empty()
|
||||
|
||||
@pytest.mark.skip("core issue")
|
||||
@pytest.mark.usefixtures("page", "vega", "continuous_market", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_submit_stop_market_order_triggered(
|
||||
continuous_market, vega: VegaService, page: Page
|
||||
continuous_market, vega: VegaServiceNull, page: Page
|
||||
):
|
||||
# 7002-SORD-071
|
||||
# 7002-SORD-074
|
||||
@@ -165,9 +164,9 @@ def test_submit_stop_market_order_triggered(
|
||||
).not_to_be_empty()
|
||||
|
||||
@pytest.mark.skip("core issue")
|
||||
@pytest.mark.usefixtures("continuous_market", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_submit_stop_limit_order_pending(
|
||||
continuous_market, vega: VegaService, page: Page
|
||||
continuous_market, vega: VegaServiceNull, page: Page
|
||||
):
|
||||
# 7002-SORD-071
|
||||
# 7002-SORD-074
|
||||
@@ -226,9 +225,9 @@ def test_submit_stop_limit_order_pending(
|
||||
).not_to_be_empty()
|
||||
|
||||
@pytest.mark.skip("core issue")
|
||||
@pytest.mark.usefixtures("continuous_market", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_submit_stop_limit_order_cancel(
|
||||
continuous_market, vega: VegaService, page: Page
|
||||
continuous_market, vega: VegaServiceNull, page: Page
|
||||
):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
page.get_by_test_id(stop_orders_tab).click()
|
||||
@@ -270,7 +269,7 @@ class TestStopOcoValidation:
|
||||
def continuous_market(self, vega):
|
||||
return setup_continuous_market(vega)
|
||||
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_stop_market_order_form_validation(self, continuous_market, page: Page):
|
||||
# 7002-SORD-052
|
||||
# 7002-SORD-055
|
||||
@@ -303,7 +302,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("page", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_stop_limit_order_form_validation(self, continuous_market, page: Page):
|
||||
# 7002-SORD-020
|
||||
# 7002-SORD-021
|
||||
@@ -347,9 +346,9 @@ class TestStopOcoValidation:
|
||||
expect(page.get_by_test_id(order_price)).to_be_empty()
|
||||
|
||||
@pytest.mark.skip("core issue")
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_maximum_number_of_active_stop_orders(
|
||||
self, continuous_market, vega: VegaService, page: Page
|
||||
self, continuous_market, vega: VegaServiceNull, page: Page
|
||||
):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
page.get_by_test_id(stop_orders_tab).click()
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import pytest
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
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"
|
||||
@@ -43,16 +42,16 @@ trigger_price_oco = "triggerPrice-oco"
|
||||
order_size_oco = "order-size-oco"
|
||||
order_limit_price_oco = "order-price-oco"
|
||||
|
||||
def create_position(vega: VegaService, market_id):
|
||||
def create_position(vega: VegaServiceNull, 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("page", "vega", "continuous_market", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_submit_stop_order_market_oco_rejected(
|
||||
continuous_market, vega: VegaService, page: Page
|
||||
continuous_market, vega: VegaServiceNull, page: Page
|
||||
):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
page.get_by_test_id(stop_orders_tab).click()
|
||||
@@ -127,9 +126,9 @@ def test_submit_stop_order_market_oco_rejected(
|
||||
assert trigger_price_list.sort() == trigger_value_list.sort()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "vega", "continuous_market", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_submit_stop_oco_market_order_triggered(
|
||||
continuous_market, vega: VegaService, page: Page
|
||||
continuous_market, vega: VegaServiceNull, page: Page
|
||||
):
|
||||
create_position(vega, continuous_market)
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
@@ -204,9 +203,9 @@ def test_submit_stop_oco_market_order_triggered(
|
||||
assert trigger_price_list.sort() == trigger_value_list.sort()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "vega", "continuous_market", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_submit_stop_oco_market_order_pending(
|
||||
continuous_market, vega: VegaService, page: Page
|
||||
continuous_market, vega: VegaServiceNull, page: Page
|
||||
):
|
||||
create_position(vega, continuous_market)
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
@@ -236,9 +235,9 @@ def test_submit_stop_oco_market_order_pending(
|
||||
"PendingOCO"
|
||||
)
|
||||
|
||||
@pytest.mark.usefixtures("page", "vega", "continuous_market", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("page", "continuous_market", "auth", "risk_accepted")
|
||||
def test_submit_stop_oco_limit_order_pending(
|
||||
continuous_market, vega: VegaService, page: Page
|
||||
continuous_market, vega: VegaServiceNull, page: Page
|
||||
):
|
||||
create_position(vega, continuous_market)
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
@@ -287,9 +286,9 @@ def test_submit_stop_oco_limit_order_pending(
|
||||
assert trigger_price_list.sort() == trigger_value_list.sort()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "vega", "continuous_market", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_submit_stop_oco_limit_order_cancel(
|
||||
continuous_market, vega: VegaService, page: Page
|
||||
continuous_market, vega: VegaServiceNull, page: Page
|
||||
):
|
||||
create_position(vega, continuous_market)
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
@@ -325,5 +324,3 @@ 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,12 +1,10 @@
|
||||
import pytest
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
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"
|
||||
@@ -18,13 +16,12 @@ 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("page", "auth", "risk_accepted")
|
||||
def test_should_display_info_and_button_for_deposit(continuous_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_should_display_info_and_button_for_deposit(continuous_market, 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")
|
||||
@@ -35,8 +32,8 @@ def test_should_display_info_and_button_for_deposit(continuous_market, vega: Veg
|
||||
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("page", "auth", "risk_accepted")
|
||||
def test_should_show_an_error_if_your_balance_is_zero(continuous_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_should_show_an_error_if_your_balance_is_zero(continuous_market, vega: VegaServiceNull, page: Page):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
vega.create_key("key_empty")
|
||||
change_keys(page, vega, "key_empty")
|
||||
|
||||
@@ -0,0 +1,686 @@
|
||||
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"
|
||||
YOUR_TIER_0 = "your-tier-0"
|
||||
YOUR_TIER_1 = "your-tier-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"
|
||||
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-tier-0"),
|
||||
(2, "volume", "my-volume-value-1", "206", "your-tier-1"),
|
||||
(1, "referral", "my-volume-value-0", "103", "your-tier-0"),
|
||||
(2, "referral", "my-volume-value-1", "206", "your-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)).to_be_visible()
|
||||
expect(page.get_by_test_id(your_tier)).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")
|
||||
row = page.locator(ROW_LOCATOR)
|
||||
expect(row.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.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from fixtures.market import setup_simple_market
|
||||
from conftest import init_vega
|
||||
from actions.vega import submit_order
|
||||
@@ -10,21 +10,17 @@ 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: VegaService):
|
||||
def simple_market(vega: VegaServiceNull):
|
||||
return setup_simple_market(vega)
|
||||
|
||||
class TestGetStarted:
|
||||
@pytest.mark.usefixtures("page")
|
||||
def test_get_started_interactive(self, vega: VegaService, page: Page):
|
||||
def test_get_started_interactive(self, vega: VegaServiceNull, page: Page):
|
||||
page.goto("/")
|
||||
# 0007-FUGS-001
|
||||
expect(page.get_by_test_id("order-connect-wallet")).to_be_visible
|
||||
@@ -134,8 +130,7 @@ class TestGetStarted:
|
||||
# Assert dialog isn't visible
|
||||
expect(page.get_by_test_id("welcome-dialog")).not_to_be_visible()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "risk_accepted")
|
||||
@pytest.mark.usefixtures("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")
|
||||
@@ -148,8 +143,6 @@ 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}")
|
||||
@@ -159,14 +152,13 @@ class TestGetStarted:
|
||||
expect(locator).to_be_visible
|
||||
expect(locator).to_have_text("Connect")
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "risk_accepted")
|
||||
@pytest.mark.usefixtures("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("page", "risk_accepted")
|
||||
@pytest.mark.usefixtures("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}")
|
||||
@@ -174,8 +166,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.usefixtures("page")
|
||||
def test_redirect_default_market(self, continuous_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.skip("tbd-market-sim")
|
||||
def test_redirect_default_market(self, continuous_market, vega: VegaServiceNull, page: Page):
|
||||
page.goto("/")
|
||||
# 0007-FUGS-012
|
||||
expect(page).to_have_url(
|
||||
@@ -186,8 +178,7 @@ class TestGetStarted:
|
||||
expect(page.get_by_test_id("welcome-dialog")).not_to_be_visible()
|
||||
|
||||
class TestBrowseAll:
|
||||
@pytest.mark.usefixtures("page")
|
||||
def test_get_started_browse_all(self, simple_market, vega: VegaService, page: Page):
|
||||
def test_get_started_browse_all(self, simple_market, vega: VegaServiceNull, 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.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from actions.vega import submit_order
|
||||
from conftest import init_vega
|
||||
from fixtures.market import setup_continuous_market
|
||||
@@ -11,7 +11,6 @@ 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):
|
||||
@@ -22,8 +21,8 @@ class TestIcebergOrdersValidations:
|
||||
def continuous_market(self, vega):
|
||||
return setup_continuous_market(vega)
|
||||
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
|
||||
def test_iceberg_submit(self, continuous_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_iceberg_submit(self, continuous_market, vega: VegaServiceNull, page: Page):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
page.get_by_test_id("iceberg").click()
|
||||
page.get_by_test_id("order-peak-size").type("2")
|
||||
@@ -47,8 +46,8 @@ class TestIcebergOrdersValidations:
|
||||
(page.get_by_role("row").locator('[col-id="type"]')).nth(1)
|
||||
).to_have_text("Limit (Iceberg)")
|
||||
|
||||
@pytest.mark.usefixtures("vega", "page", "continuous_market", "auth", "risk_accepted")
|
||||
def test_iceberg_open_order(continuous_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_iceberg_open_order(continuous_market, vega: VegaServiceNull, page: Page):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
|
||||
submit_order(vega, "Key 1", continuous_market, "SIDE_SELL", 102, 101, 2, 1)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from conftest import init_vega
|
||||
from fixtures.market import setup_continuous_market
|
||||
from actions.utils import next_epoch, truncate_middle, change_keys
|
||||
@@ -17,27 +17,34 @@ def continuous_market(vega):
|
||||
return setup_continuous_market(vega)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
|
||||
def test_liquidity_provision_amendment(continuous_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_liquidity_provision_amendment(continuous_market, vega: VegaServiceNull, 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",
|
||||
@@ -50,26 +57,32 @@ def test_liquidity_provision_amendment(continuous_market, vega: VegaService, pag
|
||||
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("page", "auth", "risk_accepted")
|
||||
def test_liquidity_provision_inactive(continuous_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_liquidity_provision_inactive(continuous_market, vega: VegaServiceNull, 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"
|
||||
)
|
||||
@@ -82,4 +95,3 @@ def test_liquidity_provision_inactive(continuous_market, vega: VegaService, page
|
||||
)
|
||||
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.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from playwright.sync_api import Page, expect
|
||||
from fixtures.market import setup_continuous_market
|
||||
from conftest import init_vega
|
||||
@@ -12,8 +12,9 @@ def vega():
|
||||
with init_vega() as vega:
|
||||
yield vega
|
||||
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
def create_settled_market(vega: VegaService):
|
||||
def create_settled_market(vega: VegaServiceNull):
|
||||
market_id = setup_continuous_market(vega)
|
||||
vega.submit_termination_and_settlement_data(
|
||||
settlement_key="FJMKnwfZdd48C8NqvYrG",
|
||||
@@ -73,8 +74,9 @@ 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(
|
||||
@@ -87,12 +89,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"
|
||||
# )
|
||||
@@ -107,11 +109,13 @@ 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: VegaService):
|
||||
def test_terminated_market_no_settlement_date(page: Page, vega: VegaServiceNull):
|
||||
setup_continuous_market(vega)
|
||||
print("I have started test_terminated_market_no_settlement_date")
|
||||
governance.submit_oracle_data(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
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.usefixtures("vega", "page", "simple_market", "risk_accepted", "auth")
|
||||
def test_price_monitoring(simple_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.skip("tbd")
|
||||
@pytest.mark.usefixtures("risk_accepted", "auth")
|
||||
def test_price_monitoring(simple_market, vega: VegaServiceNull, 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: VegaService, 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: VegaService, 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,22 +191,32 @@ def test_price_monitoring(simple_market, vega: VegaService, 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("vega", "page", "continuous_market", "risk_accepted", "auth")
|
||||
def test_auction_uncross_fees(continuous_market, vega: VegaService, page: Page):
|
||||
|
||||
@pytest.mark.usefixtures("risk_accepted", "auth")
|
||||
def test_auction_uncross_fees(continuous_market, vega: VegaServiceNull, 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")
|
||||
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")
|
||||
# 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")
|
||||
expect(page.locator(COL_ID_FEE)).to_have_text("0.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")
|
||||
# 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"
|
||||
)
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import re
|
||||
import pytest
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from fixtures.market import setup_continuous_market
|
||||
|
||||
from conftest import init_page, init_vega, risk_accepted_setup
|
||||
|
||||
market_title_test_id = "accordion-title"
|
||||
@@ -15,10 +14,9 @@ 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, local_server):
|
||||
with init_page(vega, browser, request, local_server) as page:
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
setup_continuous_market(vega)
|
||||
risk_accepted_setup(page)
|
||||
page.goto("/")
|
||||
@@ -44,7 +42,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()
|
||||
@@ -56,7 +54,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()
|
||||
@@ -68,7 +66,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()
|
||||
@@ -82,15 +80,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)
|
||||
|
||||
|
||||
def test_market_info_key_details(page: Page, vega: VegaService):
|
||||
@pytest.mark.skip("tbd-market-sim")
|
||||
def test_market_info_key_details(page: Page, vega: VegaServiceNull):
|
||||
# 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")
|
||||
@@ -108,7 +106,7 @@ def test_market_info_key_details(page: Page, vega: VegaService):
|
||||
]
|
||||
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()
|
||||
@@ -122,7 +120,9 @@ def test_market_info_instrument(page: Page):
|
||||
|
||||
|
||||
# @pytest.mark.skip("oracle test to be fixed")
|
||||
def test_market_info_oracle(page: Page, vega: VegaService):
|
||||
|
||||
@pytest.mark.skip("tbd-market-sim")
|
||||
def test_market_info_oracle(page: Page):
|
||||
# 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, vega: VegaService):
|
||||
# "href", re.compile(rf'(\/oracles\/{vega.find_market_id("BTC:DAI_2023")})')
|
||||
# )
|
||||
|
||||
|
||||
def test_market_info_settlement_asset(page: Page, vega: VegaService):
|
||||
@pytest.mark.skip("tbd-market-sim")
|
||||
def test_market_info_settlement_asset(page: Page, vega: VegaServiceNull):
|
||||
# 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: VegaService):
|
||||
]
|
||||
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)
|
||||
|
||||
|
||||
def test_market_info_proposal(page: Page, vega: VegaService):
|
||||
@pytest.mark.skip("tbd-market-sim")
|
||||
def test_market_info_proposal(page: Page, vega: VegaServiceNull):
|
||||
# 6002-MDET-301
|
||||
page.get_by_test_id(market_title_test_id).get_by_text("Proposal").click()
|
||||
first_link = (
|
||||
@@ -280,8 +280,9 @@ def test_market_info_proposal(page: Page, vega: VegaService):
|
||||
"href", re.compile(r"(\/proposals\/propose\/update-market)")
|
||||
)
|
||||
|
||||
|
||||
def test_market_info_succession_line(page: Page, vega: VegaService):
|
||||
|
||||
@pytest.mark.skip("tbd-market-sim")
|
||||
def test_market_info_succession_line(page: Page, vega: VegaServiceNull):
|
||||
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,7 +2,7 @@ import pytest
|
||||
from playwright.sync_api import expect, Page
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "continuous_market", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("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()
|
||||
@@ -27,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("page", "continuous_market", "simple_market", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("simple_market", "auth", "risk_accepted")
|
||||
@pytest.mark.parametrize(
|
||||
"simple_market",
|
||||
[
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
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
|
||||
|
||||
@@ -12,8 +11,8 @@ def vega(request):
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def page(vega, browser, request, local_server):
|
||||
with init_page(vega, browser, request, local_server) as page:
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) 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.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from conftest import init_vega
|
||||
from fixtures.market import setup_simple_market
|
||||
from wallet_config import MM_WALLET, MM_WALLET2, TERMINATE_WALLET, wallets
|
||||
from wallet_config import MM_WALLET
|
||||
|
||||
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,8 +16,9 @@ def vega(request):
|
||||
with init_vega(request) as vega:
|
||||
yield vega
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def proposed_market(vega: VegaService):
|
||||
def proposed_market(vega: VegaServiceNull):
|
||||
# setup market without liquidity provided
|
||||
market_id = setup_simple_market(vega, approve_proposal=False)
|
||||
# approve market
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import pytest
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from actions.vega import submit_order
|
||||
from fixtures.market import setup_simple_market
|
||||
from conftest import init_vega
|
||||
from 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:
|
||||
@@ -17,8 +18,9 @@ def vega(request):
|
||||
def simple_market(vega):
|
||||
return setup_simple_market(vega)
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def setup_market_monitoring_auction(vega: VegaService, simple_market):
|
||||
def setup_market_monitoring_auction(vega: VegaServiceNull, simple_market):
|
||||
vega.submit_liquidity(
|
||||
key_name=MM_WALLET.name,
|
||||
market_id=simple_market,
|
||||
@@ -48,12 +50,18 @@ def setup_market_monitoring_auction(vega: VegaService, 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")
|
||||
@@ -71,9 +79,11 @@ def setup_market_monitoring_auction(vega: VegaService, simple_market):
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
@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):
|
||||
|
||||
|
||||
@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
|
||||
):
|
||||
page.goto(f"/#/markets/{simple_market}")
|
||||
page.get_by_test_id("order-size").clear()
|
||||
page.get_by_test_id("order-size").type("1")
|
||||
@@ -82,10 +92,14 @@ def test_market_monitoring_auction_price_volatility_limit_order(page: Page, simp
|
||||
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)")
|
||||
@@ -103,8 +117,11 @@ def test_market_monitoring_auction_price_volatility_limit_order(page: Page, simp
|
||||
"BTC:DAI_2023Futr0+1LimitActive110.00GTC"
|
||||
)
|
||||
|
||||
@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):
|
||||
|
||||
@pytest.mark.usefixtures("risk_accepted", "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()
|
||||
@@ -112,8 +129,12 @@ def test_market_monitoring_auction_price_volatility_market_order(page: Page, sim
|
||||
# 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.service import VegaService, PeggedOrder
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from vega_sim.service import 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("vega", "page", "proposed_market", "risk_accepted")
|
||||
def test_market_lifecycle(proposed_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
def test_market_lifecycle(proposed_market, vega: VegaServiceNull, page: Page):
|
||||
# 7002-SORD-001
|
||||
# 7002-SORD-002
|
||||
trading_mode = page.get_by_test_id("market-trading-mode").get_by_test_id(
|
||||
@@ -27,8 +27,12 @@ def test_market_lifecycle(proposed_market, vega: VegaService, 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
|
||||
@@ -36,18 +40,30 @@ def test_market_lifecycle(proposed_market, vega: VegaService, 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
|
||||
@@ -182,4 +198,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, local_server):
|
||||
with init_page(vega, browser, request, local_server) as page:
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
yield page
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import pytest
|
||||
import re
|
||||
from playwright.sync_api import expect, Page
|
||||
from vega_sim.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from actions.vega import submit_order
|
||||
|
||||
order_details = [
|
||||
@@ -48,10 +48,11 @@ def verify_order_value(
|
||||
else:
|
||||
expect(element).to_have_text(expected_text)
|
||||
|
||||
|
||||
@pytest.mark.skip("tbd")
|
||||
@pytest.mark.usefixtures("vega", "page", "continuous_market", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_order_details_are_correctly_displayed(
|
||||
continuous_market, vega: VegaService, page: Page
|
||||
continuous_market, vega: VegaServiceNull, 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,12 +2,13 @@ import pytest
|
||||
import re
|
||||
import logging
|
||||
from playwright.sync_api import expect, Page
|
||||
from vega_sim.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
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()
|
||||
@@ -37,7 +38,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: VegaService, wallet_name, market_id, side, volume, price):
|
||||
def submit_order(vega: VegaServiceNull, wallet_name, market_id, side, volume, price):
|
||||
vega.submit_order(
|
||||
trading_key=wallet_name,
|
||||
market_id=market_id,
|
||||
@@ -49,11 +50,9 @@ def submit_order(vega: VegaService, wallet_name, market_id, side, volume, price)
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures(
|
||||
"vega", "page", "opening_auction_market", "auth", "risk_accepted"
|
||||
)
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_limit_order_trade_open_order(
|
||||
opening_auction_market, vega: VegaService, page: Page
|
||||
opening_auction_market, vega: VegaServiceNull, page: Page
|
||||
):
|
||||
market_id = opening_auction_market
|
||||
submit_order(vega, "Key 1", market_id, "SIDE_BUY", 1, 110)
|
||||
@@ -80,7 +79,7 @@ def test_limit_order_trade_open_order(
|
||||
verify_data_grid(page, "Open", expected_open_order)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("vega", "page", "continuous_market", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_limit_order_trade_open_position(continuous_market, page: Page):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
|
||||
@@ -148,7 +147,7 @@ def test_limit_order_trade_open_position(continuous_market, page: Page):
|
||||
expect(unrealisedPNL).to_have_text(position["unrealised_pnl"])
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("vega", "page", "continuous_market", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("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
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import pytest
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.service import VegaService, PeggedOrder
|
||||
from vega_sim.service import PeggedOrder
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from conftest import auth_setup, init_page, init_vega, risk_accepted_setup
|
||||
from fixtures.market import setup_continuous_market, setup_simple_market
|
||||
from actions.utils import wait_for_toast_confirmation
|
||||
@@ -15,7 +16,7 @@ def vega(request):
|
||||
|
||||
|
||||
@pytest.fixture(scope="module", autouse=True)
|
||||
def markets(vega: VegaService):
|
||||
def markets(vega: VegaServiceNull):
|
||||
market_1 = setup_continuous_market(
|
||||
vega,
|
||||
custom_market_name="market-1",
|
||||
@@ -223,8 +224,8 @@ def markets(vega: VegaService):
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def page(vega, browser, request, local_server):
|
||||
with init_page(vega, browser, request, local_server) as page:
|
||||
def page(vega, browser, request):
|
||||
with init_page(vega, browser, request) as page:
|
||||
risk_accepted_setup(page)
|
||||
auth_setup(vega, page)
|
||||
page.goto("/")
|
||||
@@ -357,7 +358,7 @@ def test_order_status_pegged_mid(page: Page):
|
||||
)
|
||||
|
||||
|
||||
def test_order_amend_order(vega: VegaService, page: Page):
|
||||
def test_order_amend_order(vega: VegaServiceNull, page: Page):
|
||||
# 7002-SORD-053
|
||||
# 7003-MORD-012
|
||||
# 7003-MORD-014
|
||||
@@ -377,7 +378,7 @@ def test_order_amend_order(vega: VegaService, page: Page):
|
||||
)
|
||||
|
||||
|
||||
def test_order_cancel_single_order(vega: VegaService, page: Page):
|
||||
def test_order_cancel_single_order(vega: VegaServiceNull, page: Page):
|
||||
# 7003-MORD-009
|
||||
# 7003-MORD-010
|
||||
# 7003-MORD-011
|
||||
@@ -394,7 +395,7 @@ def test_order_cancel_single_order(vega: VegaService, page: Page):
|
||||
)
|
||||
|
||||
|
||||
def test_order_cancel_all_orders(vega: VegaService, page: Page):
|
||||
def test_order_cancel_all_orders(vega: VegaServiceNull, page: Page):
|
||||
# 7003-MORD-009
|
||||
# 7003-MORD-010
|
||||
# 7003-MORD-011
|
||||
|
||||
@@ -6,6 +6,7 @@ from conftest import init_vega
|
||||
from fixtures.market import setup_simple_market
|
||||
from wallet_config import MM_WALLET, MM_WALLET2
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vega():
|
||||
with init_vega() as vega:
|
||||
@@ -78,8 +79,9 @@ def verify_prices_descending(page: Page):
|
||||
prices = [float(price.text_content()) for price in prices_locator.all()]
|
||||
assert prices == sorted(prices, reverse=True)
|
||||
|
||||
|
||||
@pytest.mark.skip("tbd")
|
||||
@pytest.mark.usefixtures("page", "risk_accepted")
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
def test_orderbook_grid_content(setup_market, page: Page):
|
||||
vega = setup_market[0]
|
||||
market_id = setup_market[1]
|
||||
@@ -138,7 +140,7 @@ def test_orderbook_grid_content(setup_market, page: Page):
|
||||
verify_prices_descending(page)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "risk_accepted")
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
def test_orderbook_resolution_change(setup_market, page: Page):
|
||||
market_id = setup_market[1]
|
||||
# 6003-ORDB-008
|
||||
@@ -188,7 +190,7 @@ def test_orderbook_resolution_change(setup_market, page: Page):
|
||||
# verify_orderbook_grid(page, resolution[1])
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "risk_accepted")
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
def test_orderbook_price_size_copy(setup_market, page: Page):
|
||||
market_id = setup_market[1]
|
||||
# 6003-ORDB-009
|
||||
@@ -206,8 +208,9 @@ def test_orderbook_price_size_copy(setup_market, page: Page):
|
||||
volume.click()
|
||||
expect(page.get_by_test_id("order-size")).to_have_value(volume.text_content())
|
||||
|
||||
|
||||
@pytest.mark.skip("tbd")
|
||||
@pytest.mark.usefixtures("page", "risk_accepted")
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
def test_orderbook_price_movement(setup_market, page: Page):
|
||||
vega = setup_market[0]
|
||||
market_id = setup_market[1]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import pytest
|
||||
import re
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from vega_sim.service import MarketStateUpdateType
|
||||
from datetime import datetime, timedelta
|
||||
from conftest import init_vega
|
||||
@@ -13,15 +13,15 @@ from wallet_config import MM_WALLET, MM_WALLET2, TERMINATE_WALLET
|
||||
row_selector = '[data-testid="tab-funding-payments"] .ag-center-cols-container .ag-row'
|
||||
col_amount = '[col-id="amount"]'
|
||||
|
||||
class TestPerpetuals:
|
||||
|
||||
class TestPerpetuals:
|
||||
@pytest.fixture(scope="class")
|
||||
def vega(self, request):
|
||||
with init_vega(request) as vega:
|
||||
yield vega
|
||||
|
||||
@pytest.fixture(scope="class")
|
||||
def perps_market(self, vega: VegaService):
|
||||
def perps_market(self, vega: VegaServiceNull):
|
||||
perps_market = setup_perps_market(vega)
|
||||
submit_multiple_orders(
|
||||
vega, MM_WALLET.name, perps_market, "SIDE_SELL", [[1, 110], [1, 105]]
|
||||
@@ -53,31 +53,33 @@ class TestPerpetuals:
|
||||
vega.wait_for_total_catchup()
|
||||
return perps_market
|
||||
|
||||
@pytest.mark.usefixtures("page","risk_accepted", "auth")
|
||||
@pytest.mark.usefixtures("risk_accepted", "auth")
|
||||
def test_funding_payment_profit(self, perps_market, page: Page):
|
||||
page.goto(f"/#/markets/{perps_market}")
|
||||
page.goto(f"/#/markets/{perps_market}")
|
||||
page.get_by_test_id("Funding payments").click()
|
||||
row = page.locator(row_selector)
|
||||
expect(row.locator(col_amount)).to_have_text("9.00 tDAI")
|
||||
|
||||
@pytest.mark.usefixtures("page","risk_accepted", "auth")
|
||||
@pytest.mark.usefixtures("risk_accepted", "auth")
|
||||
def test_funding_payment_loss(self, perps_market, page: Page, vega):
|
||||
page.goto(f"/#/markets/{perps_market}")
|
||||
page.goto(f"/#/markets/{perps_market}")
|
||||
change_keys(page, vega, "market_maker")
|
||||
page.get_by_test_id("Funding payments").click()
|
||||
row = page.locator(row_selector)
|
||||
expect(row.locator(col_amount)).to_have_text("-27.00 tDAI")
|
||||
|
||||
@pytest.mark.usefixtures("page","risk_accepted", "auth")
|
||||
|
||||
@pytest.mark.usefixtures("risk_accepted", "auth")
|
||||
def test_funding_header(self, perps_market, page: Page):
|
||||
page.goto(f"/#/markets/{perps_market}")
|
||||
expect(page.get_by_test_id("market-funding")).to_contain_text("Funding Rate / Countdown-8.1818%")
|
||||
expect(page.get_by_test_id("market-funding")).to_contain_text(
|
||||
"Funding Rate / Countdown-8.1818%"
|
||||
)
|
||||
expect(page.get_by_test_id("index-price")).to_have_text("Index Price110.00")
|
||||
|
||||
@pytest.mark.skip("Skipped due to issue #5421")
|
||||
@pytest.mark.usefixtures("page","risk_accepted", "auth")
|
||||
@pytest.mark.usefixtures("risk_accepted", "auth")
|
||||
def test_funding_payment_history(perps_market, page: Page, vega):
|
||||
page.goto(f"/#/markets/{perps_market}")
|
||||
page.goto(f"/#/markets/{perps_market}")
|
||||
change_keys(page, vega, "market_maker")
|
||||
page.get_by_test_id("Funding history").click()
|
||||
element = page.get_by_test_id("tab-funding-history")
|
||||
@@ -92,52 +94,66 @@ class TestPerpetuals:
|
||||
else:
|
||||
print("Bounding box not found for the element")
|
||||
|
||||
@pytest.mark.usefixtures("page","risk_accepted", "auth")
|
||||
def test_perps_market_termination_proposed(page: Page, vega: VegaService):
|
||||
|
||||
@pytest.mark.usefixtures("risk_accepted", "auth")
|
||||
def test_perps_market_termination_proposed(page: Page, vega: VegaServiceNull):
|
||||
perpetual_market = setup_perps_market(vega)
|
||||
page.goto(f"/#/markets/{perpetual_market}")
|
||||
page.goto(f"/#/markets/{perpetual_market}")
|
||||
vega.update_market_state(
|
||||
proposal_key=MM_WALLET.name,
|
||||
market_id=perpetual_market,
|
||||
market_state=MarketStateUpdateType.Terminate,
|
||||
price=100,
|
||||
vote_closing_time = datetime.now() + timedelta(seconds=15),
|
||||
vote_enactment_time = datetime.now() + timedelta(seconds=60),
|
||||
approve_proposal = True,
|
||||
forward_time_to_enactment = False,
|
||||
vote_closing_time=datetime.now() + timedelta(seconds=15),
|
||||
vote_enactment_time=datetime.now() + timedelta(seconds=60),
|
||||
approve_proposal=True,
|
||||
forward_time_to_enactment=False,
|
||||
)
|
||||
vega.forward("10s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
banner_text = page.get_by_test_id(f"termination-warning-banner-{perpetual_market}").text_content()
|
||||
banner_text = page.get_by_test_id(
|
||||
f"termination-warning-banner-{perpetual_market}"
|
||||
).text_content()
|
||||
pattern = re.compile(
|
||||
r"Trading on Market BTC:DAI_Perpetual may stop on \d{2} [A-Za-z]+\. There is open proposal to close this market\.Proposed final price is 100\.00 BTC\.View proposal"
|
||||
r"Trading on Market BTC:DAI_Perpetual may stop on \d{2} [A-Za-z]+\. There is open proposal to close this market\.Proposed final price is 100\.00 BTC\.View proposal"
|
||||
)
|
||||
assert pattern.search(banner_text), f"Text did not match pattern. Text was: {banner_text}"
|
||||
assert pattern.search(
|
||||
banner_text
|
||||
), f"Text did not match pattern. Text was: {banner_text}"
|
||||
|
||||
@pytest.mark.usefixtures("page","risk_accepted", "auth" )
|
||||
def test_perps_market_terminated(page: Page, vega: VegaService):
|
||||
|
||||
@pytest.mark.usefixtures("risk_accepted", "auth")
|
||||
def test_perps_market_terminated(page: Page, vega: VegaServiceNull):
|
||||
perpetual_market = setup_perps_market(vega)
|
||||
vega.update_market_state(
|
||||
proposal_key=MM_WALLET.name,
|
||||
market_id=perpetual_market,
|
||||
market_state=MarketStateUpdateType.Terminate,
|
||||
price=100,
|
||||
approve_proposal = True,
|
||||
forward_time_to_enactment = True,
|
||||
approve_proposal=True,
|
||||
forward_time_to_enactment=True,
|
||||
)
|
||||
vega.forward("10s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
page.goto(f"/#/markets/{perpetual_market}")
|
||||
# TODO cahnge back to have text once bug #5465 is fixed
|
||||
page.goto(f"/#/markets/{perpetual_market}")
|
||||
# TODO change back to have text once bug #5465 is fixed
|
||||
expect(page.get_by_test_id("market-price")).to_have_text("Mark Price100.00")
|
||||
expect(page.get_by_test_id("market-change")).to_contain_text("Change (24h)")
|
||||
expect(page.get_by_test_id("market-volume")).to_contain_text("Volume (24h)")
|
||||
expect(page.get_by_test_id("market-trading-mode")).to_have_text("Trading modeNo trading")
|
||||
expect(page.get_by_test_id("market-trading-mode")).to_have_text(
|
||||
"Trading modeNo trading"
|
||||
)
|
||||
expect(page.get_by_test_id("market-state")).to_have_text("StatusClosed")
|
||||
expect(page.get_by_test_id("liquidity-supplied")).to_have_text("Liquidity supplied 0.00 (0.00%)")
|
||||
expect(page.get_by_test_id("market-funding")).to_contain_text("Funding Rate / Countdown")
|
||||
expect(page.get_by_test_id("liquidity-supplied")).to_have_text(
|
||||
"Liquidity supplied 0.00 (0.00%)"
|
||||
)
|
||||
expect(page.get_by_test_id("market-funding")).to_contain_text(
|
||||
"Funding Rate / Countdown"
|
||||
)
|
||||
expect(page.get_by_test_id("index-price")).to_contain_text("Index Price")
|
||||
expect(page.get_by_test_id("deal-ticket-error-message-summary")).to_have_text("This market is closed and not accepting orders")
|
||||
expect(page.get_by_test_id("deal-ticket-error-message-summary")).to_have_text(
|
||||
"This market is closed and not accepting orders"
|
||||
)
|
||||
|
||||
@@ -1,17 +1,19 @@
|
||||
import pytest
|
||||
from playwright.sync_api import Page
|
||||
from vega_sim.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from actions.vega import submit_order
|
||||
from actions.utils import change_keys
|
||||
|
||||
|
||||
def check_pnl_color_value(element, expected_color, expected_value):
|
||||
color = element.evaluate("element => getComputedStyle(element).color")
|
||||
value = element.inner_text()
|
||||
assert color == expected_color, f"Unexpected color: {color}"
|
||||
assert value == expected_value, f"Unexpected value: {value}"
|
||||
|
||||
@pytest.mark.usefixtures("vega", "page", "continuous_market", "auth", "risk_accepted")
|
||||
def test_pnl(continuous_market, vega: VegaService, page: Page):
|
||||
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_pnl(continuous_market, vega: VegaServiceNull, page: Page):
|
||||
page.set_viewport_size({"width": 1748, "height": 977})
|
||||
submit_order(vega, "Key 1", continuous_market, "SIDE_BUY", 1, 104.50000)
|
||||
vega.wait_fn(1)
|
||||
@@ -59,9 +61,13 @@ def test_pnl(continuous_market, vega: VegaService, page: Page):
|
||||
|
||||
key_1_unrealised_pnl = key_1.query_selector('xpath=./div[@col-id="unrealisedPNL"]')
|
||||
key_1_realised_pnl = key_1.query_selector('xpath=./div[@col-id="realisedPNL"]')
|
||||
key_mm_unrealised_pnl = key_mm.query_selector('xpath=./div[@col-id="unrealisedPNL"]')
|
||||
key_mm_unrealised_pnl = key_mm.query_selector(
|
||||
'xpath=./div[@col-id="unrealisedPNL"]'
|
||||
)
|
||||
key_mm_realised_pnl = key_mm.query_selector('xpath=./div[@col-id="realisedPNL"]')
|
||||
key_mm2_unrealised_pnl = key_mm2.query_selector('xpath=./div[@col-id="unrealisedPNL"]')
|
||||
key_mm2_unrealised_pnl = key_mm2.query_selector(
|
||||
'xpath=./div[@col-id="unrealisedPNL"]'
|
||||
)
|
||||
key_mm2_realised_pnl = key_mm2.query_selector('xpath=./div[@col-id="realisedPNL"]')
|
||||
check_pnl_color_value(key_1_realised_pnl, "rgb(0, 0, 0)", "0.00")
|
||||
check_pnl_color_value(key_1_unrealised_pnl, "rgb(236, 0, 60)", "-4.00")
|
||||
|
||||
@@ -2,30 +2,31 @@ import os
|
||||
import pytest
|
||||
from playwright.sync_api import Page, expect
|
||||
|
||||
from actions.utils import wait_for_toast_confirmation
|
||||
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted", "continuous_market")
|
||||
#TODO migrate to jest
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted", "continuous_market")
|
||||
def test_ledger_entries_downloads(page: Page):
|
||||
page.goto("/#/portfolio")
|
||||
page.get_by_test_id("Ledger entries").click()
|
||||
expect(page.get_by_test_id("ledger-download-button")).to_be_enabled()
|
||||
# 7007-LEEN-001
|
||||
page.get_by_test_id("ledger-download-button").click()
|
||||
#7007-LEEN-009
|
||||
# 7007-LEEN-009
|
||||
expect(page.get_by_test_id("toast-content")).to_contain_text(("Your file is ready"))
|
||||
# Get the user's Downloads directory
|
||||
downloads_directory = os.path.expanduser("~") + "/Downloads/"
|
||||
# Start waiting for the download
|
||||
with page.expect_download() as download_info:
|
||||
# Perform the action that initiates download
|
||||
# Perform the action that initiates download
|
||||
page.get_by_role("link", name="Get file here").click()
|
||||
|
||||
|
||||
download = download_info.value
|
||||
# Wait for the download process to complete and save the downloaded file in the Downloads directory
|
||||
download.save_as(os.path.join(downloads_directory, download.suggested_filename))
|
||||
|
||||
# Verify the download by asserting that the file exists
|
||||
downloaded_file_path = os.path.join(downloads_directory, download.suggested_filename)
|
||||
assert os.path.exists(downloaded_file_path), f"Download failed! File not found at: {downloaded_file_path}"
|
||||
|
||||
downloaded_file_path = os.path.join(
|
||||
downloads_directory, download.suggested_filename
|
||||
)
|
||||
assert os.path.exists(
|
||||
downloaded_file_path
|
||||
), f"Download failed! File not found at: {downloaded_file_path}"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from conftest import init_vega
|
||||
from fixtures.market import setup_continuous_market
|
||||
|
||||
@@ -8,44 +8,60 @@ TOOLTIP_LABEL = "margin-health-tooltip-label"
|
||||
TOOLTIP_VALUE = "margin-health-tooltip-value"
|
||||
COL_ID_USED = ".ag-center-cols-container [col-id='used'] .ag-cell-value"
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
with init_vega(request) as vega:
|
||||
yield vega
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def continuous_market(vega: VegaService):
|
||||
def continuous_market(vega: VegaServiceNull):
|
||||
return setup_continuous_market(vega)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_usage_breakdown(continuous_market, page: Page):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
page.get_by_test_id("Collateral").click()
|
||||
page.locator(".ag-floating-top-container .ag-row [col-id='used']").click()
|
||||
usage_breakdown = page.get_by_test_id('usage-breakdown')
|
||||
usage_breakdown = page.get_by_test_id("usage-breakdown")
|
||||
|
||||
# Verify headers
|
||||
headers = ['Market', 'Account type', 'Balance', 'Margin health']
|
||||
ag_headers = usage_breakdown.locator('.ag-header-cell-text').element_handles()
|
||||
headers = ["Market", "Account type", "Balance", "Margin health"]
|
||||
ag_headers = usage_breakdown.locator(".ag-header-cell-text").element_handles()
|
||||
for i, header_element in enumerate(ag_headers):
|
||||
header_text = header_element.text_content()
|
||||
assert header_text == headers[i]
|
||||
|
||||
# Other expectations
|
||||
expect(usage_breakdown.locator('[class="mb-2 text-sm"]')).to_have_text("You have 1,000,000.00 tDAI in total.")
|
||||
expect(usage_breakdown.locator('[class="mb-2 text-sm"]')).to_have_text(
|
||||
"You have 1,000,000.00 tDAI in total."
|
||||
)
|
||||
expect(usage_breakdown.locator(COL_ID_USED).first).to_have_text("8.50269 (0%)")
|
||||
expect(usage_breakdown.locator(COL_ID_USED).nth(1)).to_have_text("999,991.49731 (99%)")
|
||||
expect(usage_breakdown.locator(COL_ID_USED).nth(1)).to_have_text(
|
||||
"999,991.49731 (99%)"
|
||||
)
|
||||
|
||||
# Maintenance Level
|
||||
expect(usage_breakdown.locator(".ag-center-cols-container [col-id='market.id'] .ag-cell-value").first).to_have_text("2.85556 above maintenance level")
|
||||
expect(
|
||||
usage_breakdown.locator(
|
||||
".ag-center-cols-container [col-id='market.id'] .ag-cell-value"
|
||||
).first
|
||||
).to_have_text("2.85556 above maintenance level")
|
||||
|
||||
# Margin health tooltip
|
||||
usage_breakdown.get_by_test_id("margin-health-chart-track").hover()
|
||||
tooltip_data = [("maintenance level", "5.64713"), ("search level", "6.21184"), ("initial level", "8.47069"), ("balance", "8.50269"), ("release level", "9.60012")]
|
||||
tooltip_data = [
|
||||
("maintenance level", "5.64713"),
|
||||
("search level", "6.21184"),
|
||||
("initial level", "8.47069"),
|
||||
("balance", "8.50269"),
|
||||
("release level", "9.60012"),
|
||||
]
|
||||
|
||||
for index, (label, value) in enumerate(tooltip_data):
|
||||
expect(page.get_by_test_id(TOOLTIP_LABEL).nth(index)).to_have_text(label)
|
||||
expect(page.get_by_test_id(TOOLTIP_VALUE).nth(index)).to_have_text(value)
|
||||
|
||||
|
||||
page.get_by_test_id('dialog-close').click()
|
||||
page.get_by_test_id("dialog-close").click()
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import pytest
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from fixtures.market import (
|
||||
setup_continuous_market,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_closed_market_position(vega: VegaService, page: Page):
|
||||
def test_closed_market_position(vega: VegaServiceNull, page: Page):
|
||||
market_id = setup_continuous_market(vega)
|
||||
|
||||
vega.submit_termination_and_settlement_data(
|
||||
@@ -26,4 +27,3 @@ def test_closed_market_position(vega: VegaService, page: Page):
|
||||
expect(market.get_by_test_id("stack-cell-primary")).to_have_text("BTC:DAI_2023")
|
||||
page.get_by_test_id("open-transfer").click()
|
||||
expect(page.locator(".ag-overlay-panel")).to_have_text("No positions")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import pytest
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.service import VegaService
|
||||
from playwright.sync_api import Page
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from conftest import init_vega
|
||||
from fixtures.market import setup_continuous_market, setup_simple_market
|
||||
from actions.utils import change_keys, create_and_faucet_wallet, forward_time, selector_contains_text
|
||||
@@ -72,7 +72,7 @@ def create_staking_tier(minimum_staked_tokens, referral_reward_multiplier):
|
||||
}
|
||||
|
||||
|
||||
def setup_market_and_referral_scheme(vega: VegaService, continuous_market: str, page: Page):
|
||||
def setup_market_and_referral_scheme(vega: VegaServiceNull, continuous_market: str, page: Page):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
|
||||
create_and_faucet_wallet(vega=vega, wallet=PARTY_A)
|
||||
@@ -118,7 +118,7 @@ def setup_market_and_referral_scheme(vega: VegaService, continuous_market: str,
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
|
||||
def test_can_traverse_up_and_down_through_tiers(continuous_market, vega: VegaService, page: Page):
|
||||
def test_can_traverse_up_and_down_through_tiers(continuous_market, vega: VegaServiceNull, page: Page):
|
||||
setup_market_and_referral_scheme(vega, continuous_market, page)
|
||||
change_keys(page, vega, PARTY_B.name)
|
||||
submit_order(vega, PARTY_B.name, continuous_market, "SIDE_BUY", 1, 115)
|
||||
@@ -162,7 +162,7 @@ def test_can_traverse_up_and_down_through_tiers(continuous_market, vega: VegaSer
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
|
||||
def test_does_not_move_up_tiers_when_not_enough_epochs(continuous_market, vega: VegaService, page: Page):
|
||||
def test_does_not_move_up_tiers_when_not_enough_epochs(continuous_market, vega: VegaServiceNull, page: Page):
|
||||
setup_market_and_referral_scheme(vega, continuous_market, page)
|
||||
change_keys(page, vega, PARTY_B.name)
|
||||
submit_order(vega, PARTY_B.name, continuous_market, "SIDE_BUY", 2, 115)
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import pytest
|
||||
from playwright.sync_api import expect, Page
|
||||
|
||||
settings_icon = "icon-cog"
|
||||
settings_column_btn = "popover-trigger"
|
||||
settings_close_btn = "settings-close"
|
||||
split_view_view = "split-view-view"
|
||||
|
||||
@pytest.mark.usefixtures("page", "continuous_market", "auth", "risk_accepted")
|
||||
def test_column_settings_is_visible(continuous_market, page: Page):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
expect(page.get_by_test_id(split_view_view).get_by_test_id(settings_column_btn)).to_be_visible()
|
||||
page.goto("/#/portfolio")
|
||||
expect(page.get_by_test_id(split_view_view).get_by_test_id(settings_column_btn).nth(0)).to_be_visible()
|
||||
expect(page.get_by_test_id(split_view_view).get_by_test_id(settings_column_btn).nth(1)).to_be_visible()
|
||||
page.goto(f"/#/markets/all")
|
||||
expect(page.get_by_test_id(settings_column_btn)).to_be_visible()
|
||||
page.click('[data-testid="Proposed markets"]')
|
||||
expect(page.get_by_test_id(settings_column_btn)).to_be_visible()
|
||||
page.click('[data-testid="Closed markets"]')
|
||||
expect(page.get_by_test_id(settings_column_btn)).to_be_visible()
|
||||
|
||||
@pytest.mark.usefixtures("page", "continuous_market", "auth", "risk_accepted")
|
||||
def test_can_reset_columns_state(continuous_market, page: Page):
|
||||
page.goto(f"/#/markets/all")
|
||||
col_market = page.locator('[col-id="tradableInstrument.instrument.code"]').first
|
||||
col_settlement_asset = page.locator('[col-id="tradableInstrument.instrument.product.settlementAsset.symbol"]').first
|
||||
col_market.drag_to(col_settlement_asset)
|
||||
|
||||
# Check the attribute of the dragged element
|
||||
attribute_value = col_market.get_attribute("aria-colindex")
|
||||
assert attribute_value != "1"
|
||||
page.get_by_test_id(settings_column_btn).click()
|
||||
page.get_by_role("button", name="Reset Columns").click()
|
||||
attribute_value_after_reset = col_market.get_attribute("aria-colindex")
|
||||
assert attribute_value_after_reset == "1"
|
||||
@@ -9,10 +9,9 @@ def vega():
|
||||
yield vega
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "risk_accepted")
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
def test_share_usage_data(page: Page):
|
||||
page.goto("/")
|
||||
# page.get_by_test_id("icon-cross").click()
|
||||
page.get_by_test_id("Settings").click()
|
||||
telemetry_switch = page.locator("#switch-settings-telemetry-switch")
|
||||
expect(telemetry_switch).to_have_attribute("data-state", "unchecked")
|
||||
@@ -41,7 +40,7 @@ ICON_TO_TOAST = {
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "risk_accepted")
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
def test_toast_positions(page: Page):
|
||||
page.goto("/")
|
||||
page.get_by_test_id("Settings").click()
|
||||
@@ -52,7 +51,7 @@ def test_toast_positions(page: Page):
|
||||
expect(page.locator(f"[{toast_selector}]")).to_be_visible()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "risk_accepted")
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
def test_dark_mode(page: Page):
|
||||
page.goto("/")
|
||||
page.get_by_test_id("Settings").click()
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import pytest
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from fixtures.market import setup_continuous_market, setup_simple_successor_market
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@pytest.mark.usefixtures("vega")
|
||||
def successor_market(vega: VegaService):
|
||||
@pytest.mark.usefixtures()
|
||||
def successor_market(vega: VegaServiceNull):
|
||||
parent_market_id = setup_continuous_market(vega)
|
||||
tdai_id = vega.find_asset_id(symbol="tDAI")
|
||||
successor_market_id = setup_simple_successor_market(
|
||||
@@ -22,9 +22,8 @@ def successor_market(vega: VegaService):
|
||||
vega.wait_for_total_catchup()
|
||||
return successor_market_id
|
||||
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "risk_accepted")
|
||||
@pytest.mark.skip("tbd")
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
def test_succession_line(page: Page, successor_market):
|
||||
page.goto(f"/#/markets/{successor_market}")
|
||||
page.get_by_test_id("Info").click()
|
||||
|
||||
@@ -5,7 +5,7 @@ from playwright.sync_api import expect
|
||||
from actions.vega import submit_order
|
||||
from conftest import init_vega
|
||||
from playwright.sync_api import Page
|
||||
from vega_sim.null_service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
|
||||
logger = logging.getLogger()
|
||||
|
||||
@@ -45,8 +45,10 @@ def verify_data_grid(page: Page, data_test_id, expected_pattern):
|
||||
raise AssertionError(f"Pattern does not match: {expected} != {actual}")
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "continuous_market", "auth", "risk_accepted")
|
||||
def test_limit_order_new_trade_top_of_list(continuous_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_limit_order_new_trade_top_of_list(
|
||||
continuous_market, vega: VegaServiceNull, page: Page
|
||||
):
|
||||
submit_order(vega, "Key 1", continuous_market, "SIDE_BUY", 1, 110)
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
@@ -67,7 +69,7 @@ def test_limit_order_new_trade_top_of_list(continuous_market, vega: VegaService,
|
||||
verify_data_grid(page, "Trades", expected_trade)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "continuous_market", "auth", "risk_accepted")
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_price_copied_to_deal_ticket(continuous_market, page: Page):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
page.get_by_test_id("Trades").click()
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import pytest
|
||||
from playwright.sync_api import expect, Page
|
||||
from vega_sim.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
|
||||
from actions.vega import submit_multiple_orders
|
||||
|
||||
|
||||
@pytest.mark.skip("tbd")
|
||||
@pytest.mark.usefixtures(
|
||||
"page", "vega", "opening_auction_market", "auth", "risk_accepted"
|
||||
)
|
||||
def test_trade_match_table(opening_auction_market: str, vega: VegaService, page: Page):
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_trade_match_table(opening_auction_market: str, vega: VegaServiceNull, page: Page):
|
||||
row_locator = ".ag-center-cols-container .ag-row"
|
||||
page.goto(f"/#/markets/{opening_auction_market}")
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# import re
|
||||
# from collections import namedtuple
|
||||
# from playwright.sync_api import Page
|
||||
# from vega_sim.service import VegaService
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
# from actions.vega import submit_order
|
||||
|
||||
# import logging
|
||||
@@ -12,9 +12,9 @@
|
||||
# InfoItem = namedtuple('InfoItem', ['name', 'infoText'])
|
||||
|
||||
# @pytest.mark.skip("temporary skip")
|
||||
# @pytest.mark.parametrize("vega", [120], indirect=True)
|
||||
# @pytest.mark.parametrize(, [120], indirect=True)
|
||||
# @pytest.mark.usefixtures("continuous_market","risk_accepted", "auth")
|
||||
# def test_trading_chart(continuous_market, vega: VegaService, page: Page):
|
||||
# def test_trading_chart(continuous_market, vega: VegaServiceNull, page: Page):
|
||||
# page.goto(f"/#/markets/{continuous_market}")
|
||||
# vega.forward("24h")
|
||||
# vega.wait_for_total_catchup()
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import pytest
|
||||
import re
|
||||
from playwright.sync_api import Page, expect
|
||||
from vega_sim.service import VegaService
|
||||
from actions.utils import wait_for_toast_confirmation, create_and_faucet_wallet, WalletConfig, next_epoch, change_keys
|
||||
from vega_sim.null_service import VegaServiceNull
|
||||
from actions.utils import (
|
||||
wait_for_toast_confirmation,
|
||||
create_and_faucet_wallet,
|
||||
WalletConfig,
|
||||
next_epoch,
|
||||
change_keys,
|
||||
)
|
||||
import vega_sim.proto.vega as vega_protos
|
||||
|
||||
LIQ = WalletConfig("liq", "liq")
|
||||
@@ -10,8 +16,9 @@ PARTY_A = WalletConfig("party_a", "party_a")
|
||||
PARTY_B = WalletConfig("party_b", "party_b")
|
||||
PARTY_C = WalletConfig("party_c", "party_c")
|
||||
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
|
||||
def test_transfer_submit(continuous_market, vega: VegaService, page: Page):
|
||||
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_transfer_submit(continuous_market, vega: VegaServiceNull, page: Page):
|
||||
# 1003-TRAN-001
|
||||
# 1003-TRAN-006
|
||||
# 1003-TRAN-007
|
||||
@@ -19,38 +26,50 @@ def test_transfer_submit(continuous_market, vega: VegaService, page: Page):
|
||||
# 1003-TRAN-009
|
||||
# 1003-TRAN-010
|
||||
# 1003-TRAN-023
|
||||
page.goto('/#/portfolio')
|
||||
page.goto("/#/portfolio")
|
||||
|
||||
expect(page.get_by_test_id('transfer-form')).to_be_visible
|
||||
page.get_by_test_id('select-asset').click()
|
||||
expect(page.get_by_test_id('rich-select-option')).to_have_count(1)
|
||||
expect(page.get_by_test_id("transfer-form")).to_be_visible
|
||||
page.get_by_test_id("select-asset").click()
|
||||
expect(page.get_by_test_id("rich-select-option")).to_have_count(1)
|
||||
|
||||
page.get_by_test_id('rich-select-option').click()
|
||||
page.get_by_test_id("rich-select-option").click()
|
||||
page.select_option('[data-testid=transfer-form] [name="toVegaKey"]', index=2)
|
||||
page.select_option('[data-testid=transfer-form] [name="fromAccount"]', index=1)
|
||||
|
||||
expected_asset_text = re.compile(r"tDAI tDAI999991.49731 tDAI.{6}….{4}")
|
||||
actual_asset_text = page.get_by_test_id('select-asset').text_content().strip()
|
||||
actual_asset_text = page.get_by_test_id("select-asset").text_content().strip()
|
||||
|
||||
assert expected_asset_text.search(actual_asset_text), f"Expected pattern not found in {actual_asset_text}"
|
||||
assert expected_asset_text.search(
|
||||
actual_asset_text
|
||||
), f"Expected pattern not found in {actual_asset_text}"
|
||||
|
||||
page.locator('[data-testid=transfer-form] input[name="amount"]').fill('1')
|
||||
expect(page.locator('[data-testid=transfer-form] input[name="amount"]')).not_to_be_empty()
|
||||
page.locator('[data-testid=transfer-form] input[name="amount"]').fill("1")
|
||||
expect(
|
||||
page.locator('[data-testid=transfer-form] input[name="amount"]')
|
||||
).not_to_be_empty()
|
||||
|
||||
page.locator('[data-testid=transfer-form] [type="submit"]').click()
|
||||
wait_for_toast_confirmation(page)
|
||||
vega.forward("10s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
expected_confirmation_text = re.compile(r"Transfer completeYour transaction has been confirmedView in block explorerTransferTo .{6}….{6}1\.00 tDAI")
|
||||
actual_confirmation_text = page.get_by_test_id('toast-content').text_content()
|
||||
assert expected_confirmation_text.search(actual_confirmation_text), f"Expected pattern not found in {actual_confirmation_text}"
|
||||
expected_confirmation_text = re.compile(
|
||||
r"Transfer completeYour transaction has been confirmedView in block explorerTransferTo .{6}….{6}1\.00 tDAI"
|
||||
)
|
||||
actual_confirmation_text = page.get_by_test_id("toast-content").text_content()
|
||||
assert expected_confirmation_text.search(
|
||||
actual_confirmation_text
|
||||
), f"Expected pattern not found in {actual_confirmation_text}"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
|
||||
def test_transfer_vesting_below_minimum(continuous_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_transfer_vesting_below_minimum(
|
||||
continuous_market, vega: VegaServiceNull, page: Page
|
||||
):
|
||||
vega.update_network_parameter(
|
||||
"market_maker", parameter="transfer.minTransferQuantumMultiple", new_value="100000"
|
||||
"market_maker",
|
||||
parameter="transfer.minTransferQuantumMultiple",
|
||||
new_value="100000",
|
||||
)
|
||||
vega.wait_for_total_catchup()
|
||||
|
||||
@@ -94,28 +113,34 @@ def test_transfer_vesting_below_minimum(continuous_market, vega: VegaService, pa
|
||||
vega.wait_for_total_catchup()
|
||||
next_epoch(vega=vega)
|
||||
next_epoch(vega=vega)
|
||||
page.goto('/#/portfolio')
|
||||
expect(page.get_by_test_id('transfer-form')).to_be_visible
|
||||
page.goto("/#/portfolio")
|
||||
expect(page.get_by_test_id("transfer-form")).to_be_visible
|
||||
|
||||
change_keys(page, vega, "party_b")
|
||||
page.get_by_test_id('select-asset').click()
|
||||
page.get_by_test_id('rich-select-option').click()
|
||||
page.get_by_test_id("select-asset").click()
|
||||
page.get_by_test_id("rich-select-option").click()
|
||||
|
||||
option_value = page.locator('[data-testid="transfer-form"] [name="fromAccount"] option[value^="ACCOUNT_TYPE_VESTED_REWARDS"]').first.get_attribute("value")
|
||||
option_value = page.locator(
|
||||
'[data-testid="transfer-form"] [name="fromAccount"] option[value^="ACCOUNT_TYPE_VESTED_REWARDS"]'
|
||||
).first.get_attribute("value")
|
||||
|
||||
page.select_option('[data-testid="transfer-form"] [name="fromAccount"]', option_value)
|
||||
page.select_option(
|
||||
'[data-testid="transfer-form"] [name="fromAccount"]', option_value
|
||||
)
|
||||
|
||||
page.locator('[data-testid=transfer-form] input[name="amount"]').fill('0.000001')
|
||||
page.locator('[data-testid=transfer-form] input[name="amount"]').fill("0.000001")
|
||||
page.locator('[data-testid=transfer-form] [type="submit"]').click()
|
||||
expect(page.get_by_test_id('input-error-text')).to_be_visible
|
||||
expect(page.get_by_test_id('input-error-text')).to_have_text("Amount below minimum requirements for partial transfer. Use max to bypass")
|
||||
expect(page.get_by_test_id("input-error-text")).to_be_visible
|
||||
expect(page.get_by_test_id("input-error-text")).to_have_text(
|
||||
"Amount below minimum requirements for partial transfer. Use max to bypass"
|
||||
)
|
||||
vega.one_off_transfer(
|
||||
from_key_name=PARTY_B.name,
|
||||
to_key_name=PARTY_B.name,
|
||||
from_account_type= vega_protos.vega.AccountType.ACCOUNT_TYPE_VESTED_REWARDS,
|
||||
to_account_type= vega_protos.vega.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
asset= asset_id,
|
||||
amount= 24.999999,
|
||||
from_account_type=vega_protos.vega.AccountType.ACCOUNT_TYPE_VESTED_REWARDS,
|
||||
to_account_type=vega_protos.vega.AccountType.ACCOUNT_TYPE_GENERAL,
|
||||
asset=asset_id,
|
||||
amount=24.999999,
|
||||
)
|
||||
vega.forward("10s")
|
||||
vega.wait_fn(10)
|
||||
@@ -127,6 +152,10 @@ def test_transfer_vesting_below_minimum(continuous_market, vega: VegaService, pa
|
||||
vega.forward("10s")
|
||||
vega.wait_fn(1)
|
||||
vega.wait_for_total_catchup()
|
||||
expected_confirmation_text = re.compile(r"Transfer completeYour transaction has been confirmedView in block explorerTransferTo .{6}….{6}0\.00001 tDAI")
|
||||
actual_confirmation_text = page.get_by_test_id('toast-content').text_content()
|
||||
assert expected_confirmation_text.search(actual_confirmation_text), f"Expected pattern not found in {actual_confirmation_text}"
|
||||
expected_confirmation_text = re.compile(
|
||||
r"Transfer completeYour transaction has been confirmedView in block explorerTransferTo .{6}….{6}0\.00001 tDAI"
|
||||
)
|
||||
actual_confirmation_text = page.get_by_test_id("toast-content").text_content()
|
||||
assert expected_confirmation_text.search(
|
||||
actual_confirmation_text
|
||||
), f"Expected pattern not found in {actual_confirmation_text}"
|
||||
|
||||
@@ -2,7 +2,6 @@ import pytest
|
||||
import re
|
||||
import json
|
||||
from playwright.sync_api import Page, expect, Route
|
||||
from vega_sim.service import VegaService
|
||||
from conftest import init_vega
|
||||
from fixtures.market import setup_continuous_market
|
||||
|
||||
@@ -15,6 +14,7 @@ tif = "order-tif"
|
||||
expire = "expire"
|
||||
api_request_match = r"http://localhost:\d+/api/v2/requests"
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def vega(request):
|
||||
with init_vega(request) as vega:
|
||||
@@ -25,50 +25,59 @@ def vega(request):
|
||||
def continuous_market(vega):
|
||||
return setup_continuous_market(vega)
|
||||
|
||||
|
||||
def handle_route_connection_lost(route: Route, request):
|
||||
if request.method == "POST" and re.match(api_request_match, request.url):
|
||||
route.fulfill(
|
||||
status=200,
|
||||
headers={"Content-Type": "application/json"},
|
||||
body='{"jsonrpc": "2.0", "id": "1"}'
|
||||
)
|
||||
else:
|
||||
route.continue_()
|
||||
if request.method == "POST" and re.match(api_request_match, request.url):
|
||||
route.fulfill(
|
||||
status=200,
|
||||
headers={"Content-Type": "application/json"},
|
||||
body='{"jsonrpc": "2.0", "id": "1"}',
|
||||
)
|
||||
else:
|
||||
route.continue_()
|
||||
|
||||
|
||||
def handle_route_connection_rejected(route: Route, request):
|
||||
if request.method == "POST" and re.match(api_request_match, request.url):
|
||||
custom_response = {
|
||||
"jsonrpc": "2.0",
|
||||
"error": {
|
||||
"code": 3001,
|
||||
"data": "the user rejected the wallet connection",
|
||||
"message": "User error"
|
||||
},
|
||||
"id": "0"
|
||||
}
|
||||
route.fulfill(
|
||||
status=400,
|
||||
headers={"Content-Type": "application/json"},
|
||||
body=json.dumps(custom_response)
|
||||
)
|
||||
else:
|
||||
route.continue_()
|
||||
if request.method == "POST" and re.match(api_request_match, request.url):
|
||||
custom_response = {
|
||||
"jsonrpc": "2.0",
|
||||
"error": {
|
||||
"code": 3001,
|
||||
"data": "the user rejected the wallet connection",
|
||||
"message": "User error",
|
||||
},
|
||||
"id": "0",
|
||||
}
|
||||
route.fulfill(
|
||||
status=400,
|
||||
headers={"Content-Type": "application/json"},
|
||||
body=json.dumps(custom_response),
|
||||
)
|
||||
else:
|
||||
route.continue_()
|
||||
|
||||
def assert_connection_approve(route: Route, request, page:Page):
|
||||
if request.method == "POST" and re.match(api_request_match, request.url):
|
||||
expect(page.get_by_test_id("toast-content")).to_have_text("Please go to your Vega wallet application and approve or reject the transaction.")
|
||||
else:
|
||||
route.continue_()
|
||||
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
|
||||
def assert_connection_approve(route: Route, request, page: Page):
|
||||
if request.method == "POST" and re.match(api_request_match, request.url):
|
||||
expect(page.get_by_test_id("toast-content")).to_have_text(
|
||||
"Please go to your Vega wallet application and approve or reject the transaction."
|
||||
)
|
||||
else:
|
||||
route.continue_()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_wallet_connection_error(continuous_market, page: Page):
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
page.route("**/*", handle_route_connection_lost)
|
||||
page.get_by_test_id("connect-vega-wallet").click()
|
||||
page.get_by_test_id("connector-jsonRpc").click()
|
||||
expect(page.get_by_test_id("wallet-dialog-title")).to_have_text("Something went wrong")
|
||||
expect(page.get_by_test_id("wallet-dialog-title")).to_have_text(
|
||||
"Something went wrong"
|
||||
)
|
||||
|
||||
@pytest.mark.usefixtures("page", "risk_accepted")
|
||||
|
||||
@pytest.mark.usefixtures("risk_accepted")
|
||||
def test_wallet_connection_rejected(continuous_market, page: Page):
|
||||
# 0002-WCON-002
|
||||
# 0002-WCON-005
|
||||
@@ -78,11 +87,13 @@ def test_wallet_connection_rejected(continuous_market, page: Page):
|
||||
page.route("**/*", handle_route_connection_rejected)
|
||||
page.get_by_test_id("connect-vega-wallet").click()
|
||||
page.get_by_test_id("connector-jsonRpc").click()
|
||||
expect(page.get_by_test_id("dialog-content").nth(1)).to_have_text("User errorthe user rejected the wallet connectionTry againAbout the Vega wallet | Supported browsers ")
|
||||
expect(page.get_by_test_id("dialog-content").nth(1)).to_have_text(
|
||||
"User errorthe user rejected the wallet connectionTry againAbout the Vega wallet | Supported browsers "
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
|
||||
def test_wallet_connection_error_transaction(continuous_market, vega: VegaService, page: Page):
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_wallet_connection_error_transaction(continuous_market, page: Page):
|
||||
# 0003-WTXN-009
|
||||
# 0003-WTXN-011
|
||||
# 0002-WCON-016
|
||||
@@ -92,20 +103,26 @@ def test_wallet_connection_error_transaction(continuous_market, vega: VegaServic
|
||||
page.get_by_test_id(order_price).fill("120")
|
||||
page.route("**/*", handle_route_connection_lost)
|
||||
page.get_by_test_id(place_order).click()
|
||||
expect(page.get_by_test_id("toast-content")).to_have_text("Wallet disconnectedThe connection to your Vega Wallet has been lost.Connect vega wallet")
|
||||
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
|
||||
def test_wallet_transaction_rejected(continuous_market, vega: VegaService, page: Page):
|
||||
expect(page.get_by_test_id("toast-content")).to_have_text(
|
||||
"Wallet disconnectedThe connection to your Vega Wallet has been lost.Connect vega wallet"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_wallet_transaction_rejected(continuous_market, page: Page):
|
||||
# 0003-WTXN-007
|
||||
page.goto(f"/#/markets/{continuous_market}")
|
||||
page.get_by_test_id(order_size).fill("10")
|
||||
page.get_by_test_id(order_price).fill("120")
|
||||
page.route("**/*", handle_route_connection_rejected)
|
||||
page.get_by_test_id(place_order).click()
|
||||
expect(page.get_by_test_id("toast-content")).to_have_text("Error occurredthe user rejected the wallet connection")
|
||||
|
||||
@pytest.mark.usefixtures("page", "auth", "risk_accepted")
|
||||
def test_wallet_connection_approve(continuous_market, vega: VegaService, page: Page):
|
||||
expect(page.get_by_test_id("toast-content")).to_have_text(
|
||||
"Error occurredthe user rejected the wallet connection"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("auth", "risk_accepted")
|
||||
def test_wallet_connection_approve(continuous_market, page: Page):
|
||||
# 0002-WCON-005
|
||||
# 0002-WCON-007
|
||||
# 0002-WCON-009
|
||||
@@ -113,4 +130,4 @@ def test_wallet_connection_approve(continuous_market, vega: VegaService, page: P
|
||||
page.get_by_test_id(order_size).fill("10")
|
||||
page.get_by_test_id(order_price).fill("120")
|
||||
page.route("**/*", assert_connection_approve)
|
||||
page.get_by_test_id(place_order).click()
|
||||
page.get_by_test_id(place_order).click()
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
import {
|
||||
Intent,
|
||||
useToasts,
|
||||
ToastHeading,
|
||||
CLOSE_AFTER,
|
||||
} from '@vegaprotocol/ui-toolkit';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { useT } from '../use-t';
|
||||
import { VegaWalletConnectButton } from '../../components/vega-wallet-connect-button';
|
||||
|
||||
const WALLET_DISCONNECTED_TOAST_ID = 'WALLET_DISCONNECTED_TOAST_ID';
|
||||
|
||||
export const useWalletDisconnectedToasts = () => {
|
||||
const t = useT();
|
||||
const [hasToast, setToast, updateToast] = useToasts((state) => [
|
||||
state.hasToast,
|
||||
state.setToast,
|
||||
state.update,
|
||||
]);
|
||||
const { isAlive } = useVegaWallet();
|
||||
|
||||
const toast = useMemo(
|
||||
() => ({
|
||||
id: WALLET_DISCONNECTED_TOAST_ID,
|
||||
intent: Intent.Danger,
|
||||
content: (
|
||||
<>
|
||||
<ToastHeading>{t('Wallet connection lost')}</ToastHeading>
|
||||
<p>{t('The connection to the Vega wallet has been lost.')}</p>
|
||||
<p className="mt-2">
|
||||
<VegaWalletConnectButton
|
||||
intent={Intent.Danger}
|
||||
onClick={() => {
|
||||
updateToast(WALLET_DISCONNECTED_TOAST_ID, {
|
||||
hidden: true,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</>
|
||||
),
|
||||
onClose: () => {
|
||||
updateToast(WALLET_DISCONNECTED_TOAST_ID, {
|
||||
hidden: true,
|
||||
});
|
||||
},
|
||||
closeAfter: CLOSE_AFTER,
|
||||
}),
|
||||
[t, updateToast]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (isAlive === false) {
|
||||
if (hasToast(WALLET_DISCONNECTED_TOAST_ID)) {
|
||||
updateToast(WALLET_DISCONNECTED_TOAST_ID, { hidden: false });
|
||||
} else {
|
||||
setToast(toast);
|
||||
}
|
||||
}
|
||||
}, [hasToast, isAlive, setToast, t, toast, updateToast]);
|
||||
};
|
||||
@@ -13,7 +13,7 @@ export default function Document() {
|
||||
{/* preload fonts */}
|
||||
<link
|
||||
rel="preload"
|
||||
href="/AlphaLyrae-Medium.woff2"
|
||||
href="/AlphaLyrae.woff2"
|
||||
as="font"
|
||||
type="font/woff2"
|
||||
/>
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
/** Load AlphaLyrae font */
|
||||
@font-face {
|
||||
font-family: AlphaLyrae;
|
||||
src: url('/AlphaLyrae-Medium.woff2') format('woff2'),
|
||||
url('/AlphaLyrae-Medium.woff') format('woff');
|
||||
src: url('/AlphaLyrae.woff2') format('woff2');
|
||||
}
|
||||
|
||||
@tailwind base;
|
||||
|
||||
@@ -6,6 +6,7 @@ import { useEthereumWithdrawApprovalsToasts } from '@vegaprotocol/web3';
|
||||
import { useReadyToWithdrawalToasts } from '@vegaprotocol/withdraws';
|
||||
import { Links } from '../lib/links';
|
||||
import { useReferralToasts } from '../client-pages/referrals/hooks/use-referral-toasts';
|
||||
import { useWalletDisconnectedToasts } from '../lib/hooks/use-wallet-disconnected-toasts';
|
||||
|
||||
export const ToastsManager = () => {
|
||||
useProposalToasts();
|
||||
@@ -16,6 +17,7 @@ export const ToastsManager = () => {
|
||||
withdrawalsLink: Links.PORTFOLIO(),
|
||||
});
|
||||
useReferralToasts();
|
||||
useWalletDisconnectedToasts();
|
||||
|
||||
const toasts = useToasts((store) => store.toasts);
|
||||
return <ToastsContainer order="desc" toasts={toasts} />;
|
||||
|
||||
Binary file not shown.
@@ -29,7 +29,7 @@ const AccountBreakdown = ({
|
||||
variables: { partyId, assetId },
|
||||
update: ({ data }) => {
|
||||
if (gridRef.current?.api && data?.breakdown) {
|
||||
gridRef.current?.api.setRowData(data?.breakdown);
|
||||
gridRef.current?.api.setGridOption('rowData', data?.breakdown);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -7,6 +7,7 @@ import type {
|
||||
FetchResult,
|
||||
ErrorPolicy,
|
||||
ApolloQueryResult,
|
||||
QueryOptions,
|
||||
} from '@apollo/client';
|
||||
import type { GraphQLErrors } from '@apollo/client/errors';
|
||||
import type { Subscription } from 'zen-observable-ts';
|
||||
@@ -158,6 +159,7 @@ interface DataProviderParams<
|
||||
};
|
||||
fetchPolicy?: FetchPolicy;
|
||||
resetDelay?: number;
|
||||
pollInterval?: number;
|
||||
additionalContext?: Record<string, unknown>;
|
||||
errorPolicyGuard?: (graphqlErrors: GraphQLErrors) => boolean;
|
||||
getQueryVariables?: (variables: Variables) => QueryVariables;
|
||||
@@ -198,6 +200,7 @@ function makeDataProviderInternal<
|
||||
errorPolicyGuard,
|
||||
getQueryVariables,
|
||||
getSubscriptionVariables,
|
||||
pollInterval,
|
||||
}: DataProviderParams<
|
||||
QueryData,
|
||||
Data,
|
||||
@@ -222,6 +225,7 @@ function makeDataProviderInternal<
|
||||
let client: ApolloClient<object>;
|
||||
let subscription: Subscription[] | undefined;
|
||||
let pageInfo: PageInfo | null = null;
|
||||
let watchQuerySubscription: Subscription | null = null;
|
||||
|
||||
// notify single callback about current state, delta is passes optionally only if notify was invoked onNext
|
||||
const notify = (
|
||||
@@ -243,34 +247,100 @@ function makeDataProviderInternal<
|
||||
callbacks.forEach((callback) => notify(callback, updateData));
|
||||
};
|
||||
|
||||
const call = (
|
||||
const getQueryOptions = (
|
||||
pagination?: Pagination,
|
||||
policy?: ErrorPolicy
|
||||
): QueryOptions<OperationVariables, QueryData> => ({
|
||||
query,
|
||||
variables: {
|
||||
...(getQueryVariables ? getQueryVariables(variables) : variables),
|
||||
...(pagination && {
|
||||
// let the variables pagination be prior to provider param
|
||||
pagination: {
|
||||
...pagination,
|
||||
...(variables?.['pagination'] ?? null),
|
||||
},
|
||||
}),
|
||||
},
|
||||
fetchPolicy: fetchPolicy || 'no-cache',
|
||||
context: additionalContext,
|
||||
errorPolicy: policy || 'none',
|
||||
pollInterval,
|
||||
});
|
||||
|
||||
const onNext = (res: ApolloQueryResult<QueryData>) => {
|
||||
data = getData(res.data, variables);
|
||||
if (data && pagination) {
|
||||
if (!(data instanceof Array)) {
|
||||
throw new Error(
|
||||
'data needs to be instance of Edge[] when using pagination'
|
||||
);
|
||||
}
|
||||
pageInfo = pagination.getPageInfo(res.data);
|
||||
}
|
||||
// if there was some updates received from subscription during initial query loading apply them on just received data
|
||||
if (update && data && updateQueue && updateQueue.length > 0) {
|
||||
while (updateQueue.length) {
|
||||
const delta = updateQueue.shift();
|
||||
if (delta) {
|
||||
setData(update(data, delta, reload, variables));
|
||||
}
|
||||
}
|
||||
}
|
||||
loaded = true;
|
||||
};
|
||||
|
||||
const onError = (e: Error) => {
|
||||
if (isNotFoundGraphQLError(e, ['party'])) {
|
||||
data = getData(null, variables);
|
||||
loaded = true;
|
||||
return;
|
||||
}
|
||||
// if error will occur data provider stops subscription
|
||||
error = e;
|
||||
subscriptionUnsubscribe();
|
||||
};
|
||||
|
||||
const onComplete = (isUpdate?: boolean) => {
|
||||
loading = false;
|
||||
notifyAll({ isUpdate });
|
||||
};
|
||||
|
||||
const callWatchQuery = (pagination?: Pagination, policy?: ErrorPolicy) => {
|
||||
let onNextCalled = false;
|
||||
try {
|
||||
watchQuerySubscription = client
|
||||
.watchQuery(getQueryOptions(pagination, policy))
|
||||
.subscribe(
|
||||
(res) => {
|
||||
onNext(res);
|
||||
onComplete(onNextCalled);
|
||||
onNextCalled = true;
|
||||
},
|
||||
(error) => {
|
||||
onError(error as Error);
|
||||
onComplete();
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
onError(e as Error);
|
||||
onComplete();
|
||||
}
|
||||
};
|
||||
|
||||
const callQuery = (
|
||||
pagination?: Pagination,
|
||||
policy?: ErrorPolicy
|
||||
): Promise<ApolloQueryResult<QueryData>> =>
|
||||
client
|
||||
.query<QueryData>({
|
||||
query,
|
||||
variables: {
|
||||
...(getQueryVariables ? getQueryVariables(variables) : variables),
|
||||
...(pagination && {
|
||||
// let the variables pagination be prior to provider param
|
||||
pagination: {
|
||||
...pagination,
|
||||
...(variables?.['pagination'] ?? null),
|
||||
},
|
||||
}),
|
||||
},
|
||||
fetchPolicy: fetchPolicy || 'no-cache',
|
||||
context: additionalContext,
|
||||
errorPolicy: policy || 'none',
|
||||
})
|
||||
.query<QueryData>(getQueryOptions(pagination, policy))
|
||||
.catch((err) => {
|
||||
if (
|
||||
err.graphQLErrors &&
|
||||
errorPolicyGuard &&
|
||||
errorPolicyGuard(err.graphQLErrors)
|
||||
) {
|
||||
return call(pagination, 'ignore');
|
||||
return callQuery(pagination, 'ignore');
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
@@ -294,7 +364,7 @@ function makeDataProviderInternal<
|
||||
}
|
||||
}
|
||||
|
||||
const res = await call(paginationVariables);
|
||||
const res = await callQuery(paginationVariables);
|
||||
|
||||
const insertionData = getData(res.data, variables);
|
||||
const insertionPageInfo = pagination.getPageInfo(res.data);
|
||||
@@ -329,7 +399,7 @@ function makeDataProviderInternal<
|
||||
variables,
|
||||
fetchPolicy,
|
||||
})
|
||||
.subscribe(onNext, onError)
|
||||
.subscribe(subscriptionOnNext, subscriptionOnError)
|
||||
);
|
||||
};
|
||||
|
||||
@@ -347,39 +417,16 @@ function makeDataProviderInternal<
|
||||
const paginationVariables = pagination
|
||||
? { first: pagination.first }
|
||||
: undefined;
|
||||
if (pollInterval) {
|
||||
callWatchQuery();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await call(paginationVariables);
|
||||
data = getData(res.data, variables);
|
||||
if (data && pagination) {
|
||||
if (!(data instanceof Array)) {
|
||||
throw new Error(
|
||||
'data needs to be instance of Edge[] when using pagination'
|
||||
);
|
||||
}
|
||||
pageInfo = pagination.getPageInfo(res.data);
|
||||
}
|
||||
// if there was some updates received from subscription during initial query loading apply them on just received data
|
||||
if (update && data && updateQueue && updateQueue.length > 0) {
|
||||
while (updateQueue.length) {
|
||||
const delta = updateQueue.shift();
|
||||
if (delta) {
|
||||
setData(update(data, delta, reload, variables));
|
||||
}
|
||||
}
|
||||
}
|
||||
loaded = true;
|
||||
onNext(await callQuery(paginationVariables));
|
||||
} catch (e) {
|
||||
if (isNotFoundGraphQLError(e as Error, ['party'])) {
|
||||
data = getData(null, variables);
|
||||
loaded = true;
|
||||
return;
|
||||
}
|
||||
// if error will occur data provider stops subscription
|
||||
error = e as Error;
|
||||
subscriptionUnsubscribe();
|
||||
onError(e as Error);
|
||||
} finally {
|
||||
loading = false;
|
||||
notifyAll({ isUpdate });
|
||||
onComplete(isUpdate);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -399,7 +446,7 @@ function makeDataProviderInternal<
|
||||
}
|
||||
};
|
||||
|
||||
const onNext = ({
|
||||
const subscriptionOnNext = ({
|
||||
data: subscriptionData,
|
||||
}: FetchResult<SubscriptionData>) => {
|
||||
if (!subscriptionData || !getDelta || !update) {
|
||||
@@ -418,7 +465,7 @@ function makeDataProviderInternal<
|
||||
}
|
||||
};
|
||||
|
||||
const onError = (e: Error) => {
|
||||
const subscriptionOnError = (e: Error) => {
|
||||
error = e;
|
||||
subscriptionUnsubscribe();
|
||||
notifyAll();
|
||||
@@ -442,6 +489,9 @@ function makeDataProviderInternal<
|
||||
};
|
||||
|
||||
const reset = () => {
|
||||
if (watchQuerySubscription) {
|
||||
watchQuerySubscription.unsubscribe();
|
||||
}
|
||||
subscriptionUnsubscribe();
|
||||
initialized = false;
|
||||
data = null;
|
||||
|
||||
@@ -24,20 +24,27 @@ export const useDataGridEvents = (
|
||||
defaultFilterModel?: State['filterModel']
|
||||
) => {
|
||||
const apiRef = useRef<GridApi | undefined>();
|
||||
const hasStateRef = useRef(Boolean(state.columnState || state.filterModel));
|
||||
|
||||
useEffect(() => {
|
||||
if (apiRef.current?.isDestroyed()) {
|
||||
apiRef.current = undefined;
|
||||
}
|
||||
if (apiRef.current) {
|
||||
const hasState = Boolean(state.columnState || state.filterModel);
|
||||
if (apiRef.current && hasStateRef.current && !hasState) {
|
||||
if (!state.columnState) {
|
||||
apiRef.current.resetColumnState();
|
||||
apiRef.current.sizeColumnsToFit();
|
||||
if (autoSizeColumns?.length) {
|
||||
apiRef.current.autoSizeColumns(autoSizeColumns);
|
||||
}
|
||||
}
|
||||
if (!state.filterModel) {
|
||||
apiRef.current.setFilterModel(defaultFilterModel);
|
||||
}
|
||||
}
|
||||
}, [state, defaultFilterModel]);
|
||||
hasStateRef.current = hasState;
|
||||
}, [state, defaultFilterModel, autoSizeColumns]);
|
||||
|
||||
/**
|
||||
* Callback for filter events
|
||||
|
||||
@@ -76,9 +76,14 @@ export const DealTicketFeeDetails = ({
|
||||
<KeyValue
|
||||
label={
|
||||
<>
|
||||
{t('Fees')}
|
||||
<span data-testid="fees-text">{t('Fees')}</span>
|
||||
{totalDiscountFactor !== '0' ? (
|
||||
<Pill size="xxs" intent={Intent.Info} className="ml-1">
|
||||
<Pill
|
||||
size="xxs"
|
||||
intent={Intent.Info}
|
||||
className="ml-1"
|
||||
data-testid="discount-pill"
|
||||
>
|
||||
{formatNumberPercentage(
|
||||
new BigNumber(totalDiscountFactor).multipliedBy(100)
|
||||
)}
|
||||
|
||||
@@ -649,7 +649,6 @@ const formatTrigger = (
|
||||
Number(triggerTrailingPercentOffset) || 0
|
||||
).toFixed(1),
|
||||
})
|
||||
}
|
||||
}`;
|
||||
|
||||
const SubmitButton = ({
|
||||
|
||||
@@ -23,19 +23,23 @@ const FeesBreakdownItem = ({
|
||||
value,
|
||||
symbol,
|
||||
decimals,
|
||||
testId,
|
||||
}: {
|
||||
label: string;
|
||||
factor?: string | number;
|
||||
value: string;
|
||||
symbol?: string;
|
||||
decimals: number;
|
||||
testId?: string;
|
||||
}) => (
|
||||
<>
|
||||
<dt className="col-span-2">{label}</dt>
|
||||
<dd className="text-right col-span-1">
|
||||
<dt className="col-span-2" data-testid={`${testId}-label`}>
|
||||
{label}
|
||||
</dt>
|
||||
<dd className="text-right col-span-1" data-testid={`${testId}-factor`}>
|
||||
{factor ? formatNumberPercentage(new BigNumber(factor).times(100)) : ''}
|
||||
</dd>
|
||||
<dd className="text-right col-span-3">
|
||||
<dd className="text-right col-span-3" data-testid={`${testId}-value`}>
|
||||
{formatValue(value, decimals)} {symbol || ''}
|
||||
</dd>
|
||||
</>
|
||||
@@ -73,6 +77,7 @@ export const FeesBreakdown = ({
|
||||
value={fees.infrastructureFee}
|
||||
symbol={symbol}
|
||||
decimals={decimals}
|
||||
testId="infrastructure-fee"
|
||||
/>
|
||||
|
||||
<FeesBreakdownItem
|
||||
@@ -81,6 +86,7 @@ export const FeesBreakdown = ({
|
||||
value={fees.liquidityFee}
|
||||
symbol={symbol}
|
||||
decimals={decimals}
|
||||
testId="liquidity-fee"
|
||||
/>
|
||||
|
||||
<FeesBreakdownItem
|
||||
@@ -89,6 +95,7 @@ export const FeesBreakdown = ({
|
||||
value={fees.makerFee}
|
||||
symbol={symbol}
|
||||
decimals={decimals}
|
||||
testId="maker-fee"
|
||||
/>
|
||||
{totalDiscount && totalDiscount !== '0' ? (
|
||||
<>
|
||||
@@ -100,6 +107,7 @@ export const FeesBreakdown = ({
|
||||
}
|
||||
symbol={symbol}
|
||||
decimals={decimals}
|
||||
testId="subtotal-fee"
|
||||
/>
|
||||
<div className="col-span-6 mt-2"></div>
|
||||
<FeesBreakdownItem
|
||||
@@ -108,12 +116,14 @@ export const FeesBreakdown = ({
|
||||
value={`-${totalDiscount}`}
|
||||
symbol={symbol}
|
||||
decimals={decimals}
|
||||
testId="discount-fee"
|
||||
/>
|
||||
<FeesBreakdownItem
|
||||
label={t('Total')}
|
||||
value={discountedTotalFeeAmount}
|
||||
symbol={symbol}
|
||||
decimals={decimals}
|
||||
testId="total-fee"
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
@@ -127,6 +137,7 @@ export const FeesBreakdown = ({
|
||||
value={totalFeeAmount}
|
||||
symbol={symbol}
|
||||
decimals={decimals}
|
||||
testId="full-total-fee"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -87,9 +87,9 @@ export const FillsTable = forwardRef<AgGridReact, Props>(
|
||||
colId: 'fee',
|
||||
field: 'market',
|
||||
valueFormatter: formatFee(partyId),
|
||||
tooltipComponent: FeesBreakdownTooltip,
|
||||
type: 'rightAligned',
|
||||
tooltipField: 'market',
|
||||
tooltipComponent: FeesBreakdownTooltip,
|
||||
tooltipComponentParams: { partyId },
|
||||
},
|
||||
{
|
||||
@@ -97,13 +97,13 @@ export const FillsTable = forwardRef<AgGridReact, Props>(
|
||||
colId: 'fee-discount',
|
||||
field: 'market',
|
||||
valueFormatter: formatFeeDiscount(partyId),
|
||||
type: 'rightAligned',
|
||||
// return null to disable tooltip if fee discount is 0 or empty
|
||||
tooltipValueGetter: ({ valueFormatted, value }) => {
|
||||
return valueFormatted && /[1-9]/.test(valueFormatted)
|
||||
? valueFormatted
|
||||
: null;
|
||||
},
|
||||
type: 'rightAligned',
|
||||
// return null to disable tooltip if fee discount is 0 or empty
|
||||
cellRenderer: ({
|
||||
value,
|
||||
valueFormatted,
|
||||
@@ -146,7 +146,7 @@ export const FillsTable = forwardRef<AgGridReact, Props>(
|
||||
overlayNoRowsTemplate={t('No fills')}
|
||||
getRowId={({ data }) => data?.id}
|
||||
tooltipShowDelay={0}
|
||||
tooltipHideDelay={2000}
|
||||
tooltipHideDelay={10000}
|
||||
components={{ MarketNameCell }}
|
||||
{...props}
|
||||
/>
|
||||
@@ -292,21 +292,27 @@ const FeesBreakdownTooltip = ({
|
||||
)}
|
||||
{role === MAKER && (
|
||||
<>
|
||||
<p className="mb-1">{t('The maker will receive the maker fee.')}</p>
|
||||
<p className="mb-1">
|
||||
{t(
|
||||
'If the market is active the maker will pay zero infrastructure and liquidity fees.'
|
||||
`Fee revenue to be received by the maker, takers' fee discounts already applied.`
|
||||
)}
|
||||
</p>
|
||||
<p className="mb-1">
|
||||
{t(
|
||||
'During continuous trading the maker pays no infrastructure and liquidity fees.'
|
||||
)}
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
{role === TAKER && (
|
||||
<p className="mb-1">{t('Fees to be paid by the taker.')}</p>
|
||||
<p className="mb-1">
|
||||
{t('Fees to be paid by the taker; discounts are already applied.')}
|
||||
</p>
|
||||
)}
|
||||
{(role === '-' || marketState === Schema.MarketState.STATE_SUSPENDED) && (
|
||||
<p className="mb-1">
|
||||
{t(
|
||||
'If the market is in monitoring auction, half of the infrastructure and liquidity fees will be paid.'
|
||||
'During auction, half the infrastructure and liquidity fees will be paid.'
|
||||
)}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -36,7 +36,7 @@ export const FundingPaymentsManager = ({
|
||||
dataProvider: fundingPaymentsWithMarketProvider,
|
||||
update: ({ data }) => {
|
||||
if (data?.length && gridRef.current?.api) {
|
||||
gridRef.current?.api.setRowData(data);
|
||||
gridRef.current?.api.setGridOption('rowData', data);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
"Date": "Date",
|
||||
"Fee": "Fee",
|
||||
"Fee Discount": "Fee Discount",
|
||||
"Fees to be paid by the taker.": "Fees to be paid by the taker.",
|
||||
"If the market is active the maker will pay zero infrastructure and liquidity fees.": "If the market is active the maker will pay zero infrastructure and liquidity fees.",
|
||||
"If the market is in monitoring auction, half of the infrastructure and liquidity fees will be paid.": "If the market is in monitoring auction, half of the infrastructure and liquidity fees will be paid.",
|
||||
"Fees to be paid by the taker; discounts are already applied.": "Fees to be paid by the taker; discounts are already applied.",
|
||||
"During continuous trading the maker pays no infrastructure and liquidity fees.": "During continuous trading the maker pays no infrastructure and liquidity fees.",
|
||||
"During auction, half the infrastructure and liquidity fees will be paid.": "During auction, half the infrastructure and liquidity fees will be paid.",
|
||||
"Infrastructure Fee": "Infrastructure Fee",
|
||||
"Market": "Market",
|
||||
"No fills": "No fills",
|
||||
|
||||
@@ -298,8 +298,8 @@
|
||||
"liquidityOnsenIntro": "Earn rewards for providing liquidity on the",
|
||||
"liquidityOnsenLinkText": "SushiSwap Onsen Menu",
|
||||
"liquidityProviderVote": "Liquidity provider vote",
|
||||
"liquidityProviderVotesAgainst": "LP votes against",
|
||||
"liquidityProviderVotesFor": "LP votes for",
|
||||
"liquidityProviderVotesAgainst": "LP share against",
|
||||
"liquidityProviderVotesFor": "LP share for",
|
||||
"liquidityRewardsTitle": "Active liquidity rewards",
|
||||
"liquidityRewardsTitlePrevious": "Previous liquidity rewards",
|
||||
"liquidityStakedBalance": "SLP token balance",
|
||||
@@ -759,7 +759,7 @@
|
||||
"Total stake": "Total stake",
|
||||
"Total supply": "Total supply",
|
||||
"totalDistributed": "Total distributed",
|
||||
"totalLiquidityProviderTokensVoted": "Total LP tokens voted",
|
||||
"totalLiquidityProviderTokensVoted": "Total LP share voted",
|
||||
"totalPenalties": "Total penalties",
|
||||
"TotalPenaltiesDescription": "Total of penalties taking into account performance (considering proportion of blocks proposed against the number of blocks the validator was expected to propose) and any overstaking.",
|
||||
"totalStake": "Total stake",
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
"The fraction of the insurance pool balance that is carried over from the parent market to the successor.": "The fraction of the insurance pool balance that is carried over from the parent market to the successor.",
|
||||
"The ID of the market this market succeeds.": "The ID of the market this market succeeds.",
|
||||
"The length of time over which open interest is measured.": "The length of time over which open interest is measured.",
|
||||
"The liquidity price range is a {{{liquidityPriceRange}} difference from the mid price.": "The liquidity price range is a {{{liquidityPriceRange}} difference from the mid price.",
|
||||
"The liquidity price range is a {{liquidityPriceRange}} difference from the mid price.": "The liquidity price range is a {{liquidityPriceRange}} difference from the mid price.",
|
||||
"The lower bound for the probability of trading calculation, used to measure liquidity available on a market to determine if LPs are meeting their commitment. This is a network parameter.": "The lower bound for the probability of trading calculation, used to measure liquidity available on a market to determine if LPs are meeting their commitment. This is a network parameter.",
|
||||
"The market's liquidity requirement which is derived from the maximum open interest observed over a rolling time window.": "The market's liquidity requirement which is derived from the maximum open interest observed over a rolling time window.",
|
||||
"The maximum amount, as a fraction, that an LP's bond can be slashed by if they fail to reach the minimum SLA. This is a network parameter.": "The maximum amount, as a fraction, that an LP's bond can be slashed by if they fail to reach the minimum SLA. This is a network parameter.",
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
"Current tier": "Current tier",
|
||||
"Dark mode": "Dark mode",
|
||||
"Date Joined": "Date Joined",
|
||||
"Depending on data node retention you may not be able see the full 30 days": "Depending on data node retention you may not be able see the full 30 days",
|
||||
"Deposit": "Deposit",
|
||||
"Deposit funds": "Deposit funds",
|
||||
"Deposits": "Deposits",
|
||||
@@ -224,9 +225,9 @@
|
||||
"Referral benefits": "Referral benefits",
|
||||
"Referral discount": "Referral discount",
|
||||
"Referrals": "Referrals",
|
||||
"referralStatisticsCommission": "Commission earned in <0>qUSD</0> (last {{count}} epochs)",
|
||||
"referralStatisticsCommission_one": "Commission earned in <0>qUSD</0> (last {{count}} epoch)",
|
||||
"referralStatisticsCommission_other": "Commission earned in <0>qUSD</0> (last {{count}} epochs)",
|
||||
"referralStatisticsCommission": "Commission earned in <0>qUSD</0> (<1>last {{count}} epochs</1>)",
|
||||
"referralStatisticsCommission_one": "Commission earned in <0>qUSD</0> (<1>last {{count}} epoch</1>)",
|
||||
"referralStatisticsCommission_other": "Commission earned in <0>qUSD</0> (<1>last {{count}} epochs</1>)",
|
||||
"Referrer commission": "Referrer commission",
|
||||
"Referrer trading discount": "Referrer trading discount",
|
||||
"Referrers earn commission based on a percentage of the taker fees their referees pay": "Referrers earn commission based on a percentage of the taker fees their referees pay",
|
||||
@@ -296,9 +297,9 @@
|
||||
"Total distributed": "Total distributed",
|
||||
"Total fee after discount": "Total fee after discount",
|
||||
"Total fee before discount": "Total fee before discount",
|
||||
"totalCommission": "Total commission (last {{count}}} epochs)",
|
||||
"totalCommission_one": "Total commission (last {{count}}} epoch)",
|
||||
"totalCommission_other": "Total commission (last {{count}}} epochs)",
|
||||
"totalCommission": "Total commission (<0>last {{count}} epochs</0>)",
|
||||
"totalCommission_one": "Total commission (<0>last {{count}} epoch</0>)",
|
||||
"totalCommission_other": "Total commission (<0>last {{count}} epochs</0>)",
|
||||
"Trader": "Trader",
|
||||
"Trades": "Trades",
|
||||
"Trading": "Trading",
|
||||
@@ -309,9 +310,6 @@
|
||||
"Trading on Market {{name}} may stop. There are open proposals to close this market": "Trading on Market {{name}} may stop. There are open proposals to close this market",
|
||||
"Trading on Market {{name}} will stop on {{date}}": "Trading on Market {{name}} will stop on {{date}}",
|
||||
"Transfer": "Transfer",
|
||||
"totalCommission": "Total commission (last {{count}} epochs)",
|
||||
"totalCommission_one": "Total commission (last {{count}} epoch)",
|
||||
"totalCommission_other": "Total commission (last {{count}} epochs)",
|
||||
"Unknown": "Unknown",
|
||||
"Unknown settlement date": "Unknown settlement date",
|
||||
"Vega chart": "Vega chart",
|
||||
|
||||
@@ -34,6 +34,7 @@ export const marketInfoProvider = makeDataProvider<
|
||||
query: MarketInfoDocument,
|
||||
getData,
|
||||
errorPolicyGuard: marketDataErrorPolicyGuard,
|
||||
pollInterval: 5000,
|
||||
});
|
||||
|
||||
export const marketInfoWithDataProvider = makeDerivedDataProvider<
|
||||
|
||||
@@ -135,7 +135,7 @@ describe('MarketInfoPanels', () => {
|
||||
render(<DataSourceProof dataSourceSpecId={''} {...props} />);
|
||||
expect(screen.getByText('Internal conditions')).toBeInTheDocument();
|
||||
const dateFromUnixTimestamp = condition.value
|
||||
? getDateTimeFormat().format(new Date(parseInt(condition.value)))
|
||||
? getDateTimeFormat().format(new Date(parseInt(condition.value) * 1000))
|
||||
: '-';
|
||||
expect(
|
||||
screen.getByText(
|
||||
|
||||
@@ -970,7 +970,7 @@ export const LiquidityPriceRangeInfoPanel = ({
|
||||
/>
|
||||
<p className="mb-2 mt-2 border-l-2 pl-2 text-xs">
|
||||
{t(
|
||||
'The liquidity price range is a {{{liquidityPriceRange}} difference from the mid price.',
|
||||
'The liquidity price range is a {{liquidityPriceRange}} difference from the mid price.',
|
||||
{ liquidityPriceRange }
|
||||
)}
|
||||
</p>
|
||||
@@ -1263,7 +1263,9 @@ export const DataSourceProof = ({
|
||||
{data.sourceType.sourceType?.conditions?.map((condition, i) => {
|
||||
if (!condition) return null;
|
||||
const dateFromUnixTimestamp = condition.value
|
||||
? getDateTimeFormat().format(new Date(parseInt(condition.value)))
|
||||
? getDateTimeFormat().format(
|
||||
new Date(parseInt(condition.value) * 1000)
|
||||
)
|
||||
: '-';
|
||||
return (
|
||||
<p key={i}>
|
||||
|
||||
@@ -68,10 +68,13 @@ export const useBlockRising = (skip = false) => {
|
||||
}
|
||||
);
|
||||
|
||||
const heights = compact([
|
||||
...results.map((r) => r?.blockHeight),
|
||||
blockInfo?.result.block.header.height,
|
||||
]);
|
||||
const heights = compact([...results.map((r) => r?.blockHeight)]);
|
||||
|
||||
// Handles TendermintErrorResponses
|
||||
if (blockInfo && 'result' in blockInfo) {
|
||||
heights.push(blockInfo.result.block.header.height);
|
||||
}
|
||||
|
||||
const current = max(heights);
|
||||
if (current && Number(current) > prev) {
|
||||
setBlock(Number(current));
|
||||
|
||||
@@ -76,16 +76,26 @@ export const useFetch = <T>(
|
||||
...options,
|
||||
body: body ? body : options?.body,
|
||||
});
|
||||
if (!response.ok) {
|
||||
|
||||
data = (await response.json()) as T;
|
||||
|
||||
if (!response.ok && !data) {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
|
||||
data = (await response.json()) as T;
|
||||
// @ts-ignore - 'error' in data
|
||||
if (data && 'error' in data) {
|
||||
if (data && data.error) {
|
||||
// Explicit check for TendermintErrorResponse style error
|
||||
// @ts-ignore - 'error' in data
|
||||
if (data.error.data) {
|
||||
// @ts-ignore - 'error' in data
|
||||
|
||||
throw new Error(data.error.data);
|
||||
}
|
||||
// @ts-ignore - data.error
|
||||
throw new Error(data.error);
|
||||
}
|
||||
|
||||
if (cancelRequest.current) return;
|
||||
|
||||
dispatch({ type: ActionType.FETCHED, payload: data });
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import { useEnvironment } from '@vegaprotocol/environment';
|
||||
import { useFetch } from '@vegaprotocol/react-helpers';
|
||||
import { type TendermintBlockResponse } from '../types';
|
||||
import type {
|
||||
TendermintBlockResponse,
|
||||
TendermintErrorResponse,
|
||||
} from '../types';
|
||||
|
||||
type TendermintResponse = TendermintBlockResponse | TendermintErrorResponse;
|
||||
|
||||
export const useBlockInfo = (blockHeight?: number, canFetch = true) => {
|
||||
const { TENDERMINT_URL } = useEnvironment();
|
||||
@@ -10,7 +15,7 @@ export const useBlockInfo = (blockHeight?: number, canFetch = true) => {
|
||||
TENDERMINT_URL && blockHeight && !isNaN(blockHeight) && canFetch
|
||||
);
|
||||
|
||||
const { state, refetch } = useFetch<TendermintBlockResponse>(
|
||||
const { state, refetch } = useFetch<TendermintResponse>(
|
||||
url,
|
||||
{ cache: 'force-cache' },
|
||||
canFetchData
|
||||
|
||||
@@ -7,6 +7,16 @@ export type TendermintBlockResponse = {
|
||||
};
|
||||
};
|
||||
|
||||
export type TendermintErrorResponse = {
|
||||
jsonrpc: string;
|
||||
id: number;
|
||||
error: {
|
||||
code: number;
|
||||
message: string;
|
||||
data: string;
|
||||
};
|
||||
};
|
||||
|
||||
type Id = {
|
||||
hash: string;
|
||||
parts: {
|
||||
@@ -34,7 +44,7 @@ type Header = {
|
||||
proposer_address: string;
|
||||
};
|
||||
|
||||
type Block = {
|
||||
export type Block = {
|
||||
header: Header;
|
||||
data: {
|
||||
txs: string[];
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user