siesta-lite
Version:
Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers
1 lines • 36.6 kB
JavaScript
Ext.data.JsonP.getting_started_browser({"guide":"<h1 id='getting_started_browser-section-getting-started-with-siesta-in-browser-environment'>Getting started with Siesta in browser environment</h1>\n<div class='toc'>\n<p><strong>Contents</strong></p>\n<ol>\n<li><a href='#!/guide/getting_started_browser-section-installation'>Installation</a></li>\n<li><a href='#!/guide/getting_started_browser-section-siesta-browser-project'>Siesta browser project</a></li>\n<li><a href='#!/guide/getting_started_browser-section-testing-specific-web-page'>Testing specific web page</a></li>\n<li><a href='#!/guide/getting_started_browser-section-sandboxing.-test-page-vs-project-web-interface-page'>Sandboxing. Test page vs project web-interface page</a></li>\n<li><a href='#!/guide/getting_started_browser-section-configuring-the-project'>Configuring the project</a></li>\n<li><a href='#!/guide/getting_started_browser-section-configuring-the-individual-test'>Configuring the individual test</a></li>\n<li><a href='#!/guide/getting_started_browser-section-using-ecma-modules'>Using Ecma modules</a></li>\n<li><a href='#!/guide/getting_started_browser-section-simulating-user-interaction'>Simulating user interaction</a></li>\n<li><a href='#!/guide/getting_started_browser-section-user-actions-recorder'>User actions recorder</a></li>\n<li><a href='#!/guide/getting_started_browser-section-structuring-the-test-suite'>Structuring the test suite</a></li>\n<li><a href='#!/guide/getting_started_browser-section-extending-the-test-class'>Extending the test class</a></li>\n<li><a href='#!/guide/getting_started_browser-section-launchers-and-reports'>Launchers and reports</a></li>\n<li><a href='#!/guide/getting_started_browser-section-code-coverage'>Code coverage</a></li>\n<li><a href='#!/guide/getting_started_browser-section-assertions'>Assertions</a></li>\n<li><a href='#!/guide/getting_started_browser-section-testing-asynchronous-code'>Testing asynchronous code</a></li>\n<li><a href='#!/guide/getting_started_browser-section-detecting-global-variable-leaks'>Detecting global variable leaks</a></li>\n<li><a href='#!/guide/getting_started_browser-section-%22todo%22-assertions'>\"TODO\" assertions</a></li>\n<li><a href='#!/guide/getting_started_browser-section-limitations-'>Limitations </a></li>\n<li><a href='#!/guide/getting_started_browser-section-buy-this-product'>Buy this product</a></li>\n<li><a href='#!/guide/getting_started_browser-section-support'>Support</a></li>\n<li><a href='#!/guide/getting_started_browser-section-see-also'>See also</a></li>\n<li><a href='#!/guide/getting_started_browser-section-attribution'>Attribution</a></li>\n<li><a href='#!/guide/getting_started_browser-section-copyright-and-license'>COPYRIGHT AND LICENSE</a></li>\n</ol>\n</div>\n\n<p>Siesta is a stress-free JavaScript unit and UI-testing tool. It is known that change of activity is a form of rest,\nso stop writing code, write some tests and have some rest! Your application will win from both.</p>\n\n<p>Siesta is very easy to learn and as your test suite grows and your requirements becomes more complex it still scales very well.</p>\n\n<p>Siesta is also cross-platform - the same tests can run in browsers and NodeJS, on Linux, MacOs and Windows\n(assuming of course they are written in a platform-independent manner). Headless browser modes are supported.</p>\n\n<p><p><img src=\"guides/getting_started_browser/images/demo.png\" alt=\"autogen\" width=\"1600\" height=\"1200\"></p></p>\n\n<p>In this guide, we assume a setup, pointed toward running tests in browsers.</p>\n\n<p>For the setup, targeting NodeJS environment, please refer to this guide <a href=\"#!/guide/getting_started_nodejs\">Siesta getting started with NodeJS.</a></p>\n\n<h2 id='getting_started_browser-section-installation'>Installation</h2>\n\n<p>Siesta Lite is <a href=\"https://www.npmjs.com/package/siesta-lite\">published in npm</a>, so it can be installed with:</p>\n\n<pre><code>> npm install siesta-lite\n</code></pre>\n\n<p>Siesta Standard is distributed as plain archive file, you just unpack it in the preferred location.</p>\n\n<h2 id='getting_started_browser-section-siesta-browser-project'>Siesta browser project</h2>\n\n<p>Since plain browsers can't access the file system, we need to start with creation of the Siesta project - a single place for storing the meta-information\nabout your test suite.</p>\n\n<pre><code>const project = new <a href=\"#!/api/Siesta.Project.Browser\" rel=\"Siesta.Project.Browser\" class=\"docClass\">Siesta.Project.Browser</a>();\n\nproject.configure({\n title : 'Basic browser test suite',\n\n preload : [\n 'https://code.jquery.com/jquery-1.6.4.min.js'\n ]\n});\n\nproject.plan(\n '010_sanity.t.js',\n '020_basic.t.js'\n);\n\nproject.start();\n</code></pre>\n\n<p>Lets save this file as <code>siesta.js</code> in the <code>tests</code> folder of your app. We'll need a wrapping html file for this project too, to be able to access\nthe web interface, lets name it <code>siesta.html</code>:</p>\n\n<pre><code><!DOCTYPE html>\n<html>\n <head>\n <!-- Recommended set of pragmas, required for IE11 compatibility-->\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no\">\n\n <!-- Web interface -->\n <link rel=\"stylesheet\" type=\"text/css\" href=\"__SIESTA_FOLDER__/resources/css/siesta-all.css\">\n <script type=\"text/javascript\" src=\"__SIESTA_FOLDER__/siesta-all.js\"></script>\n\n <!-- Project file -->\n <script type=\"text/javascript\" src=\"siesta.js\"></script>\n </head>\n\n <body>\n </body>\n</html>\n</code></pre>\n\n<p>As you've probably already guessed, we've created a project with 2 test files: <code>010_sanity.t.js</code> and <code>020_basic.t.js</code>.\n<strong>The paths in project file, are relative to the <code>siesta.html</code> wrapper file</strong></p>\n\n<p>Lets check how the test file look itself:</p>\n\n<pre><code>StartTest(t => {\n\n t.it(\"Sanity\", t => {\n\n t.ok($, 'jQuery is here');\n\n t.is(1, \"1\", \"Relaxed equality\")\n\n t.exact(1, 1, \"Exact equality\")\n\n t.is(1, t.anyNumberApprox(0.95, 0.1), \"Fuzzy equality\")\n\n t.like(window.location.href, /010_sanity\\.t\\.js/, \"Location of the test file is as expected\")\n\n t.throwsOk(\n () => { vixie },\n /vixie/,\n \"Correct exception thrown\"\n )\n });\n}) \n</code></pre>\n\n<p>The test code is wrapped with <code>StartTest(t => { ... })</code> construct. The function passed to it will receive an instance\nof the <a href=\"#!/api/Siesta.Test.Browser\" rel=\"Siesta.Test.Browser\" class=\"docClass\">Siesta.Test.Browser</a> class, as the 1st argument.</p>\n\n<p>Alternative wrapper form is supported:</p>\n\n<pre><code class=\"javascript\">describe('Test case name', t => {\n t.it(\"Sanity\", t => {\n ...\n });\n}) \n</code></pre>\n\n<p>The instance of the test class has various <em>assertion</em> methods. An \"assertion\" is any statement about your code,\nwhich can be either truthy (we say \"assertion pass\") or false (assertion fail). It may have arbitrary meaning,\nranging from very simple like \"this variable is equal to that variable\" to complex and domain specific:\n\"this instance of EventEmitter will fire this event exactly N times during the following X milliseconds\".</p>\n\n<p>Siesta has many general-purpose assertions built-in and it also allows you to <a href=\"#!/guide/extending_test_class\">create your own assertions.</a></p>\n\n<p>In the example above we use the simplest possible assertion: <code>t.ok(value, description)</code>. It passes when the provided <code>value</code> is \"truthy\",\nlike : <code>true</code>, <code>1</code>, <code>{}</code> etc and fails otherwise. Each assertion also has an optional description which should contain\nan explanation of what's being asserted.</p>\n\n<p>We also used <code>throwsOk</code> assertion, which, accepts a function, run it, and verify that it does throw exception, which serializes to the string,\nmatching a given <code>RegExp</code>. You've probably get the idea.</p>\n\n<p>To see the list of all <strong>generic</strong> assertions, supported by Siesta, please refer to: <a href=\"#!/api/Siesta.Test\" rel=\"Siesta.Test\" class=\"docClass\">Siesta.Test</a> class.</p>\n\n<p>For the list of <strong>browser-specific</strong> assertions, please refer to: <a href=\"#!/api/Siesta.Test.Browser\" rel=\"Siesta.Test.Browser\" class=\"docClass\">Siesta.Test.Browser</a> class.</p>\n\n<p>Ok, we now have a project file, a web-interface wrapper for it, and test file. Lets open the <code>siesta.html</code> file in a browser.</p>\n\n<p class=\"side-note\">\nWhile it is possible to use file-system only setup, using `file://` urls, it is not recommended, as support for it varies per browser\nand some features may be different from normal `http://` setup. \n<br><br>\nThe recommended way is to use a local web server on your machine. For a simple, zero-configuration one, just to serve the static files, you can check\nthis Node package: <a href=\"https://www.npmjs.com/package/local-web-server\">https://www.npmjs.com/package/local-web-server</a>\n<br><br>\nSo, the browser url should look like: http://localhost/yourproject/tests/siesta.html\n</p>\n\n\n<p>You should see something like this:</p>\n\n<p><p><img src=\"guides/getting_started_browser/images/synopsys.png\" alt=\"autogen\" width=\"800\" height=\"600\"></p></p>\n\n<p>Click the \"Run all\" button in the toolbar. Notice, how the <code>010_sanity.t.js</code> test gains a green checkmark, indicating it has completed successfully,\nwithout failing assertions.</p>\n\n<p>The <code>020_basic.t.js</code> has a red cross indicating the file is missing - feel free to create it after reading a couple of the following sections :)</p>\n\n<h2 id='getting_started_browser-section-testing-specific-web-page'>Testing specific web page</h2>\n\n<p>The sample test file above assumes a unit testing approach - you specify what files to preload and a new web page is constructed and test launched on it.\nSometimes though, you might want to test a code on the already created web page. This is common for the functional (or acceptance) testing.\nTo do this, you can use the <a href=\"#!/api/Siesta.Project.Browser-cfg-pageUrl\" rel=\"Siesta.Project.Browser-cfg-pageUrl\" class=\"docClass\">pageUrl</a> config. See below about using the configuration options.</p>\n\n<h2 id='getting_started_browser-section-sandboxing.-test-page-vs-project-web-interface-page'>Sandboxing. Test page vs project web-interface page</h2>\n\n<p>By default, <a href=\"#!/api/Siesta.Project.Browser-cfg-sandbox\" rel=\"Siesta.Project.Browser-cfg-sandbox\" class=\"docClass\">sandboxing</a> is enabled. Every test is launched in isolated browser JavaScript context. Isolation is\ndone using iframes or <a href=\"#!/api/Siesta.Project.Browser-cfg-runInPopup\" rel=\"Siesta.Project.Browser-cfg-runInPopup\" class=\"docClass\">popups</a>. In general, there is no need to cleanup anything after the test.</p>\n\n<p>This behavior is configurable with the <a href=\"#!/api/Siesta.Project.Browser-cfg-sandbox\" rel=\"Siesta.Project.Browser-cfg-sandbox\" class=\"docClass\">sandbox</a> option, but we recommend to keep it enabled\nuntil you start feeling comfortable with Siesta.</p>\n\n<p>One need to understand the difference between the test page - the iframe in which the test will be launched, and the project page - the web-interface\npage. These are not related, and run different code.</p>\n\n<p>Typical mistake is to include the files from your application to the web-interface page:</p>\n\n<pre><code><!-- Web interface -->\n<link rel=\"stylesheet\" type=\"text/css\" href=\"__SIESTA_FOLDER__/resources/css/siesta-all.css\">\n<script type=\"text/javascript\" src=\"__SIESTA_FOLDER__/siesta-all.js\"></script>\n\n<!-- WRONG, web-interface does not need files from your projects -->\n<link rel=\"stylesheet\" type=\"text/css\" href=\"my/project/styles.css\">\n<script type=\"text/javascript\" src=\"my/project/bundle.js\"></script>\n\n<!-- Project file -->\n<script type=\"text/javascript\" src=\"siesta.js\"></script>\n</code></pre>\n\n<p>In the same manner don't include the Siesta files in the <a href=\"#!/api/Siesta.Project.Browser-cfg-preload\" rel=\"Siesta.Project.Browser-cfg-preload\" class=\"docClass\">preload</a> option:</p>\n\n<pre><code>project.configure({\n title : 'Awesome Test Suite',\n\n preload : [\n '../../siesta-all.js', // WRONG, no need to include siesta files on the test page\n '../my-app-all.js'\n ]\n});\n</code></pre>\n\n<h2 id='getting_started_browser-section-configuring-the-project'>Configuring the project</h2>\n\n<p>A project can be configured with the <a href=\"#!/api/Siesta.Project.Browser-method-configure\" rel=\"Siesta.Project.Browser-method-configure\" class=\"docClass\">configure</a> method, which can be called several times.\nSee the <a href=\"#!/api/Siesta.Project.Browser\" rel=\"Siesta.Project.Browser\" class=\"docClass\">Siesta.Project.Browser</a> for a detailed description of all available options.\nThe most important option is <a href=\"#!/api/Siesta.Project.Browser-cfg-preload\" rel=\"Siesta.Project.Browser-cfg-preload\" class=\"docClass\">preload</a>, which defines\nthe files that should be pre-loaded for each test. All urls in <a href=\"#!/api/Siesta.Project.Browser-cfg-preload\" rel=\"Siesta.Project.Browser-cfg-preload\" class=\"docClass\">preload</a> config\nare relative to the project html wrapper file <code>siesta.html</code>.</p>\n\n<p>You can add test files to the project using the <a href=\"#!/api/Siesta.Project.Browser-method-plan\" rel=\"Siesta.Project.Browser-method-plan\" class=\"docClass\">plan</a> method, which can be called several times.</p>\n\n<p>Note, that the project file contains regular javascript code, so you can configure it\ndifferently, depending on various conditions. Siesta includes <a href=\"https://github.com/ded/bowser\">Bowser</a>\nlibrary for browser detection, so you can for example mute some tests for certain browsers:</p>\n\n<pre><code>var isDev = window.location.href.match(/localhost/);\nvar project = new <a href=\"#!/api/Siesta.Project.Browser\" rel=\"Siesta.Project.Browser\" class=\"docClass\">Siesta.Project.Browser</a>()\n\nproject.configure({\n title : 'Awesome Test Suite',\n\n preload : [\n isDev ? '../ext-4.0.6/ext-all-debug.js' : '../ext-4.0.6/ext-all.js',\n isDev ? '../yourproject-all-debug.js' : '../yourproject-all.js'\n ]\n});\n\nproject.plan('some_test_for_all_browsers.t.js')\n\nif (!bowser.msie) project.plan('some_test_for_all_browsers_except_IE.t.js');\n\nproject.start()\n</code></pre>\n\n<p>Once the project is fully configured, you can launch it with the <a href=\"#!/api/Siesta.Project.Browser-method-start\" rel=\"Siesta.Project.Browser-method-start\" class=\"docClass\">start</a> method.</p>\n\n<p>As your test suite grows, you may need to start grouping your tests in a logical hierarchy. You can do this by passing special\n\"test file descriptor\" instead of the string to the <a href=\"#!/api/Siesta.Project.Browser-method-plan\" rel=\"Siesta.Project.Browser-method-plan\" class=\"docClass\">plan</a> method.\nThe descriptor should contain a group name and an array of child descriptors:</p>\n\n<pre><code>project.plan(\n '011_single.t.js',\n {\n group : 'Rendering tests',\n\n items : [\n 'rendering/grid.t.js',\n 'rendering/tree.t.js'\n ]\n }\n);\n</code></pre>\n\n<p>In turn, child descriptors can be groups as well. This feature is especially useful, when you need to override the\n<a href=\"#!/api/Siesta.Project.Browser\" rel=\"Siesta.Project.Browser\" class=\"docClass\">project</a> options for some group of tests (see the following section).</p>\n\n<p>See also <a href=\"#!/api/Siesta.Project.Browser-method-plan\" rel=\"Siesta.Project.Browser-method-plan\" class=\"docClass\">Siesta.Project.Browser.plan</a> method for additional information.</p>\n\n<h2 id='getting_started_browser-section-configuring-the-individual-test'>Configuring the individual test</h2>\n\n<p>When configuring a \"test file descriptor\", one can also provide some of the project configuration options and they\nwill override the corresponding options that were provided to the project.\nSuch options are explicitly marked in the <a href=\"#!/api/Siesta.Project.Browser\" rel=\"Siesta.Project.Browser\" class=\"docClass\">project</a> documentation.\nFor example, one can have a test with its own <code>preload</code> and <code>autoCheckGlobals</code> configs:</p>\n\n<pre><code>project.configure({\n autoCheckGlobals : false\n ...\n})\n\nproject.plan(\n {\n url : '011_simple.t.js',\n\n autoCheckGlobals : true,\n preload : [\n ...\n ]\n },\n '012_complex.t.js'\n)\n</code></pre>\n\n<p>When specifying config options for a group descriptor, these options will override the configuration for all child descriptors of that group:</p>\n\n<pre><code>project.plan(\n {\n group : 'On demand loading',\n\n // will override the `preload` option for all tests in this group\n preload : [\n ...\n ],\n\n items : [\n ...\n ]\n }\n)\n</code></pre>\n\n<p>You can also provide test file descriptor in the test file itself, by adding it to the StartTest call:</p>\n\n<pre><code>StartTest({\n autoCheckGlobals : false\n}, t => {\n ...\n}) \n</code></pre>\n\n<p>Values from this object takes the highest priority and will override any other configuration.</p>\n\n<p>See also <a href=\"#!/api/Siesta.Project.Browser-method-plan\" rel=\"Siesta.Project.Browser-method-plan\" class=\"docClass\">Siesta.Project.Browser.plan</a> method for additional information.</p>\n\n<h2 id='getting_started_browser-section-using-ecma-modules'>Using Ecma modules</h2>\n\n<p>Virtually all modern browsers already supports Ecma modules, which is very convenient way of structuring the dependencies. To use an Ecma\nmodule as the test file, use the <a href=\"#!/api/Siesta.Project.Browser-cfg-isEcmaModule\" rel=\"Siesta.Project.Browser-cfg-isEcmaModule\" class=\"docClass\">isEcmaModule</a> config:</p>\n\n<pre><code>project.plan(\n 'regular_script.t.js',\n { url: 'ecma-module.t.js', isEcmaModule: true }\n)\n</code></pre>\n\n<p>Then, inside the test file, you can use <code>import/export</code> normally:</p>\n\n<pre><code>import {value} from './lib/ecmamodule.js'\n\nStartTest(t => {\n t.is(value, 1, 'Imported correct');\n});\n</code></pre>\n\n<h2 id='getting_started_browser-section-simulating-user-interaction'>Simulating user interaction</h2>\n\n<p>Siesta can simulate user interactions such as <a href=\"#!/api/Siesta.Test.Browser-method-click\" rel=\"Siesta.Test.Browser-method-click\" class=\"docClass\">click</a>, <a href=\"#!/api/Siesta.Test.Browser-method-doubleClick\" rel=\"Siesta.Test.Browser-method-doubleClick\" class=\"docClass\">double click</a>,\n<a href=\"#!/api/Siesta.Test.Browser-method-type\" rel=\"Siesta.Test.Browser-method-type\" class=\"docClass\">type</a>, <a href=\"#!/api/Siesta.Test.Browser-method-dragBy\" rel=\"Siesta.Test.Browser-method-dragBy\" class=\"docClass\">drag-drop</a> etc.</p>\n\n<p>Mouse simulating user actions are listed here: <a href=\"#!/api/Siesta.Test.UserAgent.Mouse\" rel=\"Siesta.Test.UserAgent.Mouse\" class=\"docClass\">Siesta.Test.UserAgent.Mouse</a></p>\n\n<p>Keyboard simulating user actions are listed here: <a href=\"#!/api/Siesta.Test.UserAgent.Keyboard\" rel=\"Siesta.Test.UserAgent.Keyboard\" class=\"docClass\">Siesta.Test.UserAgent.Keyboard</a></p>\n\n<p>Touch simulating user actions are listed here: <a href=\"#!/api/Siesta.Test.UserAgent.Touch\" rel=\"Siesta.Test.UserAgent.Touch\" class=\"docClass\">Siesta.Test.UserAgent.Touch</a></p>\n\n<p>By default Siesta uses synthetic events simulation, which is very fast. To speed it up even further, check the\n<a href=\"#!/api/Siesta.Project.Browser-cfg-mouseMovePrecision\" rel=\"Siesta.Project.Browser-cfg-mouseMovePrecision\" class=\"docClass\">mouseMovePrecision</a> option.</p>\n\n<p>In some cases, however, you may need to test some intrinsic browser behavior which synthetic events can not reproduce.\nMost notable example will be testing the <code>:hover</code> CSS styles of some DOM elements.\nIn such case you can use native events simulation</p>\n\n<p>Keep in mind, for tests involving mouse interaction - you should not move the mouse during the execution of such test,\nto not interfere with simulation.</p>\n\n<h2 id='getting_started_browser-section-user-actions-recorder'>User actions recorder</h2>\n\n<p>You can also record user actions as Siesta test. Please refer to this guide: <a href=\"#!/guide/event_recorder\">Using the event recorder.</a></p>\n\n<h2 id='getting_started_browser-section-structuring-the-test-suite'>Structuring the test suite</h2>\n\n<p>Siesta supports BDD syntax for structuring your tests. Please refer to this guide for more information:\n<a href=\"#!/guide/structuring_test_suite\">Structuring the test suite</a></p>\n\n<h2 id='getting_started_browser-section-extending-the-test-class'>Extending the test class</h2>\n\n<p>Quite often you may find yourself repeating various initialization code in your tests. Or you may need your own assertions,\nspecific to your data. To avoid repetition, you can extend the default Siesta test class by adding own methods to it.</p>\n\n<p>Please refer to <a href=\"#!/guide/extending_test_class\">Extending test class</a> guide to know more.</p>\n\n<h2 id='getting_started_browser-section-launchers-and-reports'>Launchers and reports</h2>\n\n<p>You can launch your browser project from the command line, in various browsers / browser automation environments and\ngenerate reports with test suite results.</p>\n\n<p>Please refer to <a href=\"#!/guide/siesta_launchers\">Siesta launchers & reports</a> guide for more information.</p>\n\n<h2 id='getting_started_browser-section-code-coverage'>Code coverage</h2>\n\n<p>Please refer to <a href=\"#!/guide/code_coverage\">Code coverage</a> guide.</p>\n\n<h2 id='getting_started_browser-section-assertions'>Assertions</h2>\n\n<p>Some assertions are generic and cross platform - they belong to the <a href=\"#!/api/Siesta.Test\" rel=\"Siesta.Test\" class=\"docClass\">Siesta.Test</a> class. Others are browser specific - and those are\nlisted in the <a href=\"#!/api/Siesta.Test.Browser\" rel=\"Siesta.Test.Browser\" class=\"docClass\">Siesta.Test.Browser</a> class.</p>\n\n<p>When an assertion passes - it shows a green checkmark with the assertion description (if description is not provided, Siesta will try to generate\na sensible default text). When it fails, it also tries to provide you with as much information about the failure as possible, including the\narguments passed to the assertion method. This is why you are encouraged to use various special assertions for each specific case. For example,\nlets say we would like to check if one value is greater than other. We could do that with a simple:</p>\n\n<pre><code>t.ok(value1 > value2, 'Value1 is greater than value2')\n</code></pre>\n\n<p>But in case of a failure, the only additional information you will see will be something like:</p>\n\n<pre><code>Failed assertion [ok] at line xxx, \nGot : false, \nNeed : \"truthy\" value\"\n</code></pre>\n\n<p>Compare with the output from the more specific \"isGreater\" assertion:</p>\n\n<pre><code>t.isGreater(value1, value2, 'Value1 is greater than value2')\n</code></pre>\n\n<p>It will output the message along with the provided arguments, instantly making it clear what happened:</p>\n\n<pre><code>Failed assertion [isGreater] at line xxx, \nGot : value1, \nNeed, greater than : value2\n</code></pre>\n\n<p>So make sure you've scanned the documentation <a href=\"#!/api/Siesta.Test\" rel=\"Siesta.Test\" class=\"docClass\">Siesta.Test</a> or <a href=\"#!/api/Siesta.Test.Browser\" rel=\"Siesta.Test.Browser\" class=\"docClass\">Siesta.Test.Browser</a> - doing so will save you a lot of time.</p>\n\n<h2 id='getting_started_browser-section-testing-asynchronous-code'>Testing asynchronous code</h2>\n\n<p>Siesta is fine-tuned to allow easy testing of asynchronous code. There are several ways to do it.</p>\n\n<p>One way, is to return a <code>Promise</code> from the test function. Siesta will wait until that promise is resolved/rejected, before\nfinalizing the test. Using the <code>async/await</code> syntax (which just de-sugars to the <code>Promise</code> returned from the function) it may look like this:</p>\n\n<pre><code>let someAsyncOperation = () => new Promise((resolve, reject) => {\n setTimeout(() => resolve(42), 1000)\n})\n\nt.it('Doing async stuff', async t => {\n let res = await someAsyncOperation()\n\n t.is(res, 42, \"Async stuff finished correctly\")\n})\n\n// same thing \nt.it('Doing async stuff', t => {\n return someAsyncOperation().then(() => {\n t.is(res, 42, \"Async stuff finished correctly\")\n })\n})\n</code></pre>\n\n<p>Sometimes, you need to explicitly explain to Siesta, that test need to wait the finalization of some asynchronous code block. For that,\nindicate the beginning of the asynchronous code with <a href=\"#!/api/Siesta.Test-method-beginAsync\" rel=\"Siesta.Test-method-beginAsync\" class=\"docClass\">beginAsync</a> method. This method returns an \"asynchronous frame\" handler.\nThen, once the async code is complete, use <a href=\"#!/api/Siesta.Test-method-endAsync\" rel=\"Siesta.Test-method-endAsync\" class=\"docClass\">endAsync</a> method with the frame handler from the <code>beginAsync</code>.</p>\n\n<p>For example:</p>\n\n<pre><code>let async = t.beginAsync();\n\nAjax.request({\n url : 'ajax_demo/sample.json',\n\n success : function (response, opts) {\n t.is(response, 'foobar', 'Response is correct');\n\n t.endAsync(async);\n },\n\n failure : function (response, opts) {\n t.fail(\"request failed\");\n\n t.endAsync(async);\n }\n});\n</code></pre>\n\n<p>You can start as many asynchronous code \"frames\" as you need. By default, all frames will be forced to finalize\nafter the <a href=\"#!/api/Siesta.Project-cfg-defaultTimeout\" rel=\"Siesta.Project-cfg-defaultTimeout\" class=\"docClass\">Siesta.Project.defaultTimeout</a> seconds, so the whole test will not get stuck in case of unexpected failures.\nYou can configure this interval in the <a href=\"#!/api/Siesta.Test-method-beginAsync\" rel=\"Siesta.Test-method-beginAsync\" class=\"docClass\">beginAsync</a>.</p>\n\n<h3 id='getting_started_browser-section-chaining'>Chaining</h3>\n\n<p>Many methods of the test class are asynchronous, accept a callback and returns a <code>Promise</code>. A typical scenario is to execute one such method after another,\nemulating user actions.</p>\n\n<p>When using old-good callbacks, the nesting level can grow very quickly and affect the readability:</p>\n\n<pre><code>t.type(userNameField, 'username', function () {\n t.type(passwordField, 'secret', function () {\n t.click(loginButton, function () {\n })\n })\n})\n</code></pre>\n\n<p>Promises makes the things a bit better, but code still looks cluttered:</p>\n\n<pre><code>t.type(userNameField, 'username').then(() => {\n return t.type(passwordField, 'secret')\n}).then(() => {\n return t.type(passwordField, 'secret')\n}).then(() => {\n return t.click(loginButton)\n})\n</code></pre>\n\n<p>If you see such code in your tests, make sure you've checked the <a href=\"#!/api/Siesta.Test-method-chain\" rel=\"Siesta.Test-method-chain\" class=\"docClass\">chain</a> method. It allows you to keep the nesting at minimum,\nas in Promises variant:</p>\n\n<pre><code>t.chain(\n next => {\n t.type(userNameField, 'username', next)\n },\n next => {\n t.type(passwordField, 'secret', next)\n },\n next => {\n t.click(loginButton, next)\n }\n})\n</code></pre>\n\n<p>and, supports compact notation, resulting in most readable code:</p>\n\n<pre><code>t.chain(\n { type : 'username', target : userNameField },\n { type : 'secret', target : passwordField },\n { click : loginButton }\n)\n</code></pre>\n\n<h3 id='getting_started_browser-section-waiting'>Waiting</h3>\n\n<p>Since the nature of web applications is very asynchronous (Ajax calls, animations, etc.), be prepared to wait a lot in your tests.\nTo wait for a condition, do:</p>\n\n<pre><code>this.waitFor(\n // The condition to check for, this line will mean waiting \n // until the presence of #foo element in the documented \n () => document.getElementById('foo'), \n\n // The callback, after the condition has been fulfilled\n el => { /* DO COOL STUFF WITH el */ } \n);\n</code></pre>\n\n<p>You will find lots and lots of waitForXXX methods in the API to assist you in various situations, example:</p>\n\n<pre><code>t.waitForSelector('.some_class', () => {\n // Found it\n});\n\nsetTimeout(() => {\n // this fulfills the condition,\n // and the waitFor's callback function is called\n document.body.className = 'some_class'\n}, 1000); \n</code></pre>\n\n<p>You can also wait in a chain, by adding a \"waitFor\" step with a value equal to XXX of any waitForXXX command as the value:</p>\n\n<pre><code>t.chain({\n { waitFor : 'selector', args : ['.some_class'] }, // calls waitForSelector which waits until \n // the some_class CSS class exists in the DOM\n\n { waitFor : 500 }, // waits for 500 ms\n\n { waitFor : 'elementVisible', args : [ someEl ] }, // calls waitForElementVisible and waits \n // for an element to become visible\n });\n</code></pre>\n\n<h2 id='getting_started_browser-section-detecting-global-variable-leaks'>Detecting global variable leaks</h2>\n\n<p>Siesta has a special built-in assertion, called <a href=\"#!/api/Siesta.Test-method-verifyGlobals\" rel=\"Siesta.Test-method-verifyGlobals\" class=\"docClass\">t.verifyGlobals()</a>. It will scan\nthe global properties of the test context (<code>window</code> object in browsers), and compare them with the properties of a\nclean and fresh context. In case it finds any \"unexpected\" globals it will report them as a test failure.</p>\n\n<p>You can specify your list of \"expected\" globals, using the <a href=\"#!/api/Siesta.Project.Browser-cfg-expectedGlobals\" rel=\"Siesta.Project.Browser-cfg-expectedGlobals\" class=\"docClass\">expectedGlobals</a> configuration\noption, or by using the <a href=\"#!/api/Siesta.Test-method-expectGlobals\" rel=\"Siesta.Test-method-expectGlobals\" class=\"docClass\">t.expectGlobals</a> method of your test.</p>\n\n<p>You can enable this assertion to be executed automatically at the end of each test, by setting <a href=\"#!/api/Siesta.Project.Browser-cfg-autoCheckGlobals\" rel=\"Siesta.Project.Browser-cfg-autoCheckGlobals\" class=\"docClass\">autoCheckGlobals</a>\nto true on the project configuration.</p>\n\n<p>For example, in project:</p>\n\n<pre><code>project.configure({\n autoCheckGlobals : true,\n expectedGlobals : [ 'Ext', 'MyProject' ],\n ...\n});\n</code></pre>\n\n<p>And then in tests:</p>\n\n<pre><code>// will suppress the complaints about these globals\nt.expectGlobals('Additional', 'Globals');\n</code></pre>\n\n<h2 id='getting_started_browser-section-%22todo%22-assertions'>\"TODO\" assertions</h2>\n\n<p>Sometimes, you might want to mark some assertions in a test as \"TODO\". For example, you might start to write a test covering an edge case,\nbut only fully implement it later. It's still desirable to run such assertions (sometimes they can accidentally start passing actually),\nbut if they fail - that doesn't mean a failure of the whole test.</p>\n\n<p>In such cases you can wrap your assertions using the <a href=\"#!/api/Siesta.Test-method-todo\" rel=\"Siesta.Test-method-todo\" class=\"docClass\">t.todo()</a> method:</p>\n\n<pre><code>t.todo('Scheduled for 4.1.x release', t => {\n let treePanel = new Ext.tree.Panel()\n\n t.is(treePanel.getView().store, treePanel.store, \"NodeStore and TreeStore have been merged and there's only 1 store now\");\n})\n</code></pre>\n\n<p>The <code>todo</code> method starts a special sub-test (see <a href=\"#!/guide/structuring_test_suite\">Structuring the test suite</a> guide), in which\nthe failing assertions are considered not harmful for the overall suite.</p>\n\n<p>See also <a href=\"#!/api/Siesta.Test-method-snooze\" rel=\"Siesta.Test-method-snooze\" class=\"docClass\">snooze</a> method, with which you can \"snooze\" some sub-test, or assertion group till certain date:</p>\n\n<pre><code>// allow an assertion to fail until a certain date\nt.snooze(new Date(2016, 0, 1), t => {\n // TODO fix this soon\n t.expect(1).toBe(2);\n});\n</code></pre>\n\n<h2 id='getting_started_browser-section-limitations-'>Limitations </h2>\n\n<p>Please note that the test page is limited by the same-origin policy as any other web page. You can include scripts/CSS from another domain,\nbut XHR requests on older browsers are restricted to the same domain.</p>\n\n<p>The best approach is to run the test suite on the same domain as your application, by placing your tests in one of the deploy directories\nduring the staging deploys.</p>\n\n<p>You can also configure a server side proxy.</p>\n\n<h2 id='getting_started_browser-section-buy-this-product'>Buy this product</h2>\n\n<p>Visit our store: <a href=\"https://bryntum.com/store/siesta\">https://bryntum.com/store/siesta</a></p>\n\n<h2 id='getting_started_browser-section-support'>Support</h2>\n\n<p>Ask question in our community forum: <a href=\"https://www.bryntum.com/forum/viewforum.php?f=20\">https://www.bryntum.com/forum/viewforum.php?f=20</a></p>\n\n<p>Subscribers can post expedited questions in Premium Forum: <a href=\"https://www.bryntum.com/forum/viewforum.php?f=21\">https://www.bryntum.com/forum/viewforum.php?f=21</a></p>\n\n<p>Please report any bugs through the web interface at <a href=\"https://www.assembla.com/spaces/bryntum/support/tickets\">https://www.assembla.com/spaces/bryntum/support/tickets</a></p>\n\n<h2 id='getting_started_browser-section-see-also'>See also</h2>\n\n<p>Siesta web-page: <a href=\"https://bryntum.com/products/siesta\">https://bryntum.com/products/siesta</a></p>\n\n<p>Other Bryntum products: <a href=\"https://bryntum.com/products\">https://bryntum.com/products</a></p>\n\n<h2 id='getting_started_browser-section-attribution'>Attribution</h2>\n\n<p>This software contains icons from the following icon packs (licensed under Creative Common 2.5/3.0 Attribution licenses)</p>\n\n<ul>\n<li><a href=\"http://www.famfamfam.com/lab/icons/silk/\">http://www.famfamfam.com/lab/icons/silk/</a></li>\n<li><a href=\"http://led24.de/iconset/\">http://led24.de/iconset/</a></li>\n<li><a href=\"http://p.yusukekamiyamane.com/\">http://p.yusukekamiyamane.com/</a></li>\n<li><a href=\"http://rrze-icon-set.berlios.de/index.html\">http://rrze-icon-set.berlios.de/index.html</a></li>\n<li><a href=\"http://www.smashingmagazine.com/2009/05/20/flavour-extended-the-ultimate-icon-set-for-web-designers/\">http://www.smashingmagazine.com/2009/05/20/flavour-extended-the-ultimate-icon-set-for-web-designers/</a></li>\n<li><a href=\"http://www.doublejdesign.co.uk/products-page/icons/super-mono-icons/\">http://www.doublejdesign.co.uk/products-page/icons/super-mono-icons/</a></li>\n<li><a href=\"http://pixel-mixer.com/\">http://pixel-mixer.com/</a></li>\n</ul>\n\n\n<p>Thanks a lot to the authors of the respective icons packs.</p>\n\n<h2 id='getting_started_browser-section-copyright-and-license'>COPYRIGHT AND LICENSE</h2>\n\n<p>Copyright (c) 2009-2022, Bryntum & Nickolay Platonov</p>\n\n<p>All rights reserved.</p>\n","title":"Browser environment"});