U
    g~                     @   s  d Z ddlZddlZddlZddlZddlZddl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 ddlmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlm Z  ddl!m"Z" ddl!m#Z# ddl$m%Z% ddl&m'Z' ddl(m)Z) ddl(m*Z* ddl(m+Z+ ddl,m-Z- ddl.m/Z/ ddl0m1Z1 dd l2m3Z3 dd!l4m5Z5 dd"l6m7Z7 dd#l8m9Z9 dd$l:m;Z; dd%l:m<Z< dd&l=m>Z> dd'l?m@Z@ dd(lAmBZB dd)lCmDZD dd*lEmFZF dd+lGmHZH dd,lImJZJ dd-lKmLZL daMdaNd.d/ ZOd0d1 ZPd=eQeeReBf eSeSee3 eBd2d3d4ZTee# ed5d6d7ZUG d8d9 d9ed:ZVG d;d< d<eVZWdS )>zThe WebDriver implementation.    N)ABCMeta)	b64decode)urlsafe_b64encode)asynccontextmanager)contextmanager)import_module)Dict)List)Optional)Union)InvalidArgumentException)JavascriptException)NoSuchCookieException)NoSuchElementException)WebDriverException)Script)By)
ArgOptions)BaseOptions)PrintOptions)Timeouts)
Credential)VirtualAuthenticatorOptions)required_virtual_authenticator)
RelativeBy   )Dialog   )BidiConnection)ClientConfig)Command)ErrorHandler)FedCM)FileDetector)LocalFileDetector)LocatorConverter)Mobile)RemoteConnection)	ScriptKey)
ShadowRoot)SwitchTo)
WebElement)WebSocketConnectionc                   C   s   t stda d S )Nz"selenium.webdriver.common.bidi.cdp)cdpr    r.   r.   G/tmp/pip-unpacked-wheel-3ysq0mf8/selenium/webdriver/remote/webdriver.py
import_cdpN   s    r0   c                 C   s8   t | } i }|  D ]\}}|||< qdi g|diS )a  Makes a W3C alwaysMatch capabilities object.

    Filters out capability names that are not in the W3C spec. Spec-compliant
    drivers will reject requests containing unknown capability names.

    Moves the Firefox profile, if present, from the old location to the new Firefox
    options object.

    :Args:
     - caps - A dictionary of capabilities requested by the caller.
    capabilities)
firstMatchalwaysMatch)copydeepcopyitems)capsZalways_matchkvr.   r.   r/   _create_capsT   s
    

r:   )r1   command_executor
keep_aliveignore_local_proxyclient_configreturnc                    s   t |tr(|pt|d}||_t|d}ddlm} ddlm} ddl	m
} ddlm} ||||g}	t fdd	|	D t}
|
||||d
S )N)remote_server_addr)r>   r   )ChromeRemoteConnection)EdgeRemoteConnection)FirefoxRemoteConnection)SafariRemoteConnectionc                 3   s"   | ]}|j  d kr|V  qdS )browserNameN)Zbrowser_nameget).0cr1   r.   r/   	<genexpr>x   s      z(get_remote_connection.<locals>.<genexpr>)r@   r<   Zignore_proxyr>   )
isinstancestrr   r@   r'   Z+selenium.webdriver.chrome.remote_connectionrA   Z)selenium.webdriver.edge.remote_connectionrB   Z,selenium.webdriver.firefox.remote_connectionrC   Z+selenium.webdriver.safari.remote_connectionrD   next)r1   r;   r<   r=   r>   rA   rB   rC   rD   
candidateshandlerr.   rI   r/   get_remote_connectiong   s     

rP   optionsr?   c                 C   s   di i}g }| D ]}| |  qt|}i }t|D ]p}|}|d |k r8||  }|D ]J}	|	||d   kr\|| |	 ||d  |	 kr\||	|| |	 i q\q8i }
| D ]\}}||
|< q|D ]}|
D ]
}||= qq|
|d d< ||d d< |S )Nr1   r   r3   r2   )appendto_capabilitieslenrangekeysupdater6   )rR   r1   optsoptZ	opts_sizeZsamesiesiZ	min_indexZ
first_keysZkysalwaysr8   r9   r.   r.   r/   create_matches   s.    

r]   c                   @   s   e Zd ZdZdS )BaseWebDriverzAbstract Base Class for all Webdriver subtypes.

    ABC's allow custom implementations of Webdriver to be registered so
    that isinstance type checks will succeed.
    N)__name__
__module____qualname____doc__r.   r.   r.   r/   r^      s   r^   )	metaclassc                
   @   s  e Zd ZdZeZeZdee	e
