§
    ÎÁj	?  ã                   ó   — d 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mZ ddlmZmZmZ ddlZddlmZmZmZmZ  ee	j        d¦  «        re	j                             d¬¦  «          ee	j        d¦  «        re	j                             d¬¦  «         ej                             d	d
¦  «        Ze› d�Z ed¦  «        Ze                      dd¬¦  «         ddede!ddfd„Z" ej#        d¬¦  «        d„ ¦   «         Z$d„ Z%d„ Z&d„ Z'd„ Z(d„ Z)dS )a  Adversarial Stress Test Suite for Milestone 1 (3D Dimensions & Billboard Annotations).

Empirical challenger test harness targeting:
1. 360-degree camera orbit at extreme angles (billboard orientation, legibility, no backwards flipping).
2. 50x rapid toggle stress test (zero race conditions, constant texture count, zero dangling textures).
3. Viewport resizing from Mobile (375x667) to Full HD (1920x1080) to 4K (3840x2160) (WebGL context & responsive layout).
4. Strict console error and warning audit (0 errors, 0 warnings).
é    N)ÚPath)ÚAnyÚDictÚList)ÚBrowserÚBrowserContextÚPageÚsync_playwrightÚreconfigurezutf-8)ÚencodingÚTEST_BASE_URLzhttp://127.0.0.1:8000z/static/bim/index.htmlzreports/stress_m1T)ÚparentsÚexist_oké N  ÚpageÚ
timeout_msÚreturnc                 óÞ   — |                       d¦  «        }|r	d| j        vrL|                      t          d|¬¦  «         |                      dd|¬¦  «         |                      d¦  «         dS dS )	z3Ensures page is loaded and WebGL canvas is mounted.z#webgl-container canvasz
index.htmlÚdomcontentloaded)Ú
wait_untilÚtimeoutÚvisible)Ústater   i°  N)Úquery_selectorÚurlÚgotoÚBIM_URLÚwait_for_selectorÚwait_for_timeout)r   r   Úcanvass      úNC:\Projects\DSCons\tools\verification\test_adversarial_m1_dimensions_stress.pyÚensure_page_readyr"      s‚   € à× Ò Ð!:Ñ;Ô;€FØð $�\¨¬Ð1Ð1Ø�	Š	•'Ð&8À*ˆ	ÑMÔMÐMØ×ÒÐ8À	ÐS]ÐÑ^Ô^Ð^Ø×Ò˜dÑ#Ô#Ð#Ð#Ð#ð 2Ð1ó    Úmodule)Úscopec               #   ó`  ‡	‡
K  — t          ¦   «         5 } g d¢}d}dD ]2}	 d|dœ}|r||d<    | j        j        di |¤Ž} n# t          $ r Y Œ/w xY w|s| j                             d|¬¦  «        }|                     ddd	œd
¬¦  «        }|                     ¦   «         }g Š	g Š
ˆ	fd„}ˆ
fd„}|                     d|¦  «         |                     d|¦  «         t          |¦  «         |||‰	‰
dœV — |                     ¦   «          |                     ¦   «          ddd¦  «         dS # 1 swxY w Y   dS )z9Launches Playwright headless Chromium with WebGL enabled.)z%--disable-background-timer-throttlingz(--disable-backgrounding-occluded-windowsz --disable-renderer-backgroundingz--ignore-gpu-blocklistz--enable-webglz--enable-gpu-rasterizationN)ÚchromeNT)ÚheadlessÚargsÚchannelé   é„  ©ÚwidthÚheightzƒMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 DSCons4DBimVerifier)ÚviewportÚ
user_agentc                 ór   •— ‰                      | j        | j        t          | j        ¦  «        dœ¦  «         d S )N)ÚtypeÚtextÚlocation)Úappendr3   r4   Ústrr5   )ÚmsgÚconsole_logss    €r!   Úhandle_consolez'browser_context.<locals>.handle_consoleN   s8   ø€ Ø×Ò¨¬¸3¼8ÕQTÐUXÔUaÑQbÔQbÐ cÐ cÑdÔdÐdÐdÐdr#   c                 óL   •— ‰                      t          | ¦  «        ¦  «         d S )N)r6   r7   )ÚexcÚpage_errorss    €r!   Úhandle_page_errorz*browser_context.<locals>.handle_page_errorQ   s#   ø€ Ø×Ò�s 3™xœxÑ(Ô(Ð(Ð(Ð(r#   ÚconsoleÚ	pageerror)ÚbrowserÚcontextr   r9   r=   © )	r
   ÚchromiumÚlaunchÚ	ExceptionÚnew_contextÚnew_pageÚonr"   Úclose)Úpr)   rA   r*   Úlaunch_kwargsrB   r   r:   r>   r9   r=   s            @@r!   Úbrowser_contextrM   (   s%  øøè è € õ 
