
    wfiq                     ^   d dl Z e j                  j                  d d       d dlZd dlZd dlZd dlmZ d Zd Z	d Z
d Zd Zd	 Zd
 Zd Z G d d      Z G d d      Z G d d      Z G d d      Z G d d      Zd&dZd Zd Zd Zd Zd Zd Zd Zd Zd Zd  Zd! Z d" Z!d# Z"d$ Z#d% Z$y)'    Nz /home/jay/workspace/teams/shared)scenario_runnerc                 z    t        | dd      5 }t        j                  ||d       d d d        y # 1 sw Y   y xY w)Nwutf-8encodingT)allow_unicode)openyamldumppathdatafs      A/home/jay/workspace/teams/shared/qc/tests/test_scenario_runner.py_write_yamlr      s5    	dC'	* /a		$./ / /   1:c                 z    t        | dd      5 }t        j                  ||d       d d d        y # 1 sw Y   y xY w)Nr   r   r   F)ensure_ascii)r
   jsonr   r   s      r   _write_jsonr      s5    	dC'	* /a		$./ / /r   c           	          dddgddddgdd	d
dg}| dz  }t        t        |      |       t        j                  t        |             }|d   dk(  sJ d|d    d       y)uH   subprocess 타입 시나리오가 모두 통과하면 gate='PASS' 반환zSC-TEST-001smokedummy.py
subprocess
echo hellohelloactionexpect_containsmustTu   echo hello 테스트idcategorytargettypestepspriorityautomatabledescriptionztest_pass.yamlscenarios_dirgatePASS   gate가 PASS여야 하지만 
    반환됨Nr   strr   run_scenariostmp_pathscenario	yaml_fileresults       r   test_run_scenarios_all_passr9      s      !l  +'. 1	
H" ++II)**XGF&>V#_'DVF^DTT^%__#    c           	          dddgddddgdd	d
dg}| dz  }t        t        |      |       t        j                  t        |             }|d   dk(  sJ d|d    d       t	        |d         dk\  sJ d       y)uS   must 시나리오 1개 FAIL → gate='FAIL'이고 failures에 1건 이상 기록됨zSC-TEST-002r   r   r   r   XYZZY_IMPOSSIBLE_STRING_12345r   r!   Tu4   절대 통과하지 않는 expect_contains 테스트r"   ztest_fail.yamlr+   r-   FAIL    gate가 FAIL이어야 하지만 r0   failures   u,   failures 목록에 1건 이상 있어야 함N)r   r2   r   r3   lenr4   s       r   !test_must_fail_triggers_gate_failrB   6   s      !l  +'F Q	
H" ++II)**XGF&>V#b'GvGWWa%bb#vj!"a'W)WW'r:   c                     | dz  }|j                          t        j                  dt        |      d      }|d   dk(  sJ d|d    d       t        |j	                  d	d
            }d|v sd|v s
J d|        yy)u=   시나리오 0건 + level=3 → verify() 반환 status='FAIL'emptytest   task_idr,   levelstatusr=   u=   level=3에서 시나리오 없으면 FAIL이어야 하지만 r0   details zLv.3u   시나리오 없음u>   details에 'Lv.3' 또는 '시나리오 없음' 포함 필요: N)mkdirr   verifyr2   get)r5   	empty_dirr8   details_strs       r    test_empty_scenarios_level3_failrR   R   s    7"IOO##)nF (v%  D)fgmnvgwfx  yC  (D  D%fjjB/0K+!6+!EV	G}UVE!Er:   c                     | dz  }|j                          t        j                  dt        |      d      }|d   dk(  sJ d|d    d       y	)
u=   시나리오 0건 + level=1 → verify() 반환 status='SKIP'rD   rE   r@   rG   rJ   SKIPu=   level=1에서 시나리오 없으면 SKIP이어야 하지만 r0   N)rM   r   rN   r2   )r5   rP   r8   s      r    test_empty_scenarios_level1_skiprU   d   sm    7"IOO##)nF (v%  D)fgmnvgwfx  yC  (D  D%r:   c           
      4   dddgddddgdd	d
