<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Engineering Blog | Nightwatch.js]]></title><description><![CDATA[Updates and tutorials from the Nightwatch team]]></description><link>https://blog.nightwatchjs.org/</link><image><url>https://blog.nightwatchjs.org/favicon.png</url><title>Engineering Blog | Nightwatch.js</title><link>https://blog.nightwatchjs.org/</link></image><generator>Ghost 4.34</generator><lastBuildDate>Thu, 23 Apr 2026 07:32:36 GMT</lastBuildDate><atom:link href="https://blog.nightwatchjs.org/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Advanced Techniques and Scenarios in Web Testing]]></title><description><![CDATA[Learn how to test the complex elements and user interactions of the web. We'll go over advanced testing concepts and scenarios while showcasing the extensive capabilities of what Nightwatch can do.]]></description><link>https://blog.nightwatchjs.org/advanced-techniques-in-web-testing/</link><guid isPermaLink="false">689034e800bae33461ddef7d</guid><category><![CDATA[web testing]]></category><category><![CDATA[end to end testing]]></category><category><![CDATA[complex testing scenarios]]></category><category><![CDATA[nightwatch v3]]></category><category><![CDATA[iframe]]></category><category><![CDATA[async/await]]></category><category><![CDATA[test hooks]]></category><dc:creator><![CDATA[David Burns]]></dc:creator><pubDate>Thu, 17 Aug 2023 05:30:19 GMT</pubDate><media:content url="https://blog.nightwatchjs.org/content/images/2023/08/Banner-1.png" medium="image"/><content:encoded><![CDATA[<h2 id="intro">Intro</h2><h3 id="previously-on-our-web-testing-series">Previously on our Web Testing Series</h3><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://nightwatchjs.org/blog/common-scenarios-in-web-testing/"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Basics of Writing Nightwatch Web Tests</div><div class="kg-bookmark-description">Learn how to test most scenarios on the web using these 3 techniques &#x2192; finding elements, interacting, and asserting their properties.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://nightwatchjs.org/favicon.ico" alt="Advanced Techniques and Scenarios in Web Testing"><span class="kg-bookmark-author">Engineering Blog | Nightwatch.js</span><span class="kg-bookmark-publisher">Bharath Raja</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://blog.nightwatchjs.org/content/images/2023/08/Banner.png" alt="Advanced Techniques and Scenarios in Web Testing"></div></a></figure><img src="https://blog.nightwatchjs.org/content/images/2023/08/Banner-1.png" alt="Advanced Techniques and Scenarios in Web Testing"><p>In our previous chapter, we learnt how to test basic scenarios on the web using these three powerful techniques.</p><ul><li>Finding Elements &#x2192; &#xA0;<code>browser.element.find()</code></li><li>Interacting with Elements &#x2192; <code>.click()</code> and <code>.sendKeys()</code></li><li>Asserting Elements &#x2192; <code>.getText().assert.contains()</code></li></ul><h3 id="overview-of-this-post">Overview of this Post</h3><p>Today we will learn some advanced techniques and use cases in web testing. &#xA0;This will also help you understand the extensive capabilities of what Nightwatch can do. We will expose you to the following scenarios and concepts. </p><p><strong>Concepts:</strong></p><ul><li>Test Hooks</li><li>Keyboard Shortcuts &amp; Clipboard</li><li>OS &amp; Browser Info</li><li>Executing client JS</li><li>Actions API</li><li>iFrame</li><li>Async/Await</li><li>Multi-tab Interaction</li><li>Emulating geolocation</li></ul><p>For the following tests, you can run them individually after writing each of them or run them all together at the end. You can also use this post as a reference to come back when you&apos;re facing similar scenarios.</p><h2 id="complex-scenarios-concepts">Complex Scenarios &amp; Concepts</h2><h3 id="%F0%9F%AA%9D-test-hooks">&#x1FA9D; Test Hooks</h3><p>Test hooks are special functions that allow developers to perform specific actions at different stages of the test execution process. In our <code>home.spec.js</code> test, we always want to go to the homepage of our nightwatch website. Instead of writing <code>browser.navigateTo(&apos;/&apos;)</code> in every test, we can add it under a <code>beforeEach</code> hook that will get executed before each test is run. We can also close the browser after every test with <code>browser.end()</code>.</p><pre><code class="language-js">describe(&apos;Nighwatch homepage&apos;, function() {
  beforeEach(browser =&gt; browser.window.maximize().navigateTo(&apos;/&apos;))
  afterEach(browser =&gt; browser.end())
  ...
})</code></pre><p>If you want to execute something before or after initiating the tests from a file (<code>home.spec.js</code>), you can do so using <code>before</code> and <code>after</code> hooks. You can also perform an operation before starting or just before exiting the test runner using <a href="https://nightwatchjs.org/guide/writing-tests/global-test-hooks.html">Global Hooks</a>.</p><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text"><code><strong>.window.maximize()</strong></code> maximizes our browser window to the screen size.</div></div><h3 id="%F0%9F%93%8E-keyboard-shortcuts-clipboard">&#x1F4CE; Keyboard Shortcuts &amp; Clipboard </h3><p>We learnt how to simulate key press using <code>.sendKeys()</code> in our <a href="https://nightwatchjs.org/blog/common-scenarios-in-web-testing/#interact-%E2%9C%8D%EF%B8%8F">previous post</a>, so shortcuts, including copy and paste, should be fairly straightforward. Pressing <code>CONTROL</code> or <code>COMMAND</code> or <code>SHIFT</code> will hold that key until <code>Keys.NULL</code> is pressed, which will release all the held keys. But the clipboard isn&apos;t directly accessible for us to test. We check the clipboard&apos;s contents by pasting it on an input element using the keyboard shortcut (<strong>&#x2318; </strong>+ v / Ctrl + v) and checking the value attribute of the input. Let&apos;s test the following scenario,</p><p><strong>Click the copy button on the home page and verify if the text is copied.</strong></p><pre><code class="language-js">it(&apos;Should copy the installation command on copy button click&apos;, function (browser) {
  browser.element.findByText(&apos;Copy&apos;).click()
  browser.element.find(&apos;#docsearch&apos;).click()
  const $inputEl = browser.element.find(&apos;.DocSearch-Modal .DocSearch-Form input&apos;)
  $inputEl.sendKeys([browser.Keys.COMMAND, &apos;v&apos;])
  $inputEl.getAttribute(&apos;value&apos;).assert.contains(&apos;npm init nightwatch&apos;)
})</code></pre><p>If we&apos;re running the tests on Windows or Linux, we need to replace <code>browser.Keys.COMMAND</code> with <code>browser.Keys.CONTROL</code>. This brings us to the next topic.</p><h3 id="%F0%9F%8C%90-os-browser-info">&#x1F310; OS &amp; Browser Info</h3><p>We can find the details about the browser and the platform the test is running in from the <code>browser.capabilities</code> object. These three are the most commonly used &#x2013; <code>.platformName</code>, <code>.browserName</code> and <code>.browserVersion</code>. We can use this for the previous example and rewrite our test to run on multiple platforms.</p><pre><code class="language-js">const is_mac = browser.capabilities.platformName.toLowerCase().includes(&apos;mac&apos;)
...
$inputEl.sendKeys([is_mac ? browser.Keys.COMMAND : browser.Keys.CONTROL, &apos;v&apos;])</code></pre><h3 id="%F0%9F%A4%9D-executing-client-js">&#x1F91D; Executing client JS </h3><p>Next, we&apos;ll try to execute some JS in the browser client. This can be done in Nightwatch using <code>executeScript</code> or <code>executeAsyncScript</code> function. </p><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text"><code><strong>.executeScript</strong>(&lt;script&gt;, [...&lt;data&gt;], &lt;optional-return-function&gt;)</code> <br><br>The <code><strong>&lt;script&gt;</strong></code> argument can be a string <code>&quot;window.location.reload()&quot;</code> or a function <code>function (...&lt;args&gt;) {...}</code> <br><br>The arguments <strong><code>...&lt;args&gt;</code></strong> of the script function will be the <code><strong>[...&lt;data&gt;]</strong></code> sent. <br><br>The <strong><code>&lt;optional-return-function&gt;</code></strong> will have the return of the client script as an argument.</div></div><p><strong>Execute a client script to increase the size of the logo and change the text of the &quot;Get Started&quot; button to &quot;{Client Side Execution}&quot;. Try finding the button with the new text and click it.</strong></p><pre><code class="language-js">it(&apos;Should should change with client script&apos;, async function (browser) {
  const change_text = &quot;{Client Side Execution}&quot;
  browser.executeScript(function (new_text) {
    const $hero_cta = document.querySelector(&apos;.hero__action-button--get-started&apos;)
    $hero_cta.innerHTML = new_text
    $hero_cta.style.background = &apos;#ff7f2b&apos;
    document.querySelector(&apos;header .navigation-list&apos;).style.display = &apos;none&apos;
    document.querySelector(&apos;header .navigation__logo&apos;).style.width = &apos;900px&apos;
  }, [change_text])
  browser.pause(1000) // Pausing just to notice the changes
  browser.element.findByText(change_text).click()
  browser.assert.titleMatches(&apos;Getting Started&apos;)
})</code></pre><h3 id="%E2%9C%8D-%EF%B8%8Factions-api">&#x270D; &#xFE0F;Actions API </h3><p>The Actions API provides granular control over exactly what designated input devices can do. Nightwatch provides an interface for 3 kinds of input sources:</p><ul><li>A key input for keyboard devices</li><li>A pointer input for a mouse, pen or touch devices</li><li>Wheel inputs for scroll wheel devices</li></ul><p>This can be done within the existing <code>.perform()</code> command. These are the available actions &#x2013; <code>.clear()</code>, <code>.click([element])</code>, <code>.contextClick([element])</code>, <code>.doubleClick([element])</code>, <code>.dragAndDrop(from, to)</code>, <code>.insert(device, ...actions)</code>, <code>.keyDown(key)</code>, <code>.keyUp(key)</code>, <code>.keyboard()</code>, <code>.mouse()</code>, <code>.move([options])</code>, <code>.pause(duration, ...devices)</code>, <code>.press([button])</code>, <code>.release([button])</code>, <code>.sendKeys(...keys)</code> and <code>.synchronize(...devices)</code>.</p><p><strong>Example:</strong></p><pre><code class="language-js">browser
  .perform(function () {
    const actions = this.actions({ async: true })

    return actions
      .keyDown(Keys.SHIFT)
      .move({ origin: el })
      .press()
      .release()
      .keyUp(Keys.SHIFT)
  })</code></pre><h3 id="%F0%9F%96%BC-iframe">&#x1F5BC; iFrame </h3><p>One of the trickiest aspects of the web is iFrame. These embedded iFrames render a completely different webpage and have their own browsing context and document, allowing for a new non-inherited web page inside yours. Nightwatch has a way to switch to these documents using the <code>.frame()</code> method.</p><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text"><code><strong>.frame</strong>(&lt;identifier&gt;)</code> <br>and the <code><strong>&lt;identifier&gt;</strong></code> can be any of the following<br><strong>- id:</strong> The id attribute of the iframe we&apos;re targeting<br><strong>- number:</strong> The position of the iframe in the document, starting with <code>0</code><br><strong>- <code>null</code>:</strong> Used to switch to the original browser window</div></div><p><strong>Enter the email and click subscribe inside an iframe.</strong> </p><pre><code class="language-js">it(&apos;Should allow for substack subscription&apos;, function (browser) {
  const iframe_selector = &apos;.footer__wrapper-inner-social-subscribe iframe&apos;
  browser
    .executeScript(function (iframe_selector) {
      document.querySelector(iframe_selector).scrollIntoView()
    }, [iframe_selector])
  browser.element.find(iframe_selector).setAttribute(&apos;id&apos;, &apos;test-nightwatch-123&apos;)
  browser.frame(&apos;test-nightwatch-123&apos;)

  browser.element.find(&apos;input[type=email]&apos;).sendKeys(&apos;test@nightwatchjs.org&apos;)
  browser.element.find(&apos;button[type=submit]&apos;).click()

  browser.ensure.alertIsPresent()
  browser.alerts.accept()
  browser.element.findByText(&apos;Sign out&apos;).assert.present()
})</code></pre><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text"><strong><code>.setAttribute</code></strong><code>(&lt;element&gt;, &lt;attribute&gt;, &lt;new-value&gt;)</code> allows us to set new values to DOM attributes. (<a href="https://nightwatchjs.org/api/element/setAttribute.html#setAttribute">read more</a>)<br><br><strong><code>.ensure</code></strong> is similar to <code>.assert</code> that offers an extra level of flexibility (<a href="https://nightwatchjs.org/api/ensure/#ensure-api">read more</a>)<br><br><strong><code>.alerts.[accept/dismiss/getText/setText]()</code></strong> can be used to interact with the browser alert box (<a href="https://nightwatchjs.org/api/alerts/accept.html#alerts.accept">read more</a>)</div></div><p>We execute a client script to scroll to the bottom of the page as the iframe we want to interact with is lazy loaded. This scroll to the bottom can also be achieved using the <a href="#&#x270D;-%EF%B8%8Factions-api">Actions API</a> as follows.</p><pre><code class="language-js">browser
  .perform(function() {
    return this.actions().move({
      origin: browser.element.find(iframe_selector),
    })
  })</code></pre><h3 id="%F0%9F%9A%A6-not-using-asyncawait">&#x1F6A6; (Not) Using Async/Await </h3><p>Javascript is a language built around the asynchronous nature of User Interfaces. This was a pain for developers, and to control the order of execution of our code, we started using callbacks. But soon, we ended up in <a href="http://callbackhell.com/">callback hell</a>, and we hated it. Then the beauty of <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promises</a> was introduced, and soon in ES7, we got a syntax sugar for it called <a href="https://tc39.es/ecma262/#sec-async-function-definitions">async/await</a>. </p><p>When writing our tests in Javascript, one often comes across the same issue, &quot;Why isn&apos;t this code executing&quot; or &quot;This line isn&apos;t supposed to execute at this time&quot;. We at Nightwatch cared a lot about solving this issue with programming in Javascript. We implemented an async <a href="https://github.com/nightwatchjs/nightwatch/wiki/Understanding-the-Command-Queue">command queue</a> behind the scenes, so you, as a tester, don&apos;t have to worry about it.</p><blockquote>Nightwatch has internal command queue, so you don&apos;t have to worry about the async issues of Javascript</blockquote><p>But on the rare occasion that you&apos;re taking a value out of Nightwatch API and using it in a vanilla Javascript, then <code>async</code> and <code>await</code> becomes essential. While testing, this is very unlikely, but if you do face such a situation, you can use <code>await</code> to get the value out since every Nightwatch API returns a Promise. </p><p><strong>Example:</strong></p><pre><code class="language-js">it(&apos;Use values from the webpage&apos;, async function(browser) {
  const href = await browser.element.find(&apos;.navigation-list li a&apos;).getAttribute(&apos;href&apos;).value
  // You can do anything with the href value here after
  console.log(href)
  MyAPI.track(href)
})</code></pre><h3 id="%F0%9F%97%82-multi-tab-interaction">&#x1F5C2; Multi-tab Interaction </h3><p>One of the scenarios we commonly come across during browsing is clicking a link that opens in a new tab. Nightwatch allows you to test this scenario by giving you an API to switch between different open documents.</p><p><strong>Click on the GitHub icon and check the URL of the new tab opened.</strong></p><pre><code class="language-js">it(&apos;Should lead to the GitHub repo on clicking the Github icon&apos;, async function (browser) {
  browser.element.find(&apos;ul.navigation-list.social li:nth-child(2) a&apos;).click()
  // wait until window handle for the new window is available
  browser.waitUntil(async function () {
    const windowHandles = await browser.window.getAllHandles()
    return windowHandles.length === 2
  })

  const allWindows = await browser.window.getAllHandles()
  browser.window.switchTo(allWindows[1])

  browser.assert.urlContains(&apos;github.com/nightwatchjs&apos;)
})</code></pre><p>Every tab is considered a window by the browser. We have a different <code>window</code> object in each of them, after all. Here we wait for the new tab to be available, switch to the new tab, and check if the browser URL matches our GitHub repo URL.</p><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text"><code><strong>.waitUntil(</strong>&lt;condition&gt;<strong>)</strong></code> waits for a condition to evaluate to a &quot;truthy&quot; value and fails if it doesn&apos;t. <br><br>The <code><strong>&lt;condition&gt;</strong></code> maybe any function that returns the value or a Promise to wait for.<br><br><code><strong>.window.getAllHandles()</strong></code> returns the id array of all the windows<br><br><code><strong>.window.switchTo(</strong>&lt;id&gt;<strong>)</strong></code> takes a window id and switches the test runner to that window</div></div><h3 id="%F0%9F%8C%8D-emulating-geolocation">&#x1F30D; Emulating geolocation </h3><p>When your website or web app is changing based on the location from which it is being accessed, it becomes important to test your website for all these locations. With the introduction of <a href="https://chromedevtools.github.io/devtools-protocol/tot/Emulation/#method-setGeolocationOverride">Chrome DevTools Protocol</a>, Nightwatch supports mocking the geolocation of the browser during the test run with just one command.</p><p><strong>Check the address from 3 different locations on the globe.</strong></p><pre><code class="language-js">it(&apos;sets and verifies the geolocation to Japan, USA and Denmark&apos;, function (browser) {
  const location_tests = [
    {
      location: { latitude: 35.689487, longitude: 139.691706, accuracy: 100 },
      // Tokyo Metropolitan Government Office, &#x90FD;&#x5E81;&#x901A;&#x308A;, Nishi - Shinjuku 2 - chome, Shinjuku, 163 - 8001, Japan
      test_text: &apos;Japan&apos;,
    },
    {
      location: { latitude: 40.730610, longitude: -73.935242, accuracy: 100 },
      // 38-20 Review Avenue, New York, NY 11101, United States of America
      test_text: &apos;New York&apos;,
    },
    {
      location: { latitude: 55.676098, longitude: 12.568337, accuracy: 100 },
      // unnamed road, 1550 K&#xF8;benhavn V, Denmark
      test_text: &apos;Denmark&apos;,
    }
  ]

  const waitTillLoad = async function () {
    const geo_dom_class = await browser.element.find(&apos;#geolocation_address&apos;)
      .getAttribute(&apos;class&apos;).value
    return !geo_dom_class.includes(&apos;text-muted&apos;)
  }

  location_tests.forEach(obj =&gt; {
    browser.setGeolocation(obj.location).navigateTo(&apos;https://www.where-am-i.co/&apos;)
    browser.waitUntil(waitTillLoad)
    browser.element.find(&apos;#geolocation_address&apos;).getText().assert.contains(obj.test_text)
  })
})</code></pre><p><strong>Explanation:</strong></p><p>We go through each location in the <code>location_tests</code> array and set the browser to that geolocation. Then wait for the address to be loaded using <code>.waitUntil(fn)</code> by checking if the <code>text-muted</code> class has disappeared. Then we verify if the address has the right text.</p><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text"><strong><code>.setGeolocation(</code></strong><code>{ latitude, longitude, accuracy }</code><strong><code>)</code></strong> sets the geolocation of the browser to the given <strong>latitude</strong>, <strong>longitude</strong>, and <strong>accuracy</strong> while mocking the geolocation.</div></div><p>For the test to work, you should first visit <a href="https://www.where-am-i.co/">www.where-am-i.co</a> and allow the website to access your location. </p><figure class="kg-card kg-image-card"><img src="https://blog.nightwatchjs.org/content/images/2023/08/image.png" class="kg-image" alt="Advanced Techniques and Scenarios in Web Testing" loading="lazy" width="676" height="360" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2023/08/image.png 600w, https://blog.nightwatchjs.org/content/images/2023/08/image.png 676w"></figure><p>Don&apos;t worry. You could always reset the permission for the location after the testing is done.</p><div class="kg-card kg-callout-card kg-callout-card-yellow"><div class="kg-callout-text">This command only works with Chromium-based browsers such as Google Chrome and Microsoft Edge.</div></div><h2 id="coming-up-next">Coming up Next</h2><h4 id="writing-scalable-tests-with-page-object-model">Writing scalable tests with Page Object Model</h4><p>Today you learnt a lot about how to do in-depth testing of websites and web apps to simulate complex use cases and scenarios using Nightwatch. In the next chapter of our series on web testing, we will explore test writing patterns and introduce you to Page Object Model (POM). We&#x2019;ll go through different patterns that improve the structure and maintainability of your test code, and you&#x2019;ll learn how to implement the POM &#x2013; a design pattern promoting reusability and modularity in your test scripts.</p><h2 id="join-our-community-%F0%9F%92%AC">Join Our Community &#x1F4AC;</h2><p>If you have any questions, don&apos;t hesitate to visit our <a href="https://discord.com/invite/SN8Da2X">Discord server</a> and say hello. Our community is always available to provide support, share insights, and assist you with any testing-related inquiries you may have. We welcome your active participation and look forward to connecting with you in our Discord community. You can also reach out to us via <a href="https://twitter.com/nightwatchjs">Twitter</a>.</p><p><strong>Happy testing! &#x1F389;</strong></p><!--kg-card-begin: html--><div class="kg-card kg-button-card kg-align-center">
<a href="https://discord.com/invite/SN8Da2X" class="kg-btn kg-btn-accent" style="
    color: #fff;
">
<svg role="img" xmlns="http://www.w3.org/2000/svg" viewbox="-2 0 135 96" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" style="
    width: 30px;
    fill: #fff;
    margin-right: 10px;
">
              <title>Discord</title>
              <g id="&#x56FE;&#x5C42;_2" data-name="&#x56FE;&#x5C42; 2">
                <g id="Discord_Logos" data-name="Discord Logos">
                  <g id="Discord_Logo_-_Large_-_White" data-name="Discord Logo - Large - White">
                    <path d="M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,1-10.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z"/>
                  </g>
                </g>
              </g>
            </svg>
Join our Community
    </a>
</div><!--kg-card-end: html-->]]></content:encoded></item><item><title><![CDATA[Basics of Writing Nightwatch Web Tests]]></title><description><![CDATA[Learn how to test most scenarios on the web using these 3 techniques → finding elements, interacting, and asserting their properties.]]></description><link>https://blog.nightwatchjs.org/common-scenarios-in-web-testing/</link><guid isPermaLink="false">689034e800bae33461ddef7e</guid><category><![CDATA[end to end testing]]></category><category><![CDATA[DOM interaction]]></category><category><![CDATA[testing basics]]></category><dc:creator><![CDATA[David Burns]]></dc:creator><pubDate>Wed, 02 Aug 2023 07:07:12 GMT</pubDate><media:content url="https://blog.nightwatchjs.org/content/images/2023/08/Banner.png" medium="image"/><content:encoded><![CDATA[<h2 id="intro">Intro</h2><h3 id="previously-on-our-web-testing-series">Previously on our Web Testing Series</h3><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://nightwatchjs.org/blog/get-started-web-testing-using-nightwatch/"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Get Started with Web Testing Using Nightwatch</div><div class="kg-bookmark-description">Discover how to get started with web testing using Nightwatch, a powerful no-compromise test automation framework. Learn how to install Nightwatch, set up your testing environment, and write basic end-to-end tests.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://nightwatchjs.org/favicon.ico" alt="Basics of Writing Nightwatch Web Tests"><span class="kg-bookmark-author">Engineering Blog | Nightwatch.js</span><span class="kg-bookmark-publisher">Bharath Raja</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://blog.nightwatchjs.org/content/images/2023/07/Banner@2x-8.png" alt="Basics of Writing Nightwatch Web Tests"></div></a></figure><img src="https://blog.nightwatchjs.org/content/images/2023/08/Banner.png" alt="Basics of Writing Nightwatch Web Tests"><p>We learnt how to set up a testing environment with Nightwatch and successfully wrote our first end-to-end test. Here is a quick recap,<br><strong>Install:</strong> <code>npm init nightwatch</code><br><strong>Write:</strong> &#xA0;<code>browser.navigateTo(&apos;/&apos;).assert.textEquals(&apos;h1&apos;, &apos;&lt;TEXT&gt;&apos;)</code><br><strong>Run:</strong> <code>npx nightwatch test</code></p><h3 id="overview-of-this-post">Overview of this Post</h3><p>Checking a text isn&apos;t enough of an end-to-end test for ensuring the reliability of websites and web apps. The web is made of complex elements and involves a lot of user interactions. In this tutorial, we&apos;ll teach you how to test some of the common scenarios continuing from <a href="https://nightwatchjs.org/blog/get-started-web-testing-using-nightwatch/#your-first-test">the first test</a> we wrote.</p><p>Writing web tests majorly surround these 3 components,</p><ul><li>Finding an element</li><li>Interacting with the element</li><li>Testing the element and its properties</li></ul><p>We&apos;ll cover these three primary aspects of testing to be able to write tests for the following scenarios.</p><ul><li>Click the &quot;Get Started&quot; button and verify if we&apos;ve gone to the installation page.</li><li>Click on Search, type the query &quot;frame&quot;, wait for the results, press the down arrow to the second result, and press enter. Verify if we&apos;ve gone to the <code>.parentFrame()</code> documentation page.</li></ul><p>You can also watch the <a href="#video-tutorial">video tutorial</a> of this post.</p><h2 id="find-%F0%9F%91%80">Find &#x1F440;</h2><p>The first step in web testing is to find DOM elements in the page we want to test. Nightwatch allows you to find elements using a variety of selectors. The most common approach is to use <a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Selectors">CSS selectors</a>. You can do this using the <code><strong>.element.find()</strong></code> API. </p><p>Beyond that, you can search for elements on the page through various other means shown below. In the following examples, we&apos;ll use <code>.find()</code>, <code>.findByText()</code> and <code>.findByPlaceholderText()</code>. You can learn more about all the <a href="https://nightwatchjs.org/guide/writing-tests/selectors.html">selectors available here</a>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.nightwatchjs.org/content/images/2023/07/image-3.png" class="kg-image" alt="Basics of Writing Nightwatch Web Tests" loading="lazy" width="1688" height="818" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2023/07/image-3.png 600w, https://blog.nightwatchjs.org/content/images/size/w1000/2023/07/image-3.png 1000w, https://blog.nightwatchjs.org/content/images/size/w1600/2023/07/image-3.png 1600w, https://blog.nightwatchjs.org/content/images/2023/07/image-3.png 1688w" sizes="(min-width: 720px) 720px"><figcaption>Element find APIs</figcaption></figure><div class="kg-card kg-callout-card kg-callout-card-grey"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text">To get suggestions in your editor, you can install our <a href="https://marketplace.visualstudio.com/items?itemName=browserstackcom.nightwatch">VSCode extension</a>.</div></div><p>You can also keep searching deeper inside elements by chaining all the find APIs. This really makes it easy to get the exact element you want.</p><p><strong>Example:</strong></p><pre><code class="language-js">browser.element.find(&apos;main&apos;).find(&apos;.hero&apos;).findByText(&apos;Get Started&apos;)</code></pre><h3 id="waiting">Waiting </h3><p>Sometimes the element we&apos;re looking for isn&apos;t ready, and we might need to wait for it. A good example is typing in an input box and waiting for the results to be populated. You can do this using the <code>.waitUntil(&lt;status&gt;)</code> API.</p><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text"><strong>API Reference</strong><br><br><code><strong>.find</strong>(&lt;string&gt;)</code> - The string should be a valid CSS Selector <br><br><code><strong>.findByText</strong>(&lt;string&gt;)</code> <br><br><code><strong>.findByPlaceholderText</strong>(&lt;string&gt;)</code> <br><br><code><strong>.waitUntil</strong>(&lt;string&gt;)</code> - The <code>&lt;string&gt;</code> can be any of the following: <code>&quot;visible&quot;</code>, <code>&quot;not.visible&quot;</code>, <code>&quot;selected&quot;</code>, <code>&quot;not.selected&quot;</code>, <code>&quot;enabled&quot;</code>, <code>&quot;not.enabled&quot;</code>, or <code>&quot;disabled&quot;</code></div></div><p><strong>Example:</strong></p><pre><code class="language-js">// Find the element with class &quot;DocSearch-Modal&quot; and wait for it to be visible
browser.element.find(&apos;.DocSearch-Modal&apos;).waitUntil(&apos;visible&apos;)</code></pre><p>Now that we&apos;ve learnt how to find an element, we can move on to interacting with it.</p><h2 id="interact-%E2%9C%8D%EF%B8%8F">Interact &#x270D;&#xFE0F;</h2><p>The next step is to interact with the web. The most common scenarios are users clicking a button or filling out a form. This part of testing becomes essential when testing a dynamic web app or website.</p><p>Nightwatch helps you simulate these actions through the element Interaction API <code>browser.element.find().<strong>&lt;interaction_api&gt;</strong>()</code>. These are the available interaction APIs: clear, <a href="https://nightwatchjs.org/api/element/click.html">click</a>, dragAndDrop, <a href="https://nightwatchjs.org/api/element/sendKeys.html">sendKeys</a>, setAttribute, setProperty, submit, update, upload, submitForm, updateValue, uploadFile, clickAndHold, doubleClick, rightClick and moveTo.</p><p>Beyond this, you can also do <a href="https://nightwatchjs.org/guide/writing-tests/write-complex-user-actions.html">complex user actions</a> using <code>.perform()</code>. But for the scope of this blog, we&apos;ll only be using <code>.click()</code> and <code>.sendKeys()</code>.</p><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text"><strong>API Reference</strong><br><br><code><strong>.click</strong>()</code> - Clicks the element we&apos;ve found<br><br><code><strong>.sendKeys</strong>(&lt;string | [...keycodes]&gt;)</code> - The keyboard input to be sent to the selected element<br><br>&#x2192; arg: <code><strong>&lt;string&gt;</strong></code> The text to send as keyboard input. e.g., <code>.sendKeys(&quot;hello world!&quot;)</code><br><br>&#x2192; arg: <code><strong>&lt;[...keycodes]&gt;</strong></code> You can also send a list of strings and keycodes, including the special keys found under <code>browser.keys.&lt;special_key&gt;</code>. e.g., <code>.sendKeys([browser.Keys.TAB, &quot;hello&quot;, browser.Keys.ENTER])</code>. You can find the list of <a href="https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_Key.html">special keys here</a>.</div></div><p><strong>Example:</strong></p><pre><code class="language-js">// Find the button &quot;Get Started&quot; and click it
browser.element.findByText(&apos;Get Started&apos;).click()

