/** * @jest-environment node */ import { renderToString } from 'react-dom/server'; import en from './i18n/en.json'; import * as exposedLibraryItems from '.'; type ExposedLibraryItemsType = typeof exposedLibraryItems; type ExposedLibraryKeysType = keyof ExposedLibraryItemsType; const excluded = new Set([ // hooks 'useSnackbar', 'useDirection', 'useLayout', 'useScreenSize', // specific components 'Provider', 'BottomSheet', 'DropFade', 'SelectInputTriggerButton', 'Panel', 'ResponsivePanel', // enums 'Size', 'Width', 'Sentiment', 'Variant', 'Priority', 'ControlType', 'Type', 'Theme', 'DateMode', 'MonthFormat', 'Position', 'Scroll', 'ProfileType', 'Breakpoint', 'Layout', 'Status', 'MarkdownNodeType', 'AvatarType', 'InfoPresentation', 'UploadStep', 'DecisionPresentation', 'DecisionType', 'AlertArrowPosition', 'LogoType', 'FileType', 'Direction', 'Typography', // types 'SearchInputProps', 'SelectInputItem', 'SelectInputOptionContentProps', 'SelectInputProps', 'UploadedFile', 'UploadError', 'UploadResponse', 'LayoutDirection', // utils 'SUPPORTED_LANGUAGES', 'RTL_LANGUAGES', 'DEFAULT_LANG', 'DEFAULT_LOCALE', 'adjustLocale', 'getLangFromLocale', 'getCountryFromLocale', 'getDirectionFromLocale', 'getLocaleCurrencyName', 'isServerSide', 'isBrowser', // other 'translations', ]); function isNotExcluded(item: ExposedLibraryKeysType) { return !excluded.has(item); } describe('Server side rendering', () => { const componentNames = ( Object.keys(exposedLibraryItems) as (keyof ExposedLibraryItemsType)[] ).filter((moduleName) => isNotExcluded(moduleName)); // stick all possible properties we might need to render all components in here const allProps: Record = { actionPrimary: { label: 'Action', onClick: jest.fn(), href: '#' }, currencies: [], currencySelector: { options: [] }, steps: [], stepper: { steps: [], }, items: [], children: 'yo', id: '1', text: 'test', timeout: 0, timestamp: 1, title: 'trolo', name: 'lolo', label: 'hello', content: 'world', currency: 'XYZ', amount: 0, options: [], model: {}, fields: {}, media:

Hello

, onClick: jest.fn(), onChange: jest.fn(), status: 'processing', size: 'sm', body: 'body', onClose: jest.fn(), onDismiss: jest.fn(), onRemove: jest.fn(), radios: [ { id: 'id-test-0', label: 'Radio1', }, { id: 'id-test-0', label: 'Radio1', }, ], position: 'left', open: true, tabs: [], direction: { xs: 'column', sm: 'row', md: 'column', lg: 'row', }, alt: '', src: '', details: 'yo', icon: , badge: , link: 'link', href: '#', description: 'description', 'aria-label': 'a label', logo: , chips: [ { value: 1, label: 'One', }, { value: 2, label: 'Two', }, ], segments: [ { id: '1', value: 'accounting', label: 'Accounting', }, { id: '2', value: 'payroll', label: 'Payroll', }, { id: '3', value: 'reporting', label: 'Reporting', }, ], }; // Override props in case of name collision. const overrideProps: Partial>> = { ActionPrompt: { action: { label: 'Action', onClick: jest.fn(), href: '#' } }, Alert: { children: undefined, message: 'Fluffy kittens', size: undefined }, Card: { isExpanded: true }, CheckboxButton: { children: undefined, onChange: jest.fn() }, Typeahead: { size: 'md' }, InputWithDisplayFormat: { displayPattern: '**-**' }, TextareaWithDisplayFormat: { displayPattern: '**-**' }, Sticky: { position: 'top' }, MoneyInput: { selectedCurrency: { currency: 'EUR' } }, Tabs: { selected: 1, onTabSelect: jest.fn() }, Markdown: { children: '# Markdown string' }, SnackbarConsumer: { children: jest.fn(), }, SnackbarContext: { children: jest.fn(), }, Popover: { children:
, }, Progress: { progress: { value: 50, max: 100 }, }, ProgressBar: { progress: { value: 50, max: 100 }, }, Field: { model: 'a model', type: 'text', children: , }, Input: { children: undefined, }, SearchInput: { children: undefined, }, TextArea: { children: undefined, }, Summary: { status: 'done', content: undefined, }, Modal: { position: 'top' }, ActionOption: { action: 'hello' }, DateLookup: { value: new Date() }, Link: { size: 16 }, Tooltip: { children: <>yo }, }; const { Provider } = exposedLibraryItems; type ComponentWithProvider = React.ComponentType & { Provider?: React.ComponentType; }; componentNames.forEach((componentName: ExposedLibraryKeysType) => { it(`can render component: ${componentName}`, () => { const Component = exposedLibraryItems[componentName] as ComponentWithProvider; const newProps = { ...allProps }; Object.keys(overrideProps[componentName] ?? {}).forEach((propertyToOverrideKey) => { const key = propertyToOverrideKey as keyof (typeof overrideProps)[typeof componentName]; newProps[key] = overrideProps?.[componentName]?.[key]; }); const view = renderToString( {componentName.endsWith('Context') && Component.Provider ? ( ) : (
)}
, ); expect(view).toStrictEqual(expect.any(String)); }); }); });