ddddgddddgdd	ddg}| dz  }t        t        |      |       ddgi}| dz  }t        t        |      |       t        j                  t        |       t        |            }|d   dk(  sJ d|d    d       y)uS   impact.json으로 시나리오 필터링 — affected에 없는 target은 제외됨zSC-FILTER-001r   za.pyr   zecho aar   r!   Tu   a.py 시나리오r"   zSC-FILTER-002zb.pyzecho bbu   b.py 시나리오 — 필터됨zfilter_test.yamlaffectedzimpact.json)r,   impact_filetotalr@   u-   impact 필터 후 total=1이어야 하지만 r0   N)r   r2   r   r   r3   )r5   	scenariosr7   impact_datarZ   r8   s         r   test_impact_filteringr^   r   s     "h !)cBC.		
 "h !)cBC<		
I, --II	*x(K]*KK +.**(m$F
 '?al#PQWX_Q`Paak!llr:   c           	      4   dddgddddgdd	d
dg}| dz  }t        t        |      |       t        j                         }t	        j
                  t        |             }t        j                         |z
  }|j                  d|      }|dk  sJ d|dd       y)u7   단순 시나리오 실행이 30초 이내에 완료됨zSC-TIMEOUT-001r   r   r   zecho timingtimingr   r!   Tu   실행 시간 측정용r"   ztimeout_test.yamlr+   duration_seconds   u   실행 시간이 30초 초과: z.2fu   초N)r   r2   time	monotonicr   r3   rO   )r5   r6   r7   startr8   elapseddurations          r   test_execution_within_timeoutrh      s     #!l !.8LM4		
H ..II)NNE**XGFnn&Gzz,g6Hb=M;HS>MM=r:   c                        e Zd ZddZd Zd Zy)MockLocatorc                     || _         y N_visible)selfvisibles     r   __init__zMockLocator.__init__   	    r:   c                     | j                   S rl   rm   ro   s    r   
is_visiblezMockLocator.is_visible       }}r:   c                 ,    | j                   rdddddS d S )Nd      i,  2   )xywidthheightrm   rt   s    r   bounding_boxzMockLocator.bounding_box   s    CG==SsSB?ZVZZr:   NT)__name__
__module____qualname__rq   ru   r    r:   r   rj   rj      s     [r:   rj   c                   D    e Zd Zd Zd Zd Zd Zd Zd Zd Z	dd	Z
d
 Zy)MockPagec                      d| _         d | _        y NT)rn   _screenshot_pathrt   s    r   rq   zMockPage.__init__   s     $r:   c                      y rl   r   )ro   _url_kwargss      r   gotozMockPage.goto       r:   c                      y rl   r   )ro   _states     r   wait_for_load_statezMockPage.wait_for_load_state   r   r:   c                      y rl   r   )ro   	_selector_values      r   fillzMockPage.fill   r   r:   c                      y rl   r   ro   r   s     r   clickzMockPage.click   r   r:   c                     | j                   S rl   rm   r   s     r   ru   zMockPage.is_visible   rv   r:   c                 ,    t        | j                        S rl   )rj   rn   r   s     r   locatorzMockPage.locator   s    4==))r:   Nc                     || _         y rl   )r   )ro   r   s     r   
screenshotzMockPage.screenshot   s
     $r:   c                      y rl   r   )ro   _mss     r   wait_for_timeoutzMockPage.wait_for_timeout   r   r:   rl   )r   r   r   rq   r   r   r   r   ru   r   r   r   r   r:   r   r   r      s/    %*%r:   r   c                       e Zd Zd Zd Zd Zy)MockContextc                     || _         y rl   _page)ro   pages     r   rq   zMockContext.__init__   s	    
