<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: vladimirbag</title>
    <description>The latest articles on DEV Community by vladimirbag (@vladimirbag).</description>
    <link>https://dev.to/vladimirbag</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F190548%2F6bdc0852-fdf6-4d1c-b16b-78c3ebf24b14.jpg</url>
      <title>DEV Community: vladimirbag</title>
      <link>https://dev.to/vladimirbag</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vladimirbag"/>
    <language>en</language>
    <item>
      <title>Catch Them If You Can: Quality Locators for Stable End 2 End Tests</title>
      <dc:creator>vladimirbag</dc:creator>
      <pubDate>Thu, 29 Aug 2019 17:28:47 +0000</pubDate>
      <link>https://dev.to/vladimirbag/catch-them-if-you-can-or-why-locators-make-my-tests-stable-4lja</link>
      <guid>https://dev.to/vladimirbag/catch-them-if-you-can-or-why-locators-make-my-tests-stable-4lja</guid>
      <description>&lt;p&gt;Each test automation beginner encounters many difficulties in writing effective tests, especially for websites, since websites have a DOM tree in their structure. &lt;strong&gt;Sometimes finding the element we need on the page is not so simple, especially if it's not labeled. And no AI has normally resolved this problem so far.&lt;/strong&gt; The way the user sees a website is not the same as we see it in our tests. When a user sees a link or a button, we have only an HTML element. How can we automate the user's actions then?&lt;br&gt;
Yes. This is a huge question. And in order to understand it and find the answer, you need to use help. I propose two candidates for this role.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XPath or CSS&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dBS1KIDo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/zhq2iljcetib97mx2d2a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dBS1KIDo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/zhq2iljcetib97mx2d2a.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are two most common types of locators. Each tester and developer considers this or that type to be the most effective and is ready to prove it in the battle for adherence.&lt;br&gt;
Still, as practice shows, out of the many types of locators, the two most powerful and effective are XPath locators and CSS locators. However, they were never designed to be used for test automation.&lt;br&gt;
&lt;strong&gt;However, they were never designed to be used for test automation. Why? Let's see.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CSS&lt;/strong&gt;&lt;br&gt;
All browsers implement the CSS engine so that developers can use CSS in their projects. CSS has patterns, according to which styles created by a developer are applied to page elements (DOM). These patterns are called selectors. Selenium WebDriver uses the same principle to find elements.&lt;br&gt;
The strong points of the CSS are simplicity in perception, reading, and compilation. The weak point is that the CSS can search for an element only by moving up and down the DOM tree, search for the third or fifth element in a row(if it can, the locator will be very long and difficult to read), for example, search for the third checkbox in an account, or look for specific items while working with drop-down lists).&lt;br&gt;
Let's look at some basic locators using CSS:&lt;br&gt;
 &lt;br&gt;
&lt;strong&gt;Absolute path:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;html body form input&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Relative path:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;input&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search for an immediate child:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;div&amp;gt;a&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search for a child of any level:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;div a&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search by item ID:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;input#username&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search by class:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;input.classname&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XPath&lt;/strong&gt;&lt;br&gt;
XPath is a language used to search for nodes in an XML document tree. And it works for web pages because HTML is actually a subset of an XML document, so we can query its elements by XPath. XPath goes beyond simple search methods for the &lt;strong&gt;id&lt;/strong&gt; or &lt;strong&gt;name&lt;/strong&gt; attributes (and at the same time supports them) and opens up a range of new features, such as searching for the third checkbox by its text, for example.&lt;br&gt;
A good reason to use XPath is when you cannot use attributes that are suitable as pointers, such as an identifier or name, for the element you want to get. You can use XPath to search for an element in either the absolute path (not recommended) or the relative path (for elements with given id or name). XPath pointers can also be used to define elements using attributes other than &lt;strong&gt;id&lt;/strong&gt; and &lt;strong&gt;name.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The biggest advantages of XPath are:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The ability to search upwards, that is, to search for a parent element by its descendant.&lt;/li&gt;
&lt;li&gt;Ability to use built-in functions.&lt;/li&gt;
&lt;li&gt;You can do vertical navigation on the DOM.&lt;/li&gt;
&lt;li&gt;The ability to search by text.
But there are certain &lt;strong&gt;disadvantages:&lt;/strong&gt; too long, difficult to build and read, too strict, not quite optimised for HTML search.
For example, It is difficult to specify an element with one of the classes:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;//div[contains(concat(' ', normalize-space(@class), ' '), ' test ')]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's look at some basic locators using XPath:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Absolute path:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;//html/body/div/div/form/input&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Relative path:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;//input&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search for an immediate child:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;//div/a&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search for a child of any level:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;//div//a&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search for an item in the text:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;.//&lt;/em&gt;[text()='First link']/..*&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search by attribute values:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;//input[&lt;a class="comment-mentioned-user" href="https://dev.to/id"&gt;@id&lt;/a&gt;
='username']&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Search by attribute name:&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;//img[@alt]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JiJoX6O6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/zqsb5vxyhrr7e87357ww.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JiJoX6O6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/zqsb5vxyhrr7e87357ww.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So what should a locator really be?&lt;/strong&gt;&lt;br&gt;
For myself, I defined three criteria which, in my opinion, should be met by a well-designed locator:&lt;br&gt;
 &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Stable:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;the shorter the locator, the more stable it will be, for example,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;//ul[@role ="listbox"]/li[1]&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;when compiling a locator, initially work with the attributes &lt;strong&gt;"id"&lt;/strong&gt;, &lt;strong&gt;"name"&lt;/strong&gt;, &lt;strong&gt;"class"&lt;/strong&gt;;
  &lt;/li&gt;
