⬆️ ⬇️

We deliver a cup of hot coffee to our office with one team of console using TestCafe



Friends, today I will tell you a story about how to easily and gracefully solve the problem of end-to-end testing a web-service for delivering coffee using a new open source test framework. We will check not only the work of the site, but also the managers and even the delivery service, moreover we will spend a minimum of effort and time on this. And as a bonus for the effort, we get a cup of hot coffee right in your hands. I ask all lovers of adventure under the cat…



To date, the need for e2e web testing is not new to anyone. The question of choosing a service for testing sooner or later arises an edge for any web-application. The general public is aware of various Selenium-derived solutions, the vast majority of which are built on the use of WebDriver. We are going to demonstrate work with the new open source TestCafe test framework, built on a completely different principle. Let us turn, finally, from talk to business.



Install TestCafe



As always, it all starts with the installation of the product. This is of course completely boring, but I will please you, the full installation of TestCafe is performed with just one console command.



npm install -g testcafe 


If you had to install Selenium or the frameworks based on it, then you will be pleasantly surprised at how easy and fast it is to do with TestCafe. As you can see, TestCafe is built on Node.js , which means no Java, no browser plugins or bindings to the operating system. All you need is to have Node.js on your computer.



Now we will create a file that will contain our test, let's call it get-a-cup-of-coffee.js . In the file, create a fixture - a set of tests, specify the address of the page and create an empty test.



 fixture `Let\'s take a look at the new TestCafe` .page ` url     (    )`; test(`Get a cup of coffee`, async t => { // TODO: test }); 


One of the nice features of the TestCafe framework is that you can use ES6 and ES7 syntax in your test, regardless of whether your browser supports it or your version of Node.js. TestCafe, with the help of Babel , translates all code into ES5 syntax.



Writing a test



Perform actions with page elements



Let's start writing a test. Go to the hot coffee delivery section. Everything is extremely simple - click on the "Menu" item and select the "Coffee" item.

image



 test(`Get a cup of coffee`, async t => { await t .click(Selector('#nav').find('a').withText('')) .click(Selector('#content').find('#smenu-150')); }); 


Please note that during the test there will be several transitions to new pages. But, as you can see for yourself, nowhere in the test will we indicate at what point and for how long it is necessary to wait for the page to load, send the form or respond to an XHR request. TestCafe takes all these responsibilities on yourself, you no longer need to worry about it.



For the indication of elements with which it is necessary to carry out actions, we used selectors . Selectors in TestCafe let you do all the work related to DOM elements. To do this, you must specify the method of obtaining the item on the client, for example, css - selector or function. As well, TestCafe provides an API for creating composite selectors that allow you to find an element by its location in the page hierarchy or by specified filters (text, index, and any custom filters).



After we have moved to the menu we need, add a cup of "classic latte" to the basket:

image



 await t.click(Selector('.title').withText(' ').sibling('.labels')); 


Check the status of page elements



Now we need to make sure that the item is added to the cart. Go to the appropriate page:



 await t.click('.myShop-cartmini'); 


For verification, use the built-in assertions provided by TestCafe. And to get the value of the page element property that interests us, we will use the selectors again. Selectors contain a set of asynchronous properties and methods that can be directly executed in a test or passed to assertion. In the second case, the assertions activate the wait mechanism . After all, it is often necessary to wait for the animation to complete, or to receive a response to an XHR request, before performing assertion.



All existing assertion libraries imply the use of artificial delays, which greatly increases the time required to pass tests and makes them unstable. TestCafe takes care of this itself. If, when using the property and the selector method, the test fails, the test does not fall instantly. Assertions are calculated several times, at each iteration getting the current value and falling only if the timeout is reached and the check has not been executed successfully. This approach allows you to write stable, fast and reliable tests, without thinking about the response time of the test page.



Check the number and name of the goods in the basket.



image



 const items = Selector('.myShop-cart-item'); await t .expect(items.count).eql(2) .expect(items.nth(0).innerText).contains(' ') .expect(items.nth(1).innerText).contains(''); 


Execution code on the client



We can also use the client function to get the quantity of goods in the cart. This function will be executed on the client, and the result will be returned to the server. Inside the client function, any js code can be used, as if you just added it to the page.



 const getOrderCount = ClientFunction(() => document.querySelectorAll('.myShop-cart-item').length); let orderCount = await getOrderCount(); 


There is also a way to immediately execute code on the client — using the t.eval method.



 orderCount = await t.eval(() => document.querySelectorAll('.myShop-cart-item').length); 


Let us verify that the data obtained correspond to our expectations.



 await t.expect(orderCount).eql(2); 


Completion and checkout



Return to the coffee selection menu and add a “Flat White Popcorn” to the basket:

image



 await t .click('.myShop-cartmini') .click(Selector('#content').find('#smenu-150')) .click(Selector('.title').withText('  ').sibling('.labels')); 


Again, go to the cart and check that the number and name of the goods has changed.



 await t .click('.myShop-cartmini') .expect(Selector('.myShop-cart-item').count).eql(3) .expect(Selector('.myShop-cart-item').nth(0).innerText).contains(' ') .expect(Selector('.myShop-cart-item').nth(1).innerText).contains('  ') .expect(Selector('.myShop-cart-item').nth(2).innerText).contains(''); 


Now we’ll complete the checkout - we’ll go to the contact information and shipping address page. Having filled in the required fields, all that remains is to click the "Submit" button.



image



 await t .click('.myShop-button-order') .typeText('#ffio', ' ') .typeText('#ftel', '+79999999999') .click('#fgorod') .click(Selector('#fgorod > option').withText('--')) .typeText('#fulica', '') .typeText('#fdom', '1') .click('input[type="submit"]'); 


The test is ready. There is nothing superfluous in the code, it contains only a list of actions performed and work with page elements, while remaining understandable for reading and maintenance.



Test run



Run the test with the following console command:



 testcafe chrome get-a-cup-of-coffee.js 


TestCafe will find the browser installed on the machine, launch it itself and run the test.



The console will be given detailed information about the results of passing the test.

image

The test fell due to an error on the site. In the event of a test crash, TestCafe provides callsite and callstack, and, if you specify the appropriate option , also a link to the screenshot made when it crashes. Thus, thanks to TestCafe, we were able to find the error by writing just one simple test. Having found an error, we reported this to the site owners and advised using TestCafe for testing in order to avoid errors in the future :).



Let's run the test without crashing the page with the following console command:



 testcafe chrome get-a-cup-of-coffee.js --skip-js-errors 


image

Reports on the passage of tests can be presented in various formats , for this there are a set of appropriate plug-ins. They allow you to customize the work with the main systems of continuous integration. You can run tests not only on local, but also on remote and cloud devices (for example, Sauce Labs ). For the final automation of our service, it remains for us to integrate the result into a system of continuous integration. Who knows, maybe in the future we will want to add a check on the temperature of the coffee, its delivery time or even its taste. About automation and integration of this process, we probably write a separate article :).



findings



As you can see, we achieved the original goal: with one team we ordered our coffee directly to the office and confirmed the effectiveness of the service. Of course, this is a joking example, we took a company that delivers coffee in just four cities. But you can write a simple test for any such service, which is located near you.



A complete example can be found here . We used the methodology PageObject , which allows you to make the test code more readable and understandable.



I hope after reading you look at TestCafe for a cup of coffee. You can discuss all your questions in the comments or on discuss . Coffee you day!



')

Source: https://habr.com/ru/post/318452/



All Articles