
    >iU                       d dl mZ d dlZd dlZd dlZd dlZd dlmZ d dlm	Z	m
Z
 d dlZd dlmZmZmZmZ d dlmZ d dlmZmZ d dlmZ d d	lmZ d d
lmZmZmZmZmZm Z m!Z!m"Z"m#Z# d dl$m%Z%m&Z& d dl'm(Z( d dl)m*Z* d dl+m,Z,m-Z-m.Z.m/Z/ d dl0m1Z1m2Z2 d dl3m4Z4m5Z5m6Z6m7Z7 d dl8m9Z9 d dl:m;Z;m<Z<m=Z= e	r$d dl>m?Z@ d dlAmBZBmCZCmDZDmEZE d dl)mFZF d dlGmHZH d dl3m6Z6  ej                  eJ      ZK G d de      ZLy)    )annotationsN)Path)TYPE_CHECKINGOptional)DomCommandsInputCommandsPageCommandsRuntimeCommands)ConnectionHandler)KeyScripts)FindElementsMixin)
ShadowRoot)	ElementNotAFileInputElementNotFoundElementNotInteractableElementNotVisibleInvalidFileExtensionInvalidIFrameMissingScreenshotPathShadowRootNotFoundWaitElementTimeout)IFrameContextIFrameContextResolver)Keyboard)ShadowRootType)KeyEventTypeKeyModifierMouseButtonMouseEventType)ScreenshotFormatViewport)CallFunctionOnResponseEvaluateResponseGetPropertiesResponseSerializationOptions)CallArgument)decode_base64_to_bytesextract_text_from_htmlis_script_already_function)Mouse)DescribeNodeResponseGetBoxModelResponseGetOuterHTMLResponseResolveNodeResponse)Quad)CaptureScreenshotResponse)r%   c                  ,   e Zd ZU dZerded<   ded<   ded<   ddg df	 	 	 	 	 	 	 	 	 	 	 d>dZd?d	Zd@d
Ze	dAd       Z
e	dBd       Ze	dBd       Ze	dBd       Ze	dBd       Ze	dCd       Ze	dCd       Ze	dDd       Ze	dEd       Ze	dDd       Ze	dFd       ZdGdZdHdZdIdZdJdKdZdLdZdg df	 	 	 	 	 	 	 dMdZg df	 	 	 	 	 dNdZ	 	 	 dO	 	 	 	 	 	 	 dPd Zd! Zdddd"	 	 	 	 	 dQd#Zd$ Z	 	 	 	 dR	 	 	 	 	 	 	 dSd%Z d& Z!d' Z"dTd(Z#dUd)Z$	 	 dV	 	 	 	 	 dWd*Z%dXdYd+Z&dZd,Z'	 	 d[	 	 	 	 	 d\d-Z(dCd.Z)d/ Z*d0 Z+d1 Z,dddddddddddd2	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d]d3Z-d4 Z.dCd5Z/dDd6Z0d^d7Z1d8 Z2dg f	 	 	 	 	 	 	 d_d9Z3d`d:Z4d; Z5dCd<Z6e7dad=       Z8y)b
WebElementz
    DOM element wrapper for browser automation.

    Provides comprehensive functionality for element interaction, inspection,
    and manipulation using Chrome DevTools Protocol commands.
    zOptional[ConnectionHandler]_routing_session_handlerOptional[str]_routing_session_id_routing_parent_frame_idNc                H   || _         || _        || _        || _        i | _        d| _        || _        d| _        d| _        | j                  |       t        j                  d| j                    d| j                   d| j                   dt        | j                                y)a  
        Initialize WebElement wrapper.

        Args:
            object_id: Unique CDP object identifier for this DOM element.
            connection_handler: Connection instance for browser communication.
            method: Search method used to find this element (for debugging).
            selector: Selector string used to find this element (for debugging).
            attributes_list: Flat list of alternating attribute names and values.
            mouse: Optional Mouse instance for humanized click behavior.

        Note:
            Mouse and Keyboard follow different ownership strategies. Mouse is a shared
            instance from Tab, passed down to elements to preserve cursor position state
            across interactions. It dispatches commands through Tab._execute_command, which
            means it has no iframe context awareness. Keyboard is created per-element and
            routes commands through the element's own _execute_command, correctly handling
            iframe routing. For iframe elements, the mouse is intentionally skipped during
            humanized clicks (see click()) to avoid dispatching events to the wrong frame.
        Nz"WebElement initialized: object_id=z	, method=z, selector=z, attributes=)
_object_id_search_method	_selector_connection_handler_attributes	_keyboard_mouse_iframe_context_iframe_resolver_def_attributesloggerdebuglen)self	object_idconnection_handlermethodselectorattributes_listmouses          a/var/www/python/tenders/Scrapper/venv/lib/python3.12/site-packages/pydoll/elements/web_element.py__init__zWebElement.__init__W   s    : $$!#5 +--18<AE_-00A B))*+dnn5E Fd../02	
    c                R    | j                   t        |       | _         | j                   S )z&Get or create the keyboard controller.)r>   r   rF   s    rM   _get_keyboardzWebElement._get_keyboard   s!    >>!%d^DN~~rO   c                R    | j                   t        |       | _         | j                   S )z*Get or create the iframe context resolver.)rA   r   rQ   s    rM   _get_iframe_resolverzWebElement._get_iframe_resolver   s'      ($9$$?D!$$$rO   c                ,    t        | j                        S )z2Read-only copy of the element's cached attributes.)dictr=   rQ   s    rM   
