Skip to content

Commit

Permalink
Merge pull request #263 from bvandercar-vt/consoleprocessor-bold
Browse files Browse the repository at this point in the history
feat: console logging accommodate cy.log message markdown
  • Loading branch information
archfz authored Nov 19, 2024
2 parents 532702c + 07c1b68 commit 1429f17
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 6 deletions.
18 changes: 13 additions & 5 deletions src/outputProcessor/consoleProcessor.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import CONSTANTS from '../constants';
import type {Colors, Log, LogSymbols, LogType, MessageData} from '../types';
import utils from '../utils';
import type {PluginOptions} from '../installLogsPrinter.types';
import chalk from 'chalk';

Expand Down Expand Up @@ -110,9 +111,7 @@ function consoleProcessor(messages: Log[], options: PluginOptions, data: Message

messages.forEach(({type, message, severity, timeString}) => {
let processedMessage = message;

let {color, icon, trim} = TYPE_COMPUTE[type](options);
trim = trim || options.defaultTrimLength || 800;
let {color, icon, trim = options.defaultTrimLength || 800} = TYPE_COMPUTE[type](options);

if (severity === CONSTANTS.SEVERITY.ERROR) {
color = COLORS.RED;
Expand All @@ -122,8 +121,17 @@ function consoleProcessor(messages: Log[], options: PluginOptions, data: Message
icon = LOG_SYMBOLS.WARNING;
}

if (message.length > trim) {
processedMessage = message.substring(0, trim) + ' ...';
const maybeTrimLength = (msg: string) =>
msg.length > trim ? msg.substring(0, trim) + ' ...' : msg;

if (type == 'cy:log') {
processedMessage = utils.applyMessageMarkdown(processedMessage, {
bold: chalk.bold,
italic: chalk.italic,
processContents: maybeTrimLength,
});
} else {
processedMessage = maybeTrimLength(processedMessage);
}

if (timeString) {
Expand Down
56 changes: 56 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@ import jsonPrune from './jsonPrune';
import {compare} from 'compare-versions';
import type {Failure} from 'superstruct';

// Markdown regex: https://gist.github.com/elfefe/ef08e583e276e7617cd316ba2382fc40
function getMarkdownRegex(numWrapperChars: number) {
const asteriskWrapper = `(?:\\*){${numWrapperChars}}`;
const underscoreWrapper = `(?:_){${numWrapperChars}}`;
return new RegExp(
`^${asteriskWrapper}(.+?)${asteriskWrapper}$|^${underscoreWrapper}(.+?)${underscoreWrapper}$`
);
}

const MARKDOWN_REGEX = {
BOLD_AND_ITALIC: getMarkdownRegex(3),
BOLD: getMarkdownRegex(2),
ITALIC: getMarkdownRegex(1),
};

const utils = {
nonQueueTask: async (name: string, data: Record<string, any>) => {
if (Cypress.testingType === 'component' && compare(Cypress.version, '12.15.0', '>=')) {
Expand Down Expand Up @@ -97,6 +112,47 @@ const utils = {
'\n' +
errorList.map((error) => ` => ${error.path.join('.')}: ${error.message}`).join('\n') +
'\n',

/**
* The Cypress GUI runner allows markdown in `cy.log` messages. We can take this
* into account for our loggers as well.
*/
applyMessageMarkdown(
message: string,
{
bold,
italic,
processContents,
}: {
bold: (str: string) => string;
italic: (str: string) => string;
processContents?: (str: string) => string;
}
) {
let contentsHaveBeenProcessed = false;
const maybeProcessContents = (str: string) => {
if (contentsHaveBeenProcessed || !processContents) return str;
contentsHaveBeenProcessed = true;
return processContents(str);
};

// bold and italic, i.e. ***text*** or ___text___
message = message.replace(MARKDOWN_REGEX.BOLD_AND_ITALIC, (str, group1, group2) =>
bold(italic(maybeProcessContents(group1 || group2)))
);

// bold, i.e. **text** or __text__
message = message.replace(MARKDOWN_REGEX.BOLD, (str, group1, group2) =>
bold(maybeProcessContents(group1 || group2))
);

// italic, i.e. *text* or _text_
message = message.replace(MARKDOWN_REGEX.ITALIC, (str, group1, group2) =>
italic(maybeProcessContents(group1 || group2))
);

return maybeProcessContents(message);
},
};

export default utils;
21 changes: 21 additions & 0 deletions test/cypress/integration/logMarkdown.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
describe('cy.log markdown.', () => {
/**
* Covers: cy.log markdown to console
*/
it('cy.log markdown.', () => {
cy.log('_This is an_italic* log._');
cy.log('*This is an_italic* log.*');
cy.log('**This is a__bold* log.**');
cy.log('__This is a__bold* log.__');
cy.log('***This is a_bold and italic* log.***');
cy.log('___This is a_bold and italic* log.___');
cy.log('_This is a normal log');
cy.log('This is a normal log_');
cy.log('__This is a normal log');
cy.log('This is a normal log__');
cy.log('*This is a normal log');
cy.log('This is a normal log*');
cy.log('**This is a normal log');
cy.log('This is a normal log**');
});
});
34 changes: 33 additions & 1 deletion test/specs/commandsLogging.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {PADDING, ICONS, clean, runTest, commandBase, logLastRun} from '../utils';
import {PADDING, ICONS, clean, runTest, commandBase, logLastRun, runTestContinuous} from '../utils';
import {expect} from 'chai';
import chalk from 'chalk';

describe('Commands logging.', () => {
afterEach(function () {
Expand Down Expand Up @@ -238,4 +239,35 @@ describe('Commands logging.', () => {
);
});
}).timeout(60000);

it('Should apply chalk markdown to console', async () => {
// runTestContinuous to use spawn instead of exec, in order to get unicode stdout
await runTestContinuous(
commandBase(
['printLogsToConsoleAlways=1', 'enableContinuousLogging=1'],
['logMarkdown.spec.js']
),
(error, stdout, stderr) => {
const lines = stdout.split('\n');
[
chalk.italic('This is an_italic* log.'),
chalk.italic('This is an_italic* log.'),
chalk.bold('This is a__bold* log.'),
chalk.bold('This is a__bold* log.'),
chalk.bold(chalk.italic('This is a_bold and italic* log.')),
chalk.bold(chalk.italic('This is a_bold and italic* log.')),
'_This is a normal log',
'This is a normal log_',
'__This is a normal log',
'This is a normal log__',
'*This is a normal log',
'This is a normal log*',
'**This is a normal log',
'This is a normal log**',
].forEach((msg, index) => {
expect(lines[index + 4]).to.equal(` cy:log ${ICONS.info} ${msg}`);
});
}
);
}).timeout(60000);
});
36 changes: 36 additions & 0 deletions test/specs/utils.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import utils from '../../src/utils';
import {expect} from 'chai';

const {applyMessageMarkdown} = utils;

describe('utils', () => {
describe('applyMessageMarkdown', () => {
it('correctly detects markdown and returns processed message with functions applied', () => {
const LONG_MSG = 'abc123'.repeat(5);
const tests = [
['*text text*', '<i>text text<i>'],
['_text text_', '<i>text text<i>'],
['**text text**', '<b>text text<b>'],
['__text text__', '<b>text text<b>'],
['***text text***', '<b><i>text text<i><b>'],
['___text text___', '<b><i>text text<i><b>'],
['_text text_text_', '<i>text text_text<i>'],
['text text_', 'text text_'],
['*text text', '*text text'],
['*text text**', '<i>text text*<i>'],
['**text text*', '<i>*text text<i>'],
[`**${LONG_MSG}**`, `<b>${LONG_MSG.substring(0, 20)}...<b>`],
];
tests.forEach(([message, expected]) => {
expect(
applyMessageMarkdown(message, {
bold: (str) => `<b>${str}<b>`,
italic: (str) => `<i>${str}<i>`,
processContents: (c) => (c.length > 20 ? c.substring(0, 20) + '...' : c),
}),
message
).to.deep.equal(expected);
});
});
});
});

0 comments on commit 1429f17

Please sign in to comment.