
    iI                     `    d Z ddlZddlmZ dZdZg Zg ZddZd Z	d Z
d	 Zed
k(  r e        yy)uL  
Argos QA Tester - 네이버블로그 Keyword Analysis FINAL (corrected)
Key findings from debug:
1. page.fill() doesn't trigger React onChange - must use React nativeInputValueSetter
2. The step indicator has button text "0키워드 분석" - avoid matching it
3. After React setter, button becomes enabled and API fires correctly
    N)sync_playwrightz8/home/jay/workspace/memory/reports/task-1933-screenshotsz http://localhost:8000/dashboard/c                     ddddj                  | d      }| d| }|r|d| z  }t        |       t        j                  | ||d       y )	N[PASS][FAIL][WARN]PASSFAILWARNz[INFO] u    — )statustestdetail)getprintresultsappend)r   	test_namer   iconmsgs        L/home/jay/workspace/memory/reports/task-1933-screenshots/03_keyword_FINAL.py
log_resultr      sY    hAEEfhWDF!I;
Cvh	#JNNfi6JK    c                 .    | j                  d||g      }|S )z6Set input value in a way that triggers React onChange.a/  
        ([sel, value]) => {
            const inp = document.querySelector(sel);
            if (!inp) return {ok: false, error: 'not found'};
            const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
                window.HTMLInputElement.prototype, 'value'
            ).set;
            nativeInputValueSetter.call(inp, value);
            inp.dispatchEvent(new Event('input', { bubbles: true }));
            inp.dispatchEvent(new Event('change', { bubbles: true }));
            return {ok: true, value: inp.value};
        }
        evaluate)pageselectorvalueresults       r   set_react_inputr!      s&    ]]	 
5F  Mr   c                 (    | j                  d      }|S )u1   Click the 분석 button (not the step indicator).u  
        () => {
            // Find buttons with '분석' text, exclude step indicators
            const btns = document.querySelectorAll('button');
            for (const btn of btns) {
                const txt = btn.textContent.trim();
                if (txt === '분석' || txt === '분석 중...') {
                    btn.click();
                    return {clicked: true, text: txt, disabled: btn.disabled};
                }
            }
            // Fallback: any button with only '분석' in a form-like context
            for (const btn of btns) {
                if (btn.textContent.includes('분석') && !btn.textContent.includes('경쟁') && btn.textContent.length < 10) {
                    btn.click();
                    return {clicked: true, text: btn.textContent.trim(), disabled: btn.disabled};
                }
            }
            return {clicked: false, available: Array.from(btns).map(b => b.textContent.trim().substring(0, 20))};
        }
    r   )r   r    s     r   click_analyze_buttonr#   /   s     ]]  	F* Mr   c                     t               5 } | j                  j                  d      }|j                  ddd      }|j	                         }d }d }|j                  d	|       |j                  d
|       t        d       |j                  t        d       |j                  d       |j                  t         d       t        dd|j                         t        d       |j                  d      j                  }|j!                  dd       |j#                          |j                  d       |j                  t         d       t        ddd       t        d       |j                  d      j                  }|j%                  d      r#|j'                  d      }t        ddd | d!       nt        d"d#d$       |j)                  d%      }	|	rt        dd&d'|	        nt        d(d)d*       t        d+       t+        |dd,      }
t        d-|
        |j                  d      j                  j-                         }d,|v rt        dd.d/| d!       nt        d"d.d/| d!       |j)                  d0      }t        d1|        |j                  t         d2       t        d3       t/        |      }t        d4|        |j1                  d5      rt        dd6d7|d8    d9|d:           n#t        d"d6d;|j1                  d<g       d d=         |j                  d>       |j                  t         d?       t        d@       dA}dA}dB}dC}t3        dD      D ]  }t5        j6                  dE       |dFz   dEz  }t        dG| dH|dFz    dI       	 |j                  dJ      j9                  dK      }dL|v rt        dM       hdN|v r8d}|j                  dO      j;                         }t        ddPdQ| dR| dS        n dT|v rk|j                  dU      j;                         }|dCkD  r7d}|j                  dO      j;                         }t        ddVdW| dR| dS        n|d=kD  rt        dX       |j                  dY      }t3        |j;                               D ]}  }	 |j=                  |      j9                  dZ      }|j?                         rId[|v sd\|v sd]|jA                         v r/d^|vr+d}|j?                         }t        d"d_d`| da|d dZ  d!        n |r n t        dc       |j                  t         dd       t        de       t        ddfdg       |r>t        dh       |j                  di      jE                         }|D cg c]#  }|j?                         s|j?                         % }}t        dj|        h dk}||D ch c]2  }|jG                  dldB      jG                  dmdB      j?                         4 c}z  }tI        |      dnk\  rt        ddodp| dq|        nt        d(drdstI        |       dt|        t        du       dC}tK        |d dv       D ]  \  }} 	 |j                  di      j=                  |      }|j%                  dZ      r\|j#                          |j                  dw       |j9                  dx      }!dy|!v sdz|!v r!t        dd{|  d!d||! d!       |dFz  }|dEk\  r n |j                  t         d       t        d       t        d       |j                  dO      }"|"j;                         }#dC}$t        d|#        |#dCkD  rt3        tO        |#dn            D ]  }	 |"j=                  |      }%|%j9                  dx      }&|%j#                          |j                  dK       |j                  dJ      j9                  d      }'|$dFz    d|'v sd|'v r-|$dFz  }$t        dd|dFz    d|&d d j?                          d!        |$dCk(  rX	 |j                  dJ      j9                  d      }'|'jQ                  d      D (cg c]	  }(d|(v s|( })}(t        d(dd|)d dE         |j                  t         d       t        d       n|r.t        d"dd|d dZ  d!       |j                  t         d       n|j                  dJ      j9                  d>      }*tR        D +cg c]  }+d|+j1                  ddB      v s|+ },}+|,rt        d(dtI        |,       d       nt        d"dd       d|*v sd|*v rt        d(dd       t        d|*d dK         t        d       tR        D +cg c]  }+d|+j1                  ddB      v s|+ }-}+|-D +cg c]  }+d|+j1                  ddB      v s|+ },}+t        dtI        |-              |-D ]O  }+|+j1                  ddB      }.t        dG|+d   jU                          d|+j1                  ddB       d|+d    d|.        Q |,r|,D +cg c]-  }+tW        |+j1                  d      tX              s#|+d   dk\  s,|+/ }/}+|/r-t        d"dtI        |/       d|/D +cg c]  }+|+d   	 c}+        n^|,D +cg c]  }+|+d   dk(  s|+ }0}+t        dddtI        |,       d|0D +cg c]  }+|+j1                  d       c}+        nt        d"d       |j                  t         d       t        d       |j[                          d d d        t        d       t        d       t        d       t]        d t^        D              }1t]        d t^        D              }2t]        d t^        D              }3t        d|1 d|2 d|3 dtI        t^               d	       t        d       t^        D ]  }4ddddj1                  |4d   d      }5t        d|5 d|4d           |4d   s6|4d   jQ                  d      d dE D ]2  }6|6j?                         st        d|6j?                         d d         4  t        d       y # tB        $ r Y w xY w# tB        $ r}t        db|        Y d }~	$d }~ww xY wc c}w c c}w # tB        $ r(}t        d(d}|  d!tM        |      d d~        Y d }~[d }~ww xY w# tB        $ r+}t        d(d|dFz    dtM        |      d d~        Y d }~d }~ww xY wc c}(w # tB        $ r Y w xY wc c}+w c c}+w c c}+w c c}+w c c}+w c c}+w c c}+w # 1 sw Y   xY w)NT)headlessi  i  )widthheight)viewportc                     d| j                   v rSt        j                  d| j                  | j                   d       t	        d| j                   d| j                           y y )N
