11import  { task }  from  'gulp' ; 
22import  { readdirSync ,  statSync ,  existsSync ,  mkdirSync }  from  'fs' ; 
3- import  { openScreenshotsCloudStorage ,  openScreenshotsFirebaseDatabase }  from  '../task_helpers' ; 
3+ import  { openScreenshotsCloudStorage ,  openFirebaseScreenshotsDatabase }  from  '../task_helpers' ; 
4+ import  *  as  path  from  'path' ; 
5+ import  *  as  firebase  from  'firebase' ; 
46const  imageDiff  =  require ( 'image-diff' ) ; 
57
68const  SCREENSHOT_DIR  =  './screenshots' ; 
@@ -11,38 +13,50 @@ const FIREBASE_REPORT = 'screenshot/reports';
1113task ( 'screenshots' ,  ( )  =>  { 
1214  let  prNumber  =  process . env [ 'TRAVIS_PULL_REQUEST' ] ; 
1315  if  ( prNumber )  { 
14-     let  database  =  openScreenshotsFirebaseDatabase ( ) ; 
15-     return  getFilenameList ( database ) 
16+     let  database  =  openFirebaseScreenshotsDatabase ( ) ; 
17+     return  getScreenFilenames ( database ) 
1618      . then ( ( filenames : string [ ] )  =>  { 
17-         return  downloadReferenceScreenshots ( filenames ,  database ) 
18-           . then ( ( results :  any )  =>  { 
19-             return  compareScreenshots ( filenames ,  database ,  prNumber ) ; 
19+         return  downloadAllGolds ( filenames ,  database ) 
20+           . then ( ( )  =>  { 
21+             return  diffAllScreenshots ( filenames ,  database ,  prNumber ) ; 
2022          } ) ; 
2123      } ) 
22-       . then ( ( results : boolean )  =>  { 
23-         return  database . ref ( FIREBASE_REPORT ) . child ( `${ prNumber }  ) . set ( results ) ; 
24-       } ) 
25-       . then ( ( )  =>  database . ref ( FIREBASE_REPORT ) . child ( `${ prNumber }  ) . set ( process . env [ 'TRAVIS_COMMIT' ] ) ) 
26-       . then ( ( )  =>  setFilenameList ( database ,  prNumber ) ) 
24+       . then ( ( results : boolean )  =>  updateResult ( database ,  prNumber ,  results ) ) 
25+       . then ( ( )  =>  setScreenFilenames ( database ,  prNumber ) ) 
2726      . then ( ( )  =>  uploadScreenshots ( prNumber ,  'diff' ) ) 
2827      . then ( ( )  =>  uploadScreenshots ( prNumber ,  'test' ) ) 
28+       . then ( ( )  =>  updateCommit ( database ,  prNumber ) ) 
2929      . then ( ( )  =>  database . goOffline ( ) ,  ( )  =>  database . goOffline ( ) ) ; 
3030  } 
3131} ) ; 
3232
33+ function  updateFileResult ( database : firebase . database . Database ,  prNumber : string , 
34+                           filenameKey : string ,  result : boolean )  { 
35+   return  database . ref ( FIREBASE_REPORT ) . child ( `${ prNumber } ${ filenameKey }  ) . set ( result ) ; 
36+ } 
37+ 
38+ function  updateResult ( database : firebase . database . Database ,  prNumber : string ,  result : boolean )  { 
39+   return  database . ref ( FIREBASE_REPORT ) . child ( `${ prNumber }  ) . set ( result ) ; 
40+ } 
41+ 
42+ function  updateCommit ( database : firebase . database . Database ,  prNumber : string )  { 
43+   return  database . ref ( FIREBASE_REPORT ) . child ( `${ prNumber }  ) . set ( process . env [ 'TRAVIS_COMMIT' ] ) ; 
44+ } 
45+ 
3346/** Get a list of filenames from firebase database. */ 
34- function  getFilenameList ( database : any )  : Promise < string [ ] >  { 
35-   return  database . ref ( FIREBASE_FILELIST ) . once ( 'value' ) . then ( function ( snapshots : any )  { 
47+ function  getScreenFilenames ( database : any )  : firebase . Promise < string [ ] >  { 
48+   return  database . ref ( FIREBASE_FILELIST ) . once ( 'value' ) 
49+       . then ( ( snapshots : firebase . database . DataSnapshot )  =>  { 
3650    return  snapshots . val ( ) ; 
3751  } ) ; 
3852} 
3953
40- /** Upload a list of filenames to firebase database as reference . */ 
41- function  setFilenameList ( database : any , 
42-                          reportKey ?: string ) : Promise < any >  { 
54+ /** Upload a list of filenames to firebase database as gold . */ 
55+ function  setScreenFilenames ( database : firebase . database . Database , 
56+                              reportKey ?: string ) : firebase . Promise < any >  { 
4357  let  filenames : string [ ]  =  [ ] ; 
44-   readdirSync ( SCREENSHOT_DIR ) . map ( function ( file )  { 
45-     let  fullName  =  SCREENSHOT_DIR   +   '/'   +   file ; 
58+   readdirSync ( SCREENSHOT_DIR ) . map ( ( file :  string )   =>  { 
59+     let  fullName  =  path . join ( SCREENSHOT_DIR ,   file ) ; 
4660    let  key  =  file . replace ( '.screenshot.png' ,  '' ) ; 
4761    if  ( ! statSync ( fullName ) . isDirectory ( )  &&  key )  { 
4862      filenames . push ( file ) ; 
@@ -54,23 +68,31 @@ function setFilenameList(database: any,
5468  return  filelistDatabase . set ( filenames ) ; 
5569} 
5670
57- /** Upload screenshots to google cloud storage. */ 
71+ /** 
72+  * Upload screenshots to google cloud storage. 
73+  * @param  {string } reportKey - The key used in firebase. Here it is the PR number. 
74+  *   If there's no reportKey, we will upload images to 'golds/' folder 
75+  * @param  {string } mode - Can be 'test' or 'diff' or null. 
76+  *   If the images are the test results, mode should be 'test'. 
77+  *   If the images are the diff images generated, mode should be 'diff'. 
78+  *   For golds mode should be null. 
79+  */ 
5880function  uploadScreenshots ( reportKey ?: string ,  mode ?: 'test'  |  'diff' )  { 
5981  let  bucket  =  openScreenshotsCloudStorage ( ) ; 
6082
61-   let  promises : Promise < any > [ ]  =  [ ] ; 
83+   let  promises : firebase . Promise < any > [ ]  =  [ ] ; 
6284  let  localDir  =  mode  ==  'diff'  ? `${ SCREENSHOT_DIR }   : SCREENSHOT_DIR ; 
63-   readdirSync ( localDir ) . map ( function ( file )  { 
64-     let  fileName  =  localDir   +   '/'   +   file ; 
85+   readdirSync ( localDir ) . map ( ( file :  string )   =>  { 
86+     let  fileName  =  path . join ( localDir ,   file ) ; 
6587    let  key  =  file . replace ( '.screenshot.png' ,  '' ) ; 
6688    let  destination  =  ( mode  ==  null  ||  ! reportKey )  ?
67-       `references /${ file }   : `screenshots/${ reportKey } ${ mode } ${ file }  ; 
89+       `golds /${ file }   : `screenshots/${ reportKey } ${ mode } ${ file }  ; 
6890
6991    if  ( ! statSync ( fileName ) . isDirectory ( )  &&  key )  { 
7092      promises . push ( bucket . upload ( fileName ,  {  destination : destination  } ) ) ; 
7193    } 
7294  } ) ; 
73-   return  Promise . all ( promises ) ; 
95+   return  firebase . Promise . all ( promises ) ; 
7496} 
7597
7698/** Check whether the directory exists. If not then create one. */ 
@@ -80,57 +102,57 @@ function _makeDir(dirName: string) {
80102  } 
81103} 
82104
83- /** Download references  screenshots. */ 
84- function  downloadReferenceScreenshots ( 
85-     filenames : string [ ] ,  database : any ) : Promise < any >  { 
86-   _makeDir ( `${ SCREENSHOT_DIR } references ` ) ; 
105+ /** Download golds  screenshots. */ 
106+ function  downloadAllGolds ( 
107+     filenames : string [ ] ,  database : firebase . database . Database ) : firebase . Promise < void [ ] >  { 
108+   _makeDir ( `${ SCREENSHOT_DIR } golds ` ) ; 
87109
88-   return  Promise . all ( filenames . map ( ( filename : string )  =>  { 
89-     return  _downloadReferenceScreenshot ( filename ) ; 
110+   return  firebase . Promise . all ( filenames . map ( ( filename : string )  =>  { 
111+     return  downloadGold ( filename ) ; 
90112  } ) ) ; 
91113} 
92114
93- /** Download one reference  screenshot */ 
94- function  _downloadReferenceScreenshot ( filename : string ) : Promise < any >  { 
115+ /** Download one gold  screenshot */ 
116+ function  downloadGold ( filename : string ) : Promise < void >  { 
95117  let  bucket  =  openScreenshotsCloudStorage ( ) ; 
96-   return  bucket . file ( `references /${ filename }  ) . download ( { 
97-     destination : `${ SCREENSHOT_DIR } references /${ filename }  
118+   return  bucket . file ( `golds /${ filename }  ) . download ( { 
119+     destination : `${ SCREENSHOT_DIR } golds /${ filename }  
98120  } ) ; 
99121} 
100122
101- /** Compare the test result and the reference. */ 
102- function  compareScreenshots ( filenames : string [ ] ,  database : any ,  reportKey : string ) : Promise < any >  { 
103-   return  Promise . all ( filenames . map ( ( filename )  => 
104-     _compareScreenshot ( filename ,  database ,  reportKey ) ) ) 
105-       . then ( ( results : any )  =>  results . every ( ( value : boolean )  =>  value  ==  true ) ) ; 
123+ /** Compare the test result and the gold. */ 
124+ function  diffAllScreenshots ( filenames : string [ ] ,  database : firebase . database . Database , 
125+                             reportKey : string ) : firebase . Promise < boolean >  { 
126+   return  firebase . Promise . all ( filenames . map ( ( filename )  => 
127+     diffScreenshot ( filename ,  database ,  reportKey ) ) ) 
128+       . then ( ( results : boolean [ ] )  =>  results . every ( ( value : boolean )  =>  value  ==  true ) ) ; 
106129} 
107130
108- function  _compareScreenshot ( filename : string ,  database : any , 
109-                              reportKey : string ) : Promise < any >  { 
110-   let  expectedUrl  =  `${ SCREENSHOT_DIR } ${ filename }  ; 
111-   let  actualUrl  =  `${ SCREENSHOT_DIR } ${ filename }  ; 
131+ function  diffScreenshot ( filename : string ,  database : firebase . database . Database , 
132+                              reportKey : string ) : firebase . Promise < boolean >  { 
133+   // TODO(tinayuangao): Run the downloads and diffs in parallel. 
134+   let  goldUrl  =  `${ SCREENSHOT_DIR } ${ filename }  ; 
135+   let  pullRequestUrl  =  `${ SCREENSHOT_DIR } ${ filename }  ; 
112136  let  diffUrl  =  `${ SCREENSHOT_DIR } ${ filename }  ; 
113137  let  filenameKey  =  filename . replace ( '.screenshot.png' ,  '' ) ; 
114138
115-   if  ( existsSync ( expectedUrl )  &&  existsSync ( actualUrl ) )  { 
116-     return  new  Promise ( function ( resolve ,  reject )  { 
139+   if  ( existsSync ( goldUrl )  &&  existsSync ( pullRequestUrl ) )  { 
140+     return  new  firebase . Promise ( ( resolve :  any ,  reject :  any )   =>  { 
117141      imageDiff ( { 
118-         actualImage : actualUrl , 
119-         expectedImage : expectedUrl , 
142+         actualImage : pullRequestUrl , 
143+         expectedImage : goldUrl , 
120144        diffImage : diffUrl , 
121-       } ,  function   ( err : any ,  imagesAreSame : boolean )  { 
145+       } ,  ( err : any ,  imagesAreSame : boolean )   =>  { 
122146        if  ( err )  { 
123147          console . log ( err ) ; 
124148          imagesAreSame  =  false ; 
125149          reject ( err ) ; 
126150        } 
127151        resolve ( imagesAreSame ) ; 
128-         return  database . ref ( FIREBASE_REPORT ) . child ( `${ reportKey } ${ filenameKey }  ) 
129-           . set ( imagesAreSame ) ; 
152+         return  updateFileResult ( database ,  reportKey ,  filenameKey ,  imagesAreSame ) ; 
130153      } ) ; 
131154    } ) ; 
132155  }  else  { 
133-     return  database . ref ( FIREBASE_REPORT ) . child ( `${ reportKey } ${ filenameKey }  ) 
134-       . set ( false ) . then ( ( )  =>  false ) ; 
156+     return  updateFileResult ( database ,  reportKey ,  filenameKey ,  false ) . then ( ( )  =>  false ) ; 
135157  } 
136158} 
0 commit comments