Skip to content

Commit

Permalink
WIP dialog recording
Browse files Browse the repository at this point in the history
  • Loading branch information
Juice10 committed Jun 10, 2024
1 parent 51075e4 commit 59de782
Show file tree
Hide file tree
Showing 9 changed files with 648 additions and 60 deletions.
11 changes: 11 additions & 0 deletions packages/rrweb-snapshot/src/snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
MaskInputOptions,
SlimDOMOptions,
DataURLOptions,
DialogAttributes,
MaskTextFn,
MaskInputFn,
KeepIframeSrcFn,
Expand Down Expand Up @@ -704,6 +705,16 @@ function serializeElementNode(
delete attributes.selected;
}
}

if (
tagName === 'dialog' &&
(n as HTMLDialogElement).open &&
n.matches('dialog:modal')
) {
(attributes as DialogAttributes).rr_open = 'modal';
delete attributes.open; // prevent default `show()` behavior which blocks `showModal()` from working
}

// canvas image data
if (tagName === 'canvas' && recordCanvas) {
if ((n as ICanvas).__context === '2d') {
Expand Down
9 changes: 9 additions & 0 deletions packages/rrweb-snapshot/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,15 @@ export type mediaAttributes = {
rr_mediaVolume?: number;
};

export type DialogAttributes =
// | {
// open: '';
// }
{
rr_open: 'modal';
// rr_open_index?: number;
};

// @deprecated
export interface INode extends Node {
__sn: serializedNodeWithId;
Expand Down
122 changes: 122 additions & 0 deletions packages/rrweb-snapshot/test/__snapshots__/integration.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,121 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`dialog integration tests > should capture open attribute for modal dialogs 1`] = `
"{
\\"type\\": 0,
\\"childNodes\\": [
{
\\"type\\": 2,
\\"tagName\\": \\"html\\",
\\"attributes\\": {},
\\"childNodes\\": [
{
\\"type\\": 2,
\\"tagName\\": \\"head\\",
\\"attributes\\": {},
\\"childNodes\\": [],
\\"id\\": 3
},
{
\\"type\\": 2,
\\"tagName\\": \\"body\\",
\\"attributes\\": {},
\\"childNodes\\": [
{
\\"type\\": 3,
\\"textContent\\": \\"\\\\n \\",
\\"id\\": 5
},
{
\\"type\\": 2,
\\"tagName\\": \\"dialog\\",
\\"attributes\\": {
\\"rr_open\\": \\"modal\\"
},
\\"childNodes\\": [
{
\\"type\\": 3,
\\"textContent\\": \\"I'm a dialog\\",
\\"id\\": 7
}
],
\\"id\\": 6
},
{
\\"type\\": 3,
\\"textContent\\": \\"\\\\n \\\\n\\\\n\\",
\\"id\\": 8
}
],
\\"id\\": 4
}
],
\\"id\\": 2
}
],
\\"compatMode\\": \\"BackCompat\\",
\\"id\\": 1
}"
`;

exports[`dialog integration tests > should capture open attribute for non modal dialogs 1`] = `
"{
\\"type\\": 0,
\\"childNodes\\": [
{
\\"type\\": 2,
\\"tagName\\": \\"html\\",
\\"attributes\\": {},
\\"childNodes\\": [
{
\\"type\\": 2,
\\"tagName\\": \\"head\\",
\\"attributes\\": {},
\\"childNodes\\": [],
\\"id\\": 3
},
{
\\"type\\": 2,
\\"tagName\\": \\"body\\",
\\"attributes\\": {},
\\"childNodes\\": [
{
\\"type\\": 3,
\\"textContent\\": \\"\\\\n \\",
\\"id\\": 5
},
{
\\"type\\": 2,
\\"tagName\\": \\"dialog\\",
\\"attributes\\": {
\\"open\\": \\"\\"
},
\\"childNodes\\": [
{
\\"type\\": 3,
\\"textContent\\": \\"I'm a dialog\\",
\\"id\\": 7
}
],
\\"id\\": 6
},
{
\\"type\\": 3,
\\"textContent\\": \\"\\\\n \\\\n\\\\n\\",
\\"id\\": 8
}
],
\\"id\\": 4
}
],
\\"id\\": 2
}
],
\\"compatMode\\": \\"BackCompat\\",
\\"id\\": 1
}"
`;

exports[`iframe integration tests > snapshot async iframes 1`] = `
"{
\\"type\\": 0,
Expand Down Expand Up @@ -214,6 +330,12 @@ exports[`integration tests > [html file]: cors-style-sheet.html 1`] = `
<body></body></html>"
`;

exports[`integration tests > [html file]: dialog.html 1`] = `
"<html><head></head><body>
<dialog>I'm a dialog</dialog>
</body></html>"
`;

exports[`integration tests > [html file]: dynamic-stylesheet.html 1`] = `
"<!DOCTYPE html><html lang=\\"en\\"><head>
<meta charset=\\"UTF-8\\" />
Expand Down
5 changes: 5 additions & 0 deletions packages/rrweb-snapshot/test/html/dialog.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<html>
<body>
<dialog>I'm a dialog</dialog>
</body>
</html>
75 changes: 71 additions & 4 deletions packages/rrweb-snapshot/test/integration.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import * as fs from 'fs';
import * as path from 'path';
import * as http from 'http';
import * as url from 'url';
import * as path from 'path';
import * as puppeteer from 'puppeteer';
import { vi, assert, describe, it, beforeAll, afterAll, expect } from 'vitest';
import { waitForRAF, getServerURL } from './utils';
import * as url from 'url';
import {
afterAll,
assert,
beforeAll,
beforeEach,
describe,
expect,
it,
vi,
} from 'vitest';

import { getServerURL, waitForRAF } from './utils';

const htmlFolder = path.join(__dirname, 'html');
const htmls = fs.readdirSync(htmlFolder).map((filePath) => {
Expand Down Expand Up @@ -60,6 +70,15 @@ function sanitizeSnapshot(snapshot: string): string {
return snapshot.replace(/localhost:[0-9]+/g, 'localhost:3030');
}

async function snapshot(page: puppeteer.Page, code: string): Promise<string> {
await waitForRAF(page);
const result = (await page.evaluate(`${code}
const snapshot = rrwebSnapshot.snapshot(document);
JSON.stringify(snapshot, null, 2);
`)) as string;
return result;
}

function assertSnapshot(snapshot: string): void {
expect(sanitizeSnapshot(snapshot)).toMatchSnapshot();
}
Expand All @@ -68,6 +87,7 @@ interface ISuite {
server: http.Server;
serverURL: string;
browser: puppeteer.Browser;
page: puppeteer.Page;
code: string;
}

Expand Down Expand Up @@ -431,6 +451,53 @@ describe('iframe integration tests', function (this: ISuite) {
});
});

describe('dialog integration tests', function (this: ISuite) {
vi.setConfig({ testTimeout: 30_000 });
let server: ISuite['server'];
let serverURL: ISuite['serverURL'];
let browser: ISuite['browser'];
let code: ISuite['code'];
let page: ISuite['page'];

beforeAll(async () => {
server = await startServer();
serverURL = getServerURL(server);
browser = await puppeteer.launch({
// headless: false,
});

code = fs.readFileSync(
path.resolve(__dirname, '../dist/rrweb-snapshot.umd.cjs'),
'utf-8',
);
});

beforeEach(async () => {
page = await browser.newPage();
page.on('console', (msg) => console.log(msg.text()));
await page.goto(`${serverURL}/html/dialog.html`, {
waitUntil: 'load',
});
});

afterAll(async () => {
await browser.close();
await server.close();
});

it('should capture open attribute for non modal dialogs', async () => {
page.evaluate('document.querySelector("dialog").show()');
const snapshotResult = await snapshot(page, code);
assertSnapshot(snapshotResult);
});

it('should capture open attribute for modal dialogs', async () => {
await page.evaluate('document.querySelector("dialog").showModal()');
const snapshotResult = await snapshot(page, code);
assertSnapshot(snapshotResult);
});
});

describe('shadow DOM integration tests', function (this: ISuite) {
vi.setConfig({ testTimeout: 30_000 });
let server: ISuite['server'];
Expand Down
28 changes: 27 additions & 1 deletion packages/rrweb-snapshot/test/rebuild.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
*/
import * as fs from 'fs';
import * as path from 'path';
import { describe, it, beforeEach, expect } from 'vitest';
import { beforeEach, describe, expect, it } from 'vitest';

import {
adaptCssForReplay,
buildNodeWithSN,
Expand Down Expand Up @@ -52,6 +53,31 @@ describe('rebuild', function () {
});
});

// this doesn't really test anything, maybe remove it?
// contemplate if rrweb-snapshot should trigger .showModal() on dialog elements on rebuild...
describe('rr_open', function () {
it('should call `show` on non-modal dialog', function () {
const node = buildNodeWithSN(
{
id: 1,
tagName: 'dialog',
type: NodeType.Element,
attributes: {
open: '',
},
childNodes: [],
},
{
doc: document,
mirror,
hackCss: false,
cache,
},
) as HTMLDialogElement;
expect(node?.open).toBe(true);
});
});

describe('shadowDom', function () {
it('rebuild shadowRoot without siblings', function () {
const node = buildNodeWithSN(
Expand Down
Loading

0 comments on commit 59de782

Please sign in to comment.