1
1
import { task } from 'gulp' ;
2
2
import { 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' ;
4
6
const imageDiff = require ( 'image-diff' ) ;
5
7
6
8
const SCREENSHOT_DIR = './screenshots' ;
@@ -11,38 +13,50 @@ const FIREBASE_REPORT = 'screenshot/reports';
11
13
task ( 'screenshots' , ( ) => {
12
14
let prNumber = process . env [ 'TRAVIS_PULL_REQUEST' ] ;
13
15
if ( prNumber ) {
14
- let database = openScreenshotsFirebaseDatabase ( ) ;
15
- return getFilenameList ( database )
16
+ let database = openFirebaseScreenshotsDatabase ( ) ;
17
+ return getScreenFilenames ( database )
16
18
. 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 ) ;
20
22
} ) ;
21
23
} )
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 ) )
27
26
. then ( ( ) => uploadScreenshots ( prNumber , 'diff' ) )
28
27
. then ( ( ) => uploadScreenshots ( prNumber , 'test' ) )
28
+ . then ( ( ) => updateCommit ( database , prNumber ) )
29
29
. then ( ( ) => database . goOffline ( ) , ( ) => database . goOffline ( ) ) ;
30
30
}
31
31
} ) ;
32
32
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
+
33
46
/** 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 ) => {
36
50
return snapshots . val ( ) ;
37
51
} ) ;
38
52
}
39
53
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 > {
43
57
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 ) ;
46
60
let key = file . replace ( '.screenshot.png' , '' ) ;
47
61
if ( ! statSync ( fullName ) . isDirectory ( ) && key ) {
48
62
filenames . push ( file ) ;
@@ -54,23 +68,31 @@ function setFilenameList(database: any,
54
68
return filelistDatabase . set ( filenames ) ;
55
69
}
56
70
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
+ */
58
80
function uploadScreenshots ( reportKey ?: string , mode ?: 'test' | 'diff' ) {
59
81
let bucket = openScreenshotsCloudStorage ( ) ;
60
82
61
- let promises : Promise < any > [ ] = [ ] ;
83
+ let promises : firebase . Promise < any > [ ] = [ ] ;
62
84
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 ) ;
65
87
let key = file . replace ( '.screenshot.png' , '' ) ;
66
88
let destination = ( mode == null || ! reportKey ) ?
67
- `references /${ file } ` : `screenshots/${ reportKey } /${ mode } /${ file } ` ;
89
+ `golds /${ file } ` : `screenshots/${ reportKey } /${ mode } /${ file } ` ;
68
90
69
91
if ( ! statSync ( fileName ) . isDirectory ( ) && key ) {
70
92
promises . push ( bucket . upload ( fileName , { destination : destination } ) ) ;
71
93
}
72
94
} ) ;
73
- return Promise . all ( promises ) ;
95
+ return firebase . Promise . all ( promises ) ;
74
96
}
75
97
76
98
/** Check whether the directory exists. If not then create one. */
@@ -80,57 +102,57 @@ function _makeDir(dirName: string) {
80
102
}
81
103
}
82
104
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 ` ) ;
87
109
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 ) ;
90
112
} ) ) ;
91
113
}
92
114
93
- /** Download one reference screenshot */
94
- function _downloadReferenceScreenshot ( filename : string ) : Promise < any > {
115
+ /** Download one gold screenshot */
116
+ function downloadGold ( filename : string ) : Promise < void > {
95
117
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 } `
98
120
} ) ;
99
121
}
100
122
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 ) ) ;
106
129
}
107
130
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 } ` ;
112
136
let diffUrl = `${ SCREENSHOT_DIR } /diff/${ filename } ` ;
113
137
let filenameKey = filename . replace ( '.screenshot.png' , '' ) ;
114
138
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 ) => {
117
141
imageDiff ( {
118
- actualImage : actualUrl ,
119
- expectedImage : expectedUrl ,
142
+ actualImage : pullRequestUrl ,
143
+ expectedImage : goldUrl ,
120
144
diffImage : diffUrl ,
121
- } , function ( err : any , imagesAreSame : boolean ) {
145
+ } , ( err : any , imagesAreSame : boolean ) => {
122
146
if ( err ) {
123
147
console . log ( err ) ;
124
148
imagesAreSame = false ;
125
149
reject ( err ) ;
126
150
}
127
151
resolve ( imagesAreSame ) ;
128
- return database . ref ( FIREBASE_REPORT ) . child ( `${ reportKey } /results/${ filenameKey } ` )
129
- . set ( imagesAreSame ) ;
152
+ return updateFileResult ( database , reportKey , filenameKey , imagesAreSame ) ;
130
153
} ) ;
131
154
} ) ;
132
155
} 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 ) ;
135
157
}
136
158
}
0 commit comments