a
    .c                     @   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mZ ddl	m
Z
mZ ddlmZmZ ddlmZ ddlmZmZmZmZ ddlmZmZmZmZ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%m&Z&m'Z' ddl(m)Z) ddl*m+Z+ ddl,m-Z- ddl.m/Z/ ddl0m1Z1m2Z2 ddl3m4Z4 ddl5m6Z6 ddl7m8Z8 ddl9m:Z: ddl;m<Z< ddl=m>Z> e?g dZ@ddddZAdaBd d! ZCd"d# ZDd/d%d&ZEee ed'd(d)ZFG d*d+ d+ed,ZGG d-d. d.eGZHdS )0zThe WebDriver implementation.    N)ABCMeta)	b64decodeurlsafe_b64encode)asynccontextmanagercontextmanager)import_module)DictListOptionalUnion)InvalidArgumentExceptionJavascriptExceptionWebDriverExceptionNoSuchCookieExceptionNoSuchElementException)ByApplicationCache)BaseOptions)PrintOptions)Timeouts)
CredentialVirtualAuthenticatorOptionsrequired_virtual_authenticator)
RelativeBy   )BidiConnection)Command)ErrorHandler)FileDetectorLocalFileDetector)Mobile)RemoteConnection)	ScriptKey)
ShadowRoot)SwitchTo)
WebElement)acceptInsecureCertsbrowserNamebrowserVersionZpageLoadStrategyplatformNameproxyZsetWindowRectZstrictFileInteractabilitytimeoutsZunhandledPromptBehaviorZwebSocketUrlr'   r)   r*   )ZacceptSslCertsversionplatformc                   C   s   t stda d S )Nz"selenium.webdriver.common.bidi.cdp)cdpr    r0   r0   ]/var/www/brookimports/venv/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py
import_cdpR   s    r2   c                 C   s   t | } | d}i }| drH| d drH| d d  | d d< |  D ]H\}}|r|tv r|dkrt| n||t| < |tv sd|v rP|||< qP|r|di }d|vrt |}||d< ||d< i g|d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.
    firefox_profiler+   Z	proxyTyper.   :moz:firefoxOptionsprofile)
firstMatchalwaysMatch)copydeepcopygetloweritems_OSS_W3C_CONVERSION_W3C_CAPABILITY_NAMES)capsr6   Zalways_matchkvZmoz_optsZnew_optsr0   r0   r1   _make_w3c_capsX   s"    



rC   Fc           	         sV   ddl m} ddlm} ddlm} t|||g}t fdd|D t}||||dS )Nr   )ChromiumRemoteConnection)SafariRemoteConnection)FirefoxRemoteConnectionc                 3   s"   | ]}|j  d kr|V  qdS )r(   N)Zbrowser_namer;   ).0ccapabilitiesr0   r1   	<genexpr>       z(get_remote_connection.<locals>.<genexpr>)
keep_aliveZignore_proxy)Z-selenium.webdriver.chromium.remote_connectionrD   Z+selenium.webdriver.safari.remote_connectionrE   Z,selenium.webdriver.firefox.remote_connectionrF   r"   next)	rJ   command_executorrM   ignore_local_proxyrD   rE   rF   
candidateshandlerr0   rI   r1   get_remote_connectiony   s    rS   optionsreturnc                 C   s  di i}g }| D ]}| |  qt|}i }t|D ]p}|}|d |k r8||  }|D ]J}	|	||d   v r\|| |	 ||d  |	 kr\||	|| |	 i q\q8i }
| D ]\}}||
|< q|D ]}|
 D ]
}||= qq|
|d d< ||d d< |S )NrJ   r   r8   r7   )appendto_capabilitieslenrangekeysupdater=   )rU   rJ   optsoptZ	opts_sizeZsamesiesi	min_indexZ
first_keysZkysalwaysrA   rB   r0   r0   r1   create_matches   s.    

rb   c                   @   s   e Zd ZdZdS )BaseWebDriverz
    Abstract 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__r0   r0   r0   r1   rc      s   rc   )	metaclassc                   @   s  e Zd ZdZeZeZdee	e
