§
    ¢¾»jpC  ã                   óò   — d Z ddlZddlZddlZddlZddlmZ  ee¦  «                             ¦   «         j	        j	        j	        Z
e
dz  dz  Z G d„ dej        ¦  «        Zedk    r ej        ¦   «          dS dS )	zË
Unit tests for FreeExile Mobile WebApp & PWA Native Simulator.
Verifies Web App Manifest validity, viewport meta tags, safe area insets,
virtual joystick ergonomics, and local server LAN IP resolution.
é    N)ÚPathÚclientÚwebappc                   ó~   — e Zd Ze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dS )ÚTestMobileWebAppc                 ó  — g }t           dz  }|                     ¦   «         rQt          |dd¬¦  «        5 }|                     |                     ¦   «         ¦  «         d d d ¦  «         n# 1 swxY w Y   t          t           dz                       d¦  «        ¦  «        D ]S}t          |dd¬¦  «        5 }|                     |                     ¦   «         ¦  «         d d d ¦  «         n# 1 swxY w Y   ŒTt          t           dz                       d¦  «        ¦  «        D ]S}t          |dd¬¦  «        5 }|                     |                     ¦   «         ¦  «         d d d ¦  «         n# 1 swxY w Y   ŒTd	                     |¦  «        | _        d S )
Nú
index.htmlÚrúutf-8©ÚencodingÚjsz**/*.jsÚcssz**/*.cssú
)	Ú
WEBAPP_DIRÚexistsÚopenÚappendÚreadÚsortedÚglobÚjoinÚbundle)ÚclsÚpartsÚ
index_pathÚfÚjs_fileÚcss_files         ú=C:\Projects\FreeExile\tests\unit\test_mobile_webapp_config.pyÚ
setUpClasszTestMobileWebApp.setUpClass   s  € àˆÝ ,Ñ.ˆ
Ø×ÒÑÔð 	'Ý�j #°Ð8Ñ8Ô8ð '¸AØ—’˜QŸVšV™XœXÑ&Ô&Ð&ð'ð 'ð 'ñ 'ô 'ð 'ð 'ð 'ð 'ð 'ð 'øøøð 'ð 'ð 'ð 'å�z¨DÑ0×6Ò6°yÑAÔAÑBÔBð 	'ð 	'ˆGÝ�g˜s¨WÐ5Ñ5Ô5ð '¸Ø—’˜QŸVšV™XœXÑ&Ô&Ð&ð'ð 'ð 'ñ 'ô 'ð 'ð 'ð 'ð 'ð 'ð 'øøøð 'ð 'ð 'ð 'øå¥
¨UÑ 2×8Ò8¸ÑDÔDÑEÔEð 	'ð 	'ˆHÝ�h ¨gÐ6Ñ6Ô6ð '¸!Ø—’˜QŸVšV™XœXÑ&Ô&Ð&ð'ð 'ð 'ñ 'ô 'ð 'ð 'ð 'ð 'ð 'ð 'øøøð 'ð 'ð 'ð 'øà—Y’Y˜uÑ%Ô%ˆŒ
ˆ
ˆ
s5   ³(A'Á'A+Á.A+Â0(C$Ã$C(	Ã+C(	Ä.(E"Å"E&	Å)E&	c                 óä  — t           dz  }|                      |                     ¦   «         d¦  «         t          |dd¬¦  «        5 }t	          j        |¦  «        }ddd¦  «         n# 1 swxY w Y   |                      |                     d¦  «        d¦  «         |                      d	|                     d
d¦  «        ¦  «         |                      d|¦  «         |                      d|¦  «         dS )zJManifest exists, parses as JSON, and specifies standalone mobile settings.zmanifest.jsonz)manifest.json must exist in client/webappr
   r   r   NÚdisplayÚ
