@@ -305,81 +305,95 @@ export class VisualTestHelper {
305305 }
306306
307307 // convert reference image to canvas
308- using expected = AlphaSkiaImage . decode ( referenceFileData . buffer ) ;
309- await VisualTestHelper . expectToEqualVisuallyAsync ( actual . endRender ( ) ! , expected ! , referenceFileName , message , tolerancePercent ) ;
308+ if ( referenceFileData . length > 0 ) {
309+ using expected = AlphaSkiaImage . decode ( referenceFileData . buffer ) ;
310+ await VisualTestHelper . expectToEqualVisuallyAsync ( actual . endRender ( ) ! , expected , referenceFileName , message , tolerancePercent ) ;
311+ } else {
312+ await VisualTestHelper . expectToEqualVisuallyAsync ( actual . endRender ( ) ! , undefined , referenceFileName , message , tolerancePercent ) ;
313+ }
310314 }
311315
312316 private static async expectToEqualVisuallyAsync (
313317 actual : AlphaSkiaImage ,
314- expected : AlphaSkiaImage ,
318+ expected : AlphaSkiaImage | undefined ,
315319 expectedFileName : string ,
316320 message ?: string ,
317321 tolerancePercent : number = 1
318322 ) : Promise < void > {
319- const sizeMismatch = expected . width !== actual . width || expected . height !== actual . height ;
323+ let pass = false ;
324+ let errorMessage = '' ;
320325 const oldActual = actual ;
321- if ( sizeMismatch ) {
322- using newActual = new AlphaSkiaCanvas ( ) ;
323- newActual . beginRender ( expected . width , expected . height ) ;
324- newActual . drawImage ( actual , 0 , 0 , expected . width , expected . height ) ;
325- newActual . color = AlphaSkiaCanvas . rgbaToColor ( 255 , 0 , 0 , 255 ) ;
326- newActual . lineWidth = 2 ;
327- newActual . strokeRect ( 0 , 0 , expected . width , expected . height ) ;
328-
329- actual = newActual . endRender ( ) ! ;
330- }
331-
332- const actualImageData = actual . readPixels ( ) ! ;
333- const expectedImageData = expected . readPixels ( ) ! ;
334-
335- // do visual comparison
336- const diffImageData = new ArrayBuffer ( actualImageData . byteLength ) ;
337- let pass = true ;
338- let errorMessage = "" ;
339-
340- try {
341- const options = new PixelMatchOptions ( ) ;
342- options . threshold = 0.3 ;
343- options . includeAA = false ;
344- options . diffMask = true ;
345- options . alpha = 1 ;
346-
347- let match = PixelMatch . match (
348- new Uint8Array ( expectedImageData ) ,
349- new Uint8Array ( actualImageData ) ,
350- new Uint8Array ( diffImageData ) ,
351- expected . width ,
352- expected . height ,
353- options
354- ) ;
355-
356- // only pixels that are not transparent are relevant for the diff-ratio
357- let totalPixels = match . totalPixels - match . transparentPixels ;
358- let percentDifference = ( match . differentPixels / totalPixels ) * 100 ;
359- pass = percentDifference <= tolerancePercent ;
360- // result.pass = match.differentPixels === 0;
361- errorMessage = '' ;
362-
363- if ( ! pass ) {
364- let percentDifferenceText = percentDifference . toFixed ( 2 ) ;
365- errorMessage = `Difference between original and new image is too big: ${ match . differentPixels } /${ totalPixels } (${ percentDifferenceText } %)` ;
366-
367- using diffPng = AlphaSkiaImage . fromPixels (
368- actual . width ,
369- actual . height ,
370- diffImageData ) ! ;
371-
372- await VisualTestHelper . saveFiles ( expectedFileName , oldActual , diffPng ) ;
373- }
374326
327+ if ( expected ) {
328+ const sizeMismatch = expected . width !== actual . width || expected . height !== actual . height ;
375329 if ( sizeMismatch ) {
376- errorMessage += `Image sizes do not match: expected ${ expected . width } x${ expected . height } but got ${ oldActual . width } x${ oldActual . height } ` ;
330+ using newActual = new AlphaSkiaCanvas ( ) ;
331+ newActual . beginRender ( expected . width , expected . height ) ;
332+ newActual . drawImage ( actual , 0 , 0 , expected . width , expected . height ) ;
333+ newActual . color = AlphaSkiaCanvas . rgbaToColor ( 255 , 0 , 0 , 255 ) ;
334+ newActual . lineWidth = 2 ;
335+ newActual . strokeRect ( 0 , 0 , expected . width , expected . height ) ;
336+
337+ actual = newActual . endRender ( ) ! ;
338+ }
339+
340+ const actualImageData = actual . readPixels ( ) ! ;
341+ const expectedImageData = expected . readPixels ( ) ! ;
342+
343+ // do visual comparison
344+ const diffImageData = new ArrayBuffer ( actualImageData . byteLength ) ;
345+ let pass = true ;
346+ let errorMessage = "" ;
347+
348+ try {
349+ const options = new PixelMatchOptions ( ) ;
350+ options . threshold = 0.3 ;
351+ options . includeAA = false ;
352+ options . diffMask = true ;
353+ options . alpha = 1 ;
354+
355+ let match = PixelMatch . match (
356+ new Uint8Array ( expectedImageData ) ,
357+ new Uint8Array ( actualImageData ) ,
358+ new Uint8Array ( diffImageData ) ,
359+ expected . width ,
360+ expected . height ,
361+ options
362+ ) ;
363+
364+ // only pixels that are not transparent are relevant for the diff-ratio
365+ let totalPixels = match . totalPixels - match . transparentPixels ;
366+ let percentDifference = ( match . differentPixels / totalPixels ) * 100 ;
367+ pass = percentDifference <= tolerancePercent ;
368+ // result.pass = match.differentPixels === 0;
369+ errorMessage = '' ;
370+
371+ if ( ! pass ) {
372+ let percentDifferenceText = percentDifference . toFixed ( 2 ) ;
373+ errorMessage = `Difference between original and new image is too big: ${ match . differentPixels } /${ totalPixels } (${ percentDifferenceText } %)` ;
374+
375+ using diffPng = AlphaSkiaImage . fromPixels (
376+ actual . width ,
377+ actual . height ,
378+ diffImageData ) ! ;
379+
380+ await VisualTestHelper . saveFiles ( expectedFileName , oldActual , diffPng ) ;
381+ }
382+
383+ if ( sizeMismatch ) {
384+ errorMessage += `Image sizes do not match: expected ${ expected . width } x${ expected . height } but got ${ oldActual . width } x${ oldActual . height } ` ;
385+ pass = false ;
386+ }
387+ } catch ( e ) {
377388 pass = false ;
389+ errorMessage = `Error comparing images: ${ e } , ${ message } ` ;
378390 }
379- } catch ( e ) {
380- pass = false ;
381- errorMessage = `Error comparing images: ${ e } , ${ message } ` ;
382391 }
392+ else {
393+ pass = false ;
394+ errorMessage = 'Missing reference image file' + expectedFileName ;
395+ await VisualTestHelper . saveFiles ( expectedFileName , oldActual , undefined ) ;
396+ }
383397
384398 if ( ! pass ) {
385399 throw new Error ( errorMessage ) ;
@@ -391,20 +405,21 @@ export class VisualTestHelper {
391405 static async saveFiles (
392406 expectedFilePath : string ,
393407 actual : AlphaSkiaImage ,
394- diff : AlphaSkiaImage
408+ diff : AlphaSkiaImage | undefined
395409 ) : Promise < void > {
396410 expectedFilePath = TestPlatform . joinPath (
397411 'test-data' ,
398412 'visual-tests' ,
399413 expectedFilePath
400414 ) ;
415+ if ( diff ) {
416+ const diffData = diff . toPng ( ) ! ;
401417
402- const actualData = actual . toPng ( ) ! ;
403- const diffData = diff . toPng ( ) ! ;
404-
405- const diffFileName = TestPlatform . changeExtension ( expectedFilePath , '.diff.png' ) ;
406- await TestPlatform . saveFile ( diffFileName , new Uint8Array ( diffData ) ) ;
418+ const diffFileName = TestPlatform . changeExtension ( expectedFilePath , '.diff.png' ) ;
419+ await TestPlatform . saveFile ( diffFileName , new Uint8Array ( diffData ) ) ;
420+ }
407421
422+ const actualData = actual . toPng ( ) ! ;
408423 const actualFile = TestPlatform . changeExtension ( expectedFilePath , '.new.png' ) ;
409424 await TestPlatform . saveFile ( actualFile , new Uint8Array ( actualData ) ) ;
410425 }
0 commit comments