зеркало из https://github.com/microsoft/appium.git
Make android gestures use offsets
This commit is contained in:
Родитель
cebff91c2c
Коммит
665890b23e
|
@ -1001,6 +1001,12 @@ androidController.performTouch = function (gestures, cb) {
|
|||
// some things are special
|
||||
doTouchDrag(gestures, cb);
|
||||
} else {
|
||||
// `press` without a wait is too slow and gets interpretted as a `longPress`
|
||||
if (actions[actions.length - 2] === 'press' && actions[actions.length - 1] === 'release') {
|
||||
actions[actions.length - 2] = 'tap';
|
||||
gestures[gestures.length - 2].action = 'tap';
|
||||
}
|
||||
|
||||
// the `longPress` and `tap` methods release on their own
|
||||
if ((actions[actions.length - 2] === 'tap' ||
|
||||
actions[actions.length - 2] === 'longPress') && actions[actions.length - 1] === 'release') {
|
||||
|
@ -1011,12 +1017,15 @@ androidController.performTouch = function (gestures, cb) {
|
|||
// fix release action then perform all actions
|
||||
fixRelease(function (err) {
|
||||
if (err) return cb(err);
|
||||
async.eachSeries(gestures, performGesture, cb);
|
||||
});
|
||||
this.parseTouch(gestures, false, function (err, fixedGestures) {
|
||||
if (err) return cb(err);
|
||||
async.eachSeries(fixedGestures, performGesture, cb);
|
||||
});
|
||||
}.bind(this));
|
||||
}
|
||||
};
|
||||
|
||||
androidController.parseTouch = function (gestures, cb) {
|
||||
androidController.parseTouch = function (gestures, multi, cb) {
|
||||
if (_.last(gestures).action === 'release') {
|
||||
gestures.pop();
|
||||
}
|
||||
|
@ -1027,8 +1036,9 @@ androidController.parseTouch = function (gestures, cb) {
|
|||
|
||||
var touchStateObjects = [];
|
||||
async.eachSeries(gestures, function (gesture, done) {
|
||||
var tapPoint = false;
|
||||
if (needsPoint(gesture.action)) { // press, longPress, moveTo and tap all need a position
|
||||
var options = gesture.options;
|
||||
if (needsPoint(gesture.action)) {
|
||||
options.offset = false;
|
||||
var elementId = gesture.options.element;
|
||||
if (elementId) {
|
||||
this.getLocation(elementId, function (err, res) {
|
||||
|
@ -1040,22 +1050,17 @@ androidController.parseTouch = function (gestures, cb) {
|
|||
var size = {w: res.value.width, h: res.value.height};
|
||||
|
||||
if (gesture.options.x || gesture.options.y) {
|
||||
tapPoint = {
|
||||
offset: false,
|
||||
x: pos.x + (gesture.options.x || 0),
|
||||
y: pos.y + (gesture.options.y || 0)
|
||||
};
|
||||
options.x = pos.x + (gesture.options.x || 0);
|
||||
options.y = pos.y + (gesture.options.y || 0);
|
||||
} else {
|
||||
tapPoint = {
|
||||
offset: false,
|
||||
x: pos.x + (size.w / 2),
|
||||
y: pos.y + (size.h / 2)
|
||||
};
|
||||
options.x = pos.x + (size.w / 2);
|
||||
options.y = pos.y + (size.h / 2);
|
||||
}
|
||||
|
||||
var touchStateObject = {
|
||||
action: gesture.action,
|
||||
options: options,
|
||||
timeOffset: 0.005,
|
||||
touch: tapPoint
|
||||
};
|
||||
touchStateObjects.push(touchStateObject);
|
||||
done();
|
||||
|
@ -1064,31 +1069,28 @@ androidController.parseTouch = function (gestures, cb) {
|
|||
} else {
|
||||
// expects absolute coordinates, so we need to save these as offsets
|
||||
// and then translate when everything is done
|
||||
tapPoint = {
|
||||
offset: true,
|
||||
x: (gesture.options.x || 0),
|
||||
y: (gesture.options.y || 0)
|
||||
};
|
||||
options.offset = true;
|
||||
options.x = (gesture.options.x || 0);
|
||||
options.y = (gesture.options.y || 0);
|
||||
|
||||
touchStateObject = {
|
||||
action: gesture.action,
|
||||
options: options,
|
||||
timeOffset: 0.005,
|
||||
touch: tapPoint
|
||||
};
|
||||
touchStateObjects.push(touchStateObject);
|
||||
done();
|
||||
}
|
||||
} else {
|
||||
// in this case we need the previous entry's tap point
|
||||
tapPoint = false; // temporary marker
|
||||
var offset = 0.005;
|
||||
if (gesture.action === 'wait') {
|
||||
if (typeof gesture.options.ms !== 'undefined' || gesture.options.ms !== null) {
|
||||
offset = (parseInt(gesture.options.ms) / 1000);
|
||||
}
|
||||
options = gesture.options;
|
||||
offset = (parseInt(gesture.options.ms) / 1000);
|
||||
}
|
||||
var touchStateObject = {
|
||||
action: gesture.action,
|
||||
options: options,
|
||||
timeOffset: offset,
|
||||
touch: tapPoint
|
||||
};
|
||||
touchStateObjects.push(touchStateObject);
|
||||
done();
|
||||
|
@ -1101,20 +1103,28 @@ androidController.parseTouch = function (gestures, cb) {
|
|||
var prevPos = null,
|
||||
time = 0;
|
||||
_.each(touchStateObjects, function (state) {
|
||||
if (state.touch === false) {
|
||||
// if we have no position (this happens with `wait`) we need the previous one
|
||||
state.touch = prevPos;
|
||||
} else if (state.touch.offset && prevPos) {
|
||||
// the current position is an offset
|
||||
state.touch.x += prevPos.x;
|
||||
state.touch.y += prevPos.y;
|
||||
if (typeof state.options.x === 'undefined' && typeof state.options.x === 'undefined') {
|
||||
// this happens with wait
|
||||
state.options.x = prevPos.x;
|
||||
state.options.y = prevPos.y;
|
||||
}
|
||||
delete state.touch.offset;
|
||||
prevPos = state.touch;
|
||||
if (state.options.offset && prevPos) {
|
||||
// the current position is an offset
|
||||
state.options.x += prevPos.x;
|
||||
state.options.y += prevPos.y;
|
||||
}
|
||||
delete state.options.offset;
|
||||
prevPos = state.options;
|
||||
|
||||
var timeOffset = state.timeOffset;
|
||||
time += timeOffset;
|
||||
state.time = helpers.truncateDecimals(time, 3);
|
||||
if (multi) {
|
||||
var timeOffset = state.timeOffset;
|
||||
time += timeOffset;
|
||||
state.time = helpers.truncateDecimals(time, 3);
|
||||
|
||||
// multi gestures require 'touch' rather than 'options'
|
||||
state.touch = state.options;
|
||||
delete state.options;
|
||||
}
|
||||
|
||||
delete state.timeOffset;
|
||||
});
|
||||
|
@ -1132,7 +1142,7 @@ androidController.performMultiAction = function (elementId, actions, cb) {
|
|||
|
||||
var states = [];
|
||||
async.eachSeries(actions, function (action, done) {
|
||||
this.parseTouch(action, function (err, val) {
|
||||
this.parseTouch(action, true, function (err, val) {
|
||||
if (err) return done(err);
|
||||
|
||||
states.push(val);
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
"use strict";
|
||||
|
||||
var chai = require('chai')
|
||||
, controller_path = '../../lib/devices/android/android-controller.js'
|
||||
, controller = require(controller_path)
|
||||
, _ = require('underscore');
|
||||
|
||||
chai.should();
|
||||
|
||||
describe('android-controller', function () {
|
||||
describe('#parseTouch', function () {
|
||||
describe('given a touch sequence with absolute coordinates', function () {
|
||||
it('should use offsets for moveTo', function (done) {
|
||||
var actions = [ { action: 'press', options: { x: 100, y: 101 } },
|
||||
{ action: 'moveTo', options: { x: 50, y: 51 } },
|
||||
{ action: 'wait', options: { ms: 5000 } },
|
||||
{ action: 'moveTo', options: { x: -40, y: -41 } },
|
||||
{ action: 'release', options: {} } ];
|
||||
controller.parseTouch(actions, false, function (err, touchStates) {
|
||||
touchStates.length.should.equal(4);
|
||||
|
||||
var actions = [{action: 'press', x: 100, y: 101},
|
||||
{action: 'moveTo', x: 150, y: 152},
|
||||
{action: 'wait', x: 150, y: 152},
|
||||
{action: 'moveTo', x: 110, y: 111}];
|
||||
_.each(touchStates, function (state, index) {
|
||||
state.action.should.equal(actions[index].action);
|
||||
state.options.x.should.equal(actions[index].x);
|
||||
state.options.y.should.equal(actions[index].y);
|
||||
});
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -4,7 +4,8 @@ var chai = require('chai')
|
|||
, controller_path = '../../lib/devices/ios/ios-controller.js'
|
||||
, controller = require(controller_path)
|
||||
, createGetElementCommand = controller.createGetElementCommand
|
||||
, getSelectorForStrategy = controller.getSelectorForStrategy;
|
||||
, getSelectorForStrategy = controller.getSelectorForStrategy
|
||||
, _ = require('underscore');
|
||||
|
||||
chai.should();
|
||||
|
||||
|
@ -71,4 +72,27 @@ describe('ios-controller', function () {
|
|||
});
|
||||
});
|
||||
});
|
||||
describe('#parseTouch', function () {
|
||||
describe('given a touch sequence with absolute coordinates', function () {
|
||||
it('should use offsets for moveTo', function (done) {
|
||||
var actions = [ { action: 'press', options: { x: 100, y: 101 } },
|
||||
{ action: 'moveTo', options: { x: 50, y: 51 } },
|
||||
{ action: 'wait', options: { ms: 5000 } },
|
||||
{ action: 'moveTo', options: { x: -40, y: -41 } },
|
||||
{ action: 'release', options: {} } ];
|
||||
controller.parseTouch(actions, function (err, touchStates) {
|
||||
touchStates.length.should.equal(4); // `release` is removed
|
||||
|
||||
var locs = [{x: 100, y: 101}, {x: 150, y: 152}, {x: 150, y: 152}, {x: 110, y: 111}];
|
||||
_.each(touchStates, function (state, index) {
|
||||
var action = state.touch[0];
|
||||
action.x.should.equal(locs[index].x);
|
||||
action.y.should.equal(locs[index].y);
|
||||
});
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче