Skip to content

Commit

Permalink
Added filename_format config option for setting the filename format o…
Browse files Browse the repository at this point in the history
…f the screenshots -- #2023
  • Loading branch information
beatfactor committed Apr 6, 2021
1 parent f0388b3 commit c5b3abf
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 48 deletions.
6 changes: 4 additions & 2 deletions lib/api/client-commands/end.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ class End extends EventEmitter {
if (this.testFailuresExist() && this.shouldTakeScreenshot()) {
Logger.info(`Failures in "${this.api.currentTest.name}". Taking screenshot...`);

const prefix = `${this.api.currentTest.module}/${this.api.currentTest.name}`;
const fileNamePath = Screenshots.getFileName(prefix, false, client.options.screenshots.path);
const fileNamePath = Screenshots.getFileName({
testSuite: this.api.currentTest.module,
testCase: this.api.currentTest.name
}, client.options.screenshots);

this.api.saveScreenshot(fileNamePath, (result, err) => {
if (!err && this.client.transport.isResultSuccess(result)) {
Expand Down
20 changes: 4 additions & 16 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@ class NightwatchClient extends EventEmitter {
return this.settings.start_session;
}

get screenshotsEnabled() {
return Utils.isObject(this.settings.screenshots) ? this.settings.screenshots && this.options.screenshots.enabled === true : false;
screenshotsEnabled() {
return Utils.isObject(this.settings.screenshots) ? (this.settings.screenshots && this.options.screenshots.enabled === true) : false;
}

get reporter() {
Expand Down Expand Up @@ -297,23 +297,11 @@ class NightwatchClient extends EventEmitter {
}

setScreenshotOptions() {
let screenshots = this.settings.screenshots;

if (this.screenshotsEnabled) {
if (typeof screenshots.path == 'undefined') {
throw new Error('Please specify the screenshots.path in nightwatch.json.');
}

this.settings.screenshots.on_error = this.settings.screenshots.on_error || typeof this.options.screenshots.on_error == 'undefined';
this.settings.screenshotsPath = screenshots.path;
const {screenshots} = this.settings;

if (this.screenshotsEnabled()) {
this.setApiProperty('screenshotsPath', screenshots.path)
.setApiOption('screenshotsPath', screenshots.path);
} else {
this.settings.screenshots = {
enabled : false,
path : ''
};
}

return this;
Expand Down
24 changes: 23 additions & 1 deletion lib/settings/defaults.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
const filename_format = function ({testSuite = '', testCase = '', isError = false, dateObject = new Date()} = {}) {
const fileName = [];
const dateParts = dateObject.toString().replace(/:/g,'').split(' ');
dateParts.shift();

const dateStamp = dateParts.slice(0,5).join('-');
if (testSuite) {
fileName.push(testSuite);
}
if (testCase) {
fileName.push(testCase);
}

return `${fileName.join('/')}${isError ? '_ERROR' : '_FAILED'}_${dateStamp}.png`;
};

module.exports = {
// Location(s) where custom commands will be loaded from.
custom_commands_path: null,
Expand Down Expand Up @@ -184,7 +200,13 @@ module.exports = {
report_command_errors: false,

// Take error and failure screenshots during test execution
screenshots: false,
screenshots: {
enabled: false,
filename_format,
path: '',
on_error: true,
on_failure: true
},

// Used to enable showing the Base64 image data in the (verbose) log when taking screenshots.
log_screenshot_data: false,
Expand Down
24 changes: 22 additions & 2 deletions lib/settings/settings.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
const dotenv = require('dotenv');
const path = require('path');
const defaultsDeep = require('lodash.defaultsdeep');
const lodashClone = require('lodash.clone');
const lodashMerge = require('lodash.merge');
const CI_Info = require('ci-info');
const Defaults = require('./defaults.js');
const Utils = require('../utils');
const {Logger} = Utils;
const {Logger, isObject} = Utils;

class Settings {

Expand Down Expand Up @@ -40,7 +41,7 @@ class Settings {

let copyVal = lodashClone(this.baseSettings[key], true);

if (Utils.isObject(this.settings[key])) {
if (isObject(this.settings[key])) {
Object.assign(this.settings[key], copyVal);
} else {
this.settings[key] = copyVal;
Expand All @@ -56,6 +57,8 @@ class Settings {
lodashMerge(this.settings, settings);

this.setCliOptions();
this.setScreenshotsOptions();
this.setScreenshotsPath();
this.setUnitTestsMode();
this.setParallelMode();
this.setTestRunner();
Expand Down Expand Up @@ -202,6 +205,23 @@ class Settings {
}
}

setScreenshotsOptions() {
if (isObject(this.settings.screenshots)) {
this.settings.screenshots.path = path.resolve(this.settings.screenshots.path);
} else {
const enabled = this.settings.screenshots === true;
this.settings.screenshots = Object.assign({}, Defaults.screenshots, {enabled});
}

return this;
}

setScreenshotsPath() {
this.settings.screenshotsPath = this.settings.screenshots.path;

return this;
}

setCliOptions() {
if (this.argv.verbose) {
this.settings.silent = false;
Expand Down
29 changes: 15 additions & 14 deletions lib/utils/screenshots.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
const path = require('path');
const fs = require('fs');
const mkpath = require('mkpath');
const Defaults = require('../settings/defaults.js');

class Screenshots {
/**
* @param {string} prefix
* @param {boolean} isError
* @param {string} screenshotsPath
* @param {object} prefix
* @param {object} screenshots
* @return {string}
*/
static getFileName(prefix, isError, screenshotsPath) {
let filenamePrefix = prefix
.replace(/\s/g, '-')
.replace(/"|'/g, '');
static getFileName({testSuite, testCase, isError = false}, screenshots) {
const dateObject = new Date();
let filename;
let filename_format;

filenamePrefix += isError ? '_ERROR' : '_FAILED';
if (typeof screenshots.filename_format == 'function') {
filename_format = screenshots.filename_format.bind(screenshots);
} else {
filename_format = Defaults.screenshots.filename_format;
}

const dateParts = new Date().toString().replace(/:/g,'').split(' ');
dateParts.shift();
dateParts.pop();
filename = filename_format({testSuite, testCase, isError, dateObject});
filename = filename.replace(/\s/g, '-').replace(/["']/g, '');

const dateStamp = dateParts.join('-');

return path.resolve(path.join(screenshotsPath, `${filenamePrefix}_${dateStamp}.png`));
return path.join(screenshots.path, filename);
}

/**
Expand Down
4 changes: 3 additions & 1 deletion test/src/api/commands/testClick.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const Nightwatch = require('../../../lib/nightwatch.js');
const MockServer = require('../../../lib/mockserver.js');
const CommandGlobals = require('../../../lib/globals/commands.js');

describe('click', function() {
describe('.click()', function() {
before(function(done) {
CommandGlobals.beforeEach.call(this, done);
});
Expand Down Expand Up @@ -87,6 +87,8 @@ describe('click', function() {
version2: false,
start_process: false
},
output: true,
silent: false,
webdriver:{
start_process: true
},
Expand Down
80 changes: 77 additions & 3 deletions test/src/api/commands/testEnd.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const MockServer = require('../../../lib/mockserver.js');
const Nightwatch = require('../../../lib/nightwatch.js');
const CommandGlobals = require('../../../lib/globals/commands.js');

describe('end', function() {
describe('.end()', function() {
before(function(done) {
CommandGlobals.beforeEach.call(this, done);
});
Expand Down Expand Up @@ -45,9 +45,28 @@ describe('end', function() {
screenshots: {
enabled: true,
on_failure: true,
path: './screens'
path: 'screens'
}
}).then(client => {
assert.strictEqual(typeof client.settings.screenshots.filename_format, 'function');

const fileNameFailed = client.settings.screenshots.filename_format({
testSuite: 'xxTestSuite',
testCase: 'xxTestCase',
isError: false
});

const fileNameError = client.settings.screenshots.filename_format({
testSuite: 'xxTestSuite',
testCase: 'xxTestCase',
isError: true
});

assert.ok(fileNameFailed.startsWith('xxTestSuite/xxTestCase_FAILED_'));
assert.ok(fileNameFailed.endsWith('.png'));
assert.ok(fileNameError.startsWith('xxTestSuite/xxTestCase_ERROR_'));
assert.ok(fileNameError.endsWith('.png'));

client.api.currentTest = {
module: 'test_module',
name: 'test_name',
Expand All @@ -62,6 +81,57 @@ describe('end', function() {
});

client.start(done);
}).catch(err => done(err));
});

it('client.end() - with screenshot and custom filename format', function (done) {
MockServer.addMock({
url: '/wd/hub/session/1352110219202/screenshot',
method: 'GET',
response: JSON.stringify({
status: 0,
state: 'success',
value: '==content'
})
}, true);

Nightwatch.initClient({
screenshots: {
enabled: true,
on_failure: true,
path: './screens',
filename_format({testSuite, testCase, isError, dateObject}) {
return `${testSuite}/${testCase}--failed.png`;
}
}
}).then(client => {
client.api.currentTest = {
module: 'test_module',
name: 'test_name',
results: {
failed: 1,
passed: 0
}
};

let screenFileName;
const saveScreenshot = client.api.saveScreenshot;
client.api.saveScreenshot = function (file, callback) {
screenFileName = file;
};
client.api.end(function callback(result) {
assert.strictEqual(result.status, 0);
});

client.start(function(err) {
try {
assert.ok(screenFileName.endsWith('test_module/test_name--failed.png'));
client.api.saveScreenshot = saveScreenshot;
done(err);
} catch (e) {
done(e);
}
});
});
});

Expand Down Expand Up @@ -91,6 +161,7 @@ describe('end', function() {
}
};

const saveScreenshot = client.api.saveScreenshot;
client.api.saveScreenshot = function (file, callback) {
throw new Error('saveScreenshot should not be called');
};
Expand All @@ -99,7 +170,10 @@ describe('end', function() {
assert.strictEqual(result.status, 0);
});

client.start(done);
client.start(function(err) {
client.api.saveScreenshot = saveScreenshot;
done(err);
});
});
});
});
18 changes: 10 additions & 8 deletions test/src/index/testSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ describe('test Settings', function () {
eq(client.options.webdriver.port, 4444);
eq(client.options.webdriver.ssl, false);

assert.deepEqual(client.api.options.screenshots, {enabled: false, path: ''});
eq(client.api.options.screenshots.enabled, false);
eq(client.api.options.screenshots.path, '');

eq(client.options.start_session, true);
eq(client.options.end_session_on_fail, true);
Expand Down Expand Up @@ -131,7 +132,6 @@ describe('test Settings', function () {

eq(client.api.options.log_screenshot_data, true);
eq(client.options.screenshots.on_error, true);
eq(client.api.options.screenshotsPath, '');
});

it('testSetOptionsScreenshotsOnError', function () {
Expand All @@ -148,13 +148,15 @@ describe('test Settings', function () {
});

it('testSetOptionsScreenshotsThrows', function () {
assert.throws(function () {
Nightwatch.createClient({
screenshots: {
enabled: true
}
});
let client = Nightwatch.createClient({
screenshots: true
});

eq(client.settings.screenshots.enabled, true);
eq(client.settings.screenshots.on_error, true);
eq(client.settings.screenshots.on_failure, true);
eq(client.settings.screenshots.path, '');
assert.ok(client.settings.screenshots.filename_format().startsWith('_FAILED_'));
});

it('testEndSessionOnFail', function () {
Expand Down
2 changes: 1 addition & 1 deletion test/src/runner/cli/testCliRunnerGenerate.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ describe('Test CLI Runner Generate', function() {
}
},

readFileSync: function (fileName) {
readFileSync: function(fileName) {
return {
toString: function () {
return tplData;
Expand Down

0 comments on commit c5b3abf

Please sign in to comment.