r:   c                     | j                   S rl   r   rt   s    r   new_pagezMockContext.new_page   s    zzr:   c                      y rl   r   rt   s    r   closezMockContext.close   r   r:   N)r   r   r   rq   r   r   r   r:   r   r   r      s    r:   r   c                       e Zd Zd Zd Zd Zy)MockBrowserc                     || _         y rl   _context)ro   contexts     r   rq   zMockBrowser.__init__   rr   r:   c                     | j                   S rl   r   )ro   kwargss     r   new_contextzMockBrowser.new_context   rv   r:   c                      y rl   r   rt   s    r   r   zMockBrowser.close   r   r:   N)r   r   r   rq   r   r   r   r:   r   r   r      s     r:   r   c                       e Zd Zd Zy)MockPlaywrightc                 >     t        dddfdi             | _        y )NChromiumr   launchc                     S rl   r   )ro   kwbrowsers     r   <lambda>z)MockPlaywright.__init__.<locals>.<lambda>   s    7 r:   )r&   chromium)ro   r   s    `r   rq   zMockPlaywright.__init__   s    TZh8R-STVr:   N)r   r   r   rq   r   r:   r   r   r      s    Wr:   r   c                 n    t               }| |_        t        |      }t        |      }t	        |      }||fS )u%   playwright mock 객체 생성 헬퍼.)r   rn   r   r   r   )rp   r   r   r   pws        r   _make_playwright_mockr      s7    :DDM$G'"G		 Bt8Or:   c           	          dddgdddiddigdd	d
dg}| dz  }t        t        |      |       t        j                  t        |             }|d   dk(  sJ d|d    d       |d   dk(  sJ d|d    d       y)u8   playwright 타입이지만 automatable=false → skippedz	SC-PW-001e2efrontend/app.tsx
playwrightr   navigate http://localhost:3000assert_visible h1r!   Fu&   playwright automatable=false 테스트r"   zpw_skip.yamlr+   skippedr@   u   skipped=1이어야 하지만 r0   r-   r.   r/   Nr1   r4   s       r   5test_playwright_scenario_skipped_when_not_automatabler     s     )* ;<./  C	
H >)II)**XGF)!`%B6)CTBUU_#``!&>V#_'DVF^DTT^%__#r:   c           	      l   dddgdddiddigdd	d
dg}| dz  }t        t        |      |       t        d	      \  }ddl}|j                  fd       }|j                  d|d       t        j                  t        |             }|d   dk(  sJ d|d    d       |d   dk(  sJ d|d    d       y)u<   playwright 타입 시나리오가 정상 실행되면 passedz	SC-PW-002r   r   r   r   r   r   r!   Tu"   playwright 정상 실행 테스트r"   zpw_pass.yamlrp   r   Nc               3      K     y wrl   r   pw_mocks   r   mock_sync_playwrightz;test_playwright_scenario_pass.<locals>.mock_sync_playwright5          	"qc.scenario_runner.sync_playwrightFraisingr+   passedr@      passed=1이어야 하지만 r0   r-   r.   r/   )r   r2   r   
contextlibcontextmanagersetattrr   r3   )	r5   monkeypatchr6   r7   r   r   r   r8   r   s	           @r   test_playwright_scenario_passr     s	    )* ;<./ ?	
H >)II))$7MGT  ,   **XGF(q ]$@AQ@RR\"]] &>V#_'DVF^DTT^%__#r:   c           	        	 dddgdddiddigdd	d
dg}| dz  }t        t        |      |       t        d      \  	}ddl}|j                  	fd       }|j                  d|d       t        j                  t        |             }|d   dk(  sJ d|d    d       |d   dk(  sJ d|d    d       t        |d         dk\  sJ d       |d   d   }d|d   k(  s
J d|        y) uJ   playwright assert 실패 시 failed + reason에 스크린샷 경로 포함z	SC-PW-003r   r   r   r   r   z$assert_visible .non-existent-elementr!   Tu"   playwright assert 실패 테스트r"   zpw_fail.yamlFr   r   Nc               3      K     y wrl   r   r   s   r   r   zQtest_playwright_scenario_assert_fail_returns_failed.<locals>.mock_sync_playwright]  r   r   r   r   r+   failedr@   u   failed=1이어야 하지만 r0   r-   r=   r>   r?   u%   failures에 1건 이상 있어야 함r#   u2   실패 시나리오 ID가 SC-PW-003이어야 함: )	r   r2   r   r   r   r   r   r3   rA   )
r5   r   r6   r7   r   r   r   r8   failurer   s
            @r   3test_playwright_scenario_assert_fail_returns_failedr   E  sW    )* ;<AB ?	
