From d2df9bb673a13e5c78969b566c1d3b6161609fff Mon Sep 17 00:00:00 2001 From: Eoghan Murray Date: Thu, 23 May 2024 09:57:33 +0100 Subject: [PATCH] Don't rely on a 3rd party url (or internet access) in the new cross-origin test --- .../__snapshots__/integration.test.ts.snap | 1 - .../rrweb-snapshot/test/html/picture.html | 1 - .../test/images/rrweb-favicon-20x20.png | Bin 0 -> 487 bytes .../rrweb-snapshot/test/integration.test.ts | 41 ++++++++++++++++-- packages/rrweb-snapshot/test/utils.ts | 10 +++++ 5 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 packages/rrweb-snapshot/test/images/rrweb-favicon-20x20.png diff --git a/packages/rrweb-snapshot/test/__snapshots__/integration.test.ts.snap b/packages/rrweb-snapshot/test/__snapshots__/integration.test.ts.snap index 1abf3f40fa..e95a718645 100644 --- a/packages/rrweb-snapshot/test/__snapshots__/integration.test.ts.snap +++ b/packages/rrweb-snapshot/test/__snapshots__/integration.test.ts.snap @@ -343,7 +343,6 @@ exports[`integration tests [html file]: picture.html 1`] = ` \\"This - \\"CORS " `; diff --git a/packages/rrweb-snapshot/test/html/picture.html b/packages/rrweb-snapshot/test/html/picture.html index 3d59df428b..2401ca0c61 100644 --- a/packages/rrweb-snapshot/test/html/picture.html +++ b/packages/rrweb-snapshot/test/html/picture.html @@ -6,6 +6,5 @@ This is a robot - CORS restricted but has access-control-allow-origin: * diff --git a/packages/rrweb-snapshot/test/images/rrweb-favicon-20x20.png b/packages/rrweb-snapshot/test/images/rrweb-favicon-20x20.png new file mode 100644 index 0000000000000000000000000000000000000000..561f9060d74151fc13e569295262908a9814c3ca GIT binary patch literal 487 zcmVdCqgrkpYYV5QE;k^z9gCZ=z3GmZ2yL^KZ8suGj1T z0JGUFg25p3B}szGWWwcgL9JH9VzJ=na4CmEA%w%>AF=cKjLBqz&1QpEtA#?LfYoaC zT7|J#41>V{`~ChAv)OEj$KyC04#;FOD3wY`r_UO)$D!nVM z8}M%QFi`4=L;}TP5vr={1Ke)6>qm_G!{LyrJ)KVB_xt&*jJ}7uSML?T4+HT= dp8)^>|Nnex$5i}|dhh@M002ovPDHLkV1i4G? rollup.Plugin; @@ -210,7 +210,7 @@ iframe.contentDocument.querySelector('center').clientHeight inlineImages: true, inlineStylesheet: false })`); - await waitForRAF(page); // need a small wait, as after the crossOrigin="anonymous" change, the snapshot triggers a reload of the image (which mutates the snapshot when loaded) + // don't wait, as we want to ensure that the same-origin image can be inlined immediately const bodyChildren = (await page.evaluate(` snapshot.childNodes[0].childNodes[1].childNodes.filter((cn) => cn.type === 2); `)) as any[]; @@ -224,11 +224,44 @@ iframe.contentDocument.querySelector('center').clientHeight }, }), ); - expect(bodyChildren[2]).toEqual( + }); + + it('correctly saves cross-origin images offline', async () => { + const page: puppeteer.Page = await browser.newPage(); + + await page.goto('about:blank', { + waitUntil: 'load', + }); + await page.setContent( + ` + + + CORS restricted but has access-control-allow-origin: * + + +`, + { + waitUntil: 'load', + }, + ); + + await page.waitForSelector('img', { timeout: 1000 }); + await page.evaluate(`${code}var snapshot = rrweb.snapshot(document, { + dataURLOptions: { type: "image/webp", quality: 0.8 }, + inlineImages: true, + inlineStylesheet: false + })`); + await waitForRAF(page); // need a small wait, as after the crossOrigin="anonymous" change, the snapshot triggers a reload of the image (after which, the snapshot is mutated) + const bodyChildren = (await page.evaluate(` + snapshot.childNodes[0].childNodes[1].childNodes.filter((cn) => cn.type === 2); +`)) as any[]; + expect(bodyChildren[0]).toEqual( expect.objectContaining({ tagName: 'img', attributes: { - src: 'https://avatars.githubusercontent.com/u/43396833?s=20&v=4', + src: getServerURL(server) + '/images/rrweb-favicon-20x20.png', alt: 'CORS restricted but has access-control-allow-origin: *', rr_dataURL: expect.stringMatching(/^data:image\/webp;base64,/), }, diff --git a/packages/rrweb-snapshot/test/utils.ts b/packages/rrweb-snapshot/test/utils.ts index 43d4484bb4..631f8640a6 100644 --- a/packages/rrweb-snapshot/test/utils.ts +++ b/packages/rrweb-snapshot/test/utils.ts @@ -1,4 +1,5 @@ import * as puppeteer from 'puppeteer'; +import * as http from 'http'; export async function waitForRAF(page: puppeteer.Page) { return await page.evaluate(() => { @@ -9,3 +10,12 @@ export async function waitForRAF(page: puppeteer.Page) { }); }); } + +export function getServerURL(server: http.Server): string { + const address = server.address(); + if (address && typeof address !== 'string') { + return `http://localhost:${address.port}`; + } else { + return `${address}`; + } +}