diff --git a/.changeset/eleven-bobcats-peel.md b/.changeset/eleven-bobcats-peel.md index 75f7263e1f..e3dbcf911e 100644 --- a/.changeset/eleven-bobcats-peel.md +++ b/.changeset/eleven-bobcats-peel.md @@ -1,6 +1,6 @@ --- -'rrweb-snapshot': patch -'rrweb': patch +"rrweb-snapshot": patch +"rrweb": patch --- better support for coexistence with older libraries (e.g. MooTools & Prototype.js) which modify the in-built `Array.from` function diff --git a/.changeset/proud-clocks-hope.md b/.changeset/proud-clocks-hope.md new file mode 100644 index 0000000000..692b2081d0 --- /dev/null +++ b/.changeset/proud-clocks-hope.md @@ -0,0 +1,5 @@ +--- +"rrweb-snapshot": patch +--- + +(when `recordCanvas: true`): ensure we use doc.createElement instead of document.createElement to allow use in non-browser e.g. jsdom environments diff --git a/packages/rrweb-snapshot/src/rebuild.ts b/packages/rrweb-snapshot/src/rebuild.ts index 7c6ed948e6..2cb554cbfa 100644 --- a/packages/rrweb-snapshot/src/rebuild.ts +++ b/packages/rrweb-snapshot/src/rebuild.ts @@ -294,7 +294,7 @@ function buildNode( const value = specialAttributes[name]; // handle internal attributes if (tagName === 'canvas' && name === 'rr_dataURL') { - const image = document.createElement('img'); + const image = doc.createElement('img'); image.onload = () => { const ctx = (node as HTMLCanvasElement).getContext('2d'); if (ctx) { diff --git a/packages/rrweb-snapshot/src/snapshot.ts b/packages/rrweb-snapshot/src/snapshot.ts index 81dc2133a0..a0fc24921a 100644 --- a/packages/rrweb-snapshot/src/snapshot.ts +++ b/packages/rrweb-snapshot/src/snapshot.ts @@ -726,7 +726,7 @@ function serializeElementNode( ); // create blank canvas of same dimensions - const blankCanvas = document.createElement('canvas'); + const blankCanvas = doc.createElement('canvas'); blankCanvas.width = (n as HTMLCanvasElement).width; blankCanvas.height = (n as HTMLCanvasElement).height; const blankCanvasDataURL = blankCanvas.toDataURL( diff --git a/packages/rrweb-snapshot/test/snapshot.test.ts b/packages/rrweb-snapshot/test/snapshot.test.ts index aa4bb428ee..7c930c3929 100644 --- a/packages/rrweb-snapshot/test/snapshot.test.ts +++ b/packages/rrweb-snapshot/test/snapshot.test.ts @@ -7,6 +7,7 @@ import { serializeNodeWithId, _isBlockedElement, } from '../src/snapshot'; +import snapshot from '../src/snapshot'; import { serializedNodeWithId, elementNode } from '../src/types'; import { Mirror } from '../src/utils'; @@ -257,3 +258,27 @@ describe('form', () => { expect(sel?.childNodes).toEqual([]); // shouldn't be stored in childNodes while in transit }); }); + +describe('jsdom snapshot', () => { + const render = (html: string): Document => { + document.write(html); + return document; + }; + + it("doesn't rely on global browser objects", () => { + // this test is incomplete in terms of coverage, + // but the idea being that we are checking that all features use the + // passed-in `doc` object rather than the global `document` + // (which is only present in browsers) + // in any case, supporting jsdom is not a primary goal + + const doc = render(`

Hello world

`); + const sn = snapshot(doc, { + // JSDOM Error: Not implemented: HTMLCanvasElement.prototype.toDataURL (without installing the canvas npm package) + //recordCanvas: true, + }); + expect(sn).toMatchObject({ + type: 0, + }); + }); +});