H >)II))%8MGT  ,   **XGF(q ]$@AQ@RR\"]] &>V#b'GvGWWa%bb#vj!"a'P)PP'Z #G'$-'g+]^e]f)gg'r:   c           	      6   dddgddddgdd	d
dg}| dz  }t        t        |      |       t        j                  dt        |       d      }|d   dk(  sJ d|d    d       t        |j	                  dd            }d|j                         v s
J d|        y)u;   level=3에서 playwright 시나리오가 없으면 → WARNzSC-PW-GATE-001r   backend/api.pyr   echo okokr   r!   Tu#   playwright 없는 Lv.3 시나리오r"   zno_pw_level3.yamlztest-lv3rF   rG   rJ   WARNu;   level=3에서 playwright 없으면 WARN이어야 하지만 r0   rK   rL   r   u'   details에 'playwright' 포함 필요: N)r   r2   r   rN   rO   lower)r5   r6   r7   r8   rQ   s        r   &test_verify_level3_requires_playwrightr   q  s    
 #'( !*tDE@		
H ..II)##(mF (v%  B)deklteudv  wA  (B  B%fjjB/0K;,,..g2YZeYf0gg.r:   c                     | j                  dd       t        j                  d      }|dk(  sJ t        j                  d      }|dk(  sJ y)u;   환경변수 기반 플레이스홀더 치환 동작 확인SCENARIO_test_doc_idzdoc-123z(http://localhost:3000/docs/{test_doc_id}z"http://localhost:3000/docs/doc-123z{unknown_var}N)setenvr   _resolve_placeholders)r   r8   result2s      r   test_resolve_placeholdersr     sS    -y9223]^F9999 33ODGo%%%r:   c           	          dddgddddgdd	d
dg}| dz  }t        t        |      |       t        j                  dt        |       d      }|d   dk(  sJ d|d    d       y)uK   level=2에서 playwright 시나리오가 없어도 → 기존 동작 유지zSC-PW-GATE-002r   r   r   r   r   r   r!   Tu#   playwright 없는 Lv.2 시나리오r"   zno_pw_level2.yamlztest-lv2   rG   rJ   r.   u;   level=2에서는 playwright 없어도 PASS여야 하지만 r0   N)r   r2   r   rN   r4   s       r   (test_verify_level2_skips_playwright_gater     s     #'( !*tDE@		
H ..II)##(mF (v%  B)deklteudv  wA  (B  B%r:   c                 P   ddl }g t        dd      D cg c]  }d|dddgd	d
digddd| d }}t        dd      D cg c]  }d|dddgddddgddd| d }}| dz  }t        t        |      ||z          t	        d      \  }|j
                  fd       }|j                  d|d       t        j                  }	d-dt        d t        d!t        ffd"}
|j                  d#|
       t        j                  t        |       $      }|d%   d&k(  sJ d'|d%    d(       |d)   dk(  sJ D cg c]	  }d*|v s| }}t        |      dk(  s
J d+|        t        dd      D ch c]  }d|d
 }}t        |      |k(  s
J d,|        yc c}w c c}w c c}w c c}w ).u   playwright 시나리오가 병렬이 아닌 순차 실행되는지 확인.
    3개 playwright + 2개 subprocess 시나리오 → subprocess는 병렬, playwright는 순차.r   Nr@      z