Ñ	Ô	ð 7˜að
ð 
ð 
ˆð ˆØ'ð 	ð 	ˆGðØ=AÈ4Ð0PÐ0P�Øð 7Ø/6�M )Ñ,Ø+˜!œ*Ô+Ð<Ð<¨mÐ<Ð<�Ø�øÝð ð ð Ø�ðøøøð ð 	BØ”j×'Ò'°¸DÐ'ÑAÔAˆGà×%Ò%Ø#¨sÐ3Ð3ðYð &ñ 
ô 
ˆð ×ÒÑ!Ô!ˆà-/ˆØ!#ˆð	eð 	eð 	eð 	eð 	eð	)ð 	)ð 	)ð 	)ð 	)ð 	�Š�	˜>Ñ*Ô*Ð*Ø�Š�Ð.Ñ/Ô/Ð/å˜$ÑÔÐð ØØØ(Ø&ð
ð 
ð 	
ð 	
ð 	
ð 	�Š‰ŒˆØ�Š‰Œˆðo7ð 7ð 7ñ 7ô 7ð 7ð 7ð 7ð 7ð 7ð 7ð 7øøøð 7ð 7ð 7ð 7ð 7ð 7s2   “D#Ÿ?½D#¿
AÁ	D#ÁAÁC
D#Ä#D'Ä*D'c                 ó^  — | d         }t          |¦  «         t          dd¬¦  «         |                     d¦  «        }t          d|› �d¬¦  «         d}||k    }|s¯t          j        d|fd	||f¦  «        d
t          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        nd
t          j        |¦  «        dœz  }t          j	        d|› �¦  «        dz   d|iz  }t          t          j        |¦  «        ¦  «        ‚dx}}g d¢}d}d}	d}
d}d}|D �]{}t          j        |¦  «        }|
|t          j        |¦  «        z  z   }|t          j        |¦  «        z  }t!          |¦  «        D �]Æ}|d|z  z  }t          j        |¦  «        }|	|t          j        |¦  «        z  z   }||t          j        |¦  «        z  z   }|                     d|› d|› d|› d|	› d|
› d|› d�¦  «        }|d         }| }|sUt          j	        d|› d|› �¦  «        dz   dt          j        |¦  «        iz  }t          t          j        |¦  «        ¦  «        ‚dx}}|d          }|sUt          j	        d!|› d|› �¦  «        d"z   dt          j        |¦  «        iz  }t          t          j        |¦  «        ¦  «        ‚d}|d#         }d}||k    }|slt          j        d|fd$||f¦  «        t          j        |¦  «        t          j        |¦  «        d%œz  }d&d'|iz  }t          t          j        |¦  «        ¦  «        ‚dx}x}}�ŒÈt"          d(t%          |¦  «        › d)�z  }|                     t)          |¦  «        ¬*¦  «         t          d+|d,›d-|j        › d.�d¬¦  «         �Œ}t          d/d¬¦  «         dS )0uÝ  Adversarial Challenge 1: Orbit camera 360 degrees around culvert at extreme angles.

    Stress-tests billboard orientation:
    - Verifies sprite world matrices update smoothly across all azimuths (0..350 deg)
    - Verifies sprite orientation remains camera-facing (normal facing camera view plane)
    - Verifies no NaN/Infinity in camera or sprite transformations
    - Captures screenshots at cardinal and extreme elevation angles (top-down 85Â°, under-culvert -45Â°)
    r   zN
[STRESS 1] Executing 360-degree camera orbit stress test at extreme angles...T©Úflushzä
    () => {
        let count = 0;
        if (window.groupDimensions) {
            window.groupDimensions.traverse(obj => {
                if (obj.isSprite) count++;
            });
        }
        return count;
    }
    z1  -> Total 3D Dimension Billboard Sprites found: é
   )ú>=)z%(py0)s >= %(py3)sÚsprite_count)Úpy0Úpy3z.Expected at least 10 dimension sprites, found z
