Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to write logs only to file avoiding print to terminal #47 #51

Merged
merged 9 commits into from
Oct 7, 2020
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ integer; default: 5000; Max length of cy.route request data.
#### `options.compactLogs`
integer?; default: null; If it is set to a number greater or equal to 0, this amount of logs
will be printed only around failing commands. Use this to have shorter output especially
for when there are a lot of commands in tests. When used with `options.printLogs=always`
for when there are a lot of commands in tests. When used with `options.printLogsToConsole=always`
for tests that don't have any `severity=error` logs nothing will be printed.

#### `options.outputRoot`
Expand All @@ -71,14 +71,18 @@ string; default: null; Required if `options.outputTarget` provided. [More detail
#### `options.outputTarget`
object; default: null; Output logs to files. [More details](#logging-to-files).

#### `options.printLogsToConsole`
string; Default: 'onFail'. When to print logs to console, possible values: 'always', 'onFail', 'never' - When set to always
logs will be printed to console for successful tests as well as failing ones.

#### `options.printLogsToFile`
string; Default: 'onFail'. When to print logs to file(s), possible values: 'always', 'onFail', 'never' - When set to always
logs will be printed to file(s) for successful tests as well as failing ones.

### Options for the support install

> require('cypress-terminal-report/src/installLogsCollector')(options);

#### `options.printLogs`
string; default: 'onFail'; possible values: 'onFail', 'always' - When set to always
logs will be printed for successful test as well as failing ones.

#### `options.collectTypes`
array; default: ['cons:log','cons:info', 'cons:warn', 'cons:error', 'cy:log', 'cy:xhr', 'cy:request', 'cy:route', 'cy:command']
What types of logs to collect and print. By default all types are enabled. The 'cy:command' is the general type that
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 17 additions & 12 deletions src/installLogsCollector.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ const tv4ErrorTransformer = require('./tv4ErrorTransformer');
*
* @param {object} config
* Options for collection logs:
* - printLogs?: string; Default: 'onFail'. When to print logs, possible values: 'always', 'onFail'.
* - collectTypes?: array; Collect only these types of logs. Defaults to all types.
* - filterLog?: ([type, message, severity]) => boolean; Callback to filter logs manually.
* - xhr?:
Expand Down Expand Up @@ -79,7 +78,7 @@ function installLogsCollector(config = {}) {
}

Cypress.on('log:changed', options => {
if ( options.state === 'failed' && logsChainId[options.id] && logs[logsChainId[options.id]]) {
if (options.state === 'failed' && logsChainId[options.id] && logs[logsChainId[options.id]]) {
logs[logsChainId[options.id]][2] = CONSTANTS.SEVERITY.ERROR;
}
});
Expand All @@ -89,16 +88,15 @@ function installLogsCollector(config = {}) {
logs = [];
});

afterEach(function() {
if (this.currentTest.state !== 'passed' || (config && config.printLogs === 'always')) {
// Need to wait otherwise some last commands get omitted from logs.
cy.wait(3, {log: false});
cy.task(CONSTANTS.TASK_NAME, {
spec: this.test.file,
test: this.currentTest.title,
messages: logs
}, {log: false});
}
afterEach(function () {
// Need to wait otherwise some last commands get omitted from logs.
cy.wait(3, {log: false});
cy.task(CONSTANTS.TASK_NAME, {
spec: this.test.file,
test: this.currentTest.title,
messages: logs,
state: this.currentTest.state
}, {log: false});
});

after(function () {
Expand All @@ -108,6 +106,13 @@ function installLogsCollector(config = {}) {
}

function validateConfig(config) {
before(function () {
if (typeof config.printLogs === 'string') {
cy.log("cypress-terminal-report: WARN! printLogs " +
"configuration has been removed. Please check changelog in readme.");
}
});

const result = tv4.validateMultiple(config, schema);

if (!result.valid) {
Expand Down
46 changes: 29 additions & 17 deletions src/installLogsPrinter.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,17 @@ let outputProcessors = [];
* Cypress event listen handler.
* @param {object} options
* Options for displaying output:
* - printLogsToConsole?: string; Default: 'onFail'. When to print logs to console, possible values: 'always', 'onFail', 'never'.
* - printLogsToFile?: string; Default: 'onFail'. When to print logs to file(s), possible values: 'always', 'onFail', 'never'.
* - defaultTrimLength?: Trim length for console and cy.log.
* - commandTrimLength?: Trim length for cy commands.
* - outputRoot?: The root path to output log files to.
* - outputTarget?: Log output types. {[filePath: string]: string | function}
* - compactLogs?: Number of lines to compact around failing commands.
*/
function installLogsPrinter(on, options = {}) {
options.printLogsToFile = options.printLogsToFile || "onFail";
options.printLogsToConsole = options.printLogsToConsole || "onFail";
const result = tv4.validateMultiple(options, schema);

if (!result.valid) {
Expand All @@ -68,17 +72,25 @@ function installLogsPrinter(on, options = {}) {
}

if (options.outputTarget) {
allMessages[0] = data.state;
archfz marked this conversation as resolved.
Show resolved Hide resolved
allMessages[data.spec] = allMessages[data.spec] || {};
allMessages[data.spec][data.test] = messages;
archfz marked this conversation as resolved.
Show resolved Hide resolved
}

logToTerminal(messages, options);
if ((options.printLogsToConsole === "onFail" && data.state !== "passed")
|| options.printLogsToConsole === "always"){
logToTerminal(messages, options);
}

return null;
},
[CONSTANTS.TASK_NAME_OUTPUT]: () => {
outputProcessors.forEach((processor) => {
processor.write(allMessages);
logOutputTarget(processor);
if ((options.printLogsToFile === "onFail" && allMessages[0] !== "passed")
archfz marked this conversation as resolved.
Show resolved Hide resolved
|| options.printLogsToFile === "always"){
processor.write(allMessages);
logOutputTarget(processor);
}
});
allMessages = {};
return null;
Expand All @@ -93,7 +105,7 @@ function installLogsPrinter(on, options = {}) {
function logOutputTarget(processor) {
let message;
let standardOutputType = Object.keys(OUTPUT_PROCESSOR_TYPE).find(
(type) => processor instanceof OUTPUT_PROCESSOR_TYPE[type]
(type) => processor instanceof OUTPUT_PROCESSOR_TYPE[type]
);
if (standardOutputType) {
message = `Wrote ${standardOutputType} logs to ${processor.file}. (${processor.writeSpendTime}ms)`;
Expand Down Expand Up @@ -127,7 +139,7 @@ function installOutputProcessors(on, root, outputTargets) {

function compactLogs(logs, keepAroundCount) {
const failingIndexes = logs.filter((log) => log[2] === CONSTANTS.SEVERITY.ERROR)
.map((log) => logs.indexOf(log));
.map((log) => logs.indexOf(log));

const includeIndexes = new Array(logs.length);

Expand All @@ -141,11 +153,11 @@ function compactLogs(logs, keepAroundCount) {

const compactedLogs = [];
const addOmittedLog = (count) =>
compactedLogs.push([
CONSTANTS.LOG_TYPES.PLUGIN_LOG_TYPE,
`[ ... ${count} omitted logs ... ]`,
CONSTANTS.SEVERITY.SUCCESS
]);
compactedLogs.push([
archfz marked this conversation as resolved.
Show resolved Hide resolved
CONSTANTS.LOG_TYPES.PLUGIN_LOG_TYPE,
`[ ... ${count} omitted logs ... ]`,
CONSTANTS.SEVERITY.SUCCESS
]);

let excludeCount = 0;
for (let i = 0; i < includeIndexes.length; i++) {
Expand All @@ -170,14 +182,14 @@ function compactLogs(logs, keepAroundCount) {

function logToTerminal(messages, options) {
const padType = (type) =>
new Array(Math.max(CONSTANTS.PADDING.LOG.length - type.length - 3, 0)).join(' ') + type + ' ';
new Array(Math.max(CONSTANTS.PADDING.LOG.length - type.length - 3, 0)).join(' ') + type + ' ';

messages.forEach(([type, message, severity]) => {
let color = 'white',
typeString = KNOWN_TYPES.includes(type) ? padType(type) : padType('[unknown]'),
processedMessage = message,
trim = options.defaultTrimLength || 800,
icon = '-';
typeString = KNOWN_TYPES.includes(type) ? padType(type) : padType('[unknown]'),
processedMessage = message,
trim = options.defaultTrimLength || 800,
icon = '-';

if (type === LOG_TYPES.BROWSER_CONSOLE_WARN) {
color = 'yellow';
Expand Down Expand Up @@ -224,8 +236,8 @@ function logToTerminal(messages, options) {
}

const coloredTypeString = ['red', 'yellow'].includes(color) ?
chalk[color].bold(typeString + icon + ' ') :
chalk[color](typeString + icon + ' ');
chalk[color].bold(typeString + icon + ' ') :
chalk[color](typeString + icon + ' ');

console.log(coloredTypeString, processedMessage.replace(/\n/g, '\n' + CONSTANTS.PADDING.LOG));
});
Expand Down
8 changes: 8 additions & 0 deletions src/installLogsPrinter.schema.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
{
"type": "object",
"properties": {
"printLogsToConsole": {
"type": "string",
"enum": ["onFail", "always", "never"]
},
"printLogsToFile": {
"type": "string",
"enum": ["onFail", "always", "never"]
},
"defaultTrimLength": {
"type": "string"
},
Expand Down
4 changes: 3 additions & 1 deletion src/outputProcessor/CustomOutputProcessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ module.exports = class CustomOutputProcessor extends BaseOutputProcessor {
}

write(allMessages) {
this.processorCallback.call(this, allMessages);
let allMessagesWithoutState = Object.assign({}, allMessages);
delete allMessagesWithoutState[0];
this.processorCallback.call(this, allMessagesWithoutState);
}

};
1 change: 1 addition & 0 deletions src/outputProcessor/JsonOutputProcessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = class JsonOutputProcessor extends BaseOutputProcessor {

write(allMessages) {
Object.entries(allMessages).forEach(([spec, tests]) => {
if (spec === "0") return;
let data = {[spec]: {}};
Object.entries(tests).forEach(([test, messages]) => {
data[spec][test] = messages.map(([type, message, severity]) => ({
Expand Down
5 changes: 3 additions & 2 deletions src/outputProcessor/TextOutputProcessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@ module.exports = class TextOutputProcessor extends BaseOutputProcessor {
write(allMessages) {

Object.entries(allMessages).forEach(([spec, tests]) => {
if (spec === "0") return;
let text = `${spec}:${EOL}`;
Object.entries(tests).forEach(([test, messages]) => {
text += `${PADDING}${test}${EOL}`;
messages.forEach(([type, message, severity]) => {
text += this.padTypeText(`${type} (${this.severityToFont(severity)}): `) +
message.replace(/\n/g, `${EOL}${PADDING_LOGS}`) + EOL;
text += (this.padTypeText(`${type} (${this.severityToFont(severity)}): `) +
message.replace(/\n/g, `${EOL}${PADDING_LOGS}`) + EOL).replace(/\s+\n/, '\n');
});
text += EOL;
});
Expand Down
7 changes: 0 additions & 7 deletions test/cypress/integration/alwaysPrintLogs.spec.js

This file was deleted.

7 changes: 7 additions & 0 deletions test/cypress/integration/printLogsFail.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
describe('Print Logs Fail.', () => {

it('Print Logs Fail', () => {
archfz marked this conversation as resolved.
Show resolved Hide resolved
cy.visit('/');
cy.contains('sserpyc');
});
});
7 changes: 7 additions & 0 deletions test/cypress/integration/printLogsSuccess.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
describe('Print Logs Success.', () => {

it('Print Logs Success', () => {
archfz marked this conversation as resolved.
Show resolved Hide resolved
cy.visit('/');
cy.contains('cypress');
});
});
16 changes: 15 additions & 1 deletion test/cypress/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = (on, config) => {
'out.txt': 'txt',
'out.json': 'json',
'out.cst': function (messages) {
this.initialContent = 'Failing specs:\n';
this.initialContent = 'Specs:\n';
this.chunkSeparator = '\n';
Object.keys(messages).forEach((key) => {
this.writeSpecChunk(key, key);
Expand All @@ -26,9 +26,23 @@ module.exports = (on, config) => {
any: 100
},
compactLogs: false,
printLogsToConsole: true,
printLogsToFile: true,
shouldNotBeHere: "",
};
}
if (config.env.printLogsToConsoleAlways == '1') {
options.printLogsToConsole = 'always';
}
if (config.env.printLogsToConsoleNever == '1') {
options.printLogsToConsole = 'never';
}
if (config.env.printLogsToFileAlways == '1') {
options.printLogsToFile = 'always';
}
if (config.env.printLogsToFileNever == '1') {
options.printLogsToFile = 'never';
}

require('../../../src/installLogsPrinter')(on, options);
};
4 changes: 0 additions & 4 deletions test/cypress/support/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ if (env.setLogTypes == '1') {
if (env.setFilterLogs == '1') {
config.filterLog = ([,log]) => log.indexOf('[filter-out-string]') !== -1;
}
if (env.printLogsAlways == '1') {
config.printLogs = 'always';
}
if (env.printHeaderData == '1') {
config.xhr = config.xhr || {};
config.xhr.printHeaderData = true;
Expand All @@ -27,7 +24,6 @@ if (env.supportBadConfig == '1') {
config = {
collectTypes: 0,
filterLog: "string",
printLogs: false,
xhr: {
printRequestData: "",
printHeaderData: "",
Expand Down
4 changes: 4 additions & 0 deletions test/output/out.spec.always.cst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Specs:
cypress/integration/happyFlow.spec.js
cypress/integration/printLogsSuccess.spec.js
cypress/integration/requests.spec.js
Loading