diff --git a/.eslintrc.yml b/.eslintrc.yml
index f65f43d3..70a0b06e 100644
--- a/.eslintrc.yml
+++ b/.eslintrc.yml
@@ -4,3 +4,4 @@ extends:
rules:
'@typescript-eslint/no-dynamic-delete': off
'import/namespace': off
+ 'jest/no-standalone-expect': off
diff --git a/src/createSVG.ts b/src/createSVG.ts
new file mode 100644
index 00000000..58512250
--- /dev/null
+++ b/src/createSVG.ts
@@ -0,0 +1,9 @@
+import { createElement } from 'react';
+import { renderToString } from 'react-dom/server';
+
+import { PlotObject, PlotObjectProps } from './components/PlotObject';
+
+export function createSVG(param: PlotObjectProps) {
+ const plot = createElement(PlotObject, param);
+ return renderToString(plot);
+}
diff --git a/src/index.ts b/src/index.ts
index 7073e29b..a940e0fa 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -38,3 +38,5 @@ export {
usePlotControls,
usePlotEvents,
} from './contexts/plotController/plotControllerContext';
+
+export * from './createSVG';
diff --git a/tests/serverside.test.tsx b/tests/serverside.test.tsx
index 811dacf3..4f606acc 100644
--- a/tests/serverside.test.tsx
+++ b/tests/serverside.test.tsx
@@ -1,8 +1,16 @@
import { test, expect } from '@playwright/experimental-ct-react';
-import { ServerSide } from './utils';
+
+import { InfraredPlotTest, ServerSide } from './utils';
test('should render a plot in server-side mode', async ({ mount }) => {
- const plot = await mount();
- const html = await plot.innerHTML();
- expect(html).toContain('svg');
+ const serverPlot = await mount();
+ const clientPlot = await mount();
+ const ServerHtml = await serverPlot.innerHTML();
+ const ClientHtml = await clientPlot.innerHTML();
+ expect(ServerHtml).toBe(ClientHtml);
+
+ // compare screen shots
+ const serverImage = await serverPlot.screenshot();
+ const clientImage = await clientPlot.screenshot();
+ expect(serverImage).toStrictEqual(clientImage);
});
diff --git a/tests/utils.tsx b/tests/utils.tsx
index e6069be9..682bc725 100644
--- a/tests/utils.tsx
+++ b/tests/utils.tsx
@@ -1,7 +1,14 @@
-import { ReactNode, useState } from 'react';
-import { renderToStaticMarkup } from 'react-dom/server';
+import { ReactNode, useState, useEffect } from 'react';
+import { hydrate } from 'react-dom';
-import { Annotations, Plot, ScatterSeries } from '../src';
+import {
+ PlotObject,
+ PlotObjectPlot,
+ Annotations,
+ createSVG,
+ Plot,
+ ScatterSeries,
+} from '../src';
import { Arrow } from '../src/components/Annotations/Arrow';
import { DirectedEllipse } from '../src/components/Annotations/DirectedEllipse';
import infrared from '../stories/data/infrared.json';
@@ -14,9 +21,38 @@ interface ChildrenProps {
export function DefaultPlotTest({ children }: ChildrenProps) {
return {children};
}
+const plot: PlotObjectPlot = {
+ dimensions: DEFAULT_PLOT_CONFIG,
+ axes: [
+ {
+ type: 'main',
+ position: 'bottom',
+ },
+ {
+ type: 'main',
+ position: 'left',
+ },
+ ],
+ content: [
+ {
+ type: 'line',
+ data: infrared,
+ },
+ ],
+};
export function ServerSide() {
- const html = renderToStaticMarkup();
- return
;
+ const [result, setResult] = useState(null);
+
+ useEffect(() => {
+ const html = createSVG({ plot });
+ const rootElement = document.querySelector('root');
+ if (rootElement === null) throw new Error('Root element not found');
+ rootElement.innerHTML = html;
+ const result = hydrate(, rootElement);
+ setResult(result);
+ }, []);
+
+ return result;
}
export function InfraredPlotTest({ children }: ChildrenProps) {
return (