
    i6                    p   U d Z ddlm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ZdZ e eej$                  j'                  d e ee      j+                         j,                  j,                                    d	z        Zej0                  j3                  d
      ZdZdZded<   dZded<   h dZded<   d,d-dZ d.dZ!d/d0dZ"d Z#d Z$d Z%d Z&d Z'd Z(d,dZ)d Z*d,dZ+d  Z,d! Z-d" Z.d# Z/d$ Z0d% Z1d& Z2d' Z3d( Z4e-e.e/e0e1e2e3d)Z5d* Z6e7d+k(  r ejp                   e6              yy)1z4Browser control utility via Playwright CDP sessions.    )annotationsN)Callable)Pathz/tmp/playwright-session.jsonz/tmp/pw-browser-sessionWORKSPACE_ROOTzdashboard/screenshot-live.pngz:~/.cache/ms-playwright/chromium-1208/chrome-linux64/chromei$  )7z--test-typez--lang=en-USz--mute-audioz--disable-syncz--hide-scrollbarsz--disable-loggingz--start-maximizedz--enable-async-dnsz--accept-lang=en-USz--use-mock-keychainz--disable-translatez--disable-voice-inputz--window-position=0,0z--disable-wake-on-wifiz--ignore-gpu-blocklistz--enable-tcp-fast-openz--enable-web-bluetoothz--disable-cloud-importz--disable-print-previewz--disable-dev-shm-usagez--metrics-recording-onlyz--disable-crash-reporterz--disable-partial-rasterz--disable-gesture-typingz--disable-checker-imagingz--disable-prompt-on-repostz--force-color-profile=srgbz--font-render-hinting=nonez--aggressive-cache-discardz--disable-cookie-encryptionz--disable-domain-reliabilityz--disable-threaded-animationz--disable-threaded-scrollingz--enable-simple-cache-backendz--disable-background-networkingz --enable-surface-synchronizationz --disable-image-animation-resyncz --disable-renderer-backgroundingz!--disable-ipc-flooding-protectionz!--prerender-from-omnibox=disabledz"--safebrowsing-disable-auto-updatez#--disable-offer-upload-credit-cardsz%--disable-background-timer-throttlingz'--disable-new-content-rendering-timeoutz'--run-all-compositor-stages-before-drawz(--disable-client-side-phishing-detectionz(--disable-backgrounding-occluded-windowsz)--disable-layer-tree-host-memory-pressurez'--autoplay-policy=user-gesture-requiredz+--disable-offer-store-unmasked-wallet-cardsz---disable-blink-features=AutomationControlledz4--disable-component-extensions-with-background-pageszc--enable-features=NetworkService,NetworkServiceInProcess,TrustTokens,TrustTokensAlwaysAllowIssuancezf--blink-settings=primaryHoverType=2,availableHoverTypes=2,primaryPointerType=4,availablePointerTypes=4zM--disable-features=AudioServiceOutOfProcess,TranslateUI,BlinkGenPropertyTreesztuple[str, ...]STEALTH_ARGS)z--enable-automationz--disable-popup-blockingz--disable-component-updatez--disable-default-appsz--disable-extensionsHARMFUL_ARGS>   fontimagemediaother
stylesheetzset[str]BLOCKED_RESOURCE_TYPESc                    	 ddl }ddlm} |j                         j	                         }|dk(  rd}n|dvrd}| r |d|d	
      }n |d|d	
      }|j                         }t        |      S # t        $ r ddicY S w xY w)u,   browserforge로 실제 Chrome 헤더 생성.r   N)HeaderGeneratordarwinmacos)linuxwindowsr   r   chromedesktop)browserosdevice)r   firefoxedge
User-AgentzeMozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36)platformbrowserforge.headersr   systemlowergeneratedictImportError)browser_moder   r   os_namegenheaderss         @/home/jay/workspace/.worktrees/task-2116-dev1/scripts/browser.pygenerate_stealth_headersr)   ]   s    
8//#))+hG99G!(wyQC!*GG\efC,,.G} 
   B
 	