attributeszWebElement.attributes   s     D$$%%rO   c                8    | j                   j                  d      S )z.Element's value attribute (for form elements).valuer=   getrQ   s    rM   rY   zWebElement.value   s     ##G,,rO   c                8    | j                   j                  d      S )zElement's CSS class name(s).
class_namerZ   rQ   s    rM   r]   zWebElement.class_name   s     ##L11rO   c                8    | j                   j                  d      S )zElement's ID attribute.idrZ   rQ   s    rM   r_   zWebElement.id   s     ##D))rO   c                8    | j                   j                  d      S )zElement's HTML tag name.tag_namerZ   rQ   s    rM   ra   zWebElement.tag_name   s     ##J//rO   c                    | j                   dv S )z)Whether the element represents an iframe.>   frameiframe)ra   rQ   s    rM   	is_iframezWebElement.is_iframe   s     }} 333rO   c                L    t        d| j                  j                         v      S )z*Whether element is enabled (not disabled).disabled)boolr=   keysrQ   s    rM   
is_enabledzWebElement.is_enabled   s#     Jd&6&6&;&;&==>>rO   c                  K   | j                         rt| j                  dd       d{   }|j                  di       j                  di       j                  dd      xs d}t        j	                  dt        |              |S | j                   d{   }t        |d	      }t        j	                  d
t        |              |S 7 7 6w)z$Visible text content of the element.z&return (this.textContent || "").trim()Treturn_by_valueNresultrY    z$Extracted text length (iframe ctx): )stripzExtracted text length: )_is_inside_iframeexecute_scriptr[   rC   rD   rE   
inner_htmlr)   )rF   response
text_value
outer_htmls       rM   textzWebElement.text   s      !!#595H5H8$ 6I 6 0H "h377"EII'SUV\Z\JLL?J?PQR??*
+JdC
.s:.?@A0 +s"   'CCA,CC5CCc                   K   t        j                  | j                        }| j                  |       d{   }|d   d   d   }t        j                  dt        |       d       |S 7 3w)z}
        Element's bounding box coordinates.

        Returns coordinates in CSS pixels relative to document origin.
        rG   Nrn   modelcontentzBounds retrieved (points=))r   get_box_modelr9   _execute_commandrC   rD   rE   )rF   commandrt   r{   s       rM   boundszWebElement.bounds   sh      ++dooF.2.C.CG.L(L8$W-i80Wa@A )Ms   5A-A+4A-c                  K   | j                   r| j                          d {   S | j                         rM| j                  dd       d {   }|j	                  di       j	                  di       j	                  dd      S t        j                  | j                        }| j                  |       d {   }|d   d   S 7 7 y7 w)	Nzreturn this.outerHTMLTrl   rn   rY   ro   ry   	outerHTML)	re   _get_iframe_inner_htmlrq   rr   r[   r   get_outer_htmlr9   r~   )rF   rt   r   response_get_outer_htmls       rM   rs   zWebElement.inner_html   s     >>44666!!#595H5H' 6I 6 0H <<"-11(B?CCGRPP,,tG>B>S>ST[>\8\&x0== 70 9]s4    CC*CCA*C8C	9CC	Cc                   K   | j                   sy| j                         }|j                          d{   | _        | j	                          | j                  S 7 %w)a'  
        Return the resolved iframe context for this element when it is an <iframe>.

        The context includes: frame_id, document_url, execution_context_id,
        document_object_id and, for OOPIF targets, the session_id and
        session_handler used for routing commands. The context is always freshly
        resolved to avoid stale execution contexts after iframe navigations or
        reloads. Non-iframe elements return None.

        Returns:
            IFrameContext | None: Resolved iframe context or None for non-iframes.
        N)re   rT   resolver@   _apply_routing_from_context)rF   resolvers     rM   iframe_contextzWebElement.iframe_context   sQ      ~~,,.%-%5%5%77((*###  8s   1AA&Ac                    |dk(  r)d| j                   v r| j                   j                  d      S | j                   j                  |      S )z
        Get element attribute value.

        Note:
            Only provides attributes available when element was located.
            For dynamic attributes, consider using JavaScript execution.
        classr]   rZ   )rF   names     rM   get_attributezWebElement.get_attribute   sF     7?|t/?/??##''55##D))rO   c                   K   | j                  t        j                  d       d{   }t        j                  |d   d   d         }t
        j                  d|        |S 7 <w)z
        Get element bounds using JavaScript getBoundingClientRect().

        Returns coordinates relative to viewport (alternative to bounds property).
        Trl   Nrn   rY   zBounds via JS: )rr   r   BOUNDSjsonloadsrC   rD   )rF   rt   r   s      rM   get_bounds_using_jszWebElement.get_bounds_using_js  s_      ,,W^^T,RRHX.x8ABvh/0 Ss   %A&A$=A&c                  K   t         j                  d| j                          | j                  t        j
                         d{   }| j                  |      st        d|        |d   d   d   }| j                  |       d{   }t         j                  d|        t        || j                  || j                        S 7 7 Aw)	zElement's parent element.z%Getting parent element for object_id=Nz&Parent element not found for element: rn   objectIdry   z#Parent element resolved: object_id=rK   rL   )rC   rD   r9   rr   r   GET_PARENT_NODE_has_object_id_keyr   _get_object_attributesr3   r<   r?   )rF   rn   rG   rW   s       rM   get_parent_elementzWebElement.get_parent_element  s     <T__<MNO**7+B+BCC&&v.!$J4&"QRR8$X.z:	666KK
