Skip to content

Commit 3803ae6

Browse files
committed
fix: improving children and parent retrive docstring and creating a private generic method for then
1 parent 73d2cb7 commit 3803ae6

File tree

1 file changed

+79
-44
lines changed

1 file changed

+79
-44
lines changed

pydoll/elements/web_element.py

Lines changed: 79 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -147,58 +147,50 @@ async def get_parent_element(self) -> 'WebElement':
147147
async def get_children_elements(
148148
self, max_depth: int = 1, tag_filter: list[str] = []
149149
) -> list['WebElement']:
150-
"""Element's child elements."""
151-
result = await self.execute_script(
152-
Scripts.GET_CHILDREN_NODE.format(max_depth=max_depth, tag_filter=tag_filter)
153-
)
154-
if not self._has_object_id_key(result):
155-
raise ElementNotFound(f'Child element not found for element: {self}')
156-
157-
array_object_id = result['result']['result']['objectId']
150+
"""
151+
Retrieve all direct and nested child elements of this element.
158152
159-
get_properties_command = RuntimeCommands.get_properties(object_id=array_object_id)
160-
properties_response: GetPropertiesResponse = await self._execute_command(
161-
get_properties_command
162-
)
153+
Args:
154+
max_depth (int, optional): Maximum depth to traverse when finding children.
155+
Defaults to 1 for direct children only.
156+
tag_filter (list[str], optional): List of HTML tag names to filter results.
157+
If empty, returns all child elements regardless of tag. Defaults to [].
163158
164-
children_elements: list['WebElement'] = []
165-
for prop in properties_response['result']['result']:
166-
if prop['name'].isdigit() and 'objectId' in prop['value']:
167-
child_object_id = prop['value']['objectId']
168-
attributes = await self._get_object_attributes(object_id=child_object_id)
169-
children_elements.append(
170-
WebElement(
171-
child_object_id, self._connection_handler, attributes_list=attributes
172-
)
173-
)
159+
Returns:
160+
list[WebElement]: List of child WebElement objects found within the specified
161+
depth and matching the tag filter criteria.
174162
175-
return children_elements
163+
Raises:
164+
ElementNotFound: If no child elements are found for this element.
165+
"""
166+
try:
167+
return await self._get_family_elements(
168+
script=Scripts.GET_CHILDREN_NODE, max_depth=max_depth, tag_filter=tag_filter
169+
)
170+
except ElementNotFound:
171+
raise ElementNotFound(f'Child element not found for element: {self}')
176172

177173
async def get_siblings_elements(self, tag_filter: list[str] = []) -> list['WebElement']:
178-
"""Element's siblings elements."""
179-
result = await self.execute_script(Scripts.GET_SIBLINGS_NODE.format(tag_filter=tag_filter))
180-
if not self._has_object_id_key(result):
181-
raise ElementNotFound(f'Sibling element not found for element: {self}')
174+
"""
175+
Retrieve all sibling elements of this element (elements at the same DOM level).
182176
183-
array_object_id = result['result']['result']['objectId']
177+
Args:
178+
tag_filter (list[str], optional): List of HTML tag names to filter results.
179+
If empty, returns all sibling elements regardless of tag. Defaults to [].
184180
185-
get_properties_command = RuntimeCommands.get_properties(object_id=array_object_id)
186-
properties_response: GetPropertiesResponse = await self._execute_command(
187-
get_properties_command
188-
)
181+
Returns:
182+
list[WebElement]: List of sibling WebElement objects that share the same
183+
parent as this element and match the tag filter criteria.
189184
190-
siblings_elements: list['WebElement'] = []
191-
for prop in properties_response['result']['result']:
192-
if prop['name'].isdigit() and 'objectId' in prop['value']:
193-
child_object_id = prop['value']['objectId']
194-
attributes = await self._get_object_attributes(object_id=child_object_id)
195-
siblings_elements.append(
196-
WebElement(
197-
child_object_id, self._connection_handler, attributes_list=attributes
198-
)
199-
)
200-
201-
return siblings_elements
185+
Raises:
186+
ElementNotFound: If no sibling elements are found for this element.
187+
"""
188+
try:
189+
return await self._get_family_elements(
190+
script=Scripts.GET_SIBLINGS_NODE, tag_filter=tag_filter
191+
)
192+
except ElementNotFound:
193+
raise ElementNotFound(f'Sibling element not found for element: {self}')
202194

203195
async def take_screenshot(self, path: str, quality: int = 100):
204196
"""
@@ -492,6 +484,49 @@ async def execute_script(self, script: str, return_by_value: bool = False):
492484
)
493485
)
494486

487+
async def _get_family_elements(
488+
self, script: str, max_depth: int = 1, tag_filter: list[str] = []
489+
) -> list['WebElement']:
490+
"""
491+
Retrieve all family elements of this element (elements at the same DOM level).
492+
493+
Args:
494+
script (str): CDP script to execute for retrieving family elements.
495+
tag_filter (list[str], optional): List of HTML tag names to filter results.
496+
If empty, returns all family elements regardless of tag. Defaults to [].
497+
498+
Returns:
499+
list[WebElement]: List of family WebElement objects that share the same
500+
parent as this element and match the tag filter criteria.
501+
502+
Raises:
503+
ElementNotFound: If no family elements are found for this element.
504+
"""
505+
result = await self.execute_script(
506+
script.format(tag_filter=tag_filter, max_depth=max_depth)
507+
)
508+
if not self._has_object_id_key(result):
509+
raise ElementNotFound(f'Family element not found for element: {self}')
510+
511+
array_object_id = result['result']['result']['objectId']
512+
513+
get_properties_command = RuntimeCommands.get_properties(object_id=array_object_id)
514+
properties_response: GetPropertiesResponse = await self._execute_command(
515+
get_properties_command
516+
)
517+
518+
family_elements: list['WebElement'] = []
519+
for prop in properties_response['result']['result']:
520+
if not (prop['name'].isdigit() and 'objectId' in prop['value']):
521+
continue
522+
child_object_id = prop['value']['objectId']
523+
attributes = await self._get_object_attributes(object_id=child_object_id)
524+
family_elements.append(
525+
WebElement(child_object_id, self._connection_handler, attributes_list=attributes)
526+
)
527+
528+
return family_elements
529+
495530
def _def_attributes(self, attributes_list: list[str]):
496531
"""Process flat attribute list into dictionary (renames 'class' to 'class_name')."""
497532
for i in range(0, len(attributes_list), 2):

0 commit comments

Comments
 (0)