From 071f1a97f13eedf034b802a25fc44c512ca25ff9 Mon Sep 17 00:00:00 2001 From: pauldambra Date: Sun, 14 Sep 2025 22:00:34 +0100 Subject: [PATCH] i think this is going to fail for me --- packages/rrweb-snapshot/src/rebuild.ts | 5 ++ .../test/__snapshots__/cdata.svg.snap.html | 10 ++++ .../test/__snapshots__/cdata.svg.snap.json | 58 +++++++++++++++++++ .../rrweb-snapshot/test/integration.test.ts | 45 ++++++++++++++ 4 files changed, 118 insertions(+) create mode 100644 packages/rrweb-snapshot/test/__snapshots__/cdata.svg.snap.html create mode 100644 packages/rrweb-snapshot/test/__snapshots__/cdata.svg.snap.json diff --git a/packages/rrweb-snapshot/src/rebuild.ts b/packages/rrweb-snapshot/src/rebuild.ts index 6a91aa3b..b3bd0b9e 100644 --- a/packages/rrweb-snapshot/src/rebuild.ts +++ b/packages/rrweb-snapshot/src/rebuild.ts @@ -361,6 +361,11 @@ function buildNode( return null; } + /* + https://developer.mozilla.org/en-US/docs/Web/API/Document/createCDATASection + expected: DOMException: Failed to execute 'createCDATASection' on 'Document': This operation is not supported for HTML documents. + "createTextNode() can often be used in its place" + */ return doc.createCDATASection(n.textContent); case NodeType.Comment: return doc.createComment(n.textContent); diff --git a/packages/rrweb-snapshot/test/__snapshots__/cdata.svg.snap.html b/packages/rrweb-snapshot/test/__snapshots__/cdata.svg.snap.html new file mode 100644 index 00000000..6309b016 --- /dev/null +++ b/packages/rrweb-snapshot/test/__snapshots__/cdata.svg.snap.html @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/rrweb-snapshot/test/__snapshots__/cdata.svg.snap.json b/packages/rrweb-snapshot/test/__snapshots__/cdata.svg.snap.json new file mode 100644 index 00000000..a00a3be4 --- /dev/null +++ b/packages/rrweb-snapshot/test/__snapshots__/cdata.svg.snap.json @@ -0,0 +1,58 @@ +{ + "type": 0, + "childNodes": [ + { + "type": 2, + "tagName": "html", + "attributes": {}, + "childNodes": [ + { + "type": 2, + "tagName": "head", + "attributes": {}, + "childNodes": [], + "id": 3 + }, + { + "type": 2, + "tagName": "body", + "attributes": {}, + "childNodes": [ + { + "type": 2, + "tagName": "svg", + "attributes": { + "xmlns": "http://www.w3.org/2000/svg", + "version": "1.1" + }, + "childNodes": [ + { + "type": 2, + "tagName": "style", + "attributes": { + "_cssText": ".Icon > span { color: red; }" + }, + "childNodes": [ + { + "type": 4, + "textContent": "", + "id": 7 + } + ], + "isSVG": true, + "id": 6 + } + ], + "isSVG": true, + "id": 5 + } + ], + "id": 4 + } + ], + "id": 2 + } + ], + "compatMode": "BackCompat", + "id": 1 +} diff --git a/packages/rrweb-snapshot/test/integration.test.ts b/packages/rrweb-snapshot/test/integration.test.ts index a4a1208d..798565f5 100644 --- a/packages/rrweb-snapshot/test/integration.test.ts +++ b/packages/rrweb-snapshot/test/integration.test.ts @@ -422,6 +422,51 @@ iframe.contentDocument.querySelector('center').clientHeight ); expect(snapshotResult).toMatchSnapshot(); }); + + it('correctly records CDATA section in SVG', async () => { + const page: puppeteer.Page = await browser.newPage(); + await page.goto('about:blank', { + waitUntil: 'load', + }); + await page.evaluate(` +const defsSvg = (new window.DOMParser()).parseFromString( +'', 'image/svg+xml'); + document.body.appendChild(defsSvg.documentElement); +`); + await waitForRAF(page); // a small wait + const cdataType = await page.evaluate( + `document.querySelector('svg style').childNodes[0].nodeType`, + ); + assert(cdataType === 4); + const snapshotResult = JSON.stringify( + await page.evaluate(`${code}; + const snapshotResult = rrwebSnapshot.snapshot(document); + snapshotResult + `), + null, + 2, + ); + const fname = `./__snapshots__/cdata.svg.snap.json`; + expect(snapshotResult).toMatchFileSnapshot(fname); + + await waitForRAF(page); + const rebuildHtml = (await page.evaluate(` + const x = new XMLSerializer(); + const node = rrwebSnapshot.rebuild(JSON.parse('${snapshotResult.replace( + /\n/g, + '', + )}'), { doc: document }) + let out = x.serializeToString(node); + if (document.querySelector('html').getAttribute('xmlns') !== 'http://www.w3.org/1999/xhtml') { + // this is just an artefact of serializeToString + out = out.replace(' xmlns=\"http://www.w3.org/1999/xhtml\"', ''); + } + out; // return +`)) as string; + + const fhname = `./__snapshots__/cdata.svg.snap.html`; + expect(rebuildHtml.replace(/>\n<')).toMatchFileSnapshot(fhname); + }); }); describe('iframe integration tests', function (this: ISuite) {