// Find the input box with placeholder &quot;Search docs&quot; and type &quot;frame&quot;
browser.element.findByPlaceholderText(&apos;Search docs&apos;).sendKeys(&apos;frame&apos;)

// Press the down arrow and press Enter
browser.element.findByPlaceholderText(&apos;Search docs&apos;).sendKeys([browser.Keys.ARROW_DOWN, browser.Keys.ENTER])</code></pre><p>Now that we&apos;ve learnt how to interact with an element, we can move on to verifying aspects of it.</p><h2 id="assert-%E2%9C%85">Assert &#x2705;</h2><p>The final step is to test if what we&apos;re looking for matches what&apos;s present on the web page. This involves taking the attribute of the element we need and verifying it. </p><h3 id="finding-the-attribute">Finding the attribute</h3><p>The most commonly tested aspects of an element are its text, attributes (including class), and value (for input elements). This can be achieved using <code>.getText()</code>, <code>.getAttribute()</code> and <code>.getValue()</code>. You can read more about all the <a href="https://nightwatchjs.org/api/element/getAttribute.html">element states here</a>.</p><h3 id="testing">Testing</h3><p>Once we have found the value we need, the next step is to test it. The tests can be written as loosely or as strictly as you prefer based on these three methods: <code>equals</code>, <code>contains</code> and <code>matches</code>.</p><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text"><code>.assert.<strong>equals</strong>(&lt;str&gt;)</code> - takes a string and checks if it&apos;s exactly the same.<br><br><code>.assert.<strong>contains</strong>(&lt;str&gt;)</code> - takes a string and checks if the input is present as a substring.<br><br><code>.assert.<strong>matches</strong>(&lt;regex&gt;)</code> - takes a regex as input and verifies against it.</div></div><p><strong>Example:</strong></p><pre><code class="language-js">// Check if the h1 text contains &quot;Install Nightwatch&quot;
browser.element.find(&apos;h1&apos;).getText().assert.contains(&apos;Install Nightwatch&apos;)

