a
    5ñ»jå%  ã                   @   s  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 e  e!¡Z"G dd„ deƒZ#dS )é    N)ÚABC)Úabstractmethod)ÚIOBase)Úsystem)ÚPIPE)Úsleep)ÚIO)ÚAny)ÚList)ÚMapping)ÚOptional)ÚUnion)Úcast)Úrequest)ÚURLError)ÚWebDriverException)ÚSubprocessStdAlias)Úutilsc                   @   s
  e Zd ZdZd#eeeeee	e	f  eddœdd„Z
eedœdd	„ƒZeee dœd
d„ƒZeedœdd„ƒZejeddœdd„ƒZddœdd„Zddœdd„Zedœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd„Zeddœdd „Zee dœd!d"„ZdS )$ÚServicea™  The abstract base class for all service objects.  Services typically
    launch a child program in a new process as an interim process to
    communicate with a browser.

    :param executable: install path of the executable.
    :param port: Port for the service to run on, defaults to 0 where the operating system will decide.
    :param log_output: (Optional) int representation of STDOUT/DEVNULL, any IO instance or String path to file.
    :param env: (Optional) Mapping of environment variables for the new process, defaults to `os.environ`.
    :param driver_path_env_key: (Optional) Environment variable to use to get the path to the driver executable.
    Nr   )Úexecutable_pathÚportÚ
log_outputÚenvÚdriver_path_env_keyÚreturnc                 K   sÊ   t |tƒr"ttt|ddd�ƒ| _nX|tjkrFttt	t
tf  d ƒ| _n4|d u sX|tjkrtttt	t
tf  tjƒ| _n|| _|p„t ¡ | _| di ¡| _| j dd¡| _|p®tj| _|| _|  ¡ pÂ|| _d S )Nza+zutf-8)ÚencodingÚpopen_kwÚcreation_flagsr   )Ú
isinstanceÚstrr   r   Úopenr   Ú
subprocessÚSTDOUTr   r   ÚintÚDEVNULLr   Z	free_portr   Úpopr   r   ÚosÚenvironr   ÚDRIVER_PATH_ENV_KEYÚenv_pathÚ_path)Úselfr   r   r   r   r   Úkwargs© r-   úGE:\soccer\ml_env\Lib\site-packages\selenium/webdriver/common/service.pyÚ__init__8   s    	