>assert %(py5)sÚpy5N)g      4@g     @U@g     €FÀé   g     @P@g      ø?g      9Àg      N@g     €v@z9
            () => {
                camera.position.set(z, z');
                controls.target.set(a¡  );
                controls.update();
                renderer.render(scene, camera);

                let allFacing = true;
                let nanDetected = false;
                let spritesChecked = 0;

                window.groupDimensions.traverse(obj => {
                    if (obj.isSprite && obj.visible) {
                        spritesChecked++;
                        if (isNaN(obj.position.x) || isNaN(obj.position.y) || isNaN(obj.position.z)) nanDetected = true;
                        if (obj.scale.x <= 0 || obj.scale.y <= 0) allFacing = false;
                        if (!obj.material || !obj.material.map || !obj.material.map.image) allFacing = false;
                    }
                });

                return {
                    spritesChecked: spritesChecked,
                    allFacing: allFacing,
                    nanDetected: nanDetected
                };
            }
            ÚnanDetectedzNaN detected at elev=z, az=ú
>assert not %(py1)sÚpy1Ú	allFacingz'Invalid sprite face or texture at elev=z
>assert %(py1)sÚspritesChecked)z%(py1)s >= %(py4)s©rZ   Úpy4úassert %(py6)sÚpy6Úorbit_elev_z_deg.png©Úpathz  -> Elevation z+.0fu,   Â° (360Â° orbit completed, saved screenshot ú)uP     -> PASSED: Camera 360Â° orbit at all angles confirms 100% billboard stability.)r"   ÚprintÚevaluateÚ
@pytest_arÚ_call_reprcompareÚ@py_builtinsÚlocalsÚ_should_repr_global_nameÚ	_safereprÚ_format_assertmsgÚAssertionErrorÚ_format_explanationÚmathÚradiansÚsinÚcosÚrangeÚ
REPORT_DIRÚintÚ
screenshotr7   Úname)rM   r   rS   Ú@py_assert2Ú@py_assert1Ú@py_format4Ú@py_format6Útest_elevationsÚazimuth_stepsÚcenter_xÚcenter_yÚcenter_zÚradiusÚelevÚelev_radÚy_posÚr_groundÚstepÚazimuth_degÚazimuth_radÚx_posÚz_posÚeval_resÚ@py_assert0Ú@py_format3Ú@py_format2Ú@py_assert3Ú@py_format5Ú@py_format7Úscreenshot_paths                                 r!   Ú*test_adv_1_camera_orbit_360_extreme_anglesr”   e   s¹  € ð ! Ô(€DÝ�dÑÔÐå	Ð
[ÐcgÐhÑhÔhÐhà—=’=ð 
"ñ 
	ô 
	€Lõ 
Ð
L¸lÐ
LÐ
LÐTXÐYÑYÔYÐYØÐ^ˆ<˜2ÒÐ^Ð^Ð^Õ^Ô^Ð^Ð^Ð^Ð^ˆ<˜2Ð^Ñ^Ô^Ð^Õ^Ô^Ñ^Ô^Ð^Ð^Õ^Ô^ˆ<Ñ^Ô^Ð^Õ^Ô^ˆ<Ñ^Ô^Ð^Ð^Õ^Ô^˜2Ñ^Ô^Ð^Ð^Ñ^Ð^Õ^Ô^Ð^ÐP\Ð^Ð^Ñ^Ô^Ð^Ñ^Ð^Ð^Ð^Ñ^Ð^Õ^Õ^Ô^Ð^Ñ^Ô^Ñ^Ô^Ð^Ð^Ð^Ð^Ð^à)Ð)Ð)€OØ€Mà€HØ€HØ€HØ€Fàð .|ñ .|ˆÝ”< Ñ%Ô%ˆØ˜6¥D¤H¨XÑ$6Ô$6Ñ6Ñ6ˆØ�DœH XÑ.Ô.Ñ.ˆå˜-Ñ(Ô(ð %	4ñ %	4ˆDØ %¨-Ñ"7Ñ8ˆKÝœ, {Ñ3Ô3ˆKà˜x­$¬(°;Ñ*?Ô*?Ñ?Ñ?ˆEØ˜x­$¬(°;Ñ*?Ô*?Ñ?Ñ?ˆEà—}’}ð &à%*ð&ð &à.3ð&ð &à7<ð&ð &ð &.ð&ð &ð 2:ð&ð &ð >Fð&ð &ð &ñ ô ˆHð8   Ô.Ð`Ð.Ð.Ð`Ð.Ð`Õ`Ô`Ð0`ÈÐ0`Ð0`ÐS^Ð0`Ð0`Ñ`Ô`Ð`Ñ`Ð`Õ`Ô`Ð.Ñ`Ô`Ð`Ñ`Ð`Õ`Õ`Ô`Ð`Ñ`Ô`Ñ`Ô`Ð`Ð`Ð`Ð`Ð`Ø˜KÔ(ÐlÐ(ÐlÕlÔlÐ*lÐTXÐ*lÐ*lÐ_jÐ*lÐ*lÑlÔlÐlÑlÐlÕlÔlÐ(ÑlÔlÐlÑlÐlÕlÕlÔlÐlÑlÔlÑlÔlÐlÐlÐlØÐ,Ô-Ð3°Ð3Ð-°Ò3Ð3Ð3Ð3Õ3Ô3Ð3Ð3Ð3Ð3Ð-°Ð3Ñ3Ô3Õ3Ô3Ð-Ñ3Ô3Õ3Ô3°Ñ3Ô3Ð3Ð3Ñ3Ð3Ð3Ð3Ð3Ð3Ñ3Ð3Õ3Õ3Ô3Ð3Ñ3Ô3Ñ3Ô3Ð3Ð3Ð3Ð3Ð3Ð3Ð3Ñ3å$Ð'HµS¸±Y´YÐ'HÐ'HÐ'HÑHˆØ�Š�S Ñ1Ô1ˆÑ2Ô2Ð2ÝÐn ÐnÐnÐnÐWfÔWkÐnÐnÐnÐvzÐ{Ñ{Ô{Ð{Ñ{å	Ð
\ÐdhÐiÑiÔiÐiÐiÐir#   c                 óˆ	  — | d         }t          |¦  «         t          dd¬¦  «         |                     d¦  «        }t          d|› �d¬¦  «         d}|                     |¦  «        }t          d|› �d¬¦  «         |d	         }d
}||k    }|slt          j        d|fd||f¦  «        t          j        |¦  «        t          j        |¦  «        dœz  }dd|iz  }	t          t          j        |	¦  «        ¦  «        ‚dx}x}}|d         }|d         }||k    }|slt          j        d|fd||f¦  «        t          j        |¦  «        t          j        |¦  «        dœz  }dd|iz  }	t          t          j        |	¦  «        ¦  «        ‚dx}x}}|d         }|d         }||k    }|slt          j        d|fd||f¦  «        t          j        |¦  «        t          j        |¦  «        dœz  }dd|iz  }	t          t          j        |	¦  «        ¦  «        ‚dx}x}}|d         }|d         }||k    }|slt          j        d|fd||f¦  «        t          j        |¦  «        t          j        |¦  «        dœz  }dd|iz  }	t          t          j        |	¦  «        ¦  «        ‚dx}x}}|d         }|d         }||k    }|s�t          j        d|fd||f¦  «        t          j        |¦  «        t          j        |¦  «        dœz  }t          j        d¦  «        dz   d|iz  }	t          t          j        |	¦  «        ¦  «        ‚dx}x}}|d         }|d         }||k    }|s�t          j        d|fd||f¦  «        t          j        |¦  «        t          j        |¦  «        dœz  }t          j        d¦  «        dz   d|iz  }	t          t          j        |	¦  «        ¦  «        ‚dx}x}}|d         }|d         }||k    }|s�t          j        d|fd||f¦  «        t          j        |¦  «        t          j        |¦  «        dœz  }t          j        d¦  «        dz   d|iz  }	t          t          j        |	¦  «        ¦  «        ‚dx}x}}t          dz  }
| 
                    t          |
