+
    i                       R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIH	t	 ^ RI
HtHtHt ^ RIHt ^ RIHt ^ RIHt ^ R	IHt ^ R
IHt ^ RIHt ^ RIHt ^ RIHt ^ RI H!t" Rt#Rt$]PJ                  PM                  RR4      PO                  4       ;'       g    Rt(Rt)Rt*Rt+. RoOt,Rt-Rt.Rpt/^xt0^t1^t2^<t3^t4R R lt5R R lt6R R lt7R R lt8R  R! lt9R" R# lt:R$ R% lt;R& R' lt<R( R) lt=]03R* R+ llt>]13R, R- llt?R. R/ lt@R0 R1 ltA]23R2 R3 lltBR4 R5 ltCR6 R7 ltDR8 R9 ltERqR: R; lltFR< R= ltGR> R? ltHR@ RA ltIRB RC ltJRD RE ltKRrRF RG lltLRH RI ltMRJ RK ltNRL RM ltORN RO ltP]33RP RQ lltQRR RS ltRRT RU ltSRV RW ltTRX RY ltURsRZ R[ lltVR\ R] ltWRtR^ R_ lltXRuR` Ra lltYRb Rc ltZRd Re lt[Rf Rg lt\]43Rh Ri llt]RvRj Rk llt^Rl Rm lt_]`Rn8X  d   ]a! ]_! 4       4      hR# )wa  
Pull_On_Hand_Footwear.py (v14)

Attaches to an already-open Firefox session created by Open_PowerBi_patched.py (via powerbi_session.json),
loads the Inventory Detail paginated report, switches into the paginated-reports iframe, sets:

  Store Type = Dealership
  As Of      = Current Date
  Category   = Footwear (multi-select: turns off Any, turns on Footwear)
  Store No   = 614-WALDORF, MD
  Bucket     = On hand

Then:
  - Clicks View report (if needed)
  - Clicks Export -> Comma Separated Values (.csv)
  - Waits for the download to complete (monitors download folder)
  - Moves/renames it into the CURRENT WORKING DIRECTORY as: yyyymmdd_On_Hand_Footwear.csv

Env (optional)
--------------
POWERBI_SESSION_FILE=/full/path/to/powerbi_session.json
POWERBI_DOWNLOAD_DIR=/full/path/to/downloads

Debug (optional)
--------------
If the script cannot find/click the Export (or Download) button, set:

  POWERBI_DEBUG_EXPORT=1

It will save:
  export_debug/export_debug_default.png
  export_debug/export_debug_default.json
  export_debug/export_debug_frame.png
  export_debug/export_debug_frame.json

Send me those JSON contents (or paste the console output) and I can lock the selector.

Requires
--------
pip install selenium
)annotationsN)datetime)Path)IterableOptionalTuple)urlparse)	webdriver)By)Keys)ActionChains)	WebDriver)Options)WebDriverWait)expected_conditionszhttps://app.powerbi.com/groups/me/apps/e65cf9b1-6444-4b63-8a86-b94e47839c83/rdlreports/c98f4a29-f532-4bf7-929d-4328ef57a6c2?experience=power-bi
DealershipPOWERBI_AS_OF_VALUEzCurrent Datez614-WALDORF, MDzOn handFootwearzconfig/powerbi_session.jsonpaginated-reports.powerbi.comc                    V ^8  d   QhRRRR/# )   msgstrreturnNone )formats   "aC:\Users\jasti\Documents\My_Sync\Shared\61_RW_Site\Pulled_Info\Inventory\Pull_On_Hand_Footwear.py__annotate__r   _   s      C D     c                    \         P                  P                  RR4      P                  4       P	                  4       R9   d   \        V 4       R# R# )z0Verbose logging controlled by POWERBI_VERBOSE=1.POWERBI_VERBOSE N1trueyesyon)osenvirongetstriplowerprint)r   s   &r   _vr/   _   s:    	zz~~',224::<@__c
 `r   c                    V ^8  d   QhRRRR/# )r   startr   r   zIterable[Path]r   )r   s   "r   r   r   i   s       . r   c              #  d   "   V P                  4       pVx  VP                   F  pVx  K	  	  R # 5iN)resolveparents)r1   pparents   &  r   _walk_parentsr8   i   s(     A
G)) s   .0c                   V ^8  d   QhRR/# )r   r   z
list[Path]r   )r   s   "r   r   r   p   s      * r   c                 >   . p \         P                  P                  R R4      P                  4       pV'       d7   V P	                  \        V4      P                  4       P                  4       4       V P	                  \
        P                  ! 4       P                  4       \        ,          4       V P	                  \        \        4      P                  4       P                  \        ,          4       V P	                  \
        P                  ! 4       P                  4       R,          \        ,          4       V P	                  \        \        4      P                  4       P                  R,          \        ,          4       \        \
        P                  ! 4       4       FB  pV P	                  V\        ,          4       V P	                  VR,          \        ,          4       KD  	  \        \        \        4      P                  4       P                  4       FB  pV P	                  V\        ,          4       V P	                  VR,          \        ,          4       KD  	  \        4       p. pV  F8  p\        V4      pWc9  g   K  VP                  V4       VP	                  V4       K:  	  V# )POWERBI_SESSION_FILEr"   Powerbi_Background)r)   r*   r+   r,   appendr   
expanduserr4   cwdSESSION_FILENAME__file__r7   r8   setr   add)
candidatesoverridebaseseenoutcss          r   _candidate_session_pathsrK   p   s   Jzz~~4b9??AH$x.335==?@dhhj((*-==>d8n,,.558HHIdhhj((*-AADTTUd8n,,.558LLO__`dhhj)$!112$!558HHI * d8n446==>$!112$!558HHI ? 5DCF=HHQKJJqM	 
 Jr   c                   V ^8  d   QhRR/# )r   r   r   r   )r   s   "r   r   r      s     3 3D 3r   c                     \        4        F  p V P                  4       '       g   K  V u # 	  \        P                  ! 4       P	                  4       \
        ,          # r3   )rK   existsr   r?   r4   r@   r6   s    r   _pick_session_filerP      s<    %'88::H ( 88:"222r   c                    V ^8  d   QhRRRR/# )r   pathr   r   zTuple[str, str, Optional[str]]r   )r   s   "r   r   r      s     2 2T 2&D 2r   c           	     v   V P                  4       '       g   \        4       pR R.pY!R,           Uu. uF  pRV 2NK
  	  up,          p\        V4      ^8  d&   VP                  R\        V4      ^,
           R24       V. RO,          p\	        RP                  V4      4      h\        P                  ! V P                  RR7      4      pVP                  R	4      pVP                  R
