§
    ƒ¿jÉ!  ã                  óÐ  — d Z ddlmZ ddlZddlmc mZ ddl	Z	ddl
ZddlZddlZddlZddlZddlZddlmZ ddlmZmZ  eej        d¦  «        rej                             d¬¦  «          ee¦  «                             ¦   «         j        j        j        Zed	z  d
z  Z G d„ dej        j        ¦  «        Z dd„Z! G d„ dej"        ¦  «        Z#e$dk    r ej%        ¦   «          dS dS )a¯  
Comprehensive End-to-End (E2E) Test Suite for Reactive i18n & Chat UI (Milestone 2).
Validates live in-place language switching without page reload across WebApp UI:
- Dynamic updates of 8 channel tabs, input placeholder, send button, cooldown badge.
- Multi-language round-trip cycle: VI -> EN -> ZH -> JA -> KO -> VI.
- Zero page reloads (single continuous DOM session).
- Zero uncaught JavaScript errors or console exceptions.
é    )ÚannotationsN)ÚPath)ÚAnyÚListÚreconfigurezutf-8)ÚencodingÚclientÚwebappc                  ó   — e Zd ZdZd
d„Zd	S )ÚQuietHandlerzESilent HTTP handler to suppress server access log noise during tests.ÚformatÚstrÚargsr   ÚreturnÚNonec                ó   — d S ©N© )Úselfr   r   s      úCC:\Projects\FreeExile\tests\e2e\test_i18n_reactive_switching_e2e.pyÚlog_messagezQuietHandler.log_message    s   € Øˆó    N)r   r   r   r   r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r      s.   € € € € € ØOÐOðð ð ð ð ð r   r   r   Úintc                 ó   — t          j         t           j        t           j        ¦  «        5 } |                      d¦  «         t	          |                      ¦   «         d         ¦  «        cddd¦  «         S # 1 swxY w Y   dS )z6Finds an available TCP port for ephemeral test server.)ú	127.0.0.1r   é   N)ÚsocketÚAF_INETÚSOCK_STREAMÚbindr   Úgetsockname)Úss    r   Úget_free_portr'   $   s¥   € å	Œ•v”~¥vÔ'9Ñ	:Ô	:ð '¸aØ	�ŠÐÑ Ô Ð Ý�1—=’=‘?”? 1Ô%Ñ&Ô&ð'ð 'ð 'ð 'ñ 'ô 'ð 'ð 'ð 'ð 'ð 'ð 'øøøð 'ð 'ð 'ð 'ð 'ð 's   ª<A3Á3A7Á:A7c                  ó„   — e Zd ZU dZdZded<   dZded<   dZded	<   d
Zded<   e	dd„¦   «         Z
e	dd„¦   «         Zdd„ZdS )ÚTestI18nReactiveSwitchingE2EzRAutomated E2E test verifying live reactive language switching without page reload.Nz&http.server.ThreadingHTTPServer | NoneÚserverzthreading.Thread | NoneÚserver_threadr   r   Úserver_portÚ r   Ú
server_urlr   r   c                ó   — t          ¦   «         | _        d| j        › �| _        t          j        t
          t          t          ¦  «        ¬¦  «        }t          j	         
                    d| j        f|¦  «        | _	        t          j        | j	        j        d¬¦  «        | _        | j                             ¦   «          t!          j        d¦  «         d S )Nzhttp://127.0.0.1:)Ú	directoryr   T)ÚtargetÚdaemongš™™™™™¹?)r'   r,   r.   Ú	functoolsÚpartialr   r   Ú