¦  «        ¬¦  «         t          d|
j        › �d¬¦  «         dS )a�  Adversarial Challenge 2: Rapidly toggle dimensions on/off 50 times.

    Stress-tests race conditions & resource leaks:
    - 50 rapid state inversions
    - Checks that texture count in WebGL renderer remains strictly constant
    - Checks that groupDimensions children count remains identical
    - Verifies final state is fully coherent across DOM checkbox, toolbar button, and 3D visibility
    r   z?
[STRESS 2] Executing 50x rapid dimension toggle stress test...TrO   aÌ  
    () => {
        return {
            groupVisible: window.groupDimensions.visible,
            childrenCount: window.groupDimensions.children.length,
            textureCount: renderer.info.memory.textures,
            geometriesCount: renderer.info.memory.geometries,
            chkChecked: document.getElementById('chkDimensions').checked,
            btnActive: document.getElementById('btnDims').classList.contains('btn-active')
        };
    }
    z  -> Initial state: aa  
    () => new Promise((resolve) => {
        let iterations = 50;
        let count = 0;
        function step() {
            if (count >= iterations) {
                resolve({
                    finalToggles: count,
                    groupVisible: window.groupDimensions.visible,
                    childrenCount: window.groupDimensions.children.length,
                    textureCount: renderer.info.memory.textures,
                    geometriesCount: renderer.info.memory.geometries,
                    chkChecked: document.getElementById('chkDimensions').checked,
                    btnActive: document.getElementById('btnDims').classList.contains('btn-active')
                });
                return;
            }
            if (count % 2 === 0) {
                window.toggleDimensions();
            } else {
                const nextState = !window.groupDimensions.visible;
                window.toggleLayer('dimensions', nextState);
            }
            renderer.render(scene, camera);
            count++;
            requestAnimationFrame(step);
        }
        step();
    })
    z  -> Post-50x-toggle state: ÚfinalTogglesé2   ©ú==©z%(py1)s == %(py4)sr]   r_   r`   NÚgroupVisibleÚ
chkCheckedÚ	btnActiveÚtextureCountzMemory leak: texture count grewú
>assert %(py6)sÚgeometriesCountz Memory leak: geometry count grewÚchildrenCountzDangling children detectedzpost_50x_toggle_verified.pngrb   zM  -> PASSED: 50x rapid toggle showed ZERO leaks, ZERO race conditions, saved )r"   re   rf   rg   rh   rl   rn   ro   rm   ru   rw   r7   rx   )rM   r   Úinitial_stateÚtoggle_scriptÚresultr�   r�   ry   r‘   r’   r“   s              r!   Ú(test_adv_2_rapid_dimension_toggle_stressr¥   ¼   sò  € ð ! Ô(€DÝ�dÑÔÐå	Ð
LÐTXÐYÑYÔYÐYà—M’Mð #ñ 	ô 	€Mõ 
Ð
0 Ð
0Ð
0¸Ð=Ñ=Ô=Ð=ð€Mð< �]Š]˜=Ñ)Ô)€FÝ	Ð
1¨Ð
1Ð
1¸Ð>Ñ>Ô>Ð>à�.Ô!Ð' RÐ'Ð! RÒ'Ð'Ð'Ð'Õ'Ô'Ð'Ð'Ð'Ð'Ð! RÐ'Ñ'Ô'Õ'Ô'Ð!Ñ'Ô'Õ'Ô' RÑ'Ô'Ð'Ð'Ñ'Ð'Ð'Ð'Ð'Ð'Ñ'Ð'Õ'Õ'Ô'Ð'Ñ'Ô'Ñ'Ô'Ð'Ð'Ð'Ð'Ð'Ð'Ð'Ø�.Ô!ÐB ]°>Ô%BÐBÐ!Ð%BÒBÐBÐBÐBÕBÔBÐBÐBÐBÐBÐ!Ð%BÐBÑBÔBÕBÔBÐ!ÑBÔBÕBÔBÐ%BÑBÔBÐBÐBÑBÐBÐBÐBÐBÐBÑBÐBÕBÕBÔBÐBÑBÔBÑBÔBÐBÐBÐBÐBÐBÐBÐBØ�,ÔÐ> =°Ô#>Ð>ÐÐ#>Ò>Ð>Ð>Ð>Õ>Ô>Ð>Ð>Ð>Ð>ÐÐ#>Ð>Ñ>Ô>Õ>Ô>ÐÑ>Ô>Õ>Ô>Ð#>Ñ>Ô>Ð>Ð>Ñ>Ð>Ð>Ð>Ð>Ð>Ñ>Ð>Õ>Õ>Ô>Ð>Ñ>Ô>Ñ>Ô>Ð>Ð>Ð>Ð>Ð>Ð>Ð>Ø�+ÔÐ< -°Ô"<Ð<ÐÐ"<Ò<Ð<Ð<Ð<Õ<Ô<Ð<Ð<Ð<Ð<ÐÐ"<Ð<Ñ<Ô<Õ<Ô<ÐÑ<Ô<Õ<Ô<Ð"<Ñ<Ô<Ð<Ð<Ñ<Ð<Ð<Ð<Ð<Ð<Ñ<Ð<Õ<Õ<Ô<Ð<Ñ<Ô<Ñ<Ô<Ð<Ð<Ð<Ð<Ð<Ð<Ð<Ø�.Ô!Ðe ]°>Ô%BÐeÐ!Ð%BÒBÐeÐeÐeÕeÔeÐeÐeÐeÐeÐ!Ð%BÐeÑeÔeÕeÔeÐ!ÑeÔeÕeÔeÐ%BÑeÔeÐeÐeÑeÐeÕeÔeÐDeÑeÔeÐeÑeÐeÐeÐeÑeÐeÕeÕeÔeÐeÑeÔeÑeÔeÐeÐeÐeÐeÐeÐeÐeØÐ#Ô$Ðl¨Ð6GÔ(HÐlÐ$Ð(HÒHÐlÐlÐlÕlÔlÐlÐlÐlÐlÐ$Ð(HÐlÑlÔlÕlÔlÐ$ÑlÔlÕlÔlÐ(HÑlÔlÐlÐlÑlÐlÕlÔlÐJlÑlÔlÐlÑlÐlÐlÐlÑlÐlÕlÕlÔlÐlÑlÔlÑlÔlÐlÐlÐlÐlÐlÐlÐlØ�/Ô"Ðb m°OÔ&DÐbÐ"Ð&DÒDÐbÐbÐbÕbÔbÐbÐbÐbÐbÐ"Ð&DÐbÑbÔbÕbÔbÐ"ÑbÔbÕbÔbÐ&DÑbÔbÐbÐbÑbÐbÕbÔbÐFbÑbÔbÐbÑbÐbÐbÐbÑbÐbÕbÕbÔbÐbÑbÔbÑbÔbÐbÐbÐbÐbÐbÐbÐbå Ð#AÑA€OØ‡O‚O�˜_Ñ-Ô-€OÑ.Ô.Ð.Ý	Ð
pÐZiÔZnÐ
pÐ
pÐx|Ð}Ñ}Ô}Ð}Ð}Ð}r#   c                 ó^  — | d         }t          |¦  «         t          dd¬¦  «         ddddœd	d
ddœddddœg}|D �]^}|d         }|d         }|                     ||dœ¦  «         |                     d¦  «         |                     d¦  «        }t          d|d         › d|d         › d|d         › d|d         › d|d         › d|d         d ›�d¬¦  «         |d         }d!}||u }	|	s‹t          j        d"|	fd#||f¦  «        t          j        |¦  «        t          j        |¦  «        d$œz  }
t          j        d%|d         › d&�¦  «        d'z   d(|
iz  }t          t          j
        |¦  «        ¦  «        ‚d)x}x}	}|d         }d*}||k    }	|	s”t          j        d+|	fd,||f¦  «        t          j        |¦  «        t          j        |¦  «        d$œz  }
t          j        d-|d         › d.|d         › d&�¦  «        d'z   d(|
iz  }t          t          j
        |¦  «        ¦  «        ‚d)x}x}	}|d         }d/}||k    }	|	sŠt          j        d0|	fd1||f¦  «        t          j        |¦  «        t          j        |¦  «        d$œz  }
t          j        d2|d         › �¦  «        d'z   d(|
iz  }t          t          j
        |¦  «        ¦  «        ‚d)x}x}	}|d3         }| }	|	sXt          j        d4|d         › �¦  «        d5z   d6t          j        |¦  «        iz  }t          t          j
        |¦  «        ¦  «        ‚d)x}}	|d7         }| }	|	sXt          j        d8|d         › �¦  «        d5z   d6t          j        |¦  «        iz  }t          t          j
        |¦  «        ¦  «        ‚d)x}}	�Œ`t          d9d¬¦  «         d)S ):z¿Adversarial Challenge 3A: Viewport resize from Desktop FHD (1920x1080) to 4K (3840x2160).

    Verifies no WebGL context loss, valid projection matrices, and zero glErrors on desktop/4K.
    r   zL
