mirror of
https://github.com/lux-tel/session-desktop.git
synced 2026-10-30 20:33:24 +00:00
100 lines
3.1 KiB
TypeScript
100 lines
3.1 KiB
TypeScript
/* eslint-disable import/no-extraneous-dependencies */
|
|
import type { ReactElement, ReactNode, SessionDataTestId } from 'react';
|
|
import { AnimatePresence, MotionGlobalConfig } from 'framer-motion';
|
|
import { render, RenderResult, screen, within } from '@testing-library/react';
|
|
import { ErrorBoundary } from 'react-error-boundary';
|
|
import { Provider } from 'react-redux';
|
|
import useMount from 'react-use/lib/useMount';
|
|
import { SessionTheme } from '../../themes/SessionTheme';
|
|
import { themeStore } from '../../state/theme/store';
|
|
|
|
const Providers = ({ children }: { children: ReactNode }) => {
|
|
useMount(() => {
|
|
MotionGlobalConfig.skipAnimations = false;
|
|
});
|
|
|
|
return (
|
|
<Provider store={themeStore}>
|
|
<SessionTheme>
|
|
<AnimatePresence>
|
|
<ErrorBoundary
|
|
fallback={<>{`Failed to render a component!\n\t${JSON.stringify(children)}`}</>}
|
|
>
|
|
{children}
|
|
</ErrorBoundary>
|
|
</AnimatePresence>
|
|
</SessionTheme>
|
|
</Provider>
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Renders a component wrapped with all necessary providers.
|
|
* Returns the render result from @testing-library/react.
|
|
*/
|
|
function renderComponent(children: ReactElement<any>): RenderResult {
|
|
return render(<Providers>{children}</Providers>);
|
|
}
|
|
|
|
/**
|
|
* Finds an element by its data-testid attribute.
|
|
* Throws if not found.
|
|
*/
|
|
function findByDataTestId(renderResult: RenderResult, dataTestId: SessionDataTestId): HTMLElement {
|
|
return within(renderResult.container).getByTestId(dataTestId);
|
|
}
|
|
|
|
/**
|
|
* Finds all elements matching a given role.
|
|
* Use this as a replacement for findAllByElementType.
|
|
* Common roles: 'button', 'textbox', 'img', 'link', 'checkbox', etc.
|
|
* For SVGs, use queryAllByRole or container.querySelectorAll.
|
|
*/
|
|
function findAllByRole(renderResult: RenderResult, role: string): Array<HTMLElement> {
|
|
return within(renderResult.container).queryAllByRole(role);
|
|
}
|
|
|
|
/**
|
|
* Finds all elements by tag name (useful for elements like 'input', 'svg', etc.)
|
|
* This is a direct replacement for findAllByElementType when you need to query by tag.
|
|
*/
|
|
function findAllByTagName<T extends Element = HTMLElement>(
|
|
renderResult: RenderResult,
|
|
tagName: string
|
|
): Array<T> {
|
|
return Array.from(renderResult.container.querySelectorAll<T>(tagName));
|
|
}
|
|
|
|
/**
|
|
* Compares two render results for equality.
|
|
* Note: This is a simplified comparison using container innerHTML.
|
|
* For more robust comparisons, consider snapshot testing with Jest.
|
|
*/
|
|
function expectContainersToBeEqual(renderResult: RenderResult, renderResult2: RenderResult) {
|
|
// Remove data-testid attributes for comparison
|
|
const cleanHtml = (container: HTMLElement): string => {
|
|
const clone = container.cloneNode(true) as HTMLElement;
|
|
clone.querySelectorAll('[data-testid]').forEach(el => {
|
|
el.removeAttribute('data-testid');
|
|
});
|
|
return clone.innerHTML;
|
|
};
|
|
|
|
const html1 = cleanHtml(renderResult.container);
|
|
const html2 = cleanHtml(renderResult2.container);
|
|
|
|
if (html1 !== html2) {
|
|
throw new Error('Rendered outputs are not equal');
|
|
}
|
|
}
|
|
|
|
export {
|
|
expectContainersToBeEqual,
|
|
findAllByRole,
|
|
findAllByTagName,
|
|
findByDataTestId,
|
|
renderComponent,
|
|
screen,
|
|
within,
|
|
};
|