&lt;li&gt;do not use unstable classes and attributes, for example, &lt;strong&gt;@ aria-controls&lt;/strong&gt; (this is not a standard attribute for an element) or &lt;strong&gt;"id = 123rth45bvj"&lt;/strong&gt; (it is clear that the &lt;strong&gt;id&lt;/strong&gt; is generated and may change in the future).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2.&lt;strong&gt;Readable&lt;/strong&gt; (you need to be able to read the locator that was compiled. For example, &lt;strong&gt;// input [&lt;a class="comment-mentioned-user" href="https://dev.to/id"&gt;@id&lt;/a&gt;
 = "fsc-origin-search"]&lt;/strong&gt; - find &lt;strong&gt;input&lt;/strong&gt; where the attribute &lt;strong&gt;id = "fcs-origin-search"&lt;/strong&gt;. And such the locator is hard to read:&lt;br&gt;
&lt;strong&gt;// div / div / div / div [contains (concat ('', normalize-space (@class), ''), 'test')]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;3.&lt;strong&gt;Semantic&lt;/strong&gt; (it should correlate with what the element does. For example, &lt;strong&gt;input # city-from&lt;/strong&gt; explicitly displays that it is an element for entering text, but *** [@ react-select-bla = "asdsad"]&lt;strong&gt;) it is not clear what it does )&lt;br&gt;
It is very difficult for a beginner automation tester to understand all the intricacies of writing the locators correctly because they should be **short&lt;/strong&gt; and &lt;strong&gt;stable&lt;/strong&gt; and &lt;strong&gt;semantic&lt;/strong&gt; so that given any possible changes in the DOM tree, you would not have to rewrite them again. And I began looking for &lt;strong&gt;an alternative&lt;/strong&gt; because there should be something simpler and more comprehensive. And you know, I found a way that helped me understand that you should not be afraid of Locators, they need to be commanded.&lt;br&gt;
&lt;strong&gt;These are Semantic locators in CodeceptJS&lt;/strong&gt; - when you don't even look at the source code of the page, but simply write which links to click and which fields to fill in since CodeceptJS works through XPath inside. Various strategies are used to locate semantic elements. However, CodeceptJS Semantic locators may run slower than specifying an exact locator by XPath or CSS.&lt;br&gt;
&lt;strong&gt;CodeceptJS&lt;/strong&gt; can guess an element's locator from context. For example, upon clicking, CodeceptJS will try to find a link or button by their text value. When typing into a field, this field can be located by its &lt;strong&gt;name&lt;/strong&gt; and &lt;strong&gt;placeholder.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fR__49fv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/s9i4eqtkpl1yll5me4un.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fR__49fv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/s9i4eqtkpl1yll5me4un.jpeg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you are not familiar with CodeceptJS - check my previous post, how I discovered it and wrote my first test.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript End 2 End Testing for Mere Mortals&lt;/strong&gt;&lt;br&gt;
(&lt;a href="https://medium.com/@vladimirbaginskiy/javascript-end-2-end-testing-for-mere-mortals-e055db5e80d4"&gt;https://medium.com/@vladimirbaginskiy/javascript-end-2-end-testing-for-mere-mortals-e055db5e80d4&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;The article describes how, step by step, a beginner will become able to make his first autotest without any knowledge about JavaScript and Locators. This, at least, saved me a ton of time and nerves.&lt;br&gt;
With a basic knowledge of locators, I could start writing a test for a real website.&lt;br&gt;
I will use SkyScanner (&lt;a href="https://www.skyscanner.com"&gt;https://www.skyscanner.com&lt;/a&gt;) to get a list of flights from Kyiv to Berlin. Just follow my steps to see how locators worked for me. However, I can't guarantee that Skyscanner team won't change their booking page in the future, and the same locators will work for you as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KpR7-mgE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/b0lwl7xahgp8a6zpzyln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KpR7-mgE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/b0lwl7xahgp8a6zpzyln.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Skyscanner expects the user to enter their origin and destinations, and pick the correct city names from a list. And picking an item from popping out dropdown was a bit tricky.&lt;/p&gt;

&lt;p&gt;I will use CodeceptJS + Puppeteer setup. I can install it with just two commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;npm init -y&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;npm install codeceptjs puppeteer --steps&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Puppeteer is a tool from Google Chrome that allows executing tests directly in a browser, without Selenium. And that's cool, cause I don't need to install anything extra!&lt;br&gt;
 After you have walked the entire installation path and created a test file (I have &lt;strong&gt;sky_test&lt;/strong&gt;), we will go to our experimental site and try to write an &lt;strong&gt;XPath&lt;/strong&gt; locator which, as already mentioned, will be responsible for selecting an item in a drop-down list.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;With the help of &lt;strong&gt;Dev Tools (F12)&lt;/strong&gt;, we are looking for elements corresponding to "From" and "To" fields.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v7vn7p9I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/uhz4dhzqtz8wlwp3h7q5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v7vn7p9I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/uhz4dhzqtz8wlwp3h7q5.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1.1.In the field &lt;strong&gt;"From"&lt;/strong&gt; enter Kyiv and when the list appears, right-click the mouse on the list and select &lt;strong&gt;"Inspect element".&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The same thing with &lt;strong&gt;Dev Tools (F12)&lt;/strong&gt;, we are looking for elements corresponding to the &lt;strong&gt;"To"&lt;/strong&gt; field.&lt;/p&gt;

&lt;p&gt;2.We press "Ctrl + F" and enter our locator in the window that appears. The locator can be attached to &lt;strong&gt;"id"&lt;/strong&gt; or &lt;strong&gt;"name"&lt;/strong&gt; or &lt;strong&gt;"class"&lt;/strong&gt;(if you are sure that they are unique and stable, that is, developers will not change them in the future), but in our case, this is a drop-down list where you need to select the element from. Therefore, after conducting many experiments with finding the right locator, I got this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cDYxhoPS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ee78w9n8vgnuc5yn8zm6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cDYxhoPS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ee78w9n8vgnuc5yn8zm6.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;//ul[@role="listbox"]/li[1]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With the second element of the "To" window drop-down list, I got this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OImF6Y6A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/hxloc0fbnz8t68ubqm97.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OImF6Y6A--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/hxloc0fbnz8t68ubqm97.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;//ul[@role="listbox"]/li[1]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;3.We'll open our code editor (I have this &lt;strong&gt;"Visual Studio Code"&lt;/strong&gt;), open the javascript file that you created when installing the CodeceptJS, and write the script for our test:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario('test something',(I) =&amp;gt;{&lt;br&gt;
I.amOnPage('/');&lt;br&gt;
I.fillField('From',' Kyiv');&lt;br&gt;
I.click('//ul[@role="listbox"]/li[1]]');&lt;br&gt;
I.fillField('To',' Berlin');&lt;br&gt;
I.click('//ul[@role="listbox"]/li[1]]');&lt;br&gt;
I.click('Search flight');&lt;br&gt;
})&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;4.Let's open our &lt;strong&gt;Node.js command prompt&lt;/strong&gt; and use the &lt;strong&gt;npx codeceptjs run -- steps&lt;/strong&gt; command to run the test.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;npx codeceptjs run --steps&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If everything is done correctly, the site will open.&lt;br&gt;
Now press &lt;strong&gt;"Еnter"&lt;/strong&gt; and check the test.&lt;/p&gt;