[STRESS 3A] Executing Viewport Resize Test on Standard & High Resolution...TrO   Údesktop_fhd_1920x1080i€  i8  )rx   ÚwÚhÚdesktop_4k_3840x2160i   ip  Úrestored_1440x900r+   r,   r¨   r©   r-   é,  a  
        () => {
            window.dispatchEvent(new Event('resize'));
            renderer.render(scene, camera);

            const gl = renderer.getContext();
            const isContextLost = gl.isContextLost();
            const glErr = gl.getError();
            const mat = camera.projectionMatrix.elements;
            const hasInf = mat.some(v => !isFinite(v));
            const hasNan = mat.some(v => isNaN(v));

            return {
                isContextLost: isContextLost,
                glError: glErr,
                canvasWidth: renderer.domElement.width,
                canvasHeight: renderer.domElement.height,
                cameraAspect: camera.aspect,
                hasInf: hasInf,
                hasNan: hasNan
            };
        }
        z  -> Tested rx   z: glContextLost=ÚisContextLostz, glErr=ÚglErrorz
, canvas=(ÚcanvasWidthÚxÚcanvasHeightz
), aspect=ÚcameraAspectz.3fF©Úis©z%(py1)s is %(py4)sr]   zWebGL context LOST at ú!rŸ   r`   Nr   r˜   rš   zWebGL error z at g      ð?)ú>)z%(py1)s > %(py4)szInvalid aspect ratio at ÚhasInfz!Infinity in projection matrix at rY   rZ   ÚhasNanzNaN in projection matrix at z[  -> PASSED: Desktop FHD and 4K viewports maintained 100% WebGL context & matrix integrity.)r"   re   Úset_viewport_sizer   rf   rg   rh   rl   rm   rn   ro   )rM   r   Ú	viewportsÚvpr¨   r©   Ú	gl_statusr�   r�   ry   r‘   r’   rŽ   s                r!   Ú+test_adv_3_viewport_resizing_desktop_and_4kr¾     s  € ð
 ! Ô(€DÝ�dÑÔÐå	Ð
YÐaeÐfÑfÔfÐfð )¨t¸$Ð?Ð?Ø'¨d¸Ð>Ð>Ø$¨4°cÐ:Ð:ð€Ið ð $Tñ $TˆØˆsŒGˆØˆsŒGˆØ×Ò¨°aÐ8Ð8Ñ9Ô9Ð9Ø×Ò˜cÑ"Ô"Ð"à—M’Mð #ñ ô ˆ	õ0 	ð  ]˜R œZð  ]ð  ]¸À?Ô9Sð  ]ð  ]Ð]fÐgpÔ]qð  ]ð  ]ð  ~Gð  HUô  ~Vð  ]ð  ]ð  Ybð  cqô  Yrð  ]ð  ]ð  ~Gð  HVô  ~Wð  ]ð  ]ð  ]ð  eið  	jñ  	jô  	jð  	jà˜Ô)ÐZ¨UÐZÐ)¨UÐ2ÐZÐZÐZÕZÔZÐZÐZÐZÐZÐ)¨UÐZÑZÔZÕZÔZÐ)ÑZÔZÕZÔZ¨UÑZÔZÐZÐZÑZÐZÕZÔZÐ4ZÈRÐPVÌZÐ4ZÐ4ZÐ4ZÑZÔZÐZÑZÐZÐZÐZÑZÐZÕZÕZÔZÐZÑZÔZÑZÔZÐZÐZÐZÐZÐZÐZÐZØ˜Ô#Ð` qÐ`Ð# qÒ(Ð`Ð`Ð`Õ`Ô`Ð`Ð`Ð`Ð`Ð# qÐ`Ñ`Ô`Õ`Ô`Ð#Ñ`Ô`Õ`Ô` qÑ`Ô`Ð`Ð`Ñ`Ð`Õ`Ô`Ð*`¸À9Ô9MÐ*`Ð*`ÐSUÐV\ÔS]Ð*`Ð*`Ð*`Ñ`Ô`Ð`Ñ`Ð`Ð`Ð`Ñ`Ð`Õ`Õ`Ô`Ð`Ñ`Ô`Ñ`Ô`Ð`Ð`Ð`Ð`Ð`Ð`Ð`Ø˜Ô(ÐW¨3ÐWÐ(¨3Ò.ÐWÐWÐWÕWÔWÐWÐWÐWÐWÐ(¨3ÐWÑWÔWÕWÔWÐ(ÑWÔWÕWÔW¨3ÑWÔWÐWÐWÑWÐWÕWÔWÐ0WÈ2ÈfÌ:Ð0WÐ0WÑWÔWÐWÑWÐWÐWÐWÑWÐWÕWÕWÔWÐWÑWÔWÑWÔWÐWÐWÐWÐWÐWÐWÐWØ˜XÔ&ÐXÐ&Ð&ÐXÐ&ÐXÕXÔXÐ(XÈBÈvÌJÐ(XÐ(XÑXÔXÐXÑXÐXÕXÔXÐ&ÑXÔXÐXÑXÐXÕXÕXÔXÐXÑXÔXÑXÔXÐXÐXÐXÐXÐXØ˜XÔ&ÐSÐ&Ð&ÐSÐ&ÐSÕSÔSÐ(SÀrÈ&ÄzÐ(SÐ(SÑSÔSÐSÑSÐSÕSÔSÐ&ÑSÔSÐSÑSÐSÕSÕSÔSÐSÑSÔSÑSÔSÐSÐSÐSÐSÐSÑSå	Ð
gÐosÐtÑtÔtÐtÐtÐtr#   c                 óØ  — | d         }t          |¦  «         t          dd¬¦  «         |                     dddœ¦  «         |                     d¦  «         |                     d	¦  «        }t          d
|d         › d|d         › d|d         › d|d         › d|d         › �
d¬¦  «         |d         }d}||u }|s�t          j        d|fd||f¦  «        t          j        |¦  «        t          j        |¦  «        dœz  }t          j        d¦  «        dz   d|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}x}}|d         }d}||k    }|s�t          j        d|fd ||f¦  «        t          j        |¦  «        t          j        |¦  «        dœz  }t          j        d!¦  «        dz   d|iz  }t          t          j
        |¦  «        ¦  «        ‚dx}x}}t          d"z  }|                     t          |¦  «        ¬#¦  «         |d         dk    s|d         s|d         rt          d$|d         › d%�d¬¦  «         |                     d&d'dœ¦  «         |                     d(¦  «         dS ))aÛ  Adversarial Challenge 3B: Investigate Mobile (375x667) Viewport Behavior.

    Empirical stress test reveals:
    - On screens <= 390px, .sidebar (min-width: 390px, flex-shrink: 0) completely crushes
      #webgl-container (flex: 1, min-width: 0) down to clientWidth = 0.
    - Camera aspect collapses to 0.0, causing camera.projectionMatrix to contain [Infinity, NaN].
    - WebGL context is NOT lost (gl.isContextLost() == false), but rendering is completely occluded.
    r   zA