SC-SEQ-PW-03dr   r   r   r   r   r!   Tu#   playwright 순차 실행 테스트 r"   rF   z
SC-SEQ-SP-r   r   r   r   r   r   u#   subprocess 병렬 실행 테스트 zseq_test.yamlr   c               3      K     y wrl   r   r   s   r   r   z?test_playwright_runs_sequentially.<locals>.mock_sync_playwright  r   r   r   Fr   r6   storage_statereturnc                 >    j                  | d          | d   dddS )Nr#   r   rL   )r#   rJ   reasonappend)r6   r   execution_orders     r   recording_run_playwrightzCtest_playwright_runs_sequentially.<locals>.recording_run_playwright  s&    x~.tnBGGr:   z+qc.scenario_runner._run_playwright_scenarior+   r      u   passed=5여야 하지만 r0   r   PWu1   playwright 3개 실행 기록이어야 하지만 u   playwright ID 불일치: rL   )r   ranger   r2   r   r   r   r   _run_playwright_scenariodictr3   rA   set)r5   r   r   ipw_scenariossp_scenariosr7   _r   original_run_playwrightr   r8   sc_idpw_idsexpected_pw_idsr   r   s                  @@r   !test_playwright_runs_sequentiallyr    sO     "$O q!  qg&)* !ABC@D		
L 0 q!  qg&'( !*tDE@D		
L  ?*II| ;<&t4JGQ  <>R\ab .FFH4 H HT H EG_`**XGF (q Z$=fX>N=Oz"ZZ (q    "1BDEMeBFBv;!YPQWPXYY
 6;1a[AAc7+AOAv;/)O-Fvh+OO){R C Bs   FF6	F F,F#c           	         ddl }g dddgdddigd	d
ddg}| dz  }t        t        |      |       t        d
      \  }|j                  fd       }|j                  d|d       dt        ffd}ddl}|j                  d      }	||	_	        |j                  t        j                  d|	       t        j                  t        |             }
|
d   dk(  sJ d|
d    d       t              dk\  sJ d       y)uF   playwright 시나리오 실행 전 check_and_refresh_ttl 호출 확인r   Nz
SC-TTL-001r   r   r   r   r   r!   Tu   TTL 체크 테스트r"   zttl_test.yamlr   c               3      K     y wrl   r   r   s   r   r   zEtest_ttl_check_called_before_playwright.<locals>.mock_sync_playwright  r   r   r   Fr   r   c                  (    j                  d       yNTFr   argsr   ttl_call_logs     r   mock_check_and_refresh_ttlzKtest_ttl_check_called_before_playwright.<locals>.mock_check_and_refresh_ttl       D!r:   qc.auth.setup_authr+   r   r@   r   r0   u8   check_and_refresh_ttl이 최소 1회 호출되어야 함)r   r   r2   r   r   r   booltypes
ModuleTypecheck_and_refresh_ttlsetitemsysmodulesr   r3   rA   )r5   r   r   r6   r7   r  r   r  r  mock_setup_authr8   r   r  s              @@r   'test_ttl_check_called_before_playwrightr    s.   !L )* !ABC1		
H ?*II)&t4JGQ  <>R\abt 
 &&';<O,FO)%9?K**XGF(q ]$@AQ@RR\"]] |!]#]]!r:   c           	         ddl }ddl}dddgdddigd	d
ddg}| dz  }t        t        |      |       t	        d
      \  }|j
                  fd       }|j                  d|d       dt        fd}	|j                  d      }
|	|
_	        |j                  t        j                  d|
       t        j                  t        |              |j                         }d|j                   v s#d|j                   v sJ d|j                          yy)u*   TTL 만료 시 경고 로그 출력 확인r   Nz
SC-TTL-002r   r   r   r   r   r!   Tu   TTL 만료 경고 테스트r"   zttl_expire_test.yamlr   c               3      K     y wrl   r   r   s   r   r   zHtest_ttl_check_warning_logged_when_expired.<locals>.mock_sync_playwrightH  r   r   r   Fr   r   c                       yr   r   r  r   s     r   mock_check_expiredzFtest_ttl_check_warning_logged_when_expired.<locals>.mock_check_expiredO      r:   r  r+   TTLstorageStateuF   TTL 만료 경고가 출력되어야 하지만 출력 없음. stdout: r   r  r   r2   r   r   r   r  r  r  r  r  r  r   r3   
readouterrout)r5   r   capsysr   r  r6   r7   r  r   r$  r  capturedr   s               @r   *test_ttl_check_warning_logged_when_expiredr-  2  s2    )* !ABC8		
H 11II)&t4JGQ  <>R\abt  &&';<O,>O)%9?K!!H>  "H8<<!?a	OPXP\P\O_`a?!?r:   c           	      n   ddl }g dddgdddd	gd
dddg}| dz  }t        t        |      |       dt        ffd}|j	                  d      }||_        |j                  t        j                  d|       t        j                  t        |             }|d   dk(  sJ t              dk(  sJ d       y)uF   playwright 시나리오 없으면 check_and_refresh_ttl 호출 안 됨r   Nz
SC-TTL-003r   r   r   r   r   r   r!   Tu#   subprocess only - TTL 호출 안됨r"   zno_pw_ttl.yamlr   c                  (    j                  d       yr  r   r  s     r   r  zJtest_ttl_not_called_without_playwright.<locals>.mock_check_and_refresh_ttls  r  r:   r  r+   r   r@   u-   playwright 없으면 TTL 체크 호출 안됨)r  r   r2   r  r  r  r  r  r  r   r3   rA   )	r5   r   r  r6   r7   r  r  r8   r  s	           @r   &test_ttl_not_called_without_playwrightr0  ^  s    !L '( !*tDE@		
H ++II)t  &&';<O,FO)%9?K**XGF(q   |!R#RR!r:   c                    | dz  }|j                          t        dd      D cg c]  }d|dddgdd	d
igddd| d }}t        t        |dz        |       | dz  }|j                          t        dd      D cg c]  }d|dddgdd	d
igddd| d }}t        t        |dz        |       t	        j
                  t        |             }d|v sJ d       d|v sJ d       d|v sJ d       |d   d   dk(  sJ d|d   j                  d              |d   d   dk(  sJ d|d   j                  d              |d   d k(  sJ d!|d           y"c c}w c c}w )#u4   프로젝트별 시나리오 카운트 정상 동작insuwikir@   r   zSC-INSUWIKI-r   r   zinsuwiki/main.pyr   r   r   r!   Tu   insuwiki 시나리오 r"   zinsuwiki.yaml	dashboardrF   zSC-DASH-zdashboard/main.pyu   dashboard 시나리오 zdashboard.yamlr+   projectsu)   결과에 'projects' 키가 있어야 함r[   u&   결과에 'total' 키가 있어야 함
duplicatesu+   결과에 'duplicates' 키가 있어야 함u(   insuwiki 카운트=3이어야 하지만 r   u)   dashboard 카운트=2이어야 하지만 r   u   total=5이어야 하지만 N)rM   r   r   r2   r   
show_statsrO   )r5   insuwiki_dirr  insuwiki_scenariosdashboard_dirdashboard_scenariosr8   s          r   !test_show_stats_counts_by_projectr;    s    j(L q!  !3()* +,3A37		
  L?235GH {*M q!  QsG$*+ +,4QC8		
  M$4457JK''c(mDFL!LLfFFF6!P#PP!*j)Q.2Z[abl[m[q[qr|[}Z~0.z;'1,Y	26*3E3I3I+3V2WXY,'?aP#>vg>O!PPU$s   E>Ec                     ddg dddg dddg dddg dddg dg}t        j                  |      }d|v s
J d|        d|v s
J d|        d|vs
J d|        y	)
u   중복 ID 감지z
SC-DUP-001r   r#   r&   r'   z
SC-DUP-002z
SC-DUP-003u.   SC-DUP-001이 중복 목록에 있어야 함: u.   SC-DUP-003이 중복 목록에 있어야 함: u    SC-DUP-002는 중복이 아님: Nr   _detect_duplicatesr5   r\   r5  s      r   "test_detect_duplicates_finds_dupesrA    s     \B?\B?\B?\B?\B?I !33I>J:%d)WXbWc'dd%:%d)WXbWc'dd%z)Z-Mj\+ZZ)r:   c                 n    ddg dddg dddg dg}t        j                  |      }|g k(  s
J d|        y)u   중복 없으면 빈 리스트zSC-UNIQ-001r   r=  zSC-UNIQ-002zSC-UNIQ-003u/   중복 없으면 빈 리스트여야 하지만 Nr>  r@  s      r   test_detect_duplicates_no_dupesrC    sV     lR@lR@lR@I !33I>J[Nzl[[r:   c           	         ddl }ddl}dddgdddigd	d
ddg}| dz  }t        t        |      |       t	        d
      \  }|j
                  fd       }|j                  d|d       dt        fd}|j                  d      }	||	_	        |j                  t        j                  d|	       g ddt        dt        ffd}