4      pVP                  R4      pV'       d	   V'       g)   \        RV  R\        VP                  4       4       24      hWVV3# u upi )zSession file not found.z	Searched:N   Nz  - z
  ... and z more
utf-8encodingexecutor_url
session_iddownload_dirzBad session file z keys=)r"   zFix:z7  - Run from folder containing powerbi_session.json, ORzB  - export POWERBI_SESSION_FILE=/full/path/to/powerbi_session.json)rN   rK   lenr=   FileNotFoundErrorjoinjsonloads	read_textr+   
ValueErrorlistkeys)rR   searchedr   r6   datarZ   r[   r\   s   &       r   _load_session_filerh      s   ;;==+-(+6SM2Mq$qc
M22x=2JJCMB$6#7u=> 
 	
  		#//::dnngn67D88N+L,'J88N+Lz,TF&diik9J8KLMM\11# 3s   D6c               $    V ^8  d   QhRRRRRR/# )r   rZ   r   r[   r   RemoteWebDriverr   )r   s   "r   r   r      s!      C S _ r   c                  aa \         P                  oRVV3R llpV\         n         \        4       p \        P                  ! WR7      pSTn        S\         n        TP                  pT#   \
         dF     \        P                  ! T R7      p LE  \
         d    \        P                  ! T / R7      p  Lki ; ii ; i  S\         n        i ; i)Nc                4   < VR 8X  d	   RR/ /RS/# S! WV4      # )
newSessionvaluecapabilities	sessionIdr   )selfcommandparamsoriginal_executer[   s   &&&r   _patched_execute+attach_to_session.<locals>._patched_execute   s,    l"nb1;
KKv66r   )command_executoroptions)rw   )rw   desired_capabilitiesr3   )rj   executeFirefoxOptionsr	   Remote	TypeErrorr[   current_url)rZ   r[   ru   rx   driver_rt   s   &f    @r   attach_to_sessionr      s    &..7 7
 /O3 "	b%%|UF '"2AM  	bb"))<H b"))<^`ab	b #3sL   
B= A* 
B= *B:6BB= #B62B:3B= 5B66B::B= =C
c               $    V ^8  d   QhRRRRRR/# )r   ar   br   boolr   )r   s   "r   r   r      s!      c c d r   c                     \        V 4      p\        V4      pVP                  VP                  VP                  3VP                  VP                  VP                  38H  #   \         d     R # i ; iF)r   schemenetlocrR   	Exception)r   r   papbs   &&  r   _url_same_pager      s\    a[a[		299bgg.299bii2QQQ s   AA A.-A.c                   V ^8  d   QhRR/# r   r   rj   r   )r   s   "r   r   r      s      / r   c                $   \          Uu. uF	  pR V R2NK  	  ppVP                  R4       VP                  R4       V F7  p V P                  \        P                  V4      pV'       d   V^ ,          u # K9  	  R# u upi   \
         d     KP  i ; i)ziframe[src*='']ziframe[name*='rdl' i]ziframe[id*='rdl' i]N)IFRAME_SRC_HINTSr=   find_elementsr
   CSS_SELECTORr   )r   h	selectorsselframess   &    r   %_find_report_frame_in_current_contextr      s    0@A0@1=2&0@IA,-*+	))"//3?Fay     B  		s   A;0B  BBc                   V ^8  d   QhRR/# r   r   )r   s   "r   r   r      s     ! !o !r   c                    V P                   P                  4        \        V 4      pVe   V P                   P	                  V4       R#  V P                  \        P                  R4      pVR,           Ff  p V P                   P                  4        V P                   P	                  V4       \        V 4      pVe   V P                   P	                  V4        R# Kh  	   V P                   P                  4        R#   \         d     Li ; i  \         d    . p Li ; i  \         d     K  i ; i  \         d     R# i ; i)zAFind report iframe from default content or one nested level down.TiframerT   F)	switch_todefault_contentr   r   framer   r
   r   )r   r   outer_framesouterinners   &    r   !_switch_to_report_iframe_anywherer      s6   ((* 2&9Eu%++BOOXF c""	,,.""5)9&AE   &&u- ! #((* ;      		
  sH   C9 	 D
 6ADD/ 9DD
DDD,+D,/D>=D>c               $    V ^8  d   QhRRRRRR/# r   r   rj   timeoutintr   r   r   )r   s   "r   r   r     s'     B B B3 BRV Br   c                   a
 \         pR p V P                  pV FJ  p V P                  P	                  V4       V P
                  ;'       g    Rp\        Wb4      '       d   Rp MKL  	  V'       g   V P                  V4       \        P                  ! 4       V,           pRo
\        P                  ! 4       V8  d    V P
                  ;'       g    Ro
\        ;QJ d    V
3R lR 4       F  '       g   K   RM	  R M! V
3R lR 4       4      '       d   \        RS
 R24      h V P                  R4      pVR9   d/   \        V 4      '       d    V P                  P                  4        R# \        P                  ! R4       K  Rp	 V P                  p	\!        R	S
: R
V	: 24      h  \         d    . p ELi ; i  \         d     EK  i ; i  \         d    Ro
 ELi ; i  \         d    Rp Li ; i  \         d     R# i ; i  \         d     Li ; i)Fr"   Tc              3  .   <"   T F
  pVS9   x  K  	  R # 5ir3   r   ).0r   last_urls   & r   	<genexpr>'ensure_report_loaded.<locals>.<genexpr>'  s       
 Ms   z2Power BI session is not authenticated. Landed on: z-. Re-run Open_PowerBi and complete login/MFA.zreturn document.readyStateNffffff?zATimed out waiting for paginated report iframe to load. Last URL: z	; title: )zlogin.microsoftonline.comaadcdnmicrosoftonline)interactivecomplete)TARGET_REPORT_URLwindow_handlesr   r   windowr~   r   r+   timeanyRuntimeErrorexecute_scriptr   r   sleeptitleTimeoutError)r   r   desiredfoundhandlesr   curdeadlinereadyr   r   s   &&        @r   ensure_report_loadedr     s   GE'' 	##A&$$**Cc++ ,	  

7yy{W$HH
))+
 	))//RH
 3 

333 

 
 
 DXJ O> > 
	))*FGE //088$$446 

4E 	L	%	4 s    		  	H	&  	E	 !   sv   F -F3F39G G G 	G-  G? F0/F03GGGGG*)G*-G<;G<?HHc               $    V ^8  d   QhRRRRRR/# r   r   )r   s   "r   r   r   M  s'     Z Zo Z Zae Zr   c                    \        W4      pVP                  R  4      pV'       g   \        R4      hVP                  R 4       R# )c                    \        V 4      # r3   )r   ds   &r   <lambda>3switch_to_paginated_report_iframe.<locals>.<lambda>O  s
    ?Br   z,Could not switch to paginated report iframe.c                Z    \        V P                  \        P                  R 4      4      ^ 8  # )z//input[@role='combobox'])r]   r   r
   XPATHr   s   &r   r   r   R  s    Q__RXX7RSTWXXr   N)r   untilr   )r   r   waitoks   &&  r   !switch_to_paginated_report_iframer   M  s7    )D	B	CBIJJJJXYr   c                    V ^8  d   QhRRRR/# r   r   rj   r   r   r   )r   s   "r   r   r   Y  s      o 4 r   c                P     V P                  R V4       R#   \         d     R# i ; i)z@arguments[0].scrollIntoView({block:'center', inline:'nearest'});N)r   r   r   elements   &&r   _scroll_into_viewr   Y  s+    `bij s    %%c                    V ^8  d   QhRRRR/# r   r   )r   s   "r   r   r   `  s       T r   c                `   \        W4        VP                  4        R #   \         d     Mi ; i \        T 4      P	                  T4      P                  R4      P                  4       P                  4        R #   \         d     Mi ; i T P                  RT4       R #   \         d     R # i ; i)N皙?zarguments[0].click();)r   clickr   r   move_to_elementpauseperformr   r   s   &&r   _safe_clickr   `  s    f& V,,W5;;DAGGIQQS 5w? s0    --AA8 8BB
