
    u`j5                        d Z ddlmZ ddlZddlZddlZddlZddlmZm	Z	 ddl
mZmZmZmZmZ d
ddZd
ddZddZed	k(  r e e             y)z*Smoke-test the monster review frame board.    )annotationsN)	urlencodeurljoin)WebDriverError
execute_js	free_portrequest_jsonwait_for_driverc                    d}t        j                         |z   }d }t        j                         |k  rt        | ||      }|j                  d      xs i }|j                  d      r_|j                  d      rN|j                  d      r=|j                  d      r,|j                  dd      dkD  r|j                  d	d      dkD  r|S t        j                  d
       t        j                         |k  rt        d|      )NaW  
return {
  readyState: document.readyState,
  title: document.title,
  render: window.HWANSE_LAST_MONSTER_REVIEW_RENDER || null,
  frameRows: document.querySelectorAll('#frameStrip [data-frame-index]').length,
  frameDownloadButtons: document.querySelectorAll('#frameStrip [data-frame-png-download]').length,
  visibleFrameRows: document.querySelectorAll('#frameStrip [data-frame-empty="false"]').length,
  auditText: document.getElementById('frameAuditMeta')?.textContent || '',
  boardSummary: document.getElementById('frameBoardSummary')?.textContent || '',
  infoText: document.getElementById('monsterInfo')?.textContent || '',
  chipText: document.getElementById('attackChips')?.textContent || '',
  skillPayloadSummary: document.getElementById('skillPayloadSummary')?.textContent || '',
  skillPayloadStatus: document.getElementById('skillPayloadStatus')?.textContent || '',
  skillPayloadCards: document.querySelectorAll('#skillPayloadRows .skill-payload-card').length,
  skillPayloadMatchedCards: document.querySelectorAll('#skillPayloadRows .skill-payload-card[data-skill-payload-matched="true"]').length,
  skillPayloadCanvases: document.querySelectorAll('#skillPayloadRows canvas').length,
  skillPayloadParameterTables: document.querySelectorAll('#skillPayloadRows .skill-param-table').length,
  titleText: document.getElementById('monsterTitle')?.textContent || '',
  bodyText: document.body?.innerText || '',
  visibleUtilityPanelCount: Array.from(document.querySelectorAll('details.utility-panel'))
    .filter((node) => node.offsetParent !== null).length,
  bootError: window.HWANSE_BOOT_ERROR || null,
};
render#browserMonsterFrameBoardImplemented,browserMonsterSkillPayloadPreviewImplemented-browserMonsterSkillParameterReviewImplementedframeRectTablesLoaded	frameRowsr   skillPayloadParameterTables皙?z%monster review did not become ready: time	monotonicr   getsleepr   )port
session_idtimeoutscriptdeadline
last_stater   s          &tools/verify_monster_review_browser.pywait_for_reviewr       s    F2 ~~')H"J
..
X
%j&9
)/RJJ<=

IJ

JK

23{A.2<a@1D

3 ..
X
% @O
PP    c                p   t        j                         |z   }d }t        j                         |k  rvt        | |d      }|j                  d      xs i }|j                  d      r|j                  d      |k(  r|S t        j                  d       t        j                         |k  rvt        d| d|      )Nz
return {
  render: window.HWANSE_LAST_MONSTER_REVIEW_RENDER || null,
  titleText: document.getElementById('monsterTitle')?.textContent || '',
  bodyText: document.body?.innerText || '',
  bootError: window.HWANSE_BOOT_ERROR || null,
};
r   monsterCatalogLoadedselectedKeyr   zmonster review did not select z: r   )r   r   assetr   r   r   r   s          r   wait_for_selected_assetr&   @   s    ~~')H"J
..
X
%

 )/R::,-&**]2Ku2T

3! ..
X
%" 9%:.Q
RRr!   c                    t        j                  t              } | j                  dd       | j                  dd       | j	                         }t        j                  d      }|st        d      t               }t        j                  |d	| gt        j                  t        j                  
      }d}	 t        ||       t        |ddddddiiid      }t        |d   d         }t        |dd| ddddd       t        |j                   dd      }t        |dd| ddt#        |j$                  j'                  d       d z   d!|       id       t)        ||      }|d"   }	|	j+                  d#      d$k7  rt        d%|      |	j+                  d&d'      d(k  rt        d)|      |	j+                  d*      d+urt        d,|      |	j+                  d-      st        d.|      |	j+                  d/      d0k7  rt        d1|      |	j+                  d2      d3urt        d4|      |j+                  d5d'      d'k  rt        d6|      |	j+                  d7      d3urt        d8|      |j+                  d9      |j+                  d:      k7  rt        d;|      |	j+                  d<      |j+                  d:      k7  rt        d=|      t-        ||d>      }
|
j+                  d?      st        d@|
      |
d?   j+                  dAd      j/                  dB      st        dC|
      |
d?   j+                  dD      dEk7  rt        dF|
      |
j+                  dG       dH|
j+                  dI       }||
j+                  dJd      vrt        dK|
      dL|j+                  dMd      vr"dN|j+                  dMd      vrt        dO|      |	j+                  dP      st        dQ|      |	j+                  dR      st        dS|      |	j+                  dTd'      dUk  rt        dV|      |	j+                  dWd'      d'k7  s|j+                  dXd'      d'k7  rt        dY|      |	j+                  dZd'      d'k  s|j+                  d[d'      d'k  rt        d\|      |	j+                  d]      d^k7  rt        d_|      |	j+                  d`      d+urt        da|      |	j+                  db      dck7  rt        dd|      |	j+                  de      d3urt        df|      |	j+                  dg      d3urt        dh|      |	j+                  di      d3urt        dj|      |	j+                  dk      dlk7  s|	j+                  dm      dngk7  rt        do|      |	j+                  dp      dqgk7  rt        dr|      |	j+                  ds      d$k7  rt        dt|      |j+                  dud      }dq|vsdv|vrt        dw|      dx|v sdy|v rt        dz|      d{|vrt        d||      d}|vsd~|vsd|vrt        d|      t        ddi      }t        |dd| ddt#        |j$                  j'                  d       d z   d!|       id       t)        ||      }|d"   }|j+                  dk      dk7  rt        d|      |j+                  dp      ddgk7  rt        d|      |j+                  dm      ddgk7  rt        d|      t        ddd      }t        |dd| ddt#        |j$                  j'                  d       d z   d!|       id       t1        ||d      }|d"   }|j+                  dg      d+us|j+                  dk      d'k7  rt        d|      |j+                  d      dlk7  rt        d|      t3        |       	 |r	 t        |dd| d       |j7                          	 |j9                  d       y'# t4        $ r Y /w xY w# t        j:                  $ r |j=                          Y y'w xY w# |r#	 t        |dd| d       n# t4        $ r Y nw xY w|j7                          	 |j9                  d       w # t        j:                  $ r |j=                          Y w w xY wxY w)N)descriptionz--basezhttp://127.0.0.1:8013)defaultz--assetzky_aoWebKitWebDriverz WebKitWebDriver is not installedz--port=)stdoutstderr POSTz/sessioncapabilitiesalwaysMatchbrowserNameMiniBrowser   )r   value	sessionIdz	/session/z/window/rectiP  i  )widthheight
   zspecial-or-reaction)r%   attackz/urlurl/zweb/monster_review.html?r   originalEnemyStatRowCountP   z&stat table count missing from review: manualMonsterGuideEntryCountr   F   z(manual guide count missing from review: frameBoardSkillFrameBoundFz/frame board should remain skill-frame unbound: r   z'latest frame rect tables did not load: frameBoardGeometryModerectz3monster review is still using fallback frame grid: 0browserMonsterFrameBoardUsesLatestGridReviewDataTz2latest monster grid review data is not reflected: visibleFrameRowszno visible frame cells found: framePngDownloadImplementedz)frame PNG download controls are missing: frameDownloadButtonsr   z0each frame should have one PNG download button: framePngDownloadButtonCountz6download marker count does not match the frame board: a  
const button = document.querySelector('#frameStrip [data-frame-png-download]');
const card = button?.closest('[data-frame-index]');
const detail = card?.querySelectorAll('span')[1]?.textContent || '';
let capture = null;
const originalClick = HTMLAnchorElement.prototype.click;
HTMLAnchorElement.prototype.click = function () {
  capture = { href: this.href, download: this.download, target: this.target };
};
try {
  button?.click();
} finally {
  HTMLAnchorElement.prototype.click = originalClick;
}
let pngWidth = 0;
let pngHeight = 0;
if (capture?.href?.startsWith('data:image/png;base64,')) {
  const bytes = atob(capture.href.split(',', 2)[1]);
  const uint32 = (offset) => (
    ((bytes.charCodeAt(offset) << 24) >>> 0)
    | (bytes.charCodeAt(offset + 1) << 16)
    | (bytes.charCodeAt(offset + 2) << 8)
    | bytes.charCodeAt(offset + 3)
  ) >>> 0;
  pngWidth = uint32(16);
  pngHeight = uint32(20);
}
return { capture, detail, pngWidth, pngHeight };
capturez+PNG download button did not create a link: downloadz.pngz"PNG download filename is invalid: target_blankz#mobile fallback target is missing: pngWidthx	pngHeightdetailz.PNG export is not using the native rect size: u   스킬	auditTextskillz+frame audit does not expose unbound state: r   z&skill payload preview did not render: r   z'skill parameter review did not render: battleSkillRecordCountd   z.battle skill records are missing from review:  skillPayloadAnimationCanvasCountskillPayloadCanvasesz4skill payload animation canvases should be removed: skillPayloadParameterTableCountr   z skill parameter tables missing: skillPayloadProjectionModez"removed-animation-parameter-decodez,skill payload projection mode not replaced: originalMonsterSkillBindingz(skill preview should remain unpromoted: battleSkillConsumerStatusz4consumer-narrowed-pointer-base-indexed-skill-recordsz%skill consumer trace status missing: r#   z%monster action catalog did not load: originalEnemyRowBoundz5selected CNS is not bound to its original enemy row: originalAttackSequenceBoundz1selected CNS is not bound to its action scripts: monsterBindingCount   monsterStatRowIndexes:   z$zky_ao should bind to enemy row 58: monsterNamesu   창룡성령z#canonical monster name is missing:  monsterCoverageBoundStatRowCountz'all 80 enemy rows should be CNS-bound: bodyTextu   몬스터 row 1개 연결z'bound monster identity is not visible: u   몬스터명 미연결u   기술명 미연결z/stale global unbound labels are still visible: u"   기술 payload 파라미터 해석z.skill payload parameter panel is not visible: u   대상u   계열u   상태z(skill parameter labels are not visible: r%   zky_gen   z*zky_gen shared CNS binding was flattened: u   현무성령u   지옥의마인z,zky_gen shared monster names are incorrect: ;   B   z!zky_gen stat rows are incorrect: zky_nmkunbound)r%   scopez+review-only zky_nmk should remain unbound: visibleRowCountz+unbound scope should contain only zky_nmk: DELETE      )argparseArgumentParser__doc__add_argument
parse_argsshutilwhichr   r   
subprocessPopenPIPEr
   r	   strr   r%   r   baserstripr    r   r   endswithr&   print	Exception	terminatewaitTimeoutExpiredkill)parserargsdriverr   procr   sessionquerystater   
png_exportnative_sizevisible_textshared_queryshared_stateshared_renderunbound_queryunbound_stateunbound_renders                      r   mainr   W   s	   $$9F
*AB
	84D\\+,F?@@;DVwtf%56zWaWfWfgDJfd#mm]-KLM
 )+67
