Skip to content

Commit fffb5f0

Browse files
committed
Move files to tools/screenshot-test/functions
1 parent 8ed0d58 commit fffb5f0

File tree

15 files changed

+102
-179
lines changed

15 files changed

+102
-179
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
/screenshots
88

99
# dependencies
10-
/node_modules
10+
node_modules
1111
/bower_components
1212

1313
# Dart

functions/data.ts

Lines changed: 0 additions & 22 deletions
This file was deleted.

functions/index.js

Lines changed: 0 additions & 106 deletions
This file was deleted.

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
"@angular/platform-browser-dynamic": "^4.0.0",
4343
"@angular/platform-server": "^4.0.0",
4444
"@angular/router": "^4.0.0",
45+
"@google-cloud/storage": "^0.8.0",
4546
"@types/chalk": "^0.4.31",
4647
"@types/fs-extra": "0.0.37",
4748
"@types/glob": "^5.0.30",
@@ -61,6 +62,7 @@
6162
"dgeni": "^0.4.7",
6263
"dgeni-packages": "^0.16.5",
6364
"firebase-admin": "^4.1.2",
65+
"firebase-functions": "^0.5.2",
6466
"firebase-tools": "^2.2.1",
6567
"firebase": "^3.7.2",
6668
"fs-extra": "^2.0.0",
@@ -86,6 +88,7 @@
8688
"http-rewrite-middleware": "^0.1.6",
8789
"image-diff": "^1.6.3",
8890
"jasmine-core": "^2.5.2",
91+
"jsonwebtoken": "^7.3.0",
8992
"karma": "^1.5.0",
9093
"karma-browserstack-launcher": "^1.2.0",
9194
"karma-chrome-launcher": "^2.0.0",
@@ -99,6 +102,7 @@
99102
"minimist": "^1.2.0",
100103
"node-sass": "^4.5.0",
101104
"protractor": "^5.1.1",
105+
"request": "^2.81.0",
102106
"resolve-bin": "^0.4.0",
103107
"rollup": "^0.41.6",
104108
"run-sequence": "^1.2.2",

functions/data_image.ts renamed to tools/screenshot-test/functions/data_image.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as firebaseFunctions from 'firebase-functions';
22
import {writeFileSync} from 'fs';
3-
import {verifySecureTokenAndExecute} from './jwt_util';
3+
import {verifySecureToken} from './jwt_util';
4+
import {isCreateEvent} from './util/util';
45

56
const gcs = require('@google-cloud/storage')();
67