// Check if the &quot;autocomplete&quot; attribute of the input box is exactly &quot;off&quot;
browser.element.findByPlaceholderText(&apos;Filter by title&apos;).getAttribute(&apos;autocomplete&apos;).assert.equals(&apos;off&apos;)</code></pre><div class="kg-card kg-callout-card kg-callout-card-grey"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text">You can use <code>.verify</code> instead of <code>.assert</code> to log the failure and continue with other assertions in the test.</div></div><h4 id="negation">Negation</h4><p>To check if something should &quot;not&quot; be equal or should &quot;not&quot; contain, it&apos;s as simple as adding a <code>.not</code> after the <code>.assert</code>.</p><pre><code class="language-js">// Check if the h1 does not text contains &quot;Selenium&quot;
browser.element.find(&apos;h1&apos;).getText().assert.not.contains(&apos;Selenium&apos;)</code></pre><h4 id="element-status">Element Status</h4><p>You can assert the state of the element using <code>.visible()</code>, <code>.present()</code>, <code>.selected()</code> and <code>.enabled()</code> after the <code>.assert</code>. This is very similar to the <code>.waitUntil</code> status we learnt earlier in the <a href="#waiting">waiting</a> section and can be used interchangeably.</p><pre><code class="language-js">// Check if the element with class &quot;DocSearch-Dropdown-Container&quot; is present
browser.element.find(&apos;.DocSearch-Dropdown-Container&apos;).assert.present()</code></pre><h4 id="document-status">Document Status</h4><p>You can assert the title and URL of the document using the <code>browser.assert.<strong>url[Contains/Matches/Equals]</strong>(&lt;string&gt;)</code> and <code>browser.assert.<strong>title[Contains/Matches/Equals]</strong>(&lt;string&gt;)</code>.</p><pre><code class="language-js">// Check if the title contains &quot;Getting Started&quot;
browser.assert.titleContains(&apos;Getting Started&apos;)</code></pre><div class="kg-card kg-callout-card kg-callout-card-accent"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text">Nightwatch automatically retries failed assertions for up to half a second, which can be configured in the <code>globals</code> object in the <code>nightwatch.json</code> file. <a href="https://nightwatchjs.org/guide/writing-tests/adding-assertions.html#automatic-retries">Read more</a>.</div></div><h2 id="putting-it-all-together-%F0%9F%A7%A9">Putting it all together &#x1F9E9;</h2><p>With all the things we&apos;ve learnt so far, let&apos;s write tests for these two scenarios. </p><blockquote><strong>Scenario: </strong>Should lead to the installation page on click of &quot;Get Started&quot;</blockquote><h3 id="code">Code</h3><pre><code class="language-js">  it(&apos;Should lead to the installation page on click of Get Started&apos;, function (browser) {
    browser.navigateTo(&apos;/&apos;)
    browser.element.findByText(&apos;Get Started&apos;).click()
    browser.element.findByPlaceholderText(&apos;Filter by title&apos;).waitUntil(&apos;visible&apos;)
    browser.element.find(&apos;h1&apos;).getText().assert.equals(&apos;Install Nightwatch&apos;)
    browser.assert.titleEquals(&apos;Getting Started | Developer Guide | Nightwatch.js&apos;)
    browser.assert.urlContains(&apos;nightwatchjs.org/guide/quickstarts&apos;)
    browser.element.findByPlaceholderText(&apos;Filter by title&apos;)
      .getAttribute(&apos;autocomplete&apos;).assert.equals(&apos;off&apos;)
    ;
    browser.end()
  })</code></pre><h3 id="explanation">Explanation</h3><p>First, we navigate to the home page using <code>.navigateTo(&apos;/&apos;)</code>. This is possible because previously, in the <a href="https://nightwatchjs.org/blog/get-started-web-testing-using-nightwatch/#setting-up-nightwatch">setup of our project</a>, we set the <code>base_url</code> of our project to be the <a href="https://nightwatchjs.org/">Nightwatch</a> home page. You can edit this in the <code>nightwatch.conf.js</code> file. After the navigation, we find the button with the text &quot;Get Started&quot; and click it. For situations when the link is routed in the front end and doesn&apos;t reload the page, it is recommended to wait for the action to complete. Here we&apos;ll wait for the left-side search bar to become visible. Then we&apos;ll check the installation page by asserting the title, the URL, and the <code>h1</code> element. We&apos;ll also assert the &quot;autocomplete&quot; attribute of the search bar to showcase attribute assertions.</p><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text"><code><strong>browser.end</strong>()</code> closes the browser window. It&apos;s a good practice to finish the test with closing the browser.</div></div><blockquote><strong>Scenario:</strong> Should allow search and show correct results</blockquote><h3 id="code-1">Code</h3><pre><code class="language-js">  it(&apos;Should allow search and show correct results&apos;, function (browser) {
    browser.navigateTo(&apos;/&apos;)
    browser.element.find(&apos;#docsearch&apos;).click()
    browser.element.find(&apos;.DocSearch-Modal&apos;).waitUntil(&apos;visible&apos;)
    
    const search_input = browser.element.findByPlaceholderText(&apos;Search docs&apos;) 
    search_input.sendKeys(&apos;frame&apos;)
    browser.element.find(&apos;.DocSearch-Dropdown-Container&apos;).assert.present()
    search_input.sendKeys([browser.Keys.ARROW_DOWN, browser.Keys.ENTER])

    browser.element.find(&apos;h1&apos;).getText().assert.contains(&apos;.frameParent&apos;)
    browser.end()
  })</code></pre><h3 id="explanation-1">Explanation</h3><p>We&apos;ll navigate to the home page, find the search icon and click on it. We&apos;ll wait for the modal to open and be visible. Then we&apos;ll type in the text &quot;frame&quot; in the search input bar. We wait for the results to load by checking the presence of <code>&quot;.DocSearch-Dropdown-Container&quot;</code>, and once the results are loaded, we&apos;ll press the down arrow and enter. This will lead to the docs of the second result <code>.frameParent()</code>, and we verify the <code>h1</code> text to confirm that.</p><h3 id="final-file">Final File</h3><p>The final <code>home.spec.js</code> should look like this.</p><pre><code class="language-js">describe(&apos;Nighwatch homepage&apos;, function () {
    
  it(&apos;Should have the correct title&apos;, function(browser) {
    browser
      .navigateTo(&apos;/&apos;)
      .assert.textEquals(&apos;h1&apos;, &apos;Introducing Nightwatch v3&apos;)
      .end()
    ;
  })
    
  it(&apos;Should lead to the installation page on click of Get Started&apos;, function (browser) {
    browser.navigateTo(&apos;/&apos;)
    browser.element.findByText(&apos;Get Started&apos;).click()
    browser.element.findByPlaceholderText(&apos;Filter by title&apos;).waitUntil(&apos;visible&apos;)
    browser.element.find(&apos;h1&apos;).getText().assert.equals(&apos;Install Nightwatch&apos;)
    browser.assert.titleEquals(&apos;Getting Started | Developer Guide | Nightwatch.js&apos;)
    browser.assert.urlContains(&apos;nightwatchjs.org/guide/quickstarts&apos;)
    browser.element.findByPlaceholderText(&apos;Filter by title&apos;)
      .getAttribute(&apos;autocomplete&apos;).assert.equals(&apos;off&apos;)
    ;
    browser.end()
  })

  it(&apos;Should allow search and show correct results&apos;, function (browser) {
    browser.navigateTo(&apos;/&apos;)
    browser.element.find(&apos;#docsearch&apos;).click()
    browser.element.find(&apos;.DocSearch-Modal&apos;).waitUntil(&apos;visible&apos;)
    
    const search_input = browser.element.findByPlaceholderText(&apos;Search docs&apos;) 
    search_input.sendKeys(&apos;frame&apos;)
    browser.element.find(&apos;.DocSearch-Dropdown-Container&apos;).assert.present()
    search_input.sendKeys([browser.Keys.ARROW_DOWN, browser.Keys.ENTER])

    browser.element.find(&apos;h1&apos;).getText().assert.contains(&apos;.frameParent&apos;)
    browser.end()
  })

})</code></pre><p>Let&apos;s run the tests with the same command we learnt in the previous post.</p><pre><code>npx nightwatch test</code></pre><p>After the browser is done with the tests, the output should look like this.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.nightwatchjs.org/content/images/2023/07/image-9.png" class="kg-image" alt="Basics of Writing Nightwatch Web Tests" loading="lazy" width="2000" height="1167" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2023/07/image-9.png 600w, https://blog.nightwatchjs.org/content/images/size/w1000/2023/07/image-9.png 1000w, https://blog.nightwatchjs.org/content/images/size/w1600/2023/07/image-9.png 1600w, https://blog.nightwatchjs.org/content/images/2023/07/image-9.png 2008w" sizes="(min-width: 720px) 720px"><figcaption>Test output</figcaption></figure><div class="kg-card kg-callout-card kg-callout-card-green"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text"><strong>Cheers!</strong> Your tests have passed.</div></div><h2 id="coming-up-next">Coming up Next</h2><h3 id="advanced-techniques-and-scenarios-in-web-testing">Advanced Techniques and Scenarios in Web Testing</h3><p>Today you learnt how to test the web for the common use cases using these three techniques &#x2192; Finding, Interacting and Asserting. In the next chapter of our series on web testing, we will learn about advanced techniques in web testing, such as test hooks, multi-tab interactions, iFrames, copy/paste, using async/await, executing client JS, emulating geolocation, handling shadow DOM, actions API and more. Stay tuned for our upcoming post on Advanced Techniques and Scenarios in Web Testing. </p><h2 id="join-our-community-%F0%9F%92%AC">Join Our Community &#x1F4AC;</h2><p>If you have any questions, don&apos;t hesitate to visit our <a href="https://discord.com/invite/SN8Da2X">Discord server</a> and say hello. Our community is always available to provide support, share insights, and assist you with any testing-related inquiries you may have. We welcome your active participation and look forward to connecting with you in our Discord community. You can also reach out to us via <a href="https://twitter.com/nightwatchjs">Twitter</a>.</p><p><strong>Happy testing! &#x1F389;</strong></p><!--kg-card-begin: html--><div class="kg-card kg-button-card kg-align-center">
<a href="https://discord.com/invite/SN8Da2X" class="kg-btn kg-btn-accent" style="
    color: #fff;
">
<svg role="img" xmlns="http://www.w3.org/2000/svg" viewbox="-2 0 135 96" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" style="
    width: 30px;
    fill: #fff;
    margin-right: 10px;
">
              <title>Discord</title>
              <g id="&#x56FE;&#x5C42;_2" data-name="&#x56FE;&#x5C42; 2">
                <g id="Discord_Logos" data-name="Discord Logos">
                  <g id="Discord_Logo_-_Large_-_White" data-name="Discord Logo - Large - White">
                    <path d="M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,1-10.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z"/>
                  </g>
                </g>
              </g>
            </svg>
Join our Community
    </a>
</div><!--kg-card-end: html--><h2 id="video-tutorial">Video Tutorial</h2><figure class="kg-card kg-image-card kg-card-hascaption"><a href="https://www.youtube.com/watch?v=P0wAa2FPgxQ"><img src="https://blog.nightwatchjs.org/content/images/2023/08/testing-basics.png" class="kg-image" alt="Basics of Writing Nightwatch Web Tests" loading="lazy" width="1280" height="720" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2023/08/testing-basics.png 600w, https://blog.nightwatchjs.org/content/images/size/w1000/2023/08/testing-basics.png 1000w, https://blog.nightwatchjs.org/content/images/2023/08/testing-basics.png 1280w" sizes="(min-width: 720px) 720px"></a><figcaption>Basics of Writing Nightwatch Web Tests - Video Tutorial</figcaption></figure>]]></content:encoded></item><item><title><![CDATA[Get Started with Web Testing Using Nightwatch]]></title><description><![CDATA[Discover how to get started with web testing using Nightwatch, a powerful no-compromise test automation framework. Learn how to install Nightwatch, set up your testing environment, and write basic end-to-end tests.]]></description><link>https://blog.nightwatchjs.org/get-started-web-testing-using-nightwatch/</link><guid isPermaLink="false">689034e800bae33461ddef7c</guid><category><![CDATA[web testing]]></category><category><![CDATA[nightwatch v3]]></category><category><![CDATA[installation]]></category><category><![CDATA[get started]]></category><dc:creator><![CDATA[David Burns]]></dc:creator><pubDate>Mon, 17 Jul 2023 08:52:01 GMT</pubDate><media:content url="https://blog.nightwatchjs.org/content/images/2023/07/Banner@2x-6.png" medium="image"/><content:encoded><![CDATA[<h2 id="intro">Intro</h2><h3 id="a-series-on-web-testing-with-nightwatch">A Series on Web Testing with Nightwatch</h3><img src="https://blog.nightwatchjs.org/content/images/2023/07/Banner@2x-6.png" alt="Get Started with Web Testing Using Nightwatch"><p>Welcome to our blog series on testing websites and web apps in real browsers with Nightwatch. We will go through learning about testing step by step.</p><ul><li><strong>Getting started</strong> <em>(you&#x2019;re here)</em></li><li><strong>Complex scenarios</strong> and tests for websites</li><li>Test writing patterns focussing on <strong>Page Object Model</strong> (POM)</li><li>Generating <strong>HTML reports</strong> with <strong>DOM history</strong> for thorough analysis</li><li>Creating <strong>custom commands</strong> using Nightwatch</li></ul><p>Additionally, we&apos;ll explore two powerful features of Nightwatch:</p><ul><li>The <strong>Inspector tool</strong>, which enables you to write tests using a graphical interface, and</li><li>The <strong>Chrome Recorder</strong>, which allows you to create tests without writing code. We&apos;ll guide you through the process of using these tools effectively.</li></ul><p>To ensure comprehensive testing, we&apos;ll also discuss</p><ul><li>Running tests on <strong>CI</strong> &#x2013; <strong>GitHub Actions</strong></li><li><strong>Cross-browser testing</strong> using BrowserStack</li><li>Running tests on <strong>mobile browsers</strong></li></ul><p>By the end of this series, you will have a solid foundation in web testing with Nightwatch, enabling you to ensure the quality and reliability of your web projects.</p><p>In this initial blog post, we will focus on getting started with Nightwatch. From setting up Nightwatch to writing your first test and generating reports, we&apos;ll provide a step-by-step guide to get you started on your web testing journey using Nightwatch. You can also watch the <a href="#video-tutorial">video tutorial</a> of this post.</p><h4 id="a-brief-on-the-testing-space">A Brief on the Testing Space</h4><p>Software testing encompasses various types of testing to ensure the quality and reliability of applications. Unit testing validates individual code units, integration testing checks component interactions, and API testing focuses on API functionality. Visual regression testing detects visual changes, while end-to-end testing covers the entire application flow. Accessibility testing ensures inclusive user experiences. Cross-browser testing guarantees compatibility across different browsers, and mobile testing ensures optimal performance on mobile devices. Each type of testing serves a specific purpose and contributes to ensuring a high-quality software product.</p><h4 id="a-brief-on-nightwatch-%F0%9F%A6%89">A Brief on Nightwatch &#x1F989;</h4><p>Nightwatch is a no-compromise test automation framework that simplifies web and mobile testing for developers. Nightwatch comes with a powerful set of tools to write, run and debug your tests across web and native mobile applications. It seamlessly integrates with popular testing tools and services, enabling efficient test execution and analysis of results.</p><h2 id="setting-up-nightwatch">Setting up Nightwatch</h2><p>Let&apos;s get started. First, we need to set up Nightwatch in our development environment. Whether you&apos;re starting a new project or integrating Nightwatch into an existing one, we&apos;ve got you covered.</p><pre><code class="language-shell">npm init nightwatch &lt;project-name&gt;</code></pre><p>If you already have an existing web application, go into the root folder and run the following.</p><pre><code class="language-shell">npm init nightwatch</code></pre><p>Nightwatch will then ask a series of questions. Please answer the following.</p><pre><code class="language-shell">? Select testing type to setup for your project 
    &#x276F;&#x25C9; End-to-End testing
? Select language + test runner variant 
    &#x276F; JavaScript / default
? Select target browsers 
    &#x276F;&#x25C9; Chrome
? Enter source folder where test files are stored 
    test
? Enter the base_url of the project 
    https://nightwatchjs.org/
? Select where to run Nightwatch tests On 
    &#x276F; localhost
? Allow Nightwatch to collect completely anonymous usage metrics? 
    &#x276F; Yes
? Setup testing on Mobile devices as well? 
    &#x276F; No, skip for now</code></pre><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text"><strong>Note:</strong> Nightwatch supports TypeScript by default, different types of testing, other test runners and all major browsers. For the scope of this tutorial, we&apos;ll keep it simple and focus on End-to-End testing using JavaScript with no test runners on Chrome.</div></div><p>It is as simple as that to set up Nightwatch! Once you answer the questions, Nightwatch installs all the necessary dependencies and prepares your development environment for writing tests. For both new projects and existing ones, it&apos;s the exact same journey. You can read more about installation in our <a href="https://nightwatchjs.org/guide/quickstarts/create-and-run-a-nightwatch-test.html">Guide here</a>.</p><h2 id="your-first-test">Your First Test</h2><p>Now comes the exciting part &#x2013; writing your first test! We&apos;ll guide you through the fundamentals of creating test scripts with Nightwatch. </p><p>Nightwatch supports the popular BDD interfaces for writing tests - <code>describe</code> and <code>it</code> format. Let&apos;s start by defining the spec for our first test. In this test, we will go to the homage page of Nightwatch and check if the title is correct &#x2192; &#x201C;Introducing Nightwatch v3&#x201D;. </p><p>Create a file <code>home.spec.js</code> under <code>/test</code> folder with the following code.</p><pre><code class="language-js">describe(&apos;Nighwatch homepage&apos;, function() {
  it(&apos;Should have the correct title&apos;, function(browser) {
    browser.navigateTo(&apos;/&apos;).assert.textEquals(&apos;h1&apos;, &apos;Introducing Nightwatch v3&apos;)
  })
})</code></pre><h3 id="explanation">Explanation</h3><p><code><strong>browser.navigateTo</strong>(&apos;/&apos;)</code> - We request the browser to go to the path &apos;/&apos; from the launch URL we&apos;ve defined during installation. You can edit this in the config - <code>nightwatch.conf.js</code></p><p><code><strong>.assert.textEquals</strong>(&apos;h1&apos;, &apos;Introducing Nightwatch v3&apos;)</code> - We verify if the text in the element with the selector <code>h1</code> is equal to &quot;Introducing Nightwatch v3&quot; using the <a href="https://nightwatchjs.org/api/assert/textEquals.html#assert.textEquals">textEquals</a> function.</p><h3 id="running">Running</h3><p>Once your test script is saved, it&apos;s time to execute it with Nightwatch. Go to your command line and enter the following command.</p><pre><code class="language-shell">npx nightwatch test</code></pre><p>You should see the Chrome browser open up, navigate to the Nightwatch home page and close. The command line should have the following.</p><figure class="kg-card kg-image-card"><img src="https://blog.nightwatchjs.org/content/images/2023/07/image.png" class="kg-image" alt="Get Started with Web Testing Using Nightwatch" loading="lazy" width="1324" height="564" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2023/07/image.png 600w, https://blog.nightwatchjs.org/content/images/size/w1000/2023/07/image.png 1000w, https://blog.nightwatchjs.org/content/images/2023/07/image.png 1324w" sizes="(min-width: 720px) 720px"></figure><div class="kg-card kg-callout-card kg-callout-card-green"><div class="kg-callout-text"><strong>Congrats!! &#x1F44F;&#x1F44F; You&apos;ve successfully run your first test.</strong></div></div><h3 id="reports-and-debugging">Reports and Debugging</h3><p>After executing tests, Nightwatch generates detailed reports that provide invaluable insights. Copy the HTML report file path and paste it into a browser with the prefix <code>file://</code>, and you&apos;ll see the following report. We can check this report for debugging our tests as we write complex tests and face issues.</p><figure class="kg-card kg-image-card"><img src="https://blog.nightwatchjs.org/content/images/2023/07/image-20230711-102539.png" class="kg-image" alt="Get Started with Web Testing Using Nightwatch" loading="lazy" width="1800" height="930" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2023/07/image-20230711-102539.png 600w, https://blog.nightwatchjs.org/content/images/size/w1000/2023/07/image-20230711-102539.png 1000w, https://blog.nightwatchjs.org/content/images/size/w1600/2023/07/image-20230711-102539.png 1600w, https://blog.nightwatchjs.org/content/images/2023/07/image-20230711-102539.png 1800w" sizes="(min-width: 720px) 720px"></figure><h2 id="coming-up-next">Coming up Next</h2><h5 id="exploring-complex-testing-use-cases-and-advanced-techniques">Exploring Complex Testing Use Cases and Advanced Techniques</h5><p>You&apos;ve learnt how to set up a testing environment with Nightwatch and successfully write an end-to-end test. In our next blog post, we will dive deeper into the realm of website testing &#x2013; strategies for handling intricate testing scenarios, such as multi-tab interactions, complex selectors, iFrames, copy/paste, attribute assertions, using async/await, interacting with DOM elements, executing client JS and more. Stay tuned for our upcoming blog post on &quot;Complex Testing Scenarios for Websites&quot;. </p><h2 id="join-our-community-%F0%9F%92%AC">Join Our Community &#x1F4AC;</h2><p>If you have any questions, don&apos;t hesitate to visit our Discord server and say hello. Our community is always available to provide support, share insights, and assist you with any testing-related inquiries you may have. We welcome your active participation and look forward to connecting with you in our Discord community.</p><p><strong>Happy testing! &#x1F389;</strong></p><!--kg-card-begin: html--><div class="kg-card kg-button-card kg-align-center">
<a href="https://discord.com/invite/SN8Da2X" class="kg-btn kg-btn-accent" style="
    color: #fff;
">
<svg role="img" xmlns="http://www.w3.org/2000/svg" viewbox="-2 0 135 96" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" style="
    width: 30px;
    fill: #fff;
    margin-right: 10px;
">
              <title>Discord</title>
              <g id="&#x56FE;&#x5C42;_2" data-name="&#x56FE;&#x5C42; 2">
                <g id="Discord_Logos" data-name="Discord Logos">
                  <g id="Discord_Logo_-_Large_-_White" data-name="Discord Logo - Large - White">
                    <path d="M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,1-10.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z"/>
                  </g>
                </g>
              </g>
            </svg>
Join our Community
    </a>