:9+FGt//SWS^S^
 	
 D
 Ls&   ACCACCA CCr   c                  K   |s| j                          d{   S t        j                         j                         }	 	 | j                          d{   S 7 @7 # t        $ r Y nw xY wt        j                         j                         |z
  |kD  rt        d| d      t        j                  d       d{  7   w)aB  
        Get the shadow root attached to this element.

        Args:
            timeout: Maximum seconds to wait for the shadow root to appear.
                When > 0, repeatedly polls (every 0.5s) until a shadow root
                is found or the timeout expires.

        Returns:
            ShadowRoot instance for traversing the shadow DOM.

        Raises:
            ShadowRootNotFound: If no shadow root is attached (when timeout=0).
            WaitElementTimeout: If timeout > 0 and no shadow root appears
                within the specified duration.
        NzTimed out after z$s waiting for shadow root on element      ?)_get_shadow_rootasyncioget_event_looptimer   r   sleep)rF   timeout
start_times      rM   get_shadow_rootzWebElement.get_shadow_root  s     " ..000++-224
!22444 1
 5%  %%',,.;gE(&wi/ST  --$$$ sR   CA'CA AA CA 	A)&C(A))AC;B><Cc                l  K   | j                  t        j                  | j                  dd             d{   }|j	                  di       j	                  di       }|j	                  dg       }|s
t               |d   }|j	                  d	      }|st        d
      | j                  t        j                  |             d{   }|d   d   d   }t        |j	                  dd            }t        j                  d| d|j                          t        || j                  ||       S 7 7 jw)z>Get the shadow root attached to this element (single attempt).   T)rG   depthpierceNrn   nodeshadowRootsr   backendNodeIdz4Shadow root found but backend node ID is unavailable)backend_node_idobjectr   shadowRootTypeopenz Shadow root resolved: object_id=z, mode=)rG   rH   modehost_element)r~   r   describe_noder9   r[   r   resolve_noder   rC   rD   rY   r   r<   )	rF   rt   	node_infoshadow_rootsshadow_root_datar   resolve_responseshadow_object_idr   s	            rM   r   zWebElement._get_shadow_root<  s8    /3/D/D%%qQUV0
 *
 LL2.2262>	 }}]B7$&&'?*..?$%[\\6:6K6K$$_E7
 1
 ,H5h?
K.223CVLM78H7IQUQ[Q[P\]^&#77	
 	
+*
1
s#   5D4D0BD4D2A)D42D4r   Fc                  K   t         j                  d| d| d|        | j                  t        j                  ||       d{   }|s|rt        d|        t         j                  dt        |              |S 7 9w)a  
        Retrieve all direct and nested child elements of this element.

        Args:
            max_depth (int, optional): Maximum depth to traverse when finding children.
                Defaults to 1 for direct children only.
            tag_filter (list[str], optional): List of HTML tag names to filter results.
                If empty, returns all child elements regardless of tag. Defaults to [].

        Returns:
            list[WebElement]: List of child WebElement objects found within the specified
                depth and matching the tag filter criteria.

        Raises:
            ElementNotFound: If no child elements are found for this element and raise_exc is True.
        zGetting children: max_depth=z, tag_filter=, raise_exc=)script	max_depth
tag_filterNz%Child element not found for element: zChildren found: )rC   rD   _get_family_elementsr   GET_CHILDREN_NODEr   rE   )rF   r   r   	raise_excchildrens        rM   get_children_elementsz WebElement.get_children_elementsZ  s     & 	*9+ 6$\)>	
 22,,	j 3 
 
 I!$I$"PQQ'H78
s   ABB :Bc                   K   t         j                  d| d|        | j                  t        j                  |       d{   }|s|rt        d|        t         j                  dt        |              |S 7 9w)aV  
        Retrieve all sibling elements of this element (elements at the same DOM level).

        Args:
            tag_filter (list[str], optional): List of HTML tag names to filter results.
                If empty, returns all sibling elements regardless of tag. Defaults to [].

        Returns:
            list[WebElement]: List of sibling WebElement objects that share the same
                parent as this element and match the tag filter criteria.

        Raises:
            ElementNotFound: If no sibling elements are found for this element
            and raise_exc is True.
        zGetting siblings: tag_filter=r   )r   r   Nz'Sibling element not found for element: zSiblings found: )rC   rD   r   r   GET_SIBLINGS_NODEr   rE   )rF   r   r   siblingss       rM   get_siblings_elementsz WebElement.get_siblings_elementsy  s     $ 	4ZLYKXY22,, 3 
 
 I!$KD6"RSS'H78
s   A A>A<:A>c                &  K   |s|s
t               |r%t        |t              r|j                  d      d   }n>|r,t        |t              r|j
                  j                  d      }nt        j                  }|dk(  rd}t        j                  |      st        | d      t        j                  |      }| j                          d{   }t        |d   |d   |d	   |d
   d      }t        j                  d| d| d| d|d    d|d    d|d	    d|d
    d       | j                   j#                  t%        j&                  |||             d{   }|d   d   }	|rt        j)                  d       |	S |rtt+        |	      }
t-        j.                  t        |      d      4 d{   }|j1                  |
       d{    ddd      d{    t        j)                  d|        y7 )7 7 K7 47 &# 1 d{  7  sw Y   6xY ww)aL  
        Capture screenshot of this element only.

        Automatically scrolls element into view before capturing.

        Args:
            path: File path for screenshot (extension determines format).
            quality: Image quality 0-100 (default 100).
            as_base64: Return as base64 string instead of saving file.

        Returns:
            Base64 screenshot data if as_base64=True, None otherwise.

        Raises:
            InvalidFileExtension: If file extension not supported.
            MissingScreenshotPath: If path is None and as_base64 is False.
        .jpgjpegz extension is not supported.Nxywidthheightr   )r   r   r   r   scalez Taking element screenshot: path=z