e	 f 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de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 Z*ed6d7d8Z+eedd9d:Z,eedd;d<Z-ddd=d>Z.ddd?d@Z/eeddAdBZ0ee
e ddCdDZ1dddEdFZ2dddGdHZ3dddIdJZ4dee5 edKdLdMZ6ee7ddNdOZ8dddPdQZ9dddRdSZ:dddTdUZ;e
e ddVdWZ<ejej= ddXdYZ>dddZd[Z?ddd\d]Z@ddd^d_ZAddd`daZBdddbdcZCdddddeZDeeEddfdgZFeFjGdddhdgZFeHjIdfeddidjZJeHjIdfe
e ddkdlZKeeddmdnZLeeddodpZMeNddqdrZOeNddsdtZPeQddudvZReddwdxZSdeddzd{d|ZTdeedzd}d~ZUdeedzddZVdedddZWedddZXdedddZYeeZdddZ[e[jGdd Z[edd Z\e\jGdd Z\edd Z]edd Z^dd Z_e`dd Zadd ZbecddddZdeedddZeefddddZgefehddddZiefe
eh dddZjefeeekf ddddZlefddddZmefeNddddZnd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://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol

    :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://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities
     - command_executor - remote_connection.RemoteConnection object used to execute commands.
     - error_handler - errorhandler.ErrorHandler object used to handle errors.
    http://127.0.0.1:4444NT)rU   c           
      C   s(  |rt jdtdd |r(t jdtdd |r<t jdtdd |sPt jdtdd i }t|trht|}n8d}	|r~| }|j}	|rt|tst	dn
|
| || _t| jttfrt||||	d	| _d
| _d| _i | _i | _t | _t| | _t| | _|pt | _d| _|   | || dS )aX  
        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'.
         - desired_capabilities - A dictionary of capabilities to request when
             starting the browser session. Required parameter.
         - browser_profile - A selenium.webdriver.firefox.firefox_profile.FirefoxProfile object.
             Only used if Firefox is requested. Optional.
         - proxy - A selenium.webdriver.common.proxy.Proxy object. The browser session will
             be started with given proxy settings, if possible. Optional.
         - keep_alive - 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
        z]desired_capabilities has been deprecated, please pass in an Options object with options kwarg   
