Files
rrweb/packages/all/test/cross-origin-iframe-packer.test.ts
Justin Halsall 5fd6ea43b4 Fix async assertions in test files (#1510)
* fix: await assertSnapshot in test files for async assertions
2026-04-01 12:00:00 +08:00

157 lines
3.8 KiB
TypeScript

import {
describe,
it,
vi,
beforeAll,
beforeEach,
afterEach,
afterAll,
} from 'vitest';
import type {
eventWithTime,
listenerHandler,
mutationData,
} from '@rrweb/types';
import { unpack } from '@rrweb/packer';
import * as fs from 'fs';
import * as path from 'path';
import type * as puppeteer from 'puppeteer';
import type { recordOptions } from 'rrweb';
import type {} from '@rrweb/types';
import { EventType } from '@rrweb/types';
import {
assertSnapshot,
getServerURL,
launchPuppeteer,
startServer,
waitForRAF,
} from './utils';
import type * as http from 'http';
interface ISuite {
code: string;
browser: puppeteer.Browser;
page: puppeteer.Page;
events: eventWithTime[];
server: http.Server;
serverURL: string;
}
interface IWindow extends Window {
rrweb: {
record: (
options: recordOptions<eventWithTime>,
) => listenerHandler | undefined;
addCustomEvent<T>(tag: string, payload: T): void;
pack: (e: eventWithTime) => string;
};
emit: (e: eventWithTime) => undefined;
snapshots: eventWithTime[];
}
type ExtraOptions = {
usePackFn?: boolean;
};
async function injectRecordScript(
frame: puppeteer.Frame,
options?: ExtraOptions,
) {
await frame.addScriptTag({
path: path.resolve(__dirname, '../dist/all.umd.cjs'),
});
options = options || {};
await frame.evaluate((options) => {
(window as unknown as IWindow).snapshots = [];
const { record, pack } = (window as unknown as IWindow).rrweb;
const config: recordOptions<eventWithTime> = {
recordCrossOriginIframes: true,
recordCanvas: true,
emit(event) {
(window as unknown as IWindow).snapshots.push(event);
(window as unknown as IWindow).emit(event);
},
};
if (options.usePackFn) {
config.packFn = pack;
}
record(config);
}, options);
for (const child of frame.childFrames()) {
await injectRecordScript(child, options);
}
}
const setup = function (
this: ISuite,
content: string,
options?: ExtraOptions,
): ISuite {
const ctx = {} as ISuite;
beforeAll(async () => {
ctx.browser = await launchPuppeteer();
ctx.server = await startServer();
ctx.serverURL = getServerURL(ctx.server);
});
beforeEach(async () => {
ctx.page = await ctx.browser.newPage();
await ctx.page.goto('about:blank');
await ctx.page.setContent(
content.replace(/\{SERVER_URL\}/g, ctx.serverURL),
);
ctx.events = [];
await ctx.page.exposeFunction('emit', (e: eventWithTime) => {
if (e.type === EventType.DomContentLoaded || e.type === EventType.Load) {
return;
}
ctx.events.push(e);
});
ctx.page.on('console', (msg) => console.log('PAGE LOG:', msg.text()));
await injectRecordScript(ctx.page.mainFrame(), options);
});
afterEach(async () => {
await ctx.page.close();
});
afterAll(async () => {
await ctx.browser.close();
ctx.server.close();
});
return ctx;
};
describe('cross origin iframes & packer', function (this: ISuite) {
vi.setConfig({ testTimeout: 100_000 });
describe('blank.html', function (this: ISuite) {
const content = `
<!DOCTYPE html>
<html>
<body>
<iframe src="{SERVER_URL}/html/blank.html"></iframe>
</body>
</html>
`;
const ctx = setup.call(this, content, { usePackFn: true });
describe('should support packFn option in record()', () => {
it('', async () => {
const frame = ctx.page.mainFrame().childFrames()[0];
await waitForRAF(frame);
const packedSnapshots = (await ctx.page.evaluate(
'window.snapshots',
)) as string[];
const unpackedSnapshots = packedSnapshots.map((packed) =>
unpack(packed),
) as eventWithTime[];
await assertSnapshot(unpackedSnapshots);
});
});
});
});