T6Yzl,#GSWcfIgqstDJJ:OPQ
|4(GDII,,S1C7;STYSZ9[\]	
  j1x::12b8 #I%!STT::4a82= #KE9!UVV::12%? #RSXR[!\]]zz12 #J5)!TUU::./69 #VW\V_!`aa::HIQUU #UV[U^!_``99'+q0 #A%!KLL::34D@ #LUI!VWW99+,		+0FF #STYS\!]^^::34		+8NN #YZ_Yb!cdd 

B ~~i( #Nzn!]^^)$((R8AA&I #Ej^!TUUi $$X.(: #Fzn!UVV#
34Ajnn[6Q5RSjnnXr:: #QR\Q_!`aa599["55'S^`bIc:c #Nui!XYYzzHI #I%!STTzzIJ #J5)!TUU::.2S8 #QRWQZ![\\::8!<AUYYOeghEimnEn #WX]W`!abb::7;q@EIINkmnDostDt #CE9!MNN::237[[ #OPUy!YZZ::34EA #KE9!UVV::126ll #H	!RSS::,-T9 #H	!RSS::-.d: #XY^Xa!bcc::34D@ #TUZT]!^__::+,1VZZ@W5X]_\`5` #Gy!QRR::n%.)99 #Fui!PQQ::89R? #J5)!TUUyyR0-1LT`1` #J5)!TUU#|37LP\7\ #RSXR[!\]]/|C #QRWQZ![\\<'8<+G8[gKg #KE9!UVV '9!56
|4(GDII,,S1C7;ST`Sa9bcd	
 'tZ8$X.23q8 #MlM]!^__^,AR0SS #OP\O_!`aa45"bA #D\DT!UVV!I	"JK
|4(GDII,,S1C7;STaSb9cde	
 0j)L&x056eC~GYGYZoGptuGu #N}N_!`aa/0A5 #N}N_!`aaeT8y-EqQ 		IIaI 	  
 (( 	IIK	 T8y-EqQ 	IIaI (( 	IIK	sy   9\'a $` `) 	`&%`&)#aaca)(c)	a52c4a55c	bc#c?ccc__main__)r9   )r   intr   ry   r   floatreturndict)
r   r   r   ry   r%   ry   r   r   r   r   )r   r   )rq   
__future__r   ro   rt   rv   r   urllib.parser   r   verify_mobile_browser_controlsr   r   r   r	   r
   r    r&   r   __name__
SystemExit r!   r   <module>r      sT    0 "     + )QXS.sl z
TV
 r!   