</div><!--kg-card-end: html--><h2 id="video-tutorial">Video Tutorial</h2><figure class="kg-card kg-image-card kg-card-hascaption"><a href="https://www.youtube.com/watch?v=PCpMH86mO6c"><img src="https://blog.nightwatchjs.org/content/images/2023/07/Thumbnail-3--1-.png" class="kg-image" alt="Get Started with Web Testing Using Nightwatch" loading="lazy" width="1280" height="720" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2023/07/Thumbnail-3--1-.png 600w, https://blog.nightwatchjs.org/content/images/size/w1000/2023/07/Thumbnail-3--1-.png 1000w, https://blog.nightwatchjs.org/content/images/2023/07/Thumbnail-3--1-.png 1280w" sizes="(min-width: 720px) 720px"></a><figcaption>Get Started with Web Testing using Nightwatch - Video Tutorial</figcaption></figure>]]></content:encoded></item><item><title><![CDATA[Introducing Nightwatch v3—the only test automation framework you need]]></title><description><![CDATA[Nightwatch is a no-compromise test automation framework with a powerful set of tools to write, run and debug your tests across web and native mobile applications. 



]]></description><link>https://blog.nightwatchjs.org/introducing-v3/</link><guid isPermaLink="false">689034e800bae33461ddef7b</guid><category><![CDATA[new release]]></category><category><![CDATA[nightwatch v3]]></category><dc:creator><![CDATA[Nightwatch.js]]></dc:creator><pubDate>Thu, 22 Jun 2023 06:44:01 GMT</pubDate><media:content url="https://blog.nightwatchjs.org/content/images/2023/06/Banner@2x.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.nightwatchjs.org/content/images/2023/06/Banner@2x.png" alt="Introducing Nightwatch v3&#x2014;the only test automation framework you need"><p>We are excited to announce Nightwatch v3, a no-compromise test automation framework to write, run and debug your tests across web and native mobile applications.</p><h2 id="the-3-pillars-of-v3">The 3 Pillars of v3</h2><p>Nightwatch v3 has been redesigned around the three core pillars of <strong>developer experience, mobile-first, and one framework for everything testing.</strong></p><h3 id="developer-experience">Developer experience<br></h3><p>The entire experience for installing, writing, running, and debugging tests has been redesigned for an amazing developer experience:</p><p><strong>Installing &#x2013; Get started in 60 seconds</strong></p><p>The new installation helper in Nightwatch makes the setup of the framework and dependencies a breeze. Answer a few questions, and Nightwatch will do the entire setup for you based on your answers.</p><figure class="kg-card kg-image-card"><img src="https://blog.nightwatchjs.org/content/images/2023/06/image.png" class="kg-image" alt="Introducing Nightwatch v3&#x2014;the only test automation framework you need" loading="lazy" width="1340" height="564" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2023/06/image.png 600w, https://blog.nightwatchjs.org/content/images/size/w1000/2023/06/image.png 1000w, https://blog.nightwatchjs.org/content/images/2023/06/image.png 1340w" sizes="(min-width: 720px) 720px"></figure><p><strong>Writing &#x2013; Auto-wait. Selector playground. Simplified commands.</strong></p><p>Nightwatch automatically waits for elements to appear before attempting to interact with them, reducing the need for explicit wait commands in the test code. You can create and test selectors instantly with the <a href="https://www.youtube.com/watch?v=U8FbtsgPtU8">Selector Playground</a> and write test scripts that are easy to maintain.</p><p><strong>Running &#x2013; IDE integration. Default parallelization. Improved performance.</strong></p><p>Run your Nightwatch tests from VS Code itself without switching screens to run or debug your tests. Nightwatch also supports running <a href="https://nightwatchjs.org/guide/running-tests/parallel-running.html">tests in parallel</a> on your local machine or a cloud grid. We&#x2019;ve also improved our performance significantly for up to 25% faster tests than Nightwatch v2.</p><p><strong>Debugging &#x2013; DOM History. Pause and Debug. HTML reporter.</strong></p><p>View DOM changes and relive the tests visually as they happened with DOM History. Using Nightwatch Inspector, you can stop execution at any point in the test, get selector recommendations and debug issues. You can easily identify any issues in your Nightwatch tests using the built-in HTML reporter with test statuses, assertion logs, and raw HTTP logs.</p><h3 id="mobile-first">Mobile first</h3><p><strong>Native Apps, Mobile Web, and Flexible Mobile Testing.</strong></p><p>Test your native mobile and mobile web applications along with the flexibility to run tests on your own mobile device, emulators, or cloud platforms. Nightwatch also supports Safari, both desktop and mobile, out of the box. The best part is that you can configure all of this easily with the <a href="https://github.com/nightwatchjs/mobile-helper-tool">mobile-helper</a>.</p><h3 id="one-framework-for-everything-testing">One framework for everything testing</h3><p><strong>Test everything with a single framework.</strong></p><p>Avoid switching test automation frameworks for different types of testing. Here is a list of all the tests that you can run with Nightwatch:</p><ul><li>Unit testing</li><li>Integration testing</li><li>API testing</li><li>Component testing</li><li>Visual Regression testing (VRT)</li><li>Accessibility testing (A11Y)</li><li>End-to-end testing (E2E)</li><li>Mobile testing</li></ul><h2 id="faster-than-ever">Faster than ever</h2><p>This update significantly increases the performance of Nightwatch. Nightwatch v3 is up to 2.7x faster than Cypress when testing on multiple VMs. Here&#x2019;s a detailed comparison of Nightwatch against Cypress.</p><p><a href="https://github.com/nightwatchjs/performance_benchmarking">Try it yourself</a></p><figure class="kg-card kg-image-card"><img src="https://blog.nightwatchjs.org/content/images/2023/06/image-2.png" class="kg-image" alt="Introducing Nightwatch v3&#x2014;the only test automation framework you need" loading="lazy" width="1278" height="716" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2023/06/image-2.png 600w, https://blog.nightwatchjs.org/content/images/size/w1000/2023/06/image-2.png 1000w, https://blog.nightwatchjs.org/content/images/2023/06/image-2.png 1278w" sizes="(min-width: 720px) 720px"></figure><h2 id="what%E2%80%99s-next">What&#x2019;s next?</h2><p>Here&#x2019;s a quick preview of what&#x2019;s coming next.</p><p><strong>Even better Developer Experience</strong></p><ul><li>New commands for easy installation of more testing types &amp; plugins</li><li>Video recording and HTML reporter improvements</li><li>Keeping the drivers in sync with browsers using Selenium manager</li><li>Online Playground - write tests without having to set up Nightwatch</li><li>Switch between Nightwatch VRT and Percy with just a config change</li></ul><p><strong>Integrations Support</strong></p><ul><li>Svelte end-to-end and component testing with Nightwatch</li><li>Nightwatch integration with BrowserStack Test Observability</li><li>Improve CucumberJS reporter and output</li></ul><div class="kg-card kg-button-card kg-align-center"><a href="https://nightwatchjs.org/guide/quickstarts/create-and-run-a-nightwatch-test.html" class="kg-btn kg-btn-accent">Try Nightwatch V3</a></div><p></p>]]></content:encoded></item><item><title><![CDATA[Test your React Components with Nightwatch and Testing Library]]></title><description><![CDATA[React component testing in Nightwatch has been recently refined (via the @nightwatch/react plugin) and support for using the popular Testing Library with Nightwatch has been added.]]></description><link>https://blog.nightwatchjs.org/test-your-react-components-with-nightwatch-and-testing-library/</link><guid isPermaLink="false">689034e800bae33461ddef7a</guid><category><![CDATA[Component Testing]]></category><category><![CDATA[React]]></category><category><![CDATA[Vite]]></category><dc:creator><![CDATA[Andrei Rusu]]></dc:creator><pubDate>Sun, 08 Jan 2023 16:34:00 GMT</pubDate><media:content url="https://blog.nightwatchjs.org/content/images/2023/01/nightwatch-testing-library.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.nightwatchjs.org/content/images/2023/01/nightwatch-testing-library.png" alt="Test your React Components with Nightwatch and Testing Library"><p>Component testing in Nightwatch has been refined with version 2.4 and support for testing React components (via the <code><a href="https://github.com/nightwatchjs/nightwatch-plugin-react">@nightwatch/react</a></code> plugin) has been significantly improved. We also released a new plugin for using the popular <a href="https://testing-library.com/">Testing Library</a> with Nightwatch &#x2013; <code><a href="https://github.com/nightwatchjs/nightwatch-testing-library">@nightwatch/testing-library</a></code>, available since Nightwatch v2.6.</p><p>We&apos;re now going to build a detailed example of how to use Nightwatch and Testing Library to test React components. We&apos;ll be <a href="https://github.com/testing-library/react-testing-library#complex-example">Complex example</a> available on the <a href="https://www.npmjs.com/package/@testing-library/react">React Testing Library</a> docs, which is written with Jest.</p><p>This tutorial we&apos;ll cover how to:</p><ol><li>set up a new React project with <a href="https://vitejs.dev/">Vite</a>, which is also what Nightwatch uses internally for component testing;</li><li>install and configure Nightwatch and Testing Library;</li><li>mock API requests with the <code>@nightwatch/api-testing</code> plugin;</li><li>write a complex React component test using Nightwatch and Testing Library.</li></ol><h2 id="step-0-create-a-new-project"><strong>Step 0. Create a new project</strong></h2><p>To get started, we&apos;ll create a new project with Vite:</p><pre><code class="language-bash">npm init vite@latest
</code></pre><p>Select <code>React</code> and <code>JavaScript</code> when prompted. This will create a new project with React and JavaScript.</p><h2 id="step-1-install-nightwatch-and-testing-library"><strong>Step 1. Install Nightwatch and Testing Library</strong></h2><p><strong><strong>Testing Library</strong></strong> for React can be installed with the <code>@testing-library/react</code> package:</p><pre><code class="language-bash">npm i @testing-library/react --save-dev
</code></pre><p>To install Nightwatch, run the init command:</p><pre><code class="language-bash">npm init nightwatch@latest
</code></pre><p>Select <code>Component testing</code> and <code>React</code> when prompted. This will install <code>nightwatch</code> and the <code>@nightwatch/react</code> plugin. Choose a browser to install the driver for. We&apos;ll be using Chrome in this example.</p><h3 id="11-install-nightwatchtesting-library-plugin"><strong>1.1. Install @nightwatch/testing-library plugin</strong></h3><p>Since v2.6, Nightwatch provides its own plugin for using the Testing Library queries directly as commands. We&apos;re going to need it to write our test later on so let&apos;s install it now:</p><pre><code class="language-bash">npm i @nightwatch/testing-library --save-dev
</code></pre><h3 id="12-install-nightwatchapitesting-plugin"><strong>1.2 Install @nightwatch/apitesting plugin</strong></h3><p>The example contains a mock server that is needed to test the component. We&apos;ll be using the integrated mock server that comes with the <code>@nightwatch/apitesting</code> plugin. Install it with:</p><pre><code class="language-bash">npm i @nightwatch/apitesting --save-dev
</code></pre><h2 id="step-2-create-the-login-component"><strong>Step 2. Create the Login component</strong></h2><p>We&apos;ll use the same component as in the <a href="https://github.com/testing-library/react-testing-library#complex-example">React Testing Library</a> docs. Create a new file <code>src/Login.jsx</code> and add the following code:</p><pre><code class="language-js">// login.jsx
import * as React from &apos;react&apos;

function Login() {
  const [state, setState] = React.useReducer((s, a) =&gt; ({...s, ...a}), {
    resolved: false,
    loading: false,
    error: null,
  })

  function handleSubmit(event) {
    event.preventDefault()
    const {usernameInput, passwordInput} = event.target.elements

    setState({loading: true, resolved: false, error: null})

    window
      .fetch(&apos;http://localhost:3000/api/login&apos;, {
        method: &apos;POST&apos;,
        headers: {&apos;Content-Type&apos;: &apos;application/json&apos;},
        body: JSON.stringify({
          username: usernameInput.value,
          password: passwordInput.value,
        }),
      })
      .then(r =&gt; r.json().then(data =&gt; (r.ok ? data : Promise.reject(data))))
      .then(
        user =&gt; {
          setState({loading: false, resolved: true, error: null})
          window.localStorage.setItem(&apos;token&apos;, user.token)
        },
        error =&gt; {
          setState({loading: false, resolved: false, error: error.message})
        },
      )
  }

  return (
    &lt;div&gt;
      &lt;form onSubmit={handleSubmit}&gt;
        &lt;div&gt;
          &lt;label htmlFor=&quot;usernameInput&quot;&gt;Username&lt;/label&gt;
          &lt;input id=&quot;usernameInput&quot; /&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;label htmlFor=&quot;passwordInput&quot;&gt;Password&lt;/label&gt;
          &lt;input id=&quot;passwordInput&quot; type=&quot;password&quot; /&gt;
        &lt;/div&gt;
        &lt;button type=&quot;submit&quot;&gt;Submit{state.loading ? &apos;...&apos; : null}&lt;/button&gt;
      &lt;/form&gt;
      {state.error ? &lt;div role=&quot;alert&quot;&gt;{state.error}&lt;/div&gt; : null}
      {state.resolved ? (
        &lt;div role=&quot;alert&quot;&gt;Congrats! You&apos;re signed in!&lt;/div&gt;
      ) : null}
    &lt;/div&gt;
  )
}

export default Login
</code></pre><h2 id="step-3-create-the-component-test"><strong>Step 3. Create the component test</strong></h2><p>One of the founding principles of Testing Library is that tests should resemble how users interact with the application as much as possible. When writing component tests in Nightwatch using JSX, we need to write the test as a component story using the <a href="https://storybook.js.org/docs/react/api/csf">Component Story Format</a>, a declarative format introduced by <a href="https://storybook.js.org/">Storybook</a>.</p><p>This enables us to write tests that focus on how the component is used, rather than how it&apos;s implemented, which is in line with the Testing Library philosophy. You can read more about this in the <a href="https://nightwatchjs.org/guide/component-testing/write-jsx-react-tests.html">Nightwatch docs</a>.</p><p>The great thing about using this format to write our tests is that we can use the same code to write stories for our components, which can be used to document and showcase them in Storybook.</p><h3 id="31-login-with-valid-credentials-test"><strong>3.1 Login with valid credentials test</strong></h3><p>Create a new file <code>src/Login.spec.jsx</code> and add the following code, which does the same as the <a href="https://github.com/testing-library/react-testing-library#complex-example">complex example</a> written with Jest:</p><p>To render the component using JSX in Nightwatch, we simply create an export for the rendered component, optionally with a set of props. The <code>play</code> and <code>test</code> functions are used to interact with the component and verify the results.</p><ul><li><code>play</code> is used to interact with the component. It&apos;s executed in the browser context, so we can use the <code>screen</code> object from Testing Library to query the DOM and fire events;</li><li><code>test</code> is used to verify the results. It&apos;s executed in the Node.js context, so we can use the Nightwatch <code>browser</code> object to query the DOM and verify the results.</li></ul><pre><code class="language-js">// login.spec.jsx
import {render, fireEvent, screen} from &apos;@testing-library/react&apos;
import Login from &apos;../src/login&apos;

export default {
  title: &apos;Login&apos;,
  component: Login
}

export const LoginWithValidCredentials = () =&gt; &lt;Login /&gt;;
LoginWithValidCredentials.play = async ({canvasElement}) =&gt; {
  //fill out the form
};

LoginWithValidCredentials.test = async (browser) =&gt; {
  // verify the results
};
</code></pre><h3 id="add-the-mock-server"><strong>Add the mock server</strong></h3><p>The example uses a mock server to simulate a login request. We&apos;ll be using the integrated mock server that comes with the <code>@nightwatch/apitesting</code> plugin.</p><p>For this we&apos;ll use the <code>setup</code> and <code>teardown</code> hooks which we can write directly in the test file. Both hooks are executed in the Node.js context.</p><p>We also need to set login endpoint to <code>http://localhost:3000/api/login</code> in the <code>Login</code> component, which is the url to the mock server.</p><h3 id="complete-test-file"><strong>Complete test file</strong></h3><p>The complete test file will look like this:</p><pre><code class="language-js">// login.spec.jsx
import {render, fireEvent, screen} from &apos;@testing-library/react&apos;
import Login from &apos;../src/Login&apos;

let server;
const token = &apos;fake_user_token&apos;;
let serverResponse = {
  status: 200,
  body: {token}
};

export default {
  title: &apos;Login&apos;,
  component: Login,
  setup: async ({mockserver}) =&gt; {
    server = await mockserver.create();
    server.setup((app) =&gt; {
      app.post(&apos;/api/login&apos;, function (req, res) {
        res.status(serverResponse.status).json(serverResponse.body);
      });
    });

    await server.start(mockServerPort);
  },

  teardown: async (browser) =&gt; {
    await browser.execute(function() {
      window.localStorage.removeItem(&apos;token&apos;)  
    });
    
    await server.close();
  }
}

export const LoginWithValidCredentials = () =&gt; &lt;Login /&gt;;
LoginWithValidCredentials.play = async ({canvasElement}) =&gt; {
  //fill out the form
  fireEvent.change(screen.getByLabelText(/username/i), {
    target: {value: &apos;chuck&apos;},
  });

  fireEvent.change(screen.getByLabelText(/password/i), {
    target: {value: &apos;norris&apos;},
  });

  fireEvent.click(screen.getByText(/submit/i))
};

LoginWithValidCredentials.test = async (browser) =&gt; {
  const alert = await browser.getByRole(&apos;alert&apos;)
  await expect(alert).text.to.match(/congrats/i)

  const localStorage = await browser.execute(function() {
    return window.localStorage.getItem(&apos;token&apos;);
  });

  await expect(localStorage).to.equal(fakeUserResponse.token)
};</code></pre><h3 id="debugging"><strong>Debugging</strong></h3><p>One of the main benefits of using Nightwatch for component testing, besides having the same API available for end-to-end testing, is that we can run the tests in a real browser, instead of a virtual DOM environment, such as JSDOM.</p><p>This allows us to use the Chrome Dev Tools to debug the tests.</p><p>For example, let&apos;s go ahead and add a <code>debugger</code> statement in the <code>LoginWithValidCredentials.play</code> function:</p><pre><code class="language-js">LoginWithValidCredentials.play = async ({canvasElement}) =&gt; {
  //fill out the form
  fireEvent.change(screen.getByLabelText(/username/i), {
    target: {value: &apos;chuck&apos;},
  });

  fireEvent.change(screen.getByLabelText(/password/i), {
    target: {value: &apos;norris&apos;},
  });
  
  debugger;
  
  fireEvent.click(screen.getByText(/submit/i))
};</code></pre><p>Now, let&apos;s run the test with <code>--debug</code> and <code>--devtools</code> flags:</p><pre><code class="language-bash">npx nightwatch test/login.spec.jsx --debug --devtools
</code></pre><p>This will open a new Chrome window with the Dev Tools open. We can now set a breakpoint in the Dev Tools and step through the code.</p><figure class="kg-card kg-image-card"><img src="https://blog.nightwatchjs.org/content/images/2023/01/Screenshot-2023-01-03-at-22.20.12.png" class="kg-image" alt="Test your React Components with Nightwatch and Testing Library" loading="lazy" width="2000" height="1312" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2023/01/Screenshot-2023-01-03-at-22.20.12.png 600w, https://blog.nightwatchjs.org/content/images/size/w1000/2023/01/Screenshot-2023-01-03-at-22.20.12.png 1000w, https://blog.nightwatchjs.org/content/images/size/w1600/2023/01/Screenshot-2023-01-03-at-22.20.12.png 1600w, https://blog.nightwatchjs.org/content/images/size/w2400/2023/01/Screenshot-2023-01-03-at-22.20.12.png 2400w" sizes="(min-width: 720px) 720px"></figure><h3 id="32-login-with-server-exception-test"><strong>3.2 Login with server exception test</strong></h3><p>The original <a href="https://github.com/testing-library/react-testing-library#complex-example">example</a> from the Testing Library docs also includes a test for the case when the server throws an exception.</p><p>Let&apos;s try to write the same in Nightwatch. This time we&apos;ll use just the <code>test</code> function, since we can interact with the component this way as well. As we&apos;ve mentioned earlier, the <code>test</code> function is executed in the Node.js context, and it receives the Nightwatch <code>browser</code> object as argument.</p><p>We&apos;ll also need to update the mock server response to return a 500 status code and an error message. This we can easily accomplish by writing a <code>preRender</code> test hook on the <code>LoginWithServerException</code> component story.</p><pre><code class="language-js">export const LoginWithServerException = () =&gt; &lt;Login /&gt;;
LoginWithServerException.preRender = async (browser) =&gt; {
  serverResponse = {
    status: 500,
    body: {message: &apos;Internal server error&apos;}
  };
};

LoginWithServerException.test = async (browser) =&gt; {
  const username = await browser.getByLabelText(/username/i);
  await username.sendKeys(&apos;chuck&apos;);

  const password = await browser.getByLabelText(/password/i);
  await password.sendKeys(&apos;norris&apos;);

  const submit = await browser.getByText(/submit/i);
  await submit.click();

  const alert = await browser.getByRole(&apos;alert&apos;);
  await expect(alert).text.to.match(/internal server error/i);

  const localStorage = await browser.execute(function() {
    return window.localStorage.getItem(&apos;token&apos;);
  });

  await expect(localStorage).to.equal(token)
};

</code></pre><h2 id="4-run-the-test"><strong>4. Run the test</strong></h2><p>Finally, let&apos;s run the test. This will run the <code>LoginWithValidCredentials</code> and <code>LoginWithServerException</code> component stories in Chrome.</p><pre><code class="language-bash">npx nightwatch test/login.spec.jsx
</code></pre><p>To run the test without opening the browser, we can pass the <code>--headless</code> flag.</p><p>If all goes well, you should see the following output:</p><pre><code class="language-bash">[Login] Test Suite
&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;
&#x2139; Connected to ChromeDriver on port 9515 (1134ms).
  Using: chrome (108.0.5359.124) on MAC OS X.

Mock server listening on port 3000

  Running &lt;LoginWithValidCredentials&gt; component:
&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;
[browser] [vite] connecting...
[browser] [vite] connected.
  &#x2714; Expected element &lt;LoginWithValidCredentials&gt; to be visible (15ms)
  &#x2714; Expected element &lt;DIV[id=&apos;app&apos;] &gt; DIV &gt; DIV&gt; text to match: &quot;/congrats/i&quot; (14ms)
  &#x2714; Expected &apos;fake_user_token&apos;  to equal(&apos;fake_user_token&apos;): 

  &#x2728; PASSED. 3 assertions. (1.495s)

  Running &lt;LoginWithServerException&gt; component:
&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;
[browser] [vite] connecting...
[browser] [vite] connected.
  &#x2714; Expected element &lt;LoginWithServerException&gt; to be visible (8ms)
  &#x2714; Expected element &lt;DIV[id=&apos;app&apos;] &gt; DIV &gt; DIV&gt; text to match: &quot;/internal server error/i&quot; (8ms)
  &#x2714; Expected &apos;fake_user_token&apos;  to equal(&apos;fake_user_token&apos;): 

  &#x2728; PASSED. 3 assertions. (1.267s)

  &#x2728; PASSED. 6 total assertions (4.673s)
</code></pre><h2 id="5-conclusion"><strong>5. Conclusion</strong></h2><p>That&apos;s it! You can find the complete code for this example in the <a href="https://github.com/nightwatchjs-community/testing-library-example">GitHub repository</a>. PRs are welcome.</p><p>Fell free to drop by the <a href="https://discord.com/invite/SN8Da2X">Nightwatch Discord</a> if you have any questions or feedback.</p>]]></content:encoded></item><item><title><![CDATA[Component Driven Development with Storybook and Nightwatch]]></title><description><![CDATA[Storybook integration is part of Nightwatch starting with v2.4 via the @nightwatch/storybook plugin, currently available for React.]]></description><link>https://blog.nightwatchjs.org/component-driven-development-with-storybook-and-nightwatch/</link><guid isPermaLink="false">689034e800bae33461ddef79</guid><category><![CDATA[Component Testing]]></category><category><![CDATA[Storybook]]></category><dc:creator><![CDATA[Andrei Rusu]]></dc:creator><pubDate>Thu, 17 Nov 2022 20:41:58 GMT</pubDate><media:content url="https://blog.nightwatchjs.org/content/images/2022/12/Nightwatch-Storybook-integration-blog-banner.png" medium="image"/><content:encoded><![CDATA[<h2 id="introduction">Introduction</h2><img src="https://blog.nightwatchjs.org/content/images/2022/12/Nightwatch-Storybook-integration-blog-banner.png" alt="Component Driven Development with Storybook and Nightwatch"><p>Storybook integration is part of Nightwatch starting with <strong>v2.4</strong> via the <code><a href="https://nightwatchjs.org/guide/component-testing/storybook-component-testing.html">@nightwatch/storybook</a></code> plugin, currently available for React.</p><p>Storybook is arguably the most popular component library around at the moment, with a steady user base for React and growing communities for Vue, Svelte, Angular, and other UI libraries. It&#x2019;s being used by thousands of teams around the world to build UIs with reusable components.</p><p>The popularity of Storybook can probably be attributed to identifying one essential need that frontend developers have today: in order to be able to build modern complex UIs, frontend teams need to be able to design, build, and test UI components in isolation. Storybook calls this technique <strong>component driven development</strong> (CDD).</p><h2 id="component-driven-development">Component Driven Development</h2><p>Storybook aims to deliver a complete solution for managing large component libraries by offering compelling tools for documenting and testing. Each component is rendered in isolation with its various states and requirements.</p><p>Each representation of a component with various properties and arguments is called a <strong>story</strong> and all the stories belonging to a particular component are collected in a <code>.stories.js[x]</code> (or <code>.ts[x]</code>) file. Stories are written in a declarative syntax and each story simulates a particular component variation, by rendering the component with a specific set of props and mock data.</p><p>Here&#x2019;s a basic component story example:</p><!--kg-card-begin: markdown--><pre><code class="language-js">// Histogram.stories.js|jsx

