@@ -25,6 +25,7 @@ describe("CDP/Selectivity/CSSSelectivity", () => {
2525 let pathStub : { posix : { join : SinonStub } } ;
2626 let hasProtocolStub : SinonStub ;
2727 let isDataProtocolStub : SinonStub ;
28+ let canParseStub : SinonStub ;
2829 let debugSelectivityStub : SinonStub ;
2930
3031 const CacheType = { Asset : "a" , CssSessionCache : "cs" } ;
@@ -99,6 +100,9 @@ describe("CDP/Selectivity/CSSSelectivity", () => {
99100 } ;
100101 hasProtocolStub = sandbox . stub ( ) . returns ( false ) ;
101102 isDataProtocolStub = sandbox . stub ( ) . callsFake ( ( url : string ) => url . startsWith ( "data:" ) ) ;
103+ // In production "urlResolve" yields an absolute (parseable) url; the stub above returns a relative one,
104+ // so we stub the global "URL.canParse" to mirror the production "parseable" outcome by default.
105+ canParseStub = sandbox . stub ( URL , "canParse" ) . returns ( true ) ;
102106 debugSelectivityStub = sandbox . stub ( ) ;
103107
104108 getCachedSelectivityFileStub = sandbox . stub ( ) . resolves ( JSON . stringify ( mockSourceMap ) ) ;
@@ -1174,4 +1178,56 @@ describe("CDP/Selectivity/CSSSelectivity", () => {
11741178 } ) ;
11751179 } ) ;
11761180 } ) ;
1181+
1182+ describe ( "anonymous stylesheets with embedded source maps" , ( ) => {
1183+ const embeddedSourceMapUrl = "data:application/json;base64,eyJ2ZXJzaW9uIjozfQ==" ;
1184+ const anonymousStyleSheetEvent = {
1185+ header : {
1186+ ...styleSheetEvent . header ,
1187+ sourceURL : "" , // anonymous stylesheet (e.g. injected <style>)
1188+ sourceMapURL : embeddedSourceMapUrl ,
1189+ } ,
1190+ } ;
1191+
1192+ it ( "should fetch the embedded source map for a stylesheet without a sourceURL" , async ( ) => {
1193+ patchSourceMapSourcesStub . returns ( { sources : [ "src/styles.css" ] , sourceRoot : "/root" } ) ;
1194+ cdpMock . css . stopRuleUsageTracking . resolves ( {
1195+ ruleUsage : [ { styleSheetId : "stylesheet-123" , startOffset : 0 , endOffset : 100 , used : true } ] ,
1196+ } ) ;
1197+
1198+ const cssSelectivity = new CSSSelectivity ( cdpMock as any , sessionId , wdSessionId , sourceRoot , null ) ;
1199+
1200+ await cssSelectivity . start ( ) ;
1201+
1202+ const styleSheetAddedHandler = cdpMock . css . on . getCall ( 0 ) . args [ 1 ] ;
1203+ styleSheetAddedHandler ( anonymousStyleSheetEvent , sessionId ) ;
1204+
1205+ const result = await cssSelectivity . stop ( ) ;
1206+
1207+ // Embedded (data:) source maps are fetched directly and never offloaded to fs-cache
1208+ assert . calledWith ( fetchTextWithBrowserFallbackStub , embeddedSourceMapUrl , cdpMock . runtime , sessionId ) ;
1209+ assert . neverCalledWith ( hasCachedSelectivityFileStub , CacheType . Asset , embeddedSourceMapUrl ) ;
1210+ assert . neverCalledWith ( setCachedSelectivityFileStub , CacheType . Asset , embeddedSourceMapUrl ) ;
1211+ assert . deepEqual ( Array . from ( result || [ ] ) . sort ( ) , [ "/root/src/styles.css" ] ) ;
1212+ } ) ;
1213+
1214+ it ( "should skip the stylesheet when the resolved source map url is not parseable" , async ( ) => {
1215+ canParseStub . returns ( false ) ;
1216+ cdpMock . css . stopRuleUsageTracking . resolves ( {
1217+ ruleUsage : [ { styleSheetId : "stylesheet-123" , startOffset : 0 , endOffset : 100 , used : true } ] ,
1218+ } ) ;
1219+
1220+ const cssSelectivity = new CSSSelectivity ( cdpMock as any , sessionId , wdSessionId , sourceRoot , null ) ;
1221+
1222+ await cssSelectivity . start ( ) ;
1223+
1224+ const styleSheetAddedHandler = cdpMock . css . on . getCall ( 0 ) . args [ 1 ] ;
1225+ styleSheetAddedHandler ( styleSheetEvent , sessionId ) ;
1226+
1227+ const result = await cssSelectivity . stop ( ) ;
1228+
1229+ assert . notCalled ( fetchTextWithBrowserFallbackStub ) ;
1230+ assert . deepEqual ( Array . from ( result || [ ] ) , [ ] ) ;
1231+ } ) ;
1232+ } ) ;
11771233} ) ;
0 commit comments