@@ -2,9 +2,25 @@ import path from 'path';
22import fs from 'fs' ;
33import { Config } from 'backstopjs' ;
44import chalk from 'chalk' ;
5- import { BackstopReport , HtmlReportSummary } from './types' ;
5+ import crypto from 'node:crypto' ;
6+ import { BackstopReport , BackstopTest , HtmlReportSummary } from './types' ;
67
7- function processTestSuite ( backstopDir : string , config : Config ) : HtmlReportSummary | null {
8+ function calculateHash ( filePath : string ) : string {
9+ const content = fs . readFileSync ( filePath ) ;
10+ const sha1Hash = crypto . createHash ( 'sha1' ) ;
11+
12+ sha1Hash . update ( content ) ;
13+ return sha1Hash . digest ( 'base64url' ) . substring ( 0 , 10 ) ;
14+ }
15+
16+ function calculateTextHash ( text : string ) : string {
17+ const sha1Hash = crypto . createHash ( 'sha1' ) ;
18+
19+ sha1Hash . update ( text ) ;
20+ return sha1Hash . digest ( 'base64url' ) . substring ( 0 , 10 ) ;
21+ }
22+
23+ function processTestSuite ( backstopDir : string , config : Config , hashes : Record < string , string > ) : HtmlReportSummary | null {
824 const testDir = path . join ( backstopDir , config . id ) ;
925 if ( ! fs . existsSync ( testDir ) ) {
1026 console . log ( chalk . red ( `Test directory does not exist: ${ testDir } ` ) ) ;
@@ -19,6 +35,7 @@ function processTestSuite(backstopDir: string, config: Config): HtmlReportSummar
1935 }
2036
2137 const configPath = path . join ( htmlReportDir , 'config.js' ) ;
38+ const htmlIndexPath = path . join ( htmlReportDir , 'index.html' ) ;
2239
2340 if ( ! fs . existsSync ( configPath ) ) {
2441 return null ;
@@ -47,6 +64,43 @@ function processTestSuite(backstopDir: string, config: Config): HtmlReportSummar
4764 const passCount = report ?. tests ?. filter ( ( t ) => t . status === 'pass' ) . length ?? 0 ;
4865 const failCount = report ?. tests ?. filter ( ( t ) => t . status === 'fail' ) . length ?? 0 ;
4966
67+ if ( report ?. tests ) {
68+ [ ] . forEach . call ( report . tests , ( test : BackstopTest ) => {
69+ if ( test ?. pair ?. reference ) {
70+ const referencePath = path . join ( bitmapTestDir , test . pair . reference ) ;
71+ if ( ! fs . existsSync ( referencePath ) ) {
72+ if ( ! hashes [ test . pair . reference ] ) {
73+ const hash = calculateHash ( referencePath ) ;
74+ hashes [ test . pair . reference ] = hash ;
75+ }
76+ }
77+ }
78+
79+ if ( test ?. pair ?. test ) {
80+ const testPath = path . join ( bitmapTestDir , test . pair . test ) ;
81+ if ( ! fs . existsSync ( testPath ) ) {
82+ if ( ! hashes [ test . pair . test ] ) {
83+ const hash = calculateHash ( testPath ) ;
84+ hashes [ test . pair . test ] = hash ;
85+ }
86+ }
87+ }
88+ } ) ;
89+ }
90+
91+ let modifiedConfigText = configText ;
92+ for ( const [ filePath , hash ] of Object . entries ( hashes ) ) {
93+ if ( modifiedConfigText . includes ( filePath ) ) {
94+ modifiedConfigText = modifiedConfigText . replaceAll ( filePath , `${ filePath } ?v=${ hash } ` ) ;
95+ }
96+ }
97+ fs . writeFileSync ( configPath , modifiedConfigText , 'utf-8' ) ;
98+
99+ const configHash = calculateTextHash ( modifiedConfigText ) ;
100+ const htmlIndexText = fs . readFileSync ( htmlIndexPath , 'utf-8' ) ;
101+ let modifiedHtmlIndexText = htmlIndexText . replaceAll ( 'config.js' , `config.js?v=${ configHash } ` ) ;
102+ fs . writeFileSync ( htmlIndexPath , modifiedHtmlIndexText , 'utf-8' ) ;
103+
50104 console . log ( chalk . green ( `Snapshot directory: ${ subDir } , Passed: ${ passCount } , Failed: ${ failCount } ` ) ) ;
51105
52106 return {
@@ -157,9 +211,10 @@ export function snapshot({ configs, backstopDirName }: { configs: Config[]; back
157211 }
158212
159213 const htmlReportSummary : HtmlReportSummary [ ] = [ ] ;
214+ const hashes : Record < string , string > = { } ;
160215
161216 for ( const config of configs ) {
162- const summary = processTestSuite ( backstopDir , config ) ;
217+ const summary = processTestSuite ( backstopDir , config , hashes ) ;
163218 if ( summary ) {
164219 htmlReportSummary . push ( summary ) ;
165220 }
0 commit comments