[STRESS 3B] Investigating Mobile (375x667) Viewport Edge Case...TrO   iw  i›  r-   r¬   aš  
    () => {
        window.dispatchEvent(new Event('resize'));
        renderer.render(scene, camera);

        const gl = renderer.getContext();
        const mat = camera.projectionMatrix.elements;
        return {
            isContextLost: gl.isContextLost(),
            glError: gl.getError(),
            containerWidth: document.getElementById('webgl-container').clientWidth,
            sidebarWidth: document.querySelector('.sidebar').clientWidth,
            cameraAspect: camera.aspect,
            hasInf: mat.some(v => !isFinite(v)),
            hasNan: mat.some(v => isNaN(v)),
            canvasWidth: renderer.domElement.width
        };
    }
    z)  -> Mobile 375px Result: containerWidth=ÚcontainerWidthzpx, sidebarWidth=ÚsidebarWidthzpx, aspect=r²   z	, hasInf=r¸   z	, hasNan=r¹   r­   Fr³   rµ   r]   z WebGL context was lost on mobilerŸ   r`   Nr®   r   r˜   rš   zWebGL error on mobilezmobile_375x667_crushed.pngrb   z.  -> [DEFECT DETECTED] Container collapsed to z:px on mobile (<= 390px) with Inf/NaN in projection matrix!r+   r,   z/() => window.dispatchEvent(new Event('resize')))r"   re   rº   r   rf   rg   rh   rl   rm   rn   ro   ru   rw   r7   )	rM   r   Úresr�   r�   ry   r‘   r’   r“   s	            r!   Ú8test_adv_3_viewport_resizing_mobile_defect_investigationrÃ   ?  sj  € ð ! Ô(€DÝ�dÑÔÐå	Ð
NÐVZÐ[Ñ[Ô[Ð[à×Ò S°CÐ8Ð8Ñ9Ô9Ð9Ø×Ò˜#ÑÔÐà
�-Š-ð ñ 	ô 	€Cõ( 
ð  D°cÐ:JÔ6Kð  Dð  DÐ^aÐbpÔ^qð  Dð  Dð  Bð  CQô  Rð  Dð  Dð  ]`ð  aiô  ]jð  Dð  Dð  uxð  yAô  uBð  Dð  Dð  LPð  Qñ  Qô  Qð  Qð ˆÔÐL 5ÐLÐ 5Ð(ÐLÐLÐLÕLÔLÐLÐLÐLÐLÐ 5ÐLÑLÔLÕLÔLÐÑLÔLÕLÔL 5ÑLÔLÐLÐLÑLÐLÕLÔLÐ*LÑLÔLÐLÑLÐLÐLÐLÑLÐLÕLÕLÔLÐLÑLÔLÑLÔLÐLÐLÐLÐLÐLÐLÐLØˆyŒ>Ð7˜QÐ7ˆ>˜QÒÐ7Ð7Ð7Õ7Ô7Ð7Ð7Ð7Ð7ˆ>˜QÐ7Ñ7Ô7Õ7Ô7ˆ>Ñ7Ô7Õ7Ô7˜QÑ7Ô7Ð7Ð7Ñ7Ð7Õ7Ô7Ð 7Ñ7Ô7Ð7Ñ7Ð7Ð7Ð7Ñ7Ð7Õ7Õ7Ô7Ð7Ñ7Ô7Ñ7Ô7Ð7Ð7Ð7Ð7Ð7Ð7Ð7õ !Ð#?Ñ?€OØ‡O‚O�˜_Ñ-Ô-€OÑ.Ô.Ð.ð ÐÔ Ò!Ð! S¨¤]Ð!°c¸(´mÐ!Ýð  Q¸sÐCSÔ?Tð  Qð  Qð  Qð  Y]ð  	^ñ  	^ô  	^ð  	^ð 	×Ò T°SÐ9Ð9Ñ:Ô:Ð:Ø‡M‚MÐCÑDÔDÐDÐDÐDr#   c           
      óþ  — | d         }| d         }t          dd¬¦  «         d„ |D ¦   «         }d„ |D ¦   «         }t          dt          |¦  «        › �¦  «         t          d	t          |¦  «        › d