, quality=z, as_base64=z, clip={x: z, y: z, w: z, h: })formatclipqualityrn   dataz2Element screenshot captured and returned as base64wbzElement screenshot saved: )r   
isinstancestrsplitr   suffixlstripr!   JPEG	has_valuer   	get_valuer   r"   rC   rD   r<   execute_commandr	   capture_screenshotinfor(   aiofilesr   write)rF   pathr   	as_base64output_extensionfile_formatr   r   
screenshotscreenshot_dataimage_bytesfiles               rM   take_screenshotzWebElement.take_screenshot  s    . I'))JtS)#zz#r2jt,#{{11#6/44 u$%))*:;&*:);;W'XYY&001AB//11SkSk/(#
 	.tfJwi|T]S^ _c5c5guTRZ^L\\^`	

 7;6N6N6^6^++;TSZ[7
 1

 %X.v6KKLM""0AK}}SY5 . .jj---. .KK4TF;<; 21
.-. . . .s   CHG1	BHG4AH*G6+H.G<G8G<HG:H4H6H8G<:H<HHH
Hc                   K   t        j                  | j                        }t        j	                  d| j                          | j                  |       d{    y7 w)z%Scroll element into visible viewport.ry   z'Scrolling element into view: object_id=N)r   scroll_into_view_if_neededr9   rC   r   r~   )rF   r   s     rM   scroll_into_viewzWebElement.scroll_into_view  sG     884??S=doo=NOP##G,,,s   AA!AA!)
is_visibleis_interactabler   c          	       K   || j                   f|| j                  fg}|D cg c]
  \  }}|s	| }}}|st        d      g }|r|j                  d       |r|j                  d       dj	                  |      }	t
        j                  d| d| d| d       t        j                         }
|
j                         }	 t        j                  d	 |D          d
{   }t        |      rt
        j                  d|	        y
|r<|
j                         |z
  |kD  r&t
        j                  d|	        t        d|	       t        j                  d       d
{    c c}}w 7 7 w)zWait for element to meet specified conditions.

        Raises:
            ValueError: If neither ``is_visible`` nor ``is_interactable`` is True.
            WaitElementTimeout: If the condition is not met within ``timeout``.
        z:At least one of is_visible or is_interactable must be Truevisibleinteractablez and zWaiting for element: visible=z, interactable=z
, timeout=sc              3  *   K   | ]  } |         y wN ).0checks     rM   	<genexpr>z(WebElement.wait_until.<locals>.<genexpr>  s     ,IUW,Is   NzElement condition satisfied: z&Timeout waiting for element to become z(Timed out waiting for element to become r   )r   r   
ValueErrorappendjoinrC   r   r   r   r   gatherallerrorr   r   )rF   r   r   r   
checks_mapflagfunccheckscondition_partscondition_msgloopr   resultss                rM   
wait_untilzWebElement.wait_until  sm     )d223

 *4<:4t$<<YZZ""9-"">2_5+J< 8+,JwiqB	
 %%'YY[
#NN,I&,IJJG7|;M?KL499;3g=Em_UV(+STaSb)cdd--$$$ # =$ K %s4   "E+
E!E!B)E+E'A>E+E)E+)E+c                  K   | j                          d{   r| j                          d{   S | j                          d{    | j                          d{   s
t	               t
        j                  d| j                          | j                  t        j                  d       d{   }|d   d   d   }|s
t               y7 7 7 7 w7 $w)a_  
        Click element using JavaScript click() method.

        Raises:
            ElementNotVisible: If element is not visible.
            ElementNotInteractable: If element couldn't be clicked.

        Note:
            For <option> elements, uses specialized selection approach.
            Element is automatically scrolled into view.
        Nz#Clicking element via JS: object_id=Trl   rn   rY   )_is_option_element_click_option_tagr   r   r   rC   r   r9   rr   r   CLICKr   )rF   rn   clickeds      rM   click_using_jszWebElement.click_using_js  s      ((***//111##%%%__&&&#%%9$//9JKL**7==$*OO"8,W5(**  +1%& PsV   CCCCCCCCAC3C4CCCCCc           	       K   | j                          d{   r| j                          d{   S | j                          d{   s
t               | j	                          d{    	 | j
                   d{   }| j                  |      }|d   |z   |d   |z   f}t        | d	d      du}|rZ| j                  N|sLt        j                  d
|d    d|d           | j                  j                  |d   |d          d{    yt        j                  d|d    d|d    d| d       t        j                  t         j"                  t%        |d         t%        |d         t&        j(                  d      }	t        j                  t         j*                  t%        |d         t%        |d         t&        j(                  d      }
| j-                  |	       d{    t/        j0                  |       d{    | j-                  |
       d{    y7 	7 7 7 7 # t        $ r? | j                          d{  7  }|d   |d   dz  z   |z   |d   |d   dz  z   |z   f}Y w xY w7 q7 7 }7 fw)a*  
        Click element using simulated mouse events.

        Args:
            x_offset: Horizontal offset from element center.
            y_offset: Vertical offset from element center.
            hold_time: Duration to hold mouse button down (used when humanize=False).
            humanize: When True and a Mouse instance is available, uses humanized
                Bezier curve movement from the current tracked position to the
                element center before clicking. When False, dispatches raw CDP
                mousePressed/mouseReleased events directly.

        Raises:
            ElementNotVisible: If element is not visible.

        Note:
            For <option> elements, delegates to specialized JavaScript approach.
            Element is automatically scrolled into view.
        Nr   r   r   r      r   r   r@   z Clicking element (humanized): x=z, y=zClicking element: x=z, hold=r   )typer   r   buttonclick_count)r  r  r   r   r   r   _calculate_centerKeyErrorr   getattrr?   rC   r   clickr   dispatch_mouse_eventr    MOUSE_PRESSEDintr   LEFTMOUSE_RELEASEDr~   r   r   )rF   x_offsety_offset	hold_timehumanizeelement_boundsposition_to_clickelement_bounds_jshas_iframe_contextpress_commandrelease_commands              rM   r  zWebElement.click+  s    4 ((***//111__&&&#%%##%%%	#';;.N $ 6 6~ F!!$x/!!$x/! %T+<dC4O/8JKK23DQ3G2HM^_`MaLbc ++##$5a$8:KA:NOOO"#4Q#7"8 9"1%&gi[;	
 &::--#A&'#A&'##
 (<<..#A&'#A&'##
 ##M222mmI&&&##O444e +1& 	& /  	&*&>&>&@ @ @!#&):7)Ca)GG(R!#&):8)Dq)HH8S!	 P* 	3&4s   JHJH"JH%!J(H()J.H. =H+>%H. #A%JI9	CJ#I<$J I>JJ J"J%J(J+H. .I6
I'I62J5I66J<J>J Jc                ~   K   | j                  t        j                  | j                               d{    y7 w)z-Focus this element via CDP DOM.focus command.ry   N)r~   r   focusr9   rQ   s    rM   r*  zWebElement.focusy  s)     ##K$5$5$PQQQs   3=;=c                  K   t         j                  d       | j                  t        j                  d       d{   }|d   j                  di       j                  dd      }|s t         j                  d       t        d      | j                  j                  d	d
      j                         dv rd
| j                  d<   yy7 w)a9  
        Clear the current value of the element.

        Supports standard inputs, textareas, and contenteditable elements.
        Dispatches ``input`` and ``change`` events so frameworks detect the update.

        Raises:
            ElementNotInteractable: If the element does not accept text input.
        zClearing element valueTrl   Nrn   rY   F"Element does not accept text inputra   ro   >   inputtextarea)