B B-,B-c                    V ^8  d   QhRRRR/# )r   r   r   r   r   r   )r   s   "r   r   r   r  s     : :C :D :r   c                h   \         P                   ! 4       V,           p\         P                   ! 4       V8  db    V P                  R 4      pV P                  R4      pVe   VR8X  d   Ve   VP                  4       R8X  d   R# \         P                  ! R4       K{  \        R4      h  \         d     L0i ; i)disabledaria-disabledNr"   false333333?zField stayed disabled too long.)r   get_attributer-   r   r   r   )r   r   enddisaria_diss   &&   r   _wait_enabledr   r  s    
))+
C
))+
	''
3C,,_=Hsbyx/?8>>CSW^C^ 	

4
8
99  		s   AB# #B10B1c                   V ^8  d   QhRR/# )r   r   r   r   )r   s   "r   r   r     s      3 r   c                z     V P                  R 4      ;'       g    RP                  4       #   \         d     R# i ; i)rn   r"   )r   r,   r   )inps   &r   _visible_valuer     s;    !!'*00b7799 s   + + ::c                    V ^8  d   QhRRRR/# )r   r   rj   labelr   r   )r   s   "r   r   r     s     L L L Lr   c           
        R RRRRRRRRR	/pW9   d8   V P                  \        P                  W!,          4      pV'       d
   V^ ,          # R
\        P                  ! V4       R2pV P                  \        P
                  V4      pV'       d
   V^ ,          # R\        P                  ! V4       R2pV P                  \        P
                  V4      pV'       d
   V^ ,          # \        RV 24      h)