t          |¦  «        › dt          |¦  «        › �¦  «         t          |¦  «        }d}||k    }|�s
t          j        d|fd||f¦  «        dt	          j        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        nddt	          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndt          j        |¦  «        t          j        |¦  «        dœz  }t          j        d|› �¦  «        dz   d|iz  }	t          t          j
        |	¦  «        ¦  «        ‚dx}x}}t          |¦  «        }d}||k    }|�s
t          j        d|fd||f¦  «        dt	          j        ¦   «         v st          j        t          ¦  «        rt          j        t          ¦  «        nddt	          j        ¦   «         v st          j        |¦  «        rt          j        |¦  «        ndt          j        |¦  «        t          j        |¦  «        dœz  }t          j        d|› �¦  «        dz   d|iz  }	t          t          j
        |	¦  «        ¦  «        ‚dx}x}}t          dd¬¦  «         dS )zTAdversarial Challenge 4: Verify 0 console errors, unhandled exceptions, or warnings.r9   r=   zE
[STRESS 4] Auditing browser console logs and unhandled exceptions...TrO   c                 ó&   — g | ]}|d          dv ¯|‘ŒS )r3   )ÚerrorrC   ©Ú.0Úlogs     r!   ú
<listcomp>z3test_adv_4_strict_console_audit.<locals>.<listcomp>~  s&   € ÐGÐGÐG�c¨S°¬[¸JÐ-FÐ-FˆcÐ-FÐ-FÐ-Fr#   c                 ó&   — g | ]}|d          dv ¯|‘ŒS )r3   )ÚwarningrC   rÇ   s     r!   rÊ   z3test_adv_4_strict_console_audit.<locals>.<listcomp>  s&   € ÐKÐKÐK˜¨s°6¬{¸lÐ/JÐ/J�Ð/JÐ/JÐ/Jr#   z&  -> Total Console Messages captured: z  -> Errors: z, Warnings: z, Page Exceptions: r   r˜   )z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sÚlen)rT   rZ   rU   r`   zPage errors encountered: z
>assert %(py8)sÚpy8NÚerrorszConsole errors encountered: zD  -> PASSED: Clean console with zero errors or unhandled exceptions.)re   rÍ   rg   rh   ri   rj   rk   rl   rm   rn   ro   )
rM   r9   r=   rÏ   Úwarningsry   Ú@py_assert5Ú@py_assert4r’   Ú@py_format9s
             r!   Útest_adv_4_strict_console_auditrÔ   w  s7  € à" >Ô2€LØ! -Ô0€Kå	Ð