WEBAPP_DIRÚhttpr*   ÚThreadingHTTPServerÚ	threadingÚThreadÚserve_foreverr+   ÚstartÚtimeÚsleep)ÚclsÚhandlers     r   Ú
setUpClassz'TestI18nReactiveSwitchingE2E.setUpClass3   sž   € å'™/œ/ˆŒØ>¨S¬_Ð>Ð>ˆŒÝÔ#¥L½CÅ
¹O¼OÐLÑLÔLˆÝ”[×4Ò4°kÀ3Ä?Ð5SÐU\Ñ]Ô]ˆŒ
Ý%Ô,°C´JÔ4LÐUYÐZÑZÔZˆÔØÔ×ÒÑ!Ô!Ð!ÝŒ
�3‰Œˆˆˆr   c                ó|   — | j         r4| j                              ¦   «          | j                              ¦   «          d S d S r   )r*   ÚshutdownÚserver_close)r>   s    r   ÚtearDownClassz*TestI18nReactiveSwitchingE2E.tearDownClass=   sD   € àŒ:ð 	&ØŒJ×ÒÑ!Ô!Ð!ØŒJ×#Ò#Ñ%Ô%Ð%Ð%Ð%ð	&ð 	&r   c                ó  ‡— ddl m} g Š |¦   «         5 }|j                             dd¬¦  «        }|                     ¦   «         }|                     dˆfd„¦  «         dIˆfd„}|                     d|¦  «         |                     | j        › d�¦  «         |                     d¦  «         | 	                    d¦  «         |                     d¦  «         | 	                    d¦  «         | 
                    d¦  «        }| 
                    d¦  «        }| 
                    d¦  «        }|                     dd¦  «        pd}	|                      |dd¦  «         |                      |dd¦  «         |                      |dd¦  «         |                      d|	v pd|	v ¦  «         |                     d d!¦  «         |                     d¦  «         | 	                    d"¦  «        }
|                      |
d#d$¦  «         d%d&d'd(d)d*d+d,d-œ}|                     ¦   «         D ]<\  }}| 
                    d.|› d/�¦  «        }|                      ||d0|› d1|› d2�¦  «         Œ=| 
                    d¦  «        }|                      |d3d4¦  «         |                     dd¦  «        pd}|                      d%|v pd5|v ¦  «         |                     d6¦  «         |                     d¦  «         |                     dd¦  «        pd}|                      d7|v d8|› �¦  «         | 
                    d9¦  «        }|                      |d:d;¦  «         |                     d d<¦  «         |                     d=¦  «         |                      | 
                    d¦  «        d>¦  «         |                      | 
                    d¦  «        d?¦  «         |                     d d@¦  «         |                     d=¦  «         |                      | 
                    d¦  «        dA¦  «         |                      | 
                    d¦  «        dB¦  «         |                     d dC¦  «         |                     d=¦  «         |                      | 
                    d¦  «        dD¦  «         |                      | 
                    d¦  «        dE¦  «         |                     d dF¦  «         |                     d=¦  «         |                      | 
                    d¦  «        d¦  «         |                      | 
                    d¦  «        d¦  «         |                     ¦   «          |                      t%          ‰¦  «        ddG‰› �¦  «         dHdHdH¦  «         dHS # 1 swxY w Y   dHS )JzKRuns full browser headless E2E verification of reactive language switching.r   )Úsync_playwrightÚmsedgeT)ÚchannelÚheadlessÚ	pageerrorc                ó4   •— ‰                      d| › �¦  «        S )NzPageError: )Úappend)ÚerrÚ	js_errorss    €r   ú<lambda>zdTestI18nReactiveSwitchingE2E.test_e2e_live_reactive_language_switching_zero_reload.<locals>.<lambda>M   s   ø€ ¨Y×-=Ò-=Ð>QÈCÐ>QÐ>QÑ-RÔ-R€ r   Úmsgr   r   r   c                ó„   •— | j         dk    r-| j        }d|vr$d|vr"d|vr ‰                     d|› �¦  «         d S d S d S d S d S )NÚerrorÚ404Úfaviconzapi/mapzConsoleError: )ÚtypeÚtextrL   )rP   ÚtxtrN   s     €r   Ú