Store TypezStoreType-inputAs Ofz
AsOf-inputCategoryzCategory-inputStore NozStoreNo-inputBucketzBucket-inputz)//input[@role='combobox' and @aria-label=]z3//input[@role='combobox' and contains(@aria-label, z)]z)Could not find combobox input for label: )r   r
   IDr`   dumpsr   r   )r   r   id_mapelsxpxp2s   &&    r   _find_combobox_inputr     s    '$O.F ""255&-8q6M4TZZ5F4Gq	IB


rxx
,C
1v?

5@Q?RRT
UC


rxx
-C
1v
B5'J
KKr   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   r     s      ? r   c                    V P                  \        P                  R 4      pV'       d
   V^ ,          # V P                  \        P                  R4      pV'       d
   V^ ,          # R# )z<//div[@role='listbox' and @aria-labelledby='Category-label']zD//div[@role='listbox' and .//*[@id[starts-with(.,'Category-list')]]]N)r   r
   r   )r   boxess   & r   _find_category_listboxr    sK      +ijEQx  +qrEQxr   c               (    V ^8  d   QhRRRRRRRR/# )	r   r   rj   r   r   triesr   r   r   r   )r   s   "r   r   r     s)      ? 3 C PT r   c                    \        V4       F  p V P                  \        P                  R V R24      p\	        W4       \        P                  ! R4        VP                  \        P                  4       \        P                  ! R4       V P                  \        P                  R4      '       d    R# VR8X  g   K  \        V 4      f   K   R# 	  R#   \
         d    \	        Y4        Li ; i  \
         d     Li ; i)z[aria-label='Open r   皙?r   //*[@role='option']Nr   )rangefind_elementr
   r   r   r   r   r   	send_keysr   
ARROW_DOWNr   r   r  )r   r   r   r  r   exps   &&&&  r   _open_dropdownr    s    5\	%%%boo9KE7RT7UVC$ 	

4	MM$//* 	

4*?@@J#9&#A#M%   	%$	%  		s#   /CC/C,+C,/C=<C=c                    V ^8  d   QhRRRR/# )r   r   rj   rn   r   r   )r   s   "r   r   r     s      ? 3 r   c                   VP                  4       pV P                  \        P                  R 4      pV F  p VP	                  4       '       g   K   TP                  ;'       g    RP                  4       ;'       g*    TP                  R4      ;'       g    RP                  4       pTP                  4       T8X  g   K  Tu # 	  V Fp  pVP                  ;'       g    RP                  4       ;'       g*    VP                  R4      ;'       g    RP                  4       pW%P                  4       9   g   Kn  Vu # 	  R#   \
         d     EK  i ; i)r  r"   r   N)	r-   r   r
   r   is_displayedr   textr,   r   )r   rn   lowoptsoptts   &&    r   _find_option_clickabler    s   
++-C*?@D	##%% & XX^^""$RR):):7)C)I)Ir(P(P(R779J  XX^^""$RR):):7)C)I)Ir(P(P(R'')J    		s   D::E
	E
c               (    V ^8  d   QhRRRRRRRR/# )r   r   rj   r   r   rn   r   r   r   )r   s   "r   r   r     s.     .S .S .S .SC .SD .Sr   c                   \        W4      p\        V4       \        W4       \        V4      P	                  4       VP	                  4       8X  d   \        V R V R24       R# \        WV4       \        W4        VP                  \        P                  R4       VP                  V4       \        P                  ! R4       \        W4      pVe   \        W4       M? VP                  \        P                  4       VP                  \        P                   4        VP                  \        P"                  4       \        P                  ! 4       \$        ,           pRp\        P                  ! 4       V8  d   \        V4      pVP	                  4       VP	                  4       8X  d   \        V R V R24       R# VP	                  4       VP	                  4       9   d   \        V R V R24       R# \        P                  ! R4       K  \'        V RV RV: 24      h  \         d     ELi ; i  \         d     ELi ; i  \         d     ELi ; i)	z
: set to ''.Nr   g?r"   r  z: did not become 'z'. Last value: )r   r   r   r   r-   r.   r  r   r	  r   CONTROLr   r   r   r  r
  ENTERTABFIELD_TIMEOUTr   )r   r   rn   r   r  r   lasts   &&&    r   set_single_comboboxr    s   
v
-C#f"c  "ekkm3z%+,6#&dllC( MM%JJt
 
/C
F 	MM$//*MM$**%dhh ))+
%CD
))+
c"::<5;;=(UG:eWB/0;;=DJJL(UG:dV2./

3
% 25'Q
RRA    		
  s6   9 H >H+ H= H('H(+H:9H:=IIc                   V ^8  d   QhRR/# )r   r   rd   r   )r   s   "r   r   r   	  s      t r   c                j     V P                  \        P                  R 4      #   \         d    . u # i ; i)z.//*[@role='menuitemcheckbox'])r   r
   r   r   )listboxs   &r   _listbox_itemsr"  	  s3    $$RXX/OPP 	s   " 22c                   V ^8  d   QhRR/# )r   
label_textr   r   )r   s   "r   r   r     s     	 	 	r   c                   VP                  4       P                  4       p\        V 4       F@  p VP                  ;'       g    R P                  4       P                  4       pWB8X  g   K>  Vu # 	  R#   \         d    R p Li ; i)r"   N)r,   r-   r"  r  r   )r!  r$  targetittxts   &&   r   _find_menuitemcheckboxr)    su    %%'FW%	77==b'')//1C =I & 	  	C	s   A0A00B ?B c                   V ^8  d   QhRR/# )r   r   zOptional[bool]r   )r   s   "r   r   r     s       r   c                     V P                  R 4      ;'       g    RP                  4       pVR9   d   VR8H  #  R#   \         d     R# i ; i)zaria-checkedr"   r%   N)r%   r   )r   r-   r   )elvs   & r   _aria_checkedr.    s\    n-33::<!!; "   s   : : A	A	c          
     ,    V ^8  d   QhRRRRRRRRRR	/# )
r   r   rj   r$  r   r   r   allow_missingr   r   r   )r   s   "r   r   r   &  s=     $\ $\/ $\ $\VZ $\ko $\  }A $\r   c                   \         P                   ! 4       \        ,           p. p\         P                   ! 4       V8  d   \        W4      pVfo   \        V 4      pVe   Tp\	        V4       U	u. uF&  qP
                  ;'       g    RP                  4       NK(  	  pp	V'       d   R # \         P                  ! R4       K  \        V4      p
W8X  d   R # \        W4       \         P                  ! R4       \        V 4      pVe   Tp\        W4      pVf   K  \        V4      pW8X  g   EK  R # V'       d   R # V Uu. uF  q'       g   K  VNK  	  upR,          p\        RV RV RV 24      hu up	i u upi )Nr"   r  g      ?N   NzCould not set 'z' to z. Items seen: )r   r  r)  r  r"  r  r,   r   r.  r   r   )r   r!  r$  r   r0  r   
last_itemsitemlb2r'  r   item2cur2rJ   previews   &&&&&          r   _set_menuitemcheckboxr:  &  s4   
))+
%CJ
))+
%g:<(0C<J7<ST<Sb77==b//1<SJTJJsOD!>F!

4$V,?G&w;=U#?$**Qqq**3/G
E'.QXPYZ
[[7 U4 +s   *E&E&4	E+E+c                    V ^8  d   QhRRRR/# r   r   )r   s   "r   r   r   M  s     $a $a/ $ad $ar   c           	     ,   R p\        W4      p\        V4       \        W4       \        WV4       \	        V \
        4      pVP                  R 4      pVf   \        R4      h\         F  p\        WVRRR7       K  	  \        W\        RRR7        VP                  \        P                  4        VP                  \        P                  4       \         P                   ! 4       \
        ,           pRp\         P                   ! 4       V8  dZ   \#        V4      pVP%                  4       pRV9   d    R	V9  d   R
V9  d   \'        RV R24       R# \         P(                  ! R4       Ks  \        RV: 24      h  \         d     Li ; i  \         d     Li ; i)r   c                    \        V 4      # r3   )r  r   s   &r   r   /set_category_to_footwear_only.<locals>.<lambda>V  s
    #9!#<r   Nz Category listbox did not appear.FT)r0  r"   footwearr   accesszCategory: set to 'r  r  z=Category: did not settle to Footwear-only. Final field text: )r   r   r   r  r   r  r   r   CATEGORY_OFFr:  CATEGORY_ONr	  r   ESCAPEr   r  r   r   r-   r.   r   )	r   r   r   r   r!  offr   r  r  s	   &        r   set_category_to_footwear_onlyrE  M  sS   E
v
-C#f"6#&/Djj<=G=>>fsEN &;ERdkk"dhh ))+
%CD
))+
c"jjl#E$483;N&tfB/0

3
VW[V^_
``#    s$   E4 1F 4FFFFc                    V ^8  d   QhRRRR/# r   r   )r   s   "r   r   r   x  s       T r   c                l   \        V ^4      p\        P                  R3\        P                  R3\        P                  R3\        P                  R33 FK  p VP	                  \
        P                  ! V4      4      p\        W4       \        P                  ! R4        R# 	  R#   \         d     K_  i ; i)   z)//button[normalize-space()='View report']z2//button[.//span[normalize-space()='View report']]zbutton[title='View report']z button[aria-label='View report']g      ?N)r   r
   r   r   r   ECelement_to_be_clickabler   r   r   r   )r   r   locbtns   &   r   click_view_report_if_presentrM  x  s    #D	>?	GH	78	<=		**R77<=C$JJsO  		s   AB$$B32B3c                   V ^8  d   QhRR/# r   r   r   r   )r   s   "r   r   r     s     " " "r   c                <    V P                  4       '       g   R#   T P                  R4      pTe
   TR8w  d   R#  T P                  R4      ;'       g    RP                  4       P	                  4       pTR8X  d   R#   T P
                  ;'       g    / pTP                  R4      ;'       g    ^ ^ 8:  g!   TP                  R4      ;'       g    ^ ^ 8:  d   R#  R#   \         d     R# i ; i  \         d     Li ; i  \         d     Li ; i  \         d     R# i ; i)	zBest-effort check that an element is *the* visible, usable instance.

Power BI often renders duplicate command bar buttons (hidden/overflow variants).
If we click a hidden clone, nothing happens (even with JS click).
Fr   r"   r   r%   widthheightT)r  r   r   r,   r-   rectr+   )r,  r   r   rs   &   r   _element_interactablerU    s      !
z*?sby$$_5;;BBDJJLv 
GGMMrEE'NaA%!%%/*>*>Q1)D *E 3        s]   C C* C; &C; =D D +D D C'&C'*C87C8;D	D	DDc                   V ^8  d   QhRR/# r   r   )r   s   "r   r   r     s     	 	 	r   c                    Vw  r# V P                  W#4      pT F  p\        T4      '       g   K  Tu # 	  R #   \         d     R # i ; ir3   )r   r   rU  )r   rK  byr   r   r,  s   &&    r   _first_interactablerY    sS    GB""2+  $$I    s   7 AAc                    V ^8  d   QhRRRR/# )r   r   rj   r   r   r   )r   s   "r   r   r     s     #A #A? #AS #Ar   c           	       a \        W4      p\        P                  R 3\        P                  R3\        P                  R3\        P                  R3\        P                  R3\        P                  R3\        P                  R3\        P                  R33pV F/  o VP	                  V3R l4      pVe   \        R	S 24       Vu # K1  	  V F?  o VP	                  \        P                  ! S4      4      pVe   \        R
S 24       Vu # KA  	  \        R4      h  \         d     K  i ; i  \         d     Kn  i ; i)zVbutton[data-testid='toolbar-export-dropdown'], [data-testid='toolbar-export-dropdown']z\button[data-testid='trident-export-menu-button'], [data-testid='trident-export-menu-button']zZbutton[data-testid='toolbar-download-dropdown'], [data-testid='toolbar-download-dropdown']z`button[data-testid='trident-download-menu-button'], [data-testid='trident-download-menu-button']z//*[@data-testid='toolbar-export-dropdown' or @data-testid='trident-export-menu-button' or @data-testid='toolbar-download-dropdown' or @data-testid='trident-download-menu-button']zI//*[self::button or @role='button'][@title='Export' or @title='Download']z//*[self::button or @role='button'][contains(translate(@aria-label,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'),'export') or contains(translate(@aria-label,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'),'download')]z//*[self::button or @role='button'][normalize-space()='Export' or normalize-space()='Download' or .//span[normalize-space()='Export' or normalize-space()='Download']]c                   < \        V S4      # r3   rY  r   rK  s   &r   r   (wait_for_export_button.<locals>.<lambda>  s    &9!S&Ar   z1[export] picked interactable export/download via z6[export] fell back to presence_of_element_located via z&Export/Download button did not appear.)
r   r
   r   r   r   r/   r   rI  presence_of_element_locatedr   )r   r   r   locatorsr,  rK  s   &&   @r   wait_for_export_buttonrb    sM   )D
 
