@@ -316,30 +316,73 @@ test('small-and-fast', async ({ page }) => {
316316} ) ;
317317
318318test ( 'dark mode' , async ( { page } ) => {
319+ // Helper: returns relative luminance in range [0, 1]
320+ const getPageBrightness = async ( ) => {
321+ const screenshot = await page . screenshot ( { type : 'png' } ) ;
322+ const base64 = screenshot . toString ( 'base64' ) ;
323+
324+ return await page . evaluate ( ( b64 ) => {
325+ return new Promise ( ( resolve ) => {
326+ const img = new Image ( ) ;
327+ img . src = `data:image/png;base64,${ b64 } ` ;
328+ img . onload = ( ) => {
329+ const canvas = document . createElement ( 'canvas' ) ;
330+ canvas . width = canvas . height = 1 ;
331+ const ctx = canvas . getContext ( '2d' ) ;
332+ ctx . drawImage ( img , 0 , 0 , 1 , 1 ) ;
333+ const [ r , g , b ] = ctx . getImageData ( 0 , 0 , 1 , 1 ) . data ;
334+
335+ // Calculate brightness, for more details, see
336+ // https://en.wikipedia.org/wiki/Relative_luminance#Relative_luminance_and_%22gamma_encoded%22_colorspaces
337+ const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b ;
338+
339+ // Normalize to [0, 1]
340+ resolve ( luminance / 255 ) ;
341+ } ;
342+ img . onerror = ( ) => resolve ( - 1 ) ; // error indicator
343+ } ) ;
344+ } , base64 ) ;
345+ } ;
346+
319347 await page . setViewportSize ( devices [ 'iPhone X' ] . viewport ) ;
348+ await page . goto ( url ) ;
320349
321- await page . goto ( ` ${ url } ` ) ;
350+ // Ensure consistent test state
322351 await page . evaluate ( ( ) => {
323352 document . querySelector ( '#tagline' ) . innerHTML = '--dark-mode-for-dark-times' ;
324353 } ) ;
354+
325355 const darkModeButton = page . locator ( '#dark-mode-button' ) ;
326356
327- const o = { maxDiffPixels : 30 } ;
328- await expect ( page ) . toHaveScreenshot ( { name : 'light-mode.png' , ...o } ) ;
357+ // 1. Light mode
358+ const lightBrightness = await getPageBrightness ( ) ;
359+ expect ( lightBrightness ) . toBeCloseTo ( 0.85 , 0.1 ) ; // e.g., 0.75–0.95
360+
361+ // 2. Toggle to dark mode
329362 await darkModeButton . click ( ) ;
330- await expect ( page ) . toHaveScreenshot ( { name : 'dark-mode.png' , ...o } ) ;
363+ const darkBrightness = await getPageBrightness ( ) ;
364+ expect ( darkBrightness ) . toBeCloseTo ( 0.25 , 0.1 ) ; // e.g., 0.15–0.35
331365
332- // Now, try again, but this time with system's preference being dark mode
366+ // 3. Verify dark < light
367+ expect ( darkBrightness ) . toBeLessThan ( lightBrightness ) ;
333368
369+ // --- Test system preference: prefers-color-scheme: dark ---
334370 await page . emulateMedia ( { colorScheme : 'dark' } ) ;
335- await page . evaluate ( ( ) => window . localStorage . clear ( ) ) ;
336- await page . evaluate ( ( ) => window . sessionStorage . clear ( ) ) ;
371+ await page . evaluate ( ( ) => {
372+ localStorage . clear ( ) ;
373+ sessionStorage . clear ( ) ;
374+ } ) ;
337375 await page . reload ( ) ;
338376 await page . evaluate ( ( ) => {
339377 document . querySelector ( '#tagline' ) . innerHTML = '--dark-mode-for-dark-times' ;
340378 } ) ;
341379
342- await expect ( page ) . toHaveScreenshot ( { name : 'dark-mode.png' , ...o } ) ;
380+ // Should start in dark mode
381+ const autoDarkBrightness = await getPageBrightness ( ) ;
382+ expect ( autoDarkBrightness ) . toBeCloseTo ( 0.25 , 0.1 ) ;
383+
384+ // Toggle to light
343385 await darkModeButton . click ( ) ;
344- await expect ( page ) . toHaveScreenshot ( { name : 'light-mode.png' , ...o } ) ;
345- } )
386+ const autoLightBrightness = await getPageBrightness ( ) ;
387+ expect ( autoLightBrightness ) . toBeCloseTo ( 0.85 , 0.1 ) ;
388+ } ) ;
0 commit comments