zService.__init__)r   c                 C   s   dt  d| j¡› �S )zGets the url of the Service.zhttp://Ú	localhost)r   Zjoin_host_portr   ©r+   r-   r-   r.   Úservice_urlR   s    zService.service_urlc                 C   s   t dƒ‚dS )z7A List of program arguments (excluding the executable).z2This method needs to be implemented in a sub classN)ÚNotImplementedErrorr1   r-   r-   r.   Úcommand_line_argsW   s    zService.command_line_argsc                 C   s
   | j pdS )NÚ )r*   r1   r-   r-   r.   Úpath\   s    zService.path)Úvaluer   c                 C   s   t |ƒ| _d S ©N)r   r*   )r+   r7   r-   r-   r.   r6   `   s    c                 C   sp   | j du rtdƒ‚|  | j ¡ d}|  ¡  |  ¡ r4qlttdd|  dƒƒ |d7 }|dkr"td	| j › �ƒ‚q"dS )
z³Starts the Service.

        :Exceptions:
         - WebDriverException : Raised either when it can't start the service
           or when it can't connect to the service
        NúService path cannot be None.r   g{®Gáz„?gš™™™™™©?g      à?é   éF   zCan not connect to the Service )r*   r   Ú_start_processÚassert_process_still_runningÚis_connectabler   Úmin)r+   Úcountr-   r-   r.   Ústartd   s    
zService.startc                 C   s(   | j  ¡ }|r$td| j› d|› �ƒ‚dS )z1Check if the underlying process is still running.zService z' unexpectedly exited. Status code was: N)ÚprocessÚpollr   r*   )r+   Zreturn_coder-   r-   r.   r=   z   s    
z$Service.assert_process_still_runningc                 C   s   t  | j¡S )zfEstablishes a socket connection to determine if the service running
        on the port is accessible.)r   r>   r   r1   r-   r-   r.   r>   €   s    zService.is_connectablec                 C   sR   zt  | j› d�¡ W n ty*   Y dS 0 tdƒD ]}|  ¡ sD qNtdƒ q4dS )zcDispatch an HTTP request to the shutdown endpoint for the service in
        an attempt to stop it.z	/shutdownNé   r:   )r   Úurlopenr2   r   Úranger>   r   )r+   Ú_r-   r-   r.   Úsend_remote_shutdown_command…   s    z$Service.send_remote_shutdown_commandc                 C   s”   | j ttjhvr@t| j tƒr(| j  ¡  nt| j tƒr@t | j ¡ | j	dur�| j	 
¡ du r�z,z|  ¡  W n tyx   Y n0 W |  ¡  n
|  ¡  0 dS )zStops the service.N)r   r   r!   r$   r   r   Úcloser#   r&   rB   rC   rH   Ú	TypeErrorÚ_terminate_processr1   r-   r-   r.   Ústop’   s    zService.stopc              	   C   s¾   z˜| j j| j j| j j  }}}|||fD ]$}z| ¡  W q( tyJ   Y q(0 q(| j  ¡  z| j  d¡ W n, tj	y”   t
jddd� | j  ¡  Y n0 W n  ty¸   t
jddd� Y n0 dS )a#  Terminate the child process.

        On POSIX this attempts a graceful SIGTERM followed by a SIGKILL,
        on a Windows OS kill is an alias to terminate.  Terminating does
        not raise itself if something has gone wrong but (currently)
        silently ignores errors here.
        é<   zTService process refused to terminate gracefully with SIGTERM, escalating to SIGKILL.T)Úexc_infoz"Error terminating service process.N)rB   ÚstdinÚstdoutÚstderrrI   ÚAttributeErrorÚ	terminateÚwaitr!   ÚTimeoutExpiredÚloggerÚerrorÚkillÚOSError)r+   rO   rP   rQ   Ústreamr-   r-   r.   rK   £   s*    ý

þzService._terminate_processc                 C   s$   z|   ¡  W n ty   Y n0 d S r8   )rL   Ú	Exceptionr1   r-   r-   r.   Ú__del__Â   s    zService.__del__)r6   r   c                 C   sL  |g}|  |  ¡ ¡ | j dtƒ dk¡}z¦d}tƒ dkrVt ¡ }tjtjB |_	tj
|_tj|f| j|tttttt f  | jƒtttttt f  | jƒt| j|dœ| j¤Ž| _t d| j| jj| j| j¡ W nx tyâ   ‚ Y nf t�yF } zL|jtjk�r0| jdu �rt dƒ‚t dt!j" #| j¡› d�ƒ|‚‚ W Y d}~n
d}~0 0 dS )	zmCreates a subprocess by executing the command provided.

        :param cmd: full command to execute
        Ú	close_fdsÚWindowsN)r   r]   rP   rQ   rO   ÚcreationflagsÚstartupinfozNStarted executable: `%s` in a child process with pid: %s using %s to output %sr9   ú'z(' executable may have wrong permissions.)$Úextendr4   r   r%   r   r!   ÚSTARTUPINFOÚCREATE_NEW_CONSOLEÚSTARTF_USESHOWWINDOWÚdwFlagsÚSW_HIDEÚwShowWindowÚPopenr   r   r   r   r#   r   r	   r   r   r   rB   rV   Údebugr*   ÚpidrJ   rY   ÚerrnoÚEACCESr   r&   r6   Úbasename)r+   r6   ÚcmdZclose_file_descriptorsZ
start_infoÚerrr-   r-   r.   r<   Í   sR    
ÿø	÷ûÿþzService._start_processc                 C   s   | j rt | j d ¡S d S r8   )r(   r&   Úgetenvr1   r-   r-   r.   r)   ù   s    zService.env_path)Nr   NNN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r#   r   r   r   r	   r/   Úpropertyr2   r   r
   r4   r6   ÚsetterrA   r=   Úboolr>   rH   rL   rK   r\   r<   r)   r-   r-   r-   r.   r   ,   s>        úø,r   )$rl   Úloggingr&   r!   Úabcr   r   Úior   Úplatformr   r   Útimer   Útypingr   r	   r
   r   r   r   r   Úurllibr   Úurllib.errorr   Zselenium.common.exceptionsr   Zselenium.typesr   Zselenium.webdriver.commonr   Ú	getLoggerrr   rV   r   r-   r-   r-   r.   Ú<module>   s.   