rs	xy	vw	|}	  I  	J	^_	  G  	H	  |  	}	H 	ABB~FseLM	   	B::3?@B~KC5QR	   ?
@@  		  		s$   (D8D.D+*D+.D=<D=c                    V ^8  d   QhRRRR/# )r   r   rj   r   z	list[str]r   )r   s   "r   r   r     s      ? y r   c                   V P                  \        P                  R 4      p. pV FC  p VP                  ;'       g    RP	                  4       pV'       d   VP                  V4       KC  KE  	  \        4       p. pV F-  pWu9  g   K  VP                  V4       VP                  V4       K/  	  VR,          #   \         d     K  i ; i)z//*[@role='menuitem' or @role='option' or @role='menuitemcheckbox']//*[self::span or self::div or self::button]|//*[@role='menuitem' or @role='option' or @role='menuitemcheckbox']r"   r2  )	r   r
   r   r  r,   r=   r   rB   rC   )r   itemsrH   r'  r(  rG   uniqr  s   &       r   _dump_export_menu_textrg    s        ,a  bEC	77==b'')C

3   5DD=HHQKKKN  9  		s   B4B4B44CCc                   V ^8  d   QhRR/# rO  r   )r   s   "r   r   r     s     0 0t 0r   c                     \         P                  P                  R R4      P                  4       P	                  4       p V R9   # )POWERBI_DEBUG_EXPORTr"   r#   )r)   r*   r+   r,   r-   )r-  s    r   _debug_export_enabledrk    s5    


-r288:@@BA///r   c                   V ^8  d   QhRR/# r   r   )r   s   "r   r   r     s     =C =C/ =Cr   c           	     |    Rp V P                  V4      #   \         d   pR. R. R\        T4      /u Rp?# Rp?ii ; i)zCollect potentially relevant clickable elements in the *current browsing context*.

This runs inside whatever frame you're currently in.
u  
        const kw = /export|download|csv/i;
        const nodes = Array.from(document.querySelectorAll(
          'button, [role="button"], [role="menuitem"], [role="option"], [data-testid], a'
        ));

        function t(v){ return (v || '').toString().trim(); }
        function trunc(s, n){ s = t(s); return s.length > n ? (s.slice(0, n) + '…') : s; }

        const out = [];
        for (const e of nodes) {
          try {
            const text = trunc(e.innerText || e.textContent || '', 140);
            const aria = trunc(e.getAttribute('aria-label') || '', 140);
            const title = trunc(e.getAttribute('title') || '', 140);
            const dt = trunc(e.getAttribute('data-testid') || '', 140);
            const role = t(e.getAttribute('role') || '');
            const hay = (text + ' ' + aria + ' ' + title + ' ' + dt).trim();
            if (!kw.test(hay)) continue;

            const cs = window.getComputedStyle(e);
            const rect = e.getBoundingClientRect();
            const vis = cs && cs.display !== 'none' && cs.visibility !== 'hidden' && rect.width > 0 && rect.height > 0;

            out.push({
              tag: e.tagName,
              id: t(e.id),
              className: trunc(e.className || '', 180),
              role,
              text,
              ariaLabel: aria,
              title,
              dataTestid: dt,
              disabled: !!e.disabled,
              ariaDisabled: t(e.getAttribute('aria-disabled')),
              href: trunc(e.getAttribute('href') || '', 200),
              visible: vis,
              rect: { x: rect.x, y: rect.y, w: rect.width, h: rect.height },
            });
          } catch (err) {
            // ignore
          }
        }

        const iframes = Array.from(document.querySelectorAll('iframe')).map(f => ({
          id: t(f.id),
          name: t(f.name),
          className: trunc(f.className || '', 180),
          src: trunc(f.getAttribute('src') || '', 240)
        }));

        return { candidates: out.slice(0, 200), iframes };
    rD   iframeserrorN)r   r   repr)r   jses   &  r   _js_collect_exportishrs    sJ    
