Repository: Codeception/CodeceptJS (js)

Issue:
I.dragAndDrop does not work with WebDriverIO helper
#### What are you trying to achieve?
Using WebDriverIO helper and trying to use I.dragAndDrop

#### What do you get instead?
dragAndDrop fails. 

#### Error on console:
```bash
CodeceptJS v1.0.3
Using test root "/home/prashant_sail/cc/ccIssue"

Codecept Evaluation --
   [1] Starting recording promises
   Emitted | suite.before ([object Object])
   [1] Queued | hook WebDriverIO._beforeSuite()
 Trial
   Emitted | test.before
   [1] Queued | hook WebDriverIO._before()
   Emitted | test.start ([object Object])
   Emitted | step.before (I am on page "droppable")
   [1] Queued | amOnPage: "droppable"
   Emitted | step.after (I am on page "droppable")
   [1] Queued | step passed
   [1] Queued | return result
   [1] Queued | register within wrapper
   [1] Queued | fire test.passed
   [1] Queued | finish test
   Emitted | step.start (I am on page "droppable")
 • I am on page "droppable"
   Emitted | step.passed (I am on page "droppable")
   Step finished in 6.07 sec
   [1] Starting <within> session
   Within {"frame":"#content > iframe"}:
   [1] <within> Queued | start within block
   Emitted | step.before (I drag and drop "#draggable", "#droppable")
   [1] <within> Queued | dragAndDrop: "#draggable", "#droppable"
   Emitted | step.after (I drag and drop "#draggable", "#droppable")
   [1] <within> Queued | step passed
   [1] <within> Queued | return result
   [1] <within> Queued | finish within block
   [1] <within> Queued | Finalize within session
   Emitted | step.start (Within {"frame":"#content > iframe"}: I drag and drop "#draggable", "#droppable")
   • Within {"frame":"#content > iframe"}: I drag and drop "#draggable", "#droppable"
WARNING: the "moveTo" command will be deprecated soon. If you have further questions, reach out in the WebdriverIO Gitter support channel (https://gitter.im/webdriverio/webdriverio).
Note: This command is not part of the W3C WebDriver spec and won't be supported in future versions of the driver. It is recommended to use the actions command to emulate pointer events.

(You can disable this warning by setting `"deprecationWarnings": false` in your WebdriverIO config)
   [1] <within> Error | Error: Unable to move cursor to (#draggable)
   Emitted | step.failed (Within {"frame":"#content > iframe"}: I drag and drop "#draggable", "#droppable")
   Step finished in 0.112 sec
   [1] <within> Error | Error: Unable to move cursor to (#draggable)
   [1] <within> Error | Error: Unable to move cursor to (#draggable)
   [1] <within> Starting <teardown> session
   Emitted | test.failed ([object Object])
   [1] <teardown> Queued | hook WebDriverIO._failed()
   [1] <teardown> Queued | () => done(err)
   [1] <teardown> Stopping recording promises
 > Screenshot has been saved to /home/prashant_sail/cc/ccIssue/output/Trial.failed.png
 ✖ FAILED in 6409ms

   [2] Starting recording promises
   Emitted | test.after
   [2] Queued | hook WebDriverIO._after()
   Emitted | suite.after ([object Object])
   [2] Queued | hook WebDriverIO._afterSuite()

-- FAILURES:

  1) Codecept Evaluation: Trial:
     Unable to move cursor to (#draggable)
  
  Scenario Steps:
  
  - Within {"frame":"#content > iframe"}: I.dragAndDrop("#draggable", "#droppable") at within (demo_test.js:6:9)
  - I.amOnPage("droppable") at Test.<anonymous> (demo_test.js:4:5)
  
  Error: Unable to move cursor to (#draggable)
      at Object.<anonymous> (/usr/lib/node_modules/codeceptjs/lib/helper/WebDriverIO.js:1485:42)
      at Object.exec (/usr/lib/node_modules/webdriverio/build/lib/helpers/safeExecute.js:28:24)
      at Object.resolve (/usr/lib/node_modules/webdriverio/build/lib/webdriverio.js:191:29)
      at /usr/lib/node_modules/webdriverio/build/lib/webdriverio.js:540:32
      at _fulfilled (/usr/lib/node_modules/webdriverio/node_modules/q/q.js:854:54)
      at self.promiseDispatch.done (/usr/lib/node_modules/webdriverio/node_modules/q/q.js:883:30)
      at Promise.promise.promiseDispatch (/usr/lib/node_modules/webdriverio/node_modules/q/q.js:816:13)
      at /usr/lib/node_modules/webdriverio/node_modules/q/q.js:624:44
      at runSingle (/usr/lib/node_modules/webdriverio/node_modules/q/q.js:137:13)
      at flush (/usr/lib/node_modules/webdriverio/node_modules/q/q.js:125:13)


  FAIL  | 0 passed, 1 failed   // 7s
   Emitted | global.result ([object Object])
   [2] Queued | hook WebDriverIO._finishTest()
```