naver-blogreq)typemethodurlz
    [REQ] r   )r.   	api_callsr   r-   r   )r+   s    r   on_reqzrun_tests.<locals>.on_reqP   M    sww&  %3::cgg!VW
3::,ay9: 'r   c                     d| j                   v rSt        j                  d| j                  | j                   d       t	        d| j                   d| j                           y y )Nr*   res)r,   r   r.   z
    [RES] r   )r.   r/   r   r   r   )r3   s    r   on_reszrun_tests.<locals>.on_resU   r1   r   requestresponsez&
=== TEST 1: Navigate to dashboard ===domcontentloaded)
wait_untili  z/03_keyword_01_loaded.png)pathr	   zDashboard navigationu-   
=== TEST 2: Click 네이버블로그 tab ===u%   button:has-text('네이버블로그')visible)statetimeouti  z/03_keyword_02_tab_active.pngu   Click 네이버블로그 tabz3s render wait completeu0   
=== TEST 3: Verify 키워드 분석 step UI ===u2   input[placeholder*='키워드를 입력하세요'])r<   placeholderzKeyword input presentzplaceholder: ''r
   zKeyword inputzNot visibleu  
            () => {
                const btns = document.querySelectorAll('button');
                const found = [];
                for (const btn of btns) {
                    if (btn.textContent.trim() === '분석') {
                        found.push({text: btn.textContent.trim(), disabled: btn.disabled, cls: btn.className.substring(0, 60)});
                    }
                }
                return found;
            }
        u    분석 button (exact text match)zFound: r   u   분석 button exact matchu"   Not found with exact text '분석'u7   