s   A)A, ,A<;A<c                      y)u!   Google 검색 referer URL 반환.zhttps://www.google.com/ r+       r(   get_google_refererr-   x   s    $r,   c                &    | | nt         fd}|S )u,   리소스 차단 async route handler 반환.c                   K   | j                   j                  v r| j                          d {    y | j                          d {    y 7 7 wN)requestresource_typeabort	continue_)routetypes_to_blocks    r(   handlerz(create_resource_blocker.<locals>.handler   sA     ==&&.8++-//###  #s!   ,AAAA	AA)r   )block_typesr7   r6   s     @r(   create_resource_blockerr9   }   s    $/$;[AWN$ Nr,   c                D    t        t        j                  | d             y )NF)ensure_ascii)printjsondumps)ds    r(   joutr@      s    	$**QU
+,r,   c                     	 t        t              5 } t        j                  |       cd d d        S # 1 sw Y   y xY w# t        $ r Y y w xY wr0   )openSESSION_FILEr=   load	Exception)fs    r(   load_sessionrG      sB    , 	 199Q<	  	  	  s#   < 0	< 9< < 	AAc                    t        t        d      5 }t        j                  | |d|       d d d        y # 1 sw Y   y xY w)Nw)pidport)rB   rC   r=   dump)rJ   rK   rF   s      r(   save_sessionrM      s6    	lC	  1A		#t,a01 1 1s   4=c                 V    	 t        j                  t               y # t        $ r Y y w xY wr0   )r   removerC   FileNotFoundErrorr+   r,   r(   clear_sessionrQ      s%    
		, s    	((c                P    	 t        j                  | d       y# t        $ r Y yw xY w)Nr   TF)r   killrE   )rJ   s    r(   aliverT      s)    
Q s    	%%c                    	 | j                         j                  d      \  }}t        |      t        |      fS # t        $ r Y yw xY w)Nx)i   i  )r    splitintrE   )srI   hs      r(   parse_vpr[      sC    wwys#11vs1v~ s   7: 	AAc                   t        j                  t        d       t        ddd|  dt         dg}|r)t        gt	        t
              z   ddd|  dt         dgz   }t        j                  |t        j                  t        j                        }t        j                  d	       |j                         t        d
      |j                  S )z/Launch headless Chrome with CDP and return PID.Texist_okz