#### My testcase file(demo_test.js) :
```js
Feature('Codecept Evaluation');

Scenario('Trial', function(I) {
  I.amOnPage('droppable');
    within({frame: "#content > iframe"}, () => {
      I.dragAndDrop('#draggable','#droppable');
    });
});
```

### Details
* CodeceptJS version: 1.0.3
* NodeJS Version: 6.12.0
* Operating System: CentOS Linux release 7.4.1708 (Core)
* WebDriverIO 4.9.11
* Configuration file:
```js
{
  "tests": "./*_test.js",
  "timeout": 10000,
  "output": "./output",
  "helpers": {
    "WebDriverIO": {
      "url": "https://jqueryui.com/",
      "browser": "chrome"
      }
  },
  "bootstrap": false,
  "mocha": {},
  "name": "ccIssue"
}
```


Pull request description:
[WebDriverIO] Use inbuilt dragAndDrop function
#### Highlights
* [WebDriverIO] Utilise the inbuilt WebDriverIO dragAndDrop function instead of doing mouse moves and clicks manually. Fixes #822

#### Notes
* This still does not work with Firefox

Patch:
diff --git a/lib/codecept.js b/lib/codecept.js
index 04921c9a..b76b1e71 100644
--- a/lib/codecept.js
+++ b/lib/codecept.js
@@ -85,7 +85,12 @@ class Codecept {
    */
   loadTests(pattern) {
     pattern = pattern || this.config.tests;
-    glob.sync(fsPath.resolve(global.codecept_dir, pattern)).forEach((file) => {
+
+    const options = {
+      cwd: global.codecept_dir,
+    };
+
+    glob.sync(pattern, options).forEach((file) => {
       this.testFiles.push(fsPath.resolve(file));
     });
   }
diff --git a/lib/command/run-multiple.js b/lib/command/run-multiple.js
index e3e922d3..ad18410e 100644
--- a/lib/command/run-multiple.js
+++ b/lib/command/run-multiple.js
@@ -143,6 +143,11 @@ function runSuite(suite, suiteConf, browser) {
   overriddenConfig = replaceValue(overriddenConfig, 'reportDir', path.join(config.output, outputDir));
   overriddenConfig = replaceValue(overriddenConfig, 'mochaFile', path.join(config.output, outputDir, `${browser}_report.xml`));
 
+  // override tests configuration
+  if (overriddenConfig.tests) {
+    overriddenConfig.tests = suiteConf.tests;
+  }
+
   // override grep param and collect all params
   const params = ['run',
     '--child', `${suiteId++}.${suite}:${browser}`,
diff --git a/lib/helper/Nightmare.js b/lib/helper/Nightmare.js
index e2176be4..eb20f630 100644
--- a/lib/helper/Nightmare.js
+++ b/lib/helper/Nightmare.js
@@ -865,7 +865,7 @@ class Nightmare extends Helper {
   }
 
   /**
-   * {{> ../webapi/waitForVisible }}
+   * {{> ../webapi/waitForInvisible }}
    */
   waitForInvisible(locator, sec) {
     this.browser.options.waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
diff --git a/lib/helper/WebDriverIO.js b/lib/helper/WebDriverIO.js
index d8d25629..a21e1ff2 100644
--- a/lib/helper/WebDriverIO.js
+++ b/lib/helper/WebDriverIO.js
@@ -1348,13 +1348,10 @@ class WebDriverIO extends Helper {
       return this.browser.touchUp(location.value.x, location.value.y);
     }
 
-    let res = await this.moveCursorTo(withStrictLocator.call(this, srcElement));
-    if (res.state !== 'success') throw new Error(`Unable to move cursor to (${srcElement})`);
-    res = await this.browser.buttonDown();
-    if (res.state !== 'success') throw new Error(`Failed to press button down on (${srcElement})`);
-    res = await this.moveCursorTo(withStrictLocator.call(this, destElement));
-    if (res.state !== 'success') throw new Error(`Unable to move cursor to (${destElement})`);
-    return this.browser.buttonUp();
+    return client.dragAndDrop(
+      withStrictLocator.call(this, srcElement),
+      withStrictLocator.call(this, destElement),
+    );
   }
 
 


Test patch:
diff --git a/test/data/sandbox/codecept.glob.json b/test/data/sandbox/codecept.glob.json
new file mode 100644
index 00000000..76756f38
--- /dev/null
+++ b/test/data/sandbox/codecept.glob.json
@@ -0,0 +1,12 @@
+{
+  "tests": "{./*does_not_exist_test.js,./*fs_test.glob.js}",
+  "timeout": 10000,
+  "output": "./output",
+  "helpers": {
+    "FileSystem": {}
+  },
+  "include": {},
+  "bootstrap": false,
+  "mocha": {},
+  "name": "sandbox"
+}
\ No newline at end of file
diff --git a/test/data/sandbox/codecept.multiple.json b/test/data/sandbox/codecept.multiple.json
index 918d9cff..5adf5841 100644
--- a/test/data/sandbox/codecept.multiple.json
+++ b/test/data/sandbox/codecept.multiple.json
@@ -25,6 +25,11 @@
       "grep": "@grep",
       "browsers": ["chrome",
         { "browser": "firefox", "windowSize": "1200x840"}]
+    },
+    "test": {
+      "tests": "./*_test_override.multiple.js",
+      "browsers": ["chrome",
+        { "browser": "firefox", "windowSize": "1200x840"}]
     }
   },
   "include": {},
diff --git a/test/data/sandbox/fs_test.glob.js b/test/data/sandbox/fs_test.glob.js
new file mode 100644
index 00000000..bb652540
--- /dev/null
+++ b/test/data/sandbox/fs_test.glob.js
@@ -0,0 +1,7 @@
+Feature('Filesystem');
+
+Scenario('glob current dir', (I) => {
+  I.amInPath('.');
+  I.say('hello world');
+  I.seeFile('codecept.glob.json');
+});
diff --git a/test/data/sandbox/tests_test_override.multiple.js b/test/data/sandbox/tests_test_override.multiple.js
new file mode 100644
index 00000000..d8cb6c27
--- /dev/null
+++ b/test/data/sandbox/tests_test_override.multiple.js
@@ -0,0 +1,5 @@
+Feature('print browser size');
+
+Scenario('print browser size info', (I) => {
+  I.printWindowSize();
+});
diff --git a/test/docker-compose.yml b/test/docker-compose.yml
index 5d9399a2..4c4a71d9 100644
--- a/test/docker-compose.yml
+++ b/test/docker-compose.yml
@@ -9,6 +9,15 @@ services:
       - ..:/codecept
       - node_modules:/codecept/node_modules
 
+  test-runner:
+    build: ..
+    entrypoint: docker/entrypoint node_modules/.bin/mocha
+    command: test/runner
+    working_dir: /codecept
+    volumes:
+      - ..:/codecept
+      - node_modules:/codecept/node_modules
+
   test-helpers:
     build: ..
     entrypoint: docker/entrypoint node_modules/.bin/mocha --invert --fgrep Appium
diff --git a/test/helper/WebDriverIO_test.js b/test/helper/WebDriverIO_test.js
index 5029e7d7..d47ecec5 100644
--- a/test/helper/WebDriverIO_test.js
+++ b/test/helper/WebDriverIO_test.js
@@ -646,4 +646,18 @@ describe('WebDriverIO', function () {
         assert.equal(matchingLogs.length, 2);
       }));
   });
