Skip to content

Commit 4b75f00

Browse files
committed
.
1 parent e8e84e8 commit 4b75f00

File tree

4 files changed

+79
-58
lines changed

4 files changed

+79
-58
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
"@angular/forms": "^2.2.0",
3232
"@angular/http": "^2.2.0",
3333
"@angular/platform-browser": "^2.2.0",
34-
"@types/es6-promise": "0.0.32",
3534
"core-js": "^2.4.1",
35+
"firebase": "^3.6.7",
3636
"google-cloud": "^0.45.1",
3737
"image-diff": "^1.6.3",
3838
"rxjs": "5.0.0-beta.12",

tools/gulp/task_helpers.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import * as fs from 'fs';
33
import * as gulp from 'gulp';
44
import * as gulpTs from 'gulp-typescript';
55
import * as path from 'path';
6-
76
import {NPM_VENDOR_FILES, PROJECT_ROOT, DIST_ROOT, SASS_AUTOPREFIXER_OPTIONS} from './constants';
87

98

@@ -213,7 +212,7 @@ export function sequenceTask(...args: any[]) {
213212
}
214213

215214
/** Opens a connection to the firebase realtime database. */
216-
export function openFirebaseDatabase() {
215+
export function openFirebaseDashboardDatabase() {
217216
// Initialize the Firebase application with admin credentials.
218217
// Credentials need to be for a Service Account, which can be created in the Firebase console.
219218
firebaseAdmin.initializeApp({
@@ -251,7 +250,7 @@ export function openScreenshotsCloudStorage() {
251250
}
252251

253252
/** Opens a connection to the firebase realtime database for screenshots. */
254-
export function openScreenshotsFirebaseDatabase() {
253+
export function openFirebaseScreenshotsDatabase() {
255254
// Initialize the Firebase application with admin credentials.
256255
// Credentials need to be for a Service Account, which can be created in the Firebase console.
257256
let screenshotApp = firebaseAdmin.initializeApp({

tools/gulp/tasks/payload.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {task} from 'gulp';
22
import {join} from 'path';
33
import {statSync, readFileSync} from 'fs';
44
import {DIST_COMPONENTS_ROOT} from '../constants';
5-
import {openFirebaseDatabase, isTravisPushBuild} from '../task_helpers';
5+
import {openFirebaseDashboardDatabase, isTravisPushBuild} from '../task_helpers';
66
import {spawnSync} from 'child_process';
77

88
// Those imports lack types.
@@ -48,7 +48,7 @@ function getUglifiedSize(filePath: string) {
4848
/** Publishes the given results to the firebase database. */
4949
function publishResults(results: any) {
5050
let latestSha = spawnSync('git', ['rev-parse', 'HEAD']).stdout.toString().trim();
51-
let database = openFirebaseDatabase();
51+
let database = openFirebaseDashboardDatabase();
5252

5353
// Write the results to the payloads object with the latest Git SHA as key.
5454
return database.ref('payloads').child(latestSha).set(results)

tools/gulp/tasks/screenshots.ts

Lines changed: 74 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import {task} from 'gulp';
22
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';
46
const imageDiff = require('image-diff');
57

68
const SCREENSHOT_DIR = './screenshots';
@@ -11,38 +13,50 @@ const FIREBASE_REPORT = 'screenshot/reports';
1113
task('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+
*/
5880
function 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

Comments
 (0)