&lt;p&gt;5.&lt;strong&gt;My final result:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--c9PhSguH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/1t2kzg4z0wlpqs2d9f3x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c9PhSguH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/1t2kzg4z0wlpqs2d9f3x.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my article, I showed how a beginner testing automation tool that does not know practically anything about locators, does not have super knowledge in the field of the Java programming language can write self-tests and simultaneously study the area that he needs, thereby sharpening his skills without wasting time on a simple dull theory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;XPath&lt;/strong&gt; is not as scary as you think it is. The shorter and simpler your locator, the easier it will be to use it in the future. Try to look for unique static elements that will not be changed a priori.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you are unsure if this locator is good enough, test it with locator adviser:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://davertmik.github.io/locator/"&gt;https://davertmik.github.io/locator/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope he helps you write the correct locators.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>qa</category>
      <category>testing</category>
      <category>beginners</category>
    </item>
    <item>
      <title>JavaScript End 2 End Testing for Mere Mortals</title>
      <dc:creator>vladimirbag</dc:creator>
      <pubDate>Thu, 18 Jul 2019 17:52:07 +0000</pubDate>
      <link>https://dev.to/vladimirbag/javascript-end-2-end-testing-for-mere-mortals-3hng</link>
      <guid>https://dev.to/vladimirbag/javascript-end-2-end-testing-for-mere-mortals-3hng</guid>
      <description>&lt;p&gt;My name is Vladimir, I live and work in Ukraine. I am a beginning QA engineer, and sooner or later I will have to face such concept as "test automation" because for me it is necessary for my further development in this professional field. And on the way to the implementation of this stage, I've encountered many problems. And one of the most important problems, in my opinion, for a beginner Automator is the lack of understanding of where to start.&lt;br&gt;
 This is probably the problem that every newcomer faces when starting to learn test automation. This post is for those of you who were also dreaming of testing automation but did not know where to start.&lt;br&gt;