4
BjC$$R(( Cb)R$q'BBCs    ;6;;c               $    V ^8  d   QhRRRRRR/# )r   r   rj   r   r   r   r   r   )r   s   "r   r   r   ;  s!     < <o <c <d <r   c                   \         P                  ! 4       P                  4       R,          pVP                  RRR7        VRV R2,          pV P	                  \        V4      4       \        RV 24       R
VR\        V RR4      RRR/ /p V P                  VR&   \        V 4      VR&    VRV R2,          pVP                  \        P                  ! V^R7      RR7       \        RV 24       R	#   \         d   p\        RT RT 24        R	p?LR	p?ii ; i  \         d     Li ; i  \         d   p\        RT RT 24        R	p?R	# R	p?ii ; i)zSSave screenshot + JSON of export/download/csv-related UI elements for this context.export_debugTr5   exist_okexport_debug_z.pngzExport debug screenshot: z(debug) screenshot failed in z: Nr   urlr~   r"   r   	collectedz.json)indentrW   rX   zExport debug JSON: z(debug) json write failed in )r   r?   r4   mkdirsave_screenshotr   r.   r   getattrr   rs  
write_textr`   r   )r   r   out_dirpngrr  payloadjsns   &&     r   dump_export_debugr  ;  sZ   hhj  "^3GMM$M.<-wd33s3x()#/0
 	wv}b1R	G!<< 18GK<-we44tzz'!4wG#C5)*%  <-eWBqc:;;<    <-eWBqc:;;<sB   5C. 
D (AD( .D9DDD%$D%(E3E

Ec               $    V ^8  d   QhRRRRRR/# r   r   rj   r   r   r   r   r   )r   s   "r   r   r   [  s'     L L? LS LY] Lr   c                  a \        W4      p\        P                  R3\        P                  R3\        P                  R33pV EF  o VP	                  V3R l4      pVf   K    \        W4        V P                  RV4        \        V 4      P                  V4      P                  R4      P                  4       P                  4        \        P                  ! R4        TP                  \         P"                  4       \        P                  ! R	4       TP                  \         P$                  4        \+        T \-        ^\/        T^,          4      4      R7        R# 	  R#   \
         d    Rp ELi ; i  \
         d     ELi ; i  \
         d     ELi ; i  \
         d'     TP                  4         L  \
         d      Li ; ii ; i  \
         Ed      \        T 4      P                  \         P"                  4      P                  R	4      P                  \         P$                  4      P                  4         EL  \
         d     T P'                  \        P(                  R
4      P                  \         P"                  4       \        P                  ! R	4       T P'                  \        P(                  R
4      P                  \         P$                  4         EL  \
         d       ELi ; ii ; ii ; i  \
         dx     \        T 4      P                  \         P$                  4      P                  4        \+        T \-        ^\/        T^,          4      4      R7         R#   \
         d      EK6  i ; ii ; i)a  Fallback: focus the *File* button, press Right Arrow to move to Export, then press Enter.

Why this exists:
  - Power BI/Fluent UI command bars often render *duplicate* Export buttons (hidden/overflow variants).
  - Selenium may click a hidden clone successfully (no exception) but nothing opens.
  - Keyboard navigation on the command bar is frequently more reliable.

Returns True if a menu overlay appears after attempting the key sequence.
zPbutton[title='File'], button[aria-label='File'], [role='menuitem'][title='File']z//*[self::button or @role='menuitem' or @role='button'][@title='File' or normalize-space()='File' or .//span[normalize-space()='File']]z//*[self::button or @role='menuitem' or @role='button'][contains(translate(@aria-label,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'),'file')]c                0   < \        V S4      ;'       g    R # r3   r]  r^  s   &r   r   8_open_export_menu_via_file_right_arrow.<locals>.<lambda>o  s    ,?3,G,O,O4,Or   Nzarguments[0].focus();r   gQ?r   bodyr   TF)r   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r	  r   ARROW_RIGHTr  r  TAG_NAME_wait_for_export_menumaxr   )r   r   r   	file_locsfile_btnrK  s   &&   @r   &_open_export_menu_via_file_right_arrowr  [  s    )D 
lm	  ]  	^	  p  	qI 	zz"OPH 	f/
	!!"98D	 00:@@FLLNVVX 	

4	t//0JJttzz*		!&#aWq[9I2JKc t o  	H	  		  		
  	  	  		V$..t/?/?@FFtLVVW[WaWabjjl ''V<FFtGWGWXJJt$''V<FFtzzRR  		  	V$..tzz:BBD%fc!S1=M6NO 	s   	E#%E71F	AF AG5'K=#E43E47FF	FFG'F99GGGGK:A"IK6BK!K:!K2	,K6-K:1K2	2K66K:=M?	AM**M;5M?:M;;M?c               $    V ^8  d   QhRRRRRR/# r   r   )r   s   "r   r   r     s!      / C D r   c                (   \        W4      p\        P                  R3\        P                  R3\        P                  R3\        P                  R33 F*  p VP	                  \
        P                  ! V4      4        R# 	  R#   \         d     K>  i ; i)z4Wait for the Export/Download menu overlay to appear.zul.ms-ContextualMenu-listzdiv.ms-ContextualMenuz//*[@role='menu']z'//ul[contains(@class,'ContextualMenu')]N)r   r
   r   r   r   rI  r`  r   )r   r   r   rK  s   &&  r   r  r    s    )D	56	12	&'	<=		JJr55c:;  		s   %BBBc               $    V ^8  d   QhRRRRRR/# r  r   )r   s   "r   r   r     s!     + +_ +s +D +r   c                   \        W4      p\        P                  R3.p\        P                  R3\        P                  R3\        P                  R3\        P                  R3\        P                  R3\        P                  R3.pV FT  p VP	                  \
        P                  ! V4      4      pVe(   \        RV 24       \        W4       \        R	4        R
