Skip to content

Commit

Permalink
Copy the bad data generated by the 'should record style mutations and…
Browse files Browse the repository at this point in the history
… replay them correctly' test into a dedicated 'backwards compatibility' version to ensure older recordings can still be replayed correctly even when the duplicate data generated is fixed in rrweb-io#1437
  • Loading branch information
eoghanmurray committed Jul 8, 2024
1 parent d1fba35 commit 1e8a670
Show file tree
Hide file tree
Showing 2 changed files with 255 additions and 2 deletions.
231 changes: 231 additions & 0 deletions packages/rrweb/test/events/bad-style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
import { EventType, IncrementalSource } from '@rrweb/types';
import type { eventWithTime } from '@rrweb/types';

/**
* https://github.com/rrweb-io/rrweb/pull/1417
* make sure we can replay duplicated content in style elements generated by older versions of rrweb
* test case demonstrates the duplicated content in question in two places; the initial snapshot, and in a style mutation
* (see 'BAD: duplicated content' below)
* these should no longer be generated after https://github.com/rrweb-io/rrweb/pull/1437
*/
const now = Date.now();
const events: eventWithTime[] = [
{
timestamp: now,
type: EventType.Meta,
data: {
href: 'about:blank',
width: 1920,
height: 1080,
},
},
{
timestamp: now,
type: EventType.FullSnapshot,
data: {
node: {
type: 0,
childNodes: [
{
type: 1,
name: 'html',
publicId: '',
systemId: '',
id: 2,
},
{
type: 2,
tagName: 'html',
attributes: {
lang: 'en',
},
childNodes: [
{
type: 2,
tagName: 'head',
attributes: {},
childNodes: [
{
type: 3,
textContent: '\\\\n\\\\t ',
id: 5,
},
{
type: 2,
tagName: 'style',
attributes: {
_cssText: '#one { color: rgb(255, 0, 0); }',
},
childNodes: [
{
// BAD: duplicated content
type: 3,
textContent: '#one { color: rgb(255, 0, 0); }',
isStyle: true,
id: 7,
},
],
id: 6,
},
{
type: 3,
textContent: '\\\\n ',
id: 8,
},
{
type: 2,
tagName: 'script',
attributes: {},
childNodes: [
{
type: 3,
textContent: 'SCRIPT_PLACEHOLDER',
id: 10,
},
],
id: 9,
},
],
id: 4,
},
{
type: 3,
textContent: '\\\\n ',
id: 11,
},
{
type: 2,
tagName: 'body',
attributes: {},
childNodes: [
{
type: 3,
textContent: '\\\\n\\\\t ',
id: 13,
},
{
type: 2,
tagName: 'div',
attributes: {
id: 'one',
},
childNodes: [],
id: 14,
},
{
type: 3,
textContent: '\\\\n ',
id: 15,
},
{
type: 2,
tagName: 'div',
attributes: {
id: 'two',
},
childNodes: [],
id: 16,
},
{
type: 3,
textContent: '\\\\n\\\\t ',
id: 17,
},
{
type: 2,
tagName: 'script',
attributes: {},
childNodes: [
{
type: 3,
textContent: 'SCRIPT_PLACEHOLDER',
id: 19,
},
],
id: 18,
},
{
type: 3,
textContent: '\\\\n \\\\n ',
id: 20,
},
],
id: 12,
},
],
id: 3,
},
],
id: 1,
},
initialOffset: {
left: 0,
top: 0,
},
},
},
{
timestamp: now + 1,
type: EventType.IncrementalSnapshot,
data: {
source: IncrementalSource.Mutation,
texts: [],
attributes: [],
removes: [],
adds: [
{
parentId: 4,
nextId: null,
node: {
type: 2,
tagName: 'style',
attributes: {
_cssText: '#two { color: rgb(255, 0, 0); }',
},
childNodes: [],
id: 21,
},
},
{
parentId: 21,
nextId: null,
node: {
type: 3,
// BAD: duplicated content
textContent: '#two { color: rgb(255, 0, 0); }',
isStyle: true,
id: 22,
},
},
],
},
},
{
timestamp: now + 2,
type: EventType.IncrementalSnapshot,
data: {
source: IncrementalSource.StyleDeclaration,
id: 6,
set: {
property: 'color',
value: 'rgb(255, 255, 0)',
},
index: [0],
},
},
{
timestamp: now + 3,
type: EventType.IncrementalSnapshot,
data: {
source: IncrementalSource.StyleDeclaration,
id: 21,
set: {
property: 'color',
value: 'rgb(255, 255, 0)',
},
index: [0],
},
},
];

export default events;
26 changes: 24 additions & 2 deletions packages/rrweb/test/replayer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import inputEvents from './events/input';
import iframeEvents from './events/iframe';
import selectionEvents from './events/selection';
import shadowDomEvents from './events/shadow-dom';
import textareaEvents from './events/bad-textarea';
import badTextareaEvents from './events/bad-textarea';
import badStyleEvents from './events/bad-style';
import StyleSheetTextMutation from './events/style-sheet-text-mutation';
import canvasInIframe from './events/canvas-in-iframe';
import adoptedStyleSheet from './events/adopted-style-sheet';
Expand Down Expand Up @@ -1142,7 +1143,7 @@ describe('replayer', function () {
});

it('can deal with legacy duplicate/conflicting values on textareas', async () => {
await page.evaluate(`events = ${JSON.stringify(textareaEvents)}`);
await page.evaluate(`events = ${JSON.stringify(badTextareaEvents)}`);

const displayValue = await page.evaluate(`
const { Replayer } = rrweb;
Expand All @@ -1155,4 +1156,25 @@ describe('replayer', function () {
// If the custom element is defined, the display value will be 'block'.
expect(displayValue).toEqual('this value is used for replay');
});

it('can deal with duplicate/conflicting values on style elements', async () => {
await page.evaluate(`events = ${JSON.stringify(badStyleEvents)}`);

const changedColors = await page.evaluate(`
const { Replayer } = rrweb;
const replayer = new Replayer(events);
replayer.pause(1000);
// Get the color of the elements after applying the style mutation event
[
replayer.iframe.contentWindow.getComputedStyle(
replayer.iframe.contentDocument.querySelector('#one'),
).color,
replayer.iframe.contentWindow.getComputedStyle(
replayer.iframe.contentDocument.querySelector('#two'),
).color,
];
`);
const newColor = 'rgb(255, 255, 0)'; // yellow
expect(changedColors).toEqual([newColor, newColor]);
});
});

0 comments on commit 1e8a670

Please sign in to comment.