From bd5aa59589afc4cfeecf1535fb354fd56e50d37b Mon Sep 17 00:00:00 2001 From: Yanzhen Yu Date: Wed, 1 Apr 2026 12:00:00 +0800 Subject: [PATCH] ignore style sheet changes before the target DOM was serialized The serialized DOM will contains all the styles, so this looks safe. --- src/record/observer.ts | 22 ++++++++++++++-------- test/__snapshots__/record.test.ts.snap | 12 ------------ test/integration.test.ts | 4 +++- test/record.test.ts | 19 ++++++++++++++++++- tslint.json | 3 ++- 5 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/record/observer.ts b/src/record/observer.ts index dc1f8697..00d1035a 100644 --- a/src/record/observer.ts +++ b/src/record/observer.ts @@ -523,19 +523,25 @@ function initInputObserver( function initStyleSheetObserver(cb: styleSheetRuleCallback): listenerHandler { const insertRule = CSSStyleSheet.prototype.insertRule; CSSStyleSheet.prototype.insertRule = function(rule: string, index?: number) { - cb({ - id: mirror.getId(this.ownerNode as INode), - adds: [{ rule, index }], - }); + const id = mirror.getId(this.ownerNode as INode); + if (id !== -1) { + cb({ + id, + adds: [{ rule, index }], + }); + } return insertRule.apply(this, arguments); }; const deleteRule = CSSStyleSheet.prototype.deleteRule; CSSStyleSheet.prototype.deleteRule = function(index: number) { - cb({ - id: mirror.getId(this.ownerNode as INode), - removes: [{ index }], - }); + const id = mirror.getId(this.ownerNode as INode); + if (id !== -1) { + cb({ + id, + removes: [{ index }], + }); + } return deleteRule.apply(this, arguments); }; diff --git a/test/__snapshots__/record.test.ts.snap b/test/__snapshots__/record.test.ts.snap index bd93f699..03eff2af 100644 --- a/test/__snapshots__/record.test.ts.snap +++ b/test/__snapshots__/record.test.ts.snap @@ -399,18 +399,6 @@ exports[`stylesheet-rules 1`] = ` } } }, - { - \\"type\\": 3, - \\"data\\": { - \\"source\\": 8, - \\"id\\": -1, - \\"adds\\": [ - { - \\"rule\\": \\"body { background: #000; }\\" - } - ] - } - }, { \\"type\\": 3, \\"data\\": { diff --git a/test/integration.test.ts b/test/integration.test.ts index 8cd001d5..71e4846f 100644 --- a/test/integration.test.ts +++ b/test/integration.test.ts @@ -11,6 +11,8 @@ interface ISuite extends Suite { } describe('record integration tests', function(this: ISuite) { + this.timeout(10_000); + const getHtml = (fileName: string, options: recordOptions = {}): string => { const filePath = path.resolve(__dirname, `./html/${fileName}`); const html = fs.readFileSync(filePath, 'utf8'); @@ -214,4 +216,4 @@ describe('record integration tests', function(this: ISuite) { const snapshots = await page.evaluate('window.snapshots'); assertSnapshot(snapshots, __filename, 'react-styled-components'); }); -}).timeout(10000); +}); diff --git a/test/record.test.ts b/test/record.test.ts index 4d9744b2..e706ad6d 100644 --- a/test/record.test.ts +++ b/test/record.test.ts @@ -9,6 +9,8 @@ import { listenerHandler, eventWithTime, EventType, + IncrementalSource, + styleSheetRuleData, } from '../src/types'; import { assertSnapshot, launchPuppeteer } from './utils'; import { Suite } from 'mocha'; @@ -207,6 +209,8 @@ describe('record', function(this: ISuite) { const styleSheet = styleElement.sheet; const ruleIdx0 = styleSheet.insertRule('body { background: #000; }'); + const ruleIdx1 = styleSheet.insertRule('body { background: #111; }'); + styleSheet.deleteRule(ruleIdx1); setTimeout(() => { styleSheet.insertRule('body { color: #fff; }'); }, 0); @@ -218,7 +222,20 @@ describe('record', function(this: ISuite) { }, 10); }); await this.page.waitFor(10); - expect(this.events.length).to.equal(7); + const styleSheetRuleEvents = this.events.filter( + e => + e.type === EventType.IncrementalSnapshot && + e.data.source === IncrementalSource.StyleSheetRule, + ); + const addRuleCount = styleSheetRuleEvents.filter(e => + Boolean((e.data as styleSheetRuleData).adds), + ).length; + const removeRuleCount = styleSheetRuleEvents.filter(e => + Boolean((e.data as styleSheetRuleData).removes), + ).length; + // sync insert/delete should be ignored + expect(addRuleCount).to.equal(2); + expect(removeRuleCount).to.equal(1); assertSnapshot(this.events, __filename, 'stylesheet-rules'); }); }); diff --git a/tslint.json b/tslint.json index a153081c..9656f0c9 100644 --- a/tslint.json +++ b/tslint.json @@ -15,7 +15,8 @@ "check-format", "allow-leading-underscore" ], - "arrow-parens": false + "arrow-parens": false, + "only-arrow-functions": false }, "rulesDirectory": [] }