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

Commit

Permalink
Merge pull request #287 from gemini-testing/sipayrt.addInfoToError
Browse files Browse the repository at this point in the history
Show error message + whole page screenshot on test fail
  • Loading branch information
sipayRT committed Nov 6, 2015
2 parents 3514265 + 059f27f commit 206882e
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 31 deletions.
67 changes: 38 additions & 29 deletions lib/capture-session.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,44 +43,53 @@ module.exports = inherit({

this.log('capture "%s" in %o', state.fullName, this.browser);
return _this.runHook(state.callback, state.suite)
.then(function(actions) {
.then(function() {
return _this.browser.prepareScreenshot(state.captureSelectors, opts)
// Skip the error to capture full screen image
.fail(_.noop)
.then(function(prepareData) {
.fail(function(e) {
return _this.browser.captureFullscreenImage()
.then(function(screenImage) {
_this.log('capture data:', prepareData);
if (!prepareData) {
return {image: screenImage};
}

var toImageCoords = _this._getToImageCoordsFunction(screenImage, prepareData),
cropArea = toImageCoords(prepareData.captureArea);

try {
_this._validateImage(screenImage, cropArea);
} catch (err) {
logger.error(err.message);
return {image: screenImage};
}

prepareData.ignoreAreas.forEach(function(area) {
screenImage.clear(toImageCoords(area));
_.extend(e, {
suite: state.suite,
state: state,
browserId: _this.browser.id,
image: screenImage
});
return screenImage.crop(cropArea)
.then(function(crop) {
return {
image: crop,
canHaveCaret: prepareData.canHaveCaret,
coverage: prepareData.coverage
};
});
return q.reject(e);
});
})
.then(function(prepareData) {
return _this.browser.captureFullscreenImage()
.then(_.bind(_this._cropImage, _this, _, prepareData));
});
});
},

_cropImage: function(screenImage, prepareData) {
this.log('capture data:', prepareData);

var toImageCoords = this._getToImageCoordsFunction(screenImage, prepareData),
cropArea = toImageCoords(prepareData.captureArea);

try {
this._validateImage(screenImage, cropArea);
} catch (err) {
logger.error(err.message);
return {image: screenImage};
}

prepareData.ignoreAreas.forEach(function(area) {
screenImage.clear(toImageCoords(area));
});
return screenImage.crop(cropArea)
.then(function(crop) {
return {
image: crop,
canHaveCaret: prepareData.canHaveCaret,
coverage: prepareData.coverage
};
});
},

_validateImage: function(image, cropArea) {
var imageSize = image.getSize(),
bottom = cropArea.top + cropArea.height;
Expand Down
14 changes: 14 additions & 0 deletions lib/reporters/html/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,20 @@ function prepareImages(runner) {
});
});

runner.on(RunnerEvents.ERROR, function(testResult) {
queue = queue.then(function() {
if (!testResult.image) {
return;
}

var actualImagePath = lib.currentAbsolutePath(testResult);
return makeDirFor(actualImagePath)
.then(function() {
testResult.image.save(actualImagePath);
});
});
});

runner.on(RunnerEvents.END_TEST, function(testResult) {
queue = queue.then(function() {
return q.all([
Expand Down
9 changes: 8 additions & 1 deletion lib/reporters/html/suite.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@
<div class="section__title">{{name}}</div>
<div class="section__body">
{{#if error}}
<pre class="reason">{{{reason}}}</pre>
<div class="image-box image-box_error">
<div class="image-box__image">
<pre class="reason">{{{reason}}}</pre>
{{#if image}}
{{image "actual"}}
{{/if}}
</div>
</div>
{{/if}}

{{#if warning}}
Expand Down
2 changes: 2 additions & 0 deletions lib/reporters/html/view-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ module.exports = inherit({
addError: function(result) {
this._addTestResult(result, {
name: result.browserId,
actualPath: lib.currentPath(result),
error: true,
image: !!result.image,
reason: (result.stack || result.message || result || '')
});

Expand Down
27 changes: 26 additions & 1 deletion test/unit/capture-session.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,12 @@ describe('capture session', function() {

it('should not make screenshot before prepareScreenshot has been executed', function() {
var _this = this,
spy = sinon.spy();
screenshotData = {
captureArea: {},
viewportOffset: {},
ignoreAreas: []
},
spy = sinon.stub().returns(q.resolve(screenshotData));

// add delay for guaranted call spy in next tick
this.browser.prepareScreenshot.returns(q.delay(1).then(spy));
Expand All @@ -175,6 +180,26 @@ describe('capture session', function() {
});
});

it('should call captureFullscreenImage method even if prepareScreenshot has been failed', function() {
var _this = this;

this.browser.prepareScreenshot.returns(q.reject({}));

return this.session.capture(this.state).fail(function() {
assert.calledOnce(_this.browser.captureFullscreenImage);
});
});

it('should reject error with image object on prepareScreenshot has been failed', function() {
var error = new Error('Some error');
this.browser.prepareScreenshot.returns(q.reject(error));

return this.session.capture(this.state).fail(function(e) {
assert.propertyVal(e, 'message', error.message);
assert.property(e, 'image');
});
});

it('should prepare screenshot before taking it', function() {
var _this = this;
this.state.captureSelectors = ['.selector1', '.selector2'];
Expand Down

0 comments on commit 206882e

Please sign in to comment.