Skip to content

Commit a5143d7

Browse files
Merge pull request #1276 from gemini-testing/TESTPLANE-1040.anonymous_styles
fix(selectivity): anonymous styles
2 parents 04b75f7 + a3eca39 commit a5143d7

4 files changed

Lines changed: 64 additions & 3 deletions

File tree

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
},
5151
"homepage": "https://testplane.io/",
5252
"engines": {
53-
"node": ">= 18.0.0"
53+
"node": ">= 18.17.0"
5454
},
5555
"keywords": [
5656
"testplane",

src/browser/cdp/selectivity/css-selectivity.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export class CSSSelectivity {
6262
return;
6363
}
6464

65-
if (!sourceURL || !sourceMapURL || sourceURL.startsWith("chrome-error://")) {
65+
if (!sourceMapURL || sourceURL.startsWith("chrome-error://")) {
6666
this._stylesSourceMap[styleSheetId] ||= null;
6767
return;
6868
}
@@ -73,6 +73,11 @@ export class CSSSelectivity {
7373

7474
let sourceMapResolvedUrl = urlResolve(sourceURL, sourceMapURL);
7575

76+
if (!URL.canParse(sourceMapResolvedUrl)) {
77+
this._stylesSourceMap[styleSheetId] ||= null;
78+
return;
79+
}
80+
7681
const mapResult = this._mapSourceMapUrl
7782
? this._mapSourceMapUrl({ type: "css", sourceUrl: sourceURL, sourceMapUrl: sourceMapResolvedUrl })
7883
: true;

test/src/browser/cdp/selectivity/css-selectivity.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)