import React from &apos;react&apos;;

import { Histogram } from &apos;./Histogram&apos;;

export default {
  title: &apos;Histogram&apos;,
  component: Histogram,
};

const Template = (args) =&gt; &lt;Histogram {...args} /&gt;;

export const Default = Template.bind({});
Default.args = {
  dataType: &apos;latency&apos;,
  showHistogramLabels: true,
  histogramAccentColor: &apos;#1EA7FD&apos;,
  label: &apos;Latency distribution&apos;,
};
</code></pre>
<!--kg-card-end: markdown--><p>Storybook is distributed as a Node web application which loads the existing stories and displays them in a sophisticated management interface which has integrated tools for documenting and testing the components.</p><!--kg-card-begin: html--><div class="storybook-ui-video"><video autoplay playsinline loop><source src="https://storybook.js.org/0f37e3bc4895c3ad120d760b704a2ee1/7.0-storybook-hero-video.mp4" type="video/mp4"></video></div><!--kg-card-end: html--><p>The Storybook app can run locally or it can be deployed on a web server. In fact many popular component libraries are <a href="https://storybook.js.org/showcase"><strong>available to the public</strong></a>.</p><h3 id="how-to-test-component-stories">How to test component stories</h3><p>Presently, Storybook is used mainly as a great collaboration tool between frontend developers and designers to document the UI components and even entire pages.</p><p>That is all fine until testing comes into the picture and starts complicating everything. That&#x2019;s when the real fun begins, because in order to effectively develop UI components, an efficient way to easily test them is also needed.</p><p>Automated testing of components is needed to ensure that all stories are rendered properly with the specified props and mock data. Furthermore, more complex components can have stories which require simulating user actions and verifying behaviour.</p><p>Out of the box, Storybook provides built-in support for several testing strategies of components:</p><ul><li><a href="https://storybook.js.org/docs/react/writing-tests/visual-testing">visual tests</a></li><li><a href="https://storybook.js.org/docs/react/writing-tests/interaction-testing">interactive tests</a></li><li><a href="https://storybook.js.org/docs/react/writing-tests/accessibility-testing">accessibility tests</a></li><li><a href="https://storybook.js.org/docs/react/writing-tests/snapshot-testing">snapshot testing</a></li></ul><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.nightwatchjs.org/content/images/2022/11/stories-are-tests.gif" class="kg-image" alt="Component Driven Development with Storybook and Nightwatch" loading="lazy" width="714" height="422"><figcaption>Image credits: https://storybook.js.org/docs/react/writing-tests/introduction</figcaption></figure><p>So there is some built-in support for testing and also a <a href="https://storybook.js.org/docs/react/writing-tests/test-runner">CLI test runner</a> which uses <strong>Playwright</strong> and <strong>Jest</strong> under the hood. However its strength still remains more on the design side of the whole web application development spectrum.</p><p>In order to have strong confidence over the code quality for the components that you build, you will need to either extend the stories with additional support for component testing or import stories into other tests.</p><h2 id="integrate-nightwatch-into-your-storybook">Integrate Nightwatch into your Storybook</h2><figure class="kg-card kg-image-card"><img src="https://blog.nightwatchjs.org/content/images/2022/11/nightwatch-logo.png" class="kg-image" alt="Component Driven Development with Storybook and Nightwatch" loading="lazy" width="1000" height="404" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2022/11/nightwatch-logo.png 600w, https://blog.nightwatchjs.org/content/images/2022/11/nightwatch-logo.png 1000w" sizes="(min-width: 720px) 720px"></figure><p>Nightwatch can assist here with filling the gap between UI component design+development and QA+testing. In order to add support for automated testing of components in a Storybook environment, you only need to add install Nightwatch and extend your existing stories with test functionality.</p><p>In the following section we will attempt to do just that. We&#x2019;ll take an existing Storybook which is available publicly on Github and we&#x2019;ll go through these steps:</p><ol><li>install and configure Nightwatch</li><li>run the existing component stories with Nightwatch</li><li>extend one of the complex stories and with Nightwatch testing functionality</li></ol><p>Let us begin then. We&#x2019;ll use the <a href="https://www.wfp.org/">World Food Programme</a>&#x2019;s Ui kit available on Github at <a href="https://github.com/wfp/designsystem"><strong>https://github.com/wfp/designsystem</strong></a>.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.nightwatchjs.org/content/images/2022/11/wfp-uikit.png" class="kg-image" alt="Component Driven Development with Storybook and Nightwatch" loading="lazy" width="1061" height="603" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2022/11/wfp-uikit.png 600w, https://blog.nightwatchjs.org/content/images/size/w1000/2022/11/wfp-uikit.png 1000w, https://blog.nightwatchjs.org/content/images/2022/11/wfp-uikit.png 1061w" sizes="(min-width: 720px) 720px"><figcaption><a href="http://www.wfp.org/UIGuide" rel="noopener noreferrer nofollow">wfp.org/UIGuide</a></figcaption></figure><h3 id="install-dependencies">Install Dependencies</h3><p>We&#x2019;ll first have to fork the project. My own fork is located at <a href="https://github.com/pineviewlabs/wfp-designsystem"><strong>github.com/pineviewlabs/wfp-designsystem</strong></a>. I&#x2019;m going to clone the project locally and install the existing dependencies:</p><p>The <code>--legacy-peer-deps</code> flag is needed to make some older dependencies install. If you get <code>npm audit</code> messages, you can disregard them for now, since this is just a tutorial.</p><h3 id="run-storybook">Run Storybook</h3><p>Once everything is installed, you can try running Storybook locally. To do that, run:</p><!--kg-card-begin: markdown--><pre><code class="language-sh">npm run storybook
</code></pre>
<!--kg-card-end: markdown--><p>This will build the Storybook files and run the project on your local host.</p><p>At the moment of writing this guide, the Storybook version used in the WFP design kit is 6.2. You can try to upgrade it to at least v6.5 but I already tried that and got a bunch of errors, so for the moment I am sticking with the 6.2 just to get everything working together.</p><h3 id="install-nightwatch">Install Nightwatch</h3><p>Nightwatch can be installed with just one command:</p><!--kg-card-begin: markdown--><pre><code class="language-sh">npm init nightwatch@latest
</code></pre>
<!--kg-card-end: markdown--><p>This will prompt you to install the browsers and location of the test files. I have selected all of them Chrome, Firefox, Safari, and Edge. Edge needs to be installed separately but the init tool will generate the config needed in Nightwatch.</p><figure class="kg-card kg-image-card"><img src="https://blog.nightwatchjs.org/content/images/2022/11/init-nightwatch.png" class="kg-image" alt="Component Driven Development with Storybook and Nightwatch" loading="lazy" width="768" height="550" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2022/11/init-nightwatch.png 600w, https://blog.nightwatchjs.org/content/images/2022/11/init-nightwatch.png 768w" sizes="(min-width: 720px) 720px"></figure><p>For the source folder location enter the following:</p><pre><code>src/components/**/*.stories.js</code></pre><p>For base url enter: </p><pre><code>http://localhost:9000/</code></pre><p>We&#x2019;ll also need to install the Storybook plugin for Nightwatch:</p><!--kg-card-begin: markdown--><pre><code class="language-sh">npm install @nightwatch/storybook
</code></pre>
<!--kg-card-end: markdown--><p>You might need to pass <code>--legacy-peer-deps</code> again, if you&#x2019;re on newer NPM versions.</p><p>Last step is to load and configure the plugin in Nightwatch. To do that, edit <code>nightwatch.conf.js</code> and add the following right after <code>src_folders</code>:</p><!--kg-card-begin: markdown--><pre><code class="language-js">// nightwatch.conf.js
module.exports = {
  // .. other settings
  plugins: [&apos;@nightwatch/storybook&apos;],

  &apos;@nightwatch/storybook&apos;: {
    start_storybook: false, 
    storybook_url: &apos;http://localhost:9000/&apos;
  }
}

