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,48 @@ 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
- . then ( ( filenames : string [ ] ) => {
17
- return downloadReferenceScreenshots ( filenames , database )
18
- . then ( ( results : any ) => {
19
- return compareScreenshots ( filenames , database , prNumber ) ;
20
- } ) ;
21
- } )
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 ) )
16
+ let database = openFirebaseScreenshotsDatabase ( ) ;
17
+ return getScreenFilenames ( database )
18
+ . then ( ( filenames : string [ ] ) => downloadAllGolds ( filenames , database , prNumber ) )
19
+ . then ( ( results : boolean ) => updateResult ( database , prNumber , results ) )
20
+ . then ( ( ) => setScreenFilenames ( database , prNumber ) )
27
21
. then ( ( ) => uploadScreenshots ( prNumber , 'diff' ) )
28
22
. then ( ( ) => uploadScreenshots ( prNumber , 'test' ) )
23
+ . then ( ( ) => updateCommit ( database , prNumber ) )
29
24
. then ( ( ) => database . goOffline ( ) , ( ) => database . goOffline ( ) ) ;
30
25
}
31
26
} ) ;
32
27
28
+ function updateFileResult ( database : firebase . database . Database , prNumber : string ,
29
+ filenameKey : string , result : boolean ) : firebase . Promise < void > {
30
+ return database . ref ( FIREBASE_REPORT ) . child ( `${ prNumber } /results/${ filenameKey } ` ) . set ( result ) ;
31
+ }
32
+
33
+ function updateResult ( database : firebase . database . Database , prNumber : string ,
34
+ result : boolean ) : firebase . Promise < void > {
35
+ return database . ref ( FIREBASE_REPORT ) . child ( `${ prNumber } /result` ) . set ( result ) ;
36
+ }
37
+
38
+ function updateCommit ( database : firebase . database . Database ,
39
+ prNumber : string ) : firebase . Promise < void > {
40
+ return database . ref ( FIREBASE_REPORT ) . child ( `${ prNumber } /commit` )
41
+ . set ( process . env [ 'TRAVIS_COMMIT' ] ) ;
42
+ }
43
+
33
44
/** 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 ) {
45
+ function getScreenFilenames ( database : firebase . database . Database ) : firebase . Promise < string [ ] > {
46
+ return database . ref ( FIREBASE_FILELIST ) . once ( 'value' )
47
+ . then ( ( snapshots : firebase . database . DataSnapshot ) => {
36
48
return snapshots . val ( ) ;
37
49
} ) ;
38
50
}
39
51
40
- /** Upload a list of filenames to firebase database as reference . */
41
- function setFilenameList ( database : any ,
42
- reportKey ?: string ) : Promise < any > {
52
+ /** Upload a list of filenames to firebase database as gold . */
53
+ function setScreenFilenames ( database : firebase . database . Database ,
54
+ reportKey ?: string ) : firebase . Promise < void > {
43
55
let filenames : string [ ] = [ ] ;
44
- readdirSync ( SCREENSHOT_DIR ) . map ( function ( file ) {
45
- let fullName = SCREENSHOT_DIR + '/' + file ;
56
+ readdirSync ( SCREENSHOT_DIR ) . map ( ( file : string ) => {
57
+ let fullName = path . join ( SCREENSHOT_DIR , file ) ;
46
58
let key = file . replace ( '.screenshot.png' , '' ) ;
47
59
if ( ! statSync ( fullName ) . isDirectory ( ) && key ) {
48
60
filenames . push ( file ) ;
@@ -54,23 +66,31 @@ function setFilenameList(database: any,
54
66
return filelistDatabase . set ( filenames ) ;
55
67
}
56
68
57
- /** Upload screenshots to google cloud storage. */
69
+ /**
70
+ * Upload screenshots to google cloud storage.
71
+ * @param {string } reportKey - The key used in firebase. Here it is the PR number.
72
+ * If there's no reportKey, we will upload images to 'golds/' folder
73
+ * @param {string } mode - Can be 'test' or 'diff' or null.
74
+ * If the images are the test results, mode should be 'test'.
75
+ * If the images are the diff images generated, mode should be 'diff'.
76
+ * For golds mode should be null.
77
+ */
58
78
function uploadScreenshots ( reportKey ?: string , mode ?: 'test' | 'diff' ) {
59
79
let bucket = openScreenshotsCloudStorage ( ) ;
60
80
61
- let promises : Promise < any > [ ] = [ ] ;
81
+ let promises : firebase . Promise < void > [ ] = [ ] ;
62
82
let localDir = mode == 'diff' ? `${ SCREENSHOT_DIR } /diff` : SCREENSHOT_DIR ;
63
- readdirSync ( localDir ) . map ( function ( file ) {
64
- let fileName = localDir + '/' + file ;
83
+ readdirSync ( localDir ) . map ( ( file : string ) => {
84
+ let fileName = path . join ( localDir , file ) ;
65
85
let key = file . replace ( '.screenshot.png' , '' ) ;
66
86
let destination = ( mode == null || ! reportKey ) ?
67
- `references /${ file } ` : `screenshots/${ reportKey } /${ mode } /${ file } ` ;
87
+ `golds /${ file } ` : `screenshots/${ reportKey } /${ mode } /${ file } ` ;
68
88
69
89
if ( ! statSync ( fileName ) . isDirectory ( ) && key ) {
70
90
promises . push ( bucket . upload ( fileName , { destination : destination } ) ) ;
71
91
}
72
92
} ) ;
73
- return Promise . all ( promises ) ;
93
+ return firebase . Promise . all ( promises ) ;
74
94
}
75
95
76
96
/** Check whether the directory exists. If not then create one. */
@@ -80,57 +100,50 @@ function _makeDir(dirName: string) {
80
100
}
81
101
}
82
102
83
- /** Download references screenshots. */
84
- function downloadReferenceScreenshots (
85
- filenames : string [ ] , database : any ) : Promise < any > {
86
- _makeDir ( `${ SCREENSHOT_DIR } /references` ) ;
103
+ /** Download golds screenshots. */
104
+ function downloadAllGolds (
105
+ filenames : string [ ] , database : firebase . database . Database ,
106
+ reportKey : string ) : firebase . Promise < boolean > {
107
+ _makeDir ( `${ SCREENSHOT_DIR } /golds` ) ;
87
108
88
- return Promise . all ( filenames . map ( ( filename : string ) => {
89
- return _downloadReferenceScreenshot ( filename ) ;
90
- } ) ) ;
109
+ return firebase . Promise . all ( filenames . map ( ( filename : string ) => {
110
+ return downloadGold ( filename ) . then ( ( ) => diffScreenshot ( filename , database , reportKey ) ) ;
111
+ } ) ) . then ( ( results : boolean [ ] ) => results . every ( ( value : boolean ) => value == true ) ) ;
91
112
}
92
113
93
- /** Download one reference screenshot */
94
- function _downloadReferenceScreenshot ( filename : string ) : Promise < any > {
114
+ /** Download one gold screenshot */
115
+ function downloadGold ( filename : string ) : Promise < void > {
95
116
let bucket = openScreenshotsCloudStorage ( ) ;
96
- return bucket . file ( `references /${ filename } ` ) . download ( {
97
- destination : `${ SCREENSHOT_DIR } /references /${ filename } `
117
+ return bucket . file ( `golds /${ filename } ` ) . download ( {
118
+ destination : `${ SCREENSHOT_DIR } /golds /${ filename } `
98
119
} ) ;
99
120
}
100
121
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 ) ) ;
106
- }
107
-
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 } ` ;
122
+ function diffScreenshot ( filename : string , database : firebase . database . Database ,
123
+ reportKey : string ) : firebase . Promise < boolean > {
124
+ // TODO(tinayuangao): Run the downloads and diffs in parallel.
125
+ let goldUrl = `${ SCREENSHOT_DIR } /golds/${ filename } ` ;
126
+ let pullRequestUrl = `${ SCREENSHOT_DIR } /${ filename } ` ;
112
127
let diffUrl = `${ SCREENSHOT_DIR } /diff/${ filename } ` ;
113
128
let filenameKey = filename . replace ( '.screenshot.png' , '' ) ;
114
129
115
- if ( existsSync ( expectedUrl ) && existsSync ( actualUrl ) ) {
116
- return new Promise ( function ( resolve , reject ) {
130
+ if ( existsSync ( goldUrl ) && existsSync ( pullRequestUrl ) ) {
131
+ return new firebase . Promise ( ( resolve : any , reject : any ) => {
117
132
imageDiff ( {
118
- actualImage : actualUrl ,
119
- expectedImage : expectedUrl ,
133
+ actualImage : pullRequestUrl ,
134
+ expectedImage : goldUrl ,
120
135
diffImage : diffUrl ,
121
- } , function ( err : any , imagesAreSame : boolean ) {
136
+ } , ( err : any , imagesAreSame : boolean ) => {
122
137
if ( err ) {
123
138
console . log ( err ) ;
124
139
imagesAreSame = false ;
125
140
reject ( err ) ;
126
141
}
127
142
resolve ( imagesAreSame ) ;
128
- return database . ref ( FIREBASE_REPORT ) . child ( `${ reportKey } /results/${ filenameKey } ` )
129
- . set ( imagesAreSame ) ;
143
+ return updateFileResult ( database , reportKey , filenameKey , imagesAreSame ) ;
130
144
} ) ;
131
145
} ) ;
132
146
} else {
133
- return database . ref ( FIREBASE_REPORT ) . child ( `${ reportKey } /results/${ filenameKey } ` )
134
- . set ( false ) . then ( ( ) => false ) ;
147
+ return updateFileResult ( database , reportKey , filenameKey , false ) . then ( ( ) => false ) ;
135
148
}
136
149
}
0 commit comments