Fix swipe action with target element: #3647

@Jonahss @imurchie (this reviewers of the first merge request that I closed because the new changes are a lot different) 

*  The original scope of this change was adding the ability to specify a destination element when doing a swipe.  Those are the changes you'll see in the server JS.
*  I added a bunch of tests.
*  When I started expanding the test suite for Android, I uncovered some nasty bugs w relative coordinates.  At least one was caused by copy/pasting.  I then discovered similar code (not nec buggy, but using the same patterns) in multiple places in the project.  I consolidated the logic to decrease the likelihood of bugs and ensure that absolute coordinates were all derived in the same way.
*  There's a bunch of spaghetti code.  If you have any suggestions on how I can get rid of it, lmk.
*  There's a change to the sample code that goes along with this.
*  I ran all the Android `touch` tests and they passed, with the exception of 'should work like `longPress` when released after a pause', which also failed for me before the refactoring


I tried `before`, but ran into race conditions where the elements
couldn't be found.

On 11/1/14, seb vincent <notifications@github.com> wrote:
>> +        .then(function () { return slider.getAttribute("value"); })
>> +        .then(testSliderValueNear50)
>> +
>> +        // test: press {x, y}, moveTo {destEl}
>> +        .then(function () {
>> +          return driver.performTouchAction((new TouchAction())
>> +            .press({x: centerPos.x, y: centerPos.y}).wait({ms:
>> 500}).moveTo({el: destEl}).release());
>> +        })
>> +        .then(function () { return slider.getAttribute("value"); })
>> +        .then(function (valueAfter) {
>> +          valueAfter.should.equal("100%");
>> +        })
>> +
>> +        .nodeify(done);
>> +    });
>> +
>
> Mocha execute sequentially and the setup is within a `before`, so should be
> ok to split.
>
> However, you don't need that many `then` you can do it like this instead:
> driver
> . performTouchAction(...)
> ...
> performTouchAction()
>
> only if the action parameter depends from previous results you need the
> then.
>
> Also when checking value you can use `should.become` e.g.:
> ```js
> driver
>    .getElement(...).getValue().should.become(5)
>    .getElement(...).getValue().should.become(6)
> ```
> And use eventually to resolve the promise: e.g..
>
> ```js
> driver
>    .getElement().text().should.eventually.include
>    .getElemen(...)
> ```
>
> Also can use `Q.all()`
> ```
> Q.all([
>   el.getSize(),
>   el.getLocation(),
> ]).spread(function (size, location) {
> ...
> })
> ```
>
> ---
> Reply to this email directly or view it on GitHub:
> https://github.com/appium/appium/pull/3943/files#r19703539