|j                  d|
       t        j                  t        |              t              dk\  sJ d       y)uK   TTL 만료 시 _auto_refresh_storage_state 함수가 호출되는지 확인r   NzSC-AUTOREFRESH-001r   r   r   r   r   r!   Tu%   자동 갱신 호출 확인 테스트r"   zauto_refresh_test.yamlr   c               3      K     y wrl   r   r   s   r   r   zGtest_auto_refresh_called_when_ttl_expired.<locals>.mock_sync_playwright  r   r   r   Fr   r   c                       yr   r   r#  s     r   r$  zEtest_auto_refresh_called_when_ttl_expired.<locals>.mock_check_expired  r%  r:   r  storage_state_pathc                 (    j                  d       yr   r   )rG  auto_refresh_call_logs    r   mock_auto_refreshzDtest_auto_refresh_called_when_ttl_expired.<locals>.mock_auto_refresh  s    $$T*r:   .qc.scenario_runner._auto_refresh_storage_stater+   r@   uM   _auto_refresh_storage_state가 TTL 만료 시 최소 1회 호출되어야 함r   )r   r  r   r2   r   r   r   r  r  r  r  r  r  r   r3   rA   )r5   r   r   r  r6   r7   r  r   r$  r  rJ  rI  r   s              @@r   )test_auto_refresh_called_when_ttl_expiredrL    s/    ')* !ABCB		
