Skip to content
This repository was archived by the owner on Sep 21, 2022. It is now read-only.

Commit 09b4318

Browse files
committed
feat: emits image sizes on test execution events
BREAKING CHANGE: now on test execution events (TEST_RESULT, UPDATE_RESULT, RETRY, ERROR) emited image info (object) with path and size instead of only emit image path
1 parent 3daaf2b commit 09b4318

13 files changed

Lines changed: 206 additions & 136 deletions

File tree

doc/events.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ Emitted before launching browser for test. Event is emitted with 1 argument <cod
136136
Emitted always during update. Event is emitted with 1 argument <code>result</code>:
137137
<pre>
138138
{
139-
imagePath, // absolute path to the reference image
139+
refImg, // reference image info which includes absolute path and size (width, height)
140140
updated, // shows if reference image has been changed
141141
suite,
142142
state,
@@ -154,8 +154,8 @@ Emitted if test has failed but <b>there is still number of retries left</b>.
154154
Event is emitted with 1 argument <code>result</code>:
155155
<pre>
156156
{
157-
referencePath, // absolute path to the reference image
158-
currentPath, // absolute path to the current image on your disk
157+
refImg, // reference image info which includes absolute path and size (width, height)
158+
currImg, // current image info which includes absolute path and size (width, height)
159159
equal, // always <i>false</i> for retries
160160
tolerance, // specified for current test or globally in <i>.gemini.js</i>
161161
saveDiffTo, /* function responsible for building <i>diff</i> and <i>present</i>
@@ -178,8 +178,8 @@ Event is emitted with 1 argument <code>result</code>:
178178
Emitted always after the test is completed. Event is emitted with 1 argument <code>result</code>:
179179
<pre>
180180
{
181-
referencePath, // absolute path to the reference image
182-
currentPath, // absolute path to the current image on your disk
181+
refImg, // reference image info which includes absolute path and size (width, height)
182+
currImg, // current image info which includes absolute path and size (width, height)
183183
equal, // shows if images are equal
184184
tolerance, // specified for current test or globally in <i>.gemini.js</i>
185185
saveDiffTo, /* function responsible for building <i>diff</i> and <i>present</i>
@@ -240,8 +240,8 @@ For example, if <i>Reference image is missing</i>, <code>err</code> will have ad
240240

241241
<pre>
242242
{
243-
currentPath,
244-
refImagePath,
243+
refImg,
244+
currImg,
245245
suite,
246246
state,
247247
browserId,

lib/capture-session.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ module.exports = class CaptureSession {
5151
const path = temp.path({suffix: '.png'});
5252

5353
return this.browser.captureViewportImage()
54-
.then((screenImage) => screenImage.save(path))
55-
.then(() => (obj.imagePath = path))
54+
.then((screenImage) => [screenImage.getSize(), screenImage.save(path)])
55+
.spread((size) => {
56+
obj.img = {path, size};
57+
})
5658
.catch(_.noop)
5759
.then(() => obj);
5860
}

lib/errors/no-ref-image-error.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
const StateError = require('./state-error');
44

55
module.exports = class NoRefImageError extends StateError {
6-
constructor(refImagePath, currentPath) {
7-
super(`Can not find reference image at ${refImagePath}.\n` +
6+
constructor(refImg = {}, currImg = {}) {
7+
super(`Can not find reference image at ${refImg.path}.\n` +
88
'Run `gemini update` command to capture all reference images.');
99

1010
this.name = 'NoRefImageError';
11-
this.currentPath = currentPath;
12-
this.refImagePath = refImagePath;
11+
this.refImg = refImg;
12+
this.currImg = currImg;
1313
}
1414
};

lib/errors/utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const StateError = require('./state-error');
77

88
exports.fromPlainObject = e => {
99
if (e.name === 'NoRefImageError') {
10-
return new NoRefImageError(e.refImagePath, e.currentPath);
10+
return new NoRefImageError(e.refImg, e.currImg);
1111
}
1212
if (e.name === 'StateError') {
1313
return new StateError(e.message);

lib/state-processor/capture-processor/capture-processor.js

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
const _ = require('lodash');
4+
const fs = require('fs-extra');
45
const utils = require('./utils');
56
const {temp, Image} = require('gemini-core');
67

@@ -30,32 +31,37 @@ module.exports = class CaptureProcessor {
3031
}
3132

3233
exec(capture, opts) {
33-
const referencePath = opts.referencePath;
34+
const {refImg} = opts;
3435

35-
return utils.existsRef(referencePath)
36+
return utils.existsRef(refImg.path)
3637
.then((isRefExists) => {
38+
if (isRefExists) {
39+
const refImgBase64 = fs.readFileSync(refImg.path);
40+
refImg.size = Image.fromBase64(refImgBase64).getSize();
41+
}
42+
3743
return isRefExists
38-
? this._onRefHandler(referencePath) || this._compareImages(capture, opts)
39-
: this._onNoRefHandler(referencePath, capture);
44+
? this._onRefHandler(refImg) || this._compareImages(capture, opts)
45+
: this._onNoRefHandler(refImg, capture);
4046
});
4147
}
4248

4349
_compareImages(capture, opts) {
44-
const referencePath = opts.referencePath;
45-
const currentPath = temp.path({suffix: '.png'});
50+
const {refImg} = opts;
51+
const currImg = {path: temp.path({suffix: '.png'}), size: capture.image.getSize()};
4652
const compareOpts = {
4753
canHaveCaret: capture.canHaveCaret,
4854
pixelRatio: opts.pixelRatio,
4955
tolerance: opts.tolerance,
5056
antialiasingTolerance: opts.antialiasingTolerance
5157
};
5258

53-
return capture.image.save(currentPath)
54-
.then(() => Image.compare(currentPath, referencePath, compareOpts))
59+
return capture.image.save(currImg.path)
60+
.then(() => Image.compare(currImg.path, refImg.path, compareOpts))
5561
.then((isEqual) => {
5662
return isEqual
57-
? this._onEqualHandler(referencePath, currentPath)
58-
: this._onDiffHandler(referencePath, currentPath);
63+
? this._onEqualHandler(refImg, currImg)
64+
: this._onDiffHandler(refImg, currImg);
5965
});
6066
}
6167
};

lib/state-processor/capture-processor/index.js

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,39 @@ const utils = require('./utils');
66
const NoRefImageError = require('../../errors/no-ref-image-error');
77
const {temp} = require('gemini-core');
88

9-
const throwNoRefError = (referencePath, capture) => {
10-
const currentPath = temp.path({suffix: '.png'});
11-
return capture.image.save(currentPath)
12-
.then(() => Promise.reject(new NoRefImageError(referencePath, currentPath)));
9+
const throwNoRefError = (refImg, capture) => {
10+
const currImg = {path: temp.path({suffix: '.png'}), size: capture.image.getSize()};
11+
12+
return capture.image.save(currImg.path)
13+
.then(() => Promise.reject(new NoRefImageError(refImg, currImg)));
1314
};
14-
const notUpdated = (referencePath) => ({imagePath: referencePath, updated: false});
15+
const notUpdated = (refImg) => ({refImg, updated: false});
16+
17+
const saveRef = (refImg, capture) => {
18+
refImg.size = capture.image.getSize();
1519

16-
const saveRef = (referencePath, capture) => {
17-
return utils.saveRef(referencePath, capture)
18-
.then((updated) => ({imagePath: referencePath, updated}));
20+
return utils.saveRef(refImg.path, capture)
21+
.then((updated) => ({refImg, updated}));
1922
};
2023

21-
const updateRef = (referencePath, currentPath) => {
22-
return utils.copyImg(currentPath, referencePath)
23-
.then((updated) => ({imagePath: referencePath, updated}));
24+
const updateRef = (refImg, currImg) => {
25+
return utils.copyImg(currImg.path, refImg.path)
26+
.then((updated) => {
27+
if (updated) {
28+
refImg.size = currImg.size;
29+
}
30+
31+
return {refImg, updated};
32+
});
2433
};
2534

2635
exports.create = (type) => {
2736
if (type === 'tester') {
2837
return CaptureProcessor.create()
2938
.onReference()
3039
.onNoReference(throwNoRefError)
31-
.onEqual((referencePath, currentPath) => ({referencePath, currentPath, equal: true}))
32-
.onDiff((referencePath, currentPath) => ({referencePath, currentPath, equal: false}));
40+
.onEqual((refImg, currImg) => ({refImg, currImg, equal: true}))
41+
.onDiff((refImg, currImg) => ({refImg, currImg, equal: false}));
3342
}
3443

3544
if (type === 'new-updater') {

lib/state-processor/state-processor.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,20 @@ module.exports = class StateProcessor {
1919
}
2020

2121
exec(state, browserSession, page) {
22+
const browserConfig = browserSession.browser.config;
2223
const coverage = page.coverage;
2324
const tolerance = _.isNumber(state.tolerance)
2425
? state.tolerance
25-
: browserSession.browser.config.tolerance;
26+
: browserConfig.tolerance;
2627

2728
const jobArgs = {
2829
captureProcessorType: this._captureProcessorType,
2930
browserSession: browserSession.serialize(),
3031
page: _.omit(page, 'coverage'),
3132
execOpts: {
33+
refImg: {path: browserConfig.getScreenshotPath(state.suite, state.name), size: null},
3234
pixelRatio: page.pixelRatio,
33-
referencePath: browserSession.browser.config.getScreenshotPath(state.suite, state.name),
34-
antialiasingTolerance: browserSession.browser.config.antialiasingTolerance,
35+
antialiasingTolerance: browserConfig.antialiasingTolerance,
3536
tolerance
3637
},
3738
temp: temp.serialize()

lib/state-processor/test-state-processor.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ module.exports = class TestStateProcessor extends StateProcessor {
2727
_attachDiffBuilder(result) {
2828
return _.extend(result, {
2929
saveDiffTo: (diffPath) => Image.buildDiff({
30-
reference: result.referencePath,
31-
current: result.currentPath,
30+
reference: result.refImg.path,
31+
current: result.currImg.path,
3232
diff: diffPath,
3333
diffColor: this._diffColor,
3434
tolerance: result.tolerance

test/unit/capture-session.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,16 @@ describe('capture session', () => {
145145
let browser;
146146
let session;
147147
let error;
148+
let image;
148149

149150
beforeEach(() => {
151+
image = {
152+
save: sinon.stub().resolves(),
153+
getSize: sinon.stub()
154+
};
150155
browser = {
151156
config: {},
152-
captureViewportImage: sinon.stub().returns(Promise.resolve({
153-
save: sinon.stub()
154-
}))
157+
captureViewportImage: sinon.stub().returns(Promise.resolve(image))
155158
};
156159
session = CaptureSession.create(browser);
157160
error = {};
@@ -162,14 +165,17 @@ describe('capture session', () => {
162165
.then(() => assert.called(browser.captureViewportImage));
163166
});
164167

165-
it('should add an image path to error', () => {
168+
it('should add image to an error', () => {
166169
temp.path.returns('/path/to/img');
170+
image.getSize.returns({width: 100, height: 200});
167171

168172
return session.extendWithPageScreenshot(error)
169-
.then(() => assert.deepEqual(error.imagePath, '/path/to/img'));
173+
.then(() => {
174+
assert.deepEqual(error.img, {path: '/path/to/img', size: {width: 100, height: 200}});
175+
});
170176
});
171177

172-
it('should not add an image to error if can not captureViewportImage', () => {
178+
it('should not add image to an error if can not captureViewportImage', () => {
173179
browser.captureViewportImage = sinon.stub().callsFake(() => Promise.reject({}));
174180

175181
error = new StateError('some error');

test/unit/errors/no-ref-image-error.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
const NoRefImageError = require('lib/errors/no-ref-image-error');
44

5-
describe('NoRefImageError', function() {
6-
it('should include the error message in the stacktrace', function() {
7-
const error = new NoRefImageError('anyPath');
5+
describe('NoRefImageError', () => {
6+
it('should include the error message in the stacktrace', () => {
7+
const error = new NoRefImageError({path: 'anyPath'});
88

99
assert.match(error.stack, /^NoRefImageError: Can not find reference image at anyPath.\n/);
1010
});

0 commit comments

Comments
 (0)