UNPKG

siesta-lite

Version:

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

1 lines 16.8 kB
Ext.data.JsonP.event_recorder({"guide":"<h1 id='event_recorder-section-using-the-event-recorder'>Using the event recorder</h1>\n<div class='toc'>\n<p><strong>Contents</strong></p>\n<ol>\n<li><a href='#!/guide/event_recorder-section-setup'>Setup</a></li>\n<li><a href='#!/guide/event_recorder-section-the-event-recorder-interface'>The event recorder interface</a></li>\n<li><a href='#!/guide/event_recorder-section-recording-user-actions'>Recording user actions</a></li>\n<li><a href='#!/guide/event_recorder-section-recorder-configuration'>Recorder configuration</a></li>\n<li><a href='#!/guide/event_recorder-section-editing-the-target-locator'>Editing the target locator</a></li>\n<li><a href='#!/guide/event_recorder-section-race-conditions.-waiting-for-asynchronous-operations'>Race conditions. Waiting for asynchronous operations</a></li>\n<li><a href='#!/guide/event_recorder-section-the-function-step'>The function step</a></li>\n<li><a href='#!/guide/event_recorder-section-recording-a-move-cursor-to-step'>Recording a move-cursor-to step</a></li>\n<li><a href='#!/guide/event_recorder-section-getting-the-generated-source-code'>Getting the generated source code</a></li>\n<li><a href='#!/guide/event_recorder-section-buy-this-product'>Buy this product</a></li>\n<li><a href='#!/guide/event_recorder-section-support'>Support</a></li>\n<li><a href='#!/guide/event_recorder-section-see-also'>See also</a></li>\n<li><a href='#!/guide/event_recorder-section-copyright-and-license'>COPYRIGHT AND LICENSE</a></li>\n</ol>\n</div>\n\n<p>Event recorder is a component of Siesta, that records the user actions, and then generates a corresponding Siesta <a href=\"#!/api/Siesta.Test-method-chain\" rel=\"Siesta.Test-method-chain\" class=\"docClass\">chain</a> call.</p>\n\n<p>For example, when user click some DOM element, a corresponding <code>{ click : '.selector' }</code> action will be recorded, containing\na selector, for the element clicked.</p>\n\n<p>Siesta always tries to find the shortest and most stable selector, uniquely identifying the target element of the action.\nBe aware however, that if you change the markup of your application, the selectors inside the test should be updated too.</p>\n\n<h2 id='event_recorder-section-setup'>Setup</h2>\n\n<p>In this guide, we'll be using the sample React application <a href=\"https://github.com/pankajladhar/GFontsSpace\">Google Fonts Space</a>\nIt is bundled in the Siesta examples in the directory <code>examples/react-google-fonts-space</code>.</p>\n\n<p>To complete the setup of the example, run in the console, inside the example folder:</p>\n\n<pre><code>&gt; npm install\n</code></pre>\n\n<p>And then to launch the server-side part of the example:</p>\n\n<pre><code>&gt; npm run start-siesta\n</code></pre>\n\n<p>This should open a Chrome window, pointing to application - <code>http://localhost:3000/</code>. Siesta web interface will be available at <code>http://localhost:3000/siesta.html</code></p>\n\n<h2 id='event_recorder-section-the-event-recorder-interface'>The event recorder interface</h2>\n\n<p>To activate the recorder in the Siesta web interface, click the video camera button in the top-right toolbar.</p>\n\n<p><p><img src=\"guides/event_recorder/images/recorder1.png\" alt=\"\" width=\"490\" height=\"540\"></p></p>\n\n<p>In the top left, the buttons are quite self explanatory: <code>Record</code>, <code>Stop</code>, <code>Play</code>, <code>Clear actions</code> and <code>Add action</code>.\nIn the top right section, there are <code>Show source</code> and <code>Close</code> buttons.</p>\n\n<p>The grid has 3 columns:</p>\n\n<ul>\n<li>The 'Action' column is the type of action.</li>\n<li>The 'Target/Value' column contains the either the target of a UI action, the value\n(when typing text) or source code for the special function step.</li>\n<li>The 'Offset' column allows you to set an offset for your action allowing you to click at a precise point inside your target.</li>\n</ul>\n\n\n<h2 id='event_recorder-section-recording-user-actions'>Recording user actions</h2>\n\n<p>Recorder operates in two modes - recording of the web page, and recording of the Siesta test.</p>\n\n<h3 id='event_recorder-section-recording-actions-from-the-web-page'>Recording actions from the web page</h3>\n\n<p>To record actions on the web page, you need to place Siesta web interface on the same host (and port) as the page itself.\nThis is because Siesta is limited by the same-origin policy enforced by all web browsers.</p>\n\n<p>Alternatively, you can disable web-security and same-origin policy, by launching Chrome with special options,\nas described in <a href=\"#!/guide/cross_page_testing\">this guide</a></p>\n\n<p>In our case, both the Siesta web interface and the page are available on <code>http://localhost:3000</code>, so everything is fine.</p>\n\n<p>So, we open the Siesta web interface at <code>http://localhost:3000/siesta.html</code>, hit the recorder button and type the URL of the target page into the <code>Page URL</code> field:\n<code>http://localhost:3000</code></p>\n\n<p><p><img src=\"guides/event_recorder/images/pageUrlField.png\" alt=\"autogen\" width=\"980\" height=\"90\"></p></p>\n\n<p>Hit ENTER in that field, and the web page will (re)loads in the DOM view. You should see something like this:</p>\n\n<p><p><img src=\"guides/event_recorder/images/siesta-web-interface.jpg\" alt=\"\" width=\"1280\" height=\"692\"></p></p>\n\n<p>Now hit the <code>Record</code> button and start interacting with the web page normally,\nusing mouse and keyboard. You will see the action entries show up in the recorder grid. Once you are done, hit <code>Record</code> again, to stop recording.</p>\n\n<p>After recording, ensure that the test case does what you expect by replaying it with the <code>Play</code> button. The web page will be reloaded\nand the recorded user actions will be replayed on it.</p>\n\n<p>To avoid having one huge flat list of actions, you can also group actions together in \"sub-tests\" sections, by marking them and right clicking\nto enter the name of the group. We recommend to create logical groups in the recorded tests, to make the whole test easier to maintain.</p>\n\n<p>Once you are happy with the result you can click the \"Show source\" to get the test source. Then you can create a new test file and paste the content into it.</p>\n\n<p>For example we've recorded a sample scenario, of typing two different strings \"Something\" and \"Something else\" in different colors.</p>\n\n<pre><code class=\"javascript\">describe(\"New recording...\", function(t) {\n t.it(\"First text box\", function(t) {\n t.chain(\n { click : \"#root textarea\" },\n\n { type : \"S\", target : \"#root textarea\", options : { shiftKey : true, readableKey : \"S\", key : \"S\" } },\n\n { type : \"omething\", target : \"#root textarea\" },\n\n { click : \"#root .ColorOption__ForeGround .ColorPicker__Color\" },\n\n { click : \"#root [title='\\#D0021B']\" },\n\n { click : \"#root :textEquals(Compare)\" }\n );\n });\n\n t.it(\"Second text box\", function(t) {\n t.chain(\n { click : \"#root .TextBoxContainer &gt; div:nth-of-type(2) textarea\" },\n\n { type : \"S\", target : \"#root .isActive textarea\", options : { shiftKey : true, readableKey : \"S\", key : \"S\" } },\n\n { type : \"omething ese[BACKSPACE][BACKSPACE]lse\", target : \"#root .isActive textarea\" },\n\n { click : \"#root .ColorOption__ForeGround .ColorPicker__Color\" },\n\n { click : \"#root [title='\\#BD10E0']\" }\n );\n });\n});\n</code></pre>\n\n<p>We can place it as a new test <code>compare.t.js</code> test in the <code>/src/tests/blackbox-app</code> folder. We'll also need to add a test descriptor\nto the Siesta project plan:</p>\n\n<pre><code class=\"javascript\">{\n group : 'Black box tests',\n\n pageUrl : 'index.html',\n\n items : [\n ...\n './TRANSPILED/src/tests/blackbox-app/compare.t.js'\n ]\n}\n</code></pre>\n\n<h3 id='event_recorder-section-recording-actions-from-the-siesta-test'>Recording actions from the Siesta test</h3>\n\n<p>This is very similar to testing a web page, but instead of loading a page - the test code will create a page to interact with.</p>\n\n<p>So, first write some code in the test, which will produce the web page you want to interact with:</p>\n\n<pre><code class=\"javascript\"> describe('Test case name', t =&gt; {\n document.body.innerHTML = '&lt;input type=\"text\"&gt;'\n });\n</code></pre>\n\n<p>Then, run that test in the web interface, to execute the code and receive the desired state of the test page. Now you can record actions on\nthe created page as described in the previous section, just don't enter anything in the <code>Page URL</code> field and click <code>Record</code> right away.</p>\n\n<h2 id='event_recorder-section-recorder-configuration'>Recorder configuration</h2>\n\n<p>Recorder has various configuration options, listed in <a href=\"#!/api/Siesta.Recorder.Recorder\" rel=\"Siesta.Recorder.Recorder\" class=\"docClass\">Siesta.Recorder.Recorder</a> class. To specify these options, use the\n<a href=\"#!/api/Siesta.Project.Browser-cfg-recorderConfig\" rel=\"Siesta.Project.Browser-cfg-recorderConfig\" class=\"docClass\">recorderConfig</a> option of the Siesta browser project, there's also <a href=\"#!/api/Siesta.Project.Browser-cfg-recorderClass\" rel=\"Siesta.Project.Browser-cfg-recorderClass\" class=\"docClass\">recorderClass</a>:</p>\n\n<pre><code class=\"javascript\">project.configure({\n ...\n\n recorderConfig : {\n recordInitialWindowSize : true\n }\n});\n</code></pre>\n\n<h2 id='event_recorder-section-editing-the-target-locator'>Editing the target locator</h2>\n\n<p>All fields in the recorder grid are editable, so it's easy to adjust the values inline. Clicking a <code>Target</code> cell allows you to either choose one of\nthe alternatives gathered by the recorder, or you can type any value you like. As you type, Siesta will try to highlight the target.</p>\n\n<p><p><img src=\"guides/event_recorder/images/editing_target.png\" alt=\"autogen\" width=\"1496\" height=\"1200\"></p></p>\n\n<h2 id='event_recorder-section-race-conditions.-waiting-for-asynchronous-operations'>Race conditions. Waiting for asynchronous operations</h2>\n\n<p>As you will see, just recording some clicks on the screen and playing them back, sometimes won't work.\nThis is because user interface usually contains asynchronous behavior, which takes undetermined amount of time.</p>\n\n<p>Let's say the test scenario is to click a button to load a client list into some <code>&lt;div&gt;</code>. After the data is fetched, we want to assert\nthat the list is updated correctly and contains some text. The recorded script will look just</p>\n\n<pre><code>// Start loading data\n{ click : \"input[value=Load data]\" },\n\n{ click : \"...\" },\n</code></pre>\n\n<p>We insert a function step, to verify that text <code>Client A</code> has appeared inside the <code>#client_list</code> element:</p>\n\n<pre><code class=\"javascript\">StartTest(t =&gt; {\n document.body.innerHTML = '&lt;div id=\"client_list\"&gt;&lt;/div&gt;'\n + '&lt;input id=\"button\" type=\"button\" value=\"Load data\" /&gt;'\n\n\n document.getElementById('button').addEventListener('click', () =&gt; {\n // fetch new data - this takes undetermined time\n fetch('http://server/customers/get').then(() =&gt; {\n // update the UI with new data\n });\n });\n\n t.chain(\n // Start loading data\n { click : 'input[value=\"Load data\"]' },\n\n next =&gt; {\n t.contentLike(document.getElementById('client_list'), 'Client A')\n },\n\n ...\n ) \n});\n</code></pre>\n\n<p>But this test will be failing, because, most probably the data fetch will be taking some time, but the next step in chain will be executed immediately,\nwithout taking in-progress actions into account.</p>\n\n<p>Better and more robust solution would be to use the <a href=\"#!/api/Siesta.Test.Browser-method-waitForContentLike\" rel=\"Siesta.Test.Browser-method-waitForContentLike\" class=\"docClass\">waitForContentLike</a> assertion method.\nIt waits for condition we exactly need - until the content of the given DOM element matches some string. In fact, we don't even need\na function step for this:</p>\n\n<pre><code class=\"javascript\">// Start loading data\n{ click : \"input[value=Load data]\" },\n\n{ waitFor : 'ContentLike', args : [ '#client_list', 'Client A' ] }\n</code></pre>\n\n<p>You can wait for arbitrary condition, with the <a href=\"#!/api/Siesta.Test-method-waitFor\" rel=\"Siesta.Test-method-waitFor\" class=\"docClass\">waitFor</a> test class method.\nUsing \"waitFor\" in the chain described here: <a href=\"#!/api/Siesta.Test.Action.Wait\" rel=\"Siesta.Test.Action.Wait\" class=\"docClass\">Siesta.Test.Action.Wait</a>.</p>\n\n<p>Now the test will be robust, as it will be waiting for the asynchronous action to complete. It does not matter whether the data fetching\nwill take 10ms or 10000ms to complete. However, all waiting actions are supposed to complete\nwithin <a href=\"#!/api/Siesta.Project-cfg-waitForTimeout\" rel=\"Siesta.Project-cfg-waitForTimeout\" class=\"docClass\">waitForTimeout</a> time, to avoid stucking.</p>\n\n<p>Waiting actions can be added in the Recorder UI too. Click the '+' button to add the new action, then use a drop-down in the <code>Action</code> cell.</p>\n\n<h2 id='event_recorder-section-the-function-step'>The function step</h2>\n\n<p>As you interact with your application UI you most likely want to verify some assertions along the way or execute some arbitrary code.\nWhile this is easier to do add in your own IDE, we've added a simple code editor to the recorder too, which allows you to create\na function step in the scenario - which will just execute that function.</p>\n\n<p>To add such step, click the cell in the <code>Action</code> column, select the <code>fn</code> action in the list and hit <code>TAB</code>. Now we can execute any JS code,\nand use <a href=\"#!/api/Siesta.Test\" rel=\"Siesta.Test\" class=\"docClass\">Siesta.Test</a> assertion methods.</p>\n\n<h2 id='event_recorder-section-recording-a-move-cursor-to-step'>Recording a move-cursor-to step</h2>\n\n<p>Sometimes you want to just move the cursor to certain place on the screen without doing any further action. Since the recorder doesn't record every\nmouse movement, there is a special way to signal to Siesta that you want to move the cursor somewhere.</p>\n\n<p>Move the mouse to where it should be and leave it for 3 seconds, you'll then see a <strong>moveCursorTo</strong> action added to the list.</p>\n\n<p>This is useful in lots of scenarios, for example when triggering a menu item to show. You cannot click the menu item right away,\nsince it's hidden until you move the cursor over the menu header.</p>\n\n<h2 id='event_recorder-section-getting-the-generated-source-code'>Getting the generated source code</h2>\n\n<p>When you are done with your recording actions, hit the <code>Show source</code> button and copy-paste the contents into your test file. That is all it takes\nto generate a test.</p>\n\n<p><p><img src=\"guides/event_recorder/images/recorder_generated_code.png\" alt=\"autogen\" width=\"1200\" height=\"800\"></p></p>\n\n<h2 id='event_recorder-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='event_recorder-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='event_recorder-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='event_recorder-section-copyright-and-license'>COPYRIGHT AND LICENSE</h2>\n\n<p>Copyright (c) 2009-2022, Bryntum &amp; Nickolay Platonov</p>\n\n<p>All rights reserved.</p>\n","title":"The event recorder"});