+
+  describe('#dragAndDrop', () => {
+    it('Drag item from source to target (no iframe) @dragNdrop', () => wd.amOnPage('http://jqueryui.com/resources/demos/droppable/default.html')
+      .then(() => wd.seeElementInDOM('#draggable'))
+      .then(() => wd.dragAndDrop('#draggable', '#droppable'))
+      .then(() => wd.see('Dropped')));
+
+    it('Drag and drop from within an iframe', () => wd.amOnPage('http://jqueryui.com/droppable')
+      .then(() => wd.resizeWindow(700, 700))
+      .then(() => wd.switchTo('//iframe[@class="demo-frame"]'))
+      .then(() => wd.seeElementInDOM('#draggable'))
+      .then(() => wd.dragAndDrop('#draggable', '#droppable'))
+      .then(() => wd.see('Dropped')));
+  });
 });
diff --git a/test/runner/codecept_test.js b/test/runner/codecept_test.js
index 06b9f7d5..8a12c280 100644
--- a/test/runner/codecept_test.js
+++ b/test/runner/codecept_test.js
@@ -26,6 +26,15 @@ describe('CodeceptJS Runner', () => {
     });
   });
 
+  it('should be executed with glob', (done) => {
+    process.chdir(codecept_dir);
+    exec(codecept_run_config('codecept.glob.json'), (err, stdout, stderr) => {
+      stdout.should.include('Filesystem'); // feature
+      stdout.should.include('glob current dir'); // test name
+      assert(!err);
+      done();
+    });
+  });
 
   it('should be executed with config path', (done) => {
     exec(`${codecept_run} -c ${codecept_dir}`, (err, stdout, stderr) => {
diff --git a/test/runner/run_multiple_test.js b/test/runner/run_multiple_test.js
index 9ffe9fad..65704b99 100644
--- a/test/runner/run_multiple_test.js
+++ b/test/runner/run_multiple_test.js
@@ -101,4 +101,16 @@ describe('CodeceptJS Multiple Runner', function () {
       done();
     });
   });
+
+  it('should pass tests to configuration', (done) => {
+    exec(`${codecept_run}test`, (err, stdout, stderr) => {
+      stdout.should.include('CodeceptJS'); // feature
+      stdout.should.include('[1.test:chrome] print browser size');
+      stdout.should.include('[2.test:firefox] print browser size');
+      stdout.should.include('[1.test:chrome] print browser ');
+      stdout.should.include('[2.test:firefox] print browser ');
+      assert(!err);
+      done();
+    });
+  });
 });