Eleventh grader, or testing layout bugs

In the modern web, there is unfairly little attention paid to at least some automated UI testing. This is especially true for static typesetting. On the 2GIS Online project, we tried to partially fill this gap. What good practices we have acquired, and what good libraries we learned about, will be described later.
Layout
Consider the story of one made-up

button : A square button with an icon. Everything is simple. Dimensions can be hardcoded in pixels - what's the difference?
Almost immediately, the button begins to evolve. Users rarely click on a button. What to do? As an option, add an explanatory inscription. It remains only to slightly increase the width so that the inscription is included:

But what about the inscription in Russian? Yes, and the original text may change. So you can’t hardcode the width, you have to do it arbitrary: There

can be so much text that it cannot be read on one line. It is necessary to limit the maximum width and untie the height: The

button is still little used! You can make an auxiliary multi-line description. To do this, add a span with the appropriate styles:

It seems that everything has been taken into account, and no one can break this layout. Nobody except the eleventh grader - a long word that does not fit in the maximum width. We just do the spelling:

Users began to complain about the obsessive big button, so it was decided to make a cross that closes the button without actually pressing it. A few styles for the cross, a little indentation for the heading so that it does not fall under this cross - and you

're done: Do not forget that the main text may not be there, edit the indentation:

Now we seem to have a multifunction button for all occasions, with fixed bugs, true? Let's see all the cases again, only now at the same time:

What do we see? Instead of a fully functional button, we see an abundance of regression bugs: the icon fell out of the button, vertical alignment broke, an extra indentation appeared for the cross ... In other words, they wanted the best, it turned out as always.
Now imagine that this is not about a button, but about a large, constantly evolving project with a multimillion-dollar audience. Support turns into hell, in which, unfortunately, many layout designers live.
There are many techniques and methodologies that help support the layout of complex projects. For example, the well-known BEM, which we also use. But the BEM methodology alone does not solve, but only localizes the regression typesetting bugs. How to get rid of them in principle? It’s actually very simple (and for this you don’t need to learn the API of a dozen new js libraries!) - you need to create one test html page with all the button states. Let’s together, right now, create it, it won’t take more than 10 seconds. Here is even the markup:
Test page
No js, npm dependencies, express servers ... Just an html file opened in the browser.
For each evolutionary iteration, one or several new states (that is, variants of the html code of the element under test, including content) must be made, but not deleted. Viewing all the old conditions can be called semi-automatic regression.
We deliberately will not advise any means of automating this work, for two reasons: firstly, for most cases, each front-end can (and should) create such a page on its own; secondly, for complex cases, and pixel-perfect cases, we are writing our own solution, which we are not yet ready to announce.
Eleventh grader
More than half of the layout bugs are associated with a very simple miscalculation: the front-end does not take into account that, in general, any text can fall into the text nodes of its layout. It can be multi-line, consist of long words, or it can be an empty string.
Take a couple of any of your layouts - I bet on the Russian ruble that even one eleventh grader can break them . Insert a few eleventh graders in each field - layout breakage guaranteed!
I suggest to open any popular site and execute the following code in the debugger
var a,w=document.createTreeWalker(document,NodeFilter.SHOW_TEXT);while(a=w.nextNode()){if(a.textContent.trim().length)a.textContent='Одиннадцатиклассница пошла посмотреть на достопримечательность, она шла долго, несколько строчек, пока не пришла'}
The first ten sites that came to mind (excluding 2GIS Online, of course) were broken to such an extent that it became absolutely impossible to use them.
Of course, this does not mean that the eleventh grader walks all the Internet text nodes every day and breaks the layout (with the same success, the site can be protected from ebavavirus), but you must consider the following factors:
- If your project exists in several languages, then in another language there may be a longer phrase (Russian is longer than English, Spanish is longer than Russian, etc.)
- The user may not have the main font, and fallback will be larger
- The user may have a custom zoom or other font rendering engine.
- The text can be changed during the support process, including by content managers who will certainly not check the layout
- Incorrect text may fly into the field simply because of a bug in the js code
- A bug in the layout of another block can squeeze your block
- Someone will read this article and execute the code in the debugger :)
We sincerely believe that in any of these cases all text should be visible to the user and it should be readable. It can uncritically change the block size, go to the fade, or break off with an ellipsis; but it should not turn into a monster attacking neighboring nodes, burning out the user's eyes; that is, at least it should not fit into another text.
Automation
Everything that we wrote above cannot be called automatic testing, because it requires the human eye. If you do not want to strain your eyes at all, the tests that we call dom tests will help you.
Dom test is a js code executed in a browser that checks something in the isolated part of the application, or in the entire application. Anything can be checked: from the presence of the class and attribute in html, to the arguments with which some function was called, including asynchronous.
Here you will find such wonderful libraries as:
mocha . Testing framework. Allows you to create tests and test groups, including asynchronous; execute some code before and after a test or group of tests.
chai. Library for assert. In principle, you can use the native assert node.js, but the “tea” has some goodies, for example the beautiful diff deepEqual.
sinon . A library that allows you to do two important things:
- Keep track of features. You will know how many times and with what arguments the function you are following has been called.
- FakeTimers. Allows to replace setTimeout and setInterval and, thus, “manage” time. That is, after the substitution, you can call sinon.tick (20) - and 20 milliseconds of time will pass instantly, while all the timeouts registered for execution in this period will be executed.
Combining all this, you can write tests both for the entire application, and for its isolated parts. In these tests, you can do literally everything: fill out the form and click on the buttons; change dom tree; make ajax requests ... In fact, inside such tests you are inside the debugging console of the browser, and in your hands you have any js libraries for testing that you like.
The advantage of such tests is that they run in a browser, which means that they can be run in any browser with zero adaptation resources (which cannot be said about selenium drivers, especially in combination with, say, ie8 or android 4.0). In addition, such tests can be run in fully automatic mode on phantomJS, for example on git-push hooks.
Just in case, it is worth noting that dom-tests are not an alternative to regression testing of layout; this is just another code protection approach, with its own specifics and scope.
conclusions
Get an html-page for layout regression, put an eleventh grader into it , and your layout will become 10 times better. Protect your code with js-tests, and you can refuse the services of testers (who will have to re-qualify as automation engineers and help you write tests). On the 2GIS Online project, 90% of the tasks fall into battle without manual testing, and this was largely possible thanks to the testing approaches mentioned above.
Do not wait until the eleventh grader comes to you herself!
More information can be found in my presentation on Web Standards Days.