rC   r   rr   r   CLEAR_INPUTr[   r  r   r=   lower)rF   rn   successs      rM   clearzWebElement.clear}  s      	,-**7+>+>PT*UU"&&x488%HLL=>()MNN
B/557;PP(*DW% Q Vs   :CCB	Cc                  K   t         j                  dt        |       d       | j                  t        j
                  dt        |      g       d{   }t         j                  d|        |d   j                  di       j                  d	d
      }|s t         j                  d       t        d      | j                  j                  dd      j                         dv r|| j                  d	<   yy7 w)a  
        Insert text into element using JavaScript.

        Supports standard inputs, textareas, contenteditable elements, and rich text editors.
        Inserts text at cursor position or replaces selected text.

        Args:
            text: Text to insert.

        Raises:
            ElementNotInteractable: If element does not accept text input.

        Note:
            Uses JavaScript for maximum compatibility with all input types.
            Automatically handles input/textarea and contenteditable elements.
        zInserting text (length=r|   T)rY   )rm   	argumentsNzInsert text result: rn   rY   Fr,  ra   ro   >   r-  r.  )rC   r   rE   rr   r   INSERT_TEXTr'   rD   r[   r  r   r=   r0  )rF   rw   rn   r1  s       rM   insert_textzWebElement.insert_text  s     " 	-c$i[:;**,UYBZA[ + 
 
 	+F845"&&x488%HLL=>()MNN 
B/557;PP )-DW% Q
s   AC8C6B!C8c                  K   | j                   j                  dd      j                         dk7  s-| j                   j                  dd      j                         dk7  r
t               t	        |t
              r|D cg c]  }t        |       c}nt        |      g}t        j                  dt        |              | j                  t        j                  || j                               d{    yc c}w 7 
w)	z
        Set file paths for file input element.

        Args:
            files: list of absolute file paths to existing files.

        Raises:
            ElementNotAFileInput: If element is not a file input.
        ra   ro   r-  r  r   zSetting input files: count=)filesrG   N)r=   r[   r0  r   r   listr   rC   r   rE   r~   r   set_file_input_filesr9   )rF   r8  r   
files_lists       rM   set_input_fileszWebElement.set_input_files  s        R0668GC##FB/5576A&((6@6ME2Dc$i2TWX]T^S_
1#j/1BCD##,,:Y
 	
 	
 3	
s   A9C=;C6A#C=0C;1C=c                   K   t         j                  dt        |       d| d       | j                  |       d{    | j	                         }|j                  |||       d{    y7 17 w)z
        Type text character by character.

        Args:
            text: Text to type into the element.
            humanize: When True, simulates human-like typing.
            interval: Deprecated. Use humanize=True instead.
        zTyping text (length=z, humanize=r|   )r"  N)r"  interval)rC   r   rE   r  rR   	type_text)rF   rw   r"  r>  keyboards        rM   r?  zWebElement.type_text  sn      	*3t9+[
