Repository: nightwatchjs/nightwatch (js)

Issue:
client.pause(0) leads to indefinite wait time
### Description of the bug/issue

During an execution workflow in the script, when the statement `client.pause(0)` was executed, the script execution waited indefinitely.

The documentation [here](https://nightwatchjs.org/api/pause.html#apimethod-container) points out that `client.pause()` will lead to indefinite wait time. However, `client.pause(0)` also does which is confusing and not intuitive too. Of course it is unlikely that one may call this statement, however, during execution flows where pause time is not predefined this statement can be called.

### Steps to reproduce

1. Executing the script in the sample test will highlight the issue (/undocumented feature).

### Sample test
Execute the below script. 

```node


describe("client wait time", function () {

	it("tests client wait time", async (client) => {
		let url = "https://google.com";

		await client.navigateTo(url);

		let duration = 0;

		console.log(`Waiting now for ${duration} ms.`);

		client.pause(duration)

		client.end();
	});
});
```

### Command to run

```bash
npx nightwatch .\tests\waitTimeCheck.js --env chrome
```


### Verbose Output

```fundamental
[client wait time] Test Suite
──────────────────────────────────────────────────────────
- Starting ChromeDriver on port 9515...
 Starting ChromeDriver with server_path=D:\xampp\htdocs\vmeetWebRTCTest\node_modules\chromedriver\lib\chrome
driver\chromedriver.exe...
   Request POST /session  
   {
     desiredCapabilities: {
       browserName: 'chrome',
       'goog:chromeOptions': { w3c: true, args: [] },
       name: 'client wait time'
     },
     capabilities: {
       alwaysMatch: {
         browserName: 'chrome',
         'goog:chromeOptions': { w3c: true, args: [] }
       }
     }
\ Starting ChromeDriver on port 9515...

| Starting ChromeDriver on port 9515...
   Response 200 POST /session (1532ms)
   {
     value: {
       capabilities: {
         acceptInsecureCerts: false,
         browserName: 'chrome',
         browserVersion: '105.0.5195.127',
         chrome: {
           chromedriverVersion: '104.0.5112.79 (3cf3e8c8a07d104b9e1260c910efb8f383285dc5-refs/branch-heads/5
112@{#1307})',
           userDataDir: 'C:\\Users\\syste\\AppData\\Local\\Temp\\scoped_dir6392_112913112'
         },
         'goog:chromeOptions': { debuggerAddress: 'localhost:63686' },
         networkConnectionEnabled: false,
         pageLoadStrategy: 'normal',
         platformName: 'windows',
         proxy: {},
         setWindowRect: true,
         strictFileInteractability: false,
         timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },
         unhandledPromptBehavior: 'dismiss and notify',
         'webauthn:extension:credBlob': true,
         'webauthn:extension:largeBlob': true,
         'webauthn:virtualAuthenticators': true
       },
       sessionId: '67fe443d71ea208468d6d7bbe8187c41'
     }
i Connected to ChromeDriver on port 9515 (1620ms).
  Using: chrome (105.0.5195.127) on WINDOWS.

 Received session with ID: 67fe443d71ea208468d6d7bbe8187c41

 → Running [before]:
 → Completed [before].



  Running tests client wait time:
───────────────────────────────────────────────────────────────────────────────────────────────────
 → Running [beforeEach]:
 → Completed [beforeEach].

 → Running command: navigateTo ('https://google.com')
   Request POST /session/67fe443d71ea208468d6d7bbe8187c41/url  
   { url: 'https://google.com' }
   Response 200 POST /session/67fe443d71ea208468d6d7bbe8187c41/url (2665ms)
   { value: null }
  → Completed command: navigateTo ('https://google.com') (2671ms)
Waiting now for 0 ms.
 → Running [afterEach]:
 
 → Running command: pause (0)
Paused...
  Press <space> or F10 to step over to the next test command and pause again.
  Press Ctrl+C to exit.
  Press any other key to RESUME.
[25552:20232:1006/124828.196:ERROR:device_event_log_impl.cc(214)] [12:48:28.196] USB: usb_device_handle_win.
cc:1048 Failed to read descriptor from node connection: A device attached to the system is not functioning. 
(0x1F)
[25552:20232:1006/124828.198:ERROR:device_event_log_impl.cc(214)] [12:48:28.198] USB: usb_device_handle_win.
cc:1048 Failed to read descriptor from node connection: A device attached to the system is not functioning. 
(0x1F)
```


### Nightwatch Configuration

_No response_

### Nightwatch.js Version

2.3.3

### Node Version

_No response_

### Browser

Chrome

### Operating System

Windows 10

### Additional Information

_No response_

Pull request:
Added a check for 0 ms in pause command
fixes #3422 


Patch:
diff --git a/lib/api/client-commands/pause.js b/lib/api/client-commands/pause.js
index 08c112f6..6accd2da 100644
--- a/lib/api/client-commands/pause.js
+++ b/lib/api/client-commands/pause.js
@@ -42,7 +42,7 @@ Pause.prototype.command = function(ms, cb) {
   // If we don't pass the milliseconds, the client will
   // be suspended indefinitely, until the user presses some
   // key in the terminal to resume it.
-  if (!ms) {
+  if (ms === undefined) {
     // eslint-disable-next-line
     console.log(`Paused...
   Press <space> or F10 to step over to the next test command and pause again.
diff --git a/lib/core/treenode.js b/lib/core/treenode.js
index 279deaf3..f8192236 100644
--- a/lib/core/treenode.js
+++ b/lib/core/treenode.js
@@ -170,8 +170,6 @@ class TreeNode {
         result = err;
       }
 
-      this.done = true;
-
       return result;
     }
 
diff --git a/lib/reporter/results.js b/lib/reporter/results.js
index ed700d8d..15a9807b 100644
--- a/lib/reporter/results.js
+++ b/lib/reporter/results.js
@@ -1,5 +1,5 @@
 const AssertionError = require('assertion-error');
-const {merge: lodashMerge} = require('lodash');
+const lodashMerge = require('lodash.merge');
 const Utils = require('../utils');
 const {Logger} = Utils;
 
diff --git a/package-lock.json b/package-lock.json
index fe127f13..99aa0582 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "nightwatch",
-  "version": "2.6.2",
+  "version": "2.6.4",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "nightwatch",
-      "version": "2.6.2",
+      "version": "2.6.4",
       "license": "MIT",
       "dependencies": {
         "@nightwatch/chai": "5.0.2",
diff --git a/package.json b/package.json
index 4c29debe..be7e4c81 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "name": "nightwatch",
   "description": "Easy to use Node.js based end-to-end testing solution for web applications using the W3C WebDriver API.",
-  "version": "2.6.2",
+  "version": "2.6.4",
   "author": "Andrei Rusu",
   "homepage": "https://nightwatchjs.org",
   "main": "./lib/index.js",


Test patch:
diff --git a/test/extra/commands/customCommandAppendResults.js b/test/extra/commands/customCommandAppendResults.js
new file mode 100644
index 00000000..86535ea5
--- /dev/null
+++ b/test/extra/commands/customCommandAppendResults.js
@@ -0,0 +1,14 @@
+module.exports = class AppendResult {
+  command() {
+    const {name} = this.client.reporter.currentTest;
+    const {testResults} = this.client.reporter;
+    testResults.appendTestResult({
+      [name]: {
+        customReport: {
+          success: true
+        }
+      }
+    });
+
+  }
+};
\ No newline at end of file
diff --git a/test/sampletests/appendtestresult/sampleWithAppendResults.js b/test/sampletests/appendtestresult/sampleWithAppendResults.js
new file mode 100644
index 00000000..65fa3a4c
--- /dev/null
+++ b/test/sampletests/appendtestresult/sampleWithAppendResults.js
@@ -0,0 +1,5 @@
+module.exports = {
+  demoTest(client) {
+    client.url('http://localhost').customCommandAppendResults().end();
+  }
+};
\ No newline at end of file
diff --git a/test/src/api/commands/client/testPause.js b/test/src/api/commands/client/testPause.js
index f9620a28..b543b158 100644
--- a/test/src/api/commands/client/testPause.js
+++ b/test/src/api/commands/client/testPause.js
@@ -20,6 +20,16 @@ describe('.pause()', function() {
     this.client.start(done);
   });
 
+  it('browser.pause(0) does not pause more than 2000ms', function(done) {
+    const startTime = new Date();
+    this.client.api.pause(0, function() {
+      const timeElapsed = new Date() - startTime;
+      assert.ok(timeElapsed >= 0);
+    });
+
+    this.client.start(done);
+  });
+
   it('browser.pause(200) pauses for atleast 200ms and not more than 2000ms', function(done) {
     const startTime = new Date();
     this.client.api.pause(200, function() {
diff --git a/test/src/runner/testReporter.js b/test/src/runner/testReporter.js
index e0627fb2..96c62b6c 100644
--- a/test/src/runner/testReporter.js
+++ b/test/src/runner/testReporter.js
@@ -329,4 +329,39 @@ describe('testReporter', function() {
     assert.strictEqual(possibleError, null);
 
   });
+
+  it('check reporter output with appended results', async function() {
+    let possibleError = null;
+    const testPath = [path.join(__dirname, '../../sampletests/appendtestresult/sampleWithAppendResults.js')];
+    const customCommands = [path.join(__dirname, '../../extra/commands')];
+
+    try {
+      await runTests({
+        source: testPath
+      }, settings({
+        custom_commands_path: customCommands,
+        globals: {
+          waitForConditionPollInterval: 20,
+          waitForConditionTimeout: 50,
+          retryAssertionTimeout: 50,
+          reporter: function (results) {
+            const module = results.modules['sampleWithAppendResults'];
+            
+            assert.ok(Object.keys(module).includes('completedSections'));
+            const completedSections = module['completedSections'];
+            assert.ok(Object.keys(completedSections).includes('demoTest'));
+
+            const test = completedSections['demoTest'];
+            assert.ok(Object.keys(test).includes('customReport'));
+            assert.deepStrictEqual(test.customReport, {success: true});
+          }
+        },
+        silent: true,
+        output: false
+      }));
+    } catch (err) {
+      possibleError = err;
+    }
+    assert.strictEqual(possibleError, null);
+  });
 });