f eee eeeee f  ee ee ee ddddZdd	 Zd
d Zejeje  eje ejej dddZedd ZeedddZ ee	dddZ!dd Z"dd Z#e$ddddZ%dd Z&e	edd d!Z'd"d# Z(de	e$e$d$d%d&Z)e	dd'd(d)Z*ee	dd*d+Z+de	e,d,d-d.Z-e,dd/d0d1Z.ee	 dd2d3Z/d4d5 Z0e	d6d7d8Z1ee	dd9d:Z2ee	dd;d<Z3ddd=d>Z4ddd?d@Z5ee	ddAdBZ6eee	 ddCdDZ7dddEdFZ8dddGdHZ9dddIdJZ:dee; e	dKdLdMZ<ee=ddNdOZ>dddPdQZ?dddRdSZ@dddTdUZAee$ ddVdWZBejejC ddXdYZDdddZd[ZEddd\d]ZFddd^d_ZGeHdd`dadbZIeHdd`dcddZJeHdd`dedfZKeeLddgdhZMeMjNdddidhZMeOjPdfee	 edjdkdlZQeOjPdfee	 ee djdmdnZRee$ddodpZSeddqdrZTeddsdtZUeVddudvZWe	ddwdxZXde	ddzd{d|ZYde	e$dzd}d~ZZdeHeHe	e$dddZ[de$dddZ\e	ddzddZ]e$dddZ^de$dddZ_eedddZ`e`jNddddZ`edd ZaeajNddddZaedd Zbdd Zcdd Zdeedd Zfedd Zgdd Zhdd ZiejddddZkee	dddZlemddddZnemeoddddZpemeeo dddZqemee	erf ddddZsemddddZtemeddddZue$dddZve	e	ddddZwddddZxeeydddZzeedddZ{dd Z|edd Z}dddĄZ~dS )	WebDrivera  Controls a browser by sending commands to a remote server. This server
    is expected to be running the WebDriver wire protocol as defined at
    https://www.selenium.dev/documentation/legacy/json_wire_protocol/.

    :Attributes:
     - session_id - String ID of the browser session started and controlled by this WebDriver.
     - capabilities - Dictionary of effective capabilities of this browser session as returned
         by the remote server. See https://www.selenium.dev/documentation/legacy/desired_capabilities/
     - command_executor - remote_connection.RemoteConnection object used to execute commands.
     - error_handler - errorhandler.ErrorHandler object used to handle errors.
    http://127.0.0.1:4444TN)r;   r<   file_detectorrR   locator_converterweb_element_clsr>   r?   c           
      C   s   t |trt|}d}	n| }|j}	|| _t | jttfrPt||||	|d| _d| _	d| _
i | _i | _t | _t| | _t| | _|pt | _|pt | _|p| j| _d| _|   | | t| | _d| _d| _dS )a  Create a new driver that will issue commands using the wire
        protocol.

        :Args:
         - command_executor - Either a string representing URL of the remote server or a custom
             remote_connection.RemoteConnection object. Defaults to 'http://127.0.0.1:4444/wd/hub'.
         - keep_alive - (Deprecated) Whether to configure remote_connection.RemoteConnection to use
             HTTP keep-alive. Defaults to True.
         - file_detector - Pass custom file detector object during instantiation. If None,
             then default LocalFileDetector() will be used.
         - options - instance of a driver options.Options class
         - locator_converter - Custom locator converter to use. Defaults to None.
         - web_element_cls - Custom class to use for web elements. Defaults to WebElement.
         - client_config - Custom client configuration to use. Defaults to None.
        F)r;   r<   r=   r>   TN)rK   listr]   rT   _ignore_local_proxyr;   rL   bytesrP   Z
_is_remote
session_idr7   pinned_scriptsr!   error_handlerr*   
_switch_tor&   _mobiler$   rf   r%   rg   _web_element_cls_authenticator_idstart_clientstart_sessionr"   _fedcm_websocket_connection_script)
selfr;   r<   rf   rR   rg   rh   r>   r1   rj   r.   r.   r/   __init__   s<    