=== TEST 4: Type '실손보험' (React-compatible) ===u   실손보험z  set_react_input result: u   Type keyword '실손보험'zDOM value: 'u  
            () => {
                const btns = document.querySelectorAll('button');
                for (const btn of btns) {
                    if (btn.textContent.trim() === '분석') {
                        return {disabled: btn.disabled, opacity: window.getComputedStyle(btn).opacity};
                    }
                }
                return null;
            }
        z  Button state after typing: z/03_keyword_03_typed.pngu$   
=== TEST 5: Click 분석 button ===z  click_analyze_button result: clickedu   Click 분석 buttonztext='textz', disabled=disabledzCould not click. Available: 	available   i  z/03_keyword_04_analyzing.pngz'
=== TEST 6: Poll for results (30s) ===F r            z  [zs] Attempt z/15...bodyi  u
   분석 중u       (분석 중...)u   연관 키워드 분석 결과ztbody trz!Keyword analysis results appearedu$   '연관 키워드 분석 결과' at zs, z rowsu   선택한 키워드 순위tablezResults UI visiblezSelection + table at z0    Selection area visible, waiting for table...z.bg-red-50, .text-red-700   u   오류u   실패erroru   AI 글 생성zKeyword analysis errorz	Error at zs: 'z    Poll error: z&
=== TEST 7: Screenshot of results ===z/03_keyword_05_results.pngz"  Saved: 03_keyword_05_results.pngzScreenshot savedz03_keyword_05_results.pngz+
=== TEST 8: Check keyword data columns ===thz  Column headers: >   	   경쟁도	   키워드   PC 검색량   모바일 검색량u    ▼u    ▲   zKeyword data columns presentzFound expected: z | All headers: zKeyword data columnszOnly z expected cols found: z'
=== TEST 9: Sort by column headers ===   i  i,  u   ▼u   ▲zSort column 'zIndicator: 'zSort '<   z/03_keyword_06_after_sort.pngz*  Screenshot: 03_keyword_06_after_sort.pngz2
=== TEST 10: Click keyword rows for selection ===z  tbody rows: i  u   /5개 선택u   ✓zSelect keyword row z
keyword: '   zRow z click
u
   개 선택zRow selection checkzCounter lines: z"/03_keyword_07_after_selection.pngz/  Screenshot: 03_keyword_07_after_selection.pngzKeyword analysis resultzError: 'z/03_keyword_06_error.pngzkeyword-analysisr.   z!API called but no results visiblez calls but no table appearedz$Keyword analysis did not trigger APIzCheck input React integrationu   연관u   검색zPartial results contentz0Keyword-like content found but no table renderedz
  Final page body sample:
z
=== API CALL SUMMARY ===r*   z  Total naver-blog calls: r   r,   z] r-   r   zkeyword-analysis API errorsz	 failed: r3   zkeyword-analysis APIzCalled z times, responses: z!keyword-analysis API never calledz/03_keyword_08_final.pngz+  Final screenshot: 03_keyword_08_final.pngzB
=================================================================uA     ARGOS QA REPORT — 네이버블로그 Keyword Analysis FeaturezA=================================================================c              3   2   K   | ]  }|d    dk(  sd  yw)r   r	   rG   N .0rs     r   	<genexpr>zrun_tests.<locals>.<genexpr>w       =qq{f'<=   c              3   2   K   | ]  }|d    dk(  sd  yw)r   r
   rG   NrW   rX   s     r   r[   zrun_tests.<locals>.<genexpr>x  r\   r]   c              3   2   K   | ]  }|d    dk(  sd  yw)r   r   rG   NrW   rX   s     r   r[   zrun_tests.<locals>.<genexpr>y  r\   r]   z	
  PASS: z  |  FAIL: z  |  WARN: z  |  TOTAL: zA-----------------------------------------------------------------r   r   r   r   z[?]z  r   r   z           d   )0r   chromiumlaunchnew_contextnew_pageonr   gotoBASE_URLwait_for_timeout