# KV  	  V FT  p VP	                  \
        P                  ! V4      4      pVe(   \        RV 24       \        W4       \        R	4        R
# KV  	  R#   \         d     K  i ; i  \         d     Kz  i ; i)zJAssumes the export menu is already open in the *current browsing context*.zDbutton[data-testid='export-csv-btn'], [data-testid='export-csv-btn']z"//*[@data-testid='export-csv-btn']z//span[contains(translate(normalize-space(.), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'), 'comma separated values')]/ancestor::button[1]z//li[contains(translate(@title,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'), 'comma separated values')]/descendant::button[1]zy//button[contains(translate(@title,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'), 'comma separated values')]z//*[self::button or @role='menuitem' or @role='option'][contains(translate(normalize-space(.), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'), 'comma separated values')]z//*[self::button or @role='menuitem' or @role='option'][contains(translate(normalize-space(.), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'), '.csv')]z[export] clicking CSV via Export: clicked CSV option.TF)r   r
   r   r   r   rI  r`  r/   r   r.   r   )r   r   r   css_locsxp_locsrK  r,  s   &&     r   _try_click_csv_menu_itemr    ss   )D 
`aH 
78	  n  	o	  a  	b	  O  	P	 S 	T	 A 	B	G 	B::3?@B~/u56F'34	   	B::3?@B~/u56F'34	     		  		s&   AD='AE=EEEEc               (    V ^8  d   QhRRRRRRRR/# )r   r   rj   button_timeoutr   menu_timeoutr   r   r   )r   s   "r   r   r     s6     u uuu u 
	ur   c                6    \        R\        V RR4       24       \        R4       Rp \	        WR7      p\        R4       \        R4       \        W4       R	pT'       g   \        R4       R# \        P                  ! R4       \        R4       \        ^\        T^,          4      4      p \        YR7       \        YR7      '       d   \        R4       R	#  T P                  P!                  4         \        YR7       \        YR7      '       d   \        R4       R	#   T P                  P!                  4        T P#                  \$        P&                  R4      p\)        TR,          4       F  w  r T P                  P+                  T
4       \        T ^R7      '       d9   \        RT	 24       \        R4         T P                  P!                  4         R	#   T P                  P!                  4        K  	  R#   \         d     ELi ; i  \         d   p\        R
T 24       \        R4        \        T P                  R4      4      pT'       d   \        R4       \        R4        Rp?EL  \         d    p\        RT 24       Rp Rp? Rp?EL;Rp?ii ; iRp?ii ; i  \         d,     \        YR7      '       d     EL  \         d      ELi ; ii ; i  \         d%     \        YR7        EL  \         d      ELi ; ii ; i  \         d     ELi ; i  \         d      R	# i ; i  \         d     ELii ; i  \         d     EK  i ; i   T P                  P!                  4        i   \         d     i i ; i; i  \         d     R# i ; i)zTry clicking Export/Download and then the CSV item, without switching frames.

Returns True on success, False if the CSV option wasn't found/clicked.
z [export] attempt in context url=r~   r"   z/Export: searching for Export/Download button...Fr  z([export] clicking export/download buttonz#Export: clicking Export/Download...Tz<[export] export button not found/clickable in this context: z@Export: export button not found/clickable; trying JS fallback...a  
                const sel = [
                  "[data-testid='toolbar-export-dropdown']",
                  "[data-testid='trident-export-menu-button']",
                  "[data-testid='toolbar-download-dropdown']",
                  "[data-testid='trident-download-menu-button']",
                  "button[title='Export']",
                  "button[title='Download']",
                  "button[aria-label*='Export']",
                  "button[aria-label*='Download']",
                  "[role='button'][title='Export']",
                  "[role='button'][title='Download']",
                ].join(',');
                const b = document.querySelector(sel);
                if (b) { b.click(); return true; }
                return false;
                z*[export] JS-clicked export/download buttonz#Export: JS-clicked Export/Download.z#[export] JS fallback click failed: Nz7Export: could not find Export/Download in this context.r   z4Export: export menu should be open; selecting CSV...r  r   :N   Nz$[export] clicked CSV inside iframe #)r/   r  r   r.   rb  r   r   r   r   r   r  r   r  r  r  r   r   r   r
   r   	enumerater   )r   r  r  export_clicked
export_btnrr  e2per_ctx_timeoutr   idxfrs   &&&        r   &_attempt_export_csv_in_current_contextr    sO   
-gf]2.N-OPQ 

;<N##+FK

