UNPKG

siesta-lite

Version:

Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers

227 lines (154 loc) 7.64 kB
/* Siesta 5.6.1 Copyright(c) 2009-2022 Bryntum AB https://bryntum.com/contact https://bryntum.com/products/siesta/license */ Role('Siesta.Recorder.Role.CanRecordMouseMove', { does : [ Siesta.Util.Role.CanCalculatePageScroll, Siesta.Recorder.Role.CanSwallowException ], has : { recordMouseMove : true, // used by RootCause, position in page coordinates cursorPosition : Joose.I.Array, // used by RootCause (probably not needed anymore) lastMoveTimestamp : null, // used by RootCause lastMouseMoveEvent : null }, override : { initialize : function () { this.SUPERARG(arguments) this.onBodyMouseMove = this.safeBind(this.onBodyMouseMove); this.onBodyMouseOver = this.safeBind(this.onBodyMouseOver); this.onBodyMouseOut = this.safeBind(this.onBodyMouseOut); }, onStart : function () { this.SUPERARG(arguments); var win = this.window; var doc = win.document; var body = doc.body if (this.recordMouseMove) { // Need to also observe `mouseover` since it's fired before `mousemove` in case there is a crash // in `mousemove` handler we need to know the exact cursor position body.addEventListener('mouseover', this.onBodyMouseOver, true); body.addEventListener('mouseout', this.onBodyMouseOut, true); body.addEventListener('mousemove', this.onBodyMouseMove, true); } }, onStop : function () { this.SUPERARG(arguments); var win = this.window; var doc = win.document; var body = doc.body if (this.recordMouseMove) { body.removeEventListener('mouseover', this.onBodyMouseOver, true); body.removeEventListener('mouseout', this.onBodyMouseOut, true); body.removeEventListener('mousemove', this.onBodyMouseMove, true); this.lastMouseMoveEvent = null } } }, methods : { saveMouseMoveData : function (event) { var me = this me.lastMoveTimestamp = new Date() - 0 me.cursorPosition[ 0 ] = me.viewportXtoPageX(event.clientX, me.window) me.cursorPosition[ 1 ] = me.viewportYtoPageY(event.clientY, me.window) me.lastMouseMoveEvent = event }, onBodyMouseMove : function (e) { // Skip test playback events and mouse moves in frames if ((this.ignoreSynthetic && e.synthetic) || e.target.ownerDocument !== this.window.document) return; this.saveMouseMoveData(e) this.processBodyMouseMove(e) }, processBodyMouseMove : function (e) { }, onBodyMouseOver : function (e) { // Skip test playback events and mouse moves in frames if ((this.ignoreSynthetic && e.synthetic) || e.target.ownerDocument !== this.window.document) return; this.saveMouseMoveData(e) this.processBodyMouseOver(e) }, processBodyMouseOver : function (e) { }, onBodyMouseOut : function (e) { // Skip test playback events and mouse moves in frames if ((this.ignoreSynthetic && e.synthetic) || e.target.ownerDocument !== this.window.document) return; this.saveMouseMoveData(e) this.processBodyMouseOut(e) }, processBodyMouseOut : function (e) { }, targetToPathPoint : function (target) { var pathPoint = [ target.getTargetAsQueryString() ] if (target.getTarget().offset) pathPoint.push.apply(pathPoint, target.getTarget().offset) pathPoint.xy = target.getTargetByType('xy').target return pathPoint }, addPathPoint : function (pathPoints, newPathPoint) { // early exit, in case new path point is query-based if (newPathPoint.length === 3) { pathPoints.push(newPathPoint) return } var lastPathPoint = pathPoints[ pathPoints.length - 1 ] // if new path point is a absolute point (which will be the case for the `useXY` arg // of `addMoveCursorAction` enabled then covert it to relative if (newPathPoint.length === 1 && this.typeOf(newPathPoint[ 0 ]) == 'Array') { var relativePoint = [ newPathPoint[ 0 ][ 0 ] - lastPathPoint.xy[ 0 ], newPathPoint[ 0 ][ 1 ] - lastPathPoint.xy[ 1 ] ] // do nothing if (relativePoint[ 0 ] === 0 && relativePoint[ 1 ] === 0) return relativePoint.xy = newPathPoint[ 0 ] pathPoints.push(relativePoint) } else pathPoints.push(newPathPoint) }, // this method merges several consequent calls to it to `moveCursorAlongPath` action addMoveCursorAction : function (event, targetOverride, useXY) { if (!(event instanceof Siesta.Recorder.Event)) event = Siesta.Recorder.Event.fromDomEvent(event) var lastAction = this.getLastAction() var isMouseMove = lastAction && (lastAction.action === 'moveCursorTo' || lastAction.action === 'moveCursorAlongPath') if (!lastAction || !isMouseMove || !this.recordMouseMovePath) { // defensive coding because of unknown: `lastAction.target` is undefined exception if (lastAction && lastAction.hasTarget() && lastAction.target) { var xy = lastAction.target.getTargetByType('xy') if (xy) { xy = xy.target // do nothing if we already have an action with the same target point // this might happen during our own tests, where we use `drag` command, which // issues "mouseover" for initial and last points if (event.x == xy[ 0 ] && event.y == xy[ 1 ]) return } } var targetOptions = this.getPossibleTargets(event, true, targetOverride, useXY) if (this.lastActionPosition.length === 0 || this.lastActionPosition[0] !== event.rawEvent.clientX || this.lastActionPosition[1] !== event.rawEvent.clientY) { this.addAction({ action : 'moveCursorTo', target : targetOptions, sourceEvent : event, options : event.options }) } } else { var target = new Siesta.Recorder.Target({ targets : this.getPossibleTargets(event, true, targetOverride, useXY) }) if (lastAction.action === 'moveCursorTo') { lastAction.action = 'moveCursorAlongPath' lastAction.value = [ this.targetToPathPoint(lastAction.target) ] lastAction.target = null } this.addPathPoint(lastAction.value, this.targetToPathPoint(target)) this.fireEvent('actionupdate', lastAction) } } } // eof `override` });