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 } /result` ) . set ( results ) ;
24- } )
25- . then ( ( ) => database . ref ( FIREBASE_REPORT ) . child ( `${ prNumber } /commit` ) . 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 } /results/${ filenameKey } ` ) . set ( result ) ;
36+ }
37+
38+ function updateResult ( database : firebase . database . Database , prNumber : string , result : boolean ) {
39+ return database . ref ( FIREBASE_REPORT ) . child ( `${ prNumber } /result` ) . set ( result ) ;
40+ }
41+
42+ function updateCommit ( database : firebase . database . Database , prNumber : string ) {
43+ return database . ref ( FIREBASE_REPORT ) . child ( `${ prNumber } /commit` ) . 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 } /diff` : 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 } /references/${ 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 } /golds/${ filename } ` ;
135+ let pullRequestUrl = `${ SCREENSHOT_DIR } /${ filename } ` ;
112136 let diffUrl = `${ SCREENSHOT_DIR } /diff/${ 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 } /results/${ filenameKey } ` )
129- . set ( imagesAreSame ) ;
152+ return updateFileResult ( database , reportKey , filenameKey , imagesAreSame ) ;
130153 } ) ;
131154 } ) ;
132155 } else {
133- return database . ref ( FIREBASE_REPORT ) . child ( `${ reportKey } /results/${ filenameKey } ` )
134- . set ( false ) . then ( ( ) => false ) ;
156+ return updateFileResult ( database , reportKey , filenameKey , false ) . then ( ( ) => false ) ;
135157 }
136158}
0 commit comments