</code></pre>
<!--kg-card-end: markdown--><p>Nightwatch can automatically start/stop Storybook for us during the test run, but since this particular version of Storybook takes a bit of time to load, we have kept <code>start_storybook</code> to <code>false</code> and we will run it manually.</p><h2 id="run-stories-in-nightwatch">Run stories in Nightwatch</h2><p>The <code>@nightwatch/storybook</code> plugin is designed to work in such a way that component tests can be added on top of existing component stories, instead of expecting users to import stories in tests. When using Nightwatch with Storybook, the test is the <code>.stories</code> file itself.</p><p>In our case, we are going to run the existing <code>src/component/**/*.stories.js</code> files as tests. But before we can do that, we need to configure one last thing.</p><h3 id="customise-esbuild">Customise esbuild</h3><p>Nightwatch uses <code>esbuild</code> under the hood in order to parse JSX files and this project contains some syntax features which <code>esbuild</code> doesn&#x2019;t support them by default. However, we can support them by enabling compilation using <code>babel</code>.</p><p>To do so, edit <code>nightwatch.conf.js</code> and add the following, right after the line which contains <code>&apos;@nightwatch/storybook&apos;</code>:</p><!--kg-card-begin: markdown--><pre><code class="language-js">// nightwatch.conf.js
module.exports = {
  // other settings here...
  esbuild: {
    babel: {
      filter: /\.[cm]?js$/
    }
  }
}
</code></pre>
<!--kg-card-end: markdown--><h3 id="add-babel">Add Babel</h3><p>Add a <code>babel.config.json</code> file with the following content so that <code>esbuild</code> can find it:</p><pre><code>{
  &quot;exclude&quot;: [&quot;node_modules/**&quot;],
  &quot;presets&quot;: [
    &quot;@babel/preset-env&quot;,
    &quot;@babel/preset-react&quot;
  ],
  &quot;plugins&quot;: [
    &quot;@babel/plugin-proposal-export-namespace-from&quot;,
    &quot;@babel/plugin-proposal-export-default-from&quot;
  ]
}</code></pre><h3 id="run-nightwatch">Run Nightwatch</h3><p>Now the time has come to actually run the component stories. The project already has some unit-level type of component tests written in Jest and using Enzyme. We&#x2019;re going to not touch them and instead work with the actual <code>.stories</code> files.</p><p>We&#x2019;re just going to do an exploratory test run using Chrome, and we&#x2019;ll do it in <code>--serial</code> mode so we can observe the browser:</p><!--kg-card-begin: markdown--><pre><code class="language-sh">npx nightwatch --env chrome --serial
</code></pre>
<!--kg-card-end: markdown--><p>Running all the stories in the project in serial mode could take a while. But we can try to run them in parallel (you can replace &#x201C;chrome&#x201D; with either &#x201C;firefox&#x201D;, &#x201C;safari&#x201D;, or &#x201C;edge&#x201D;, depending on which browsers you have installed).</p><p>By default it will pick up the number of test workers based on the number of CPU cores, but we will set it to 4. We&#x2019;ll also run it in <code>--headless</code> mode so the browsers won&#x2019;t popup and distract us (note that headless mode is not available in Safari):</p><!--kg-card-begin: markdown--><pre><code class="language-sh">npx nightwatch --env chrome --workers=4 --headless
</code></pre>
<!--kg-card-end: markdown--><p>So by now hopefully we have a working Nightwatch installation in the WFP Storybook project. At the moment, the stories will only be rendered and Nightwatch will perform a visibility check to ensure that everything is OK.</p><p>Next step though is to extend one of the stories and add some Nightwatch specific functionality.</p><h2 id="extend-stories-with-nightwatch-test">Extend stories with Nightwatch test</h2><p>We&#x2019;re going to pick one of the larger stories in the project and start adding additional test functionality. It seems like <code>src/components/Form/Form.stories.js</code> it&#x2019;s a good candidate in terms of complexity so we&#x2019;re going with that one.</p><p>Let&#x2019;s run it first separately:</p><!--kg-card-begin: markdown--><pre><code class="language-sh">npx nightwatch src/components/Form/Form.stories.js -e chrome
</code></pre>
<!--kg-card-end: markdown--><p>There are four different stories in the file and the output should look similar to this:</p><pre><code>[Form.stories.js component] Test Suite
&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;
  Using: chrome (107.0.5304.110) on MAC OS X.


  Running &quot;Default&quot; story:
&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;
  &#x2714; Passed [ok]: &quot;components-forms-form--default.Default&quot; story was rendered successfully.

  &#x2728; PASSED. 1 assertions. (1.078s)

  Running &quot;Detailed Form&quot; story:
&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;
  &#x2714; Passed [ok]: &quot;components-forms-form--detailed-form.DetailedForm&quot; story was rendered successfully.

  &#x2728; PASSED. 1 assertions. (583ms)

  Running &quot;Login&quot; story:
&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;
  &#x2714; Passed [ok]: &quot;components-forms-form--login.Login&quot; story was rendered successfully.

  &#x2728; PASSED. 1 assertions. (411ms)

  Running &quot;Contact&quot; story:
&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;
  &#x2714; Passed [ok]: &quot;components-forms-form--contact.Contact&quot; story was rendered successfully.

  &#x2728; PASSED. 1 assertions. (513ms)

  &#x2728; PASSED. 4 total assertions (5.768s)</code></pre><h3 id="add-nightwatch-file-uploading-test">Add Nightwatch file uploading test</h3><p>Nightwatch can run Storybook <a href="https://storybook.js.org/docs/react/writing-tests/interaction-testing">interaction tests</a> and <a href="https://storybook.js.org/docs/react/writing-tests/accessibility-testing">accessibility tests</a>, together with supporting the hooks api. However, for this article we&apos;re only going to explore the <code>test()</code> function which Nightwatch adds on top of the <a href="https://storybook.js.org/docs/react/api/csf">Component Story Format</a>. You can read more about the Storybook integration on the <a href="https://nightwatchjs.org/guide/component-testing/storybook-component-testing.html">Nightwatch documentation</a>.</p><p>We&#x2019;re going to extend the <code>DetailedForm</code> story so let&#x2019;s go ahead and edit the <code>src/components/Form/Form.stories.js</code>and add the following right before that line with <code>export const Login</code> (around line 400):</p><div class="kg-card kg-callout-card kg-callout-card-grey"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text">The <code>test()</code> function runs in the Node context so it has access to the file system, as opposed to the <code>play()</code> function which is limited by the browser sandbox.</div></div><p>The <code>test()</code> function receives both the Nightwatch <code>browser</code> API (which can be used to issue commands and run assertions) and a <code>component</code> object which points to the root element in the story and it is compatible with Nightwatch commands and assertions.</p><p>In this example will simulate the uploading of a file, using Nightwatch <code>uploadFile()</code> api command and we&#x2019;ll verify if the file drop zone element has been updated.</p><!--kg-card-begin: markdown--><pre><code class="language-js">// src/components/Form/Form.stories.js
DetailedForm.test = async (browser, {component}) =&gt; {
  await browser.uploadFile(&apos;input[type=&quot;file&quot;]&apos;, require.resolve(&apos;./README.mdx&apos;));

  const fileElementContainer = await browser.findElement(`.${settings.prefix}--file-container`);
  const elementHasDescendants = await browser.hasDescendants(fileElementContainer);
  
  await browser.strictEqual(
    elementHasDescendants, true, &apos;The file dropzone element has been populated.&apos;
  );
};

</code></pre>
<!--kg-card-end: markdown--><p>Also add this import at the top of the file:</p><!--kg-card-begin: markdown--><pre><code class="language-js">// src/components/Form/Form.stories.js
import settings from &apos;../../globals/js/settings&apos;;
</code></pre>
<!--kg-card-end: markdown--><p>We can now run only the <code>DetailedForm</code> story:</p><!--kg-card-begin: markdown--><pre><code class="language-sh">npx nightwatch src/components/Form/Form.stories.js -e chrome --story=DetailedForm
</code></pre>
<!--kg-card-end: markdown--><p>Hopefully all is well and the output should look like below (there might be some warnings on top, but those aren&#x2019;t critical):</p><pre><code>[Form.stories.js component] Test Suite
&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;
  Using: chrome (107.0.5304.110) on MAC OS X.


  Running &quot;Detailed Form&quot; story:
&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;&#x2500;
  &#x2714; Passed [ok]: &quot;components-forms-form--detailed-form.DetailedForm&quot; story was rendered successfully.
  &#x2714; Passed [strictEqual]: The file dropzone element has been populated.

  &#x2728; PASSED. 2 assertions. (1.217s)</code></pre><h2 id="conclusion">Conclusion</h2><p>That&#x2019;s pretty much it for now. I might write another similar post using a different public storybook library. Or maybe you might want to contribute one? The great humans at Storybook have recently started to put together a collection of public storybook libraries in their <a href="https://storybook.js.org/showcase"><strong>Component Encyclopedia</strong></a> so there&#x2019;s plenty of opportunity to experiment and maybe even make open-source contributions.</p><p>If you made it thus far in the tutorial, I salute you! You are now ready to make a contribution to an open-source project that&#x2019;s being used at the <a href="https://www.un.org/en/"><strong>United Nations</strong></a>, which is quite something.</p><p>Thanks for reading and don&#x2019;t forget to wear your hat as you please &#x2013; indoors or out.</p>]]></content:encoded></item><item><title><![CDATA[New Nightwatch VS Code Extension]]></title><description><![CDATA[Stay in your zone while testing. Run your Nightwatch tests from VS Code itself without switching windows or screens to run or debug your tests.]]></description><link>https://blog.nightwatchjs.org/new-nightwatch-visual-studio-code-extension/</link><guid isPermaLink="false">689034e800bae33461ddef78</guid><category><![CDATA[Getting Started]]></category><category><![CDATA[vs code]]></category><dc:creator><![CDATA[Bipul Jain]]></dc:creator><pubDate>Fri, 07 Oct 2022 09:13:23 GMT</pubDate><media:content url="https://blog.nightwatchjs.org/content/images/2022/10/Nightwatch-VS-Code-Integration-780-x-420.png" medium="image"/><content:encoded><![CDATA[<figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/nBv1neUu3Gs?start=193&amp;feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen title="New VS Code Integration, Accessibility Testing and more: Nightwatch Release Walkthrough v2.3.6-2.3.8"></iframe></figure><img src="https://blog.nightwatchjs.org/content/images/2022/10/Nightwatch-VS-Code-Integration-780-x-420.png" alt="New Nightwatch VS Code Extension"><p>We are excited to share that you can now run and debug your Nightwatch tests from VS Code itself, without having to switch screens or windows. The extension gets auto-activated if you have a Nightwatch conf.js file. You can also add it manually with the Install Nightwatch action.</p><p>As developers, we often have moments where we are in a flow or a zone and the quality of code we produce at that moment is the best of us. However, the smallest of distractions could knock you out of that zone. The new Nightwatch extension for VS Code allows you to stay focussed by helping you to run and debug your tests from VS Code itself.</p><p>Here&#x2019;s what you can do with the extension:</p><h3 id="easy-installation">Easy Installation</h3><p>The extension will be auto-activated if you have a <code>nightwatch.conf.js</code> file. You can also add it manually with the Install Nightwatch action. The installation guide will ask you for your choice of browsers to be installed.</p><figure class="kg-card kg-image-card"><img src="https://user-images.githubusercontent.com/8705386/190579688-0bb1b1fa-161e-4e10-a409-a18df2672f31.gif" class="kg-image" alt="New Nightwatch VS Code Extension" loading="lazy"></figure><h3 id="run-and-debug-your-tests">Run and Debug your tests</h3><p>Run single or multiple tests from your sidebar or with the Run command. Easily debug your tests by setting up a breakpoint. VS Code will pause your tests at the breakpoints you have set.</p><figure class="kg-card kg-image-card"><img src="https://user-images.githubusercontent.com/8705386/190579700-30e75b82-be29-4ba8-bdc6-2b669f7b8a8f.gif" class="kg-image" alt="New Nightwatch VS Code Extension" loading="lazy"></figure><figure class="kg-card kg-image-card"><img src="https://user-images.githubusercontent.com/8705386/190579636-5b68c60f-f2be-44ec-b4ab-2e6c13d5c748.gif" class="kg-image" alt="New Nightwatch VS Code Extension" loading="lazy"></figure><h3 id="view-tests-results">View tests results</h3><p>This extension simplifies test results for you. You can view individual or aggregate test results and can also view the output of the test execution in the VS code terminal.</p><figure class="kg-card kg-image-card"><img src="https://blog.nightwatchjs.org/content/images/2022/10/image.png" class="kg-image" alt="New Nightwatch VS Code Extension" loading="lazy" width="1080" height="675" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2022/10/image.png 600w, https://blog.nightwatchjs.org/content/images/size/w1000/2022/10/image.png 1000w, https://blog.nightwatchjs.org/content/images/2022/10/image.png 1080w" sizes="(min-width: 720px) 720px"></figure><p>For more details, check out the VS Code extension <a href="https://marketplace.visualstudio.com/items?itemName=browserstackcom.nightwatch">here</a>. You can also raise issues on <a href="https://github.com/nightwatchjs/nightwatch/issues">GitHub</a> or discuss any questions you have on <a href="https://discord.com/invite/SN8Da2X">Discord</a>.</p>]]></content:encoded></item><item><title><![CDATA[Introducing Nightwatch Chrome Recorder]]></title><description><![CDATA[Run Nightwatch tests without writing a single line of code. Record your tests with Chrome DevTools test recorder and download the test script]]></description><link>https://blog.nightwatchjs.org/introducing-nightwatch-chrome-recorder/</link><guid isPermaLink="false">689034e800bae33461ddef77</guid><dc:creator><![CDATA[Bipul Jain]]></dc:creator><pubDate>Mon, 29 Aug 2022 12:52:49 GMT</pubDate><media:content url="https://blog.nightwatchjs.org/content/images/2022/08/Nightwatch-Chrome-Recorder-thumbnail.png" medium="image"/><content:encoded><![CDATA[<figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/eYj4vuEjlRM?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen title="New Chrome extension: Generate Nightwatch tests from Chrome DevTools Recorder"></iframe></figure><img src="https://blog.nightwatchjs.org/content/images/2022/08/Nightwatch-Chrome-Recorder-thumbnail.png" alt="Introducing Nightwatch Chrome Recorder"><p>We are excited to introduce the new <a href="https://chrome.google.com/webstore/detail/nightwatch-chrome-recorde/nhbccjfogdgkahamfohokdhcnemjafjk/">Nightwatch Chrome Recorder</a> extension that helps you generate Nightwatch test scripts without writing a single line of code. </p><h2 id="test-without-writing-a-single-line-of-code">Test without writing a single line of code</h2><p>Nightwatch Chrome Recorder helps you to export Chrome DevTools recording as Nightwatch test scripts. This will speed up your development cycle by creating integrated or end-to-end tests instantly. In fact, a <a href="https://learn.gitlab.com/c/2021-devsecops-report?x=u5RjB_">recent survey by Gitlab</a> revealed that 49% of organizations had already started using Low Code/No code tools.</p><p>This is based on the <a href="https://developer.chrome.com/docs/devtools/recorder/">Chrome DevTools Recorder</a>, a tool that allows you to record and replay test actions directly in the browser. We decided to use it since it&#x2019;s plugged into the browser, giving the convenience of not switching context or dealing with other third-party tools.</p><h2 id="how-to-use">How to use</h2><p>Here is how you can generate your Nightwatch script in 4 simple steps:</p><ol><li>Install the <a href="https://chrome.google.com/webstore/detail/nightwatch-chrome-recorde/nhbccjfogdgkahamfohokdhcnemjafjk/">extension</a></li><li>Navigate to the Recorder section in Chrome DevTools</li><li>Start recording and perform all the actions in your test like a typical user would</li><li>Stop the recording. You can now click on export and select &#x2018;Export as Nightwatch Test Script&#x2019; to get your tests.</li></ol><p>Please refer to our <a href="https://nightwatchjs.org/guide/writing-tests/chrome-devtools-recorder.html">documentation</a> if you need more details, or reach out to us on <a href="https://discord.gg/SN8Da2X">Discord</a> if you have any questions.<br></p>]]></content:encoded></item><item><title><![CDATA[Publish your Nightwatch HTML Report on Github Pages]]></title><description><![CDATA[Use Github to Run and publish your Nightwatch test report.

]]></description><link>https://blog.nightwatchjs.org/publish-your-nightwatch-html-report-on-github-pages/</link><guid isPermaLink="false">689034e800bae33461ddef76</guid><dc:creator><![CDATA[Ravi Sawlani]]></dc:creator><pubDate>Thu, 23 Jun 2022 17:02:50 GMT</pubDate><media:content url="https://blog.nightwatchjs.org/content/images/2022/06/html-report.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.nightwatchjs.org/content/images/2022/06/html-report.png" alt="Publish your Nightwatch HTML Report on Github Pages"><p>Nightwatch v2.2 brings its own integrated <a href="https://nightwatchjs.org/guide/reporters/use-html-reporter.html" rel="noopener noreferrer">HTML reporter</a> which better aggregates test results along with other details. In this blog, we will set up the Nightwatch project which automatically publishes the generated HTML report on GitHub pages after the test tun.</p><p>Here is the preview of Nightwatch HTML Report:</p><figure class="kg-card kg-image-card"><img src="https://blog.nightwatchjs.org/content/images/2022/06/173353290-72dc2dfc-ab33-4cf9-8271-7d67929fb821.png" class="kg-image" alt="Publish your Nightwatch HTML Report on Github Pages" loading="lazy" width="2000" height="1126" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2022/06/173353290-72dc2dfc-ab33-4cf9-8271-7d67929fb821.png 600w, https://blog.nightwatchjs.org/content/images/size/w1000/2022/06/173353290-72dc2dfc-ab33-4cf9-8271-7d67929fb821.png 1000w, https://blog.nightwatchjs.org/content/images/size/w1600/2022/06/173353290-72dc2dfc-ab33-4cf9-8271-7d67929fb821.png 1600w, https://blog.nightwatchjs.org/content/images/size/w2400/2022/06/173353290-72dc2dfc-ab33-4cf9-8271-7d67929fb821.png 2400w" sizes="(min-width: 720px) 720px"></figure><!--kg-card-begin: markdown--><h2 id="create-project">Create Project</h2>
<h3 id="1-setup-nightwatch">1. Setup Nightwatch</h3>
<p>I am using the <a href="https://github.com/nightwatchjs/nightwatch-examples">nightwatch-examples</a> repo as a template to set up some example tests.</p>
<p>You can also use the Nightwatch <code>init</code> command which would manage all the config and dependencies as well as add some example tests in your project.</p>
<!--kg-card-end: markdown--><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text">You can read more about Nightwatch Onboarding client <a href="https://nightwatchjs.org/blog/introducing-onboarding-client-for-nightwatch/" rel="noopener noreferrer">here</a></div></div><pre><code class="language-bash">npm init nightwatch
</code></pre><!--kg-card-begin: markdown--><h3 id="2-run-the-tests-locally">2. Run the tests locally</h3>
<p>To check if the tests are running locally,in the nightwatch-examples template there is already a test script in <code>package.json</code>:</p>
<pre><code class="language-json">// package.json

&quot;scripts&quot;: {
    &quot;test&quot;: &quot;nightwatch --env chrome&quot;
  },
</code></pre>
<p>Run the tests with:</p>
<pre><code class="language-bash">npm test
</code></pre>
<!--kg-card-end: markdown--><!--kg-card-begin: markdown--><h2 id="define-github-workflow">Define GitHub  workflow</h2>
<p>Let&apos;s move on to automating the execution and publishing of the test report with GitHub actions.</p>
<h3 id="1-create-test-workflow">1. Create Test Workflow</h3>
<p>Create a directory <code>.github/workflows</code> and add <code>test.yml</code></p>
<pre><code class="language-yml">//test.yml

name: nightwatch.tests
on:
  push:
    branches: 
    - main
jobs:
  tests: 
    name: &apos;nightwatch tests&apos;
    timeout-minutes: 60
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - uses: actions/setup-node@v2
        with:
          node-version: &quot;14.x&quot;
      - name: Install dependencies
        run: npm ci
      - name: Run Nightwatch tests
        continue-on-error: true
        run: xvfb-run --auto-servernum npm test -- --env chrome
      - name: &quot;Publish test results&quot;
        uses: peaceiris/actions-gh-pages@v3.7.3
        with: 
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: &apos;./tests_output/nightwatch-html-report&apos;
          keep_files: true
          user_name: &lt;user-name&gt;
          user_email: &lt;user-email&gt;
</code></pre>
<p>I have selected the main branch to run GitHub Actions. In the following steps, it downloads the dependencies, runs tests, and publishes reports to a branch <code>gh-pages</code> which will be used to host the  HTML page.</p>
<p>Some configuration details:</p>
<ul>
<li><code>continue-on-error</code> is set to true as we need to publish reports in case of failure.</li>
<li><code>publish_dir</code>  points to the directory where the Nightwatch HTML report is generated by default. These can be changed using the Nightwatch output configuration.</li>
<li><code>user_name</code>, <code>user_email</code>, and <code>github_token</code> are used to create a commit and push content to the selected branch.</li>
</ul>
<!--kg-card-end: markdown--><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text">Read more about <a href="https://docs.github.com/en/actions">Github Actions</a></div></div><p>Running tests in headless mode is not always 100% reliable, so we have added &#xA0;support for using <code>xvfb</code> to run tests in Chrome.</p><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text">Xvfb is an X server that can run on Linux machines with no display hardware or physical input devices. It emulates a frame buffer using virtual memory.</div></div><!--kg-card-begin: markdown--><h3 id="2-setup-github-pages">2. Setup GitHub Pages</h3>
<p>And the final step is to enable GitHub Pages for your project under  <strong>Settings &#x2192; Pages.</strong></p>
<!--kg-card-end: markdown--><figure class="kg-card kg-image-card"><img src="https://blog.nightwatchjs.org/content/images/2022/06/screenshot_2022-06-23_at_9.38.14_pm.png" class="kg-image" alt="Publish your Nightwatch HTML Report on Github Pages" loading="lazy" width="1766" height="708" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2022/06/screenshot_2022-06-23_at_9.38.14_pm.png 600w, https://blog.nightwatchjs.org/content/images/size/w1000/2022/06/screenshot_2022-06-23_at_9.38.14_pm.png 1000w, https://blog.nightwatchjs.org/content/images/size/w1600/2022/06/screenshot_2022-06-23_at_9.38.14_pm.png 1600w, https://blog.nightwatchjs.org/content/images/2022/06/screenshot_2022-06-23_at_9.38.14_pm.png 1766w" sizes="(min-width: 720px) 720px"></figure><p>And we are good to go &#x2B50;.</p><p>To verify everything is set up correctly push all the changes to GitHub which triggers Actions.</p><div class="kg-card kg-callout-card kg-callout-card-purple"><div class="kg-callout-emoji">&#x1F680;</div><div class="kg-callout-text">Check out the test report from the demo project <a href="https://nightwatchjs.github.io/nightwatch-examples">here</a></div></div><!--kg-card-begin: markdown--><h3 id="3-triggering-test-workflows">3. Triggering Test Workflows</h3>
<p>Typically we want to run the jobs not only when tests are updated but also when there is a new deployment or a need to schedule jobs.</p>
<!--kg-card-end: markdown--><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text">Read more about <a href="https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows">Events that trigger GitHub Workflows</a></div></div><!--kg-card-begin: markdown--><h2 id="conclusion">Conclusion</h2>
<p>Using GitHub Actions helps us to automate our test execution and using GitHub pages we can publish our test reports. The report contains all the test details including raw HTTP logs which would help in debugging later on.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Introducing Onboarding Client for Nightwatch]]></title><description><![CDATA[Set up everything to run Nightwatch tests in under 60 seconds with one command. `npm init nightwatch`. Learn how to quickly set up the config, and automatically install the webdrivers and the required packages. ]]></description><link>https://blog.nightwatchjs.org/introducing-onboarding-client-for-nightwatch/</link><guid isPermaLink="false">689034e800bae33461ddef75</guid><category><![CDATA[onboarding-client]]></category><category><![CDATA[config]]></category><category><![CDATA[installation]]></category><category><![CDATA[setup]]></category><dc:creator><![CDATA[David Burns]]></dc:creator><pubDate>Fri, 27 May 2022 08:29:52 GMT</pubDate><media:content url="https://blog.nightwatchjs.org/content/images/2022/05/Nightwatch---blog-banner--3-.png" medium="image"/><content:encoded><![CDATA[<h2></h2><img src="https://blog.nightwatchjs.org/content/images/2022/05/Nightwatch---blog-banner--3-.png" alt="Introducing Onboarding Client for Nightwatch"><p>With just one command, set up everything to run Nightwatch tests in under 60 seconds. Our new onboarding client aims to provide a powerful onboarding experience to the developers setting up Nightwatch for the first time or in their existing project. Learn how to quickly set up the config, and automatically install the webdrivers and the required packages. </p><h2 id="running-it">Running it</h2><p>It all starts with the command <code>npm init nightwatch</code> </p><pre><code class="language-shell">&gt; npm init nightwatch
Need to install the following packages:
  create-nightwatch
Ok to proceed? (y)</code></pre><p>This is an npm alias for using <code>npx create-nightwatch</code> . The <code>npx</code> is a command for executing package binaries without downloading to the local dependency. &#xA0;npm then installs the package in a cache and runs the binary. If you are starting a new project, you can also run <code>npm init nightwatch &lt;directory&gt;</code> .</p><h2 id="the-flow-of-choices">The Flow of Choices</h2><p>The setup is based on a list of questions to accommodate a variety of use cases.</p><h3 id="test-runner">Test Runner</h3><p>Nightwatch also supports other test runners. You can also pick <a href="https://nightwatchjs.org/guide/third-party-runners/using-mocha.html">Mocha</a> or <a href="https://nightwatchjs.org/blog/running-cucumber-tests-with-nightwatch/">Cucumber</a> as a test runner apart from Nightwatch.</p><h3 id="javascript-typescript">JavaScript / Typescript</h3><p>Nightwatch <a href="https://github.com/nightwatchjs/nightwatch/releases/tag/v1.6.0">supports typescript</a> for test files after v1.6.0. So you can choose to have the test setup in Javascript or Typescript.</p><pre><code class="language-shell">===============================
Nightwatch Configuration Wizard
===============================

Just answer a few questions to get started with Nightwatch:

We&apos;ll setup everything for you :-)

? What is your Language - Test Runner setup? (Use arrow keys)
&#x276F; JavaScript - Nightwatch Test Runner
  JavaScript - Mocha Test Runner
  JavaScript - CucumberJS Test Runner
  TypeScript - Nightwatch Test Runner
  TypeScript - Mocha Test Runner</code></pre><h3 id="local-remote">Local / Remote</h3><p>You can setup the config and downloads based on if you&apos;re going to be running the test locally or on a remote machine or both.</p><pre><code class="language-shell"> Where do you want to run your e2e tests? (Use arrow keys)
&#x276F; On my local machine
  On a remote machine (cloud)
  Both</code></pre><h3 id="browser-selection">Browser Selection</h3><p>You can pick the browsers you&apos;ll be testing on, and the config will be created for them. We provide a multi-selection option so you can pick as many browsers you want to test on. You can also use the selenium-server when testing on the local machine.</p><pre><code class="language-shell">(Local) Where you&apos;ll be testing on? (Press &lt;space&gt; to select, &lt;a&gt; to toggle all, &lt;i&gt; to invert selection, and &lt;enter&gt; to proceed)
&#x276F;&#x25C9; Firefox
 &#x25EF; Chrome
 &#x25EF; Edge
 &#x25EF; Safari
 &#x25EF; IE (requires selenium-server)
 &#x25EF; Local selenium-server</code></pre><p>If you are running from a Mac, safaridriver is present by default but must be enabled.</p><pre><code class="language-shell">? Enable safaridriver (requires sudo password)? (Use arrow keys)
  Yes
&#x276F; No, I&apos;ll do that later.</code></pre><p>For remote testing, you should provide the host address and port of the remote machine.</p><pre><code class="language-shell">? (Remote) What is the host address of your remote machine? (localhost)
? (Remote) What is the port on which your test backend is running on your remote machine? (80)</code></pre><h3 id="other-parts">Other parts</h3><p>Apart from the fundamental differences in the ways you test, we also keep adding other extra configs you can add to the questionnaire. As of May &apos;22, the list is as follows.</p><ul><li>Directory location for the end-to-end tests</li><li>the <code>base_url</code> of your project</li><li>Using the <code>--generate-config</code> to create only the config and not download any dependencies</li></ul><h2 id="result">Result</h2><p>If <code>--generate-config</code> is not provided, the script installs the necessary packages. </p><pre><code class="language-shell">Installing the following packages:
- nightwatch
- @nightwatch/selenium-server
- @cucumber/cucumber</code></pre><p>For local tests, the script also installs the wedrivers based on your browser selection.</p><pre><code class="language-shell">Installing/Updating the following webdrivers:
- geckodriver
- chromedriver
- iedriver
- safaridriver</code></pre><p>By default, the configuration file <code>nightwatch.conf.js</code> is generated and examples at <code>tests/nightwatch-examples</code> . If the <code>nightwatch.conf.js</code> is already present then you can choose to overwrite the existing config file or to create a new one.</p><pre><code class="language-shell">? Do you want to overwrite the existing config file? No, create a new one!
? What should your new config file be called? ie-windows-test.conf.js</code></pre><p>Then you can run the examples with this command.</p><pre><code class="language-shell">npx nightwatch ./tests/nightwatch-examples</code></pre><div class="kg-card kg-callout-card kg-callout-card-accent"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text">Get started in 60 seconds! <code>npm init nightwatch</code></div></div><figure class="kg-card kg-embed-card kg-card-hascaption"><iframe src="https://player.vimeo.com/video/714406223?h=51f5bef357&amp;app_id=122963" width="426" height="240" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen title="Get started with Nightwatch in 60 seconds"></iframe><figcaption>Get started in 60 seconds!</figcaption></figure><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://www.browserstack.com/open-source"><div class="kg-bookmark-content"><div class="kg-bookmark-title">We Love Open Source - BrowserStack</div><div class="kg-bookmark-description">BrowserStack offers free web and mobile testing for open source projects. Test your web and mobile apps on our Real Device Cloud. Apply with project details to qualify</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://www.browserstack.com/favicon.ico" alt="Introducing Onboarding Client for Nightwatch"><span class="kg-bookmark-author">We have sponsored 1500+ open source projects</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://www.browserstack.com/images/layout/browserstack-logo-600x315.png" alt="Introducing Onboarding Client for Nightwatch"></div></a></figure>]]></content:encoded></item><item><title><![CDATA[Running Cucumber tests with Nightwatch]]></title><description><![CDATA[Install Nightwatch, cucumber and the driver for the browser. Set cucumber as the test_runner. Watch your tests run]]></description><link>https://blog.nightwatchjs.org/running-cucumber-tests-with-nightwatch/</link><guid isPermaLink="false">689034e800bae33461ddef74</guid><category><![CDATA[Cucumber]]></category><category><![CDATA[BDD Testing]]></category><dc:creator><![CDATA[David Burns]]></dc:creator><pubDate>Tue, 24 May 2022 12:29:04 GMT</pubDate><media:content url="https://blog.nightwatchjs.org/content/images/2022/05/Nightwatch---blog-banner.png" medium="image"/><content:encoded><![CDATA[<div class="kg-card kg-callout-card kg-callout-card-grey"><div class="kg-callout-text"><strong>TLDR;</strong> Nightwatch now has a <a href="https://nightwatchjs.org/guide/third-party-runners/cucumberjs-nightwatch-integration.html" rel="noopener noreferrer">new integrated test runner</a> for Cucumber.js. Check the sample <a href="https://github.com/nightwatchjs/nightwatch/tree/main/examples/cucumber-js">code here</a>.</div></div><h2 id="a-brief-introduction">A brief introduction</h2><h4 id="behaviour-driven-development-bdd">Behaviour-driven Development (BDD)</h4><img src="https://blog.nightwatchjs.org/content/images/2022/05/Nightwatch---blog-banner.png" alt="Running Cucumber tests with Nightwatch"><p>Behaviour-driven Development is a software development technique that has evolved from TDD (Test-driven Development), an approach or programming practice where the developers write new code only when the automated test case fails. BDD encourages teams to use concrete examples to formalize a shared understanding of how the application should behave between various tech and non-tech teams. Tests are more user-focused and based on the system&apos;s behaviour. In BDD, <em>&#x201C;Given-When-Then&#x201D;</em> is the proposed approach for writing test cases.</p><h4 id="cucumberjs-and-nightwatch">Cucumber.js and Nightwatch</h4><p>Cucumber is an Open Source framework that supports BDD using human language syntax and uses <a href="https://cucumber.io/docs/gherkin/reference/">Gherkin</a> as the parser. Cucumber is implemented in most <a href="https://cucumber.io/docs/installation/">mainstream programming languages</a>, including JS. Nightwatch recently introduced the <a href="https://nightwatchjs.org/guide/third-party-runners/cucumberjs-nightwatch-integration.html">new integrated test runner</a> for Cucumber.js in the 2.0 alpha release. No other plugins are necessary except the <a href="https://www.npmjs.com/package/@cucumber/cucumber">Cucumber library</a> itself with this new update. In this post, we&apos;ll write and run some BDD tests to verify the search results of a museum page using Cucumber.js and Nightwatch.</p><div class="kg-card kg-callout-card kg-callout-card-blue"><div class="kg-callout-emoji">&#x1F4A1;</div><div class="kg-callout-text">You can read more about <a href="https://www.browserstack.com/guide/learn-about-cucumber-testing-tool">Cucumber and BDD here</a>.</div></div><h2 id="getting-started">Getting Started</h2><ol><li>Install Nightwatch, Cucumber and the driver for the browser you want to test. <strong>Ensure that the browser driver version is the same as your local browser.</strong></li></ol><pre><code class="language-shell">npm i @cucumber/cucumber nightwatch chromedriver --save-dev</code></pre><p>2. Set Cucumber as the test_runner in the <code>nightwatch.conf</code> file.</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">{
  test_runner: {
    type: &apos;cucumber&apos;,
    options: {
      feature_path: &apos;*/*.feature&apos;,
      ...
    }
  src_folders: [&apos;features/step_definitions&apos;],
  ...
}</code></pre><figcaption>nightwatch.conf</figcaption></figure><p>You can read more about <a href="https://github.com/nightwatchjs/nightwatch/tree/v2/examples/cucumber-js">configuring Cucumber with Nightwatch</a>.</p><h2 id="writing-the-bdd-tests">Writing the BDD tests</h2><p>Cucumber uses the <a href="https://cucumber.io/docs/gherkin/reference/">Gherkin</a> syntax to create human-readable tests. Gherkin uses a set of special keywords to give structure and meaning to executable specifications. Let&apos;s create a <code>features/rijksmuseum.feature</code> and write some tests to search inside the <a href="https://www.rijksmuseum.nl/en">Rijksmuseum</a> website.</p><pre><code>Feature: Rijksmuseum Search
Background: Goto website
  Given I open the Rijksmuseum page
  And I dismiss the cookie dialog
  Then the title is &quot;Rijksmuseum Amsterdam, home of the Dutch masters&quot;</code></pre><p>We&apos;ll write some <a href="https://cucumber.io/docs/gherkin/reference/#background">Background</a> that gets executed before every scenario. In this case, we open the museum website, close the popup, and verify the page&apos;s title.</p><h4 id="scenario-1">Scenario 1</h4><pre><code>@search @nightwatch