--headlessz--no-sandboxz--remote-debugging-port=z--user-data-dir=zabout:blank)stdoutstderrg      ?zChrome failed to start)r   makedirsSESSION_DIRCHROMIUMlistr   
subprocessPopenDEVNULLtimesleeppollRuntimeErrorrJ   )rK   stealthargsprocs       r(   launch_chromero      s    KKd+
"4&)
;-(D J< ! *4&1";-0 	 D););JDVDVWDJJsOyy{34488Or,   c                R  K   t        |dd      }t        |dd      }t        |dd       }|rd}nt        |j                        }|r| j                  j	                  |       d {   }|j
                  r|j
                  d   n|j                          d {   }|j                  r|j                  d   n|j                          d {   }|j                  |j                         |j                  |d   |d   d       d {    |r"|j                  d	t                      d {    ||fS t               }	|	rt        |	d
         r	 | j                  j	                  d|	d           d {   }|j
                  r|j
                  d   n|j                          d {   }|j                  r|j                  d   n|j                          d {   }|j                  |j                         |j                  |d   |d   d       d {    |r"|j                  d	t                      d {    ||fS t-        t.        |      }
t1        |
t.               | j                  j	                  dt.                d {   }d|d   |d   di}|r@d|d<   ddd|d<   t3        d      }t5               |d<   ||d<   |j7                  dd      |d<   |j
                  r|j
                  d   n |j                  di | d {   }|j                  r|j                  d   n|j                          d {   }|j                  |j                         |j                  |d   |d   d       d {    |r"|j                  d	t                      d {    ||fS 7 G7 7 7 7 7 F7 7 7 7 # t         $ rF 	 t#        j$                  |	d
   t&        j(                         n# t         $ r Y nw xY wt+                Y w xY w7 7 7 7 7 w)Nrl   Fblock_resources
remote_cdp)  8  r      )widthheightz**/*rJ   zhttp://127.0.0.1:rK   )rl   viewport   device_scale_factorrs   rt   screenT)r$   Refererextra_http_headersr    
user_agentr+   )getattrr[   rx   chromiumconnect_over_cdpcontextsnew_contextpagesnew_pageset_default_timeouttimeoutset_viewport_sizer5   r9   rG   rT   rE   r   rS   signalSIGTERMrQ   ro   CDP_PORTrM   r)   r-   get)pwrm   rl   rq   rr   vpbctxpgsessrJ   ctx_optsr'   s                r(   get_pager      s    dIu-Gd$5u=O|T2Jdmm$ ++..z:: zzajjmQ]]_/D YYSYYq\#,,.,@
t||,""RUbe#DEEE((6#:#<==="u>Dd5k"	kk225FtF|n3UVVA#$::!**Q-3HC!$1clln0DB""4<<0&&A"Q%'HIIIhhv'>'@AAAb5L '
2Chkk**->xj+IJJA BqERU"CDH*+&''+t<*=/1	)0%&!(\2!>::!**Q-1J1J+JC1clln(<B4<<(


A"Q%@
AAAhhv68999b5La ;/D,@E= W3H0DIA 	UV^^4 O	 	K ,K(<A 	:sR  A"P'$N+%2P'N.2P'
N1<P'N4#P'+N7,#P'$O	 4N:52O	 'N=(2O	 O <O	 O#O	 ;O<O	 AP'
PBP'P2P'P!<P'>P#?#P'"P%#	P'.P'1P'4P'7P':O	 =O	  O	 O	 O	 		P'O;:P;	PPPPP'PP'P'!P'#P'%P'c                   K   t        j                  t         j                  j                  |      xs dd       | j	                  ||       d {    |S 7 w)N.Tr]   )path	full_page)r   ra   r   dirname
screenshot)r   r   fulls      r(   shotr     sF     KK%,t<
--TT-
222K 3s   AAAAc                X   K   | j                   | j                          d {   dS 7 w)Nurltitler   )r   s    r(   infor     s!     66"((*$455$4s   *(*c                n  K   t        ||        d {   \  }}|j                  | j                  d| j                         d {    |j	                  | j
                         d {    t        dt        || j                         d {   dt        |       d {          y 7 7 g7 F7 $7 w)Ndomcontentloaded)
wait_untilr   okstatusr   )
r   gotor   r   wait_for_timeoutwaitr@   r   outputr   ar   _r   s       r(   cmd_navigater     s     2q/!EAr
''!%%$6		'
JJJ


aff
%%%Dd2qxx.@(@	S$r(N	ST "J%(@NsW   B5B+2B5B-"B5(B/)#B5B1
B5 B3
!B5-B5/B51B53B5c                B  K   t        ||        d {   \  }}| j                  r|j                  | j                  d      n|j                  | j                        }| j
                  |j                  | j
                        n|j                  }d\  }}	 |j                  d       d {    t        || j                         d {    |j                  d       d {   }|j                          d {   d d }|j                          d {    |j                  | j                         d {    t        dt        || j                         d {   ||dt!        |       d {          y 7 k7 7 7 7 # t        $ r Y w xY w7 7 `7 >7 *w)	NF)exact)unknownr~   z$e => e.style.outline='3px solid red'e => e.tagName.toLowerCase()P   r   r   r   elementtext)r   r   get_by_textlocatorselectornthfirstevaluater   r   
inner_textrE   clickr   r   r@   r   )r   r   r   r   loceltagviss           r(   	cmd_clickr   #  s\    2q/!EAr12"..u.
-RZZ

=SC55,#))BHCkk@AAA2qxx   KK >??]]_$cr* ((*


aff
%%% $R 22		

 Hn	
 "
 	B ?$ % 3 s   FE=BFF +F ,F 	F
F "F#F :F;F FF"F8F9#FF
F2F
3F F F F F 	FFFFFFFc                  K   t        ||        d {   \  }}|j                  | j                        j                  }|j	                  | j
                         d {    |j                  | j                         d {    	 |j                  d       d {   }t        dt        || j                         d {   || j
                  dt        |       d {          y 7 7 7 l7 T# t        $ r d}Y _w xY w7 C7 %w)Nr   inputr   r   )r   r   r   r   fillr   r   r   r   rE   r@   r   r   r   )r   r   r   r   r   r   s         r(   cmd_typer   <  s     2q/!EAr
**QZZ
 
&
&C
((166



aff
%%%LL!?@@ 	 $R 22FF		

 Hn	
 "%@ 
 3 s   DC)A
DC+"D C-DC1 C/C1 D>D
?DD
D+D-D/C1 1C?<D>C??DDc                h  K   t        ||        d {   \  }}ddddd| j                     }|j                  |       d {    |j                  | j                         d {    t        dt        || j                         d {   dt        |       d {          y 7 7 g7 F7 $7 w)Nz(window.scrollBy(0,window.innerHeight*.8)z)window.scrollBy(0,-window.innerHeight*.8)zwindow.scrollTo(0,0)z-window.scrollTo(0,document.body.scrollHeight))downuptopbottomr   r   )	r   	directionr   r   r   r@   r   r   r   )r   r   r   r   jss        r(   
cmd_scrollr   P  s     2q/!EAr:9%A	

 kk
B ++b/


aff
%%%Dd2qxx.@(@	S$r(N	ST " %(@NsW   B2B(/B2B*"B2%B,&#B2	B.

B2B0
B2*B2,B2.B20B2c                   K   t        ||        d {   \  }}t        dt        || j                  | j                         d {   dt        |       d {          y 7 P7  7 w)Nr   r   )r   r@   r   r   r   r   r   s       r(   cmd_screenshotr   ]  sS     2q/!EArDd2qxx.H(H	[RVWYRZN	[\ "(HNs3   A)A#1A)A%
A)A'
A)%A)'A)c                  K   t        ||        d {   \  }}|j                  | j                         d {   }t        dt	        || j
                         d {   |dt        |       d {          y 7 i7 E7 #7 w)Nr   )r   r   result)r   r   r   r@   r   r   r   )r   r   r   r   r   s        r(   cmd_evalr   b  sj     2q/!EAr;;qtt$$FDd2qxx.@(@F	e\`ac\dVd	ef "$(@VdsC   BA<%BA>#BB 
B1B
2B>B BBc                   K   t               }|r6t        |d         r(	 t        j                  |d   t        j
                         t                t        ddd       y # t        $ r Y $w xY ww)NrJ   r   zsession closedr   message)	rG   rT   r   rS   r   r   rE   rQ   r@   )r   r   r   s      r(   	cmd_closer   h  s^     >Dd5k"	GGDK0 OD%5	67  		s(   A-'A A-	A*'A-)A**A-c                    t        j                  d      } | j                  dt               | j                  dd       | j                  dt        d	       | j                  d
t        d	       | j                  ddd       | j                  ddd       t        j                  d| g      }|j                  dt
        d d       |j                  dd      }|j                  d| g      j                  d       |j                  d| g      }|j                  ddd !       |j                  d"       |j                  d#t        d 	       |j                  d$| g      }|j                  d       |j                  d%       |j                  d&| g      j                  d'g d()       |j                  d*| g      j                  d+d,       |j                  d-| g      j                  d.       |j                  d/| g       |S )0NF)add_helpz--output)defaultz
--viewport1280x720z--waiti  )typer   z	--timeouti'  z	--stealth
store_truez(Enable stealth mode (anti-bot detection))actionhelpz--block-resourcesz$Block images/fonts/media/CSS loadingzBrowser control via Playwright)descriptionparentsz--remote-cdpz:Remote CDP endpoint URL (e.g., http://100.116.204.95:9222))r   r   r   commandT)destrequirednavigate)r   r   r   r   ?body)nargsr   z--textz--nthr   r   scrollr   )r   r   r   r   )choicesr   z--full)r   evalr   close)argparseArgumentParseradd_argumentDEFAULT_OUTrX   stradd_subparsers
add_parser)commonprY   clktyps        r(   build_parserr   v  s   $$e4F

K8
j9
sD9
#u=
L?ij
+LGmn,LW]V^_ANNS$5q   	
i$7ALLfXL.;;EB
,,w,
1CZsF;XW35
,,vx,
0CZ VLLF8L,99+On9oLLxL0==h|=\LL&L*77=LL6(L+Hr,   )r   r   r   r   r   r   r   c                 \  K   ddl m}  t               j                         }	  |        4 d {   }t	        |j
                     ||       d {    d d d       d {    y 7 67 7 	# 1 d {  7  sw Y   y xY w# t        $ r!}t        dt        |      d       Y d }~y d }~ww xY ww)Nr   )async_playwrighterrorr   )	playwright.async_apir   r   
parse_argsHANDLERSr   rE   r@   r   )r   rm   r   es       r(   mainr    s     5>$$&D5#% 	3 	34<<(r222	3 	3 	32	3 	3 	3 	3 5CF3445s   B,A? A$A? A*A&A*A? A(A? #B,$A? &A*(A? *A<0A31A<8A? ;B,<A? ?	B)B$B,$B))B,__main__)F)r$   boolreturnzdict[str, str])r  r   r0   )r8   zset[str] | Noner  r   )9__doc__
__future__r   r   asyncior=   r   rer   re   rh   collections.abcr   pathlibr   rC   rb   r   environr   __file__resolveparentr   r   
expanduserrc   r   r   __annotations__r   r   r)   r-   r9   r@   rG   rM   rQ   rT   r[   ro   r   r   r   r   r   r   r   r   r   r   r   r  r  __name__runr+   r,   r(   <module>r     su   : "    	 	    $ -'$rzz~~&6DN<R<R<T<[<[<b<b8cde  iH  H  I77Z[8!o 8t!o  $U  T
6%

-1
<<~6U2(
U]
g8:  5 zGKK r,   