From 090ed27d4fcd4f0872857f3fe0d6801a758e59c4 Mon Sep 17 00:00:00 2001 From: Helena Eksler Date: Mon, 16 Nov 2015 17:10:39 +0200 Subject: [PATCH 1/3] Do not duplicate screenshots --- index.js | 218 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 175 insertions(+), 43 deletions(-) diff --git a/index.js b/index.js index dc64876..c1ecb4b 100644 --- a/index.js +++ b/index.js @@ -11,6 +11,7 @@ var R = require('ramda'); var request = require('request-promise'); var WebdriverCSS = require('webdrivercss'); var WebdriverIO = require('webdriverio'); +var crypto = require('crypto'); var uploads = []; @@ -128,10 +129,8 @@ var uploadFailedImage = function(obj) { var backendUrl = getConfig('backend_url', 'https://live-shoov.pantheon.io'); var options = { - url: backendUrl + '/api/screenshots-upload', - headers: { - 'access-token': accessToken - } + backendUrl: backendUrl, + accessToken: accessToken }; var gitData = { @@ -140,60 +139,193 @@ var uploadFailedImage = function(obj) { gitRepoName: gitRepoName }; - var uploadResponse = ''; - Promise.props(gitData) .then(function(gitData) { - var req = request.post(options); - req - .on('error', function (err) { - throw new Error(err); - }) - .on('data', function(chunk) { - uploadResponse += chunk; + + // Get the repository ID. + var repoOptions = { + url: options.backendUrl + '/api/repositories?filter[label]=' + gitData.gitRepoName + '&fields=id', + headers: { + 'access-token': options.accessToken + } + }; + + request.get(repoOptions) + .then(function(data) { + if (!JSON.parse(data).count) { + // Repository doesn't exist. + return false; + } + // Get the UI Build ID. + return getBuildId(JSON.parse(data).data[0]['id'], options); }) - .on('end', function() { - var data = JSON.parse(uploadResponse).data[0]; - // Populate the build ID. - buildId = buildId || data.build; - - if (getConfig('debug')) { - // Show response. - console.log(data); + .then(function(data) { + if (!JSON.parse(data).count) { + // UI Build doesn't exist. + return false; } + // Check Same screenshots don't exist yet. + var files = [obj.baselinePath, obj.regressionPath, obj.diffPath]; + return getScreenshotByHash(files, JSON.parse(data).data[0]['id'], options); }) - .on('response', function(response) { - if (response.statusCode >= 500) { - throw new Error('Backend error'); + .then(function(data) { + if (JSON.parse(data).count) { + console.log('Screenshots already exist.'); } - else if (response.statusCode !== 200) { - throw new Error('Access token is incorrect or no longer valid, visit your account page'); + else { + // This is new regression. Files should be uploaded. + uploadFiles(gitData, obj, options); + console.log('Upload done.'); } - }); + }) + }); + + throw new Error('Found regression in test'); +}; + +/** + * Upload files to the backend. + * + * @param gitData + * Object that contains git data: gitSubject, gitPrefix and gitRepoName + * @param obj + * Contains references to files. + * @param options + * Object that contains request options: backendUrl and accessToken. + */ +var uploadFiles = function(gitData, obj, options) { + var uploadOptions = { + url: options.backendUrl + '/api/screenshots-upload', + headers: { + 'access-token': options.accessToken + } + }; + + var uploadResponse = ''; - var form = req.form(); + var req = request.post(uploadOptions); + req + .on('error', function (err) { + throw new Error(err); + }) + .on('data', function(chunk) { + uploadResponse += chunk; + }) + .on('end', function() { + var data = JSON.parse(uploadResponse).data[0]; + // Populate the build ID. + buildId = buildId || data.build; + if (getConfig('debug')) { + // Show response. + console.log(data); + } + }) + .on('response', function(response) { + if (response.statusCode >= 500) { + throw new Error('Backend error'); + } + else if (response.statusCode !== 200) { + throw new Error('Access token is incorrect or no longer valid, visit your account page'); + } + }); - var label = path.basename(obj.baselinePath, '.baseline.png').replace('.', ' '); - form.append('label', label); + var form = req.form(); - form.append('baseline', fs.createReadStream(obj.baselinePath)); - form.append('regression', fs.createReadStream(obj.regressionPath)); - form.append('diff', fs.createReadStream(obj.diffPath)); + var label = path.basename(obj.baselinePath, '.baseline.png').replace('.', ' '); - form.append('baseline_name', obj.baselinePath); - form.append('git_commit', gitCommit); - form.append('git_branch', gitBranch); - form.append('git_subject', gitData.gitSubject); + form.append('label', label); - form.append('directory_prefix', gitData.gitPrefix); - form.append('repository', gitData.gitRepoName); + form.append('baseline', fs.createReadStream(obj.baselinePath)); + form.append('regression', fs.createReadStream(obj.regressionPath)); + form.append('diff', fs.createReadStream(obj.diffPath)); - form.append('tags', obj.properties.tags ? obj.properties.tags.join(',') : ''); + form.append('baseline_name', obj.baselinePath); + form.append('git_commit', gitCommit); + form.append('git_branch', gitBranch); + form.append('git_subject', gitData.gitSubject); - uploads.push(req); - }); + form.append('directory_prefix', gitData.gitPrefix); + form.append('repository', gitData.gitRepoName); - throw new Error('Found regression in test'); + uploads.push(req); +}; + +/** + * Get UI Build ID by the repository ID from backend. + * + * @param repoId + * Repository ID. + * @param options + * Object that contains request options: backendUrl and accessToken. + */ +var getBuildId = function(repoId, options) { + var buildOptions = { + url: options.backendUrl + '/api/builds?filter[repository]=' + repoId + '&fields=id', + headers: { + 'access-token': options.accessToken + } + }; + return request.get(buildOptions); +}; + +/** + * Get the Screenshots by the hash tag. + * + * @param files + * Array that contains images urls. + * @param buildId + * UI Build ID. + * @param options + * Object that contains request options: backendUrl and accessToken. + */ +var getScreenshotByHash = function(files, buildId, options) { + var hash = createHashTag(files, buildId); + + var screenshotOptions = { + url: options.backendUrl + '/api/screenshots?filter[build]=' + buildId + '&filter[screenshot_hash]=' + hash + '&fields=id', + headers: { + 'access-token': options.accessToken + } + }; + + return request.get(screenshotOptions); +}; + +/** + * Creates hash tag for the screenshot. + * + * @param files + * Array of Screenshot images urls./ + * @param buildId + * UI Build ID. + * + * @return string + * Returns hash tag. + */ +var createHashTag = function(files, buildId) { + var hash = []; + files.forEach(function(file) { + hash.push(getFileContentsHash(file)); + }); + + hash.push(buildId); + + return crypto.createHash('md5').update(hash.join('')).digest("hex"); +}; + +/** + * Create hash tag from the file contents. + * + * @param path + * The path to the file. + * + * @returns string + * Returns the hash tag. + */ +var getFileContentsHash = function(path) { + // Get the file contents. + var file = fs.readFileSync(path, 'binary'); + return crypto.createHash('md5').update(file).digest("hex"); }; var wdcssSetup = { From 57feac9d9d8d216d5a89ad1c9a95971068f0c573 Mon Sep 17 00:00:00 2001 From: Helena Eksler Date: Tue, 17 Nov 2015 07:21:47 +0200 Subject: [PATCH 2/3] Update --- index.js | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index c1ecb4b..8563853 100644 --- a/index.js +++ b/index.js @@ -166,11 +166,13 @@ var uploadFailedImage = function(obj) { } // Check Same screenshots don't exist yet. var files = [obj.baselinePath, obj.regressionPath, obj.diffPath]; - return getScreenshotByHash(files, JSON.parse(data).data[0]['id'], options); + buildId = JSON.parse(data).data[0]['id']; + return getScreenshotByHash(files, buildId, options); }) .then(function(data) { if (JSON.parse(data).count) { console.log('Screenshots already exist.'); + showRegressionLink(buildId); } else { // This is new regression. Files should be uploaded. @@ -328,6 +330,22 @@ var getFileContentsHash = function(path) { return crypto.createHash('md5').update(file).digest("hex"); }; +/** + * Show in console link to the regression images in the client. + * + * @param buildId + * UI Build ID. + */ +var showRegressionLink = function(buildId) { + var clientUrl = getConfig('client_url', 'https://app.shoov.io'); + var regressionUrl = clientUrl + '/#/screenshots/' + buildId + '?XDEBUG_SESSION_START=16066'; + console.log('See regressions in: ' + regressionUrl); + + if (getConfig('open_link')) { + open(regressionUrl) + } +}; + var wdcssSetup = { /** @@ -356,13 +374,7 @@ var wdcssSetup = { .all(uploads) .then(function() { if (uploads.length) { - var clientUrl = getConfig('client_url', 'https://app.shoov.io'); - var regressionUrl = clientUrl + '/#/screenshots/' + buildId; - console.log('See regressions in: ' + regressionUrl); - - if (getConfig('open_link')) { - open(regressionUrl) - } + showRegressionLink(buildId); } client.end(done); From 23b58f2af7f1c970b1da7e3cc170a7d4f5a86687 Mon Sep 17 00:00:00 2001 From: Helena Eksler Date: Sun, 29 Nov 2015 08:03:15 +0200 Subject: [PATCH 3/3] Comments --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 8563853..59106fc 100644 --- a/index.js +++ b/index.js @@ -176,8 +176,8 @@ var uploadFailedImage = function(obj) { } else { // This is new regression. Files should be uploaded. + console.log('Screenshots will be uploaded.'); uploadFiles(gitData, obj, options); - console.log('Upload done.'); } }) }); @@ -297,7 +297,7 @@ var getScreenshotByHash = function(files, buildId, options) { * Creates hash tag for the screenshot. * * @param files - * Array of Screenshot images urls./ + * Array of Screenshot images urls. * @param buildId * UI Build ID. *