I will show you a real example of how to write the first test using minimal knowledge of JavaScript. This will be browser testing of a simple application. To run and create tests, I will use the CodeceptJS framework, because this is still the simplest and most understandable, as for a beginner, a test framework that I've found.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CodeceptJS is a modern 'end to end' testing framework&lt;/strong&gt; with a special BDD-style syntax. The test is written as a linear scenario of a user's action on a site. CodeceptJS is a multi-backend testing framework. It can execute tests using Webdriverio, Puppeteer, Protractor, Nightmare (for our testing, Google Chrome Puppeteer will be used as a driver for browsers). It's very simple since you just describe your actions on the site and then you execute them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1. Node.js Installation&lt;/strong&gt;&lt;br&gt;
First, install Node.js v.12.4.0. I've tried running tests at 10.16 - nothing happened. Therefore, I recommend the 12.4.0 version.&lt;br&gt;
&lt;strong&gt;! I use Windows 7 in this tutorial. But it should work on Windows 10, Linux, and Mac as well!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2. The installation of CodeceptJS with Puppeteer&lt;/strong&gt;&lt;br&gt;
Run the &lt;strong&gt;"Node.js command prompt"&lt;/strong&gt; and in the command line enter &lt;strong&gt;"npm install codeceptjs puppeteer"&lt;/strong&gt;. The installation of CodeceptJS with Puppeteer begins.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install codeceptjs puppeteer&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3. Initializing CodeceptJS in the current directory&lt;/strong&gt;&lt;br&gt;
Run the command &lt;strong&gt;"npx codeceptjs init"&lt;/strong&gt; (Initialize CodeceptJS in the current directory by running it).&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx codeceptjs init&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4. Answer simple questions&lt;/strong&gt;&lt;br&gt;
Decide on defaults, when asked to select helpers - choose Puppeteer. When asked to specify the URL, specify &lt;a href="http://jspears.github.io/subschema"&gt;http://jspears.github.io/subschema&lt;/a&gt; ( I've chosen this application because it is simple and uses React.).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5. Create the first test in your root directory&lt;/strong&gt;&lt;br&gt;
When everything is installed, create your first test using the command &lt;strong&gt;"npx codeceptjs gt"&lt;/strong&gt; and enter the name of your test.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx codeceptjs gt&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;A file is generated in your root directory (the name of your test.js). For example - "login.js"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6. First Test Code&lt;/strong&gt;&lt;br&gt;
Tests are written from a user's perspective. There is actor object (represented as 'I') contains action methods taken from helpers&lt;br&gt;
OR: represents user's actions. A test is written as a sequence of actions performed by an actor.&lt;br&gt;
Open a generated file in your favorite javascript editor. For example, I am using Visual Studio Code.&lt;br&gt;
Your first test will look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Scenario ('try react app', (I) =&amp;gt; {&lt;br&gt;
I.amOnPage ('/'); &lt;br&gt;
// This is command to open a webpage (accepts relative or absolute url)&lt;br&gt;
I.click ('Login');&lt;br&gt;
// This is command to locate a button or link and click on it&lt;br&gt;
pause ();&lt;br&gt;
// This command is prescribed when writing or debugging a test&lt;br&gt;
});&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7. The validation of written code&lt;/strong&gt;&lt;br&gt;
Run a test using the command &lt;strong&gt;"npx codeceptjs run --steps"&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx codeceptjs run --steps&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;The output should be similar to this:&lt;br&gt;
open login page and print value -&lt;br&gt;
try react app&lt;br&gt;
&lt;strong&gt;• I am on page "/"&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;• I click "Login"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 8. Start a test browser&lt;/strong&gt;&lt;br&gt;
Puppeteer starts a browser without opening a window. To see the browser, edit "codecept.json config" and set &lt;strong&gt;"show: true"&lt;/strong&gt; value for Puppeteer:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;exports.config = {&lt;br&gt;
tests: './*_test.js',&lt;br&gt;
output: './output',&lt;br&gt;
helpers: {&lt;br&gt;
Puppeteer: {&lt;br&gt;
url: 'http://jspears.github.io/subschema',&lt;br&gt;
show: true,&lt;br&gt;
}&lt;br&gt;
},&lt;br&gt;
include: {&lt;br&gt;
I: './steps_file.js'&lt;br&gt;
},&lt;br&gt;
bootstrap: null,&lt;br&gt;
mocha: {},&lt;br&gt;
name: 'User'&lt;br&gt;
}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 9. Rerun the browser&lt;/strong&gt;&lt;br&gt;
One more time, enter the command &lt;strong&gt;"npx codeceptjs run --steps"&lt;/strong&gt;.&lt;br&gt;
On the screen, we have a browser and terminal windows. In the terminal, the test has stopped running and waiting for commands from us.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 10. Receiving test data&lt;/strong&gt;&lt;br&gt;
While the &lt;strong&gt;pause ()&lt;/strong&gt; command is being executed in our code, we can enter any commands in the terminal window and watch how they are executed while the browser is running.&lt;br&gt;
 To get the test data, you need to enter &lt;strong&gt;"I.fillField"&lt;/strong&gt; commands in the terminal window and, simultaneously, you can also watch the test execution in an open browser.&lt;br&gt;
 It turns out to be not so difficult, for this test it is not necessary to use locators like XPath, codeceptjs perfectly recognizes fields with labels like "User Name", "Password", "Repeat Password". Unlike Selenium, where you need to spend extra time on the recognition of fields with the help of "locators" so that our test would work.&lt;br&gt;
