What is the best way to verify that the navigation menu contains all the anticipated items?

I am currently utilizing Nightwatch.js (Selenium/WebDriver) to conduct tests on my Node.js application.

My objective now is to verify the existence of a navigation bar and ensure that the items within the navbar are as anticipated.

This is my attempt at retrieving all navigation items, but I am unsure how to validate these elements. Furthermore, I feel that this process may be overly complex. Is this the appropriate approach when using Nightwatch.js?

module.exports = {
  'navigation': function(browser) {
    var navElements = []

    function getNavElements(elements) {
      elements.value.forEach(function(element) {
        browser.elementIdText(element.ELEMENT, function(res) {
          navElements.push(res.value)
        })
      })
    }

    browser
      .url(browser.launchUrl)
      .waitForElementVisible('#nav', 10000)

    browser.expect.element('#nav').to.be.present

    browser.elements('css selector', '#nav > .item', getNavElements)
    browser.expect(navElements).to.equal(['First', 'Second', 'Third'])

    browser.end()
  }
}

Answer №1

While your code is on the right track, there are a few key points you may have overlooked:

  • getNavElements functions as a callback, so there's no guarantee that navElements will be populated correctly when it's tested on the subsequent line.
  • browser.expect isn't actually a function; instead, it's a basic object that includes an element method. If you intend to conduct a standard test with expect, your best bet is to utilize Chai directly (Nightwatch BDD-style interface hinges on this particular library).

Below, you'll find a simplified version of the working code:

HTML (index.html)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8>
  <title>Nightwatch</title>
</head>
<body>
  <ul id="nav">
    <li class="item">First</li>
    <li class="item">>Second</li>
    <li class="item">>Third</li>
  </ul>
</body>
</html>

JavaScript (nav.js)

var expect = require('chai').expect;

module.exports = {
  'Navigation': function (browser) {
    var expectedNavElements = ['First', 'Second', 'Third'];

    function testNavElements(elements) {
      elements.value.forEach(function (element, index) {
        browser.elementIdText(element.ELEMENT, function(res) {
          expect(res.value).to.equal(expectedNavElements[index]);
        });
      });
    }

    browser
      .url('http://localhost:8000/index.html') // Modify if necessary
      .waitForElementVisible('#nav', 1000);

    browser.expect.element('#nav').to.be.present;
    browser.elements('css selector', '#nav > .item', testNavElements);

    browser.end();
  }
};

Instructions

  1. npm i chai for Chai installation
  2. nightwatch -t tests/nav.js to execute the test suite

Note: Nightwatch doesn't handle passing Chai expectations silently. You won't receive any messages in the console if Chai expectations succeed, but you'll encounter an assertion error if they fail. Feel free to input incorrect values in expectedNavElements to see this in action...

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible to trick the desktop browser into utilizing mobile-designed media queries?

While I've come across numerous solutions on Stack Overflow for displaying a desktop version on mobile devices, my inquiry is centered around the idea of forcing a browser to show a mobile version of a website on a desktop computer. Is there a way to ...

Even though I have successfully stored a key value pair in LocalStorage using JSON stringify and setItem, the data does not persist after the page is refreshed

I recently developed a Todo application that runs smoothly, except for one crucial issue - the localStorage data does not persist after refreshing the page. Initially, the localStorage operations functioned properly when there were fewer event handlers in ...

What is the best way to enable the user to scroll through a list seamlessly?

I am trying to create a div container with a scroll overflow that contains multiple child elements. I want the child elements to behave like a list, scrolling continuously so that once the user reaches the bottom, the top items reappear from the bottom as ...

Ways to store a JSON string in a variable

