mirror of
https://github.com/browser-use/browser-use.git
synced 2026-10-02 04:04:36 +08:00
fix(dom): match hidden code styles case-insensitively (#5640)
## Summary
- normalize casing and whitespace before applying the existing `display:
none` filter for `<code>` elements
- prevent hidden code payloads from entering clean Markdown when inline
CSS uses valid case or whitespace variants
- add real-browser regression coverage for lowercase, mixed-case,
tab-separated, and `!important` declarations
Fixes #5637
## Testing
- `uv run pytest tests/ci/test_html_serializer_style.py -q` — 4 passed
- `uv run pytest tests/ci/test_markdown_extractor.py
tests/ci/test_markdown_chunking.py -q` — 38 passed
- `uv run pre-commit run --files
browser_use/dom/serializer/html_serializer.py
tests/ci/test_html_serializer_style.py` — all hooks passed
Each regression case verifies that Chrome computes the element as
`display: none` and that `extract_clean_markdown` omits the hidden
payload while preserving visible content.
<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Fixes hidden code payloads from leaking into clean Markdown when inline
`style` uses valid case or whitespace variants like `Display: None` or
`DISPLAY:\tNONE`. Fixes #5637.
- Normalizes style casing and whitespace before applying the existing
`display: none` filter.
- Adds regression tests for lower-case, mixed-case, tab-separated, and
`!important` declarations.
<sup>Written for commit c9b3e5507a.
Summary will update on new commits.</sup>
<a
href="https://cubic.dev/pr/browser-use/browser-use/pull/5640?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
This commit is contained in:
@@ -74,7 +74,8 @@ class HTMLSerializer:
|
||||
if tag_name == 'code' and node.attributes:
|
||||
style = node.attributes.get('style', '')
|
||||
# Check if element is hidden (display:none) - likely JSON data
|
||||
if 'display:none' in style.replace(' ', '') or 'display: none' in style:
|
||||
normalized_style = ''.join(style.lower().split())
|
||||
if 'display:none' in normalized_style:
|
||||
return ''
|
||||
# Also check for bpr-guid IDs (LinkedIn's JSON data pattern)
|
||||
element_id = node.attributes.get('id', '')
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
from urllib.parse import quote
|
||||
|
||||
import pytest
|
||||
|
||||
from browser_use.dom.markdown_extractor import extract_clean_markdown
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'style',
|
||||
[
|
||||
'display: none',
|
||||
'Display: None',
|
||||
'DISPLAY:\tNONE',
|
||||
'color: red; display : none !important',
|
||||
],
|
||||
)
|
||||
async def test_hidden_code_inline_style_is_case_insensitive(browser_session, style: str):
|
||||
html = f'<main>visible control</main><code id="snippet" style="{style}">hidden state payload</code>'
|
||||
await browser_session.navigate_to('data:text/html,' + quote(html))
|
||||
|
||||
page = await browser_session.get_current_page()
|
||||
assert page is not None
|
||||
computed_display = await page.evaluate("() => getComputedStyle(document.querySelector('#snippet')).display")
|
||||
markdown, _ = await extract_clean_markdown(browser_session=browser_session)
|
||||
|
||||
assert computed_display == 'none'
|
||||
assert 'visible control' in markdown
|
||||
assert 'hidden state payload' not in markdown
|
||||
Reference in New Issue
Block a user