Repository: nightwatchjs/nightwatch
Pull request #3494 (2022-11-23 13:33:55)

Added properties to reporter object
Added the following properties to reporter object:

- Driver Capabilities, session id
- Start/end timestamps for test module
- test status for individual tests in module
- Start/end timestamps for individual tests in module
- Added buildName, projectName to reporter module


Patch:
diff --git a/lib/reporter/index.js b/lib/reporter/index.js
index 3d39367c..841b6a48 100644
--- a/lib/reporter/index.js
+++ b/lib/reporter/index.js
@@ -27,7 +27,7 @@ class Reporter extends SimplifiedReporter {
 
     this.suiteRetries = suiteRetries;
     this.suiteName = addOpts.suiteName;
-    this.testResults = new TestResults(tests, addOpts);
+    this.testResults = new TestResults(tests, addOpts, settings);
     this.currentContext = null;
     this.__printA11Report = false;
     this.reporter = addOpts.repoter;
@@ -108,10 +108,19 @@ class Reporter extends SimplifiedReporter {
     this.testResults.reportPrefix = prefix;
   }
 
+  setSessionInfo(data) {
+    this.testResults.sessionCapabilities = data.capabilities;
+    this.testResults.sessionId = data.sessionId;
+  }
+
   setElapsedTime() {
     this.testResults.setElapsedTime();
   }
 
+  setTestStatus() {
+    this.testResults.setTestStatus();
+  }
+
   testSuiteFinished() {
     this.testResults.setTotalElapsedTime();
   }
diff --git a/lib/reporter/results.js b/lib/reporter/results.js
index 72fef1df..b83910cf 100644
--- a/lib/reporter/results.js
+++ b/lib/reporter/results.js
@@ -3,7 +3,15 @@ const Utils = require('../utils');
 const {Logger} = Utils;
 
 module.exports = class Results {
-  constructor(tests = [], opts) {
+  static get TEST_FAIL() {
+    return 'fail';
+  }
+
+  static get TEST_PASS() {
+    return 'pass';
+  }
+
+  constructor(tests = [], opts, settings) {
     this.skipped = tests.slice(0);
     this.testcases = {};
     this.suiteName = opts.suiteName;
@@ -12,6 +20,8 @@ module.exports = class Results {
     this.groupName = opts.groupName;
     this.reportPrefix = opts.reportPrefix;
     this.globalStartTime = new Date().getTime();
+    this.startTimestamp = this.globalStartTime;
+    this.endTimestamp = this.globalStartTime;
     this.currentTestName = '';
     this.__currentTest = null;
     this.__initialResult = {
@@ -21,6 +31,12 @@ module.exports = class Results {
       assertions: [],
       tests: 0
     };
+    // Adding sessionInfo to reporter
+    const {capabilities = {}, desiredCapabilities = {}} = settings;
+    this.sessionCapabilities = {};
+    this.sessionId = '';
+    this.projectName = capabilities.projectName || desiredCapabilities.projectName || '';
+    this.buildName = capabilities.buildName || desiredCapabilities.buildName || '';
 
     this.initCount(tests);
   }
@@ -93,6 +109,10 @@ module.exports = class Results {
     };
   }
 
+  hasFailures() {
+    return this.currentTestResult.errors === 0 && this.currentTestResult.failed === 0;
+  }
+
   ////////////////////////////////////////////////////////////
   // Counters
   ////////////////////////////////////////////////////////////
@@ -178,6 +198,12 @@ module.exports = class Results {
     suiteResults.results.passedCount = this.passedCount;
     suiteResults.results.group = this.groupName;
     suiteResults.results.modulePath = this.modulePath;
+    suiteResults.results.startTimestamp = new Date(this.startTimestamp).toUTCString();
+    suiteResults.results.endTimestamp = new Date(this.endTimestamp).toUTCString();
+    suiteResults.results.sessionCapabilities = this.sessionCapabilities;
+    suiteResults.results.sessionId = this.sessionId;
+    suiteResults.results.projectName = this.projectName;
+    suiteResults.results.buildName = this.buildName;
 
     // Backwards compat
     suiteResults.results.tests = this.testsCount;
@@ -320,18 +346,36 @@ module.exports = class Results {
   setElapsedTime() {
     const currentTest = this.getCurrentTest();
     const startTime = currentTest ? currentTest.startTime : this.globalStartTime;
-    const elapsedTime = new Date().getTime() - startTime;
+    const endTime = new Date().getTime();
+    const elapsedTime = endTime - startTime;
+    this.endTimestamp = endTime;
 
     this.time += elapsedTime;
 
     if (currentTest) {
       this.currentTestResult.time = (elapsedTime/1000).toPrecision(4);
       this.currentTestResult.timeMs = elapsedTime;
+      this.currentTestResult.startTimestamp = new Date(startTime).toUTCString();
+      this.currentTestResult.endTimestamp = new Date(endTime).toUTCString();
+
     }
 
     return this;
   }
 
+  setTestStatus() {
+    const currentTest = this.getCurrentTest();
+    if (!currentTest) {
+      return;    
+    }
+
+    if (this.hasFailures()) {
+      this.currentTestResult.status = Results.TEST_FAIL;
+    } else {
+      this.currentTestResult.status = Results.TEST_PASS;
+    }
+  }
+
   setTotalElapsedTime() {
     this.time = (this.time/1000).toPrecision(4);
 


Test patch:
diff --git a/lib/testsuite/index.js b/lib/testsuite/index.js
index 07628aa4..4bffa560 100644
--- a/lib/testsuite/index.js
+++ b/lib/testsuite/index.js
@@ -474,11 +474,15 @@ class TestSuite {
     return this.createSession()
       .then(data => {
         this.setReportPrefix(data);
+        // Adding session info to report
+        if (data) {
+          this.reporter.setSessionInfo(data);
 
-        if (data && data.capabilities && data.capabilities['safari:deviceUDID']) {
-          this.settings.deviceUDID = data.capabilities['safari:deviceUDID'];
+          if (data.capabilities && data.capabilities['safari:deviceUDID']) {
+            this.settings.deviceUDID = data.capabilities['safari:deviceUDID'];
+          }
         }
-
+        
         return this.runGlobalHook('beforeEach');
       });
   }
@@ -746,6 +750,7 @@ class TestSuite {
 
   testCaseFinished() {
     this.reporter.setElapsedTime();
+    this.reporter.setTestStatus();
 
     if (!this.testcase) {
       return Promise.resolve();
diff --git a/test/src/runner/testReporter.js b/test/src/runner/testReporter.js
index d023590a..404fed88 100644
--- a/test/src/runner/testReporter.js
+++ b/test/src/runner/testReporter.js
@@ -156,6 +156,7 @@ describe('testReporter', function() {
 
     try {
       await runTests({
+
         source: testsPath
       },
       settings({
@@ -220,4 +221,45 @@ describe('testReporter', function() {
     assert.strictEqual(htmlFile, `output${path.sep}nightwatch-html-report${path.sep}index.html`);
 
   });
+
+  it('Check reporter output for varaious properties', async function () {
+    let possibleError = null;
+    const testsPath = [path.join(__dirname, '../../sampletests/simple/test/sample.js')];
+
+    try {
+      await runTests({
+        source: testsPath
+      },
+      settings({
+        output_folder: 'output',
+        globals: {
+          waitForConditionPollInterval: 20,
+          waitForConditionTimeout: 50,
+          retryAssertionTimeout: 50,
+          reporter: function (results) {
+            const module = results.modules['sample'];
+            // check for module properties
+            assert.ok(Object.keys(module).includes('sessionCapabilities'));
+            assert.ok(Object.keys(module).includes('sessionId'));
+            assert.ok(Object.keys(module).includes('projectName'));
+            assert.ok(Object.keys(module).includes('buildName'));
+            assert.ok(Object.keys(module).includes('startTimestamp'));
+            assert.ok(Object.keys(module).includes('endTimestamp'));
+            // check for individual test properties
+            const test = module.completed['demoTest'];
+            assert.ok(Object.keys(test).includes('status'));
+            assert.ok(Object.keys(test).includes('startTimestamp'));
+            assert.ok(Object.keys(test).includes('endTimestamp'));
+          }
+        },
+        silent: true,
+        output: false
+      }));
+
+    } catch (error) {
+      possibleError = error;
+    }
+    assert.strictEqual(possibleError, null);
+
+  });
 });