on_consolezfTestI18nReactiveSwitchingE2E.test_e2e_live_reactive_language_switching_zero_reload.<locals>.on_consoleO   st   ø€ Ø”8˜wÒ&Ð&Øœ(�CØ CÐ'Ð'¨I¸SÐ,@Ð,@ÀYÐVYÐEYÐEYØ!×(Ò(Ð)?¸#Ð)?Ð)?Ñ@Ô@Ð@Ð@Ð@ð 'Ð&à'Ð'Ð,@Ð,@ÐEYÐEYr   Úconsolez/index.htmli�  zu() => { document.getElementById('modal-char-create')?.classList.add('hidden'); window.chatUI?.toggleChatDock(true); }éd   zmwindow.__sessionNavCount = 1; window.addEventListener('beforeunload', () => { window.__sessionNavCount++; });z1#chat-dock .chat-channel-tab[data-channel-id="1"]z1#chat-dock .chat-channel-tab[data-channel-id="2"]z#chat-send-btnz#chat-inputÚplaceholderr-   u   Tháº¿ Giá»›iu$   Initial Tab 1 must be 'Tháº¿ Giá»›i'u	   Khu Vá»±cu!   Initial Tab 2 must be 'Khu Vá»±c'u   Gá»­iu#   Initial Send button must be 'Gá»­i'u   Nháº­p tin nháº¯nz#lang-selectÚenzwindow.__sessionNavCountr    z<Language switch must be 100% reactive with zero page reloadsÚWorldÚZoneÚGuildÚPartyÚWhisperÚSystemÚRecruitÚFeedback)r    é   é   é   é   é   é   é   z.#chat-dock .chat-channel-tab[data-channel-id="z"]zTab z must update to 'z' in EnglishÚSendz!Send button must update to 'Send'zEnter messagez1#chat-dock .chat-channel-tab[data-channel-id="6"]zSystem channel is reservedz(Expected system announcement text, got: z#chat-cooldown-badgeÚLockedz'System channel badge must show 'Locked'Úzhé2   u   ä¸–ç•Œu   å�‘é€�Újau   ãƒ¯ãƒ¼ãƒ«ãƒ‰u   é€�ä¿¡Úkou   ì›”ë“œu   ì „ì†¡Úviz.Detected unhandled JavaScript/console errors: N)rP   r   r   r   )Úplaywright.sync_apirF   ÚchromiumÚlaunchÚnew_pageÚonÚgotor.   Úwait_for_timeoutÚevaluateÚ
inner_textÚget_attributeÚassertEqualÚ
assertTrueÚselect_optionÚitemsÚclickÚcloseÚlen)r   rF   ÚpÚbrowserÚpagerX   Útab1_viÚtab2_viÚsend_btn_viÚplaceholder_viÚnav_sessionÚexpected_en_tabsÚcidÚlabelÚtab_textÚsend_btn_enÚplaceholder_enÚsys_placeholderÚ
badge_textrN   s                      @r   Ú5test_e2e_live_reactive_language_switching_zero_reloadzRTestI18nReactiveSwitchingE2E.test_e2e_live_reactive_language_switching_zero_reloadC   sf  ø€ à7Ð7Ð7Ð7Ð7Ð7à!ˆ	àˆ_ÑÔð s	n !Ø”j×'Ò'°À4Ð'ÑHÔHˆGØ×#Ò#Ñ%Ô%ˆDà�GŠG�KÐ!RÐ!RÐ!RÐ!RÑSÔSÐSðAð Að Að Að Að Að �GŠG�I˜zÑ*Ô*Ð*ð �IŠI˜œÐ5Ð5Ð5Ñ6Ô6Ð6Ø×!Ò! #Ñ&Ô&Ð&ð �MŠMð9ñô ð ð ×!Ò! #Ñ&Ô&Ð&ð �MŠMðbñô ð ð —o’oÐ&YÑZÔZˆGØ—o’oÐ&YÑZÔZˆGØŸ/š/Ð*:Ñ;Ô;ˆKØ!×/Ò/°¸}ÑMÔMÐSÐQSˆNà×Ò˜W nÐ6\Ñ]Ô]Ð]Ø×Ò˜W kÐ3VÑWÔWÐWØ×Ò˜[¨'Ð3XÑYÔYÐYØ�OŠO˜N¨nÐ<ÐeÐ@SÐWeÐ@eÑfÔfÐfð
 ×Ò˜~¨tÑ4Ô4Ð4Ø×!Ò! #Ñ&Ô&Ð&ð Ÿ-š-Ð(BÑCÔCˆKØ×Ò˜[¨!Ð-kÑlÔlÐlð ˜v¨'°gØ ¨i¸Jð ð  Ðð /×4Ò4Ñ6Ô6ð dð d‘
��UØŸ?š?Ð+cÐ\_Ð+cÐ+cÐ+cÑdÔd�Ø× Ò  ¨5Ð2b¸Ð2bÐ2bÈuÐ2bÐ2bÐ2bÑcÔcÐcÐcàŸ/š/Ð*:Ñ;Ô;ˆKØ×Ò˜[¨&Ð2UÑVÔVÐVà!×/Ò/°¸}ÑMÔMÐSÐQSˆNØ�OŠO˜G ~Ð5ÐZ¸ÈNÐ9ZÑ[Ô[Ð[ð
 �JŠJÐJÑKÔKÐKØ×!Ò! #Ñ&Ô&Ð&à"×0Ò0°ÀÑNÔNÐTÐRTˆOØ�OŠOØ,°Ð?ØL¸?ÐLÐLñô ð ð
 ŸšÐ)?Ñ@Ô@ˆJØ×Ò˜Z¨Ð3\Ñ]Ô]Ð]ð ×Ò˜~¨tÑ4Ô4Ð4Ø×!Ò! "Ñ%Ô%Ð%Ø×Ò˜TŸ_š_Ð-`ÑaÔaÐckÑlÔlÐlØ×Ò˜TŸ_š_Ð-=Ñ>Ô>ÀÑIÔIÐIð ×Ò˜~¨tÑ4Ô4Ð4Ø×!Ò! "Ñ%Ô%Ð%Ø×Ò˜TŸ_š_Ð-`ÑaÔaÐcqÑrÔrÐrØ×Ò˜TŸ_š_Ð-=Ñ>Ô>ÀÑIÔIÐIð ×Ò˜~¨tÑ4Ô4Ð4Ø×!Ò! "Ñ%Ô%Ð%Ø×Ò˜TŸ_š_Ð-`ÑaÔaÐckÑlÔlÐlØ×Ò˜TŸ_š_Ð-=Ñ>Ô>ÀÑIÔIÐIð ×Ò˜~¨tÑ4Ô4Ð4Ø×!Ò! "Ñ%Ô%Ð%Ø×Ò˜TŸ_š_Ð-`ÑaÔaÐcqÑrÔrÐrØ×Ò˜TŸ_š_Ð-=Ñ>Ô>ÀÑHÔHÐHð
 �MŠM‰OŒOˆOØ×Ò�S ™^œ^¨QÐ0lÐajÐ0lÐ0lÑmÔmÐmðgs	nð s	nð s	nñ s	nô s	nð s	nð s	nð s	nð s	nð s	nð s	nð s	nøøøð s	nð s	nð s	nð s	nð s	nð s	ns   ”UU9Õ9U=Ö U=)r   r   )r   r   r   r   r*   Ú__annotations__r+   r,   r.   Úclassmethodr@   rD   r”   r   r   r   r)   r)   +   s¾   € € € € € € Ø\Ð\à59€FÐ9Ð9Ð9Ñ9Ø-1€MÐ1Ð1Ð1Ñ1Ø€KÐÐÐÑØ€JÐÐÐÑàðð ð ñ „[ðð ð&ð &ð &ñ „[ð&ð
ynð ynð ynð ynð ynð ynr   r)   Ú__main__)r   r   )&r   Ú
__future__r   ÚbuiltinsÚ@py_builtinsÚ_pytest.assertion.rewriteÚ	assertionÚrewriteÚ
@pytest_arr3   Úhttp.serverr6   r!   Úsysr8   r<   ÚunittestÚpathlibr   Útypingr   r   ÚhasattrÚstdoutr   Ú__file__ÚresolveÚparentÚPROJECT_ROOTr5   r*   ÚSimpleHTTPRequestHandlerr   r'   ÚTestCaser)   r   Úmainr   r   r   ú<module>r­      s·  ððð ð #Ð "Ð "Ð "Ð "Ð "à  € € € € € € € € € € € € Ð Ð Ð Ð Ø Ð Ð Ð Ø €€€Ø 
€
€
€
Ø Ð Ð Ð Ø €€€Ø €€€Ø Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ð Ð à
€7ˆ3Œ:�}Ñ%Ô%ð -Ø„J×Ò GÐÑ,Ô,Ð,àˆt�H‰~Œ~×%Ò%Ñ'Ô'Ô.Ô5Ô<€Ø˜HÑ$ xÑ/€
ðð ð ð ð �4”;Ô7ñ ô ð ð'ð 'ð 'ð 'ðQnð Qnð Qnð Qnð Qn 8Ô#4ñ Qnô Qnð Qnðh ˆzÒÐØ€H„M�O„O€O€O€Oð Ðr   