@@ -15,36 +15,31 @@ type LightboxMetrics = {
1515 shapes : { rect : number ; path : number ; line : number }
1616}
1717
18- async function openLightboxForCase ( page : import ( '@playwright/test' ) . Page , caseId : string ) {
19- await page . goto ( `/mermaid-lightbox-e2e.html?case=${ encodeURIComponent ( caseId ) } ` )
20- await page . waitForSelector ( '[data-mermaid-diagram][data-rendered="true"]' , { timeout : 20_000 } )
21- await page . locator ( '[data-mermaid-diagram][data-rendered="true"]' ) . click ( )
22- await page . waitForSelector ( '[role="dialog"]' , { timeout : 10_000 } )
18+ type ExpandMetrics = {
19+ inlineW : number
20+ inlineH : number
21+ lightboxW : number
22+ lightboxH : number
23+ areaRatio : number
24+ }
2325
24- await page . waitForFunction ( ( ) => {
26+ async function readExpandMetrics ( page : import ( '@playwright/test' ) . Page ) : Promise < ExpandMetrics > {
27+ return page . evaluate ( ( ) => {
28+ const inlineSvg = document . querySelector ( '[data-mermaid-diagram][data-rendered="true"] svg' )
29+ const inlineBox = inlineSvg ?. getBoundingClientRect ( )
2530 const host = document . querySelector ( '[data-mermaid-lightbox]' )
26- const svg = host ?. shadowRoot ?. querySelector ( 'svg' )
27- const box = svg ?. getBoundingClientRect ( )
28- return Boolean ( box && box . width > 0 && box . height > 0 )
29- } , { timeout : 15_000 } )
30-
31- await page
32- . waitForFunction (
33- ( minCoverage ) => {
34- const host = document . querySelector ( '[data-mermaid-lightbox]' )
35- const svg = host ?. shadowRoot ?. querySelector ( 'svg' )
36- const box = svg ?. getBoundingClientRect ( )
37- if ( ! box || box . width <= 0 ) return false
38- const vw = window . visualViewport ?. width ?? window . innerWidth
39- const vh = window . visualViewport ?. height ?? window . innerHeight
40- return Math . max ( box . width / vw , box . height / vh ) >= minCoverage
41- } ,
42- MIN_COVERAGE ,
43- { timeout : 8_000 } ,
44- )
45- . catch ( ( ) => {
46- // Final expect below surfaces fit failures.
47- } )
31+ const lightboxSvg = host ?. shadowRoot ?. querySelector ( 'svg' )
32+ const lightboxBox = lightboxSvg ?. getBoundingClientRect ( )
33+ const inlineArea = ( inlineBox ?. width ?? 0 ) * ( inlineBox ?. height ?? 0 )
34+ const lightboxArea = ( lightboxBox ?. width ?? 0 ) * ( lightboxBox ?. height ?? 0 )
35+ return {
36+ inlineW : inlineBox ?. width ?? 0 ,
37+ inlineH : inlineBox ?. height ?? 0 ,
38+ lightboxW : lightboxBox ?. width ?? 0 ,
39+ lightboxH : lightboxBox ?. height ?? 0 ,
40+ areaRatio : inlineArea > 0 ? lightboxArea / inlineArea : 0 ,
41+ }
42+ } )
4843}
4944
5045async function readLightboxMetrics ( page : import ( '@playwright/test' ) . Page ) : Promise < LightboxMetrics > {
@@ -107,10 +102,55 @@ function assertMetrics(caseId: string, metrics: LightboxMetrics) {
107102 }
108103}
109104
105+ /** Lightbox should be visibly larger than the inline chat preview after click. */
106+ const MIN_EXPAND_AREA_RATIO = Number ( process . env . MERMAID_E2E_MIN_EXPAND_RATIO ?? '1.4' )
107+
110108for ( const caseId of MERMAID_LIGHTBOX_CASE_IDS ) {
111109 test ( `mermaid lightbox: ${ caseId } ` , async ( { page } ) => {
112- await openLightboxForCase ( page , caseId )
110+ await page . goto ( `/mermaid-lightbox-e2e.html?case=${ encodeURIComponent ( caseId ) } ` )
111+ await page . waitForSelector ( '[data-mermaid-diagram][data-rendered="true"]' , { timeout : 20_000 } )
112+
113+ const beforeExpand = await readExpandMetrics ( page )
114+ expect ( beforeExpand . lightboxW , `${ caseId } : dialog closed before click` ) . toBe ( 0 )
115+
116+ await page . locator ( '[data-mermaid-diagram][data-rendered="true"]' ) . click ( )
117+ await page . waitForSelector ( '[role="dialog"]' , { timeout : 10_000 } )
118+ await page . waitForFunction ( ( ) => {
119+ const host = document . querySelector ( '[data-mermaid-lightbox]' )
120+ const svg = host ?. shadowRoot ?. querySelector ( 'svg' )
121+ const box = svg ?. getBoundingClientRect ( )
122+ return Boolean ( box && box . width > 0 && box . height > 0 )
123+ } , { timeout : 15_000 } )
124+
125+ await page
126+ . waitForFunction (
127+ ( minCoverage ) => {
128+ const host = document . querySelector ( '[data-mermaid-lightbox]' )
129+ const svg = host ?. shadowRoot ?. querySelector ( 'svg' )
130+ const box = svg ?. getBoundingClientRect ( )
131+ if ( ! box || box . width <= 0 ) return false
132+ const vw = window . visualViewport ?. width ?? window . innerWidth
133+ const vh = window . visualViewport ?. height ?? window . innerHeight
134+ return Math . max ( box . width / vw , box . height / vh ) >= minCoverage
135+ } ,
136+ MIN_COVERAGE ,
137+ { timeout : 8_000 } ,
138+ )
139+ . catch ( ( ) => undefined )
140+
141+ const expand = await readExpandMetrics ( page )
142+ const inlineMax = Math . max ( expand . inlineW , expand . inlineH )
143+ const lightboxMax = Math . max ( expand . lightboxW , expand . lightboxH )
144+ const expandedVisibly =
145+ expand . areaRatio >= MIN_EXPAND_AREA_RATIO || lightboxMax > inlineMax * 1.05
146+ expect ( expandedVisibly , `${ caseId } : expand inline ${ Math . round ( expand . inlineW ) } x${ Math . round ( expand . inlineH ) } → lightbox ${ Math . round ( expand . lightboxW ) } x${ Math . round ( expand . lightboxH ) } ` ) . toBe ( true )
147+
113148 const metrics = await readLightboxMetrics ( page )
114149 assertMetrics ( caseId , metrics )
150+
151+ test . info ( ) . annotations . push ( {
152+ type : 'expand' ,
153+ description : `${ caseId } : inline ${ Math . round ( expand . inlineW ) } x${ Math . round ( expand . inlineH ) } → lightbox ${ Math . round ( expand . lightboxW ) } x${ Math . round ( expand . lightboxH ) } (${ expand . areaRatio . toFixed ( 1 ) } x area)` ,
154+ } )
115155 } )
116156}
0 commit comments