Scenario: Searching for Night watch
  Given I search &quot;night watch&quot;
  Then Body contains &quot;Operation Night Watch&quot;
  Then Body contains &quot;The Night Watch, Rembrandt van Rijn, 1642&quot;</code></pre><p>We have two tags here, namely <code>search</code> and <code>nightwatch</code> so that we can run tests based on tags. This scenario searches for<em> &#x201C;night watch&#x201D; </em>on the museum search page and verifies the search results contain <em>&#x201C;Operation Night Watch&quot;.</em></p><h4 id="scenario-2">Scenario 2</h4><pre><code>@search @cucumber
Scenario: Searching for cucumber
  Given I search &quot;cucumber&quot;
  Then Body contains &quot;Muskusroos (Rosa moschata) en komkommer (Cucumis sativus)&quot;</code></pre><p>These scenarios are very clear and use simple human language. The next step is to define what each of these steps means to the automated tests.</p><h2 id="using-nightwatch-behind-the-scenes">Using Nightwatch behind the scenes</h2><p>Inside the <code>features/step_definitions/rijksmuseum.js</code> file, let&apos;s write definitions for the steps. Let&apos;s start with opening the museum page.</p><pre><code class="language-javascript">const {Given, Then, When} = require(&apos;@cucumber/cucumber&apos;)