!LMjj(j+++%%'  8 LLL 	,Ls!   ;A3A/+A3)A1*A31A3c           	       K   t        j                  dt        d       |\  }}t        j	                  d| d| d|        | j                  t        j                  t        j                  ||||             d{    y7 w)	z
        Send key down event.

        .. deprecated::
            This method is deprecated. Use ``tab.keyboard.down()`` instead.

        Note:
            Only sends key down without release. Pair with key_up() for complete keypress.
        zjWebElement.key_down() is deprecated. Use tab.keyboard API instead: await tab.keyboard.down(key, modifiers)r  
stacklevelzKey down: key= code=z modifiers=)r  keywindows_virtual_key_codenative_virtual_key_code	modifiersN)
warningswarnDeprecationWarningrC   r   r~   r   dispatch_key_eventr   KEY_DOWN)rF   rE  rH  key_namecodes        rM   key_downzWebElement.key_down  s      	T		
 $nXJfTF+i[QR##,,!**)-(,#
 	
 	
s   A:B<B=Bc                  K   t        j                  dt        d       |\  }}t        j	                  d| d|        | j                  t        j                  t        j                  |||             d{    y7 w)z
        Send key up event (should follow corresponding key_down()).

        .. deprecated::
            This method is deprecated. Use ``tab.keyboard.up()`` instead.
        z[WebElement.key_up() is deprecated. Use tab.keyboard API instead: await tab.keyboard.up(key)r  rB  zKey up: key=rD  )r  rE  rF  rG  N)
rI  rJ  rK  rC   r   r~   r   rL  r   KEY_UP)rF   rE  rN  rO  s       rM   key_upzWebElement.key_up  s|      	G		
 $l8*F4&9:##,,!(()-(,	
 	
 	
s   A6B 8A>9B c                   K   t        j                  dt        d       | j                  ||       d{    t	        j
                  |       d{    | j                  |       d{    y7 ;7  7 	w)z
        Press and release keyboard key with configurable timing.

        .. deprecated::
            This method is deprecated. Use ``tab.keyboard.press()`` instead.

        Better for special keys (Enter, Tab, etc.) than type_text().
        zWebElement.press_keyboard_key() is deprecated. Use tab.keyboard API instead: await tab.keyboard.press(key, modifiers, interval)r  rB  N)rI  rJ  rK  rP  r   r   rS  )rF   rE  rH  r>  s       rM   press_keyboard_keyzWebElement.press_keyboard_key  sg      	_		
 mmC+++mmH%%%kk# 	,%s3   2A6A0A6A2A6*A4+A62A64A6c                   K   | j                  t        j                  d       d{   }|d   d   d   }t        j	                  d|        |S 7 )w)z
        Check if element can accept text input.

        Returns:
            True if element is editable (input, textarea, or contenteditable).
        Trl   Nrn   rY   zElement editable check: )rr   r   IS_EDITABLErC   rD   )rF   rn   is_editables      rM   rX  zWebElement.is_editable&  s[      **7+>+>PT*UUX&x09/}=> Vs   %AA*Ac                   K   | j                  t        j                  d       d{   }d|v ryt        |j	                  di       j	                  di       j	                  dd            S 7 Dw)zKCheck if element is visible using comprehensive JavaScript visibility test.Trl   Nr  Frn   rY   )rr   r   ELEMENT_VISIBLErh   r[   rF   rn   s     rM   r   zWebElement.is_visible2  sf     **7+B+BTX*YYfFJJx,002>BB7ERSS Z   %A.A,AA.c                   K   | j                  t        j                  d       d{   }d|v ryt        |j	                  di       j	                  di       j	                  dd            S 7 Dw)zJCheck if element is topmost at its center point (not covered by overlays).Trl   Nr  Frn   rY   )rr   r   ELEMENT_ON_TOPrh   r[   r[  s     rM   	is_on_topzWebElement.is_on_top9  sf     **7+A+ASW*XXfFJJx,002>BB7ERSS Yr\  c                   K   | j                  t        j                  d       d{   }d|v ryt        |j	                  di       j	                  di       j	                  dd            S 7 Dw)zBCheck if element is interactable based on visibility and position.Trl   Nr  Frn   rY   )rr   r   ELEMENT_INTERACTIVErh   r[   r[  s     rM   r   zWebElement.is_interactable@  sf     **7+F+FX\*]]fFJJx,002>BB7ERSS ^r\  )r4  silentrm   generate_previewuser_gestureawait_promiseexecution_context_idobject_groupthrow_on_side_effectunique_context_idserialization_optionsc               "  K   t        |      sd| d}t        j                  d| dt        |       d|rt        |      nd        t	        j
                  || j                  ||||||||	|
