§
    ¨Mºf�`  ã                   ó"  — 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mZmZ d d	lmZmZmZmZmZmZ d d
lm Z  d dl!m"Z"m#Z#m$Z$ d dl%m&Z&  ej'        e(¦  «        Z) G d„ de ¦  «        Z*dS )é    N)Ú	webdriver)Úexpected_conditions)ÚBy)ÚWebDriverWait)ÚKeys)ÚActionChains)ÚWebDriverExceptionÚTimeoutExceptionÚMoveTargetOutOfBoundsException)Útext_to_equalÚstyle_to_equalÚclass_to_equalÚcontains_textÚcontains_classÚuntil)ÚDashPageMixin)ÚDashAppLoadingErrorÚBrowserErrorÚTestingTimeoutError)ÚSELENIUM_GRID_DEFAULTc                   óè  — e Zd Z	 	 	 	 	 	 	 	 	 	 d4d„Zd„ Zd„ Z	 	 	 	 	 d5d	„Z	 d6d
„Zd„ Zd7d„Z	d7d„Z
d„ Zd„ Zd8d„Zd8d„Zd8d„Zd8d„Zd8d„Zd8d„Zd8d„Zd8d„Zd8d„Zd9d„Zd:d„Zd„ Zd;d„Zd8d„Zd „ Zd!„ Zd"„ Zd#„ Zed$„ ¦   «         Z d8d%„Z!d&„ Z"	 d<d)„Z#d*„ Z$d+„ Z%d,„ Z&e'd-„ ¦   «         Z(e'd.„ ¦   «         Z)e'd/„ ¦   «         Z*e*j+        d0„ ¦   «         Z*e'd1„ ¦   «         Z,e'd2„ ¦   «         Z-e-j+        d3„ ¦   «         Z-dS )=ÚBrowserFNÚ Té
   c                 óh  — |                      ¦   «         | _        || _        |r|t          k    rdn|| _        || _        || _        || _        |
| _        || _	        || _
        || _        t          | j        d¬¦  «        | _        | j                             d¦  «         t!          | j        |
¦  «        | _        d| _        d | _        d| _        | j
        rMt-          j        t-          j        | j        d|	¬¦  «        ¬¦  «        | _        | j                             ¦   «          t6                               d	¦  «         t6                               d
| j        ¦  «         t6                               d| j        ¦  «         t6                               dt:          j                             |	¦  «        ¦  «         d S )NTé   ©Útimeouté   r   z/assets)r   Úbase_urlÚroot_dir)Úloaderz!initialize browser with argumentsz  headless => %sz  download_path => %sz  percy asset root => %s) ÚlowerÚ_browserÚ_remote_urlr   Ú_remoteÚ	_headlessÚ_optionsÚ_download_pathÚ_wait_timeoutÚ_percy_finalizeÚ
_percy_runÚ_pauser   Úget_webdriverÚ_driverÚimplicitly_waitr   ÚdriverÚ_wd_waitÚ_last_tsÚ_urlÚ_window_idxÚpercyÚRunnerÚResourceLoaderÚpercy_runnerÚinitialize_buildÚloggerÚdebugÚosÚpathÚabspath)ÚselfÚbrowserÚremoteÚ
remote_urlÚheadlessÚoptionsÚdownload_pathÚ	percy_runÚpercy_finalizeÚpercy_assets_rootÚwait_timeoutÚpauses               úS/var/www/surfInsights/venv3-11/lib/python3.11/site-packages/dash/testing/browser.pyÚ__init__zBrowser.__init__)   s‹  € ð  Ÿš™œˆŒØ%ˆÔàÐR :Õ1FÒ#FÐ#FˆDˆDÈFð 	Œð "ˆŒØˆŒØ+ˆÔØ)ˆÔØ-ˆÔØ#ˆŒØˆŒå˜TÔ/¸Ð;Ñ;Ô;ˆŒØŒ×$Ò$ QÑ'Ô'Ð'å% d¤k°<Ñ@Ô@ˆŒØˆŒØˆŒ	àˆÔàŒ?ð 	1Ý %¤ÝÔ+Ø"œkØ&Ø.ðñ ô ð!ñ !ô !ˆDÔð Ô×.Ò.Ñ0Ô0Ð0å�ŠÐ8Ñ9Ô9Ð9Ý�ŠÐ'¨¬Ñ8Ô8Ð8Ý�ŠÐ,¨dÔ.AÑBÔBÐBÝ�ŠÐ/µ´·²ÐARÑ1SÔ1SÑTÔTÐTÐTÐTó    c                 ó   — | S ©N© ©r@   s    rL   Ú	__enter__zBrowser.__enter__\   s   € ØˆrN   c                 óª  — 	 | j                              ¦   «          | j        r<| j        r5t                               d¦  «         | j                             ¦   «          d S t                               d¦  «         d S # t          $ r t           	                    d¦  «         Y d S t          j        j        $ r t           	                    d¦  «         Y d S w xY w)Nzpercy runner finalize build nowzpercy finalize relies on CI jobz!webdriver quit was not successfulz(percy runner failed to finalize properly)r1   Úquitr,   r+   r;   Úinfor9   Úfinalize_buildr	   Ú	exceptionr6   ÚerrorsÚError)r@   Úexc_typeÚexc_valÚ	tracebacks       rL   Ú__exit__zBrowser.__exit___   sì   € ð
	IØŒK×ÒÑÔÐØŒð ? 4Ô#7ð ?Ý—’Ð=Ñ>Ô>Ð>ØÔ!×0Ò0Ñ2Ô2Ð2Ð2Ð2å—’Ð=Ñ>Ô>Ð>Ð>Ð>øÝ!ð 	Bð 	Bð 	BÝ×ÒÐ@ÑAÔAÐAÐAÐAÐAÝŒ|Ô!ð 	Ið 	Ið 	IÝ×ÒÐGÑHÔHÐHÐHÐHÐHð	Iøøøs   ‚AA: ÁA: Á:$CÂ!-CÃCc                 ó  — 	 |                      d¦  «        }||k    rt                               d¦  «         | j                             | j                             d¦  «        › d|› �¦  «         |                      |¦  «         |                      ||||¬¦  «         |r|  	                    d¦  «        r
J d¦   «         ‚|s| j         
                    ¦   «          d S d S # t          $ r"}	t                               d|¦  «         |	‚d }	~	ww xY w)Nú/z)we stripped the left '/' in resource_path)Úwait_for_callbacksÚconvert_canvasesÚwidthszdiv.dash-debug-alertz(devtools should not raise an error alertzsnapshot at resource %s error)Úlstripr;   Úwarningr1   ÚgetÚ
server_urlÚrstripÚwait_for_element_by_idÚpercy_snapshotÚfind_elementsÚbackr	   rX   )
r@   Úresource_pathÚhook_idra   rb   Úassert_checkÚstay_on_pagerc   r>   Úes
             rL   Úvisit_and_snapshotzBrowser.visit_and_snapshotl   sN  € ð	Ø ×'Ò'¨Ñ,Ô,ˆDØ�}Ò$Ð$Ý—’ÐJÑKÔKÐKØŒK�OŠO˜tœ×5Ò5°cÑ:Ô:ÐCÐC¸TÐCÐCÑDÔDÐDð ×'Ò'¨Ñ0Ô0Ð0Ø×ÒØØ#5Ø!1Øð	  ñ ô ð ð ð >Ø×-Ò-Ø*ñô ð >ð >à=ñ>ô >ð >ð  ð #Ø”× Ò Ñ"Ô"Ð"Ð"Ð"ð#ð #øå!ð 	ð 	ð 	Ý×ÒÐ<¸dÑCÔCÐCØˆGøøøøð	øøøs   ‚CC Ã
DÃ&DÄDc                 ó`  — |€dg}|› dt           j        j        › dt           j        j        › �}t                               d|¦  «         	 |r+t          j        d¦  «         t          | j	        dd¬	¦  «         n0# t          $ r# t                               d
| j        ¦  «         Y nw xY w|r| j                             d¦  «         	 | j                             ||¬¦  «         n.# t"          j        $ r}|j        j        dk    r|‚Y d}~nd}~ww xY w|r| j                             d¦  «         dS dS )a„  percy_snapshot - visual test api shortcut to `percy_runner.snapshot`.
        It also combines the snapshot `name` with the Python version,
        args:
        - name: combined with the python version to give the final snapshot name
        - wait_for_callbacks: default False, whether to wait for Dash callbacks,
            after an extra second to ensure that any relevant callbacks have
            been initiated
        - convert_canvases: default False, whether to convert all canvas elements
            in the DOM into static images for percy to see. They will be restored
            after the snapshot is complete.
        - widths: a list of pixel widths for percy to render the page with. Note
            that this does not change the browser in which the DOM is constructed,
            so the width will only affect CSS, not JS-driven layout.
            Defaults to [1280]
        Ni   z - pyú.ztaking snapshot name => %sr   é(   g333333Ó?)r   Úpollz5wait_for_callbacks failed => status of invalid rqs %sa¨  
                const stash = window._canvasStash = [];
                Array.from(document.querySelectorAll('canvas')).forEach(c => {
                    const i = document.createElement('img');
                    i.src = c.toDataURL();
                    i.width = c.width;
                    i.height = c.height;
                    i.setAttribute('style', c.getAttribute('style'));
                    i.className = c.className;
                    i.setAttribute('data-canvasnum', stash.length);
                    stash.push(c);
                    c.parentElement.insertBefore(i, c);
                    c.parentElement.removeChild(c);
                });
            )Únamerc   i�  a¶  
                const stash = window._canvasStash;
                Array.from(
                    document.querySelectorAll('img[data-canvasnum]')
                ).forEach(i => {
                    const c = stash[+i.getAttribute('data-canvasnum')];
                    i.parentElement.insertBefore(c, i);
                    i.parentElement.removeChild(i);
                });
                delete window._canvasStash;
            )ÚsysÚversion_infoÚmajorÚminorr;   rV   ÚtimeÚsleepr   Ú_wait_for_callbacksr   ÚerrorÚredux_state_rqsr1   Úexecute_scriptr9   ÚsnapshotÚrequestsÚ	HTTPErrorÚrequestÚstatus_code)r@   rw   ra   rb   rc   Úsnapshot_nameÚerrs          rL   rj   zBrowser.percy_snapshotŽ   sš  € ð$ ˆ>Ø�VˆFØÐWÐW¥cÔ&6Ô&<ÐWÐW½sÔ?OÔ?UÐWÐWˆÝ�ŠÐ0°-Ñ@Ô@Ð@ð	Ø!ð Fõ ”
