Skip to content

Commit da47396

Browse files
authored
Merge pull request #314 from autoscrape-labs/fix/iframe-oofpif
fix iframe empty inner html
2 parents 3e2dab6 + bd70299 commit da47396

File tree

2 files changed

+34
-12
lines changed

2 files changed

+34
-12
lines changed

pydoll/elements/web_element.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -928,17 +928,25 @@ async def _resolve_oopif_by_parent(
928928
if not attached_session_id:
929929
continue
930930
frame_tree = await self._get_frame_tree_for(browser_handler, attached_session_id)
931+
root_frame = (frame_tree or {}).get('frame', {})
932+
root_frame_id = root_frame.get('id', '')
933+
934+
if root_frame_id and backend_node_id is not None:
935+
owner_backend_id = await self._owner_backend_for(
936+
self._connection_handler, None, root_frame_id
937+
)
938+
if owner_backend_id == backend_node_id:
939+
return (
940+
browser_handler,
941+
attached_session_id,
942+
root_frame_id,
943+
root_frame.get('url'),
944+
)
945+
931946
child_frame_id = WebElement._find_child_by_parent(frame_tree, parent_frame_id)
932947
if child_frame_id:
933948
return browser_handler, attached_session_id, child_frame_id, None
934-
root_frame_id = (frame_tree or {}).get('frame', {}).get('id', '')
935-
if not root_frame_id or backend_node_id is None:
936-
continue
937-
owner_backend_id = await self._owner_backend_for(
938-
self._connection_handler, None, root_frame_id
939-
)
940-
if owner_backend_id == backend_node_id:
941-
return browser_handler, attached_session_id, root_frame_id, None
949+
942950
return None, None, None, None
943951

944952
@staticmethod

tests/test_web_element.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2450,7 +2450,11 @@ async def side_effect(command, timeout=60):
24502450

24512451
@pytest.mark.asyncio
24522452
async def test_resolve_oopif_scan_all_targets_find_child(self, iframe_element):
2453-
"""Test OOPIF resolution by scanning all targets and finding child."""
2453+
"""Test OOPIF resolution by scanning all targets and finding child.
2454+
2455+
This tests the fallback path where the root frame owner doesn't match,
2456+
so the code falls back to finding a child frame by parentId.
2457+
"""
24542458
with patch('pydoll.elements.web_element.ConnectionHandler') as mock_handler_class:
24552459
browser_handler = AsyncMock()
24562460
browser_handler.execute_command = AsyncMock()
@@ -2498,9 +2502,14 @@ async def side_effect(command, timeout=60):
24982502
}
24992503
}
25002504
}
2505+
if method == 'DOM.getFrameOwner':
2506+
# Return non-matching backend node ID to trigger child fallback
2507+
return {'result': {'backendNodeId': 888}} # Does NOT match 999
25012508
raise AssertionError(f'Unexpected method {method}')
25022509

25032510
browser_handler.execute_command.side_effect = side_effect
2511+
# Mock the connection handler for DOM.getFrameOwner calls
2512+
iframe_element._connection_handler.execute_command.side_effect = side_effect
25042513

25052514
handler, session_id, frame_id, url = await iframe_element._resolve_oopif_by_parent(
25062515
'parent-frame-123', 999
@@ -2509,11 +2518,16 @@ async def side_effect(command, timeout=60):
25092518
assert handler == browser_handler
25102519
assert session_id == 'session-1'
25112520
assert frame_id == 'matching-child'
2512-
assert url is None # URL not resolved in this path
2521+
assert url is None # URL not resolved in child path
25132522

25142523
@pytest.mark.asyncio
25152524
async def test_resolve_oopif_scan_all_targets_match_root_owner(self, iframe_element):
2516-
"""Test OOPIF resolution by matching root frame owner."""
2525+
"""Test OOPIF resolution by matching root frame owner.
2526+
2527+
This is the primary path for OOPIF resolution: when the root frame
2528+
of the OOPIF target is owned by our iframe element (matching backend_node_id).
2529+
The URL should be returned from the root frame.
2530+
"""
25172531
with patch('pydoll.elements.web_element.ConnectionHandler') as mock_handler_class:
25182532
browser_handler = AsyncMock()
25192533
browser_handler.execute_command = AsyncMock()
@@ -2569,7 +2583,7 @@ async def side_effect(command, timeout=60):
25692583
assert handler == browser_handler
25702584
assert session_id == 'session-1'
25712585
assert frame_id == 'oopif-root'
2572-
assert url is None
2586+
assert url == 'https://oopif.com' # URL is now correctly returned
25732587

25742588
@pytest.mark.asyncio
25752589
async def test_resolve_oopif_not_found(self, iframe_element):

0 commit comments

Comments
 (0)