Removing global document references (#1482)
fix for options `recordCanvas: true`: * replace document.createElement with doc.createElement in rrweb-snapshot code * Eoghan: add a regression test to prevent future accidental use of `document` instead of `doc`. This test can be excised if a new feature can only be run in the browser and not in the jsdom environment
This commit is contained in:
5
.changeset/proud-clocks-hope.md
Normal file
5
.changeset/proud-clocks-hope.md
Normal file
@@ -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
|
||||||
@@ -294,7 +294,7 @@ function buildNode(
|
|||||||
const value = specialAttributes[name];
|
const value = specialAttributes[name];
|
||||||
// handle internal attributes
|
// handle internal attributes
|
||||||
if (tagName === 'canvas' && name === 'rr_dataURL') {
|
if (tagName === 'canvas' && name === 'rr_dataURL') {
|
||||||
const image = document.createElement('img');
|
const image = doc.createElement('img');
|
||||||
image.onload = () => {
|
image.onload = () => {
|
||||||
const ctx = (node as HTMLCanvasElement).getContext('2d');
|
const ctx = (node as HTMLCanvasElement).getContext('2d');
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
|
|||||||
@@ -726,7 +726,7 @@ function serializeElementNode(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// create blank canvas of same dimensions
|
// create blank canvas of same dimensions
|
||||||
const blankCanvas = document.createElement('canvas');
|
const blankCanvas = doc.createElement('canvas');
|
||||||
blankCanvas.width = (n as HTMLCanvasElement).width;
|
blankCanvas.width = (n as HTMLCanvasElement).width;
|
||||||
blankCanvas.height = (n as HTMLCanvasElement).height;
|
blankCanvas.height = (n as HTMLCanvasElement).height;
|
||||||
const blankCanvasDataURL = blankCanvas.toDataURL(
|
const blankCanvasDataURL = blankCanvas.toDataURL(
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
serializeNodeWithId,
|
serializeNodeWithId,
|
||||||
_isBlockedElement,
|
_isBlockedElement,
|
||||||
} from '../src/snapshot';
|
} from '../src/snapshot';
|
||||||
|
import snapshot from '../src/snapshot';
|
||||||
import { serializedNodeWithId, elementNode } from '../src/types';
|
import { serializedNodeWithId, elementNode } from '../src/types';
|
||||||
import { Mirror } from '../src/utils';
|
import { Mirror } from '../src/utils';
|
||||||
|
|
||||||
@@ -257,3 +258,27 @@ describe('form', () => {
|
|||||||
expect(sel?.childNodes).toEqual([]); // shouldn't be stored in childNodes while in transit
|
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(`<!DOCTYPE html><p>Hello world</p><canvas></canvas>`);
|
||||||
|
const sn = snapshot(doc, {
|
||||||
|
// JSDOM Error: Not implemented: HTMLCanvasElement.prototype.toDataURL (without installing the canvas npm package)
|
||||||
|
//recordCanvas: true,
|
||||||
|
});
|
||||||
|
expect(sn).toMatchObject({
|
||||||
|
type: 0,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user