Repository: Codeception/CodeceptJS
Pull request #1804 (2019-07-25 22:12:38)

fix(allure): Failed xml parse when assert msg contains ansi symbol

DavertMik: Thanks!

Patch:
diff --git a/lib/plugin/allure.js b/lib/plugin/allure.js
index ddebdf57..ae70cb8c 100644
--- a/lib/plugin/allure.js
+++ b/lib/plugin/allure.js
@@ -1,6 +1,7 @@
 const event = require('../event');
 const Allure = require('allure-js-commons');
 const logger = require('../output');
+const ansiRegExp = require('../utils').ansiRegExp;
 
 const defaultConfig = {
   outputDir: global.output_dir,
@@ -193,6 +194,8 @@ module.exports = (config) => {
       currentMetaStep.forEach(() => reporter.endStep('failed'));
       currentMetaStep = [];
     }
+
+    err.message = err.message.replace(ansiRegExp(), '');
     reporter.endCase('failed', err);
   });
 
diff --git a/lib/utils.js b/lib/utils.js
index 1717546f..76b2e83f 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -346,3 +346,12 @@ module.exports.replaceValueDeep = function replaceValueDeep(obj, key, value) {
   }
   return obj;
 };
+
+module.exports.ansiRegExp = function ({ onlyFirst = false } = {}) {
+  const pattern = [
+    '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
+    '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))',
+  ].join('|');
+
+  return new RegExp(pattern, onlyFirst ? undefined : 'g');
+};


Test patch:
diff --git a/test/data/sandbox/configs/allure/failed_ansi.conf.js b/test/data/sandbox/configs/allure/failed_ansi.conf.js
new file mode 100644
index 00000000..ea06f9d1
--- /dev/null
+++ b/test/data/sandbox/configs/allure/failed_ansi.conf.js
@@ -0,0 +1,17 @@
+exports.config = {
+  tests: './failed_ansi_test.js',
+  timeout: 10000,
+  output: './output/ansi',
+  helpers: {
+    FileSystem: {},
+  },
+  include: {},
+  plugins: {
+    allure: {
+      enabled: true,
+      output: './output/ansi',
+    },
+  },
+  mocha: {},
+  name: 'sandbox',
+};
diff --git a/test/data/sandbox/configs/allure/failed_ansi_test.js b/test/data/sandbox/configs/allure/failed_ansi_test.js
new file mode 100644
index 00000000..a521116c
--- /dev/null
+++ b/test/data/sandbox/configs/allure/failed_ansi_test.js
@@ -0,0 +1,8 @@
+
+Feature('Filesystem').tag('main');
+
+Scenario('check error with ansi symbols', (I) => {
+  I.amInPath('.');
+  I.say('hello world');
+  throw new Error('message with ANSI symbols \n \u001b[32mgreen\u001b[39m');
+}).tag('slow').tag('@important');
diff --git a/test/runner/allure_test.js b/test/runner/allure_test.js
new file mode 100644
index 00000000..d12eafe3
--- /dev/null
+++ b/test/runner/allure_test.js
@@ -0,0 +1,30 @@
+const assert = require('assert');
+const path = require('path');
+const { exec } = require('child_process');
+const fs = require('fs');
+
+const runner = path.join(__dirname, '/../../bin/codecept.js');
+const codecept_dir = path.join(__dirname, '/../data/sandbox/configs/allure');
+const codecept_run = `${runner} run`;
+const codecept_run_config = (config, grep) => `${codecept_run} --config ${codecept_dir}/${config} ${grep ? `--grep ${grep}` : ''}`;
+
+
+describe('CodeceptJS Allure Plugin', () => {
+  afterEach(() => {
+    fs.readdir(path.join(codecept_dir, 'output/ansi'), (err, files) => {
+      files.forEach((file) => {
+        fs.unlinkSync(path.join(codecept_dir, 'output/ansi', file));
+      });
+    });
+  });
+
+  it('should create xml file when assert message has ansi symbols', (done) => {
+    exec(codecept_run_config('failed_ansi.conf.js'), (err, stdout, stderr) => {
+      assert(err);
+      fs.readdir(path.join(codecept_dir, 'output/ansi'), (err, files) => {
+        assert.equal(files.length, 1);
+        done();
+      });
+    });
+  });
+});
diff --git a/test/runner/interface_test.js b/test/runner/interface_test.js
index 344456c2..54b21a51 100644
--- a/test/runner/interface_test.js
+++ b/test/runner/interface_test.js
@@ -184,7 +184,7 @@ describe('CodeceptJS Interface', () => {
     });
   });
 
-  it.only('should inject page objects via proxy', (done) => {
+  it.skip('should inject page objects via proxy', (done) => {
     exec(`${config_run_config('../inject-fail-example')} --debug`, (err, stdout) => {
       stdout.should.include('qw');
       stdout.should.include('OK  | 1 passed');