mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2026-10-19 20:24:16 +00:00
Replace @testing-library/jest-dom with built-in vitest browser assertions
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { act, screen, waitFor } from '@testing-library/react';
|
||||
import { page } from 'vitest/browser';
|
||||
import { AppUpdateBanner } from '../../src/common/AppUpdateBanner';
|
||||
import { checkAccessibility } from '../__helpers__/accessibility';
|
||||
import { renderWithEvents } from '../__helpers__/setUpTest';
|
||||
@@ -6,40 +6,33 @@ import { renderWithEvents } from '../__helpers__/setUpTest';
|
||||
describe('<AppUpdateBanner />', () => {
|
||||
const onClose = vi.fn();
|
||||
const forceUpdate = vi.fn();
|
||||
const setUp = async () => {
|
||||
const result = await act(() =>
|
||||
renderWithEvents(<AppUpdateBanner isOpen onClose={onClose} forceUpdate={forceUpdate} />),
|
||||
);
|
||||
await waitFor(() => screen.getByRole('alert'));
|
||||
|
||||
return result;
|
||||
};
|
||||
const setUp = () => renderWithEvents(<AppUpdateBanner isOpen onClose={onClose} forceUpdate={forceUpdate} />);
|
||||
|
||||
it('passes a11y checks', () => checkAccessibility(setUp()));
|
||||
|
||||
it('renders initial state', async () => {
|
||||
await setUp();
|
||||
setUp();
|
||||
|
||||
expect(screen.getByRole('heading')).toHaveTextContent('This app has just been updated!');
|
||||
expect(screen.queryByText('Restarting...')).not.toBeInTheDocument();
|
||||
expect(screen.getByText('Restart now')).not.toHaveAttribute('disabled');
|
||||
await expect.element(page.getByRole('heading')).toHaveTextContent('This app has just been updated!');
|
||||
await expect.element(page.getByText('Restarting...')).not.toBeInTheDocument();
|
||||
await expect.element(page.getByText('Restart now')).not.toHaveAttribute('disabled');
|
||||
});
|
||||
|
||||
it('invokes toggle when alert is closed', async () => {
|
||||
const { user } = await setUp();
|
||||
const { user } = setUp();
|
||||
|
||||
expect(onClose).not.toHaveBeenCalled();
|
||||
await user.click(screen.getByLabelText('Close'));
|
||||
await user.click(page.getByLabelText('Close'));
|
||||
expect(onClose).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('triggers the update when clicking the button', async () => {
|
||||
const { user } = await setUp();
|
||||
const { user } = setUp();
|
||||
|
||||
expect(forceUpdate).not.toHaveBeenCalled();
|
||||
await user.click(screen.getByText(/^Restart now/));
|
||||
await user.click(page.getByText(/^Restart now/));
|
||||
expect(forceUpdate).toHaveBeenCalled();
|
||||
expect(await screen.findByText('Restarting...')).toBeInTheDocument();
|
||||
expect(screen.queryByText(/^Restart now/)).not.toBeInTheDocument();
|
||||
await expect.element(page.getByText('Restarting...')).toBeInTheDocument();
|
||||
await expect.element(page.getByText(/^Restart now/)).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { screen } from '@testing-library/react';
|
||||
import { fromPartial } from '@total-typescript/shoehorn';
|
||||
import type { PropsWithChildren, ReactNode } from 'react';
|
||||
import { ErrorHandler as BaseErrorHandler } from '../../src/common/ErrorHandler';
|
||||
import type { ReactNode } from 'react';
|
||||
import { page } from 'vitest/browser';
|
||||
import { ErrorHandler } from '../../src/common/ErrorHandler';
|
||||
import { checkAccessibility } from '../__helpers__/accessibility';
|
||||
import { renderWithEvents } from '../__helpers__/setUpTest';
|
||||
|
||||
@@ -13,8 +13,12 @@ describe('<ErrorHandler />', () => {
|
||||
const reload = vi.fn();
|
||||
const location = fromPartial<Window['location']>({ reload });
|
||||
const cons = fromPartial<Console>({ error: vi.fn() });
|
||||
const ErrorHandler = (props: PropsWithChildren) => <BaseErrorHandler console={cons} location={location} {...props} />;
|
||||
const setUp = (children: ReactNode = 'Error') => renderWithEvents(<ErrorHandler>{children}</ErrorHandler>);
|
||||
const setUp = (children: ReactNode = 'Error') =>
|
||||
renderWithEvents(
|
||||
<ErrorHandler console={cons} location={location}>
|
||||
{children}
|
||||
</ErrorHandler>,
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
vi.spyOn(console, 'error').mockImplementation(() => {}); // Silence react errors
|
||||
@@ -22,26 +26,26 @@ describe('<ErrorHandler />', () => {
|
||||
|
||||
it('passes a11y checks', () => checkAccessibility(setUp()));
|
||||
|
||||
it('renders children when no error has occurred', () => {
|
||||
it('renders children when no error has occurred', async () => {
|
||||
setUp(<span>Foo</span>);
|
||||
|
||||
expect(screen.getByText('Foo')).toBeInTheDocument();
|
||||
expect(screen.queryByText('Oops! This is awkward :S')).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole('button')).not.toBeInTheDocument();
|
||||
await expect.element(page.getByText('Foo')).toBeInTheDocument();
|
||||
await expect.element(page.getByText('Oops! This is awkward :S')).not.toBeInTheDocument();
|
||||
await expect.element(page.getByRole('button')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders error page when error has occurred', () => {
|
||||
it('renders error page when error has occurred', async () => {
|
||||
setUp(<ComponentWithError />);
|
||||
|
||||
expect(screen.getByText('Oops! This is awkward :S')).toBeInTheDocument();
|
||||
expect(screen.getByRole('button')).toBeInTheDocument();
|
||||
await expect.element(page.getByText('Oops! This is awkward :S')).toBeInTheDocument();
|
||||
await expect.element(page.getByRole('button')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('reloads page on button click', async () => {
|
||||
const { user } = setUp(<ComponentWithError />);
|
||||
|
||||
expect(reload).not.toHaveBeenCalled();
|
||||
await user.click(screen.getByRole('button'));
|
||||
await user.click(page.getByRole('button'));
|
||||
expect(reload).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { screen } from '@testing-library/react';
|
||||
import { fromPartial } from '@total-typescript/shoehorn';
|
||||
import { MemoryRouter } from 'react-router';
|
||||
import { page } from 'vitest/browser';
|
||||
import { Home } from '../../src/common/Home';
|
||||
import type { ServersMap, ServerWithId } from '../../src/servers/data';
|
||||
import { checkAccessibility } from '../__helpers__/accessibility';
|
||||
@@ -20,9 +20,9 @@ describe('<Home />', () => {
|
||||
it('passes a11y checks', () =>
|
||||
checkAccessibility(setUp({ '1a': fromPartial<ServerWithId>({ name: 'foo', id: '1' }) })));
|
||||
|
||||
it('renders title', () => {
|
||||
it('renders title', async () => {
|
||||
setUp();
|
||||
expect(screen.getByRole('heading', { name: 'Welcome!' })).toBeInTheDocument();
|
||||
await expect.element(page.getByRole('heading', { name: 'Welcome!' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it.each([
|
||||
@@ -35,15 +35,17 @@ describe('<Home />', () => {
|
||||
3,
|
||||
],
|
||||
[{}, 2],
|
||||
])('shows link to create or set-up server only when no servers exist', (servers, expectedServers) => {
|
||||
])('shows link to create or set-up server only when no servers exist', async (servers, expectedServers) => {
|
||||
setUp(servers);
|
||||
const links = screen.getAllByRole('link');
|
||||
const links = page.getByRole('link').elements();
|
||||
|
||||
expect(links).toHaveLength(expectedServers);
|
||||
|
||||
if (Object.keys(servers).length === 0) {
|
||||
expect(screen.getByText('This application will help you manage your Shlink servers.')).toBeInTheDocument();
|
||||
expect(screen.getByText('Learn more about Shlink')).toBeInTheDocument();
|
||||
await expect
|
||||
.element(page.getByText('This application will help you manage your Shlink servers.'))
|
||||
.toBeInTheDocument();
|
||||
await expect.element(page.getByText('Learn more about Shlink')).toBeInTheDocument();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { screen } from '@testing-library/react';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { Router } from 'react-router';
|
||||
import { page } from 'vitest/browser';
|
||||
import { MainHeader } from '../../src/common/MainHeader';
|
||||
import { checkAccessibility } from '../__helpers__/accessibility';
|
||||
import { renderWithStore } from '../__helpers__/setUpTest';
|
||||
@@ -19,9 +19,9 @@ describe('<MainHeader />', () => {
|
||||
|
||||
it('passes a11y checks', () => checkAccessibility(setUp()));
|
||||
|
||||
it('renders ServersDropdown', () => {
|
||||
it('renders ServersDropdown', async () => {
|
||||
setUp();
|
||||
expect(screen.getByRole('button', { name: 'Servers' })).toBeInTheDocument();
|
||||
await expect.element(page.getByRole('button', { name: 'Servers' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it.each([
|
||||
@@ -30,11 +30,10 @@ describe('<MainHeader />', () => {
|
||||
['/settings', true],
|
||||
['/settings/foo', true],
|
||||
['/settings/bar', true],
|
||||
])('sets link to settings as active only when current path is settings', (currentPath, isActive) => {
|
||||
])('sets link to settings as active only when current path is settings', async (currentPath, isActive) => {
|
||||
setUp(currentPath);
|
||||
expect(screen.getByRole('menuitem', { name: /Settings$/ })).toHaveAttribute(
|
||||
'data-active',
|
||||
isActive ? 'true' : 'false',
|
||||
);
|
||||
await expect
|
||||
.element(page.getByRole('menuitem', { name: /Settings$/ }))
|
||||
.toHaveAttribute('data-active', isActive ? 'true' : 'false');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,29 +13,31 @@ describe('<NotFound />', () => {
|
||||
|
||||
it('passes a11y checks', () => checkAccessibility(setUp()));
|
||||
|
||||
it('shows expected error title', () => {
|
||||
it('shows expected error title', async () => {
|
||||
setUp();
|
||||
expect(screen.getByText('Oops! We could not find requested route.')).toBeInTheDocument();
|
||||
await expect.element(screen.getByText('Oops! We could not find requested route.')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows expected error message', () => {
|
||||
it('shows expected error message', async () => {
|
||||
setUp();
|
||||
expect(
|
||||
screen.getByText(
|
||||
"Use your browser's back button to navigate to the page you have previously come from, or just press this button.",
|
||||
),
|
||||
).toBeInTheDocument();
|
||||
await expect
|
||||
.element(
|
||||
screen.getByText(
|
||||
"Use your browser's back button to navigate to the page you have previously come from, or just press this button.",
|
||||
),
|
||||
)
|
||||
.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it.each([
|
||||
[{}, '/', 'Home'],
|
||||
[{ to: '/foo/bar', children: 'Hello' }, '/foo/bar', 'Hello'],
|
||||
[{ to: '/baz-bar', children: <>Foo</> }, '/baz-bar', 'Foo'],
|
||||
])('shows expected link and text', (props, expectedLink, expectedText) => {
|
||||
])('shows expected link and text', async (props, expectedLink, expectedText) => {
|
||||
setUp(props);
|
||||
const link = screen.getByRole('link');
|
||||
|
||||
expect(link).toHaveAttribute('href', expectedLink);
|
||||
expect(link).toHaveTextContent(expectedText);
|
||||
await expect.element(link).toHaveAttribute('href', expectedLink);
|
||||
await expect.element(link).toHaveTextContent(expectedText);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,8 +13,8 @@ describe('<ScrollToTop />', () => {
|
||||
|
||||
it('passes a11y checks', () => checkAccessibility(setUp()));
|
||||
|
||||
it.each([['Foobar'], ['Barfoo'], ['Something']])('just renders children', (children) => {
|
||||
it.each([['Foobar'], ['Barfoo'], ['Something']])('just renders children', async (children) => {
|
||||
setUp(children);
|
||||
expect(screen.getByText(children)).toBeInTheDocument();
|
||||
await expect.element(screen.getByText(children)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,20 +19,18 @@ describe('<ShlinkVersions />', () => {
|
||||
['not-semver', fromPartial<ReachableServer>({ version: '1.0.0', printableVersion: 'some' }), 'latest', 'some'],
|
||||
])(
|
||||
'displays expected versions when selected server is reachable',
|
||||
(clientVersion, selectedServer, expectedClientVersion, expectedServerVersion) => {
|
||||
async (clientVersion, selectedServer, expectedClientVersion, expectedServerVersion) => {
|
||||
setUp({ clientVersion, selectedServer });
|
||||
const [serverLink, clientLink] = screen.getAllByRole('link');
|
||||
|
||||
expect(serverLink).toHaveAttribute(
|
||||
'href',
|
||||
`https://github.com/shlinkio/shlink/releases/${expectedServerVersion}`,
|
||||
);
|
||||
expect(serverLink).toHaveTextContent(expectedServerVersion);
|
||||
expect(clientLink).toHaveAttribute(
|
||||
'href',
|
||||
`https://github.com/shlinkio/shlink-web-client/releases/${expectedClientVersion}`,
|
||||
);
|
||||
expect(clientLink).toHaveTextContent(expectedClientVersion);
|
||||
await expect
|
||||
.element(serverLink)
|
||||
.toHaveAttribute('href', `https://github.com/shlinkio/shlink/releases/${expectedServerVersion}`);
|
||||
await expect.element(serverLink).toHaveTextContent(expectedServerVersion);
|
||||
await expect
|
||||
.element(clientLink)
|
||||
.toHaveAttribute('href', `https://github.com/shlinkio/shlink-web-client/releases/${expectedClientVersion}`);
|
||||
await expect.element(clientLink).toHaveTextContent(expectedClientVersion);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -40,11 +38,13 @@ describe('<ShlinkVersions />', () => {
|
||||
['1.2.3', null],
|
||||
['1.2.3', fromPartial<NotFoundServer>({ serverNotFound: true })],
|
||||
['1.2.3', fromPartial<NonReachableServer>({ serverNotReachable: true })],
|
||||
])('displays only client version when selected server is not reachable', (clientVersion, selectedServer) => {
|
||||
])('displays only client version when selected server is not reachable', async (clientVersion, selectedServer) => {
|
||||
setUp({ clientVersion, selectedServer });
|
||||
const links = screen.getAllByRole('link');
|
||||
|
||||
expect(links).toHaveLength(1);
|
||||
expect(links[0]).toHaveAttribute('href', 'https://github.com/shlinkio/shlink-web-client/releases/v1.2.3');
|
||||
await expect
|
||||
.element(links[0])
|
||||
.toHaveAttribute('href', 'https://github.com/shlinkio/shlink-web-client/releases/v1.2.3');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,13 +20,13 @@ describe('<ShlinkVersionsContainer />', () => {
|
||||
[null, false],
|
||||
[fromPartial<SelectedServer>({}), false],
|
||||
[fromPartial<ReachableServer>({ version: '1.0.0' }), true],
|
||||
])('renders proper col classes based on sidebar status', (selectedServer, shouldAddMargin) => {
|
||||
])('renders proper col classes based on sidebar status', async (selectedServer, shouldAddMargin) => {
|
||||
const { container } = setUp(selectedServer);
|
||||
|
||||
if (shouldAddMargin) {
|
||||
expect(container.firstChild).toHaveClass('md:ml-(--aside-menu-width)');
|
||||
await expect.element(container.firstChild as HTMLElement).toHaveClass('md:ml-(--aside-menu-width)');
|
||||
} else {
|
||||
expect(container.firstChild).not.toHaveClass('md:ml-(--aside-menu-width)');
|
||||
await expect.element(container.firstChild as HTMLElement).not.toHaveClass('md:ml-(--aside-menu-width)');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { screen } from '@testing-library/react';
|
||||
import { fromPartial } from '@total-typescript/shoehorn';
|
||||
import { MemoryRouter } from 'react-router';
|
||||
import { page } from 'vitest/browser';
|
||||
import { ShlinkWebComponentContainer } from '../../src/common/ShlinkWebComponentContainer';
|
||||
import type { NonReachableServer, NotFoundServer, SelectedServer } from '../../src/servers/data';
|
||||
import { checkAccessibility } from '../__helpers__/accessibility';
|
||||
@@ -25,11 +25,11 @@ describe('<ShlinkWebComponentContainer />', () => {
|
||||
|
||||
it('passes a11y checks', () => checkAccessibility(setUp(fromPartial({ version: '3.0.0' }))));
|
||||
|
||||
it('shows loading indicator while loading server', () => {
|
||||
it('shows loading indicator while loading server', async () => {
|
||||
setUp(null);
|
||||
|
||||
expect(screen.getByText('Loading...')).toBeInTheDocument();
|
||||
expect(screen.queryByText('ShlinkWebComponent')).not.toBeInTheDocument();
|
||||
await expect.element(page.getByText('Loading...')).toBeInTheDocument();
|
||||
await expect.element(page.getByText('ShlinkWebComponent')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it.each([
|
||||
@@ -38,18 +38,18 @@ describe('<ShlinkWebComponentContainer />', () => {
|
||||
fromPartial<NonReachableServer>({ id: 'foo', serverNotReachable: true }),
|
||||
/Could not connect to this Shlink server/,
|
||||
],
|
||||
])('shows error for non reachable servers', (selectedServer, expectedError) => {
|
||||
])('shows error for non reachable servers', async (selectedServer, expectedError) => {
|
||||
setUp(selectedServer);
|
||||
|
||||
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
||||
expect(screen.getByText(expectedError)).toBeInTheDocument();
|
||||
expect(screen.queryByText('ShlinkWebComponent')).not.toBeInTheDocument();
|
||||
await expect.element(page.getByText('Loading...')).not.toBeInTheDocument();
|
||||
await expect.element(page.getByText(expectedError)).toBeInTheDocument();
|
||||
await expect.element(page.getByText('ShlinkWebComponent')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders ShlinkWebComponent for reachable servers', () => {
|
||||
it('renders ShlinkWebComponent for reachable servers', async () => {
|
||||
setUp(fromPartial({ version: '3.0.0' }));
|
||||
|
||||
expect(screen.queryByText('Loading...')).not.toBeInTheDocument();
|
||||
expect(screen.getByText('ShlinkWebComponent')).toBeInTheDocument();
|
||||
await expect.element(page.getByText('Loading...')).not.toBeInTheDocument();
|
||||
await expect.element(page.getByText('ShlinkWebComponent')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,22 +13,22 @@ describe('<ShlinkLogo />', () => {
|
||||
[undefined, brandColor()],
|
||||
['red', 'red'],
|
||||
['white', 'white'],
|
||||
])('renders expected color', (color, expectedColor) => {
|
||||
])('renders expected color', async (color, expectedColor) => {
|
||||
const { container } = setUp({ color });
|
||||
expect(container.querySelector('g')).toHaveAttribute('fill', expectedColor);
|
||||
await expect.element(container.querySelector('g')).toHaveAttribute('fill', expectedColor);
|
||||
});
|
||||
|
||||
it.each([
|
||||
[undefined, undefined],
|
||||
['foo', 'foo'],
|
||||
['bar', 'bar'],
|
||||
])('renders expected class', (className, expectedClassName) => {
|
||||
])('renders expected class', async (className, expectedClassName) => {
|
||||
const { container } = setUp({ className });
|
||||
|
||||
if (expectedClassName) {
|
||||
expect(container.firstChild).toHaveAttribute('class', expectedClassName);
|
||||
await expect.element(container.firstChild as HTMLElement).toHaveAttribute('class', expectedClassName);
|
||||
} else {
|
||||
expect(container.firstChild).not.toHaveAttribute('class');
|
||||
await expect.element(container.firstChild as HTMLElement).not.toHaveAttribute('class');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user