stacklevelz`browser_profile has been deprecated, please pass in an Firefox Options object with options kwargzNproxy has been deprecated, please pass in an Options object with options kwargzckeep_alive has been deprecated. We will be using True as the default value as we start removing it.Fz)Desired Capabilities must be a dictionary)rO   rM   rP   TN)warningswarnDeprecationWarning
isinstancelistrb   rX   _ignore_local_proxydictr   r\   rO   strbytesrS   Z
_is_remote
session_idr@   pinned_scriptsr   error_handlerr%   
_switch_tor!   _mobiler    file_detector_authenticator_idstart_clientstart_session)
selfrO   desired_capabilitiesbrowser_profiler+   rM   r|   rU   rJ   rs   r0   r0   r1   __init__   sh    






zWebDriver.__init__c                 C   s   d t| | jS )Nz-<{0.__module__}.{0.__name__} (session="{1}")>)formattyperw   r   r0   r0   r1   __repr__  s    
zWebDriver.__repr__c                 C   s   | S Nr0   r   r0   r0   r1   	__enter__  s    zWebDriver.__enter__)exc_typeexc	tracebackc                 C   s   |    d S r   )quit)r   r   r   r   r0   r0   r1   __exit__  s    zWebDriver.__exit__c                 o   sL   d}t | j|s&| j}||i || _zdV  W |rH|| _n|rF|| _0 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)rq   r|   )r   Zfile_detector_classargskwargsZlast_detectorr0   r0   r1   file_detector_context  s    zWebDriver.file_detector_context)rV   c                 C   s   | j S r   )r{   r   r0   r0   r1   mobile:  s    zWebDriver.mobilec                 C   s    d| j v r| j d S tddS )zReturns the name of the underlying browser for this instance.

        :Usage:
            ::

                name = driver.name
        r(   z1browserName not specified in session capabilitiesN)r@   KeyErrorr   r0   r0   r1   name>  s    	

zWebDriver.namec                 C   s   dS )z
        Called before starting a new session. This method may be overridden
        to define custom startup behavior.
        Nr0   r   r0   r0   r1   r~   L  s    zWebDriver.start_clientc                 C   s   dS )z
        Called after executing a quit command. This method may be overridden
        to define custom shutdown behavior.
        Nr0   r   r0   r0   r1   stop_clientS  s    zWebDriver.stop_client)rJ   rV   c                 C   s   t |tstd|r>d|v r.|j|d d< n|d|ji t|}d|i}| tj|}d|vrl|d }|d | _	|
d| _| js|
d| _dS )	a#  
        Creates a new session with the desired capabilities.

        :Args:
         - capabilities - a capabilities dict to start the session with.
         - browser_profile - A selenium.webdriver.firefox.firefox_profile.FirefoxProfile object. Only used if Firefox is requested.
        z!Capabilities must be a dictionaryr5   r6   r3   rJ   	sessionIdvalueN)rq   rt   r   encodedr\   rC   executer   ZNEW_SESSIONrw   r;   r@   )r   rJ   r   Zw3c_caps
parametersresponser0   r0   r1   r   Z  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 d S )N#element-6066-11e4-a52e-4f735466cecf"shadow-6066-11e4-a52e-4f735466cecfc                 3   s   | ]}  |V  qd S r   )_wrap_valuerG   itemr   r0   r1   rK     rL   z(WebDriver._wrap_value.<locals>.<genexpr>)rq   rt   r=   r   _web_element_clsid_shadowroot_clsrr   )r   r   Z	convertedkeyvalr0   r   r1   r   v  s    



zWebDriver._wrap_value)
element_idrV   c                 C   s   |  | |S )z6Creates a web element with the specified `element_id`.)r   )r   r   r0   r0   r1   create_web_element  s    zWebDriver.create_web_elementc                    s   t |tr^d|v r  |d S d|v r8  |d S | D ]\}} |||< q@|S n$t |tr~t fdd|D S |S d S )Nr   r   c                 3   s   | ]}  |V  qd S r   )_unwrap_valuer   r   r0   r1   rK     rL   z*WebDriver._unwrap_value.<locals>.<genexpr>)rq   rt   r   r   r=   r   rr   )r   r   r   r   r0   r   r1   r     s    

zWebDriver._unwrap_value)driver_commandparamsrV   c                 C   sx   | j r(|sd| j i}nd|vr(| j |d< | |}| j||}|rj| j| | |dd|d< |S dd| j dS )aQ  
        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   )rw   r   rO   r   ry   Zcheck_responser   r;   )r   r   r   r   r0   r0   r1   r     s    


zWebDriver.execute)urlrV   c                 C   s   |  tjd|i dS )zB
        Loads a web page in the current browser session.
        r   N)r   r   GET)r   r   r0   r0   r1   r;     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_TITLEr;   r   r0   r0   r1   title  s    	zWebDriver.title)scriptrV   c                 C   s   t |}|| j|j< |S )zMStore common javascript scripts to be executed later by a unique hashable ID.)r#   rx   r   )r   r   
script_keyZscript_key_instancer0   r0   r1   
pin_script  s    zWebDriver.pin_script)r   rV   c                 C   sB   z| j |j W n* ty<   td| d| j  dY n0 dS )z$Remove a pinned script from storage.zNo script with key: z existed in N)rx   popr   r   )r   r   r0   r0   r1   unpin  s    zWebDriver.unpinc                 C   s
   t | jS r   )rr   rx   r   r0   r0   r1   get_pinned_scripts  s    zWebDriver.get_pinned_scriptsc                 G   sZ   t |tr6z| j|j }W n ty4   tdY n0 t|}tj}| 	|||dd S )a0  
        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   )
rq   r#   rx   r   r   r   rr   r   ZW3C_EXECUTE_SCRIPTr   r   r   r   Zconverted_argscommandr0   r0   r1   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   )rr   r   ZW3C_EXECUTE_SCRIPT_ASYNCr   r   r0   r0   r1   execute_async_script  s    zWebDriver.execute_async_scriptc                 C   s   |  tjd S )zw
        Gets the URL of the current page.

        :Usage:
            ::

                driver.current_url
        r   )r   r   ZGET_CURRENT_URLr   r0   r0   r1   current_url  s    
zWebDriver.current_urlc                 C   s   |  tjd S )zz
        Gets the source of the current page.

        :Usage:
            ::

                driver.page_source
        r   )r   r   ZGET_PAGE_SOURCEr   r0   r0   r1   page_source  s    
zWebDriver.page_sourcec                 C   s   |  tj dS )zl
        Closes the current window.

        :Usage:
            ::

                driver.close()
        N)r   r   ZCLOSEr   r0   r0   r1   close  s    	zWebDriver.closec                 C   s<   z"|  tj W |   | j  n|   | j  0 dS )z
        Quits the driver and closes every associated window.

        :Usage:
            ::

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

        :Usage:
            ::

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

        :Usage:
            ::

                driver.window_handles
        r   )r   r   ZW3C_GET_WINDOW_HANDLESr   r0   r0   r1   window_handlesC  s    
zWebDriver.window_handlesc                 C   s   t j}| |d dS )zF
        Maximizes the current window that webdriver is using
        N)r   ZW3C_MAXIMIZE_WINDOWr   )r   r   r0   r0   r1   maximize_windowO  s    zWebDriver.maximize_windowc                 C   s   |  tj dS )zM
        Invokes the window manager-specific 'full screen' operation
        N)r   r   ZFULLSCREEN_WINDOWr   r0   r0   r1   fullscreen_windowV  s    zWebDriver.fullscreen_windowc                 C   s   |  tj dS )zJ
        Invokes the window manager-specific 'minimize' operation
        N)r   r   ZMINIMIZE_WINDOWr   r0   r0   r1   minimize_window\  s    zWebDriver.minimize_window)print_optionsrV   c                 C   s"   i }|r|  }| tj|d S )z
        Takes 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)r   r   rU   r0   r0   r1   
print_pageb  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')
        )rz   r   r0   r0   r1   	switch_tom  s    zWebDriver.switch_toc                 C   s   |  tj dS )z
        Goes one step backward in the browser history.

        :Usage:
            ::

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

        :Usage:
            ::

                driver.forward()
        N)r   r   Z
GO_FORWARDr   r0   r0   r1   forward  s    	zWebDriver.forwardc                 C   s   |  tj dS )zo
        Refreshes the current page.

        :Usage:
            ::

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

        :Usage:
            ::

                driver.get_cookies()
        r   )r   r   ZGET_ALL_COOKIESr   r0   r0   r1   get_cookies  s    	zWebDriver.get_cookiesc                 C   sD   t t& | tjd|id W  d   S 1 s60    Y  dS )z
        Get 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r   r   r0   r0   r1   
get_cookie  s    	zWebDriver.get_cookiec                 C   s   |  tjd|i dS )z
        Deletes a single cookie with the given name.

        :Usage:
            ::

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

        :Usage:
            ::

                driver.delete_all_cookies()
        N)r   r   ZDELETE_ALL_COOKIESr   r0   r0   r1   delete_all_cookies  s    	zWebDriver.delete_all_cookiesc                 C   sB   d|v r,|d dv sJ |  tjd|i n|  tjd|i dS )aK  
        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)r   r   Z
ADD_COOKIE)r   cookie_dictr0   r0   r1   
add_cookie  s    zWebDriver.add_cookiec                 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r   Ztime_to_waitr0   r0   r1   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   r0   r0   r1   set_script_timeout  s    zWebDriver.set_script_timeoutc              	   C   sV   z"|  tjdtt|d i W n. tyP   |  tjt|d dd Y n0 dS )a  
        Set 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   r0   r0   r1   set_page_load_timeout	  s    

zWebDriver.set_page_load_timeoutc                 C   sT   |  tjd }|dd |d< |dd |d< |dd |d< tf i |S )z
        Get 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   r   r,   r0   r0   r1   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_jsonr   r0   r0   r1   r,   .  s    c                 C   s   t |tr4| j||d}|s,td|j |d S |tjkrNtj}d| }n2|tjkrhtj}d| }n|tj	krtj}d| }| 
tj||dd S )	z
        Find 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   	[id="%s"].%s[name="%s"]usingr   r   )rq   r   find_elementsr   rootr   IDCSS_SELECTOR
CLASS_NAMENAMEr   r   ZFIND_ELEMENT)r   r   r   elementsr0   r0   r1   find_element<  s(    





zWebDriver.find_elementc                 C   s   t |trPdtddd }t|dd}d| d}| ||	 S |t
jkrjt
j}d| }n2|t
jkrt
j}d	| }n|t
jkrt
j}d
| }| tj||dd pg S )z
        Find elements given a By strategy and locator.

        :Usage:
            ::

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

        :rtype: list of WebElement
        .NzfindElements.jsutf8zreturn (z).apply(null, arguments);r   r   r   r   r   )rq   r   joinrd   splitpkgutilget_datadecoder   r   r   r   r   r   r   r   r   ZFIND_ELEMENTS)r   r   r   Z_pkgZraw_functionZfind_element_jsr0   r0   r1   r   [  s,    





zWebDriver.find_elementsc                 C   s   t jdtdd | jS )zM
        returns the drivers current desired capabilities being used
        z=desired_capabilities is deprecated. Please call capabilities.rk   rl   )rn   ro   rp   r@   r   r0   r0   r1   r   |  s    zWebDriver.desired_capabilitiesc                 C   s   | j S )zF
        returns the drivers current capabilities being used.
        )r@   r   r0   r0   r1   rJ     s    zWebDriver.capabilitiesc                 C   s   |  dstdt |  }zXz8t|d}|| W d   n1 sP0    Y  W n tyt   Y W ~dS 0 W ~n~0 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` extensionwbNFT)	r<   endswithrn   ro   UserWarningget_screenshot_as_pngopenwriteOSError)r   filenameZpngfr0   r0   r1   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  )r   r   r0   r0   r1   save_screenshot  s    zWebDriver.save_screenshotc                 C   s   t |  dS )z
        Gets the screenshot of the current window as a binary data.

        :Usage:
            ::

                driver.get_screenshot_as_png()
        ascii)r   get_screenshot_as_base64encoder   r0   r0   r1   r     s    	zWebDriver.get_screenshot_as_pngc                 C   s   |  tjd S )z
        Gets 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   r0   r0   r1   r    s    