@@ -10,10 +11,11 @@ const bucket = gcs.bucket(firebaseFunctions.config().firebase.storageBucket);
1011
/**
1112
* Convert data to images. Image data posted to database will be saved as png files
1213
* and uploaded to screenshot/$prNumber/dataType/$filename
14+
* Convert BufferArray to .png image file
1315
*/
1416
export function convertTestImageDataToFiles(event: any) {
1517
// Only edit data when it is first created. Exit when the data is deleted.
16-
if (event.data.previous.exists() || !event.data.exists()) {
18+
if (!isCreateEvent(event)) {
1719
return;
1820
}
1921

@@ -22,11 +24,12 @@ export function convertTestImageDataToFiles(event: any) {
2224
let data = event.data.val();
2325
let saveFilename = `${event.params.filename}.screenshot.png`;
2426

27+
// Check it's either diff images generated by screenshot comparison, or the test image results
2528
if (dataType !== 'diff' && dataType !== 'test') {
2629
return;
2730
}
2831

29-
return verifySecureTokenAndExecute(event).then(() => {
32+
return verifySecureToken(event).then(() => {
3033
let tempPath = `/tmp/${dataType}-${saveFilename}`;
3134
let filePath = `screenshots/${prNumber}/${dataType}/${saveFilename}`;
3235
let binaryData = new Buffer(data, 'base64').toString('binary');

functions/github.ts renamed to tools/screenshot-test/functions/github.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import * as firebaseAdmin from 'firebase-admin';
21
import * as firebaseFunctions from 'firebase-functions';
32
import {setGithubStatus} from './util/github';
43

functions/image_data.ts renamed to tools/screenshot-test/functions/image_data.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,21 @@ import {readFileSync} from 'fs';
44

55
const gcs = require('@google-cloud/storage')();
66

7+
/** Folder on Firebase database to store golden images data */
78
const FIREBASE_DATA_GOLDENS = 'screenshot/goldens';
89

910
/**
1011
* Read golden files under /goldens/ and store the image data to
1112
* database /screenshot/goldens/$filename
13+
* Convert png image files to BufferArray data
1214
*/
1315
export function convertGoldenImagesToData(name: string, resourceState: string, fileBucket: any) {
1416
// The name should always look like "goldens/xxx.png"
1517
let parsedPath = path.parse(name);
1618
// Get the file name.
17-
if (parsedPath.root != '' || parsedPath.dir != 'goldens' || parsedPath.ext != '.png') {
19+
if (parsedPath.root != '' ||
20+
parsedPath.dir != 'goldens' ||
21+
parsedPath.ext.toLowerCase() != '.png') {
1822
return;
1923
}
2024

functions/index.ts renamed to tools/screenshot-test/functions/index.ts

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,45 @@
33
import * as firebaseFunctions from 'firebase-functions';
44
import * as firebaseAdmin from 'firebase-admin';
55

6-
import {verifyJWTAndUpdateData} from './data';
6+
import {verifyJwtAndTransferResultToTrustedLocation} from './verify-and-copy-report';
77
import {convertGoldenImagesToData} from './image_data';
88
import {convertTestImageDataToFiles} from './data_image';
99
import {copyTestImagesToGoldens} from './test_goldens';
1010
import {updateGithubStatus} from './github';
1111

1212
/**
1313
* Usage: Firebase functions only accept javascript file index.js
14-
* tsc
14+
* tsc -p tools/screenshot-test/functions/tsconfig.json
15+
* cd functions
16+
* npm install
1517
* firebase deploy --only functions
1618
*
1719
*
1820
* Data and images handling for Screenshot test.
1921
*
20-
* All users can post data to temporary folder. These Functions will check the data with JsonWebToken and
21-
* move the valid data out of temporary folder.
22+
* All users can post data to temporary folder. These Functions will check the data with
23+
* JsonWebToken and move the valid data out of temporary folder.
2224
*
2325
* For valid data posted to database /$temp/screenshot/reports/$prNumber/$secureToken, move it to
2426
* /screenshot/reports/$prNumber.
25-
* These are data for screenshot results (success or failure), GitHub PR/commit and TravisCI job information
27+
* These are data for screenshot results (success or failure), GitHub PR/commit and TravisCI job
28+
* information.
2629
*
27-
* For valid image results written to database /$temp/screenshot/images/$prNumber/$secureToken/, save the image
28-
* data to image files and upload to google cloud storage under location /screenshots/$prNumber
29-
* These are screenshot test result images, and difference images generated from screenshot comparison.
30+
* For valid image results written to database /$temp/screenshot/images/$prNumber/$secureToken/,
31+
* save the image data to image files and upload to google cloud storage under
32+
* location /screenshots/$prNumber
33+
* These are screenshot test result images, and difference images generated from screenshot
34+
* comparison.
3035
*
31-
* For golden images uploaded to /goldens, read the data from images files and write the data to Firebase database
32-
* under location /screenshot/goldens
33-
* Screenshot tests can only read restricted database data with no credentials, and they cannot access
34-
* Google Cloud Storage. Therefore we copy the image data to database to make it available to screenshot tests.
36+
* For golden images uploaded to /goldens, read the data from images files and write the data to
37+
* Firebase database under location /screenshot/goldens
38+
* Screenshot tests can only read restricted database data with no credentials, and they cannot
39+
* access.
40+
* Google Cloud Storage. Therefore we copy the image data to database to make it available to
41+
* screenshot tests.
3542
*
36-
* The JWT is stored in the data path, so every write to database needs a valid JWT to be copied to database/storage.
43+
* The JWT is stored in the data path, so every write to database needs a valid JWT to be copied to
44+
* database/storage.
3745
* All invalid data will be removed.
3846
* The JWT has 3 parts: header, payload and signature. These three parts are joint by '/' in path.
3947
*/
@@ -65,11 +73,11 @@ const trustedReportPath = `screenshot/reports/{prNumber}`;
6573
* sha (github PR info), result (true or false for all the tests), travis job number
6674
*/
6775
const testDataPath = `${reportPath}/{dataType}`;
68-
exports.testData = firebaseFunctions.database.ref(testDataPath)
76+
export let testData = firebaseFunctions.database.ref(testDataPath)
6977
.onWrite((event: any) => {
7078
const dataType = event.params.dataType;
7179
if (dataTypes.includes(dataType)) {
72-
return verifyJWTAndUpdateData(event, dataType);
80+
return verifyJwtAndTransferResultToTrustedLocation(event, dataType);
7381
}
7482
});
7583

@@ -79,9 +87,9 @@ exports.testData = firebaseFunctions.database.ref(testDataPath)
7987
* Data copied: test result for each file/test with ${filename}. The value should be true or false.
8088
*/
8189
const testResultsPath = `${reportPath}/results/{filename}`;
82-
exports.testResults = firebaseFunctions.database.ref(testResultsPath)
90+
export let testResults = firebaseFunctions.database.ref(testResultsPath)
8391
.onWrite((event: any) => {
84-
return verifyJWTAndUpdateData(event, `results/${event.params.filename}`);
92+
return verifyJwtAndTransferResultToTrustedLocation(event, `results/${event.params.filename}`);
8593
});
8694

8795
/**
@@ -90,14 +98,14 @@ exports.testResults = firebaseFunctions.database.ref(testResultsPath)
9098
* Data copied: test result images. Convert from data to image files in storage.
9199
*/
92100
const imageDataToFilePath = `${imagePath}/{dataType}/{filename}`;
93-
exports.imageDataToFile = firebaseFunctions.database.ref(imageDataToFilePath)
101+
export let imageDataToFile = firebaseFunctions.database.ref(imageDataToFilePath)
94102
.onWrite(convertTestImageDataToFiles);
95103

96104
/**
97105
* Copy valid goldens from storage /goldens/ to database /screenshot/goldens/
98106
* so we can read the goldens without credentials.
99107
*/
100-
exports.goldenImageToData = firebaseFunctions.storage.bucket(
108+
export let goldenImageToData = firebaseFunctions.storage.bucket(
101109
firebaseFunctions.config().firebase.storageBucket).object().onChange((event: any) => {
102110
return convertGoldenImagesToData(event.data.name, event.data.resourceState, event.data.bucket);
103111
});
@@ -107,7 +115,8 @@ exports.goldenImageToData = firebaseFunctions.storage.bucket(
107115
* Copy images from /screenshot/$prNumber/test/ to /goldens/
108116
*/
109117
const approveImagesPath = `${trustedReportPath}/approved`;
110-
exports.approveImages = firebaseFunctions.database.ref(approveImagesPath).onWrite((event: any) => {
118+
export let approveImages = firebaseFunctions.database.ref(approveImagesPath)
119+
.onWrite((event: any) => {
111120
return copyTestImagesToGoldens(event.params.prNumber);
112121
});
113122

@@ -117,4 +126,5 @@ exports.approveImages = firebaseFunctions.database.ref(approveImagesPath).onWrit
117126
* The Github Status Token is set in config.secret.github
118127
*/
119128
const githubStatusPath = `${trustedReportPath}/result/{sha}`;
120-
exports.githubStatus = firebaseFunctions.database.ref(githubStatusPath).onWrite(updateGithubStatus);
129+
export let githubStatus = firebaseFunctions.database.ref(githubStatusPath)
130+
.onWrite(updateGithubStatus);

functions/jwt_util.ts renamed to tools/screenshot-test/functions/jwt_util.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as firebaseFunctions from 'firebase-functions';
2-
import {verifySecureToken} from './util/jwt';
2+
import {verifyJWT} from './util/jwt';
33

44
/** The repo slug. This is used to validate the JWT is sent from correct repo. */
55
const repoSlug = firebaseFunctions.config().repo.slug;
@@ -17,15 +17,15 @@ function getSecureToken(event: firebaseFunctions.Event<any>) {
1717
};
1818

1919
/**
20-
* Verify event params have correct JsonWebToken, and execute callback when the JWT is verified.
21-
* Delete the data if there's an error or the callback is done
20+
* Verify that the event has a valid JsonWebToken. If the token is *not* valid,
21+
* the data tied to the event will be deleted and the function will return a rejected promise.
2222
*/
23-
export function verifySecureTokenAndExecute(event: firebaseFunctions.Event<any>) {
23+
export function verifySecureToken(event: firebaseFunctions.Event<any>) {
2424
return new Promise((resolve, reject) => {
2525
const prNumber = event.params.prNumber;
2626
const secureToken = getSecureToken(event);
2727

28-
return verifySecureToken(secureToken, prNumber, secret, repoSlug).then(() => {
28+
return verifyJWT(secureToken, prNumber, secret, repoSlug).then(() => {
2929
resolve();
3030
event.data.ref.parent.set(null);
3131
}).catch((error: any) => {

0 commit comments

Comments
 (0)