˜1‘”�Ý�dÔ.¸ÀÐEÑEÔEÐEøøÝ"ð 	ð 	ð 	õ �LŠLØGØÔ$ñô ð ð ð ð		øøøð ð 	ØŒK×&Ò&ðñô ð ð$	ØÔ×&Ò&¨MÀ&Ð&ÑIÔIÐIÐIøÝÔ!ð 	ð 	ð 	àŒ{Ô&¨#Ò-Ð-Ø�	ð .Ð-Ð-Ð-Ð-øøøøð	øøøð
 ð 	ØŒK×&Ò&ð
ñô ð ð ð ð	ð 	s*   Á
-A8 Á8*B%Â$B%ÃC" Ã"DÃ1DÄDc                 óh  — |                       ¦   «         sdnt          j        d¦  «        }t          j                             |¦  «        s@	 t          j        |¦  «         n*# t          $ r t                               d¦  «         Y nw xY w| j	         
                    |› d|› d| j        › d�¦  «         dS )a  Hook method to take snapshot when a selenium test fails. The
        snapshot is placed under.

            - `/tmp/dash_artifacts` in linux
            - `%TEMP` in windows
        with a filename combining test case name and the
        running selenium session id
        z/tmp/dash_artifactsÚTEMPzcannot make artifactsr`   Ú_z.pngN)Ú_is_windowsr=   Úgetenvr>   ÚexistsÚmkdirÚOSErrorr;   rX   r1   Úsave_screenshotÚ
session_id)r@   rw   Útargets      rL   Útake_snapshotzBrowser.take_snapshotÜ   sÈ   € ð /3×.>Ò.>Ñ.@Ô.@ÐWÐ&Ð&ÅbÄiÐPVÑFWÔFWˆÝŒw�~Š~˜fÑ%Ô%ð 	:ð:Ý”˜Ñ Ô Ð Ð øÝð :ð :ð :Ý× Ò Ð!8Ñ9Ô9Ð9Ð9Ð9ð:øøøð 	Œ×#Ò# vÐ$LÐ$L°Ð$LÐ$L°t´Ð$LÐ$LÐ$LÑMÔMÐMÐMÐMs   ÁA  Á $BÂBÚCSS_SELECTORc                 ó‚   — | j                              t          t          |                     ¦   «         ¦  «        |¦  «        S )a­  find_element returns the first found element by the attribute `selector`
        shortcut to `driver.find_element(By.CSS_SELECTOR, ...)`.
        args:
        - attribute: the attribute type to search for, aligns with the Selenium
            API's `By` class. default "CSS_SELECTOR"
            valid values: "CSS_SELECTOR", "ID", "NAME", "TAG_NAME",
            "CLASS_NAME", "LINK_TEXT", "PARTIAL_LINK_TEXT", "XPATH"
        )r1   Úfind_elementÚgetattrr   Úupper©r@   ÚselectorÚ	attributes      rL   r—   zBrowser.find_elementî   s0   € ð Œ{×'Ò'­µ°I·O²OÑ4EÔ4EÑ(FÔ(FÈÑQÔQÐQrN   c                 ó‚   — | j                              t          t          |                     ¦   «         ¦  «        |¦  «        S )aµ  find_elements returns a list of all elements matching the attribute
        `selector`. Shortcut to `driver.find_elements(By.CSS_SELECTOR, ...)`.
        args:
        - attribute: the attribute type to search for, aligns with the Selenium
            API's `By` class. default "CSS_SELECTOR"
            valid values: "CSS_SELECTOR", "ID", "NAME", "TAG_NAME",
            "CLASS_NAME", "LINK_TEXT", "PARTIAL_LINK_TEXT", "XPATH"
        )r1   rk   r˜   r   r™   rš   s      rL   rk   zBrowser.find_elementsù   s0   € ð Œ{×(Ò(­µ°Y·_²_Ñ5FÔ5FÑ)GÔ)GÈÑRÔRÐRrN   c                 óZ   — t          |t          ¦  «        r|                      |¦  «        S |S rP   )Ú
isinstanceÚstrr—   )r@   Úelem_or_selectors     rL   Ú_get_elementzBrowser._get_element  s0   € ÝÐ&­Ñ,Ô,ð 	7Ø×$Ò$Ð%5Ñ6Ô6Ð6ØÐrN   c                 ó@  — 	 |€| j         nt          | j        |¦  «        }t                               d||j        |j        ¦  «         |                     |¦  «        S # t          $ r7}t          |¦  «        r || j        ¦  «        }n|}t          |¦  «        |‚d}~ww xY w)z4Abstract generic pattern for explicit WebDriverWait.Nz!method, timeout, poll => %s %s %s)r2   r   r1   r;   r<   Ú_timeoutÚ_pollr   Ú	ExceptionÚcallabler
   )r@   Úmethodr   ÚmsgÚ_waitrˆ   Úmessages          rL   Ú	_wait_forzBrowser._wait_for	  s¼   € ð	5ð �?ð ”�å" 4¤;°Ñ8Ô8ð õ
 �LŠLØ3ØØ”Ø”ñ	ô ð ð —;’;˜vÑ&Ô&Ð&øÝð 	5ð 	5ð 	5Ý˜‰}Œ}ð Ø˜#˜dœkÑ*Ô*��à�Ý" 7Ñ+Ô+°Ð4øøøøð	5øøøs   ‚AA Á
BÁ&2BÂBc                 ó.   — |                       ||¦  «        S )z†wait_for_element is shortcut to `wait_for_element_by_css_selector`
        timeout if not set, equals to the fixture's `wait_timeout`.)Ú wait_for_element_by_css_selector©r@   r›   r   s      rL   Úwait_for_elementzBrowser.wait_for_element   s   € ð ×4Ò4°X¸wÑGÔGÐGrN   c                 ó†   — |                       t          j        t          j        |f¦  «        |d|p| j        › d|› �¦  «        S )ú¹Explicit wait until the element is present, timeout if not set,
        equals to the fixture's `wait_timeout` shortcut to `WebDriverWait` with
        `EC.presence_of_element_located`.útimeout zs => waiting for selector )r¬   ÚECÚpresence_of_element_locatedr   r•   r*   r¯   s      rL   r®   z(Browser.wait_for_element_by_css_selector%  sU   € ð �~Š~ÝÔ*Ý” (Ð+ñô ð ØZ�wÐ4 $Ô"4ÐZÐZÐPXÐZÐZñ
ô 
ð 	
rN   c                 ó@   ‡ ‡— t          ˆˆ fd„|p‰ j        ¦  «         dS )zfExplicit wait until an element is NOT found. timeout defaults to
        the fixture's `wait_timeout`.c                  óH   •— ‰j                              d‰ › d�¦  «        dk    S )Nz"return document.querySelectorAll('z	').lengthr   )r1   r�   )r›   r@   s   €€rL   ú<lambda>z.Browser.wait_for_no_elements.<locals>.<lambda>7  s1   ø€ �D”K×.Ò.ØH°XÐHÐHÐHñô ð ò€ rN   N)r   r*   r¯   s   `` rL   Úwait_for_no_elementszBrowser.wait_for_no_elements1  sH   øø€ õ 	ðð ð ð ð ð Ð)�tÔ)ñ	
ô 	
ð 	
ð 	
ð 	
rN   c                 ó†   — |                       t          j        t          j        |f¦  «        |d|p| j        › d|› �¦  «        S )r²   r³   zs => waiting for element id )r¬   r´   rµ   r   ÚIDr*   )r@   Ú
element_idr   s      rL   ri   zBrowser.wait_for_element_by_id>  sU   € ð �~Š~ÝÔ*Ý”˜
Ð#ñô ð Ø^�wÐ4 $Ô"4Ð^Ð^ÐR\Ð^Ð^ñ
ô 
ð 	
rN   c           	      ój   — |                       t          ||¦  «        |d|› d|p| j        › d�¬¦  «        S )zÏExplicit wait until the element's class has expected `value` timeout
        if not set, equals to the fixture's `wait_timeout` shortcut to
        `WebDriverWait` with customized `class_to_equal` condition.zclassname => ú not found within Ús©r¨   r   r©   )r¬   r   r*   ©r@   r›   Ú	classnamer   s       rL   Úwait_for_class_to_equalzBrowser.wait_for_class_to_equalJ  sM   € ð �~Š~Ý! (¨IÑ6Ô6ØØ] 	Ð]Ð]¸WÐ=ZÈÔHZÐ]Ð]Ð]ð ñ 
ô 
ð 	
rN   c                 ór   — |                       t          |||¦  «        |d|› d|› d|p| j        › d�¬¦  «        S )zÏExplicit wait until the element's style has expected `value` timeout
        if not set, equals to the fixture's `wait_timeout` shortcut to
        `WebDriverWait` with customized `style_to_equal` condition.zstyle val => ú r¾   r¿   rÀ   )r¬   r   r*   )r@   r›   ÚstyleÚvalr   s        rL   Úwait_for_style_to_equalzBrowser.wait_for_style_to_equalT  sW   € ð �~Š~Ý! (¨E°3Ñ7Ô7ØØ_ Ð_Ð_¨Ð_Ð_¸wÐ?\È$ÔJ\Ð_Ð_Ð_ð ñ 
ô 
ð 	
rN   c                 ól   — t          |||p| j        ¦  «        }|                      |||j        ¬¦  «        S )zæExplicit wait until the element's text equals the expected `text`.

        timeout if not set, equals to the fixture's `wait_timeout`
        shortcut to `WebDriverWait` with customized `text_to_equal`
        condition.
        rÀ   )r   rJ   r¬   r«   ©r@   r›   Útextr   r¨   s        rL   Úwait_for_text_to_equalzBrowser.wait_for_text_to_equal^  sC   € õ ˜x¨¨wÐ/K¸$Ô:KÑLÔLˆà�~Š~ØØØ”ð ñ 
ô 
ð 	
rN   c           	      ój   — |                       t          ||¦  «        |d|› d|p| j        › d�¬¦  «        S )zñExplicit wait until the element's classes contains the expected `classname`.

        timeout if not set, equals to the fixture's `wait_timeout`
        shortcut to `WebDriverWait` with customized `contains_class`
        condition.
        zclassname -> z! not found inside element within r¿   rÀ   )r¬   r   r*   rÁ   s       rL   Úwait_for_contains_classzBrowser.wait_for_contains_classm  sN   € ð �~Š~Ý! (¨IÑ6Ô6ØØl 	ÐlÐlÈGÐLiÐW[ÔWiÐlÐlÐlð ñ 
ô 
ð 	
rN   c                 ól   — t          |||p| j        ¦  «        }|                      |||j        ¬¦  «        S )zèExplicit wait until the element's text contains the expected `text`.

        timeout if not set, equals to the fixture's `wait_timeout`
        shortcut to `WebDriverWait` with customized `contains_text`
        condition.
        rÀ   )r   rJ   r¬   r«   rÊ   s        rL   Úwait_for_contains_textzBrowser.wait_for_contains_textz  sC   € õ ˜x¨¨wÐ/K¸$Ô:KÑLÔLˆØ�~Š~ØØØ”ð ñ 
ô 
ð 	
rN   c                 ó8  — | j                              |€| j        n|¦  «         	 |                      | j        |¬¦  «         n·# t
          $ rª}t                               d|¦  «         d                     d„ |  	                    ¦   «         D ¦   «         ¦  «        }t           
                    |¦  «         |                      d¦  «                             d¦  «        }t          d|› d	|› d�¦  «        |‚d}~ww xY w| j        rd
dl}|                     ¦   «          dS dS )z¤wait_for_page navigates to the url in webdriver wait until the
        renderer is loaded in browser.

        use the `server_url` if url is not provided.
        Nr   z+dash server is not loaded within %s secondsú
c              3   ó4   K  — | ]}t          |¦  «        V — Œd S rP   )r    )Ú.0Úlogs     rL   ú	<genexpr>z(Browser.wait_for_page.<locals>.<genexpr>•  s(   è è € ÐBÐB¨3�c #™hœhÐBÐBÐBÐBÐBÐBrN   ÚbodyÚ	innerHTMLzIthe expected Dash react entry point cannot be loaded in browser
 HTML => z
 Console Logs => r   )r1   rf   rg   r®   Údash_entry_locatorr
   r;   rX   ÚjoinÚget_logsr<   r—   Úget_propertyr   r-   ÚpdbÚ	set_trace)r@   Úurlr   ÚexcÚlogsÚhtmlrÝ   s          rL   Úwait_for_pagezBrowser.wait_for_pageˆ  sU  € ð 	Œ�Š¨3¨;˜œ˜¸CÑ@Ô@Ð@ð	Ø×1Ò1ØÔ'°ð 2ñ ô ð ð øõ  ð 	ð 	ð 	Ý×ÒÐJÈGÑTÔTÐTØ—9’9ÐBÐB°$·-²-±/´/ÐBÑBÔBÑCÔCˆDÝ�LŠL˜ÑÔÐØ×$Ò$ VÑ,Ô,×9Ò9¸+ÑFÔFˆDÝ%ðKØ)-ðKð KØBFðKð Kð Kñô ð ðøøøøð	øøøð Œ;ð 	ØˆJˆJˆJà�MŠM‰OŒOˆOˆOˆOð	ð 	s   ¥A Á
C6ÁB%C1Ã1C6c                 óP  — |                       |¦  «        }|                     ¦   «          |                     t          j        d¦  «        }t
                               dd                     |j         	                    d¦  «        ¦  «        ¦  «         | 
                    t          j        d¦  «        }|rXt          |t          ¦  «        r||                              ¦   «          d S |D ]$}|j        |k    r|                     ¦   «           d S Œ%t
                               d||¦  «         d S )Nzdiv.Select-menu-outerzthe available options are %sú|rÒ   zdiv.VirtualizedSelectOptionz6cannot find matching option using value=%s or index=%s)r¢   Úclickr—   r   r•   r;   r<   rÚ   rË   Úsplitrk   rŸ   Úintr   )r@   r¡   ÚvalueÚindexÚdropdownÚmenurE   Úoptions           rL   Úselect_dcc_dropdownzBrowser.select_dcc_dropdown¢  s  € Ø×$Ò$Ð%5Ñ6Ô6ˆØ�ŠÑÔÐà×$Ò$¥R¤_Ð6MÑNÔNˆÝ�ŠÐ3°S·X²X¸d¼i¿oºoÈdÑ>SÔ>SÑ5TÔ5TÑUÔUÐUà×$Ò$¥R¤_Ð6SÑTÔTˆØð 	Ý˜%¥Ñ%Ô%ð Ø˜”×$Ò$Ñ&Ô&Ð&Ø�à!ð ð �Ø”; %Ò'Ð'Ø—L’L‘N”N�NØ�F�Fð (õ 	�ŠØDÀeÈUñ	
ô 	
ð 	
ð 	
ð 	
rN   c                 ól   — | j         dz   dz  }|                      |¬¦  «         | xj         dz  c_         dS )zASwitch between the current working window and the new opened one.r   r   )ÚidxN)r5   Úswitch_window©r@   rð   s     rL   Útoggle_windowzBrowser.toggle_window¸  sE   € àÔ !Ñ# qÑ(ˆØ×Ò˜sÐÑ#Ô#Ð#ØÐÔ˜AÑÐÔÐÐrN   r   c                 ó¼   — t          | j        j        ¦  «        |k    rt          d¦  «        ‚| j        j                             | j        j        |         ¦  «         dS )zOSwitch to window by window index shortcut to
        `driver.switch_to.window`.z$there is no second window in BrowserN)Úlenr1   Úwindow_handlesr   Ú	switch_toÚwindowrò   s     rL   rñ   zBrowser.switch_window¾  sT   € õ ˆtŒ{Ô)Ñ*Ô*¨cÒ1Ð1ÝÐEÑFÔFÐFàŒÔ×$Ò$ T¤[Ô%?ÀÔ%DÑEÔEÐEÐEÐErN   c                 óP   — | j                              d|p| j        › d�¦  «         dS )zAOpen a new tab in browser url is not set, equals to `server_url`.zwindow.open("z", "new window")N)r1   r�   rg   )r@   rß   s     rL   Úopen_new_tabzBrowser.open_new_tabÆ  s;   € àŒ×"Ò"ØD˜CÐ2 4¤?ÐDÐDÐDñ	
ô 	
ð 	
ð 	
ð 	
rN   c                 óB   —  t          | d| j        › �¦  «        ¦   «         S )NÚ_get_)r˜   r$   rR   s    rL   r.   zBrowser.get_webdriverÌ  s%   € Ø5�w�tÐ4 T¤]Ð4Ð4Ñ5Ô5Ñ7Ô7Ð7rN   c                 óà   — | j         r't          | j         t          ¦  «        r| j         d         n0t          t          | j        ¦  «        j                             ¦   «         }| j        rd|_	        |S )Nr   T)
r(   rŸ   Úlistr˜   r   r$   rE   ÚOptionsr'   rD   ©r@   rE   s     rL   Ú_get_wd_optionszBrowser._get_wd_optionsÏ  sl   € ð Œ}ðEÝ!+¨D¬M½4Ñ!@Ô!@ðEˆDŒM˜!ÔÐå� D¤MÑ2Ô2Ô:×BÒBÑDÔDð 	ð Œ>ð 	$Ø#ˆGÔàˆrN   c           	      ó  — |                       ¦   «         }|                     dddi¦  «         |                     dddi¦  «         dt          j        v rt          j        d         |_        |                     d| j        ddddd	œ¦  «         |                     d
¦  «         |                     d¦  «         |                     d¦  «         |                     d¦  «         | j        rt          j
        | j        |¬¦  «        nt          j        |¬¦  «        }| j        rMd|j        j        d<   dd| j        dœdœ}|                     d|¦  «        }t"                               d|¦  «         |                     dd¦  «         |S )NÚloggingPrefsrA   ÚSEVEREzgoog:loggingPrefsÚDASH_TEST_CHROMEPATHÚprefsFT)zdownload.default_directoryzdownload.prompt_for_downloadzdownload.directory_upgradezsafebrowsing.enabledz(safebrowsing.disable_download_protectionz--disable-dev-shm-usagez--no-sandboxz--disable-gpuz--remote-debugging-port=9222©Úcommand_executorrE   ©rE   )ÚPOSTz)/session/$sessionId/chromium/send_commandÚsend_commandzPage.setDownloadBehaviorÚallow)ÚbehaviorÚdownloadPath)ÚcmdÚparamsz$enabled headless download returns %sr   )r  Úset_capabilityr=   ÚenvironÚbinary_locationÚadd_experimental_optionrF   Úadd_argumentr&   r   ÚRemoter%   ÚChromer'   r  Ú	_commandsÚexecuter;   r<   Úset_window_position)r@   rE   Úchromer  Úress        rL   Ú_get_chromezBrowser._get_chromeÛ  s°  € Ø×&Ò&Ñ(Ô(ˆà×Ò˜~°	¸8Ð/DÑEÔEÐEØ×ÒÐ2°YÀÐ4IÑJÔJÐJà!¥R¤ZÐ/Ð/Ý&(¤jÐ1GÔ&HˆGÔ#à×'Ò'Øà.2Ô.@Ø05Ø.2Ø(-Ø<@ðð ñ		
ô 		
ð 		
ð 	×ÒÐ6Ñ7Ô7Ð7Ø×Ò˜^Ñ,Ô,Ð,Ø×Ò˜_Ñ-Ô-Ð-Ø×ÒÐ;Ñ<Ô<Ð<ð Œ|ð3�IÔ¨dÔ.>ÈÐPÑPÔPÐPåÔ!¨'Ð2Ñ2Ô2ð 	ð Œ>ð 	FðAˆFÔ#Ô-¨nÑ=ð
 2Ø'.ÀÔ@RÐSÐSðð ˆFð —.’. °Ñ8Ô8ˆCÝ�LŠLÐ?ÀÑEÔEÐEà×"Ò" 1 aÑ(Ô(Ð(ØˆrN   c                 ó‚  — |                       ¦   «         }|                     dddi¦  «         |                     dd¦  «         |                     d| j        ¦  «         |                     dd¦  «         |                     d	d
¦  «         | j        rt          j        | j        |¬¦  «        nt          j        |¬¦  «        S )Nr  rA   r  Ú
marionetteTzbrowser.download.dirzbrowser.download.folderListr   z&browser.helperApps.neverAsk.saveToDiskzapplication/octet-streamr  r	  )	r  r  Úset_preferencerF   r&   r   r  r%   ÚFirefoxr   s     rL   Ú_get_firefoxzBrowser._get_firefox
  sÙ   € Ø×&Ò&Ñ(Ô(ˆà×Ò˜~°	¸8Ð/DÑEÔEÐEØ×Ò˜|¨TÑ2Ô2Ð2à×ÒÐ5°tÔ7IÑJÔJÐJØ×ÒÐ<¸aÑ@Ô@Ð@Ø×ÒØ4Ø&ñ	
ô 	
ð 	
ð Œ|ð	4�IÔØ!%Ô!1Øðñ ô ð õ
 Ô"¨7Ð3Ñ3Ô3ð	
rN   c                  ó"   — t           j        dk    S )NÚwin32)rx   ÚplatformrQ   rN   rL   rŒ   zBrowser._is_windows  s   € åŒ|˜wÒ&Ð&rN   c                 ó¤   — t          |¦  «        D ]?}|                      |¦  «                             ¦   «          |rt          j        |¦  «         Œ@dS )z9multiple_click click the element with number of `clicks`.N)Úranger¢   ræ   r|   r}   )r@   r¡   ÚclicksÚdelayr‹   s        rL   Úmultiple_clickzBrowser.multiple_click#  s[   € å�v‘”ð 	"ð 	"ˆAØ×ÒÐ.Ñ/Ô/×5Ò5Ñ7Ô7Ð7Øð "Ý”
˜5Ñ!Ô!Ð!øð	"ð 	"rN   c                 óH  — |                       |¦  «        }t                               d||¦  «         t          | j        ¦  «                             |¦  «                             d¦  «                             |¦  «                             t          j
        ¦  «                             t          j        ¦  «                             t          j        ¦  «                             t          j        ¦  «                             t          j        ¦  «                             ¦   «          dS )z&Simulate key press to clear the input.zclear input with %s => %sçš™™™™™É?N)r¢   r;   r<   r   r1   Úmove_to_elementrK   ræ   Ú	send_keysr   ÚENDÚkey_downÚSHIFTÚHOMEÚkey_upÚDELETEÚperform)r@   r¡   Úelems      rL   Úclear_inputzBrowser.clear_input*  s¸   € à× Ò Ð!1Ñ2Ô2ˆÝ�ŠÐ0Ð2BÀDÑIÔIÐIå˜œÑ%Ô%ßŠ_˜TÑ"Ô"ßŠU�3‰ZŒZßŠU�4‰[Œ[ßŠY•t”xÑ Ô ßŠX•d”jÑ!Ô!ßŠY•t”yÑ!Ô!ßŠV•D”JÑÔßŠY•t”{Ñ#Ô#ß
Š'‰)Œ)ˆ)ˆ)ˆ)rN   ç      à?r,  c                 óì  — |                       |¦  «        }|                     d¦  «        }|j        d         |j        d         }}	 t          | j        ¦  «                             |||z  ||z  ¦  «                             |||z  ||z  ¦  «                             ¦   «          n*# t          $ r t           
                    d¦  «         Y nw xY w|r#||                     d¦  «        k    sJ d¦   «         ‚dS dS )zËZoom out a graph with a zoom box fraction of component dimension
        default start at middle with a rectangle of 1/5 of the dimension use
        `compare` to control if we check the svg get changed.rØ   ÚwidthÚheightz$graph offset outside of the boundaryz*SVG content should be different after zoomN)r¢   Úget_attributeÚsizer   r1   Úmove_to_element_with_offsetÚdrag_and_drop_by_offsetr5  r   r;   rX   )	r@   r¡   Ústart_fractionÚzoom_box_fractionÚcomparer6  ÚprevÚwÚhs	            rL   Úzoom_in_graph_by_ratiozBrowser.zoom_in_graph_by_ratio:  s5  € ð × Ò Ð!1Ñ2Ô2ˆà×!Ò! +Ñ.Ô.ˆØŒy˜Ô! 4¤9¨XÔ#6ˆ1ˆð	EÝ˜œÑ%Ô%×AÒAØ�a˜.Ñ(¨!¨nÑ*<ñô ç%Ò%Ø�aÐ+Ñ+¨QÐ1BÑ-Bñô çŠg‰iŒiˆiˆiøÝ-ð 	Eð 	Eð 	EÝ×ÒÐCÑDÔDÐDÐDÐDð	Eøøøàð 	<Ø˜4×-Ò-Øñô ò ð ð à;ñô ð ð	<ð 	<ðð s   ÁAB# Â#$C
Ã	C
c                 ó  — |                       |¦  «        }t          | j        ¦  «                             ||j        d         |z  |j        d         |z  ¦  «                             ¦   «                              ¦   «          d S )Nr:  r;  )r¢   r   r1   r>  r=  ræ   r5  )r@   r¡   ÚfxÚfyr6  s        rL   Úclick_at_coord_fractionsz Browser.click_at_coord_fractionsQ  si   € Ø× Ò Ð!1Ñ2Ô2ˆå�T”[Ñ!Ô!×=Ò=Ø�$”)˜GÔ$ rÑ)¨4¬9°XÔ+>ÀÑ+Cñ	
ô 	
ç
Š%‰'Œ'—'’'‘)”)�)�)�)rN   c                 óÀ   ‡ — ‰ j         j                             ¦   «         dk    r&ˆ fd„‰ j                              d¦  «        D ¦   «         S t	          j        d¦  «         dS )z›Return a list of `SEVERE` level logs after last reset time stamps
        (default to 0, resettable by `reset_log_timestamp`.

        Chrome only
        r  c                 ó6   •— g | ]}|d          ‰j         k    ¯|‘ŒS )Ú	timestamp)r3   )rÔ   Úentryr@   s     €rL   ú
<listcomp>z$Browser.get_logs.<locals>.<listcomp>_  s5   ø€ ð ð ð àØ˜Ô%¨¬Ò5Ð5ð à5Ð5Ð5rN   rA   z=get_logs always return None with webdrivers other than ChromeN)r1   rw   r#   Úget_logÚwarningsÚwarnrR   s   `rL   rÛ   zBrowser.get_logsX  st   ø€ ð Œ;Ô×!Ò!Ñ#Ô# xÒ/Ð/ðð ð ð à!œ[×0Ò0°Ñ;Ô;ðñ ô ð õ
 	ŒÐUÑVÔVÐVØˆtrN   c                 ó°   — | j         j                             ¦   «         dk    r1| j                              d¦  «        }|r|d         d         | _        dS dS dS )z4reset_log_timestamp only work with chrome webdriver.r  rA   éÿÿÿÿrM  N)r1   rw   r#   rP  r3   )r@   Úentriess     rL   Úreset_log_timestampzBrowser.reset_log_timestampg  sa   € àŒ;Ô×!Ò!Ñ#Ô# xÒ/Ð/Ø”k×)Ò)¨)Ñ4Ô4ˆGØð 9Ø '¨¤¨KÔ 8�”��ð 0Ð/ð9ð 9rN   c                 ó   — | j         S )z2Expose the selenium webdriver as fixture property.)r/   rR   s    rL   r1   zBrowser.drivern  s   € ð Œ|ÐrN   c                 ó   — | j         j        S rP   )r1   r’   rR   s    rL   r’   zBrowser.session_ids  s   € àŒ{Ô%Ð%rN   c                 ó   — | j         S rP   )r4   rR   s    rL   rg   zBrowser.server_urlw  s
   € àŒyÐrN   c                 ó<   — || _         |                      ¦   «          dS )z‰Set the server url so the selenium is aware of the local server
        port.

        It also implicitly calls `wait_for_page`.
        N)r4   rã   ©r@   ré   s     rL   rg   zBrowser.server_url{  s#   € ð ˆŒ	Ø×ÒÑÔÐÐÐrN   c                 ó   — | j         S rP   )r)   rR   s    rL   rF   zBrowser.download_path…  s   € àÔ"Ð"rN   c                 ó   — | j         S rP   )r*   rR   s    rL   rJ   zBrowser.wait_timeout‰  s   € àÔ!Ð!rN   c                 óH   — || _         t          | j        |¦  «        | _        d S rP   )r*   r   r1   r2   r[  s     rL   rJ   zBrowser.wait_timeout�  s!   € à"ˆÔÝ% d¤k°5Ñ9Ô9ˆŒˆˆrN   )
FNFNr   TTr   r   F)TFTFN)r   FFN)r•   rP   )Nr   )NN)r   )r8  r,  T).Ú__name__Ú
__module__Ú__qualname__rM   rS   r^   rr   rj   r”   r—   rk   r¢   r¬   r°   r®   r¹   ri   rÃ   rÈ   rÌ   rÎ   rÐ   rã   rî   ró   rñ   rú   r.   r  r  r"  ÚstaticmethodrŒ   r*  r7  rF  rJ  rÛ   rV  Úpropertyr1   r’   rg   ÚsetterrF   rJ   rQ   rN   rL   r   r   '   s·  € € € € € ð
 ØØØØØØØØØð1Uð 1Uð 1Uð 1Uðfð ð ðIð Ið Ið"  ØØØØð ð  ð  ð  ðF QUðLð Lð Lð Lð\Nð Nð Nð$	Rð 	Rð 	Rð 	Rð	Sð 	Sð 	Sð 	Sð ð  ð  ð