z"WebDriver.get_screenshot_as_base64current)windowHandlerV   c                 C   s,   |dkrt d | 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)
        r  ?Only 'current' window is supported for W3C compatible browsers.widthheightNrn   ro   set_window_rectr   )r   r
  r  r  r0   r0   r1   set_window_size  s    
zWebDriver.set_window_sizec                    s@   |dkrt d |    ddr. d   fdddD S )z
        Gets the width and height of the current window.

        :Usage:
            ::

                driver.get_window_size()
        r  r  r   Nc                    s   i | ]}| | qS r0   r0   rG   rA   sizer0   r1   
<dictcomp>  rL   z-WebDriver.get_window_size.<locals>.<dictcomp>r	  )rn   ro   get_window_rectr;   r   r  r0   r  r1   get_window_size  s    

zWebDriver.get_window_sizec                 C   s(   |dkrt d | jt|t|dS )a7  
        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  xyr  )r   r  r  r  r0   r0   r1   set_window_position  s    
zWebDriver.set_window_positionc                    s,   |dkrt d |    fdddD S )z
        Gets the x,y position of the current window.

        :Usage:
            ::

                driver.get_window_position()
        r  r  c                    s   i | ]}| | qS r0   r0   r  positionr0   r1   r    rL   z1WebDriver.get_window_position.<locals>.<dictcomp>r  )rn   ro   r  r  r0   r  r1   get_window_position  s    

