Extract external CSS stylesheets from HAR for Baseline feature detection#317
Open
smsnedden wants to merge 4 commits into
Open
Extract external CSS stylesheets from HAR for Baseline feature detection#317smsnedden wants to merge 4 commits into
smsnedden wants to merge 4 commits into
Conversation
Add extractCSSFromHar() which collects external text/css stylesheets shipped by a page from a HAR, decoding base64 response bodies and recording each source's origin file. This is the first slice of the Baseline (--baseline) CSS analysis feature. Inline <style> extraction (via a dedicated HTML parser) and CSS feature detection over these sources follow in later changes. - Add CSSSource type and extend HarEntry response content with optional text/encoding fields in types.ts - Add 7 unit tests covering external extraction, base64 decoding, charset handling, ordering, and ignored resources
sergeychernyshev
requested changes
Jul 21, 2026
Member
|
Looks good. Just minor changes in typing, also need to understand in general if HAR will always contain bodies or not and what controls it. |
sergeychernyshev
previously approved these changes
Jul 21, 2026
sergeychernyshev
left a comment
Member
There was a problem hiding this comment.
Looks good - up to you if you want to do a bit more strict type checks here.
Author
Sounds good, made a small change to line 39 for a bit more strict of a type check. |
| * @param encoding - The `content.encoding` value, if present. | ||
| * @returns The decoded body as UTF-8 text. | ||
| */ | ||
| function decodeContent(text: string, encoding?: 'base64'): string { |
Member
There was a problem hiding this comment.
Let's move this as a constant to types.ts and create a type and constant, something like
export const BASE64 = 'base64';
export type HARContentEncoding = typeof BASE64 | undefined;
Suggested change
| function decodeContent(text: string, encoding?: 'base64'): string { | |
| function decodeContent(text: string, encoding: HARContentEncoding): string { |
| */ | ||
| function decodeContent(text: string, encoding?: 'base64'): string { | ||
| if (encoding === 'base64') { | ||
| return Buffer.from(text, 'base64').toString('utf8'); |
Member
There was a problem hiding this comment.
Suggested change
| return Buffer.from(text, 'base64').toString('utf8'); | |
| return Buffer.from(text, BASE64).toString('utf8'); |
| * @returns The decoded body as UTF-8 text. | ||
| */ | ||
| function decodeContent(text: string, encoding?: 'base64'): string { | ||
| if (encoding === 'base64') { |
Member
There was a problem hiding this comment.
Suggested change
| if (encoding === 'base64') { | |
| if (encoding === BASE64) { |
| size: number; | ||
| mimeType: string; | ||
| text?: string; | ||
| encoding?: 'base64'; |
Member
There was a problem hiding this comment.
Suggested change
| encoding?: 'base64'; | |
| encoding: HARContentEncoding; |
| } | ||
|
|
||
| const toBase64 = (value: string) => | ||
| Buffer.from(value, 'utf8').toString('base64'); |
Member
There was a problem hiding this comment.
Suggested change
| Buffer.from(value, 'utf8').toString('base64'); | |
| Buffer.from(value, 'utf8').toString(BASE64); |
| it('decodes base64-encoded CSS bodies', () => { | ||
| const css = '.a { color: blue; }'; | ||
| const har = makeHar([ | ||
| makeEntry('https://x.test/a.css', 'text/css', toBase64(css), 'base64'), |
Member
There was a problem hiding this comment.
Suggested change
| makeEntry('https://x.test/a.css', 'text/css', toBase64(css), 'base64'), | |
| makeEntry('https://x.test/a.css', 'text/css', toBase64(css), BASE64), |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First slice of the
--baselineCSS analysis feature. This PR adds extraction of external stylesheets from a HAR; inline<style>extraction, feature detection (css-tree), and Baseline lookup (web-features) follow in later PRs.The extractor is intentionally not wired into the CLI or
launchTestyet — it has no production caller until the detection PR consumes it, so it's exercised entirely by its unit tests. Keeping the slices separate keeps each PR small and isolates new dependencies to the PR that introduces them.Changes
extractCSSFromHar(harData): CSSSource[](src/baselineCssExtract.ts)Collects external CSS a page shipped, from a parsed HAR:
mimeTypestarts withtext/css(case-insensitive, soText/CSS; charset=utf-8matches), using the response body as the CSS source.content.encoding === 'base64').Inline
<style>blocks are out of scope here — they require parsing the HTML document, added in a follow-up PR with a dedicated parser.Types (
src/types.ts)CSSSource({ css, file }).HarEntry.response.contentwith optionaltext?andencoding?fields (response bodies weren't previously modeled).Tests
Adds
packages/telescope/__tests__/baselineCssExtract.test.ts— 7 pure unit tests (no browser) built from in-memory HAR fixtures:text/cssextracted with the URL asfiletext/css; charset=utf-8still matches