zWebDriver.__init__c                 C   s&   dt | j dt | j d| j dS )N<.z (session="z")>)typer`   r_   rl   rx   r.   r.   r/   __repr__   s    zWebDriver.__repr__c                 C   s   | S Nr.   r}   r.   r.   r/   	__enter__   s    zWebDriver.__enter__)exc_typeexc	tracebackc                 C   s   |    d S r   )quit)rx   r   r   r   r.   r.   r/   __exit__   s    zWebDriver.__exit__c                 o   s>   d}t | j|s"| j}|||| _z
dV  W 5 |r8|| _X dS )a  Overrides the current file detector (if necessary) in limited
        context. Ensures the original file detector is set afterwards.

        Example::

            with webdriver.file_detector_context(UselessFileDetector):
                someinput.send_keys('/etc/hosts')

        :Args:
         - file_detector_class - Class of the desired file detector. If the class is different
             from the current file_detector, then the class is instantiated with args and kwargs
             and used as a file detector during the duration of the context manager.
         - args - Optional arguments that get passed to the file detector class during
             instantiation.
         - kwargs - Keyword arguments, passed the same way as args.
        N)rK   rf   )rx   Zfile_detector_classargskwargsZlast_detectorr.   r.   r/   file_detector_context  s    
zWebDriver.file_detector_context)r?   c                 C   s   | j S r   )rp   r}   r.   r.   r/   mobile!  s    zWebDriver.mobilec                 C   s    d| j kr| j d S tddS )zReturns the name of the underlying browser for this instance.

        :Usage:
            ::

                name = driver.name
        rE   z1browserName not specified in session capabilitiesN)r7   KeyErrorr}   r.   r.   r/   name%  s    	

zWebDriver.namec                 C   s   dS )zxCalled before starting a new session.

        This method may be overridden to define custom startup behavior.
        Nr.   r}   r.   r.   r/   rs   2  s    zWebDriver.start_clientc                 C   s   dS )zCalled after executing a quit command.

        This method may be overridden to define custom shutdown
        behavior.
        Nr.   r}   r.   r.   r/   stop_client9  s    zWebDriver.stop_client)r1   r?   c                 C   s6   t |}| tj|d }|d| _|d| _dS )zCreates a new session with the desired capabilities.

        :Args:
         - capabilities - a capabilities dict to start the session with.
        value	sessionIdr1   N)r:   executer    ZNEW_SESSIONrF   rl   r7   )rx   r1   r7   responser.   r.   r/   rt   A  s    zWebDriver.start_sessionc                    s   t |tr2i }| D ]\}} |||< q|S t | jrHd|jiS t | jr^d|jiS t |tr~t fdd|D S |S )N#element-6066-11e4-a52e-4f735466cecf"shadow-6066-11e4-a52e-4f735466cecfc                 3   s   | ]}  |V  qd S r   )_wrap_valuerG   itemr}   r.   r/   rJ   X  s     z(WebDriver._wrap_value.<locals>.<genexpr>)rK   dictr6   r   rq   id_shadowroot_clsri   )rx   r   Z	convertedkeyvalr.   r}   r/   r   M  s    



zWebDriver._wrap_value)
element_idr?   c                 C   s   |  | |S )z6Creates a web element with the specified `element_id`.)rq   )rx   r   r.   r.   r/   create_web_element[  s    zWebDriver.create_web_elementc                    s   t |tr\d|kr  |d S d|kr8  |d S | D ]\}} |||< q@|S t |tr|t fdd|D S |S )Nr   r   c                 3   s   | ]}  |V  qd S r   )_unwrap_valuer   r}   r.   r/   rJ   i  s     z*WebDriver._unwrap_value.<locals>.<genexpr>)rK   r   r   r   r6   r   ri   )rx   r   r   r   r.   r}   r/   r   _  s    

zWebDriver._unwrap_value)driver_commandparamsr?   c                 C   sx   |  |}| jr2|s d| ji}nd|kr2| j|d< | j||}|rj| j| | |dd|d< |S dd| jdS )aH  Sends a command to be executed by a command.CommandExecutor.

        :Args:
         - driver_command: The name of the command to execute as a string.
         - params: A dictionary of named parameters to send with the command.

        :Returns:
          The command's JSON response loaded into a dictionary object.
        r   r   Nr   )successr   r   )r   rl   r;   r   rn   Zcheck_responser   rF   )rx   r   r   r   r.   r.   r/   r   l  s    


zWebDriver.execute)urlr?   c                 C   s   |  tjd|i dS )z0Loads a web page in the current browser session.r   N)r   r    GET)rx   r   r.   r.   r/   rF     s    zWebDriver.getc                 C   s   |  tjddS )zuReturns the title of the current page.

        :Usage:
            ::

                title = driver.title
        r    )r   r    Z	GET_TITLErF   r}   r.   r.   r/   title  s    	zWebDriver.title)scriptr?   c                 C   s   t |}|| j|j< |S )zUStore common javascript scripts to be executed later by a unique
        hashable ID.)r(   rm   r   )rx   r   
script_keyZscript_key_instancer.   r.   r/   
pin_script  s    zWebDriver.pin_script)r   r?   c                 C   sD   z| j |j W n, tk
r>   td| d| j  dY nX dS )z$Remove a pinned script from storage.zNo script with key: z existed in N)rm   popr   r   )rx   r   r.   r.   r/   unpin  s    zWebDriver.unpinc                 C   s
   t | jS r   )ri   rm   r}   r.   r.   r/   get_pinned_scripts  s    zWebDriver.get_pinned_scriptsc                 G   s\   t |tr8z| j|j }W n tk
r6   tdY nX t|}tj}| 	|||dd S )a'  Synchronously Executes JavaScript in the current window/frame.

        :Args:
         - script: The JavaScript to execute.
         - \*args: Any applicable arguments for your JavaScript.

        :Usage:
            ::

                driver.execute_script('return document.title;')
        z Pinned script could not be foundr   r   r   )
rK   r(   rm   r   r   r   ri   r    ZW3C_EXECUTE_SCRIPTr   rx   r   r   Zconverted_argscommandr.   r.   r/   execute_script  s    
zWebDriver.execute_script)r   c                 G   s$   t |}tj}| |||dd S )a  Asynchronously Executes JavaScript in the current window/frame.

        :Args:
         - script: The JavaScript to execute.
         - \*args: Any applicable arguments for your JavaScript.

        :Usage:
            ::

                script = "var callback = arguments[arguments.length - 1]; " \
                         "window.setTimeout(function(){ callback('timeout') }, 3000);"
                driver.execute_async_script(script)
        r   r   )ri   r    ZW3C_EXECUTE_SCRIPT_ASYNCr   r   r.   r.   r/   execute_async_script  s    zWebDriver.execute_async_scriptc                 C   s   |  tjd S )znGets the URL of the current page.

        :Usage:
            ::

                driver.current_url
        r   )r   r    ZGET_CURRENT_URLr}   r.   r.   r/   current_url  s    	zWebDriver.current_urlc                 C   s   |  tjd S )zqGets the source of the current page.

        :Usage:
            ::

                driver.page_source
        r   )r   r    ZGET_PAGE_SOURCEr}   r.   r.   r/   page_source  s    	zWebDriver.page_sourcec                 C   s   |  tj dS )zcCloses the current window.

        :Usage:
            ::

                driver.close()
        N)r   r    ZCLOSEr}   r.   r.   r/   close  s    zWebDriver.closec                 C   s*   z| tj W 5 |    | j  X dS )z|Quits the driver and closes every associated window.

        :Usage:
            ::

                driver.quit()
        N)r   r;   r   r   r    ZQUITr}   r.   r.   r/   r     s    zWebDriver.quitc                 C   s   |  tjd S )zReturns the handle of the current window.

        :Usage:
            ::

                driver.current_window_handle
        r   )r   r    ZW3C_GET_CURRENT_WINDOW_HANDLEr}   r.   r.   r/   current_window_handle  s    	zWebDriver.current_window_handlec                 C   s   |  tjd S )zReturns the handles of all windows within the current session.

        :Usage:
            ::

                driver.window_handles
        r   )r   r    ZW3C_GET_WINDOW_HANDLESr}   r.   r.   r/   window_handles
  s    	zWebDriver.window_handlesc                 C   s   t j}| |d dS )z5Maximizes the current window that webdriver is using.N)r    ZW3C_MAXIMIZE_WINDOWr   )rx   r   r.   r.   r/   maximize_window  s    zWebDriver.maximize_windowc                 C   s   |  tj dS )z<Invokes the window manager-specific 'full screen' operation.N)r   r    ZFULLSCREEN_WINDOWr}   r.   r.   r/   fullscreen_window  s    zWebDriver.fullscreen_windowc                 C   s   |  tj dS )z9Invokes the window manager-specific 'minimize' operation.N)r   r    ZMINIMIZE_WINDOWr}   r.   r.   r/   minimize_window  s    zWebDriver.minimize_window)print_optionsr?   c                 C   s"   i }|r|  }| tj|d S )zTakes PDF of the current page.

        The driver makes a best effort to return a PDF based on the
        provided parameters.
        r   )to_dictr   r    Z
PRINT_PAGE)rx   r   rR   r.   r.   r/   
print_page"  s    zWebDriver.print_pagec                 C   s   | j S )a<  
        :Returns:
            - SwitchTo: an object containing all options to switch focus into

        :Usage:
            ::

                element = driver.switch_to.active_element
                alert = driver.switch_to.alert
                driver.switch_to.default_content()
                driver.switch_to.frame('frame_name')
                driver.switch_to.frame(1)
                driver.switch_to.frame(driver.find_elements(By.TAG_NAME, "iframe")[0])
                driver.switch_to.parent_frame()
                driver.switch_to.window('main')
        )ro   r}   r.   r.   r/   	switch_to.  s    zWebDriver.switch_toc                 C   s   |  tj dS )zvGoes one step backward in the browser history.

        :Usage:
            ::

                driver.back()
        N)r   r    ZGO_BACKr}   r.   r.   r/   backC  s    zWebDriver.backc                 C   s   |  tj dS )zxGoes one step forward in the browser history.

        :Usage:
            ::

                driver.forward()
        N)r   r    Z
GO_FORWARDr}   r.   r.   r/   forwardM  s    zWebDriver.forwardc                 C   s   |  tj dS )zfRefreshes the current page.

        :Usage:
            ::

                driver.refresh()
        N)r   r    ZREFRESHr}   r.   r.   r/   refreshW  s    zWebDriver.refreshc                 C   s   |  tjd S )zReturns a set of dictionaries, corresponding to cookies visible in
        the current session.

        :Usage:
            ::

                driver.get_cookies()
        r   )r   r    ZGET_ALL_COOKIESr}   r.   r.   r/   get_cookiesb  s    	zWebDriver.get_cookiesc              
   C   s8   t t$ | tjd|id W  5 Q R  S Q R X dS )zGet a single cookie by name. Returns the cookie if found, None if
        not.

        :Usage:
            ::

                driver.get_cookie('my_cookie')
        r   r   N)
contextlibsuppressr   r   r    Z
GET_COOKIErx   r   r.   r.   r/   
get_cookiem  s    	(zWebDriver.get_cookiec                 C   s   |  tjd|i dS )zDeletes a single cookie with the given name.

        :Usage:
            ::

                driver.delete_cookie('my_cookie')
        r   N)r   r    ZDELETE_COOKIEr   r.   r.   r/   delete_cookiez  s    zWebDriver.delete_cookiec                 C   s   |  tj dS )zDelete all cookies in the scope of the session.

        :Usage:
            ::

                driver.delete_all_cookies()
        N)r   r    ZDELETE_ALL_COOKIESr}   r.   r.   r/   delete_all_cookies  s    zWebDriver.delete_all_cookiesc                 C   sB   d|kr,|d dkst | tjd|i n| tjd|i dS )ag  Adds a cookie to your current session.

        :Args:
         - cookie_dict: A dictionary object, with required keys - "name" and "value";
            optional keys - "path", "domain", "secure", "httpOnly", "expiry", "sameSite"

        :Usage:
            ::

                driver.add_cookie({'name' : 'foo', 'value' : 'bar'})
                driver.add_cookie({'name' : 'foo', 'value' : 'bar', 'path' : '/'})
                driver.add_cookie({'name' : 'foo', 'value' : 'bar', 'path' : '/', 'secure' : True})
                driver.add_cookie({'name' : 'foo', 'value' : 'bar', 'sameSite' : 'Strict'})
        ZsameSite)ZStrictZLaxNonecookieN)AssertionErrorr   r    Z
ADD_COOKIE)rx   cookie_dictr.   r.   r/   
add_cookie  s    zWebDriver.add_cookie)time_to_waitr?   c                 C   s"   |  tjdtt|d i dS )a  Sets a sticky timeout to implicitly wait for an element to be found,
        or a command to complete. This method only needs to be called one time
        per session. To set the timeout for calls to execute_async_script, see
        set_script_timeout.

        :Args:
         - time_to_wait: Amount of time to wait (in seconds)

        :Usage:
            ::

                driver.implicitly_wait(30)
        implicit  Nr   r    SET_TIMEOUTSintfloatrx   r   r.   r.   r/   implicitly_wait  s    zWebDriver.implicitly_waitc                 C   s"   |  tjdtt|d i dS )a!  Set the amount of time that the script should wait during an
        execute_async_script call before throwing an error.

        :Args:
         - time_to_wait: The amount of time to wait (in seconds)

        :Usage:
            ::

                driver.set_script_timeout(30)
        r   r   Nr   r   r.   r.   r/   set_script_timeout  s    zWebDriver.set_script_timeoutc              	   C   sX   z"|  tjdtt|d i W n0 tk
rR   |  tjt|d dd Y nX dS )zSet the amount of time to wait for a page load to complete before
        throwing an error.

        :Args:
         - time_to_wait: The amount of time to wait

        :Usage:
            ::

                driver.set_page_load_timeout(30)
        pageLoadr   z	page load)msr|   N)r   r    r   r   r   r   r   r.   r.   r/   set_page_load_timeout  s    "zWebDriver.set_page_load_timeoutc                 C   sP   |  tjd }|dd |d< |dd |d< |dd |d< tf |S )zGet all the timeouts that have been set on the current session.

        :Usage:
            ::

                driver.timeouts
        :rtype: Timeout
        r   r   r   Zimplicit_waitr   Z	page_loadr   )r   r    ZGET_TIMEOUTSr   r   )rx   timeoutsr.   r.   r/   r     s
    
zWebDriver.timeoutsc                 C   s   |  tj| d }dS )a  Set all timeouts for the session. This will override any previously
        set timeouts.

        :Usage:
            ::
                my_timeouts = Timeouts()
                my_timeouts.implicit_wait = 10
                driver.timeouts = my_timeouts
        r   N)r   r    r   Z_to_json)rx   r   _r.   r.   r/   r     s    )r   r?   c                 C   s^   | j ||\}}t|trF| j||d}|s>td|j |d S | tj	||dd S )zFind an element given a By strategy and locator.

        :Usage:
            ::

                element = driver.find_element(By.ID, 'foo')

        :rtype: WebElement
        )byr   z%Cannot locate relative element with: r   Zusingr   r   )
rg   convertrK   r   find_elementsr   rootr   r    ZFIND_ELEMENT)rx   r   r   elementsr.   r.   r/   find_element  s    

zWebDriver.find_elementc                 C   s~   | j ||\}}t|trbdtddd }t|d	d}d| d}| 
|| S | tj||dd	 p|g S )
zFind elements given a By strategy and locator.

        :Usage:
            ::

                elements = driver.find_elements(By.CLASS_NAME, 'foo')

        :rtype: list of WebElement
        r{   NzfindElements.jsutf8z/* findElements */return (z).apply(null, arguments);r   r   )rg   r   rK   r   joinr_   splitpkgutilget_datadecoder   r   r   r    ZFIND_ELEMENTS)rx   r   r   Z_pkgZraw_functionZfind_element_jsr.   r.   r/   r     s    

zWebDriver.find_elementsc                 C   s   | j S )z4Returns the drivers current capabilities being used.)r7   r}   r.   r.   r/   r1     s    zWebDriver.capabilitiesc              	   C   sx   t | ds"tjdtdd |  }zDz$t|d}|| W 5 Q R X W n t	k
rj   Y W 
dS X W 5 ~X dS )a  Saves a screenshot of the current window to a PNG image file.
        Returns False if there is any IOError, else returns True. Use full
        paths in your filename.

        :Args:
         - filename: The full path you wish to save your screenshot to. This
           should end with a `.png` extension.

        :Usage:
            ::

                driver.get_screenshot_as_file('/Screenshots/foo.png')
        z.pngz^name used for saved screenshot does not match file type. It should end with a `.png` extensionr   
stacklevelwbFT)
rL   lowerendswithwarningswarnUserWarningget_screenshot_as_pngopenwriteOSError)rx   filenameZpngfr.   r.   r/   get_screenshot_as_file  s    z WebDriver.get_screenshot_as_filec                 C   s
   |  |S )a  Saves a screenshot of the current window to a PNG image file.
        Returns False if there is any IOError, else returns True. Use full
        paths in your filename.

        :Args:
         - filename: The full path you wish to save your screenshot to. This
           should end with a `.png` extension.

        :Usage:
            ::

                driver.save_screenshot('/Screenshots/foo.png')
        )r   )rx   r   r.   r.   r/   save_screenshot=  s    zWebDriver.save_screenshotc                 C   s   t |  dS )zGets the screenshot of the current window as a binary data.

        :Usage:
            ::

                driver.get_screenshot_as_png()
        ascii)r   get_screenshot_as_base64encoder}   r.   r.   r/   r   M  s    zWebDriver.get_screenshot_as_pngc                 C   s   |  tjd S )zGets the screenshot of the current window as a base64 encoded string
        which is useful in embedded images in HTML.

        :Usage:
            ::

                driver.get_screenshot_as_base64()
        r   )r   r    Z
SCREENSHOTr}   r.   r.   r/   r   W  s    	z"WebDriver.get_screenshot_as_base64current)windowHandler?   c                 C   s$   |  | | jt|t|d dS )a$  Sets the width and height of the current window. (window.resizeTo)

        :Args:
         - width: the width in pixels to set the window to
         - height: the height in pixels to set the window to

        :Usage:
            ::

                driver.set_window_size(800,600)
        widthheightN"_check_if_window_handle_is_currentset_window_rectr   )rx   r   r   r   r.   r.   r/   set_window_sizeb  s    
zWebDriver.set_window_sizec                    s8   |  | |    ddr& d   fdddD S )zGets the width and height of the current window.

        :Usage:
            ::

                driver.get_window_size()
        r   Nc                    s   i | ]}| | qS r.   r.   rG   r8   sizer.   r/   
<dictcomp>  s      z-WebDriver.get_window_size.<locals>.<dictcomp>r   )r  get_window_rectrF   rx   r   r.   r  r/   get_window_sizeq  s
    	
zWebDriver.get_window_size)xyr   r?   c                 C   s    |  | | jt|t|dS )a.  Sets the x,y position of the current window. (window.moveTo)

        :Args:
         - x: the x-coordinate in pixels to set the window position
         - y: the y-coordinate in pixels to set the window position

        :Usage:
            ::

                driver.set_window_position(0,0)
        r  r  r   )rx   r  r  r   r.   r.   r/   set_window_position  s    
zWebDriver.set_window_positionc                    s$   |  | |    fdddD S )zGets the x,y position of the current window.

        :Usage:
            ::

                driver.get_window_position()
        c                    s   i | ]}| | qS r.   r.   r  positionr.   r/   r    s      z1WebDriver.get_window_position.<locals>.<dictcomp>r  )r  r  r	  r.   r  r/   get_window_position  s    	
zWebDriver.get_window_positionc                 C   s   |dkrt jddd dS )z5Warns if the window handle is not equal to `current`.r   z?Only 'current' window is supported for W3C compatible browsers.r   r   N)r   r   r	  r.   r.   r/   r    s    z,WebDriver._check_if_window_handle_is_currentc                 C   s   |  tjd S )zGets the x, y coordinates of the window as well as height and width
        of the current window.

        :Usage:
            ::

                driver.get_window_rect()
        r   )r   r    ZGET_WINDOW_RECTr}   r.   r.   r/   r    s    	zWebDriver.get_window_rectc                 C   s<   |dkr |dkr |s |s t d| tj||||dd S )a  Sets the x, y coordinates of the window as well as height and width
        of the current window. This method is only supported for W3C compatible
        browsers; other browsers should use `set_window_position` and
        `set_window_size`.

        :Usage:
            ::

                driver.set_window_rect(x=10, y=10)
                driver.set_window_rect(width=100, height=200)
                driver.set_window_rect(x=10, y=10, width=100, height=200)
        Nz'x and y or height and width need values)r  r  r   r   r   )r   r   r    ZSET_WINDOW_RECT)rx   r  r  r   r   r.   r.   r/   r    s    zWebDriver.set_window_rectc                 C   s   | j S r   )_file_detectorr}   r.   r.   r/   rf     s    zWebDriver.file_detectorc                 C   s(   |st dt|tst d|| _dS )a0  Set the file detector to be used when sending keyboard input. By
        default, this is set to a file detector that does nothing.

        see FileDetector
        see LocalFileDetector
        see UselessFileDetector

        :Args:
         - detector: The detector to use. Must not be None.
        z,You may not set a file detector that is nullz+Detector has to be instance of FileDetectorN)r   rK   r#   r  )rx   detectorr.   r.   r/   rf     s
    
c                 C   s   |  tjd S )zGets the current orientation of the device.

        :Usage:
            ::

                orientation = driver.orientation
        r   )r   r    ZGET_SCREEN_ORIENTATIONr}   r.   r.   r/   orientation  s    	zWebDriver.orientationc                 C   s4   ddg}|  |kr(| tjd|i ntddS )zSets the current orientation of the device.

        :Args:
         - value: orientation to set it to.

        :Usage:
            ::

                driver.orientation = 'landscape'
        Z	LANDSCAPEZPORTRAITr  z>You can only set the orientation to 'LANDSCAPE' and 'PORTRAIT'N)upperr   r    ZSET_SCREEN_ORIENTATIONr   )rx   r   Zallowed_valuesr.   r.   r/   r    s    c                 C   s   |  tjd S )zGets a list of the available log types. This only works with w3c
        compliant browsers.

        :Usage:
            ::

                driver.log_types
        r   )r   r    ZGET_AVAILABLE_LOG_TYPESr}   r.   r.   r/   	log_types  s    
zWebDriver.log_typesc                 C   s   |  tjd|id S )a>  Gets the log for a given log type.

        :Args:
         - log_type: type of log that which will be returned

        :Usage:
            ::

                driver.get_log('browser')
                driver.get_log('driver')
                driver.get_log('client')
                driver.get_log('server')
        r|   r   )r   r    ZGET_LOG)rx   Zlog_typer.   r.   r/   get_log  s    zWebDriver.get_logc                 C   s   | j rt| j fS t  ts| jdrJ| jd}| jddd }n|  \}}|sbtdt	|a| jd 
 dkrtjdtd	d
 t|| _ | j tj }|d j}| j tj|d}|| j _t| j fS d S )Nse:cdpse:cdpVersionr{   r   2Unable to find url to connect to from capabilitiesrE   ZfirefoxznCDP support for Firefox is deprecated and will be removed in future versions. Please switch to WebDriver BiDi.r   r   T)rv   devtoolsr0   r7   rF   r   _get_cdp_detailsr   r-   import_devtoolsr   r   r   DeprecationWarningr,   r   targetget_targets	target_idZattach_to_targetrl   )rx   ws_urlversiontargetsr!  sessionr.   r.   r/   start_devtools  s.    



zWebDriver.start_devtoolsc                 C  s   t   | jdr6| jd}| jddd }n|  \}}|sNtdt|}t|4 I d H X}|	|j
 I d H }|d j}||4 I d H }t|t|V  W 5 Q I d H R X W 5 Q I d H R X d S )Nr  r  r{   r   r  )r0   r7   rF   r   r  r   r-   r  Zopen_cdpr   r  r   r!  Zopen_sessionr   )rx   r"  r#  r  connr$  r!  r%  r.   r.   r/   bidi_connection1  s    

zWebDriver.bidi_connectionc                 C   s&   | j s|   | js t| j | _| jS r   )rv   _start_bidirw   r   r}   r.   r.   r/   r   E  s
    zWebDriver.scriptc                 C   s0   | j dr| j d}ntdt|| _d S )NZwebSocketUrlr  )r7   rF   r   r,   rv   )rx   r"  r.   r.   r/   r)  O  s    zWebDriver._start_bidic                 C   s   dd l }dd l}| }d}| jddkr@| jdd}n4| jddkrd| jdd}nd	}| jd
}|dd| d}||j}|d}|d}	dd l}
|rd}n|
	d|
d}||	fS )Nr   FrE   Zchromezgoog:chromeOptionsZdebuggerAddressZMicrosoftEdgezms:edgeOptionsTzmoz:debuggerAddressr   zhttp://z/json/versionZBrowserZwebSocketDebuggerUrlU   z
.*/(\d+)\.r   )jsonurllib3PoolManagerr7   rF   requestloadsdataresearchgroup)rx   r+  r,  httpZ_firefoxZdebugger_addressresr0  Zbrowser_versionZwebsocket_urlr1  r#  r.   r.   r/   r  W  s&    

zWebDriver._get_cdp_detailsrQ   c                 C   s   |  tj| d | _dS )z4Adds a virtual authenticator with the given options.r   N)r   r    ZADD_VIRTUAL_AUTHENTICATORr   rr   )rx   rR   r.   r.   r/   add_virtual_authenticatorw  s    z#WebDriver.add_virtual_authenticatorc                 C   s   | j S )z,Returns the id of the virtual authenticator.)rr   r}   r.   r.   r/   virtual_authenticator_id{  s    z"WebDriver.virtual_authenticator_idc                 C   s   |  tjd| ji d| _dS )zRemoves a previously added virtual authenticator.

        The authenticator is no longer valid after removal, so no
        methods may be called.
        authenticatorIdN)r   r    ZREMOVE_VIRTUAL_AUTHENTICATORrr   r}   r.   r.   r/   remove_virtual_authenticator  s    z&WebDriver.remove_virtual_authenticator)
credentialr?   c                 C   s    |  tj| d| ji dS )z,Injects a credential into the authenticator.r8  N)r   r    ZADD_CREDENTIALr   rr   )rx   r:  r.   r.   r/   add_credential  s    zWebDriver.add_credentialc                 C   s&   |  tjd| ji}dd |d D S )z;Returns the list of credentials owned by the authenticator.r8  c                 S   s   g | ]}t |qS r.   )r   	from_dict)rG   r:  r.   r.   r/   
<listcomp>  s     z-WebDriver.get_credentials.<locals>.<listcomp>r   )r   r    ZGET_CREDENTIALSrr   )rx   Zcredential_datar.   r.   r/   get_credentials  s    zWebDriver.get_credentials)credential_idr?   c                 C   s0   t |trt| }| tj|| jd dS )z,Removes a credential from the authenticator.)ZcredentialIdr8  N)rK   	bytearrayr   r   r   r    ZREMOVE_CREDENTIALrr   )rx   r?  r.   r.   r/   remove_credential  s    
 
zWebDriver.remove_credentialc                 C   s   |  tjd| ji dS )z/Removes all credentials from the authenticator.r8  N)r   r    ZREMOVE_ALL_CREDENTIALSrr   r}   r.   r.   r/   remove_all_credentials  s    z WebDriver.remove_all_credentials)verifiedr?   c                 C   s   |  tj| j|d dS )zSets whether the authenticator will simulate success or fail on user
        verification.

        verified: True if the authenticator will pass user verification, False otherwise.
        )r8  ZisUserVerifiedN)r   r    ZSET_USER_VERIFIEDrr   )rx   rC  r.   r.   r/   set_user_verified  s    zWebDriver.set_user_verifiedc                 C   s&   d| j krtd| tjd d S )z]Retrieves the downloadable files as a map of file names and their
        corresponding URLs.se:downloadsEnabledCYou must enable downloads in order to work with downloadable files.r   names)r1   r   r   r    ZGET_DOWNLOADABLE_FILESr}   r.   r.   r/   get_downloadable_files  s    
z WebDriver.get_downloadable_files)	file_nametarget_directoryr?   c              
   C   s   d| j krtdtj|s(t| | tjd|id d }t	
 `}tj||d }t|d}|t| W 5 Q R X t|d}|| W 5 Q R X W 5 Q R X d	S )