Given(&apos;I open the Rijksmuseum page&apos;, function() {
  return browser.navigateTo(&apos;https://www.rijksmuseum.nl/en&apos;)
});</code></pre><p>As you notice, we have access to the Nightwatch&apos;s <code>browser</code> object inside our definitions file. This access is enabled because of the new 2.0 update. We also set the <code>src_folders: [&apos;features/step_definitions&apos;]</code> in the config. Cucumber provides a way to write <a href="https://github.com/cucumber/cucumber-expressions#readme">Cucumber Expressions</a>, an alternative to Regular Expressions, with a more intuitive syntax.</p><pre><code class="language-javascript">When(&apos;I search {string}&apos;, function(searchTerm) {
  browser.click(&apos;a[aria-label=&quot;Search&quot;]&apos;)

  return browser.waitForElementVisible(&apos;#rijksmuseum-app&apos;)
    .setValue(&apos;input.search-bar-input[type=text]&apos;, [searchTerm, browser.Keys.ENTER])
})</code></pre><p>Nightwatch has a built-in <a href="https://nightwatchjs.org/api/assert/">extendable assert/verify library</a> with the same methods, which perform assertions on elements.</p><pre><code class="language-javascript">Then(&apos;the title is {string}&apos;, function(title) {
  return browser.assert.titleEquals(title)
})</code></pre><h2 id="running-the-tests">Running the tests</h2><p>Nightwatch automatically detects and configures the test runner based on the installed driver. Since we&apos;re manually adding the config, let&apos;s set the default <code>test_setting</code> in the <code>nightwatch.conf</code> file. You can read more about the default config. The following snippet shows a simple setting for running it in chrome. For more information about default settings, you can read the <a href="https://nightwatchjs.org/guide/using-nightwatch/concepts.html#defining-test-environments">test environments docs</a> and the <a href="https://nightwatchjs.org/guide/configuration/overview.html">config docs</a>.</p><figure class="kg-card kg-code-card"><pre><code class="language-javascript">  test_settings: {
    default: {
      desiredCapabilities: { browserName: &apos;chrome&apos; },
      webdriver: { start_process: true },
    },
  },</code></pre><figcaption>nightwatch.conf</figcaption></figure><p>Let&apos;s run the Nightwatch tests.</p><pre><code class="language-shell">npx nightwatch</code></pre><p>You can add more parallels to the test with <code>--parallel 2</code> flag. Alternatively, you can run specific tests using the cucumber tags flag <code>--tags @search</code>. You can check the configuration from the <a href="https://github.com/nightwatchjs/nightwatch/tree/main/examples/cucumber-js">Nightwatch examples repo</a> and the <a href="https://nightwatchjs.org/guide/third-party-runners/cucumberjs-nightwatch-integration.html">Developer Guide</a>.</p><h2 id="conclusion">Conclusion</h2><p>We&apos;ve covered the basics of BDD testing and how to write your first test using Cucumber and Nightwatch, thanks to the new integrated test runner in the 2.0 release. So update your package now and start using Cucumber. </p><div class="kg-card kg-button-card kg-align-center"><a href="https://nightwatchjs.org/guide/third-party-runners/cucumberjs-nightwatch-integration.html" class="kg-btn kg-btn-accent">Get Started Now</a></div><hr><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://www.browserstack.com/open-source"><div class="kg-bookmark-content"><div class="kg-bookmark-title">We Love Open Source - BrowserStack</div><div class="kg-bookmark-description">BrowserStack offers free web and mobile testing for open source projects. Test your web and mobile apps on our Real Device Cloud. Apply with project details to qualify</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://www.browserstack.com/favicon.ico" alt="Running Cucumber tests with Nightwatch"><span class="kg-bookmark-author">We have sponsored 1500+ open source projects</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://www.browserstack.com/images/layout/browserstack-logo-600x315.png" alt="Running Cucumber tests with Nightwatch"></div></a></figure>]]></content:encoded></item><item><title><![CDATA[Introducing Component Testing in Nightwatch]]></title><description><![CDATA[Component Testing for React and Vue apps is available in Nightwatch 2, using the Vite dev server.]]></description><link>https://blog.nightwatchjs.org/introducing-component-testing-in-nightwatch/</link><guid isPermaLink="false">689034e800bae33461ddef73</guid><category><![CDATA[Nightwatch 2.0]]></category><category><![CDATA[Component Testing]]></category><category><![CDATA[Vite]]></category><category><![CDATA[Front-End Development]]></category><category><![CDATA[Vue.js]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Andrei Rusu]]></dc:creator><pubDate>Mon, 07 Feb 2022 08:22:00 GMT</pubDate><media:content url="https://blog.nightwatchjs.org/content/images/2022/02/component-testing-nightwatch-1.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.nightwatchjs.org/content/images/2022/02/component-testing-nightwatch-1.png" alt="Introducing Component Testing in Nightwatch"><p>Last year in November we&apos;ve began working on adding component testing to Nightwatch and now I am delighted to present the first version which is ready for public use. So far, it supports Vue and React components but our plans is to support all kinds of web components in the near future.</p><p>Component testing in Nightwatch is the next logical step since we cover the browser integration and we have built-in assertion libraries and reporters. We only needed a fast and reliable way of rendering the componets in isolation and for that we have chosen <a href="https://vitejs.dev">Vite</a> &#x2013; the new frontend build tool created by the team behind the <a href="https://vuejs.org">Vue.js</a> project.</p><p>Below I will attempt to explain what component testing actually is and how Nightwatch (v2.0) tackles the various problems that arise with testing web components.</p><h2 id="component-testing-overview">Component Testing Overview</h2><p>Unit testing single page front-end applications usually presents an entire set of issues to deal with over regular approaches of unit testing. In order to reliably test a web component in isolation, we need to be able to render it first.</p><p>When testing web components, the crucial aspect is how the component is rendered. In many cases, rendering using a real browser might seem like an overkill and something clumsy that will slow everything down considerably. For instance, a large project might have a dedicated QA team who takes care of the end-to-end testing and in such a case, it might seem unnecessary to write component tests using real browsers, especially if it&#x2019;s overly complicated or slow.</p><h3 id="rendering-using-jsdom">Rendering Using JSDom</h3><p><a href="https://github.com/jsdom/jsdom"><strong>JSDom</strong></a> is tool which offers the possibility to render a web component using a Node.js virtual renderer, without the need of a real browser. Everything happens in the CLI and it&#x2019;s usually pretty fast.</p><p>Here&#x2019;s how it normally looks like:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.nightwatchjs.org/content/images/2022/02/component-testing.001.png" class="kg-image" alt="Introducing Component Testing in Nightwatch" loading="lazy" width="783" height="696" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2022/02/component-testing.001.png 600w, https://blog.nightwatchjs.org/content/images/2022/02/component-testing.001.png 783w" sizes="(min-width: 720px) 720px"><figcaption>Rendering Vue Components using JSDom</figcaption></figure><h3 id="rendering-using-karma-testrunnerpuppeteer">Rendering using Karma TestRunner/Puppeteer</h3><p>The other popular approach is to use something like the <a href="https://karma-runner.github.io/latest/index.html"><strong>Karma Runner</strong></a>, which is a frontend testing tool created about 10 years ago at Google. There are also variations on this theme where <a href="https://pptr.dev/"><strong>Puppetter</strong></a> and browser-based Mocha is used.</p><p>In this approach all files needed are loaded on the test renderer page where it all happens: the component is loaded together with dependencies and any testing tools needed, then the component is rendered and the test is executed in the same browser context. It looks a bit like this:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.nightwatchjs.org/content/images/2022/02/component-testing.002.png" class="kg-image" alt="Introducing Component Testing in Nightwatch" loading="lazy" width="1202" height="747" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2022/02/component-testing.002.png 600w, https://blog.nightwatchjs.org/content/images/size/w1000/2022/02/component-testing.002.png 1000w, https://blog.nightwatchjs.org/content/images/2022/02/component-testing.002.png 1202w" sizes="(min-width: 720px) 720px"><figcaption>Rendering using Karma TestRunner</figcaption></figure><h3 id="rendering-in-nightwatch">Rendering in Nightwatch</h3><p>Either one of the above approaches are fine in terms of running tests and debugging, however both of them come with their one limitations, which are easy to spot:</p><p>Using <strong>JSDom rendering</strong> the limitation is clear: no real browser. However, advantages to consider are speed and access to OS-level APIs, which would make tasks like loading files or generating advanced reports more straightforward.</p><p>On the other hand, when using the <strong>Karma Runner</strong> or similar approach the advantage is clear: everything is happening in the browser and thus the test is more reliable. However, the disadvantage is that working with external files is not straightforward and also reporting is limited. I also found configuration to be quite difficult, as normally you have to combine several tools together in the setup just to get it working.</p><p>What <strong>Nightwatch</strong> aims to provide is a combination of both approaches by extending its cross-browser CLI test runner and built-in assertion library and provide an integrated and easy to use solution. Nightwatch already has support for end-to-end testing in all major browsers and comes with built-in reporting and support for parallelism out of the box.</p><p>Here&#x2019;s what Nightwatch does to run a component test:</p><ul><li>the CLI test runner launches a real browser and navigates to a basic HTML page (the test renderer)</li><li>inside the test renderer, it injects the Vue or React test utils and then mounts the component which needs to be tested, optionally specifying a list of plugins&#x2013;in case of Vue, such as a store or a router&#x2013; or props in case of React</li><li>once the component has been successfully rendered a reference to the DOM element will be sent back to the Nightwatch CLI runner</li><li>the CLI runner continues running the test in the same way it does for end-to-end testing; the assertions are run in the Node.js context</li></ul><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.nightwatchjs.org/content/images/2022/02/component-testing.003.png" class="kg-image" alt="Introducing Component Testing in Nightwatch" loading="lazy" width="1174" height="700" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2022/02/component-testing.003.png 600w, https://blog.nightwatchjs.org/content/images/size/w1000/2022/02/component-testing.003.png 1000w, https://blog.nightwatchjs.org/content/images/2022/02/component-testing.003.png 1174w" sizes="(min-width: 720px) 720px"><figcaption>Rendering a Vue component using Nightwatch</figcaption></figure><h2 id="what-is-vite">What is Vite?</h2><p>Vite is an extremely fast build tool for modern web applications, initially created for Vue.js apps but now with support for React and other UI frameworks as well. <em>Vite</em> is the French word for fast, which is appropriate because among the available front-end build tools, Vite is the fastest and also one of the easiest build tools to use.</p><p>If you have used tools like <strong>Babel</strong> or <strong>Webpack</strong> you may be familiar with the problems that arise from the complexity of the build setup and the slow startup times. <strong>Vite</strong> has somehow managed to eliminate all these issues by providing a tool that it&apos;s already configured out of the box and which leverages the new capabilities of modern browsers to handle <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules">ES Modules</a> directly, so there&apos;s no need of using tools like Babel. </p><p>In addition, Vite is using <a href="https://esbuild.github.io/">ESBuild</a> under the hood for bundling the Javascript code and related assets, which appears to be the fastest among the bunch by a great deal.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://blog.nightwatchjs.org/content/images/2022/02/Screenshot-2022-02-05-at-16.37.10.png" class="kg-image" alt="Introducing Component Testing in Nightwatch" loading="lazy" width="813" height="186" srcset="https://blog.nightwatchjs.org/content/images/size/w600/2022/02/Screenshot-2022-02-05-at-16.37.10.png 600w, https://blog.nightwatchjs.org/content/images/2022/02/Screenshot-2022-02-05-at-16.37.10.png 813w" sizes="(min-width: 720px) 720px"><figcaption>ESBuild performance metrics; source: https://esbuild.github.io</figcaption></figure><h2 id="how-does-it-work">How Does it Work?</h2><p>At the moment, component testing in Nightwatch is available via our new <a href="https://github.com/nightwatchjs/vite-plugin-nightwatch">vite-plugin-nightwatch</a> plugin in projects that are using Vite. Our initial aim is to support React and Vue components so we can gather some initial feedback from the community. </p><p>Once Vue and React support is firmly in place, we will expand to add other frameworks like <a href="https://svelte.dev">Svelte</a> and <a href="https://lit.dev">Lit</a>. </p><h3 id="installation">Installation</h3><p>For now, the new Vite plugin can be installed from NPM with:</p><pre><code>npm install vite-plugin-nightwatch</code></pre><h3 id="configuration">Configuration</h3><p>Update your <a href="https://vitejs.dev/config/" rel="nofollow">Vite configuration</a>:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">import { defineConfig } from &apos;vite&apos;
import nightwatchPlugin from &apos;vite-plugin-nightwatch&apos;

export default defineConfig({
  plugins: [
    // ... other plugins, such as vue() or react()
    nightwatchPlugin()
  ]
})</code></pre><figcaption>vite.config.jsc</figcaption></figure><p>Update your Nightwatch config and add the plugin to the list:</p><figure class="kg-card kg-code-card"><pre><code class="language-js">module.exports = {
  plugins: [&apos;vite-plugin-nightwatch&apos;],
  // ... other nightwatch settings
}</code></pre><figcaption>nightwatch.conf.js</figcaption></figure><p>For more usage details, examples, and API docs, head over to the Github page: </p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://github.com/nightwatchjs/vite-plugin-nightwatch"><div class="kg-bookmark-content"><div class="kg-bookmark-title">GitHub - nightwatchjs/vite-plugin-nightwatch: Component testing plugin that integrates Vite with Nightwatch.js. Supports Vue and React components.</div><div class="kg-bookmark-description">Component testing plugin that integrates Vite with Nightwatch.js. Supports Vue and React components. - GitHub - nightwatchjs/vite-plugin-nightwatch: Component testing plugin that integrates Vite wi...</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://github.com/fluidicon.png" alt="Introducing Component Testing in Nightwatch"><span class="kg-bookmark-author">GitHub</span><span class="kg-bookmark-publisher">nightwatchjs</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://opengraph.githubassets.com/b9f11016590a96e4846d047aa81077a62d81c8d38ed769e4ff4ca6638f8e13e4/nightwatchjs/vite-plugin-nightwatch" alt="Introducing Component Testing in Nightwatch"></div></a></figure><h3 id="complete-examples">Complete Examples</h3><p>We&apos;ve also put together example projects for both React and Vue which show how the plugin can be used. </p><ul><li><a href="https://github.com/nightwatchjs-community/todo-vue">Sample Vue ToDo app</a></li><li><a href="https://github.com/nightwatchjs-community/todo-react">Sample React ToDo app</a></li></ul><p>Both of these projects are under constant development so make to keep an eye on them for updates.</p><h3 id="vue-component-example-test">Vue Component Example Test</h3><p>Here&apos;s a basic example of a Vue component test. It&apos;s testing a basic Form component written in Vue which is available <a href="https://github.com/nightwatchjs/vite-plugin-nightwatch/blob/main/test/components/vue/Form.vue">here</a>, as part of the plugin: </p><figure class="kg-card kg-code-card"><pre><code class="language-js">describe(&apos;Render Vue Component test&apos;, function() {
  let formComponent;

  before(async function() {
    formComponent = await browser.mountVueComponent(&apos;/test/components/vue/Form.vue&apos;, {});
  });

  it(&apos;checks the vue component&apos;, function(browser) {
    browser.expect.element(formComponent).to.be.present;
    browser.setValue(&apos;#movie-input&apos;, &apos;Fargo&apos;);

    const inputEl = formComponent.find(&apos;input[type=&quot;radio&quot;][value=&quot;3&quot;]&apos;);

    browser.expect(inputEl).to.be.present;

    browser.click(inputEl);

    browser.expect(formComponent.property(&apos;rating&apos;)).to.equal(&apos;3&apos;);
    browser.expect(formComponent.property(&apos;title&apos;)).to.be.a(&apos;string&apos;)
        .and.equal(&apos;Fargo&apos;);
  });

});</code></pre><figcaption>Example Vue component test available here: https://github.com/nightwatchjs/vite-plugin-nightwatch/blob/main/test/specs/vue/testVueComponent.js</figcaption></figure><p>You can run this as a any other Nightwatch test or just clone/fork the project and run the included tests:</p><pre><code class="language-bash">git clone git@github.com:nightwatchjs/vite-plugin-nightwatch.git
npm install
npx nightwatch test/specs/vue/testVueComponent.js --env vue</code></pre><p>Make sure the Vite dev server is up and running, with:</p><pre><code class="language-bash">npm run dev</code></pre><h3 id="running-the-vite-dev-server-programmatically-from-nightwatch">Running the Vite dev-server programmatically from Nightwatch</h3><p>It is also possible to start the Vite dev server from the Nightwatch global <code>before</code> hook and close it in the <code>after</code> hook.</p><p>Our plugin does just that in order to run its own tests &#xA0;and details are provided in the <a href="https://github.com/nightwatchjs/vite-plugin-nightwatch#running-the-vite-dev-server-programmatically-from-nightwatch">Readme</a>. Future Nightwatch plugin releases will provide this functionality out of the box and you will be able run component tests wheather or not your project is based on Vite. </p><h3 id="debugging-component-tests">Debugging Component Tests</h3><p><br>Debugging component tests in Nightwatch isn&apos;t as straightforward as debugging a regular Node.js application or service, since Nightwatch needs to inject the code to render to component into the browser.</p><p>However, for when running the tests in Chrome, you can use the DevTools to do debugging directly in the browser. For this purpose, Nightwatch provide 2 CLI flags:</p><ul><li><code>--devtools</code> - when this is on, the Chrome DevTools will open automatically</li><li><code>--debug</code> - this will cause the test execution to pause right after the component is rendered</li></ul><h2 id="advantages-of-using-nightwatch-for-component-testing">Advantages of using Nightwatch for Component Testing</h2><p>The main advantage and motivation for using Nightwatch for component testing is ease of use and consistency with how end-to-end testing is done. With Nightwatch you have everything installed so there is nothing more to configure in terms of testing.</p><p>And since the testing is done by the CLI test runner, we have also access to <strong>OS-level APIs</strong> and we also have access to the <strong>Vite </strong>runner APIs, so we could do more advanced integration directly between Vite and Nightwatch, but we&#x2019;ll leave that one for a future update.</p><p>The only disadvantage would be that it&#x2019;s going to be a bit slower than <em>JSDom</em> renderer and possibly also the <em>Karma Runner</em>. However, I believe it compensates by offering a more reliable and easy to use solution, better reporting and overall better experience. Once you enable parallelism, then I think the speed will not be a problem any longer.</p>]]></content:encoded></item><item><title><![CDATA[Nightwatch has joined the BrowserStack family]]></title><description><![CDATA[<p>I am happy to announce that Nightwatch.js is now officially a part of BrowserStack. As an open-source project, this means that its development is now a lot more secure, and its future is in excellent hands. BrowserStack has proven itself as the leading cloud infrastructure provider for both live</p>]]></description><link>https://blog.nightwatchjs.org/nightwatch-has-joined-the-browserstack-family/</link><guid isPermaLink="false">689034e800bae33461ddef6d</guid><category><![CDATA[BrowerStack]]></category><category><![CDATA[Selenium]]></category><dc:creator><![CDATA[Andrei Rusu]]></dc:creator><pubDate>Tue, 14 Dec 2021 07:54:00 GMT</pubDate><media:content url="https://blog.nightwatchjs.org/content/images/2022/01/nightwatch-browserstack.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.nightwatchjs.org/content/images/2022/01/nightwatch-browserstack.png" alt="Nightwatch has joined the BrowserStack family"><p>I am happy to announce that Nightwatch.js is now officially a part of BrowserStack. As an open-source project, this means that its development is now a lot more secure, and its future is in excellent hands. BrowserStack has proven itself as the leading cloud infrastructure provider for both live and automated testing on desktop and mobile devices.</p><p>It also means that now Nightwatch is maintained by a full dev team and is one of the main responsibilities of the <a href="https://www.browserstack.com/blog/open-source-at-browserstack">Open-source Program Office</a> that BrowserStack has assembled recently. I have also joined this wonderful group where I&#x2019;ll be working together with other Selenium and Nightwatch contributors. Our vision stays the same: to ensure that Nightwatch is the go-to solution for all cross-browser automated testing needs.</p><p>At the same time, BrowserStack <a href="https://www.browserstack.com/press/browserstack-announces-full-support-for-selenium-4">is fully committed to support</a> the entire Selenium ecosystem and so Nightwatch will still continue to work well with all Selenium-based cloud services. As for the day-to-day operations, we will be continuing to develop Nightwatch as an autonomous open-source project, in the same manner as for the past 8 years, but with the support of the world&#x2019;s leading software testing platform.</p><p>Our mission remains the same &#x2013; to enable software and test engineers to test their applications as quickly and as reliable as possible. I&#x2019;ve never really believed in the promise of configuration possibilities. I don&#x2019;t think that anyone really enjoys configuring tools and installing plugins, especially when they need to write automated tests.</p><p>That&#x2019;s why Nightwatch aims to bring to the table a highly integrated solution, already packed with the right set of supporting libraries that work without any additional config needed, and written in the language that all web browsers know best &#x2013; JavaScript. And since we&#x2019;ve always favoured collaboration instead of competition, Nightwatch has been designed to make use of more than a decade long of experience from the Selenium project and to implement the industry standard <a href="https://w3c.github.io/webdriver/">W3C WebDriver API</a>. Doing it any differently not only seems impractical, but it just doesn&#x2019;t make sense to us.</p><p>No matter the sailboat, sailing is all about the wind they say. Maintaining open-source software is like that in many ways. Even though I don&#x2019;t know the first thing about sailing, the wind is a free natural resource and available to everyone to use. From the beginning, Nightwatch has got either good or moderate wind conditions. Now it has received a strong boost and I&#x2019;m very excited to see it continuing its journey at a much better speed and sailing conditions.</p>]]></content:encoded></item><item><title><![CDATA[Nightwatch 2.0 Webinar at BrowserStack on December 14th]]></title><description><![CDATA[<p>We&apos;re delighted to announce that BrowserStack is hosting a Nightwatch focused webinar on December 14th. Selenium committer <a href="https://twitter.com/AutomatedTester">David Burns</a> will be experimenting with a few of the new features in Nightwatch 2 and so this is a great opportunity to check out the new version.</p><p>David heads the</p>]]></description><link>https://blog.nightwatchjs.org/nightwatch-2-0-webinar-at-browserstack-on-december-14th/</link><guid isPermaLink="false">689034e800bae33461ddef6e</guid><category><![CDATA[BrowerStack]]></category><category><![CDATA[Webinar]]></category><dc:creator><![CDATA[Nightwatch.js]]></dc:creator><pubDate>Fri, 03 Dec 2021 08:19:00 GMT</pubDate><media:content url="https://blog.nightwatchjs.org/content/images/2022/01/webinar-browserstack.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://blog.nightwatchjs.org/content/images/2022/01/webinar-browserstack.jpg" alt="Nightwatch 2.0 Webinar at BrowserStack on December 14th"><p>We&apos;re delighted to announce that BrowserStack is hosting a Nightwatch focused webinar on December 14th. Selenium committer <a href="https://twitter.com/AutomatedTester">David Burns</a> will be experimenting with a few of the new features in Nightwatch 2 and so this is a great opportunity to check out the new version.</p><p>David heads the Open-source Program Office at BrowserStack and is one of the maintainers of the <a href="https://www.selenium.dev/">Selenium project</a> as well as being co-editor of the <a href="https://nightwatchjs.org/blog/w3c.github.io/webdriver/">W3C Webdriver spec</a>.</p><p>Here&apos;s what&apos;s on the agenda:</p><ul><li>introduction new the new User Actions API from Selenium and how to use them in Nightwatch</li><li>overview of the WebDriver Bidirectional (BiDi) APIs</li><li>working with shadowRoot elements in Nightwatch</li><li>creating a plugin using the new plugin API</li><li>Q&amp;A session</li></ul><h2 id="watch-the-recording">Watch the Recording</h2><p>The recording is available at the link below. You do not want to miss out on this!</p><p><a href="https://www.browserstack.com/webinars/nightwatch-2-in-action">browserstack.com/webinars/nightwatch-2-in-action</a></p>]]></content:encoded></item><item><title><![CDATA[Cross-browser Testing at Scale with Nightwatch and Selenium Grid]]></title><description><![CDATA[Leveraging the Selenium Grid with Nightwatch.js for distributed testing]]></description><link>https://blog.nightwatchjs.org/cross-browser-testing-at-scale-with-nightwatch-and-selenium-grid/</link><guid isPermaLink="false">689034e800bae33461ddef6b</guid><category><![CDATA[Selenium Grid]]></category><category><![CDATA[Cross Browser Testing]]></category><dc:creator><![CDATA[Puja Jagani]]></dc:creator><pubDate>Fri, 03 Dec 2021 08:07:00 GMT</pubDate><media:content url="https://blog.nightwatchjs.org/content/images/2022/01/selenium-grid-nightwatch.png" medium="image"/><content:encoded><![CDATA[<img src="https://blog.nightwatchjs.org/content/images/2022/01/selenium-grid-nightwatch.png" alt="Cross-browser Testing at Scale with Nightwatch and Selenium Grid"><p>Developing a good web application means it is usable, fully functional, and compatible. Rigorous end-to-end testing ensures rolling out a stable web application. Testing across all possible browsers guarantees a great user experience.</p><p>Nightwatch is an end-to-end automated testing solution for web applications. Developers and test engineers can write tests using Nightwatch and effortlessly target various browsers without worrying about test flakiness.</p><p>Consider an infrastructure setup with different browsers on different operation system machines. Now, the tests and infrastructure are ready. But how do we delegate the tests to run on the infrastructure? Well, Selenium Grid seamlessly stitches the two together. Selenium Grid helps in efficiently finding the accurate environment to run the tests on.</p><h2 id="what-is-selenium-grid">What is Selenium Grid?</h2><p>Selenium Grid is a central point that aids in distributed testing, scaling multiple environments, and load-balancing incoming tests. Grid improves testing efficiency by supporting parallel testing across multiple browser-os combinations. All tests point to the Grid, and it intelligently routes them to run on the underlying infrastructure.</p><p>If you have a local or a cloud device farm, Selenium Grid will handle all the delegation needs for web testing.</p><figure class="kg-card kg-image-card kg-width-wide"><img src="https://user-images.githubusercontent.com/10705590/143004524-87117f3e-3fd3-4d75-a107-b875b4e75a96.png" class="kg-image" alt="Cross-browser Testing at Scale with Nightwatch and Selenium Grid" loading="lazy"></figure><p>Selenium Grid&apos;s functionality is divided into various components as follows:</p><h4 id="router">Router</h4><p>As the names suggest, the Router&apos;s primary responsibility is to route the request to the correct component. Any request to the Selenium Grid first goes to the Router. Based on the request, the Router identifies the Grid component that can handle it.</p><h4 id="distributor">Distributor</h4><p>The Distributor maintains the model of all the registered Nodes. The Distributor matches the new session request to the appropriate Node and initiates session creation. It also regularly pings the Node&apos;s health check and tracks Node&apos;s heartbeat.</p><h4 id="node">Node</h4><p>The Node is present on the machine that hosts the operating system and browser(s). Hence, a Node interacts with the web drivers and forwards browser commands to them. Each Node consists of a set of capabilities. A capability is a combination of browser name, browser version, and the operating system.</p><p>Upon startup, the Node registers itself with the Grid. Distributor handles the Node registration.</p><h4 id="session-map">Session Map</h4><p>The Session map contains the mapping of the session-id and the Node where the session is running. For every request for an existing session, the Router uses the Session Map to look up the Node and forwards the request to the respective Node.</p><h4 id="new-session-queue">New Session Queue</h4><p>The New Session Queue enqueues every new session request. The New Session Queue is a FIFO queue. Meanwhile, the Distributor regularly checks if any of the Nodes have the capacity for the new session. If so, the Distributor blocks the matching slot in the Node and removes the request from the New Session Queue. The Node creates the session and responds to the client.</p><p>New Session Queue also has request retry and request timeout mechanisms.</p><h4 id="event-bus">Event Bus</h4><p>Grid components leverage the Event bus to interact with each other using messages. Grid components communicate with each other via the Event Bus.</p><h2 id="setting-up-selenium-grid">Setting up Selenium Grid</h2><h3 id="prequisites">Prequisites</h3><ol><li>Ensure java is downloaded. If not, <a href="https://www.java.com/en/download/help/download_options.html">download</a> and set up java on the machine that will run the Grid.</li><li>Download the latest jar from the <a href="https://www.selenium.dev/downloads/">Selenium downloads</a> page.</li><li>Ensure that the web driver is on the system path. Refer <a href="https://www.selenium.dev/documentation/getting_started/installing_browser_drivers/">installing browser drivers</a> for more details. The server will auto-detect drivers on the path. This behavior is configurable.</li></ol><p>The Selenium Grid can be set up in any of the three modes: Standalone, Hub and Node, and Fully Distributed.</p><p>In all three modes, the default server address is <a href="http://localhost:4444/">http://localhost:4444</a>.</p><h3 id="standalone">Standalone</h3><p>The Standalone mode has all the Grid components in one. It is the quickest way to get started with the Grid.</p><pre><code class="language-bash">java -jar selenium-server-${grid-version}&gt;.jar standalone</code></pre><h3 id="hub-and-node">Hub and Node</h3><p>Hub consists of Router, Distributor, New Session Queue, Session Map, and Event Bus. The Node consists of the Node and the Event Bus to allow communication with the Hub.</p><h4 id="start-the-hub">Start the Hub</h4><pre><code class="language-bash">java -jar selenium-server-${grid-version}.jar hub</code></pre><h4 id="start-the-node">Start the Node</h4><pre><code class="language-bash">java -jar selenium-server-${grid-version}.jar node</code></pre><h3 id="fully-distributed">Fully Distributed</h3><p>Each Grid component runs independently in the fully distributed mode. All the Grid components rely on the Event Bus to communicate with each other.</p><h4 id="start-the-event-bus">Start the Event-Bus</h4><pre><code class="language-bash">java -jar selenium-server-${grid-version}.jar event-bus</code></pre><h4 id="start-the-session-map">Start the Session Map</h4><pre><code class="language-bash">java -jar selenium-server-${grid-version}.jar sessions</code></pre><h4 id="start-the-new-session-queue">Start the New Session Queue</h4><pre><code class="language-bash">java -jar selenium-server-${grid-version}.jar sessionqueue</code></pre><h4 id="start-the-distributor">Start the Distributor</h4><pre><code class="language-bash">java -jar selenium-server-${grid-version}.jar distributor --sessions http://localhost:5556 --sessionqueue http://localhost:5559 --bind-bus false</code></pre><h4 id="start-the-router">Start the Router</h4><pre><code class="language-bash">java -jar selenium-server-${grid-version}.jar router --sessions http://localhost:5556 --distributor http://localhost:5553 --sessionqueue http://localhost:5559</code></pre><h4 id="start-the-node-1">Start the Node</h4><pre><code class="language-bash">java -jar selenium-server-${grid-version}.jar node</code></pre><p>To check if the Grid is up, ping <code>http://&lt;grid-url&gt;/status</code> endpoint.</p><p>Each component has configurable <a href="https://www.selenium.dev/documentation/grid/configuring_components/cli_options/">CLI options</a>.</p><h3 id="docker">Docker</h3><p>Selenium Grid also supports Docker. Refer <a href="https://github.com/SeleniumHQ/docker-selenium#docker-images-for-the-selenium-grid-server">Selenium Docker</a> to get started.</p><h3 id="grid-ui">Grid UI</h3><p>Navigate to <code>http://&lt;grid-url&gt;/ui</code>.</p><p>Grid UI displays the Grid model with all the Nodes. A separate tab for sessions displays the ongoing sessions and sessions waiting in the queue.</p><h2 id="running-nightwatch-tests-on-selenium-grid">Running Nightwatch tests on Selenium Grid</h2><p>Nightwatch comes packaged with a few <a href="https://github.com/nightwatchjs/nightwatch/tree/main/examples/tests">example tests</a> which you could use to quickly be up and running with your Grid.</p><p>For this guide, we will be assuming that Nightwatch 2.0+ is used. You can install it by running:</p><pre><code class="language-bash">npm i nightwatch</code></pre><h4 id="configure-nightwatch-to-use-the-grid">Configure Nightwatch to use the Grid</h4><p>The test runner requires a configuration file. The file can have the extension &quot;.json&quot; or &quot;.js&quot;. The &quot;.js&quot; is preferred since it has more configuration options and capabilities.</p><p>Nightwatch does the heavy-lifting of generating a config file with &quot;.js&quot; extension if it is not present. It contains a good set of options to test with any environment. For simplicity, just the sharing the configuration file with selenium-server related options. Just ensure the the selenium-server host and port match the Grid url and you are good to go.</p><pre><code class="language-javascript">{
  webdriver: {},

  test_settings: {
    selenium_server: {
      selenium: {
        start_process: false,
        host: &apos;localhost&apos;,
        port: 4444
      }
    },

    &apos;selenium.chrome&apos;: {
      extends: &apos;selenium_server&apos;,
      desiredCapabilities: {
        browserName: &apos;chrome&apos;,
        chromeOptions : {
          w3c: true
        }
      }
    },

    &apos;selenium.firefox&apos;: {
      extends: &apos;selenium_server&apos;,
      desiredCapabilities: {
        browserName: &apos;firefox&apos;
      }
    }
  }
};</code></pre><h4 id="running-in-parallel-using-test-workers">Running in Parallel using Test Workers</h4><p>By default the <code>test_workers</code> options is disabled. Enable if multiple test files should be ran parallel.</p><p>To run in parallel mode, ensure Grid&apos;s max-session CLI option is set to more than 1. By default, it is based on the number of available processors on the machine.</p><p>Update the Nightwatch config with setting the desired number of test workers:</p><pre><code class="language-javascript">{
  test_workers : {
    enabled: true,
    workers: 4
  }
}</code></pre><p>Refer to the <a href="https://nightwatchjs.org/gettingstarted/configuration/">Configuration section</a> to understand and use the configuration options.</p><h3 id="run-nightwatch-against-the-selenium-grid">Run Nightwatch against the Selenium Grid</h3><p>To run Nightwatch against the Selenium Grid using Chrome</p><pre><code class="language-bash">npx nightwatch examples/tests --env selenium.chrome</code></pre><p>Run the tests on multiple browsers by passing a comma-separated list of environments:</p><pre><code class="language-bash">npx nightwatch examples/tests --env selenium.chrome,selenium.firefox</code></pre><h3 id="further-reading">Further Reading</h3><ul><li><a href="https://www.selenium.dev/documentation/grid/">Selenium Grid Documentation</a></li></ul>]]></content:encoded></item></channel></rss>