UNPKG

siesta-lite

Version:

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

552 lines (450 loc) 26 kB
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>The source code</title> <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" /> <script type="text/javascript" src="../resources/prettify/prettify.js"></script> <style type="text/css"> .highlight { display: block; background-color: #ddd; } </style> <script type="text/javascript"> function highlight() { document.getElementById(location.hash.replace(/#/, "")).className = "highlight"; } </script> </head> <body onload="prettyPrint(); highlight();"> <pre class="prettyprint lang-js">/* Siesta 5.6.1 Copyright(c) 2009-2022 Bryntum AB https://bryntum.com/contact https://bryntum.com/products/siesta/license */ <span id='Siesta-Test-UserAgent-Touch'>/** </span>@class Siesta.Test.UserAgent.Touch This is a mixin, providing the touch events simulation functionality. */ Role(&#39;Siesta.Test.UserAgent.Touch&#39;, { requires : [ &#39;normalizeElement&#39; ], has: { notSupportedWarned : false }, methods: { checkTouchEventsSupport : function () { var supports = Siesta.Project.Browser.FeatureSupport().supports var root = this.getRootTest() if (!supports.TouchEvents &amp;&amp; !supports.PointerEvents &amp;&amp; !supports.MSPointerEvents &amp;&amp; !root.notSupportedWarned) { root.notSupportedWarned = true this.warn(&quot;Touch events are not supported by browser. For Chrome, you can enable them, by launching it with: --args --touch-events&quot;) } }, <span id='Siesta-Test-UserAgent-Touch-method-touchStart'> /** </span> * This method simulates a `touchstart` for the passed target, first waiting to make sure target exists and is reachable * * @param {Siesta.Test.ActionTarget} target Target for this action * @param {Function} callback (optional) A function to call after action. * @param {Object} scope (optional) The scope for the callback * @param {Object} options (optional) Any options that will be used when simulating the event. For information about possible * config options, please see: &lt;https://developer.mozilla.org/en-US/docs/DOM/event.initMouseEvent&gt; * @param {Array} offset (optional) An X,Y offset relative to the target. Example: [20, 20] for 20px or * [&quot;50%&quot;, &quot;100%-2&quot;] to click in the center horizontally and 2px from the bottom edge. */ touchStart : function (target, callback, scope, options, offset, performTargetCheck) { var me = this; this.checkTouchEventsSupport() target = target || this.getCursorPagePosition() if (performTargetCheck !== false &amp;&amp; callback) { this.waitForTargetAndSyncMousePosition( target, offset, this.touchStart, [ target, callback, scope, options, offset, false ] ); return; } var context = this.getNormalizedTopElementInfo(target, true, &#39;tap&#39;, offset); if (!context) { callback &amp;&amp; callback.call(scope || this); return; } return me.runPromiseAsync( new Promise(function (resolve) { me.simulator.touchStart(context.el, offset, options, context), resolve(); }), &#39;touchStart&#39;, callback, scope ) }, <span id='Siesta-Test-UserAgent-Touch-method-touchEnd'> /** </span> * This method simulates a `touchend` for a single active touch * */ touchEnd : function (callback) { var me = this; return me.runPromiseAsync( new Promise(function (resolve) { me.simulator.touchEnd(); resolve(); }), &#39;touchEnd&#39;, callback ) }, <span id='Siesta-Test-UserAgent-Touch-method-tap'> /** </span> * This method taps the passed target, which can be of several different types, see {@link Siesta.Test.ActionTarget} * * @param {Siesta.Test.ActionTarget} target Target for this action * @param {Function} callback (optional) A function to call after action. * @param {Object} scope (optional) The scope for the callback * @param {Object} options (optional) Any options that will be used when simulating the event. For information about possible * config options, please see: &lt;https://developer.mozilla.org/en-US/docs/DOM/event.initMouseEvent&gt; * @param {Array} offset (optional) An X,Y offset relative to the target. Example: [20, 20] for 20px or * [&quot;50%&quot;, &quot;100%-2&quot;] to click in the center horizontally and 2px from the bottom edge. */ tap : function (target, callback, scope, options, offset, performTargetCheck) { this.checkTouchEventsSupport() target = target || this.getCursorPagePosition() if (performTargetCheck !== false &amp;&amp; callback) { this.waitForTargetAndSyncMousePosition( target, offset, this.tap, [ target, callback, scope, options, offset, false ] ); return; } var context = this.getNormalizedTopElementInfo(target, true, &#39;tap&#39;, offset); if (!context) { callback &amp;&amp; callback.call(scope || this); return; } return this.runPromiseAsync( this.simulator.simulateTap(context, options), &#39;tap&#39;, callback, scope ) }, <span id='Siesta-Test-UserAgent-Touch-method-doubleTap'> /** </span> * This method double taps the passed target, which can be of several different types, see {@link Siesta.Test.ActionTarget} * * @param {Siesta.Test.ActionTarget} target Target for this action * @param {Function} callback (optional) A function to call after action. * @param {Object} scope (optional) The scope for the callback * @param {Object} options (optional) Any optionsthat will be used when simulating the event. For information about possible * config options, please see: &lt;https://developer.mozilla.org/en-US/docs/DOM/event.initMouseEvent&gt; * @param {Array} offset (optional) An X,Y offset relative to the target. Example: [20, 20] for 20px or [&quot;50%&quot;, &quot;100%-2&quot;] to click in the center horizontally and 2px from the bottom edge. */ doubleTap : function (target, callback, scope, options, offset, performTargetCheck) { this.checkTouchEventsSupport() target = target || this.getCursorPagePosition() if (performTargetCheck !== false &amp;&amp; callback) { this.waitForTargetAndSyncMousePosition( target, offset, this.doubleTap, [ target, callback, scope, options, offset, false ] ); return; } var context = this.getNormalizedTopElementInfo(target, true, &#39;doubleTap&#39;, offset); if (!context) { callback &amp;&amp; callback.call(scope || this); return; } return this.runPromiseAsync( this.simulator.simulateDoubleTap(context, options), &#39;doubleTap&#39;, callback, scope ) }, // backward-compat with SenchaTouch class, which used to have all lower-cased method longpress : function () { return this.longPress.apply(this, arguments) }, <span id='Siesta-Test-UserAgent-Touch-method-longPress'> /** </span> * This performs a long press on the passed target, which can be of several different types, see {@link Siesta.Test.ActionTarget} * * @param {Siesta.Test.ActionTarget} target Target for this action * @param {Function} callback (optional) A function to call after action. * @param {Object} scope (optional) The scope for the callback * @param {Object} options (optional) Any optionsthat will be used when simulating the event. For information about possible * config options, please see: &lt;https://developer.mozilla.org/en-US/docs/DOM/event.initMouseEvent&gt; * @param {Array} offset (optional) An X,Y offset relative to the target. Example: [20, 20] for 20px or [&quot;50%&quot;, &quot;100%-2&quot;] to click in the center horizontally and 2px from the bottom edge. */ longPress : function (target, callback, scope, options, offset, performTargetCheck) { this.checkTouchEventsSupport() target = target || this.getCursorPagePosition() if (performTargetCheck !== false &amp;&amp; callback) { this.waitForTargetAndSyncMousePosition( target, offset, this.longPress, [ target, callback, scope, options, offset, false ] ); return; } var context = this.getNormalizedTopElementInfo(target, true, &#39;longPress&#39;, offset); if (!context) { callback &amp;&amp; callback.call(scope || this); return; } return this.runPromiseAsync( this.simulator.simulateLongPress(context, options), &#39;longPress&#39;, callback, scope ) }, <span id='Siesta-Test-UserAgent-Touch-method-pinch'> /** </span> * This method performs a pinch between the two specified points. It draws a line between the specified points and then moves 2 touches along that line, * so that the final distance between the touches becomes `scale * original distance`. * * This method can be called either in the full form with 2 different targets: * t.pinch(&quot;#grid &gt; .col1&quot;, &quot;#grid &gt; .col2&quot;, 3, function () { ... }) * or, in the short form, where the 2nd target argument is omitted: * t.pinch(&quot;#grid &gt; .col1&quot;, 3, function () { ... }) * In the latter form, `target2` is considered to be the same as `target1`. * * If `target1` and `target2` are the same, and no offsets are provided, offsets are set to the following values: * offset1 = [ &#39;25%&#39;, &#39;50%&#39; ] offset2 = [ &#39;75%&#39;, &#39;50%&#39; ] * * * @param {Siesta.Test.ActionTarget} target1 First point for pinch * @param {Siesta.Test.ActionTarget} target2 Second point for pinch. Can be omitted, in this case both points will belong to `target1` * @param {Number} scale The multiplier for a final distance between the points * @param {Function} callback A function to call after the pinch has completed * @param {Object} scope A scope for the `callback` * @param {Object} options (optional) Any optionsthat will be used when simulating the event. For information about possible * config options, please see: &lt;https://developer.mozilla.org/en-US/docs/DOM/event.initMouseEvent&gt; * @param {Array} offset1 An X,Y offset relative to the target1. Example: [20, 20] for 20px or [&quot;50%&quot;, &quot;100%-2&quot;] * for the point in the center horizontally and 2px from the bottom edge. * @param {Array} offset2 An X,Y offset relative to the target1. Example: [20, 20] for 20px or [&quot;50%&quot;, &quot;100%-2&quot;] * for the point in the center horizontally and 2px from the bottom edge. */ pinch : function (target1, target2, scale, callback, scope, options, offset1, offset2) { this.checkTouchEventsSupport() var me = this; if (this.typeOf(target2) === &#39;Number&#39;) { offset2 = offset1 offset1 = options options = scope scope = callback callback = scale scale = target2 target2 = target1 } if (target2 == null) target2 = target1 if (target1 === target2 &amp;&amp; !offset1 &amp;&amp; !offset2) { offset1 = [ &#39;25%&#39;, &#39;50%&#39; ] offset2 = [ &#39;75%&#39;, &#39;50%&#39; ] } var context1 = this.getNormalizedTopElementInfo(target1, true, &#39;pinch: target1&#39;, offset1); var context2 = this.getNormalizedTopElementInfo(target2, true, &#39;pinch: target2&#39;, offset2); if (!context1 || !context2) { var R = Siesta.Resource(&#39;Siesta.Test.Browser&#39;); this.waitFor({ method : function () { var el1 = me.normalizeElement(target1, true) var el2 = me.normalizeElement(target2, true) return el1 &amp;&amp; me.elementIsTop(el1, true, offset) &amp;&amp; el2 &amp;&amp; me.elementIsTop(el2, true, offset) }, callback : function () { me.pinch(target1, target2, scope, callback, scope, options, offset1, offset2) }, assertionName : &#39;waitForTarget&#39;, description : &#39; &#39; + R.get(&#39;target&#39;) + &#39; &quot;&#39; + target1 + &#39;&quot; and &quot;&#39; + target2 + &#39;&quot; &#39; + R.get(&#39;toAppear&#39;) }); return } return this.runPromiseAsync( this.simulator.simulatePinch(context1, context2, options), &#39;pinch&#39;, callback, scope ) }, <span id='Siesta-Test-UserAgent-Touch-method-touchDragTo'> /** </span> * This method will simulate a drag and drop operation between either two points or two DOM elements. * * @param {Siesta.Test.ActionTarget} source {@link Siesta.Test.ActionTarget} value for the drag starting point * @param {Siesta.Test.ActionTarget} target {@link Siesta.Test.ActionTarget} value for the drag end point * @param {Function} callback A function to call after the drag operation is completed. * @param {Object} scope (optional) the scope for the callback * @param {Object} options (optional) Any optionsthat will be used when simulating the event. For information about possible * config options, please see: &lt;https://developer.mozilla.org/en-US/docs/DOM/event.initMouseEvent&gt; * @param {Boolean} dragOnly true to skip the mouseup and not finish the drop operation. * @param {Array} sourceOffset (optional) An X,Y offset relative to the source. Example: [20, 20] for 20px or [&quot;50%&quot;, &quot;100%-2&quot;] to click in the center horizontally and 2px from the bottom edge. * @param {Array} targetOffset (optional) An X,Y offset relative to the target. Example: [20, 20] for 20px or [&quot;50%&quot;, &quot;100%-2&quot;] to click in the center horizontally and 2px from the bottom edge. */ touchDragTo : function (source, target, callback, scope, options, dragOnly, sourceOffset, targetOffset) { var me = this var context1 = this.getNormalizedTopElementInfo(source, true, &#39;touchDragTo: source&#39;, sourceOffset); var context2 = this.getNormalizedTopElementInfo(target, true, &#39;touchDragTo: target&#39;, targetOffset); if (!context1 || !context2) { var R = Siesta.Resource(&#39;Siesta.Test.Browser&#39;); this.waitFor({ method : function () { var el1 = me.normalizeElement(source, true) var el2 = me.normalizeElement(target, true) return el1 &amp;&amp; me.elementIsTop(el1, true, sourceOffset) &amp;&amp; el2 &amp;&amp; me.elementIsTop(el2, true, targetOffset) }, callback : function () { me.touchDragTo(source, target, callback, scope, options, dragOnly, sourceOffset, targetOffset) }, assertionName : &#39;waitForTarget&#39;, description : &#39; &#39; + R.get(&#39;target&#39;) + &#39; &quot;&#39; + source + &#39;&quot; and &quot;&#39; + target + &#39;&quot; &#39; + R.get(&#39;toAppear&#39;) }); return } return this.runPromiseAsync( this.simulator.simulateTouchDrag(context1.localXY, context2.localXY, options, dragOnly), &#39;touchDragTo&#39;, callback, scope ) }, <span id='Siesta-Test-UserAgent-Touch-method-touchDragBy'> /** </span> * This method will simulate a drag and drop operation from a point (or DOM element) and move by a delta. * * @param {Siesta.Test.ActionTarget} source {@link Siesta.Test.ActionTarget} value as the drag starting point * @param {Array} delta The amount to drag from the source coordinate, expressed as [ x, y ]. E.g. [ 50, 10 ] will drag 50px to the right and 10px down. * @param {Function} callback A function to call after the drag operation is completed. * @param {Object} scope (optional) the scope for the callback * @param {Object} options (optional) Any optionsthat will be used when simulating the event. For information about possible * config options, please see: &lt;https://developer.mozilla.org/en-US/docs/DOM/event.initMouseEvent&gt; * @param {Boolean} dragOnly true to skip the mouseup and not finish the drop operation. * @param {Array} offset (optional) An X,Y offset relative to the target. Example: [20, 20] for 20px or [&quot;50%&quot;, &quot;100%-2&quot;] to click in the center horizontally and 2px from the bottom edge. */ touchDragBy : function (source, delta, callback, scope, options, dragOnly, offset) { var me = this; var context = this.getNormalizedTopElementInfo(source, true, &#39;touchDragBy&#39;, offset); if (!context) { this.waitForTarget(source, function() { this.touchDragBy(source, delta, callback, scope, options, dragOnly, offset) }, this, null, offset) return } var sourceXY = context.globalXY; var targetXY = [ sourceXY[ 0 ] + delta[ 0 ], sourceXY[ 1 ] + delta[ 1 ] ]; return this.runPromiseAsync( this.simulator.simulateTouchDrag(sourceXY, targetXY, options, dragOnly), &#39;touchDragBy&#39;, callback, scope ) }, <span id='Siesta-Test-UserAgent-Touch-method-movePointerTo'> /** </span> * This method will simulate a move the pointer/finger to the passed target. * * @param {Siesta.Test.ActionTarget} target {@link Siesta.Test.ActionTarget} value for the drag end point * @param {Function} callback A function to call after the drag operation is completed. * @param {Object} scope (optional) the scope for the callback * @param {Object} options (optional) Any optionsthat will be used when simulating the event. For information about possible * config options, please see: &lt;https://developer.mozilla.org/en-US/docs/DOM/event.initMouseEvent&gt; * @param {Array} offset (optional) An X,Y offset relative to the target. Example: [20, 20] for 20px or [&quot;50%&quot;, &quot;100%-2&quot;] to point in the center horizontally and 2px from the bottom edge. */ movePointerTo : function (target, callback, scope, options, offset, performTargetCheck) { var me = this if (performTargetCheck !== false &amp;&amp; callback) { me.waitForTargetAndSyncMousePosition( target, null, me.movePointerTo, [ target, callback, scope, options, offset, false ] ); return; } var context = me.getNormalizedTopElementInfo(target, true, &#39;movePointerTo&#39;, offset); return me.runPromiseAsync( me.simulator.touchMoveTo(context.globalXY, options), &#39;touchMoveTo&#39;, callback, scope ) }, <span id='Siesta-Test-UserAgent-Touch-method-movePointerBy'> /** </span> * This method will simulate moving the pointer/finger by the passed distance. * * @param {Array} delta The amount to drag from the source coordinate, expressed as [ x, y ]. E.g. [ 50, 10 ] will drag 50px to the right and 10px down. * @param {Function} callback A function to call after the drag operation is completed. * @param {Object} scope (optional) the scope for the callback * @param {Object} options (optional) Any optionsthat will be used when simulating the event. For information about possible * config options, please see: &lt;https://developer.mozilla.org/en-US/docs/DOM/event.initMouseEvent&gt; */ movePointerBy : function (delta, callback, scope, options ) { return this.runPromiseAsync( this.simulator.touchMoveBy(delta, options), &#39;touchMoveBy&#39;, callback, scope ); }, <span id='Siesta-Test-UserAgent-Touch-method-swipe'> /** </span> * This method will simulate a swipe operation between either two points or on a single DOM element. * * @param {Siesta.Test.ActionTarget} target Target for this action * @param {String} direction Either &#39;left&#39;, &#39;right&#39;, &#39;up&#39; or &#39;down&#39; * @param {Function} callback A function to call after the swing operation is completed * @param {Object} scope (optional) the scope for the callback * @param {Object} options (optional) Any options that will be used when simulating the event. For information about possible * config options, please see: &lt;https://developer.mozilla.org/en-US/docs/DOM/event.initMouseEvent&gt; */ swipe : function (target, direction, callback, scope, options, performTargetCheck) { this.checkTouchEventsSupport() target = target || this.getCursorPagePosition() if (performTargetCheck !== false &amp;&amp; callback) { this.waitForTargetAndSyncMousePosition( target, null, this.swipe, [ target, direction, callback, scope, options, false ] ); return; } var context = this.getNormalizedTopElementInfo(target, true, &#39;swipe&#39;); if (!context) { callback &amp;&amp; callback.call(scope || this); return; } var Ext = this.Ext() var R = Siesta.Resource(&#39;Siesta.Test.SenchaTouch&#39;) var box = Ext.fly(context.el).getBox(), x = box.x, y = box.y, width = box.width, height = box.height, centerX = x + width / 2, centerY = y + height / 2, start, end, edgeCoef = 0.1 // Since this method accepts elements as target, we need to assure that we swipe at least about 150px // using Math.max below etc switch (direction) { case &#39;u&#39;: case &#39;up&#39;: start = [ centerX, y + height * (1 - edgeCoef) ]; end = [ centerX, y + height * edgeCoef ]; end[ 1 ] = Math.min(start[ 1 ] - 100, end[ 1 ]); break; case &#39;d&#39;: case &#39;down&#39;: start = [ centerX, y + height * edgeCoef ]; end = [ centerX, y + height * (1 - edgeCoef) ]; end[ 1 ] = Math.max(start[ 1 ] + 100, end[ 1 ]); break; case &#39;r&#39;: case &#39;right&#39;: start = [ x + width * edgeCoef, centerY ]; end = [ x + width * (1 - edgeCoef), centerY ]; end[ 0 ] = Math.max(start[ 0 ] + 100, end[ 0 ]); break; case &#39;l&#39;: case &#39;left&#39;: start = [ x + width * (1 - edgeCoef), centerY ]; end = [ x + width * edgeCoef, centerY ]; end[ 0 ] = Math.min(start[ 0 ] - 100, end[ 0 ]); break; default: throw R.get(&#39;invalidSwipeDir&#39;) + &#39;: &#39; + direction; } return this.touchDragTo(start, end, callback, scope, options); } } }); </pre> </body> </html>