RÐZ^Ð_Ñ_Ô_Ð_àGÐG˜\ÐGÑGÔG€FØKÐK˜|ÐKÑKÔK€Hå	Ð
Fµ3°|Ñ3DÔ3DÐ
FÐ
FÑGÔGÐGÝ	Ð
g�#˜f™+œ+Ð
gÐ
gµ3°x±=´=Ð
gÐ
gÕUXÐYdÑUeÔUeÐ
gÐ
gÑhÔhÐhåˆ{ÑÔÐK˜qÐKÐ˜qÒ ÐKÐKÑKÕKÔKÐKÐKÐKÐKÐ˜qÐKÑKÔKÐKÕKÔKÑKÔKÐKÐKÕKÔK�3ÑKÔKÐKÕKÔK�3ÑKÔKÐKÐKÐKÕKÔKÑKÔKÐKÐKÕKÔKˆ{ÑKÔKÐKÕKÔKˆ{ÑKÔKÐKÐKÕKÔKÐÑKÔKÕKÔK˜qÑKÔKÐKÐKÑKÐKÕKÔKÐ"K¸kÐ"KÐ"KÑKÔKÐKÑKÐKÐKÐKÑKÐKÕKÕKÔKÐKÑKÔKÑKÔKÐKÐKÐKÐKÐKÐKÐKÝˆv‰;Œ;ÐD˜!ÐDˆ;˜!ÒÐDÐDÑDÕDÔDÐDÐDÐDÐDˆ;˜!ÐDÑDÔDÐDÕDÔDÑDÔDÐDÐDÕDÔD�3ÑDÔDÐDÕDÔD�3ÑDÔDÐDÐDÐDÕDÔDÑDÔDÐDÐDÕDÔDˆvÑDÔDÐDÕDÔDˆvÑDÔDÐDÐDÕDÔDˆ;ÑDÔDÕDÔD˜!ÑDÔDÐDÐDÑDÐDÕDÔDÐD¸FÐ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å	Ð
PÐX\Ð]Ñ]Ô]Ð]Ð]Ð]r#   )r   )*Ú__doc__Úbuiltinsri   Ú_pytest.assertion.rewriteÚ	assertionÚrewriterg   rp   ÚosÚsysÚtimeÚpathlibr   Útypingr   r   r   ÚpytestÚplaywright.sync_apir   r   r	   r
   ÚhasattrÚstdoutr   ÚstderrÚenvironÚgetÚBASE_URLr   ru   Úmkdirrv   r"   ÚfixturerM   r”   r¥   r¾   rÃ   rÔ   rC   r#   r!   ú<module>ré      s!  ððð ð € € € € € € € € € € € € €€€€Ø 	€	€	€	Ø 
€
€
€
Ø €€€Ø Ð Ð Ð Ð Ð Ø "Ð "Ð "Ð "Ð "Ð "Ð "Ð "Ð "Ð "à €€€Ø NÐ NÐ NÐ NÐ NÐ NÐ NÐ NÐ NÐ NÐ NÐ Nà
€7ˆ3Œ:�}Ñ%Ô%ð -Ø„J×Ò GÐÑ,Ô,Ð,Ø
€7ˆ3Œ:�}Ñ%Ô%ð -Ø„J×Ò GÐÑ,Ô,Ð,àŒ:�>Š>˜/Ð+BÑCÔC€ØÐ
-Ð
-Ð
-€ØˆTÐ%Ñ&Ô&€
Ø 
× Ò ˜¨Ð Ñ -Ô -Ð -ð$ð $˜Dð $¨cð $¸dð $ð $ð $ð $ð €„�hÐÑÔð9ð 9ñ  Ôð9ðxTjð Tjð TjðnG~ð G~ð G~ðT6uð 6uð 6uðr5Eð 5Eð 5Eðp^ð ^ð ^ð ^ð ^r#   