UNPKG

siesta-lite

Version:

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

347 lines (269 loc) 13.6 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 */ Role(&#39;Siesta.Test.Simulate.Event&#39;, { does : [ JooseX.Observable ], requires : [ &#39;$&#39;, &#39;typeOf&#39;, &#39;createTextEvent&#39;, &#39;createMouseEvent&#39;, &#39;createKeyboardEvent&#39; ], has : { bowser : function () { return bowser }, browser : function () { return bowser }, actionDelay : 100, afterActionDelay : 100, <span id='global-cfg-simulateEventsWith'> /** </span> * @cfg {String} simulateEventsWith * * This option is IE9-strict mode (and probably above) specific. It specifies, which events simulation function Siesta should use. * The choice is between &#39;dispatchEvent&#39; (W3C standard) and &#39;fireEvent&#39; (MS interface) - both are available in IE9 strict mode * and both activates different event listeners. See this blog post for detailed explanations: * &lt;http://www.digitalenginesoftware.com/blog/archives/76-DOM-Event-Model-Compatibility-or-Why-fireEvent-Doesnt-Trigger-addEventListener.html&gt; * * Valid values are &quot;dispatchEvent&quot; and &quot;fireEvent&quot;. * * The framework specific adapters choose the most appropriate value automatically (unless explicitly configured). */ simulateEventsWith : { is : &#39;rw&#39;, lazy : function () { return &#39;dispatchEvent&#39; } } }, methods : { normalizeEventName : function (eventName) { return eventName }, <span id='global-method-simulateEvent'> /** </span> * This method will simulate an event triggered by the passed element. If no coordinates are supplied in the options object, the center of the element * will be used. * @param {Siesta.Test.ActionTarget} el * @param {String} type The type of event (e.g. &#39;mouseover&#39;, &#39;click&#39;, &#39;keypress&#39;) * @param {Object} the options for the event. See http://developer.mozilla.org/en/DOM/event for reference. */ simulateEvent : function (el, type, options) { var global = this.global; options = options || {}; if (this.typeOf(el) === &#39;Array&#39;) { if (el.length == 0) el = this.currentPosition.slice() if (!(&#39;clientX&#39; in options)) { options.clientX = el[ 0 ]; } if (!(&#39;clientY&#39; in options)) { options.clientY = el[ 1 ]; } } el = this.test.normalizeElement(el); type = this.normalizeEventName(type) var evt = this.createEvent(type, options, el); if (evt) { this.maintainScrollPositionDuring(function () { evt.synthetic = true; this.mimicBrowserBehaviorBefore(evt, type, el); this.dispatchEvent(el, type, evt); !this.isEventPrevented(evt) &amp;&amp; this.mimicBrowserBehaviorAfter(evt, type, el); }) } this.fireEvent(&#39;eventsimulated&#39;, evt, el, type, options) return evt; }, createEvent : function (type, options, el) { var event if (/^textinput$/i.test(type)) { event = this.createTextEvent(type, options, el); } else if (/^mouse(over|out|down|up|move|enter|leave)|contextmenu|wheel|(dbl)?click$/.test(type) || /^(ms)?pointer/i.test(type)) { event = this.createMouseEvent(type, options, el); } else if (/^key(up|down|press)$/.test(type)) { event = this.createKeyboardEvent(type, options, el); } /*else if (/^touch/.test(type)) { return this.createTouchEvent(type, options, el); }*/ else if (/^change$|^input$|^submit/.test(type)) { event = this.createGenericEvent(type, options, el); } else event = this.createHtmlEvent(type, options, el); // IE&gt;=9 somehow reports that &quot;defaultPrevented&quot; property of the event object is `false` // even that &quot;preventDefault()&quot; has been called on the object // more over, immediately after call to &quot;preventDefault()&quot; the property is updated // but down in stack it is replaced with &quot;false&quot; again somehow // we setup our own, additional property, indicating that event has been prevented if (event &amp;&amp; bowser.msie &amp;&amp; bowser.version &gt;= 9) { var prev = event.preventDefault event.preventDefault = function () { arguments.callee.$prevented = true; this.returnValue = false return prev &amp;&amp; prev.apply(this, arguments) } } return event }, isEventPrevented : function (event) { // our custom property - takes highest priority if (event.preventDefault &amp;&amp; this.typeOf(event.preventDefault.$prevented) == &#39;Boolean&#39;) return event.preventDefault.$prevented // W3C standards property if (this.typeOf(event.defaultPrevented) == &#39;Boolean&#39;) return event.defaultPrevented return event.returnValue === false }, createGenericEvent : function (type, options, el) { var doc = el.ownerDocument; if (doc.createEvent &amp;&amp; this.getSimulateEventsWith() == &#39;dispatchEvent&#39;) { var evt = doc.createEvent(&quot;Events&quot;); evt.initEvent(type, true, true); return evt; } else if (doc.createEventObject) { var event = doc.createEventObject() event.srcElement = el event.bubbles = options.bubbles event.cancelBubble = !options.bubbles event.type = type return event } }, createHtmlEvent : function (type, options, el) { var doc = el.ownerDocument; if (doc.createEvent &amp;&amp; this.getSimulateEventsWith() == &#39;dispatchEvent&#39;) { var evt = doc.createEvent(&quot;HTMLEvents&quot;); evt.initEvent(type, false, false); return evt; } else if (doc.createEventObject) { return doc.createEventObject(); } }, dispatchEvent : function (el, type, evt) { // use W3C standard when available and allowed by &quot;simulateEventsWith&quot; option if (el.dispatchEvent &amp;&amp; this.getSimulateEventsWith() == &#39;dispatchEvent&#39;) { el.dispatchEvent(evt); } else if (el.fireEvent) { // IE 6,7,8 can&#39;t dispatch many events cleanly - throws exceptions try { // this is the serios nominant to the best-IE-bug-ever prize and it&#39;s IE7 specific // accessing the &quot;scrollLeft&quot; property on document or body triggers a synchronous(!) &quot;resize&quot; event on the window // ExtJS uses a singleton for Ext.EventObj and its &quot;target&quot; property gets overwritten with &quot;null&quot; // thus consequent event handlers fails // doing an access to that property to cache it var doc = this.global.document.documentElement; var body = this.global.document.body; var xxx = doc &amp;&amp; doc.scrollLeft || body &amp;&amp; body.scrollLeft || 0; el.fireEvent(&#39;on&#39; + type.toLowerCase(), evt); } catch (e) { } // in IE, the &quot;fireEvent&quot; does not bubble the &quot;change&quot; event // we try to bubble it manually (to fix the TaskBoard2.x &quot;subtasks&quot; tests, but then // the target el is not set correctly and it goes too deep into Ext sources, so commenting for now // if (type == &#39;change&#39;) { // if (el != doc &amp;&amp; el != body &amp;&amp; el.parentElement) this.dispatchEvent(el.parentElement, type, evt) // } } else throw &quot;Can&#39;t dispatch event: &quot; + type return evt; }, mimicBrowserBehaviorBefore : function (event, type, target) { }, mimicBrowserBehaviorAfter : function (event, type, target) { var tagName = target.tagName.toLowerCase(); switch (type) { case &#39;mousedown&#39;: // it seems selection is actually cleared in &quot;pointerup&quot; (mouseup) if (this.isTextInput(target)) { this.mimicClearTextSelection(target); } break; case &#39;click&#39;: if ( bowser.msie &amp;&amp; bowser.version &lt; 11 &amp;&amp; tagName === &#39;a&#39; &amp;&amp; target.getAttribute(&quot;href&quot;) ) { this.mimicHashUpdate(target); } else if (tagName === &#39;option&#39; &amp;&amp; !target.getAttribute(&#39;disabled&#39;)) { this.mimicOptionSelect(target); } break; case &#39;dblclick&#39;: if (this.isTextInput(target)) { this.mimicDblClickTextSelection(target); } break; case &#39;keydown&#39;: var KeyCodes = Siesta.Test.UserAgent.KeyCodes().keys if (event.keyCode === KeyCodes.BACKSPACE) { this.mimicHistoryChangeAfterBackspace(event, target); } break; } }, // IE9+ // Breaks IE9 with Ext JS 5.1.0, tested in .540_extjs_type.t.js?5.1.0 mimicClearTextSelection : function (target) { var extVersion = this.global.Ext &amp;&amp; this.global.Ext.versions; var isExtJS51 = extVersion &amp;&amp; extVersion.extjs &amp;&amp; extVersion.extjs.equals(&#39;5.1.0.107&#39;); if (!bowser.msie || !isExtJS51 || (bowser.version &gt; 9)) { this.test.selectText(target, target.value.length - 1, target.value.length); this.test.setCaretPosition(target, target.value.length); } }, mimicDblClickTextSelection : function (target) { this.test.selectText(target); }, // After a click action in old IE, change location hash manually mimicHashUpdate : function (el) { var href = el.getAttribute(&quot;href&quot;).match(/#(.*)/); if (href) { this.global.location.hash = href[1]; } }, mimicHistoryChangeAfterBackspace : function (event, target) { // Chrome+Safari doesn&#39;t trigger page navigation (as of Chrome52) if (bowser.webkit || bowser.blink) return; var doc = target.ownerDocument; if (!target.isContentEditable &amp;&amp; doc.designMode.toLowerCase() !== &quot;on&quot; &amp;&amp; !this.isTextInput(target)) { var elWindow = target.ownerDocument.defaultView || target.ownerDocument.parentWindow; if (event.shiftKey) { this.mimicNextHistory(elWindow); } else { this.mimicPreviousHistory(elWindow); } } }, mimicPreviousHistory : function (global) { global.history.back(); }, mimicNextHistory : function (global) { global.history.forward(); }, mimicOptionSelect : function (optionNode) { var select = this.$(optionNode).closest(&#39;select&#39;)[0]; var oldValue = select.value; select.value = optionNode.value; if (oldValue !== optionNode.value) { this.simulateEvent(select, &quot;change&quot;); } } } }); </pre> </body> </html>