standaloneÚ	landscapeÚorientationÚ ÚnameÚicons)	r   Ú
assertTruer   r   ÚjsonÚloadÚassertEqualÚgetÚassertIn)ÚselfÚmanifest_pathr   Údatas       r    Útest_pwa_manifest_validityz+TestMobileWebApp.test_pwa_manifest_validity!   s  € å" _Ñ4ˆØ�Š˜×,Ò,Ñ.Ô.Ð0[Ñ\Ô\Ð\å�- ¨wÐ7Ñ7Ô7ð 	 ¸1Ý”9˜Q‘<”<ˆDð	 ð 	 ð 	 ñ 	 ô 	 ð 	 ð 	 ð 	 ð 	 ð 	 ð 	 øøøð 	 ð 	 ð 	 ð 	 ð 	×Ò˜Ÿš )Ñ,Ô,¨lÑ;Ô;Ð;Ø�Š�k 4§8¢8¨M¸2Ñ#>Ô#>Ñ?Ô?Ð?Ø�Š�f˜dÑ#Ô#Ð#Ø�Š�g˜tÑ$Ô$Ð$Ð$Ð$s   ÁA&Á&A*Á-A*c                 óT  — t           dz  }|                      |                     ¦   «         d¦  «         | j        }|                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         dS )	zNIndex.html must have apple-mobile-web-app-capable and safe-area-inset styling.r	   z&index.html must exist in client/webappzapple-mobile-web-app-capablezviewport-fit=coverzuser-scalable=nozsafe-area-inset-topzsafe-area-inset-bottomN)r   r*   r   r   r/   ©r0   r   Úhtmls      r    Ú*test_mobile_native_viewport_and_safe_areasz;TestMobileWebApp.test_mobile_native_viewport_and_safe_areas.   s¥   € å ,Ñ.ˆ
Ø�Š˜
×)Ò)Ñ+Ô+Ð-UÑVÔVÐVàŒ{ˆð 	�ŠÐ4°dÑ;Ô;Ð;Ø�ŠÐ*¨DÑ1Ô1Ð1Ø�ŠÐ(¨$Ñ/Ô/Ð/Ø�ŠÐ+¨TÑ2Ô2Ð2Ø�ŠÐ.°Ñ5Ô5Ð5Ð5Ð5ó    c                 ó0  — t           dz  }| j        }|                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         dS )	zHIndex.html must implement floating joystick and ergonomic combat skills.r	   zjoystick-zonezskill-dodgez
skill-firezskill-thunderzskill-frostzbadge-iframeN©r   r   r/   r5   s      r    Ú)test_virtual_joystick_and_combat_controlsz:TestMobileWebApp.test_virtual_joystick_and_combat_controls<   s‘   € å ,Ñ.ˆ
ØŒ{ˆà�Š�o tÑ,Ô,Ð,Ø�Š�m TÑ*Ô*Ð*Ø�Š�l DÑ)Ô)Ð)Ø�Š�o tÑ,Ô,Ð,Ø�Š�m TÑ*Ô*Ð*Ø�Š�n dÑ+Ô+Ð+Ð+Ð+r8   c                 ón   — t           dz  }| j        }dD ] }|                      |› d�|d|› d�¦  «         Œ!dS )z=Webapp dictionary must contain all 9 target global languages.r	   )	ÚviÚenÚzhÚjaÚkoÚthÚdeÚruÚesú:zLanguage key 'z!' must exist in webapp dictionaryNr:   )r0   r   r6   Úlangs       r    Útest_nine_languages_in_webappz.TestMobileWebApp.test_nine_languages_in_webappH   s[   € å ,Ñ.ˆ
ØŒ{ˆàJð 	fð 	fˆDØ�MŠM˜T˜*˜*˜* dÐ,d¸TÐ,dÐ,dÐ,dÑeÔeÐeÐeð	fð 	fr8   c                 ó´  — ddl }ddl}|j                             dt	          t
          dz  ¦  «        ¦  «         ddl}ddlm}  |¦   «         }|                      |t          ¦  «         d}|  	                    t          j        ||¦  «        d|› d�¦  «         |                     |j        ¦  «        }|                      |j        d         j        d	d