||      }| j                  |       d{   S 7 w)	av  
        Execute JavaScript in element context.

        Args:
            script (str): JavaScript code to execute. Use 'this' to reference this element.
            arguments (Optional[list[CallArgument]]): Arguments to pass to the function
                (Runtime.callFunctionOn).
            silent (Optional[bool]): Whether to silence exceptions (Runtime.callFunctionOn).
            return_by_value (Optional[bool]): Whether to return the result by value instead of
                reference (Runtime.callFunctionOn).
            generate_preview (Optional[bool]): Whether to generate a preview for the result
                (Runtime.callFunctionOn).
            user_gesture (Optional[bool]): Whether to treat the call as initiated by user
                gesture (Runtime.callFunctionOn).
            await_promise (Optional[bool]): Whether to await promise result
                (Runtime.callFunctionOn).
            execution_context_id (Optional[int]): ID of the execution context to call the
                function in (Runtime.callFunctionOn).
            object_group (Optional[str]): Symbolic group name for the result
                (Runtime.callFunctionOn).
            throw_on_side_effect (Optional[bool]): Whether to throw if side effect cannot be
                ruled out (Runtime.callFunctionOn).
            unique_context_id (Optional[str]): Unique context ID for the function call
                (Runtime.callFunctionOn).
            serialization_options (Optional[SerializationOptions]): Serialization options for
                the result (Runtime.callFunctionOn).

        Returns:
            CallFunctionOnResponse: The result of the script execution.

        Examples:
            # Click the element
            await element.execute_script('this.click()')

            # Modify element style
            await element.execute_script('this.style.border = "2px solid red"')

            # Get element text
            result = await element.execute_script('return this.textContent', return_by_value=True)

            # Set element content
            await element.execute_script('this.textContent = "Hello World"')
        zfunction(){ z }z-Executing script on element: return_by_value=z	, length=z, args=r   )function_declarationrG   r4  rb  rm   rc  rd  re  rf  rg  rh  ri  rj  N)r*   rC   rD   rE   r
   call_function_onr9   r~   )rF   r   r4  rb  rm   rc  rd  re  rf  rg  rh  ri  rj  r   s                 rM   rr   zWebElement.execute_scriptG  s     v *&1$VHC0F;O;L M&k]'I#i.1)MO	
 "22!'oo+-%'!5%!5/"7
 **73333s   BBB	Bc                    dj                  d | j                  j                         D              }| j                  j                   d| d| j
                   dS )z7String representation showing attributes and object ID.z, c              3  0   K   | ]  \  }}| d |  yw)=Nr   )r   kvs      rM   r   z&WebElement.__repr__.<locals>.<genexpr>  s     L41aQCq,Ls   (z)(object_id=r|   )r   r=   items	__class____name__r9   )rF   attrss     rM   __repr__zWebElement.__repr__  sN    		L43C3C3I3I3KLL..))*!E7,t>OqQQrO   c                <    | j                   duxr | j                   S )zJCheck if this element is inside an iframe context (not the iframe itself).N)r@   re   rQ   s    rM   rq   zWebElement._is_inside_iframe  s    ##4/F4FFrO   c                   K   | j                    d{   }|t        d      | j                  t        j                  d|j
                  d             d{   }|d   d   j                  dd      S 7 b7 w)	z$Get inner HTML of an iframe element.Nz Unable to resolve iframe contextz"document.documentElement.outerHTMLT)
expression
context_idrm   rn   rY   ro   )r   r   r~   r
   evaluaterf  r[   )rF   r   rt   s      rM   r   z!WebElement._get_iframe_inner_html  s     #222! BCC+/+@+@$$?)>> $,
 &
 !(+//<< 3&
s"   A9A5AA9A7A97A9c                     y)aW  Apply routing attributes from iframe context.

        After iframe context resolution, commands targeting the *content* of
        the iframe should route through ``_iframe_context`` (handled by
        ``_resolve_routing`` which prioritises ``_iframe_context`` over
        ``_routing_session_*``).

        The ``_routing_session_handler`` / ``_routing_session_id`` attributes
        must be preserved: they identify the parent OOPIF session where the
        ``<iframe>`` *element itself* lives.  The resolver needs them to
        re-describe the element on subsequent re-resolutions.
        Nr   rQ   s    rM   r   z&WebElement._apply_routing_from_context  s    rO   c                   K   | j                  t        j                  | j                  t        j
                  d             d{    y7 w)z?Specialized method for clicking <option> elements in dropdowns.T)rG   rl  rm   N)r~   r
   rm  r9   r   CLICK_OPTION_TAGrQ   s    rM   r  zWebElement._click_option_tag  s?     ##,,//%,%=%= $
 	
 	
s   AAAAc           	     F  K   | j                  |j                  ||             d{   }| j                  |      sg S |d   d   d   }t        j                  |      }| j                  |       d{   }g }|d   d   D ]q  }	|	d   j                         rd|	d   v s|	d   d   }
| j                  |
       d{   }|j                  t        |
| j                  || j                               s t        j                  d	t        |              |S 7 7 7 _w)
a   
        Retrieve all family elements of this element (elements at the same DOM level).

        Args:
            script (str): CDP script to execute for retrieving family elements.
            tag_filter (list[str], optional): List of HTML tag names to filter results.
                If empty, returns all family elements regardless of tag. Defaults to [].

        Returns:
            list[WebElement]: List of family WebElement objects that share the same
                parent as this element and match the tag filter criteria.
        )r   r   Nrn   r   ry   r   rY   r   zFamily elements found: )rr   r   r   r
   get_propertiesr~   isdigitr   r   r3   r<   r?   rC   rD   rE   )rF   r   r   r   rn   array_object_idget_properties_commandproperties_responsefamily_elementspropchild_object_idrW   s               rM   r   zWebElement._get_family_elements  sB     **MMZ9ME
 
 &&v.I *84Z@!0!?!?/!Z;?;P;P"<
 6
 -/'1(; 	DL((*zT']/J"7mJ7O#::_:UUJ""#,,$.++		 	.s?/C.DEF;
6
 Vs6   &D!DAD!5D6A	D!?D AD!D!D!c                    t        dt        |      d      D ]'  }||   }|dk7  r|nd}||dz      }|| j                  |<   ) t        j	                  dt        | j                                y)zNProcess flat attribute list into dictionary (renames 'class' to 'class_name').r   r  r   r]   r   zAttributes defined: count=N)rangerE   r=   rC   rD   )rF   rK   irE  rY   s        rM   rB   zWebElement._def_attributes  sv    q#o.2 	*A!!$C#\C#AE*E$)DS!		*
 	1#d6F6F2G1HIJrO   c                \    | j                   j                  dd      j                         dk(  S )z$Check if element is an <option> tag.ra   ro   option)r=   r[   r0  rQ   s    rM   _is_option_tagzWebElement._is_option_tag   s)    ##J399;xGGrO   c                  K   | j                   j                  dd      }|r|j                         dk(  S t        t	        | dd      xs d      }t	        | dd      }t        t	        |d|      xs d      j                         }|dk(  r|j                         dk(  ry|dk(  rd|j                         v ry| j                  t        j                  d	       d
{   }|j                  di       j                  di       j                  dd      }|r*| j                   j                  d      sd| j                   d<   t        |      S 7 mw)zb
        Robust check for <option> elements, falling back to JS when tag_name is missing.
        ra   ro   r  r;   r:   rY   Txpathrl   Nrn   F)	r=   r[   r0  r   r  rr   r   IS_OPTION_TAGrh   )rF   tagrJ   
method_rawrI   rn   	is_options          rM   r  zWebElement._is_option_element  s/     "":r299;(** wt["5;<T#3R8
WZ*=CDJJLZHNN$4$@WX^^-=!=**7+@+@RV*WWJJx,002>BB7ER	T--11*=+3DZ(I	 Xs   CEEA.Ec                   t        dt        |       d      D cg c]  }| |   	 }}t        dt        |       d      D cg c]  }| |   	 }}t        |      t        |      z  }t        |      t        |      z  }||fS c c}w c c}w )z5Calculate center point from bounding box coordinates.r   r  r   )r  rE   sum)r   r  x_valuesy_valuesx_centery_centers         rM   r  zWebElement._calculate_center  s     (-QFQ'?@!F1I@@',QFQ'?@!F1I@@x=3x=0x=3x=0!!	 A@s
   A?B)rG   r   rH   r   rI   r5   rJ   r5   rK   	list[str]rL   zOptional['MouseType'])returnr   )r  r   )r  zdict[str, str])r  r5   )r  rh   )r  r   )r  r0   )r  zOptional[IFrameContext])r   r   r  r5   )r  zdict[str, int])r  r3   )r   )r   floatr  r   )r  r   )r   r  r   r  r   rh   r  list[WebElement])r   r  r   rh   r  r  )Nd   F)r   zOptional[str | Path]r   r  r   rh   r  r5   )r   rh   r   rh   r   r  )r   r   皙?F)r  r  r   r  r!  r  r"  rh   )rw   r   )r8  zstr | Path | list[str | Path])FN)rw   r   r"  rh   r>  zOptional[float]r   )rE  r   rH  Optional[KeyModifier])rE  r   )Nr  )rE  r   rH  r  r>  r  )r   r   r4  zOptional[list[CallArgument]]rb  Optional[bool]rm   r  rc  r  rd  r  re  r  rf  zOptional[int]rg  r5   rh  r  ri  r5   rj  zOptional[SerializationOptions]r  r#   )r  None)r   r   r   r  r   r  r  r  )rK   r  )r   r9  r  tuple)9rv  
__module____qualname____doc__r   __annotations__rN   rR   rT   propertyrW   rY   r]   r_   ra   re   rj   rw   r   rs   r   r   r   r   r   r   r   r   r   r   r
  r  r  r*  r2  r6  r<  r?  rP  rS  rU  rX  r   r_  r   rr   rx  rq   r   r   r  r   rB   r  r  staticmethodr  r   rO   rM   r3   r3   J   s%    "==**"// !%"&%''++
+
 .+
 	+

  +
 #+
 %+
Z% & & - - 2 2 * * 0 0 4 4 ? ?   
 
 > > $ $*
*	
 %D
>  !"PU.7IM	@ ')E#59	: &*	G"G G 	G
 
GR- ! %,% ,% 	,%
 ,%\+8 L5L5 L5 	L5
 L5\R+& -D
0 $(	MM M "	M&
8
6 ,0	 ) 	0
TTT 37!%*.+/'+(,.2&*/3+/@DQ4Q4 0	Q4
 Q4 (Q4 )Q4 %Q4 &Q4 ,Q4 $Q4 -Q4 )Q4  >Q4 
 Q4fR
G=
 -.r,,&),;D,	,\KH. " "rO   r3   )M
__future__r   r   r   loggingrI  pathlibr   typingr   r   r   pydoll.commandsr   r   r	   r
   pydoll.connectionr   pydoll.constantsr   r   pydoll.elements.mixinsr   pydoll.elements.shadow_rootr   pydoll.exceptionsr   r   r   r   r   r   r   r   r   pydoll.interactions.iframer   r   pydoll.interactions.keyboardr   pydoll.protocol.dom.typesr   pydoll.protocol.input.typesr   r   r   r    pydoll.protocol.page.typesr!   r"   pydoll.protocol.runtime.methodsr#   r$   r%   r&   pydoll.protocol.runtime.typesr'   pydoll.utilsr(   r)   r*   pydoll.interactions.mouser+   	MouseTypepydoll.protocol.dom.methodsr,   r-   r.   r/   r0   pydoll.protocol.page.methodsr1   	getLoggerrv  rC   r3   r   rO   rM   <module>r     s    "      *   0 5 2
 
 
 L 1 4  B  7  <  /FE			8	$X"" X"rO   