Now, you see that our fields are filled with data.&lt;br&gt;
Next, scroll down the page and see our previously entered values ​​in the form of a script.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 11. The layout of the code-obtained data&lt;/strong&gt;&lt;br&gt;
Copy the resulting script with our data and paste it into your JS file in the editor (For example, my file name is ‘Login_test.js’).&lt;br&gt;
A few changes and it should turn out to be this:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Feature (‘open login page and print value’);&lt;br&gt;
Scenario (‘try react app’, (I) =&amp;gt; {&lt;br&gt;
I.amOnPage (‘/’);&lt;br&gt;
I.click (‘Login’);&lt;br&gt;
pause();&lt;br&gt;
I.fillField (‘username’, 'test@gmail.com')&lt;br&gt;
I.fillField (‘password’, ‘test’),&lt;br&gt;
I.fillField (‘confirmPassword’, ‘test’)&lt;br&gt;
});&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 12. Final test and verification&lt;/strong&gt;&lt;br&gt;
Now we run our test again using the command &lt;strong&gt;“npx codeceptjs run --steps”&lt;/strong&gt;&lt;br&gt;
At the end of the test, it is imperative to make a check that not just the actions were performed, but the result was achieved.&lt;br&gt;
For example, you can check that the form under the input fields at the bottom of the browser contains the text.&lt;br&gt;
To do this, we add the following commands in the terminal window:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;I.see (‘“username”: “test@gmail.com”’)&lt;br&gt;
 I.see (‘“password”: “test”’);&lt;br&gt;
 I.see (‘“confirmPassword”: “test”’)&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;These commands are called Assertions, and it is believed that any test should include them.&lt;/p&gt;

&lt;p&gt;The test we’ve created is working and is now verified. Congratulations. You, as a beginner, in 12 simple steps conducted a test which automatically fills in the fields on the site and “authenticates”. This has been the first experience of test automation for me, and, finally, the tests don’t scare me anymore. And I will think about how to improve my skills in test automation. I hope that CodeceptJS will help me with this.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>testing</category>
      <category>qa</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