¦  «         dS )zXtools/serve_webapp.py get_local_ip must return valid IPv4 and default port must be 8088.r   NÚtools)Úget_local_ipz$^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$zIP 'z%' does not match standard IPv4 formatÚporti˜  z*Default port for serve_webapp must be 8088)ÚsysÚinspectÚpathÚinsertÚstrÚPROJECT_ROOTÚserve_webapprK   ÚassertIsInstancer*   ÚreÚmatchÚ	signatureÚstart_serverr-   Ú
parametersÚdefault)r0   rM   rN   rS   rK   ÚipÚpatternÚsigs           r    Útest_server_local_ip_resolutionz0TestMobileWebApp.test_server_local_ip_resolutionP   sæ   € àˆ
ˆ
ˆ
ØˆˆˆØŒ�Š˜�3�|¨gÑ5Ñ6Ô6Ñ7Ô7Ð7ØÐÐÐØ-Ð-Ð-Ð-Ð-Ð-àˆ\‰^Œ^ˆØ×Ò˜b¥#Ñ&Ô&Ð&à9ˆØ�Š�œ ¨"Ñ-Ô-Ð/_°bÐ/_Ð/_Ð/_Ñ`Ô`Ð`à×Ò Ô 9Ñ:Ô:ˆØ×Ò˜œ¨Ô/Ô7¸Ð?kÑlÔlÐlÐlÐlr8   c                 óp  — t           dz  }| j        }|                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         dD ]}|                      ||d	|› d
�¦  «         ŒdS )zZIndex.html must implement Agent_Orb modal, harvest report, and Multi-LLM provider options.r	   zbtn-open-agent-orbzmodal-agent-orbzmodal-harvest-reportzhud-agent-bannerzhud-agent-thought-containerzagent-thought-stream)ÚLOCAL_TACTICALÚDEEPSEEKÚ
OPENROUTERÚOPENAIÚ	ANTHROPICÚGEMINIÚKIMIz
Provider 'z)' must be available in Agent Orb dropdownNr:   )r0   r   r6   Úproviders       r    Ú"test_agent_orb_ui_and_llm_elementsz3TestMobileWebApp.test_agent_orb_ui_and_llm_elementsa   sØ   € å ,Ñ.ˆ
ØŒ{ˆð 	�ŠÐ*¨DÑ1Ô1Ð1Ø�ŠÐ'¨Ñ.Ô.Ð.Ø�ŠÐ,¨dÑ3Ô3Ð3Ø�ŠÐ(¨$Ñ/Ô/Ð/Ø�ŠÐ3°TÑ:Ô:Ð:Ø�ŠÐ,¨dÑ3Ô3Ð3ð nð 	lð 	lˆHØ�MŠM˜( DÐ*j°xÐ*jÐ*jÐ*jÑkÔkÐkÐkð	lð 	lr8   c                 óÄ  — t           dz  }| j        }|                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d	|¦  «         |                      d
|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         dS )zaIndex.html must implement World Map, Dungeon Instance, and Secret Chamber UI and data structures.r	   zbtn-open-worldmapzmodal-worldmapzbtn-open-dungeonzmodal-dungeonÚCANONICAL_ZONESÚzone_boundless_sanctuaryÚzone_tang_kiem_nhaiÚzone_ancient_sword_barrowÚzone_boundless_sandstormÚzone_blood_scale_ruinsÚzone_five_elements_altarÚzone_abyssal_ice_pondÚzone_infinite_blood_riftÚzone_purgatory_lava_cavernÚzone_boundless_celestial_palacezphongma-current-layerzbtn-advance-phongmazbtn-fight-flame-demonzbtn-trigger-secret-demozsecret-timer-1ÚteleportToZoneNr:   r5   s      r    Ú%test_worldmap_and_dungeon_ui_elementsz6TestMobileWebApp.test_worldmap_and_dungeon_ui_elementsr   s×  € å ,Ñ.ˆ
ØŒ{ˆð 	�ŠÐ)¨4Ñ0Ô0Ð0Ø�ŠÐ&¨Ñ-Ô-Ð-Ø�ŠÐ(¨$Ñ/Ô/Ð/Ø�Š�o tÑ,Ô,Ð,ð 	�ŠÐ'¨Ñ.Ô.Ð.Ø�ŠÐ0°$Ñ7Ô7Ð7Ø�ŠÐ+¨TÑ2Ô2Ð2Ø�ŠÐ1°4Ñ8Ô8Ð8Ø�ŠÐ0°$Ñ7Ô7Ð7Ø�ŠÐ.°Ñ5Ô5Ð5Ø�ŠÐ0°$Ñ7Ô7Ð7Ø�ŠÐ-¨tÑ4Ô4Ð4Ø�ŠÐ0°$Ñ7Ô7Ð7Ø�ŠÐ2°DÑ9Ô9Ð9Ø�ŠÐ7¸Ñ>Ô>Ð>ð 	�ŠÐ-¨tÑ4Ô4Ð4Ø�ŠÐ+¨TÑ2Ô2Ð2Ø�ŠÐ-¨tÑ4Ô4Ð4Ø�ŠÐ/°Ñ6Ô6Ð6Ø�ŠÐ&¨Ñ-Ô-Ð-Ø�ŠÐ&¨Ñ-Ô-Ð-Ð-Ð-r8   c                 ó�  — t           dz  }| j        }|                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d	¦  «         |                      d
|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         dD ]}|                      ||d|› d�¦  «         ŒdS )z^Index.html must implement Settings modal, Feedback button inside settings, and Feedback modal.r	   zbtn-open-settingsz$Settings button must exist in headerzmodal-settingszmodal-settings must existzbtn-close-settingszbtn-close-settings must existzbtn-open-feedback-formz2Feedback trigger button must exist inside Settingszmodal-feedbackzmodal-feedback must existzbtn-close-feedbackzbtn-close-feedback must existzselect-feedback-categoryzCategory selector must existzinput-feedback-titlezTitle input must existztextarea-feedback-contentzContent textarea must existzbtn-submit-feedbackz!Submit feedback button must existzpanel-feedback-historyzHistory panel must existztxt-diag-coordsz(Telemetry coordinates element must exist)Ú
BUG_REPORTÚGAMEPLAY_SUGGESTIONÚBALANCE_ADJUSTMENTÚLOCALIZATIONÚOTHERzFeedback category 'z' must exist in select optionsNr:   )r0   r   r6   Úcats       r    Ú&test_settings_and_feedback_ui_elementsz7TestMobileWebApp.test_settings_and_feedback_ui_elements’   s~  € å ,Ñ.ˆ
ØŒ{ˆð 	�ŠÐ)¨4Ð1WÑXÔXÐXØ�ŠÐ&¨Ð.IÑJÔJÐJØ�ŠÐ*¨DÐ2QÑRÔRÐRð 	�ŠÐ.°Ð6jÑkÔkÐkð 	�ŠÐ&¨Ð.IÑJÔJÐJØ�ŠÐ*¨DÐ2QÑRÔRÐRØ�ŠÐ0°$Ð8VÑWÔWÐWØ�ŠÐ,¨dÐ4LÑMÔMÐMØ�ŠÐ1°4Ð9VÑWÔWÐWØ�ŠÐ+¨TÐ3VÑWÔWÐWØ�ŠÐ.°Ð6PÑQÔQÐQØ�ŠÐ'¨Ð/YÑZÔZÐZð hð 	`ð 	`ˆCØ�MŠM˜#˜tÐ%^¸3Ð%^Ð%^Ð%^Ñ_Ô_Ð_Ð_ð	`ð 	`r8   c                 ój  — t           dz  }| j        }|                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d	¦  «         |                      d
|d¦  «         |                      d|d¦  «         |                      d|d¦  «         dS )zZIndex.html must implement Savage Forge modal, Salvage button, and Feral Corruption button.r	   zmodal-forgezmodal-forge must existzbtn-close-forgezbtn-close-forge must existzbtn-forge-salvagezbtn-forge-salvage must existzbtn-forge-corruptzbtn-forge-corrupt must existztxt-forge-dustz!txt-forge-dust element must existzbar-forge-dustz&bar-forge-dust progress bar must existztxt-forge-destroyed-countz,txt-forge-destroyed-count element must existNr:   r5   s      r    Ú-test_forge_salvage_and_corruption_ui_elementsz>TestMobileWebApp.test_forge_salvage_and_corruption_ui_elements­   sÂ   € å ,Ñ.ˆ
ØŒ{ˆð 	�Š�m TÐ+CÑDÔDÐDØ�ŠÐ'¨Ð/KÑLÔLÐLØ�ŠÐ)¨4Ð1OÑPÔPÐPØ�ŠÐ)¨4Ð1OÑPÔPÐPØ�ŠÐ&¨Ð.QÑRÔRÐRØ�ŠÐ&¨Ð.VÑWÔWÐWØ�ŠÐ1°4Ð9gÑhÔhÐhÐhÐhr8   c                 óÆ  — t           dz  }| j        }|                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d	¦  «         |                      d
|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         dS )z_Index.html must implement Endgame Infinite Atlas modal, node inspector, and content encounters.r	   zmodal-endgame-atlaszmodal-endgame-atlas must existzbtn-open-atlasz btn-open-atlas button must existzbtn-close-atlasz!btn-close-atlas button must existzatlas-canvas-containerz!atlas-canvas-container must existzatlas-node-inspectorzatlas-node-inspector must existzbtn-atlas-activate-devicez+btn-atlas-activate-device button must existzbtn-atlas-clear-nodez&btn-atlas-clear-node button must existzatlas-contents-listz(atlas-contents-list container must existzbadge-atlas-pointszbadge-atlas-points must existNr:   r5   s      r    Ú'test_endgame_infinite_atlas_ui_elementsz8TestMobileWebApp.test_endgame_infinite_atlas_ui_elements»   só   € å ,Ñ.ˆ
ØŒ{ˆð 	�ŠÐ+¨TÐ3SÑTÔTÐTØ�ŠÐ&¨Ð.PÑQÔQÐQØ�ŠÐ'¨Ð/RÑSÔSÐSØ�ŠÐ.°Ð6YÑZÔZÐZØ�ŠÐ,¨dÐ4UÑVÔVÐVØ�ŠÐ1°4Ð9fÑgÔgÐgØ�ŠÐ,¨dÐ4\Ñ]Ô]Ð]Ø�ŠÐ+¨TÐ3]Ñ^Ô^Ð^Ø�ŠÐ*¨DÐ2QÑRÔRÐRÐRÐRr8   c                 óP  — t           dz  }| j        }|                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d	¦  «         |                      d
|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         dS )zZIndex.html must implement unified portal proximity prompts, raycasting, and notice modals.r	   zhud-interaction-promptz(hud-interaction-prompt button must existzinteraction-iconz#interaction-icon element must existzinteraction-titlez$interaction-title element must existzmodal-game-noticez#modal-game-notice dialog must existzbtn-close-noticez"btn-close-notice button must existÚcurrentNearbyInteractionz)currentNearbyInteraction state must existÚexecuteNearbyInteractionz,executeNearbyInteraction function must existÚgetAvailablePortalTargetsz-getAvailablePortalTargets function must existÚenterMapPortalz"enterMapPortal callback must existÚenterWorldGatez"enterWorldGate callback must existÚenterQuestGatez"enterQuestGate callback must existÚshowNoticeModalz#showNoticeModal function must existNr:   r5   s      r    Ú)test_portal_and_device_interaction_systemz:TestMobileWebApp.test_portal_and_device_interaction_systemË   s=  € å ,Ñ.ˆ
ØŒ{ˆð 	�ŠÐ.°Ð6`ÑaÔaÐaØ�ŠÐ(¨$Ð0UÑVÔVÐVØ�ŠÐ)¨4Ð1WÑXÔXÐXØ�ŠÐ)¨4Ð1VÑWÔWÐWØ�ŠÐ(¨$Ð0TÑUÔUÐUð 	�ŠÐ0°$Ð8cÑdÔdÐdØ�ŠÐ0°$Ð8fÑgÔgÐgØ�ŠÐ1°4Ð9hÑiÔiÐiØ�ŠÐ&¨Ð.RÑSÔSÐSØ�ŠÐ&¨Ð.RÑSÔSÐSØ�ŠÐ&¨Ð.RÑSÔSÐSØ�ŠÐ'¨Ð/TÑUÔUÐUÐUÐUr8   c                 ó²  — | j         }|                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d	|d
¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         dS )znIndex.html must implement Server-Authoritative War-Fog & Anti-Bot Procedural Maze modal, canvas, and controls.zbtn-open-war-fogz&btn-open-war-fog HUD button must existzmodal-war-fogzmodal-war-fog must existzbtn-close-war-fogz#btn-close-war-fog button must existzwarfog-canvasz warfog-canvas element must existzbtn-warfog-regenz"btn-warfog-regen button must existzbtn-warfog-stepz!btn-warfog-step button must existzbtn-warfog-break-barricadez,btn-warfog-break-barricade button must existztxt-warfog-sinuosityz'txt-warfog-sinuosity element must existz
war_fog.jsz war_fog.js script tag must existN©r   r/   ©r0   r6   s     r    Ú*test_war_fog_and_anti_bot_maze_ui_elementsz;TestMobileWebApp.test_war_fog_and_anti_bot_maze_ui_elementsà   sä   € àŒ{ˆØ�ŠÐ(¨$Ð0XÑYÔYÐYØ�Š�o tÐ-GÑHÔHÐHØ�ŠÐ)¨4Ð1VÑWÔWÐWØ�Š�o tÐ-OÑPÔPÐPØ�ŠÐ(¨$Ð0TÑUÔUÐUØ�ŠÐ'¨Ð/RÑSÔSÐSØ�ŠÐ2°DÐ:hÑiÔiÐiØ�ŠÐ,¨dÐ4]Ñ^Ô^Ð^Ø�Š�l DÐ*LÑMÔMÐMÐMÐMr8   c                 ój  — | j         }t          dz  }t          |dd¬¦  «        5 }|                     ¦   «         }ddd¦  «         n# 1 swxY w Y   |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d	|¦  «         |                      d
|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         dS )zbWebapp must implement zone boundaries, collision resolution, camera tracking, and prop footprints.r	   r
   r   r   Nzjs/engine/collision_engine.jsÚZONE_BOUNDSrk   ÚminCamWxÚisPositionBlockedÚresolveMovementWithSlidingÚvalidatePropOverlapÚclampPositionToBoundsÚupdateCameraÚfollowSpeedÚdeadzoneÚ	footprintÚisSolidz"zId === 'zone_boundless_sanctuary'z-Water hazard must be scoped to Sanctuary onlyz*Math.abs(moveDistX) >= Math.abs(moveDistY)zTresolveMovementWithSliding must prioritize dominant axis to prevent corner-glitchingu   Bá»Š CHáº¶N Bá»žI RÃ€O Cáº¢NuL   War fog modal notice title must use correct Vietnamese spelling 'RÃ€O Cáº¢N')r   r   r   r   r/   ©r0   r6   r   r   Úindex_contents        r    Ú(test_isometric_collision_and_prop_systemz9TestMobileWebApp.test_isometric_collision_and_prop_systemí   s
  € àŒ{ˆÝ ,Ñ.ˆ
Ý�*˜c¨GÐ4Ñ4Ô4ð 	%¸ØŸFšF™HœHˆMð	%ð 	%ð 	%ñ 	%ô 	%ð 	%ð 	%ð 	%ð 	%ð 	%ð 	%øøøð 	%ð 	%ð 	%ð 	%ð 	�ŠÐ5°}ÑEÔEÐEð 	�Š�m TÑ*Ô*Ð*Ø�ŠÐ0°$Ñ7Ô7Ð7Ø�Š�j $Ñ'Ô'Ð'Ø�ŠÐ)¨4Ñ0Ô0Ð0Ø�ŠÐ2°DÑ9Ô9Ð9Ø�ŠÐ+¨TÑ2Ô2Ð2Ø�ŠÐ-¨tÑ4Ô4Ð4ð 	�Š�n dÑ+Ô+Ð+Ø�Š�m TÑ*Ô*Ð*Ø�Š�j $Ñ'Ô'Ð'ð 	�Š�k 4Ñ(Ô(Ð(Ø�Š�i Ñ&Ô&Ð&ð 	�ŠÐ:¸DÐBqÑrÔrÐrØ�ŠÐBÀDð  Kañ  	bô  	bð  	bð 	�ŠÐ4°dð  =Kñ  	Lô  	Lð  	Lð  	Lð  	Ls   ¤AÁA	ÁA	c                 óp  — | j         }|                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d	|d
¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         t          dz  }t          |dd¬¦  «        5 }|                     ¦   «         }ddd¦  «         n# 1 swxY w Y   |                      d|d¦  «         dS )z_Verifies presence of Beggar's Chronicle and Quest Board modal, buttons, and script integration.zbtn-open-questsz!btn-open-quests must exist in HUDzmodal-story-questsz+modal-story-quests must exist in index.htmlztab-btn-quest-chroniclezChronicle tab button must existztab-btn-quest-listzQuests tab button must existztab-btn-quest-milestonesz Milestones tab button must existzbadge-beggar-stagez%Beggar stage badge element must existzchronicle-acts-listz&Chronicle acts list element must existzquest-list-containerz'Quest list container element must existzmilestone-list-containerz+Milestone list container element must existr	   r
   r   r   Nzjs/ui/story_quest_board.jsz3story_quest_board.js must be imported in index.html)r   r/   r   r   r   rœ   s        r    Ú1test_beggar_chronicle_and_quest_board_ui_elementszBTestMobileWebApp.test_beggar_chronicle_and_quest_board_ui_elements  s  € àŒ{ˆà�ŠÐ'¨Ð/RÑSÔSÐSØ�ŠÐ*¨DÐ2_Ñ`Ô`Ð`Ø�ŠÐ/°Ð7XÑYÔYÐYØ�ŠÐ*¨DÐ2PÑQÔQÐQØ�ŠÐ0°$Ð8ZÑ[Ô[Ð[Ø�ŠÐ*¨DÐ2YÑZÔZÐZØ�ŠÐ+¨TÐ3[Ñ\Ô\Ð\Ø�ŠÐ,¨dÐ4]Ñ^Ô^Ð^Ø�ŠÐ0°$Ð8eÑfÔfÐfå ,Ñ.ˆ
Ý�*˜c¨GÐ4Ñ4Ô4ð 	%¸ØŸFšF™HœHˆMð	%ð 	%ð 	%ñ 	%ô 	%ð 	%ð 	%ð 	%ð 	%ð 	%ð 	%øøøð 	%ð 	%ð 	%ð 	%ð 	�ŠÐ2°MÐCxÑyÔyÐyÐyÐys   Ã3DÄDÄDc                 óP  — | j         }|                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d	|d
¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d¦  «         |                      d|d ¦  «         |                      d!|d"¦  «         |                      d#|d$¦  «         d%S )&zWVerifies presence of Feral NPC system, dialogue modal, choices, and script integration.zmodal-npc-dialoguez+modal-npc-dialogue must exist in index.htmlzdialogue-avatar-imgzdialogue-avatar-img must existzdialogue-speaker-namez dialogue-speaker-name must existzdialogue-speaker-titlez!dialogue-speaker-title must existzdialogue-text-contentz dialogue-text-content must existzdialogue-choices-containerz%dialogue-choices-container must existzbtn-close-dialoguezbtn-close-dialogue must existzjs/ui/dialogue_npc.jsz.dialogue_npc.js must be imported in index.htmlÚCLIENT_NPCSzCLIENT_NPCS catalog must existÚCLIENT_DIALOGUE_TREESz CLIENT_DIALOGUE_TREES must existÚopenNpcDialoguez#openNpcDialogue function must existÚcloseNpcDialoguez$closeNpcDialogue function must existÚgetNpcsInCurrentZonez(getNpcsInCurrentZone function must existÚnpc_doc_co_tan_kiemu0   LÃ£o Ä�á»™c Cá»‘t must be present in NPC catalogÚnpc_van_gioi_thuong_nhanu*   Gian ThÆ°Æ¡ng Cáº©u Kháº¥u must be presentÚnpc_thiet_tuong_au_da_tuu.   Thiáº¿t TÆ°á»£ng Huyáº¿t Ä�á»“ must be presentÚnpc_chan_vo_truyen_thuau"   Huyáº¿t Vu BÃ  BÃ  must be presentÚnpc_sa_mac_du_thanu'   Cuá»“ng NhÃ¢n BÃ£o CÃ¡t must be presentNr�   rŽ   s     r    Ú'test_feral_npc_and_dialogue_ui_elementsz8TestMobileWebApp.test_feral_npc_and_dialogue_ui_elements$  sÄ  € àŒ{ˆð 	�ŠÐ*¨DÐ2_Ñ`Ô`Ð`Ø�ŠÐ+¨TÐ3SÑTÔTÐTØ�ŠÐ-¨tÐ5WÑXÔXÐXØ�ŠÐ.°Ð6YÑZÔZÐZØ�ŠÐ-¨tÐ5WÑXÔXÐXØ�ŠÐ2°DÐ:aÑbÔbÐbØ�ŠÐ*¨DÐ2QÑRÔRÐRð 	�ŠÐ-¨tÐ5eÑfÔfÐfØ�Š�m TÐ+KÑLÔLÐLØ�ŠÐ-¨tÐ5WÑXÔXÐXØ�ŠÐ'¨Ð/TÑUÔUÐUØ�ŠÐ(¨$Ð0VÑWÔWÐWØ�ŠÐ,¨dÐ4^Ñ_Ô_Ð_ð 	�ŠÐ+¨TÐ3eÑfÔfÐfØ�ŠÐ0°$Ð8dÑeÔeÐeØ�ŠÐ0°$Ð8hÑiÔiÐiØ�ŠÐ/°Ð7[Ñ\Ô\Ð\Ø�ŠÐ*¨DÐ2[Ñ\Ô\Ð\Ð\Ð\r8   N)Ú__name__Ú
__module__Ú__qualname__Úclassmethodr!   r3   r7   r;   rH   r^   rh   rv   r~   r€   r‚   r‹   r�   rž   r    r¬   © r8   r    r   r      s3  € € € € € Øð&ð &ñ „[ð&ð%ð %ð %ð6ð 6ð 6ð
,ð 
,ð 
,ðfð fð fðmð mð mð"lð lð lð".ð .ð .ð@`ð `ð `ð6ið ið iðSð Sð Sð Vð Vð Vð*Nð Nð Nð!Lð !Lð !LðFzð zð zð(]ð ]ð ]ð ]ð ]r8   r   Ú__main__)Ú__doc__Úunittestr+   ÚosrU   Úpathlibr   Ú__file__ÚresolveÚparentrR   r   ÚTestCaser   r­   Úmainr±   r8   r    ú<module>r¼      sÜ   ððð ð €€€Ø €€€Ø 	€	€	€	Ø 	€	€	€	Ø Ð Ð Ð Ð Ð àˆt�H‰~Œ~×%Ò%Ñ'Ô'Ô.Ô5Ô<€Ø˜HÑ$ xÑ/€
ðm]ð m]ð m]ð m]ð m]�xÔ(ñ m]ô m]ð m]ð`	 ˆzÒÐØ€H„M�O„O€O€O€Oð Ðr8   