@@ -4,9 +4,56 @@ import {fileURLToPath} from 'node:url';
44import test from 'ava' ;
55import { execa } from 'execa' ;
66import { temporaryDirectory } from 'tempy' ;
7+ import jestImageSnapshot from 'jest-image-snapshot' ;
8+ import { spawnSync } from 'node:child_process' ;
9+ const { configureToMatchImageSnapshot } = jestImageSnapshot ;
710
811const __dirname = path . dirname ( fileURLToPath ( import . meta. url ) ) ;
912
13+ /** Validate that the icon for the DMG matches the snapshot (with a small tolerance to avoid flakiness) */
14+ const assertVolumeIconMatchesSnapshot = ( t , dmgPath ) => {
15+ // Mount the DMG and extract the volume icon
16+ const existingVolumes = new Set ( fs . readdirSync ( '/Volumes' ) ) ;
17+ spawnSync ( 'hdiutil' , [ 'mount' , dmgPath ] ) ;
18+ const volumes = new Set ( fs . readdirSync ( '/Volumes' ) ) ;
19+ const mountLocation = [ ...volumes ] . find ( x => ! existingVolumes . has ( x ) ) ;
20+ t . truthy ( mountLocation ) ;
21+ const dmgIconPath = path . join ( '/Volumes' , mountLocation , '.VolumeIcon.icns' )
22+ const dirPath = path . dirname ( dmgPath ) ;
23+ const iconPath = path . join ( dirPath , 'VolumeIcon.icns' ) ;
24+ fs . copyFileSync ( dmgIconPath , iconPath ) ;
25+ spawnSync ( 'hdiutil' , [ 'unmount' , path . join ( '/Volumes' , mountLocation ) ] ) ;
26+ const pngPath = path . join ( dirPath , 'VolumeIcon.png' ) ;
27+ spawnSync ( 'sips' , [ '-s' , 'format' , 'png' , iconPath , '--out' , pngPath ] ) ;
28+
29+ // Compare the extracted icon to the snapshot
30+ const image = fs . readFileSync ( pngPath ) ;
31+
32+ // Create a Jest-like context for jest-image-snapshot
33+ const jestContext = {
34+ testPath : fileURLToPath ( import . meta. url ) ,
35+ currentTestName : t . title ,
36+ _counters : new Map ( ) ,
37+ snapshotState : {
38+ _counters : new Map ( ) ,
39+ _updateSnapshot : process . env . UPDATE_SNAPSHOT === 'true' ? 'all' : 'new' ,
40+ updated : 0 ,
41+ added : 0
42+ }
43+ } ;
44+
45+ const result = configureToMatchImageSnapshot ( {
46+ failureThreshold : 0.01 ,
47+ failureThresholdType : 'percent' ,
48+ } ) . call ( jestContext , image )
49+
50+ if ( result . pass ) {
51+ t . pass ( ) ;
52+ } else {
53+ t . fail ( result . message ( ) ) ;
54+ }
55+ }
56+
1057test ( 'main' , async t => {
1158 const cwd = temporaryDirectory ( ) ;
1259
@@ -18,8 +65,10 @@ test('main', async t => {
1865 throw error ;
1966 }
2067 }
68+ const dmgPath = path . join ( cwd , 'Fixture 0.0.1.dmg' ) ;
69+ t . true ( fs . existsSync ( dmgPath ) ) ;
2170
22- t . true ( fs . existsSync ( path . join ( cwd , 'Fixture 0.0.1.dmg' ) ) ) ;
71+ assertVolumeIconMatchesSnapshot ( t , dmgPath ) ;
2372} ) ;
2473
2574test ( 'binary plist' , async t => {
@@ -34,7 +83,9 @@ test('binary plist', async t => {
3483 }
3584 }
3685
37- t . true ( fs . existsSync ( path . join ( cwd , 'Fixture 0.0.1.dmg' ) ) ) ;
86+ const dmgPath = path . join ( cwd , 'Fixture 0.0.1.dmg' ) ;
87+ t . true ( fs . existsSync ( dmgPath ) ) ;
88+ assertVolumeIconMatchesSnapshot ( t , dmgPath ) ;
3889} ) ;
3990
4091test ( 'app without icon' , async t => {
0 commit comments