H 33II)&t4JGQ  <>R\abt  &&';<O,>O)%9?K )+c 4  HJ[\!!H>$%*{,{{*r:   c           	         ddl }ddl}dddgdddigd	d
ddg}| dz  }t        t        |      |       t	        d
      \  }|j
                  fd       }|j                  d|d       dt        fd}	|j                  d      }
|	|
_	        |j                  t        j                  d|
       d dt        dt        fd}|j                  d|       t        j                  t        |             }|j                         }d|j                   v s"d|j                   v sJ d|j                          |d   dk(  sJ d|d           y)!uo   자동 갱신 실패 시 경고 로그가 출력되고 playwright 시나리오가 계속 실행되는지 확인r   NzSC-AUTOREFRESH-002r   r   r   r   r   r!   Tu%   자동 갱신 실패 경고 테스트r"   zauto_refresh_fail_test.yamlr   c               3      K     y wrl   r   r   s   r   r   zDtest_auto_refresh_failure_logs_warning.<locals>.mock_sync_playwright  r   r   r   Fr   r   c                       yr   r   r#  s     r   r$  zBtest_auto_refresh_failure_logs_warning.<locals>.mock_check_expired&  r%  r:   r  rG  c                      y)NFr   )rG  s    r   mock_auto_refresh_failzFtest_auto_refresh_failure_logs_warning.<locals>.mock_auto_refresh_fail.  s    r:   rK  r+   u   실패u   수동uA   자동 갱신 실패 경고가 출력되어야 하지만 stdout: r[   r@   u5   시나리오 1개가 실행되어야 하지만 total=r   r(  )r5   r   r+  r   r  r6   r7   r  r   r$  r  rQ  r8   r,  r   s                 @r   &test_auto_refresh_failure_logs_warningrR  	  s}    ')* !ABCB		
H 88II)&t4JGQ  <>R\abt  &&';<O,>O)%9?K3   HJ`a**XGF  "H 	HLL H$<\	J8<<JZ[\< '?aj#XY_`gYhXi!jjr:   r   )%r  r   insertr   rc   r   qcr   r   r   r9   rB   rR   rU   r^   rh   rj   r   r   r   r   r   r   r   r   r   r   r   r  r  r-  r0  r;  rA  rC  rL  rR  r   r:   r   <module>rU     s    
 5 6    
/
/`6X8V$D$mNN8[ [ <  W W
`4%`P)hXh:&B<EPV-^`)aX SL/Qd["
\ /|d2kr:   