5634F'@ GHJJt	
@A!S!123Of>  @@+,((*	!&B $FDD/0 E((*%%boox@ -GC  &&r*+FA>>=cUCD78$$446 ?$$446 ." U    #
I!MNPQ	#!&"7"7# N& ?@;< 	#4RD9:"NN	#7#X  	5fVV 		"  	6vWW 		  & !   
 ! $$446   sz  G9 /H +J# L 2K >L AN	 1AL3:L N	 MM3N	 9HHJ J08I..J9J	JJJJ #K/KKKKKL(K74L 7LLL LLL LL L0+N	 /L00N	 3M>MMMMN	 MN	 NM54N5N	 NN	NN	 	NNc                    V ^8  d   QhRRRR/# r   r   )r   s   "r   r   r   `  s     ; ; ;4 ;r   c                   \        V 4      '       d   R#  V P                  \        P                  R4      pV Fn  p V P                  P                  V4       \        V ^^
R7      '       d      V P                  P                  4         R#   V P                  P                  4        Kp  	   V P                  P                  4        \        V 4      '       d   R# \        4       '       d&    \        V R4        \        V 4       \        V R4       \        V 4      p\        RV 24      h  \         d5     T P                  P                  4          R#   \         d       R# i ; ii ; i  \         d     Li ; i  \         d5     T P                  P                  4         EKk    \         d      EK{  i ; ii ; i   T P                  P                  4        i   \         d1     T P                  P                  4         i   \         d      i i ; ii ; i; i  \         d     EL}i ; i  \         d     ELti ; i  \         d     ELVi ; i  \         d     ELPi ; i)zClick Export/Download and choose CSV.

Power BI can surface the control either inside the paginated report frame *or* on the
outer (app.powerbi.com) top bar. We try both.
Nr   )r  r  defaultr   zCould not click Export/Download -> CSV. Set POWERBI_DEBUG_EXPORT=1 and rerun to generate export_debug/*.json + *.png. Seen menu items: )r  r   r
   r   r   r   parent_framer   r   rk  r  r   rg  r   )r   inner_framesr  rG   s   &   r   
export_csvr  `  s?    .f55++BOOXFB  &&r*9&QRacdd$$113 e
$$113 (((* .f55 	fi0	-f5fg. "&)D
	 6	# = ! ((88::$ 	  
 ! ((88::$ 	$$113  ((88:$ 	      		
  		s<  %H /E',D%H 	F:E8%H *H* (H< 5I %E$1EH E E$H E  E$$H 'E52F:4E55F:8F7F"H "F3-F7.H 2F33F77H :H<GHH	#G?=H?H
H	HHH	HH H'&H'*H98H9<I
IIIc                    V ^8  d   QhRRRR/# )r   session_download_dirOptional[str]r   r   r   )r   s   "r   r   r     s      }  r   c                   \         P                  P                  RR4      P                  4       pV'       d=   \	        V4      P                  4       P                  4       pVP                  RRR7       V# V '       d=   \	        V 4      P                  4       P                  4       pVP                  RRR7       V# \        P                  ! 4       R,          P                  4       pVP                  RRR7       V# )z
Where Firefox is actually downloading *right now*.
We DO NOT force it to Inventory (or anywhere). We just watch the real folder.
Priority:
  1) POWERBI_DOWNLOAD_DIR env override
  2) download_dir stored in powerbi_session.json
  3) ./downloads fallback
POWERBI_DOWNLOAD_DIRr"   Trw  	downloads)	r)   r*   r+   r,   r   r>   r4   r}  r?   )r  envr6   s   &  r   resolve_download_dirr    s     **../
4
:
:
<C
I  "**,	t,%&113;;=	t,	k	!**,AGGD4G(Hr   c                    V ^8  d   QhRRRR/# )r   r   r   r   	set[Path]r   )r   s   "r   r   r     s     3 3t 3	 3r   c                    V P                  4       '       g   \        4       # V P                  4        Uu0 uF  qP                  4       '       g   K  VkK  	  up# u upi r3   )rN   rB   iterdiris_file)r   r6   s   & r   _snapshot_filesr    s:    88::uyy{2{!iikAA{222s   AAc               (    V ^8  d   QhRRRRRRRR/# )r   r\   r   beforer  r   r   r   r   )r   s   "r   r   r     s/     !U !U !Ui !U# !Uei !Ur   c                f   \         P                   ! 4       V,           pRp\         P                   ! 4       V8  Ed]   V P                  4        Uu. uF  qUP                  4       '       g   K  VNK  	  ppV Uu. uF'  qUP                  P	                  R4      '       d   K%  VNK)  	  ppV Uu. uF  qUV9  g   K  VNK  	  ppV'       g   \         P
                  ! R4       K  VP                  R RR7       V^ ,          p	T	pW	P                  R,           ,          P                  4       '       d   \         P
                  ! R4       EK"  \        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       d   \         P
                  ! R4       EKu  V	# \        R	V 24      hu upi u upi u upi )
z_
Waits for a new fully-downloaded file to appear in download_dir.
Handles Firefox .part files.
N.partr   c                6    V P                  4       P                  # r3   )statst_mtimerO   s   &r   r   'wait_for_new_download.<locals>.<lambda>  s    qvvx00r   T)keyreversec              3  V   "   T F  qP                   P                  R 4      x  K!  	  R# 5i)r  N)nameendswith)r   r6   s   & r   r   (wait_for_new_download.<locals>.<genexpr>  s     7Avvw''s   ')Fz.Download did not complete in time. Last seen: )
r   r  r  r  r  r   sortrN   r   r   )
r\   r  r   r   	last_seenr6   files	completednewcands
   &&&       r   wait_for_new_downloadr    s>   
 ))+
CI
))+
(002B2qiik2B %F1VV__W-EQQ	F#7)Qqq)7JJt0$?1v	 II/088::JJt 3773337777JJt
G	{S
TT1 CF7s$   F$(F$4"F)F)'F.4F.c               (    V ^8  d   QhRRRRRRRR/# )r   
downloadedr   r  zOptional[Path]stamp_overrider  r   r   )r   s   "r   r   r     s0       " 
	r   c                   Vf(   \        \        4      P                  4       P                  pVP	                  RRR7       T;'       g    RP                  4       ;'       g%    \        P                  ! 4       P                  R4      pW R2,          pVP                  4       '       d   VP                  4        V P                  V4       V# )z
Moves the downloaded file into this script's folder (or out_dir if provided)
and renames it to: YYYYMMDD_On_Hand_Footwear.csv
Trw  r"   z%Y%m%dz_On_Hand_Footwear.csv)r   rA   r4   r7   r}  r,   r   nowstrftimerN   unlinkreplace)r  r  r  stamprH   s   &&&  r   move_to_dated_namer    s     x.((*11MM$M.!!r((*OOhlln.E.Eh.OE
g23
3C zz||

sJr   c                   V ^8  d   QhRR/# )r   r   r   r   )r   s   "r   r   r     s     3 3c 3r   c            	        \        4       p \        P                  P                  R R4      P	                  4       p \        V 4      w  r#p\        RV  24       \        W#4      p\        T4      p \        T4       \        T4       \        TR\        4       \        TR\        4       \        T4       \        TR\         4       \        TR\"        4       \%        T4      p\'        T4       \)        T4       \+        Yx\,        R	7      p	\/        YR
7      p
\        RT
 24       ^ #   \         d   p\        RT 24        Rp?^# Rp?ii ; i  \         d   p TP0                  P3                  4        \4        P6                  ! 4       R,          pTP9                  \;        T4      4       \        RT 24       M  \         d     Mi ; i\<        P>                  ! 4       p\        R\A        T4      PB                   RT: RT 24        Rp?^# Rp?ii ; i)POWERBI_OUTPUT_STAMPr"   zUsing session file: z5ERROR: Could not attach to existing Firefox session.
Nr   r   r   r   r  )r  zSaved CSV as: zpull_on_hand_footwear_error.pngzSaved error screenshot: z.ERROR: Failed while running automation.
Type: z

Message: z
Traceback:
)"rP   r)   r*   r+   r,   rh   r.   r   r   r  r   r   r  STORE_TYPE_VALUEAS_OF_VALUErE  STORE_NO_VALUEBUCKET_VALUEr  rM  r  r  DOWNLOAD_TIMEOUTr  r   r   r   r?   r~  r   	traceback
format_exctype__name__)session_pathoutput_stamprZ   r[   r  r   rr  r\   r  r  
final_pathrH   tbs                r   mainr    s   %'L::>>"8"=CCEL9KL9Y6"6$\N34"<<
 ((<=L#V$)&1FL2BCFG[9%f-FJ?FHl; .$V,6*<IYZ
'
P
zl+,& W  FqcJK4  	,,.((*@@C""3s8,,SE23 		!!#!W%%& 'u $ 	
 sP   'D  -B1E  E+D??EHAF21H2G =H?G  A HH__main__)z
Select AllAnyzFootwear Accessories)r   z/rdlreports/rdlembedrdl)   r   )   )
   )      )NN)b__doc__
__future__r   r`   r)   r   r  r   pathlibr   typingr   r   r   urllib.parser   seleniumr	   selenium.webdriver.common.byr
   selenium.webdriver.common.keysr   'selenium.webdriver.common.action_chainsr   #selenium.webdriver.remote.webdriverr   rj   "selenium.webdriver.firefox.optionsr   r{   selenium.webdriver.support.uir   selenium.webdriver.supportr   rI  r   r  r*   r+   r,   r  r  r  rB  rA  r@   IFRAME_SRC_HINTr   PAGE_TIMEOUTIFRAME_TIMEOUTr  EXPORT_TIMEOUTr  r/   r8   rK   rP   rh   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r"  r)  r.  r:  rE  rM  rU  rY  rb  rg  rk  rs  r  r  r  r  r  r  r  r  r  r  r  r  
SystemExitr   r   r   <module>r     s  (T #  	     , , !  + / @ L H 7 @
 V    jjnn2NCIIK]]~"<0 1   8328<!H BN BJ O] Z$ +8 :L4,&.Sj	$\N$aV&"J	 DR #AJ*0
=C@<@L^ +\up;F23 Qa !UH:3l z
TV
 r   