Skip to content

Commit b539771

Browse files
committed
feat(device): change xpath filter output format to use === separator
BREAKING CHANGE: The dump_hierarchy tool now returns matching XML elements separated by "===" instead of simple concatenation when xpath parameter is provided. - Update dump_hierarchy and save_dump_hierarchy functions to use "===\n" as separator between matching XML elements - Modify test cases to verify the new separator format - Update docstrings and comments to reflect the new behavior - Update changelog to reflect the changes made
1 parent 933975e commit b539771

File tree

4 files changed

+17
-11
lines changed

4 files changed

+17
-11
lines changed

.coveragerc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[run]
2+
omit =
3+
scripts/*
4+
tests/*
5+
venv/*
6+
src/**/version.py

CHANGELOG.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88
- Add xpath filter parameter to `dump_hierarchy` tool for filtering XML results
99

1010
- ⚙️ Changed:
11-
- Improve type hinting with `types-retry` dependency for better type checking
12-
- Add `types-lxml` to dev dependencies for proper type checking
13-
- Add type stubs to mypy pre-commit hook for comprehensive type coverage
11+
- Add serval type stubs for comprehensive type coverage
1412

1513
## 0.2.1
1614

src/u2mcp/tools/device.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -289,11 +289,11 @@ async def dump_hierarchy(
289289
max_depth (int): max depth of hierarchy.
290290
xpath (str): optional xpath expression to filter results.
291291
If empty, returns the full hierarchy xml.
292-
If provided, returns only matching elements as xml fragments.
292+
If provided, returns only matching elements, separated by "===".
293293
294294
Returns:
295295
str: xml string of the hierarchy tree.
296-
If xpath is provided, returns concatenated xml of all matching elements.
296+
If xpath is provided, returns matching elements separated by "===".
297297
"""
298298
async with get_device(serial) as device:
299299
xml_str = await to_thread.run_sync(
@@ -310,12 +310,12 @@ async def dump_hierarchy(
310310
if not nodes:
311311
return ""
312312

313-
# Return concatenated xml of matching nodes
313+
# Return xml of matching nodes, separated by ===
314314
result_parts: list[str] = []
315315
for node in nodes:
316316
result_parts.append(etree.tostring(node, encoding="unicode"))
317317

318-
return "\n".join(result_parts) if len(result_parts) > 1 else result_parts[0] if result_parts else ""
318+
return "\n===\n".join(result_parts)
319319

320320

321321
@mcp.tool("save_dump_hierarchy", tags={"device:capture"})
@@ -337,7 +337,7 @@ async def save_dump_hierarchy(
337337
max_depth (int): max depth of hierarchy.
338338
xpath (str): optional xpath expression to filter results.
339339
If empty, saves the full hierarchy xml.
340-
If provided, saves only matching elements as xml fragments.
340+
If provided, saves only matching elements, separated by "===".
341341
342342
Returns:
343343
str: absolute path to the saved file.
@@ -356,7 +356,7 @@ async def save_dump_hierarchy(
356356
result_parts: list[str] = []
357357
for node in nodes:
358358
result_parts.append(etree.tostring(node, encoding="unicode"))
359-
xml_str = "\n".join(result_parts) if len(result_parts) > 1 else result_parts[0] if result_parts else ""
359+
xml_str = "\n===\n".join(result_parts)
360360
else:
361361
xml_str = ""
362362

tests/unit/test_device.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ async def test_dump_hierarchy_with_xpath_single_match(mock_u2_device: MagicMock)
230230
@pytest.mark.asyncio
231231
@pytest.mark.unit
232232
async def test_dump_hierarchy_with_xpath_multiple_matches(mock_u2_device: MagicMock) -> None:
233-
"""Test dump_hierarchy returns concatenated XML when xpath matches multiple nodes."""
233+
"""Test dump_hierarchy returns XML separated by === when xpath matches multiple nodes."""
234234
sample_xml = """<?xml version='1.0' encoding='UTF-8'?>
235235
<hierarchy>
236236
<node resource-id="button1" text="Button 1" clickable="true"/>
@@ -241,10 +241,12 @@ async def test_dump_hierarchy_with_xpath_multiple_matches(mock_u2_device: MagicM
241241

242242
result = await dump_hierarchy.fn("emulator-5554", xpath="//*[@clickable='true']")
243243

244-
# Should return both clickable buttons
244+
# Should return both clickable buttons separated by ===
245245
assert 'resource-id="button1"' in result
246246
assert 'resource-id="button2"' in result
247247
assert 'clickable="true"' in result
248+
# Check for === separator
249+
assert "\n===\n" in result
248250
# Should not contain the non-clickable element
249251
assert 'resource-id="text"' not in result
250252

0 commit comments

Comments
 (0)