zDownloads a file with the specified file name to the target
        directory.

        file_name: The name of the file to download.
        target_directory: The path to the directory to save the downloaded file.
        rE  rF  r   r   contentsz.zipr   rN)r1   r   ospathexistsmakedirsr   r    ZDOWNLOAD_FILEtempfileTemporaryDirectoryr   r   r   base64r   zipfileZipFile
extractall)rx   rI  rJ  rK  Ztmp_dirzip_filefileZzip_refr.   r.   r/   download_file  s    


zWebDriver.download_filec                 C   s"   d| j krtd| tj dS )zDeletes all downloadable files.rE  rF  N)r1   r   r   r    ZDELETE_DOWNLOADABLE_FILESr}   r.   r.   r/   delete_downloadable_files  s    
z#WebDriver.delete_downloadable_filesc                 C   s   | j S )aw  
        :Returns:
            - FedCM: an object providing access to all Federated Credential Management (FedCM) dialog commands.

        :Usage:
            ::

                title = driver.fedcm.title
                subtitle = driver.fedcm.subtitle
                dialog_type = driver.fedcm.dialog_type
                accounts = driver.fedcm.account_list
                driver.fedcm.select_account(0)
                driver.fedcm.accept()
                driver.fedcm.dismiss()
                driver.fedcm.enable_delay()
                driver.fedcm.disable_delay()
                driver.fedcm.reset_cooldown()
        )ru   r}   r.   r.   r/   fedcm  s    zWebDriver.fedcmc                 C   s   | j tjdS )z8Returns whether the browser supports FedCM capabilities.F)r1   rF   r   ZFEDCM_CAPABILITYr}   r.   r.   r/   supports_fedcm  s    zWebDriver.supports_fedcmc                 C   s   | j stddS )z.Raises an exception if FedCM is not supported.znThis browser does not support Federated Credential Management. Please ensure you're using a supported browser.N)r\  r   r}   r.   r.   r/   _require_fedcm_support  s    z WebDriver._require_fedcm_supportc                 C   s   |    t| S )z0Returns the FedCM dialog object for interaction.)r]  r   r}   r.   r.   r/   dialog  s    zWebDriver.dialog         ?c                    s^   ddl m  ddlm}   |dkr. f} fdd||||d}|fdd	S )
