Autotests on Cypress
First impressions and problems encountered
Dmitry Kochergin, Lead Software Developer Luxoft
First of all, I want to note that I am not a professional autotester, but a Java programmer. But one day the task came to make smoke tests for basic verification of the main functions of an application that was recently broken by a change in the dependent service API without warning.
To begin with, I have never read anything about autotesting. The main preconception was that autotests are difficult, because, according to reviews, you can set up this Selenium … Plus, you need to learn XPath and PageObject, which you didn’t want to do at all.
A quick internet search yielded younger and more promising tools: WebDriver.IO, Pupeteer (and now Playwright is better) and Cypress. I chose the latter, bought into beautiful promises and a few comments from holivars on the best tools for autotests.
This is what the browser window of a running test looks like. On the left, the executed test commands and status, on the right, viewing the application during the test execution:
This is how the test code looks like (in Cypress, all the code is in JS, and selectors are ordinary CSS selectors):
At runtime it looks like this:
While I was looking for a tool for autotests – I had a picture in my head that tests can be created right in the browser, so that I just “clicked on the script record” – the system recorded my actions (CSS selectors of the elements that I clicked on). Then I look at the generated test, tweak the selectors if necessary, and save it to the Test Suite. Eh …
The fairy tale turned out to be unattainable then and I did not find such tools (perhaps someone will tell you the right way in the comments). But Cypress was bribed by the fact that the tests are run in a real browser, and you can even explore the DOM in parallel with the test execution with your favorite Chrome developer tools (if, for example, the selector did not work, you can open the console and immediately see why when the test is executed).
Of the other parameters that were important to me, I critically did not want to spend a lot of time either on writing (again, about writing a test in a browser) or on maintaining tests. This was enough for my purposes. Just for information about Cypress: it took 1 hour from the moment I first opened the Cypress website to the first test that logs into the application.
Further down the list of features from the site:
- Time travel – every step of the test execution in the console – you can click and return to a specific state of the entire application in the past, which is displayed right in the browser. And this is not just a captured image, but a real DOM, you can rollback and explore the page through Chrome devtools.
- Real time reloads – as in the entire modern JS theme, the sources were changed – at the same moment the test was restarted in the browser (hot reload).
- Automatic waiting – many test instructions are asynchronous, such as switching to a page, and Cypress automatically waits for the download to finish. Except, of course, when the application makes calls to the server.
- Network traffic control – Cypress can capture / see server calls and can set an instruction to wait for a response from the server.
- Screenshots and videos – Cypress records a video of the browser screen (MP4) during the test, along with instructions in the window.
All this stuff, of course, can be run without an open browser in CI, headless Chrome or Electron is used.
But there were also some problems.
At first, I didn’t know that I could wait for the XHR requests to the server to end, and I inserted timeouts instead, and the tests would randomly fall. Corrected.
Then Hot Reload worked every other time, I constantly had to restart the entire Cypress, because I was not sure that my changes were applied. It turned out that in my IDE (IntelliJ IDEA) there are such bad checkboxes, which are also enabled by default, because of which it turns out that saving a file is not saving, but eventual saving.
The next problem was that my application was using window fetch for requests to the server, and Cypress only sees XHR requests. Dirty hack from StackOverflow helped (as far as I understand, the fetch method is removed from the window so that the browser makes a fallback on XHR instead of fetch):
Then the problem of emulating a mobile browser arose, it was just that it was not possible to rewrite the user agent in the test code, but in a separate special file everything worked out.
Further solution to CORS problem:
Then file upload, it didn’t work out of the blue, the standard solutions didn’t work, but the cypress-file-upload library helped:
The only problem I could not solve was the reproducibility of the test. Namely, stable and identical initial data for running the test (fixtures), this is more of a configuration task, not Cypress, but still unresolved.
As a result, Cypress looks like a great tool for introducing autotesting into a project if:
- Have knowledge of JS
- No need to test in all kinds of browsers since IE6 (currently Cypress supports Chrome, Chromium, Edge, Electron, Firefox). Here discussion of the topic… But I can say that a year ago when I started working with Cypress, it only supported the latest version of Chrome and Electron for launches without UI.
- Want to quickly make tests and forget about them until someone breaks the application 🙂
Cypress: take it and use it!