Skip to content

Commit

Permalink
feat: use normalized redux store (#346)
Browse files Browse the repository at this point in the history
  • Loading branch information
DudaGod authored Aug 28, 2020
1 parent 537ca0b commit 7bc60bc
Show file tree
Hide file tree
Showing 129 changed files with 4,954 additions and 4,938 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,12 +300,12 @@ tool.htmlReporter.addMetaInfoExtender(name, value);
```
* **name** (required) `String` - name of meta info
* **value** (required) `Function` - handler to which `suite` and `extraItems` are passed
* **value** (required) `Function` - handler to which `data` (`Object` with `testName` field) and `extraItems` are passed
Example:
```js
tool.htmlReporter.addMetaInfoExtender('foo', (suite, extraItems) => {
return suite.suitePath.join(' ') + extraItems.platform;
tool.htmlReporter.addMetaInfoExtender('foo', (data, extraItems) => {
return data.testName + extraItems.platform;
});
```
Expand Down
60 changes: 8 additions & 52 deletions lib/gui/app.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
'use strict';

const path = require('path');
const _ = require('lodash');
const looksSame = require('looks-same');
const Promise = require('bluebird');
const ToolRunner = require('./tool-runner');

const lookSameAsync = (img1, img2, opts) => {
return new Promise((resolve, reject) => {
looksSame(img1, img2, opts, (err, data) => {
err ? reject(err) : resolve(data);
});
});
};

module.exports = class App {
static create(paths, hermione, configs) {
return new this(paths, hermione, configs);
Expand Down Expand Up @@ -54,53 +43,20 @@ module.exports = class App {
.finally(() => this._restoreRetries());
}

updateReferenceImage(failedTests = []) {
return this._toolRunner.updateReferenceImage(failedTests);
getTestsDataToUpdateRefs(imageIds = []) {
return this._toolRunner.getTestsDataToUpdateRefs(imageIds);
}

_resolveImgPath(imgPath) {
return path.resolve(process.cwd(), this._pluginConfig.path, imgPath);
getImageDataToFindEqualDiffs(imageIds = []) {
return this._toolRunner.getImageDataToFindEqualDiffs(imageIds);
}

_getCompareOpts() {
const {tolerance, antialiasingTolerance} = this._toolRunner.config;

return {tolerance, antialiasingTolerance, stopOnFirstFail: true, shouldCluster: false};
updateReferenceImage(failedTests = []) {
return this._toolRunner.updateReferenceImage(failedTests);
}

async findEqualDiffs(imagesInfo) {
const [refImagesInfo, ...comparedImagesInfo] = imagesInfo;
const compareOpts = this._getCompareOpts();

return await Promise.filter(comparedImagesInfo, async (imageInfo) => {
try {
await Promise.mapSeries(imageInfo.diffClusters, async (diffCluster, i) => {
const refComparisonRes = await lookSameAsync(
{source: this._resolveImgPath(refImagesInfo.expectedImg.path), boundingBox: refImagesInfo.diffClusters[i]},
{source: this._resolveImgPath(imageInfo.expectedImg.path), boundingBox: diffCluster},
compareOpts
);

if (!refComparisonRes.equal) {
return Promise.reject(false);
}

const actComparisonRes = await lookSameAsync(
{source: this._resolveImgPath(refImagesInfo.actualImg.path), boundingBox: refImagesInfo.diffClusters[i]},
{source: this._resolveImgPath(imageInfo.actualImg.path), boundingBox: diffCluster},
compareOpts
);

if (!actComparisonRes.equal) {
return Promise.reject(false);
}
});

return true;
} catch (err) {
return err === false ? err : Promise.reject(err);
}
});
async findEqualDiffs(data) {
return this._toolRunner.findEqualDiffs(data);
}

addClient(connection) {
Expand Down
18 changes: 18 additions & 0 deletions lib/gui/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,30 @@ exports.start = async ({paths, hermione, guiApi, configs}) => {
res.sendStatus(OK);
});

server.post('/get-update-reference-data', (req, res) => {
try {
const data = app.getTestsDataToUpdateRefs(req.body);
res.json(data);
} catch (error) {
res.status(INTERNAL_SERVER_ERROR).send({error: error.message});
}
});

server.post('/update-reference', (req, res) => {
app.updateReferenceImage(req.body)
.then((updatedTests) => res.json(updatedTests))
.catch(({message}) => res.status(INTERNAL_SERVER_ERROR).send({error: message}));
});

server.post('/get-find-equal-diffs-data', (req, res) => {
try {
const data = app.getImageDataToFindEqualDiffs(req.body);
res.json(data);
} catch (error) {
res.status(INTERNAL_SERVER_ERROR).send({error: error.message});
}
});

server.post('/find-equal-diffs', async (req, res) => {
try {
const result = await app.findEqualDiffs(req.body);
Expand Down
97 changes: 76 additions & 21 deletions lib/gui/tool-runner/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const fs = require('fs-extra');
const path = require('path');
const chalk = require('chalk');
const Promise = require('bluebird');
const looksSame = require('looks-same');

const Runner = require('./runner');
const subscribeOnToolEvents = require('./report-subscriber');
Expand All @@ -15,14 +16,15 @@ const reporterHelper = require('../../reporter-helpers');
const {UPDATED} = require('../../constants/test-statuses');
const constantFileNames = require('../../constants/file-names');
const logger = utils.logger;
const {
formatTests,
formatId, getShortMD5,
mkFullTitle,
mergeDatabasesForReuse,
getDataFromDatabase,
findTestResult
} = require('./utils');
const {formatId, getShortMD5, mkFullTitle, mergeDatabasesForReuse, getDataFromDatabase, filterByEqualDiffSizes} = require('./utils');

const lookSameAsync = (img1, img2, opts) => {
return new Promise((resolve, reject) => {
looksSame(img1, img2, opts, (err, data) => {
err ? reject(err) : resolve(data);
});
});
};

module.exports = class ToolRunner {
static create(paths, hermione, configs) {
Expand Down Expand Up @@ -51,8 +53,7 @@ module.exports = class ToolRunner {
}

get tree() {
const {suites} = this._reportBuilder.getResult();
return {...this._tree, suites};
return this._tree;
}

async initialize() {
Expand Down Expand Up @@ -86,16 +87,28 @@ module.exports = class ToolRunner {
this._eventSource.emit(event, data);
}

updateReferenceImage(tests) {
const reportBuilder = this._reportBuilder;
getTestsDataToUpdateRefs(imageIds) {
return this._reportBuilder.getTestsDataToUpdateRefs(imageIds);
}

getImageDataToFindEqualDiffs(imageIds) {
const [selectedImage, ...comparedImages] = this._reportBuilder.getImageDataToFindEqualDiffs(imageIds);

const imagesWithEqualBrowserName = comparedImages.filter((image) => image.browserName === selectedImage.browserName);
const imagesWithEqualDiffSizes = filterByEqualDiffSizes(imagesWithEqualBrowserName, selectedImage.diffClusters);

return _.isEmpty(imagesWithEqualDiffSizes) ? [] : [selectedImage].concat(imagesWithEqualDiffSizes);
}

updateReferenceImage(tests) {
return Promise.map(tests, (test) => {
const updateResult = this._prepareUpdateResult(test);
const formattedResult = reportBuilder.format(updateResult, UPDATED);
const formattedResult = this._reportBuilder.format(updateResult, UPDATED);
const failResultId = formattedResult.id;

if (formattedResult.attempt < updateResult.attempt) {
formattedResult.attempt = updateResult.attempt;
}
const updateAttempt = this._reportBuilder.getUpdatedAttempt(formattedResult);
formattedResult.attempt = updateAttempt;
updateResult.attempt = updateAttempt;

return Promise.map(updateResult.imagesInfo, (imageInfo) => {
const {stateName} = imageInfo;
Expand All @@ -107,16 +120,54 @@ module.exports = class ToolRunner {
this._emitUpdateReference(result, stateName);
});
})
.then(() => reportBuilder.addUpdated(updateResult))
.then(() => findTestResult(reportBuilder.getSuites(), formattedResult.prepareTestResult()));
.then(() => {
this._reportBuilder.addUpdated(updateResult, failResultId);
return this._reportBuilder.getTestBranch(formattedResult.id);
});
});
}

async findEqualDiffs(images) {
const [selectedImage, ...comparedImages] = images;
const {tolerance, antialiasingTolerance} = this.config;
const compareOpts = {tolerance, antialiasingTolerance, stopOnFirstFail: true, shouldCluster: false};
const equalImages = await Promise.filter(comparedImages, async (image) => {
try {
await Promise.mapSeries(image.diffClusters, async (diffCluster, i) => {
const refComparisonRes = await lookSameAsync(
{source: this._resolveImgPath(selectedImage.expectedImg.path), boundingBox: selectedImage.diffClusters[i]},
{source: this._resolveImgPath(image.expectedImg.path), boundingBox: diffCluster},
compareOpts
);

if (!refComparisonRes.equal) {
return Promise.reject(false);
}

const actComparisonRes = await lookSameAsync(
{source: this._resolveImgPath(selectedImage.actualImg.path), boundingBox: selectedImage.diffClusters[i]},
{source: this._resolveImgPath(image.actualImg.path), boundingBox: diffCluster},
compareOpts
);

if (!actComparisonRes.equal) {
return Promise.reject(false);
}
});

return true;
} catch (err) {
return err === false ? err : Promise.reject(err);
}
});

return equalImages.map((image) => image.id);
}

run(tests = []) {
const {grep, set: sets, browser: browsers} = this._globalOpts;
const formattedTests = _.flatMap([].concat(tests), (test) => formatTests(test));

return Runner.create(this._collection, formattedTests)
return Runner.create(this._collection, tests)
.run((collection) => this._hermione.run(collection, {grep, sets, browsers}));
}

Expand Down Expand Up @@ -181,7 +232,7 @@ module.exports = class ToolRunner {
this._reportBuilder.reuseTestsTree(testsTree);
}

this._tree = {...this._reportBuilder.getResult(), gui: true, autoRun};
this._tree = {...this._reportBuilder.getResult(), autoRun};
}

async _loadDataFromDatabase() {
Expand All @@ -195,4 +246,8 @@ module.exports = class ToolRunner {

return {};
}

_resolveImgPath(imgPath) {
return path.resolve(process.cwd(), this._pluginConfig.path, imgPath);
}
};
35 changes: 17 additions & 18 deletions lib/gui/tool-runner/report-subscriber.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
const clientEvents = require('../constants/client-events');
const {RUNNING} = require('../../constants/test-statuses');
const {getSuitePath} = require('../../plugin-utils').getHermioneUtils();
const {findTestResult, withErrorHandling} = require('./utils');
const {withErrorHandling} = require('./utils');
const createWorkers = require('../../workers/create-workers');

let workers;
Expand Down Expand Up @@ -33,20 +33,19 @@ module.exports = (hermione, reportBuilder, client, reportPath) => {
}

client.emit(clientEvents.BEGIN_SUITE, {
name: suite.title,
suitePath: getSuitePath(suite),
suiteId: getSuitePath(suite).join(' '),
status: RUNNING
});
});

hermione.on(hermione.events.TEST_BEGIN, (data) => {
const {browserId} = data;
const formattedResult = reportBuilder.format(data, RUNNING);
formattedResult.attempt = reportBuilder.getCurrAttempt(formattedResult);

client.emit(clientEvents.BEGIN_STATE, {
suitePath: getSuitePath(data),
browserId,
status: RUNNING
});
reportBuilder.addRunning(formattedResult);
const testBranch = reportBuilder.getTestBranch(formattedResult.id);

return client.emit(clientEvents.BEGIN_STATE, testBranch);
});

hermione.on(hermione.events.TEST_PASS, async (data) => {
Expand All @@ -56,12 +55,9 @@ module.exports = (hermione, reportBuilder, client, reportPath) => {

await formattedResult.saveTestImages(reportPath, workers);
reportBuilder.addSuccess(formattedResult);
const testResult = findTestResult(
reportBuilder.getSuites(),
formattedResult.prepareTestResult()
);

return client.emit(clientEvents.TEST_RESULT, testResult);
const testBranch = reportBuilder.getTestBranch(formattedResult.id);
return client.emit(clientEvents.TEST_RESULT, testBranch);
});
});

Expand All @@ -74,9 +70,9 @@ module.exports = (hermione, reportBuilder, client, reportPath) => {
formattedResult.hasDiff()
? reportBuilder.addFail(formattedResult)
: reportBuilder.addError(formattedResult);
const testResult = findTestResult(reportBuilder.getSuites(), formattedResult.prepareTestResult());

return client.emit(clientEvents.TEST_RESULT, testResult);
const testBranch = reportBuilder.getTestBranch(formattedResult.id);
return client.emit(clientEvents.TEST_RESULT, testBranch);
});
});

Expand All @@ -87,6 +83,9 @@ module.exports = (hermione, reportBuilder, client, reportPath) => {

await failHandler(formattedResult);
reportBuilder.addRetry(formattedResult);

const testBranch = reportBuilder.getTestBranch(formattedResult.id);
return client.emit(clientEvents.TEST_RESULT, testBranch);
});
});

Expand All @@ -97,9 +96,9 @@ module.exports = (hermione, reportBuilder, client, reportPath) => {

await failHandler(formattedResult);
reportBuilder.addSkipped(formattedResult);
const testResult = findTestResult(reportBuilder.getSuites(), formattedResult.prepareTestResult());

return client.emit(clientEvents.TEST_RESULT, testResult);
const testBranch = reportBuilder.getTestBranch(formattedResult.id);
return client.emit(clientEvents.TEST_RESULT, testBranch);
});
});

Expand Down
5 changes: 2 additions & 3 deletions lib/gui/tool-runner/runner/specific-test-runner.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict';

const Runner = require('./runner');
const {mkFullTitle} = require('../utils');

module.exports = class SpecificTestRunner extends Runner {
constructor(collection, tests) {
Expand All @@ -19,8 +18,8 @@ module.exports = class SpecificTestRunner extends Runner {
_filter() {
this._collection.disableAll();

this._tests.forEach((test) => {
this._collection.enableTest(mkFullTitle(test), test.browserId);
this._tests.forEach(({testName, browserName}) => {
this._collection.enableTest(testName, browserName);
});
}
};
Loading

0 comments on commit 7bc60bc

Please sign in to comment.