/** * @jest-environment node */ /** @jsx jsx */ import { FC, ReactNode } from 'react'; import { renderToString } from 'react-dom/server'; import { hydrate } from 'react-dom'; import { JSDOM } from 'jsdom'; import { styleCollector, ServerProvider, serverRegistry, ThemeProvider, StyleCollector, jsx, useStyles, useGlobals, css, } from './'; interface ButtonProps { children: ReactNode; primary?: boolean; } interface Theme { default: string; primary: string; } describe('Server side rendering (SSR)', () => { let styles: (props: ButtonProps) => StyleCollector; let globalStyles: StyleCollector; let Button: FC; let theme: Theme; beforeEach(() => { theme = { default: '#b3cde8', primary: '#f95b5b', }; globalStyles = css` * { background-color: red; } `; styles = (props: ButtonProps) => styleCollector('button') .element` background-color: ${theme => theme.default}; color: white; `.modifier(props.primary)` background-color: ${theme => theme.primary}; color: #ffffff; `; Button = props => { const classNames = useStyles(styles(props)); return ; }; }); afterEach(() => { // @ts-ignore global.window = undefined; // @ts-ignore global.document = undefined; }); it('stringify styles on server and hydrate on client', () => { jest.spyOn(console, 'warn'); const App: FC = () => ( ); const registry = serverRegistry(); const html = renderToString( , ); const jsdom = new JSDOM(``); const { window } = jsdom; // @ts-ignore global.window = window; // @ts-ignore global.document = window.document; const root = document.createElement('div'); root.innerHTML = html; expect(() => hydrate(, root)).not.toThrow(); expect(html).toMatchSnapshot(); expect(registry.get()).toMatchSnapshot(); expect(console.warn).not.toHaveBeenCalled(); }); it('stringify styles(css prop) on server and hydrate on client', () => { jest.spyOn(console, 'warn'); Button = props => { return ; }; const App: FC = () => ( ); const registry = serverRegistry(); const html = renderToString( , ); const jsdom = new JSDOM(``); const { window } = jsdom; // @ts-ignore global.window = window; // @ts-ignore global.document = window.document; const root = document.createElement('div'); root.innerHTML = html; expect(() => hydrate(, root)).not.toThrow(); expect(html).toMatchSnapshot(); expect(registry.get()).toMatchSnapshot(); expect(console.warn).not.toHaveBeenCalled(); }); it('stringify globals on server and hydrate on client', () => { jest.spyOn(console, 'warn'); const App: FC = () => { useGlobals(globalStyles); return

Hello world

; }; const registry = serverRegistry(); const html = renderToString( , ); const jsdom = new JSDOM(``); const { window } = jsdom; // @ts-ignore global.window = window; // @ts-ignore global.document = window.document; const root = document.createElement('div'); root.innerHTML = html; expect(() => hydrate(, root)).not.toThrow(); expect(html).toMatchSnapshot(); expect(registry.get()).toMatchSnapshot(); expect(console.warn).not.toHaveBeenCalled(); }); it('throws if ServerProvider was not used with globals', () => { const App: FC = () => { useGlobals(globalStyles); return

Hello world

; }; expect(() => renderToString()).toThrowError( 'Server style registry is required for SSR, did you forget to use ?', ); }); it('throws if ServerProvider was not used', () => { const App: FC = () => ( ); expect(() => renderToString()).toThrowError( 'Server style registry is required for SSR, did you forget to use ?', ); }); });