zWebDriver.get_window_positionc                 C   s   |  tjd S )z
        Gets 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   r0   r0   r1   r    s    
zWebDriver.get_window_rectc                 C   s<   |du r |du 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)r   r  r  r
  r  r0   r0   r1   r  !  s    zWebDriver.set_window_rectc                 C   s   | j S r   )_file_detectorr   r0   r0   r1   r|   7  s    zWebDriver.file_detectorc                 C   s(   |st dt|tst d|| _dS )a9  
        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   rq   r   r  )r   detectorr0   r0   r1   r|   ;  s
    
c                 C   s   |  tjd S )z
        Gets the current orientation of the device

        :Usage:
            ::

                orientation = driver.orientation
        r   )r   r   ZGET_SCREEN_ORIENTATIONr   r0   r0   r1   orientationN  s    
zWebDriver.orientationc                 C   s4   ddg}|  |v r(| tjd|i ntddS )z
        Sets 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   )r   r   Zallowed_valuesr0   r0   r1   r  Z  s    c                 C   s   t | S )zI Returns a ApplicationCache Object to interact with the browser app cacher   r   r0   r0   r1   application_cachem  s    zWebDriver.application_cachec                 C   s   |  tjd S )z
        Gets 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   r0   r0   r1   	log_typesr  s    
zWebDriver.log_typesc                 C   s   |  tjd|id S )aF  
        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)r   Zlog_typer0   r0   r1   get_log~  s    zWebDriver.get_logc              
   C  s  t   | jdr6| jd}| jddd }n|  \}}|sNtdt|}t|4 I d H }|	|j
 I d H }|d j}||4 I d H $}t|t|V  W d   I d H  q1 I d H s0    Y  W d   I d H  q1 I d H s0    Y  d S )Nzse:cdpzse:cdpVersionr   r   z2Unable to find url to connect to from capabilities)r2   r@   r;   r   _get_cdp_detailsr   r/   Zimport_devtoolsZopen_cdpr   targetZget_targets	target_idZopen_sessionr   )r   Zws_urlr-   Zdevtoolsconntargetsr&  sessionr0   r0   r1   bidi_connection  s    