screenshotSCREENSHOT_DIRr   r.   locatorfirstwait_forclick
is_visibleget_attributer   r!   input_valuer#   r   rangetimesleep
inner_textcountnthstriplower	Exceptionall_text_contentsreplacelen	enumeratestrminsplitr/   upper
isinstanceintclosesumr   )7pbrowsercontextr   r0   r4   tabinp_placeholderph	btn_checkr    inp_val	btn_stateclick_resultresult_founderror_found
error_text	row_countattemptelapsedrH   tableserr_divsitxtehdrsh
hdrs_cleanexpectedfound_esort_successhdrupdatedrowsrc	sel_countrowrow_txtbody_nowlcounter
body_finalcanalyze_callsnaver_callss
api_errors	res_callspass_cfail_cwarn_crZ   r   lines7                                                          r   	run_testsr   I   s   		 ga**##T#2%%/M%N!	;
	;
 		6"
F# 	78		('9	:d#//HIJ61488< 	>?llBCII9d3		d#//LMN69;TU 	AB,,'[\bb%%d%3 ..}=Bv6.A8NOv> MM # 	 vAWYKCXYv:<`a 	HI '[]kl*6(34 ,,STZZffhW$v<WIUV>WXv<WIUV>WX MM 
# 
	 	-i[9://GHI 	56+D1/~>?I&v4V 45\,zBZA[\^ v45l6F6F{TV6WXZYZ6[5\]_ 	d#//KLM 	89
	Ry 6	.GJJqM{a'GCyGAI;f=>1.||F+66s6C  4'/0 4t;#'L $Z 8 > > @Iv'J!EgYcR[Q\\abd/47!\\'288:Fz'+$(LL$<$B$B$D	"6+?%:7)3ykQV#WY 1 PR  <<(CDx~~/0 A&ll1o888E99;HOx3RY]`]f]f]hRh.c9.2-0YY[
 *63K-6witJtPSDTCUUV+W!Y %  e6	.r 	78//IJK236-/JK @A<<%779D-1?QWWY!'')?J?&zl34 YH]g!hXY!))FB"7"?"?"K"Q"Q"S!hhG7|q 6#A-gY6FzlSU 6#9"3w<.0FwiPR <>L#JrN3 E3ET*..q1A||C|0	--c2"#,,s,"; G+u/?&vse1/E)5gYa'@B(A-L+q0 %E  OON#33P!QOR>?GI<<
+DBIN2$'(Avs2qz* LAL"hhqk"%..."=		--c2#'<<#7#B#B3#B#O'k],78CuPXGX%NI&v1DQqSE/J)3GCRL4F4F4H3I'KML >#'<<#7#B#B3#B#O.6nnT.B"XlVWFW1"X"X"6+@%4WRa[M#BD
 OON#33U!VOWCDv8!*Tc"2!3157OON#33K!LOM f-888FJ(1\15G155QVXZK[5[Q\M\6#F!-011MNP 6#I:< :%Z)?6#<MO1*Tc2B1CDE 	*+"+PQ|quuUB?O/OqPP$/Zq3EuVXIY3YZZ*3{+;*<=> 	SAh#AC&	)*"QUU8R-@,A1U8*AaSQR	S %2njxRU6V[\]e[fjm[m!nJn6#@!*o.ij8Y88Y7Z[] )6L16e9KQL	L6#9$S%7$88KfoLpabQUUS[_LpKqrt vBC//GHI;<O	gT	 
-	
MN	&M=G==F=G==F=G==F	Jvhk&VHLQTU\Q]P^^`
ab	&M > (HEII!H+W\]4&!F)%&X;())$/3 >::<K

Tc(:';<=>	> 
&Mo % 
  .(,--. @
 "i. ! EvuAAsDDE2 % L"6T!A#f+=s1vcr{KKL #Y %  ]" QZ o 9ZLLpC	g gs  Nt40q"t49q"<t4?Aq"t4=q"A8qq"A2t4r"r4t47rA$t4)Br5Bt48B st4 4t	s<s<"t7A>t45ttA$t47ttt4t5t9A3t4,$t t t t49t%t4t*!t*%t4?t/A
t4	q	q"q	q""	r+q?9t4?rt4	sr=7t4=st4	s9 s4.t44s99t4<t	t
t4t&t44t>__main__)rD   )__doc__rs   playwright.sync_apir   rj   rg   r   r/   r   r!   r#   r   __name__rW   r   r   <module>r      sQ     /K-
	L(4zx	 zK r   