UNPKG

siesta-lite

Version:

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

286 lines (238 loc) 11 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-Action-Wait'>/** </span> @class Siesta.Test.Action.Wait @extends Siesta.Test.Action This action can be included in the `t.chain` call with &quot;wait&quot; or &quot;delay&quot; shortcuts: t.chain( { action : &#39;wait&#39;, // or &quot;delay&quot; delay : 1000 // 1 second } ) Alternatively, for convenience, this action can be included in the chain using &quot;waitFor&quot; config (the &quot;action&quot; property can be omitted): t.chain( { waitFor : &#39;selector&#39;, // or any other waitFor* method name args : [ &#39;.x-grid-row&#39; ] // an array of arguments for the specified method } ) t.chain( { waitFor : &#39;rowsVisible&#39;, // or any other waitFor* method name args : [ grid ] // an array of arguments for the specified method } ) t.chain( { waitFor : &#39;waitForRowsVisible&#39;, // full method name is also ok args : grid // a single value will be converted to array automatically } ) In the latter case, this action will perform a call to the one of the `waitFor*` methods of the test instance. The name of the method is computed by prepending the uppercased value of `waitFor` config with the string &quot;waitFor&quot; (unless it doesn&#39;t already start with &quot;waitFor&quot;). The arguments for method call can be provided as the &quot;args&quot; array. Any non-array value for &quot;args&quot; will be converted to an array with one element. * **Note**, that this action will provide a `callback`, `scope`, and `timeout` arguments for `waitFor*` methods - you should not specify them. As a special case, the value of `waitFor` config can be a Number or Function - that will trigger the call to {@link Siesta.Test#waitFor} method with provided value: t.chain( { waitFor : 500 }, // same as { waitFor : &#39;&#39;, args : [ 500 ] }, { waitFor : function () { return document.body.className.match(/someClass/) } } ) */ Class(&#39;Siesta.Test.Action.Wait&#39;, { isa : Siesta.Test.Action, has : { <span id='Siesta-Test-Action-Wait-cfg-delay'> /** </span> * @cfg {Number} delay * * A number of milliseconds to wait before continuing. */ delay : 1000, <span id='Siesta-Test-Action-Wait-cfg-timeout'> /** </span> * @cfg {Number} timeout * * The maximum amount of time to wait for the condition to be fulfilled. Defaults to the {@link Siesta.Test.ExtJS#waitForTimeout} value. */ timeout : null, <span id='Siesta-Test-Action-Wait-cfg-interval'> /** </span> * @cfg {Number} interval * * The interval between the checks for condition. Default value is 100ms. */ interval : null, <span id='Siesta-Test-Action-Wait-cfg-args'> /** </span> * @cfg {Array/Function} args * * The array of arguments to pass to waitForXXX method. You should omit the 3 last parameters: callback, scope, timeout. Any non-array value will be converted to * a single-value array. Can be also a function, returning either an array of a single value, which will be converted to array. * Function will be called using test instance as a &quot;this&quot; scope. * If you need to pass a function, as an argument, wrap in the array. Compare: { waitFor : &#39;SomeCondition&#39;, // will be called when processing the action, should return an array of arguments args : function () {} } { waitFor : &#39;SomeCondition&#39;, // won&#39;t be called, instead will be passed as 1st argument args : [ function () {} ] } * */ args : Joose.I.Array, <span id='Siesta-Test-Action-Wait-cfg-waitFor'> /** </span> * @cfg {String} waitFor * * The name of the `waitFor` method to call. You can omit the leading &quot;waitFor&quot;: * t.chain( { waitFor : &#39;selector&#39;, ... }, // same as { waitFor : &#39;waitForSelector&#39;, ... } ) * */ waitFor : null, <span id='Siesta-Test-Action-Wait-cfg-trigger'> /** </span> * @cfg {Object/Function} trigger * * A config object for the action that should trigger the waiting condition. Can be also a regular function to execute. * An action or function will be executed right *after* the waiting has started, to avoid the race conditions. * * To illustrate, imagine, when clicking on some button, new data package will be loaded and some event `dataloaded` * will be fired. We want to wait for that event. Usually, you will write this as the following action steps, in the `chain` method: * t.chain( { click : &#39;.someButton&#39; }, { waitFor : &#39;Event&#39;, args : [ someDataStorage, &#39;dataload&#39; ] }, ... ) * However, imagine loading mechanism implements caching, and sometimes loading happens *synchronously*. In this case, * the `dataload` event will be also fired synchronously, right during the &quot;onclick&quot; handler of the button. Then, we&#39;ll start * waiting for that event (which has already been fired) and the `waitFor` action will fail. * * To avoid this race condition, we need to first start waiting for the event, and only then - perform a click: * t.chain( function (next) { t.waitForEvent(someDataStorage, &#39;dataload&#39;, next); t.click(&#39;.someButton&#39;, function () {}) }, ... ) * or, using `trigger` config: t.chain( { waitFor : &#39;Event&#39;, args : [ someDataStorage, &#39;dataload&#39; ], trigger : { click : &#39;.someButton&#39; } }, ... ) */ trigger : null, hasOwnAsyncFrame : true, description : &#39;&#39; // used internally to have custom wait messages that don&#39;t produce noise in the UI (chain step automatically adds a t.pass with &#39;desc&#39;) }, methods : { process : function () { var waitFor = this.waitFor; var test = this.test if (test.typeOf(waitFor) === &#39;Number&#39; || test.typeOf(waitFor) === &#39;Function&#39;) { // Caller supplied a function returning true when done waiting or // a number of milliseconds to wait for. this.args = [ waitFor ]; waitFor = &#39;&#39;; } if (waitFor == null) { this.args = [ this.delay ]; waitFor = &#39;&#39;; } // special case for { waitForFn : function () {} }&quot; - we consider the function here // not a function which should return an array with arguments for the &quot;waitFor&quot; method // (which is a usual behavior for { someMehthod : function () {} } ), but the `waitFor` checker function itself if (test.typeOf(this.args) === &quot;Function&quot; &amp;&amp; waitFor != &#39;waitForFn&#39;) { this.args = this.args.call(test, this); } if (test.typeOf(this.args) !== &quot;Array&quot;) { this.args = [ this.args ]; } // also allow full method names waitFor = waitFor.replace(/^waitFor/, &#39;&#39;) var methodName = &#39;waitFor&#39; + Joose.S.uppercaseFirst(waitFor); if (!test[ methodName ]){ throw Siesta.Resource(&quot;Siesta.Test.Action.Wait&quot;, &#39;missingMethodText&#39;) + methodName; } // If using simple waitFor statement, use the object notation to be able to pass a description // which gives better debugging help than &quot;Waited too long for condition to be fulfilled&quot;. if (methodName === &#39;waitFor&#39;) { test.waitFor({ method : this.args[ 0 ], callback : this.next, scope : test, timeout : this.timeout || test.waitForTimeout, interval : this.interval, description : this.description || this.desc || &#39;&#39; }); } else { test[ methodName ].apply(test, this.args.concat(this.next, test, this.timeout || test.waitForTimeout)); } var trigger = this.trigger if (trigger) { if (test.typeOf(trigger) == &#39;Function&#39;) trigger.call(test, test) else { if (!(trigger instanceof Siesta.Test.Action)) { trigger.next = function () {} trigger.test = this.test trigger = Siesta.Test.ActionRegistry().create(trigger, test) } trigger.process() } } } } }); Joose.A.each([ &#39;wait&#39;, &#39;waitFor&#39;, &#39;delay&#39; ], function(name) { Siesta.Test.ActionRegistry().registerAction(name, Siesta.Test.Action.Wait); });</pre> </body> </html>