Skip to content

Commit

Permalink
add support of event.screenX and event.screenY properties (closes Dev…
Browse files Browse the repository at this point in the history
…Express#2325) (DevExpress#2353)

* [WIP]add support of event.screenX and event.screenY properties

* fix ugly code

* rewrite tests

* skip in mobile browsers

* fix obj is null problem

* remove functional test
  • Loading branch information
AlexKamaev authored and kirovboris committed Dec 18, 2019
1 parent 3561478 commit eebfa3f
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 4 deletions.
6 changes: 4 additions & 2 deletions src/client/automation/playback/click/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,14 +214,16 @@ export default class ClickAutomation extends VisibleElementAutomation {

return this
._ensureElement(useStrictElementCheck)
.then(({ element, clientPoint, screenPoint }) => {
.then(({ element, clientPoint, screenPoint, devicePoint }) => {
eventArgs = {
point: clientPoint,
screenPoint: screenPoint,
element: element,
options: extend({
clientX: clientPoint.x,
clientY: clientPoint.y
clientY: clientPoint.y,
screenX: devicePoint.x,
screenY: devicePoint.y
}, this.modifiers)
};

Expand Down
4 changes: 4 additions & 0 deletions src/client/automation/playback/move/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import cursor from '../../cursor';
import { underCursor as getElementUnderCursor } from '../../get-element';
import getAutomationPoint from '../../utils/get-automation-point';
import getLineRectIntersection from '../../utils/get-line-rect-intersection';
import getDevicePoint from '../../utils/get-device-point';
import nextTick from '../../utils/next-tick';
import AutomationSettings from '../../settings';

Expand Down Expand Up @@ -271,10 +272,13 @@ export default class MoveAutomation {
_emulateEvents (currentElement) {
var whichButton = this.holdLeftButton ? eventUtils.WHICH_PARAMETER.leftButton : eventUtils.WHICH_PARAMETER.noButton;
var button = this.holdLeftButton ? eventUtils.BUTTONS_PARAMETER.leftButton : eventUtils.BUTTONS_PARAMETER.noButton;
var devicePoint = getDevicePoint({ x: this.x, y: this.y });

var eventOptions = {
clientX: this.x,
clientY: this.y,
screenX: devicePoint.x,
screenY: devicePoint.y,
button: 0,
which: browserUtils.isWebKit ? whichButton : 1,
buttons: button,
Expand Down
4 changes: 3 additions & 1 deletion src/client/automation/playback/rclick.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,15 @@ export default class RClickAutomation extends VisibleElementAutomation {

return this
._ensureElement(useStrictElementCheck)
.then(({ element, clientPoint }) => {
.then(({ element, clientPoint, devicePoint }) => {
eventArgs = {
point: clientPoint,
element: element,
options: extend({
clientX: clientPoint.x,
clientY: clientPoint.y,
screenX: devicePoint.x,
screenY: devicePoint.y,
button: eventUtils.BUTTON.right,
which: eventUtils.WHICH_PARAMETER.rightButton,
buttons: eventUtils.BUTTONS_PARAMETER.rightButton
Expand Down
5 changes: 4 additions & 1 deletion src/client/automation/playback/visible-element-automation.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import hammerhead from '../deps/hammerhead';
import { delay, positionUtils, domUtils, arrayUtils, serviceUtils } from '../deps/testcafe-core';
import getAutomationPoint from '../utils/get-automation-point';
import screenPointToClient from '../utils/screen-point-to-client';
import getDevicePoint from '../utils/get-device-point';
import { fromPoint as getElementFromPoint } from '../get-element';
import AUTOMATION_ERROR_TYPES from '../errors';
import AutomationSettings from '../settings';
Expand All @@ -18,6 +19,7 @@ class ElementState {
this.screenPoint = screenPoint;
this.isTarget = isTarget;
this.inMoving = inMoving;
this.devicePoint = getDevicePoint(clientPoint);
}
}

Expand Down Expand Up @@ -130,7 +132,8 @@ export default class VisibleElementAutomation extends serviceUtils.EventEmitter
return {
element: state.element,
clientPoint: state.clientPoint,
screenPoint: state.screenPoint
screenPoint: state.screenPoint,
devicePoint: state.devicePoint
};
});
}
Expand Down
11 changes: 11 additions & 0 deletions src/client/automation/utils/get-device-point.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function getDevicePoint (clientPoint) {
if (!clientPoint)
return null;

const screenLeft = window.screenLeft || window.screenX;
const screenTop = window.screenTop || window.screenY;
const x = screenLeft + clientPoint.x;
const y = screenTop + clientPoint.y;

return { x, y };
}
76 changes: 76 additions & 0 deletions test/client/fixtures/automation/regression-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ var hammerhead = window.getTestCafeModule('hammerhead');
var browserUtils = hammerhead.utils.browser;
var featureDetection = hammerhead.utils.featureDetection;
var nativeMethods = hammerhead.nativeMethods;
var Promise = hammerhead.Promise;

var testCafeCore = window.getTestCafeModule('testCafeCore');
var eventUtils = testCafeCore.get('./utils/event');
Expand All @@ -16,6 +17,7 @@ var TypeOptions = testCafeAutomation.get('../../test-run/commands/options').Typ
var MouseOptions = testCafeAutomation.get('../../test-run/commands/options').MouseOptions;

var ClickAutomation = testCafeAutomation.Click;
var RClickAutomation = testCafeAutomation.RClick;
var DblClickAutomation = testCafeAutomation.DblClick;
var HoverAutomation = testCafeAutomation.Hover;
var TypeAutomation = testCafeAutomation.Type;
Expand Down Expand Up @@ -611,6 +613,80 @@ $(document).ready(function () {
});
});

if (!browserUtils.isIOS && !browserUtils.isAndroid) {
asyncTest('GH-2325 - mouse events should have e.screenX and e.screenY properties', function () {
var promises = [];
var screenLeft = window.screenLeft || window.screenX;
var screenTop = window.screenTop || window.screenY;
var el = document.createElement('div');
var mouseOutEl = document.createElement('div');

el.innerHTML = 'Click me';
el.className = TEST_ELEMENT_CLASS;
mouseOutEl.innerHTML = 'Hover me';
mouseOutEl.className = TEST_ELEMENT_CLASS;

document.body.appendChild(el);
document.body.appendChild(mouseOutEl);

var checkEventScreenXYOptions = function (eventName) {
var resolveFn;

promises.push(new Promise(function (resolve) {
resolveFn = resolve;
}));

var handler = function (e) {
ok(e.screenX > 0);
ok(e.screenY > 0);
equal(e.screenX, e.clientX + screenLeft);
equal(e.screenY, e.clientY + screenTop);

resolveFn();
el.removeEventListener(eventName, handler);
};

return handler;
};

var addEventListener = function (eventName) {
el.addEventListener(eventName, checkEventScreenXYOptions(eventName));
};

addEventListener('mousemove');
addEventListener('mouseenter');
addEventListener('mouseover');
addEventListener('mousedown');
addEventListener('mouseup');
addEventListener('click');
addEventListener('mouseout');
addEventListener('mouseleave');
addEventListener('contextmenu');
addEventListener('dblclick');

var click = new ClickAutomation(el, { offsetX: 5, offsetY: 5 });
var rClick = new RClickAutomation(el, { offsetX: 5, offsetY: 5 });
var dblClick = new DblClickAutomation(el, { offsetX: 5, offsetY: 5 });
var mouseOut = new ClickAutomation(mouseOutEl, { offsetX: 5, offsetY: 5 });

click.run()
.then(function () {
return mouseOut.run();
})
.then(function () {
return rClick.run();
})
.then(function () {
return dblClick.run();
})
.then(function () {
Promise.all(promises).then(function () {
startNext();
});
});
});
}

if (browserUtils.isIE) {
//TODO: fix it for other browsers
asyncTest('Unexpected focus events are raised during click', function () {
Expand Down

0 comments on commit eebfa3f

Please sign in to comment.