a  Waits for and returns the FedCM dialog.

        Args:
            timeout: How long to wait for the dialog
            poll_frequency: How frequently to poll
            ignored_exceptions: Exceptions to ignore while waiting

        Returns:
            The FedCM dialog object if found

        Raises:
            TimeoutException if dialog doesn't appear
            WebDriverException if FedCM not supported
        r   )NoAlertPresentException)WebDriverWaitNc                     s4   zt } | jr| nd W S   k
r.   Y d S X d S r   )r   r|   )r^  )ra  rx   r.   r/   _check_fedcm  s
    z,WebDriver.fedcm_dialog.<locals>._check_fedcm)poll_frequencyignored_exceptionsc                    s     S r   r.   )r   )rc  r.   r/   <lambda>      z(WebDriver.fedcm_dialog.<locals>.<lambda>)selenium.common.exceptionsra  Zselenium.webdriver.support.waitrb  r]  Zuntil)rx   timeoutrd  re  rb  waitr.   )ra  rc  rx   r/   fedcm_dialog  s    zWebDriver.fedcm_dialog)re   TNNNNN)N)N)N)r   )r   )r   )r   )NNNN)r_  r`  N)r_   r`   ra   rb   r+   rq   r)   r   r   rL   r'   boolr
   r#   r   r	   r%   r|   r   ry   r~   r   typingTypeBaseExceptiontypesTracebackTyper   r   r   propertyr&   r   r   rs   r   r   rt   r   r   r   r   rF   r   r(   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r*   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   setterr   ZIDr   r   r1   r   r   rk   r   r   r  r
  r  r  r  r  r  rf   r  r  r  r&  r   r(  r   r)  r  r   r6  r7  r   r9  r   r;  r>  r@  rA  rB  rD  rH  rY  rZ  r"   r[  r\  r]  r^  rk  r.   r.   r.   r/   rd      s         
;











 



 

	 	

rd   )N)Xrb   rS  r   r4   rM  r   rQ  rp  rm  r   rT  abcr   r   r   r   r   	importlibr   r   r	   r
   r   rh  r   r   r   r   r   Z%selenium.webdriver.common.bidi.scriptr   Zselenium.webdriver.common.byr   Z!selenium.webdriver.common.optionsr   r   Z,selenium.webdriver.common.print_page_optionsr   Z"selenium.webdriver.common.timeoutsr   Z/selenium.webdriver.common.virtual_authenticatorr   r   r   Z+selenium.webdriver.support.relative_locatorr   Zcommon.fedcm.dialogr   r(  r   r>   r   r   r    Zerrorhandlerr!   r[  r"   rf   r#   r$   rg   r%   r   r&   Zremote_connectionr'   r   r(   Z
shadowrootr)   r   r*   Z
webelementr+   Zwebsocket_connectionr,   r-   r  r0   r:   r   rL   rl  rP   r]   r^   rd   r.   r.   r.   r/   <module>   s    
"