When utilizing the ajax function, I am able to retrieve my JSON string. Here is an example: $.ajax({ type: "POST", url: "http://localhost/./Service/GetPageInfo", dataType: "json", contentType: 'application/json' ...

Redirect to a new URL using $routeProvider's resolve feature

Currently, I am in the process of developing an application that includes the following endpoint: .when('/service/:id?', { templateUrl: 'views/service.html', controller: 'ServiceCtrl', resolve: { service: fu ...

Incorporate a for loop in Javascript to add a variety of items (object1, object2, and object3) to an array

Currently, I am facing a challenge in my project where I need to fetch data from an open-source API. The issue lies in the fact that the API provides objects that must be grouped into an array named ingredients. These objects are labeled as strIngredients1 ...

Automatically simulate the pressing of the enter key in a text field upon page load using Javascript

I am looking to simulate the pressing of the enter key in a text field when a page is loaded. Essentially, I want the text field to automatically trigger the enter key press event as if it had been pressed on the keyboard by the user. Below is an example o ...

Establishing references to the following and previous pages

I am currently experiencing an issue with rendering images in a div that have anchor tags inside. When a user clicks on an image, I need to open an overlay screen to display PDF files using the TouchPdf plugin. What I want to achieve is to have arrow butto ...

The endless scroll just keeps going even after all the content has been viewed

Hello, I am currently facing an issue with the infinite scroll functionality on my website. Even after all the content has been displayed, it still continues to scroll, exhibiting strange behavior. I am desperately seeking a solution to stop the infinite s ...

Using Javascript to update text content by utilizing `innerText` property instead of checking if it is

How can I selectively use Javascript to replace the specific word "Rindan" in the text below, but not if it appears within an attribute such as img alt=="Rindan"? I only want to replace instances of the word "Rindans" when it is part of the inner text an ...

Creating a duplicate of the Object in order to include a new key and value pair

While pre-fetching a product from a database using mongoose along with next.js and react-query, I encountered a situation where I had to perform a deep copy of a nested object to successfully add a key-value pair to it. Without this deep copy, the operat ...

Is there a way for me to choose a single file while executing the migrate-mongo up command?

Hey there! I'm looking to execute the command migrate-mongo up in just one specific file. Currently, when I run the command migrate-mongo up, it processes all pending migration files. Is there a way to target only one file for execution? For example: ...

What is the best way to remove data from both arrays simultaneously?

I am working with a grid that displays a list of time ranges. For example: timeList=[{from:12:00:00 , to:14:00:00 ,id:10}{from:08:00:00 , to:09:00:00 ,id:11{from:05:00:00 , to:10:00:00 ,id:12}}] time=[{Value:12:00:00 id:10} {Value:14:00:00 id:100} ...

Hide a span dynamically based on conditions in AngularJS

I need to conceal the <span ng-show="currencyObject.to != 'undefined'">=</span> until the currencyObject.to has a value of undefined. This should only occur until the user selects an option from the dropdown menu. I attempted to use n ...

Filter an array containing nested objects based on dynamically determined properties

I'm working with an array of N objects and need to create a filter using JSON.stringify that dynamically checks multiple properties. Looking for a solution that is dynamic and doesn't rely on static properties (as shown in the code snippet above ...

Configuring select options using API data

I am currently retrieving my options from an API and have created a Const InputResponse to store the data: const inputResponse = [ { key: 'news', value: "news", datagrid:{ w:2, h:9, x:0, y:0, m ...

Having trouble with the functionality of the cascading menu?

I am having trouble with a drop-down menu. The first level works fine, but I can't seem to get the second level of the menu to display. Appreciate any help you can offer. Thank you. javascript <script type="text/javascript"> $(document).ready( ...

The issues with VUE3 compounding filters are causing unexpected results

Currently, I am attempting to filter search results using multiple filter options. After trying various methods, I have found that when applying only 2 filters, the search works as expected. However, when adding 3 or more filters, it includes additional re ...

Tips for setting up a Vue application (using vue-cli) to include nonce attributes in created script tags

My vue application, compiled using vue-cli, has a vue.config.js file structured as follows: 'use strict'; module.exports = { publicPath: `${process.env.CDN_URL || ''}/dist/`, lintOnSave: true, transpileDependencies: [], outputD ...

"Transforming a list retrieved from Django context into a JavaScript or Vue.js list: A step-by-step guide

Having a basic list presented in the django context. rlinks: ['test1', 'test2'', 'test3'] var v_root = new Vue({ delimiters: [ '[[', ']]' ], el: '#vue-main', data: { job ...