5ð 5ð 5ð.Hð Hð Hð Hð


ð 

ð 

ð 

ð
ð 
ð 
ð 
ð

ð 

ð 

ð 

ð
ð 
ð 
ð 
ð
ð 
ð 
ð 
ð
ð 
ð 
ð 
ð
ð 
ð 
ð 
ð
ð 
ð 
ð 
ðð ð ð ð4
ð 
ð 
ð 
ð,ð ð ðFð Fð Fð Fð
ð 
ð 
ð 
ð8ð 8ð 8ð
ð 
ð 
ð-ð -ð -ð^
ð 
ð 
ð* ð'ð 'ñ „\ð'ð"ð "ð "ð "ðð ð ð" TXð<ð <ð <ð <ð.ð ð ðð ð ð9ð 9ð 9ð ðð ñ „Xðð ð&ð &ñ „Xð&ð ðð ñ „Xðð Ôðð ñ Ôðð ð#ð #ñ „Xð#ð ð"ð "ñ „Xð"ð Ôð:ð :ñ Ôð:ð :ð :rN   r   )+r=   rx   r|   ÚloggingrQ  r6   rƒ   Úseleniumr   Úselenium.webdriver.supportr   r´   Úselenium.webdriver.common.byr   Úselenium.webdriver.support.waitr   Úselenium.webdriver.common.keysr   Ú'selenium.webdriver.common.action_chainsr   Úselenium.common.exceptionsr	   r
   r   Údash.testing.waitr   r   r   r   r   r   Údash.testing.dash_pager   Údash.testing.errorsr   r   r   Údash.testing.constsr   Ú	getLoggerr_  r;   r   rQ   rN   rL   ú<module>rr     sÈ  ðà 	€	€	€	Ø 
€
€
€
Ø €€€Ø €€€Ø €€€Ø €€€Ø €€€à Ð Ð Ð Ð Ð Ø @Ð @Ð @Ð @Ð @Ð @Ø +Ð +Ð +Ð +Ð +Ð +Ø 9Ð 9Ð 9Ð 9Ð 9Ð 9Ø /Ð /Ð /Ð /Ð /Ð /Ø @Ð @Ð @Ð @Ð @Ð @ðð ð ð ð ð ð ð ð ð ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð 1Ð 0Ð 0Ð 0Ð 0Ð 0Ø VÐ VÐ VÐ VÐ VÐ VÐ VÐ VÐ VÐ VØ 5Ð 5Ð 5Ð 5Ð 5Ð 5ð 
ˆÔ	˜8Ñ	$Ô	$€ði	:ð i	:ð i	:ð i	:ð i	:ˆmñ i	:ô i	:ð i	:ð i	:ð i	:rN   