zWebDriver.bidi_connectionc                 C   s   dd l }dd l}| }d}| jddkrV| j| j d| jd dd}nd}| jd	}|d
d| d}||j}|d}|d}	dd l	}
|rd}n|

d|d}||	fS )Nr   Fr(   chromer4   OptionsZdebuggerAddressTzmoz:debuggerAddressr   zhttp://z/json/versionZBrowserZwebSocketDebuggerUrlU   z
.*/(\d+)\.r   )jsonurllib3PoolManagerr@   r;   Zvendor_prefixrequestloadsdataresearchgroup)r   r.  r/  httpZ_firefoxZdebugger_addressresr3  Zbrowser_versionZwebsocket_urlr4  r-   r0   r0   r1   r$    s"    *

zWebDriver._get_cdp_detailsrT   c                 C   s   |  tj| d | _dS )zF
        Adds a virtual authenticator with the given options.
        r   N)r   r   ZADD_VIRTUAL_AUTHENTICATORr   r}   )r   rU   r0   r0   r1   add_virtual_authenticator  s    z#WebDriver.add_virtual_authenticatorc                 C   s   | j S )z>
        Returns the id of the virtual authenticator.
        )r}   r   r0   r0   r1   virtual_authenticator_id  s    z"WebDriver.virtual_authenticator_idc                 C   s   |  tjd| ji d| _dS )z
        Removes 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_AUTHENTICATORr}   r   r0   r0   r1   remove_virtual_authenticator  s    z&WebDriver.remove_virtual_authenticator)
credentialrV   c                 C   s$   |  tji | d| ji dS )z>
        Injects a credential into the authenticator.
        r;  N)r   r   ZADD_CREDENTIALr   r}   )r   r=  r0   r0   r1   add_credential  s    zWebDriver.add_credentialc                 C   s&   |  tjd| ji}dd |d D S )zM
        Returns the list of credentials owned by the authenticator.
        r;  c                 S   s   g | ]}t |qS r0   )r   	from_dict)rG   r=  r0   r0   r1   
<listcomp>  rL   z-WebDriver.get_credentials.<locals>.<listcomp>r   )r   r   ZGET_CREDENTIALSr}   )r   Zcredential_datar0   r0   r1   get_credentials  s    zWebDriver.get_credentials)credential_idrV   c                 C   s2   t |tu rt| }| tj|| jd dS )z>
        Removes a credential from the authenticator.
        )ZcredentialIdr;  N)r   	bytearrayr   r   r   r   ZREMOVE_CREDENTIALr}   )r   rB  r0   r0   r1   remove_credential  s    
zWebDriver.remove_credentialc                 C   s   |  tjd| ji dS )zA
        Removes all credentials from the authenticator.
        r;  N)r   r   ZREMOVE_ALL_CREDENTIALSr}   r   r0   r0   r1   remove_all_credentials  s    z WebDriver.remove_all_credentials)verifiedrV   c                 C   s   |  tj| j|d dS )z
        Sets whether the authenticator will simulate success or fail on user verification.
        verified: True if the authenticator will pass user verification, False otherwise.
        )r;  ZisUserVerifiedN)r   r   ZSET_USER_VERIFIEDr}   )r   rF  r0   r0   r1   set_user_verified  s    
zWebDriver.set_user_verified)rj   NNNTNN)N)N)N)N)r  )r  )r  )r  )NNNN)ord   re   rf   rg   r&   r   r$   r   r   r   r	   r   r   r   typingr
   TypeBaseExceptiontypesTracebackTyper   r   r   propertyr!   r   ru   r   r~   r   rt   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   r   r   r   r   r,   setterr   r   r   r   r   rJ   boolr  r  rv   r   r  r  r  r  r  r  r  r   r|   r  r!  r"  r#  r   r*  r$  r   r9  r:  r   r<  r   r>  rA  rC  rD  rE  rG  r0   r0   r0   r1   ri      s      M


!





	ri   )F)Irg   r   r9   r   rK  rH  rn   abcr   base64r   r   r   r   	importlibr   r   r	   r
   r   Zselenium.common.exceptionsr   r   r   r   r   Zselenium.webdriver.common.byr   Z1selenium.webdriver.common.html5.application_cacher   Z!selenium.webdriver.common.optionsr   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   r*  r   r   r   Zerrorhandlerr   r|   r   r    r   r!   Zremote_connectionr"   r   r#   Z
shadowrootr$   r   r%   Z
webelementr&   	frozensetr?   r>   r/   r2   rC   rS   rb   rc   ri   r0   r0   r0   r1   <module>   sR   !
"