fix(trading): update click area in network switcher (#4057)
Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
This commit is contained in:
parent
2e7a6a6458
commit
37247a504a
@ -13,6 +13,24 @@ import { Networks } from '../../';
|
|||||||
jest.mock('../../hooks/use-environment');
|
jest.mock('../../hooks/use-environment');
|
||||||
|
|
||||||
describe('Network switcher', () => {
|
describe('Network switcher', () => {
|
||||||
|
const { location } = window;
|
||||||
|
let hrefSetSpy: jest.SpyInstance;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
hrefSetSpy = jest.fn();
|
||||||
|
// @ts-ignore can't set location as optional
|
||||||
|
delete window.location;
|
||||||
|
window.location = {} as Location;
|
||||||
|
Object.defineProperty(window.location, 'href', {
|
||||||
|
// @ts-ignore set cannot take SpyInstance
|
||||||
|
set: hrefSetSpy,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
window.location = location;
|
||||||
|
});
|
||||||
|
|
||||||
it.each`
|
it.each`
|
||||||
network | label
|
network | label
|
||||||
${Networks.CUSTOM} | ${envTriggerMapping[Networks.CUSTOM]}
|
${Networks.CUSTOM} | ${envTriggerMapping[Networks.CUSTOM]}
|
||||||
@ -49,21 +67,29 @@ describe('Network switcher', () => {
|
|||||||
render(<NetworkSwitcher />);
|
render(<NetworkSwitcher />);
|
||||||
|
|
||||||
await userEvent.click(screen.getByRole('button'));
|
await userEvent.click(screen.getByRole('button'));
|
||||||
|
let links = screen.getAllByRole('link');
|
||||||
|
|
||||||
|
expect(links[0]).toHaveTextContent(envNameMapping[Networks.MAINNET]);
|
||||||
|
expect(links[1]).toHaveTextContent(envNameMapping[Networks.TESTNET]);
|
||||||
|
expect(links[0]).not.toHaveTextContent(t('current'));
|
||||||
|
expect(links[1]).not.toHaveTextContent(t('current'));
|
||||||
|
expect(links[0]).not.toHaveTextContent(t('not available'));
|
||||||
|
expect(links[1]).not.toHaveTextContent(t('not available'));
|
||||||
|
expect(links[2]).toHaveTextContent(t('Propose a network parameter change'));
|
||||||
|
|
||||||
const menuitems = screen.getAllByRole('menuitem');
|
const menuitems = screen.getAllByRole('menuitem');
|
||||||
|
|
||||||
expect(menuitems[0]).toHaveTextContent(envNameMapping[Networks.MAINNET]);
|
expect(menuitems[0]).toHaveTextContent('Advanced');
|
||||||
expect(menuitems[1]).toHaveTextContent(envNameMapping[Networks.TESTNET]);
|
|
||||||
expect(menuitems[0]).not.toHaveTextContent(t('current'));
|
|
||||||
expect(menuitems[1]).not.toHaveTextContent(t('current'));
|
|
||||||
expect(menuitems[0]).not.toHaveTextContent(t('not available'));
|
|
||||||
expect(menuitems[1]).not.toHaveTextContent(t('not available'));
|
|
||||||
expect(menuitems[2]).toHaveTextContent(t('Advanced'));
|
|
||||||
|
|
||||||
const links = screen.getAllByRole('link');
|
await userEvent.click(links[0]);
|
||||||
|
expect(hrefSetSpy).toHaveBeenCalledWith(mainnetUrl);
|
||||||
|
|
||||||
expect(links[0]).toHaveAttribute('href', mainnetUrl);
|
// re open dropdown as clicking an item will close it
|
||||||
expect(links[1]).toHaveAttribute('href', testnetUrl);
|
await userEvent.click(screen.getByRole('button'));
|
||||||
|
links = screen.getAllByRole('link');
|
||||||
|
|
||||||
|
await userEvent.click(links[1]);
|
||||||
|
expect(hrefSetSpy).toHaveBeenCalledWith(testnetUrl);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays the correct selected network on the default dropdown view', async () => {
|
it('displays the correct selected network on the default dropdown view', async () => {
|
||||||
@ -82,10 +108,10 @@ describe('Network switcher', () => {
|
|||||||
|
|
||||||
await userEvent.click(screen.getByRole('button'));
|
await userEvent.click(screen.getByRole('button'));
|
||||||
|
|
||||||
const menuitems = screen.getAllByRole('menuitem');
|
const links = screen.getAllByRole('link');
|
||||||
|
|
||||||
expect(menuitems[0]).toHaveTextContent(envNameMapping[Networks.MAINNET]);
|
expect(links[0]).toHaveTextContent(envNameMapping[Networks.MAINNET]);
|
||||||
expect(menuitems[0]).toHaveTextContent(t('current'));
|
expect(links[0]).toHaveTextContent(t('current'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays the correct selected network on the default dropdown view when it does not have an associated url', async () => {
|
it('displays the correct selected network on the default dropdown view when it does not have an associated url', async () => {
|
||||||
@ -103,10 +129,10 @@ describe('Network switcher', () => {
|
|||||||
|
|
||||||
await userEvent.click(screen.getByRole('button'));
|
await userEvent.click(screen.getByRole('button'));
|
||||||
|
|
||||||
const menuitems = screen.getAllByRole('menuitem');
|
const links = screen.getAllByRole('link');
|
||||||
|
|
||||||
expect(menuitems[0]).toHaveTextContent(envNameMapping[Networks.MAINNET]);
|
expect(links[0]).toHaveTextContent(envNameMapping[Networks.MAINNET]);
|
||||||
expect(menuitems[0]).toHaveTextContent(t('current'));
|
expect(links[0]).toHaveTextContent(t('current'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays the correct state for a network without url on the default dropdown view', async () => {
|
it('displays the correct state for a network without url on the default dropdown view', async () => {
|
||||||
@ -123,44 +149,59 @@ describe('Network switcher', () => {
|
|||||||
render(<NetworkSwitcher />);
|
render(<NetworkSwitcher />);
|
||||||
|
|
||||||
await userEvent.click(screen.getByRole('button'));
|
await userEvent.click(screen.getByRole('button'));
|
||||||
|
const links = screen.getAllByRole('link');
|
||||||
|
|
||||||
const menuitems = screen.getAllByRole('menuitem');
|
expect(links[0]).toHaveTextContent(envNameMapping[Networks.MAINNET]);
|
||||||
|
expect(links[0]).toHaveTextContent(t('not available'));
|
||||||
expect(menuitems[0]).toHaveTextContent(envNameMapping[Networks.MAINNET]);
|
|
||||||
expect(menuitems[0]).toHaveTextContent(t('not available'));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays the advanced view in the correct state', async () => {
|
it.each([Networks.MAINNET, Networks.TESTNET, Networks.DEVNET])(
|
||||||
const VEGA_NETWORKS: Record<Networks, string | undefined> = {
|
'displays the advanced view in the correct state',
|
||||||
[Networks.CUSTOM]: undefined,
|
async (network) => {
|
||||||
[Networks.MAINNET]: 'https://main.net',
|
const VEGA_NETWORKS: Record<Networks, string | undefined> = {
|
||||||
[Networks.TESTNET]: 'https://test.net',
|
[Networks.CUSTOM]: undefined,
|
||||||
[Networks.VALIDATOR_TESTNET]: 'https://validator-test.net',
|
[Networks.MAINNET]: 'https://main.net',
|
||||||
[Networks.DEVNET]: 'https://dev.net',
|
[Networks.TESTNET]: 'https://test.net',
|
||||||
[Networks.STAGNET1]: 'https://stag1.net',
|
[Networks.VALIDATOR_TESTNET]: 'https://validator-test.net',
|
||||||
};
|
[Networks.DEVNET]: 'https://dev.net',
|
||||||
// @ts-ignore Typescript doesn't know about this module being mocked
|
[Networks.STAGNET1]: 'https://stag1.net',
|
||||||
useEnvironment.mockImplementation(() => ({
|
};
|
||||||
VEGA_ENV: Networks.DEVNET,
|
// @ts-ignore Typescript doesn't know about this module being mocked
|
||||||
VEGA_NETWORKS,
|
useEnvironment.mockImplementation(() => ({
|
||||||
}));
|
VEGA_ENV: Networks.DEVNET,
|
||||||
|
VEGA_NETWORKS,
|
||||||
|
}));
|
||||||
|
|
||||||
render(<NetworkSwitcher />);
|
render(<NetworkSwitcher />);
|
||||||
|
|
||||||
await userEvent.click(screen.getByRole('button'));
|
await userEvent.click(screen.getByTestId('network-switcher'));
|
||||||
await userEvent.click(
|
|
||||||
screen.getByRole('menuitem', { name: t('Advanced') })
|
|
||||||
);
|
|
||||||
|
|
||||||
[Networks.MAINNET, Networks.TESTNET, Networks.DEVNET].forEach((network) => {
|
|
||||||
expect(
|
expect(
|
||||||
screen.getByRole('link', { name: envNameMapping[network] })
|
await screen.findByRole('menuitem', { name: t('Advanced') })
|
||||||
).toHaveAttribute('href', VEGA_NETWORKS[network]);
|
|
||||||
expect(
|
|
||||||
screen.getByText(envDescriptionMapping[network])
|
|
||||||
).toBeInTheDocument();
|
).toBeInTheDocument();
|
||||||
});
|
|
||||||
});
|
await userEvent.click(
|
||||||
|
screen.getByRole('menuitem', { name: t('Advanced') })
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
await screen.findByText(envDescriptionMapping[network])
|
||||||
|
).toBeInTheDocument();
|
||||||
|
expect(
|
||||||
|
screen.getByRole('link', {
|
||||||
|
name: new RegExp(`^${envNameMapping[network]}`),
|
||||||
|
})
|
||||||
|
).toBeInTheDocument();
|
||||||
|
|
||||||
|
await userEvent.click(
|
||||||
|
screen.getByRole('link', {
|
||||||
|
name: new RegExp(`^${envNameMapping[network]}`),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(hrefSetSpy).toHaveBeenCalledWith(VEGA_NETWORKS[network]);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
it('labels the selected network in the advanced view', async () => {
|
it('labels the selected network in the advanced view', async () => {
|
||||||
const selectedNetwork = Networks.DEVNET;
|
const selectedNetwork = Networks.DEVNET;
|
||||||
@ -188,7 +229,7 @@ describe('Network switcher', () => {
|
|||||||
const label = screen.getByText(`(${t('current')})`);
|
const label = screen.getByText(`(${t('current')})`);
|
||||||
|
|
||||||
expect(label).toBeInTheDocument();
|
expect(label).toBeInTheDocument();
|
||||||
expect(label.parentNode?.firstElementChild).toHaveTextContent(
|
expect(label.parentNode?.parentNode?.firstElementChild).toHaveTextContent(
|
||||||
envNameMapping[selectedNetwork]
|
envNameMapping[selectedNetwork]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -217,7 +258,7 @@ describe('Network switcher', () => {
|
|||||||
const label = screen.getByText('(not available)');
|
const label = screen.getByText('(not available)');
|
||||||
|
|
||||||
expect(label).toBeInTheDocument();
|
expect(label).toBeInTheDocument();
|
||||||
expect(label.parentNode?.firstElementChild).toHaveTextContent(
|
expect(label.parentNode?.parentNode?.firstElementChild).toHaveTextContent(
|
||||||
envNameMapping[Networks.MAINNET]
|
envNameMapping[Networks.MAINNET]
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { useState, useCallback, useRef } from 'react';
|
import { useState, useCallback } from 'react';
|
||||||
import { t } from '@vegaprotocol/i18n';
|
import { t } from '@vegaprotocol/i18n';
|
||||||
import {
|
import {
|
||||||
Link,
|
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
DropdownMenuItem,
|
DropdownMenuItem,
|
||||||
@ -99,7 +98,6 @@ export const NetworkSwitcher = ({
|
|||||||
},
|
},
|
||||||
[setOpen, setAdvancedView]
|
[setOpen, setAdvancedView]
|
||||||
);
|
);
|
||||||
const menuRef = useRef<HTMLButtonElement | null>(null);
|
|
||||||
|
|
||||||
const current = currentNetwork || VEGA_ENV;
|
const current = currentNetwork || VEGA_ENV;
|
||||||
|
|
||||||
@ -110,7 +108,6 @@ export const NetworkSwitcher = ({
|
|||||||
trigger={
|
trigger={
|
||||||
<DropdownMenuTrigger
|
<DropdownMenuTrigger
|
||||||
data-testid="network-switcher"
|
data-testid="network-switcher"
|
||||||
ref={menuRef}
|
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'flex justify-between items-center text-sm text-vega-dark-600 dark:text-vega-light-600 py-1 px-2 rounded border border-vega-dark-200 whitespace-nowrap dark:hover:bg-vega-dark-500 hover:bg-vega-light-500',
|
'flex justify-between items-center text-sm text-vega-dark-600 dark:text-vega-light-600 py-1 px-2 rounded border border-vega-dark-200 whitespace-nowrap dark:hover:bg-vega-dark-500 hover:bg-vega-light-500',
|
||||||
className
|
className
|
||||||
@ -123,10 +120,7 @@ export const NetworkSwitcher = ({
|
|||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<DropdownMenuContent
|
<DropdownMenuContent align="start">
|
||||||
align="start"
|
|
||||||
style={{ minWidth: `${menuRef.current?.offsetWidth || 290}px` }}
|
|
||||||
>
|
|
||||||
{!isAdvancedView && (
|
{!isAdvancedView && (
|
||||||
<>
|
<>
|
||||||
{standardNetworkKeys.map((key) => (
|
{standardNetworkKeys.map((key) => (
|
||||||
@ -134,14 +128,16 @@ export const NetworkSwitcher = ({
|
|||||||
key={key}
|
key={key}
|
||||||
data-testid="network-item"
|
data-testid="network-item"
|
||||||
disabled={!VEGA_NETWORKS[key]}
|
disabled={!VEGA_NETWORKS[key]}
|
||||||
|
role="link"
|
||||||
|
onClick={() =>
|
||||||
|
(window.location.href = VEGA_NETWORKS[key] || '')
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<a href={VEGA_NETWORKS[key]}>
|
{envNameMapping[key]}
|
||||||
{envNameMapping[key]}
|
<NetworkLabel
|
||||||
<NetworkLabel
|
isCurrent={current === key}
|
||||||
isCurrent={current === key}
|
isAvailable={!!VEGA_NETWORKS[key]}
|
||||||
isAvailable={!!VEGA_NETWORKS[key]}
|
/>
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
))}
|
))}
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
@ -159,10 +155,17 @@ export const NetworkSwitcher = ({
|
|||||||
{isAdvancedView && (
|
{isAdvancedView && (
|
||||||
<>
|
<>
|
||||||
{advancedNetworkKeys.map((key) => (
|
{advancedNetworkKeys.map((key) => (
|
||||||
<DropdownMenuItem key={key} data-testid="network-item-advanced">
|
<DropdownMenuItem
|
||||||
|
key={key}
|
||||||
|
data-testid="network-item-advanced"
|
||||||
|
role="link"
|
||||||
|
onClick={() =>
|
||||||
|
(window.location.href = VEGA_NETWORKS[key] || '')
|
||||||
|
}
|
||||||
|
>
|
||||||
<div className="w-full flex justify-between gap-2">
|
<div className="w-full flex justify-between gap-2">
|
||||||
<div>
|
<div>
|
||||||
<Link href={VEGA_NETWORKS[key]}>{envNameMapping[key]}</Link>
|
{envNameMapping[key]}
|
||||||
<NetworkLabel
|
<NetworkLabel
|
||||||
isCurrent={current === key}
|
isCurrent={current === key}
|
||||||
isAvailable={!!VEGA_NETWORKS[key]}
|
isAvailable={!!VEGA_NETWORKS[key]}
|
||||||
|
Loading…
Reference in New Issue
Block a user