Tips for navigating to an element with Nightwatch

I am currently using nightwatch for end-to-end testing of my application. One of the tests is failing because it seems unable to scroll to the element that needs to be tested. I am wondering if scrolling is necessary, or if there is another workaround. Here is the code snippet for the element in question:

 return this.waitForElementVisible('#myElement', 4000) //wait for it to be visible
       .assert.visible('#myElement')
       .click('#myElement')

The element being tested is located at the top of the page, but the test runner has scrolled down slightly and the element is not visible in the screenshot. How can I scroll to this element if necessary? Or is there an alternative way to test this element?

Answer №1

If you need to ensure elements are visible on the screen while using nightwatch, there is a native method available. You can use getLocationInView() to scroll elements into view:

return this.getLocationInView('#myElement')
   .assert.visible('#myElement')
   .click('#myElement')

Alternatively, Nightwatch also allows direct manipulation via the Webdriver Protocol using moveTo() without abstraction. Here's an example of how it can be done:

const self = this;
return this.api.element('#myElement', (res) => {
  self.api.moveTo(res.value.ELEMENT, 0, 0, () => {
    self.assert.visible('#myElement');
    self.click('#myElement');
  })
});

Adjusting selenium's element scroll behavior in the configuration can also be useful for your specific case. Consider changing it like so:

firefox: {
  desiredCapabilities: {
    browserName: 'firefox',
    javascriptEnabled: true,
    acceptSslCerts: true,
    elementScrollBehavior: 1
  }
}

The default behavior scrolls elements to the top of the page. By setting elementScrollBavior to 1, elements will be scrolled to the bottom of the page.

Answer №2

Keep this in mind:

.execute() injects a piece of JavaScript into the page to be executed within the current frame's context. The script is assumed to run synchronously, and the client receives the result of the evaluation.

also

Window.scrollTo() Scrolls to specific coordinates in the document.

Your test should appear like this:

module.exports = {
    'your-test': function (browser) {
        browser
            .url("http://example.com")
            .waitForElementPresent('body', 2000, "Make sure the page has loaded")
            .execute('scrollTo(x, y)')
            .yourFirstAssertionHere()
            .yourSecondAssertionHere()
            ...
            .yourLastAssertionHere()
            .end()
    }
};
  • If you know that the element with id myElement is at the top of the page, simply change x and y to 0 (to ensure scrolling to the top of the page).

  • If you need to find the exact values of x and y, you can use: getLocationInView() like this:

    module.exports = {
        'your-test': function (browser) {
            browser
                .url("http://example.com")
                .waitForElementPresent('body', 2000, "Make sure the page has loaded")
                .getLocationInView("#myElement", function(result) {
                    //The x value will be: result.value.x
                    //The y value will be: result.value.y
                });
        }
    }

    .getLocationInView(): Determines an element's location on the screen once it has been scrolled into view... Returns The X and Y coordinates for the element on the page.

I hope this explanation helps you out.

Answer №3

To implement the moveToElement() function:

Just follow this example for usage:

browser.
.moveToElement(#targetElement, 20, 20)
.waitForElementVisible(#targetElement, 1000)

Answer №4

To run the following javascript, use the command execute

document.querySelector({{CUSTOM_SELECTOR}}).scrollIntoView();

Answer №5

Moreover, I have implemented a page object command called "be_expand" in which the selector used was an xpath that had already been utilized in another element (@be_click):

    be_expand() {
        this.api.execute(function(xpath) {
            function getElementByXpath(path) {
                return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
            }
            var res = getElementByXpath(xpath);
            res.scrollIntoView(true);
        }, [this.elements.be_click.selector]);
        this.assert.visible('@be_click');
        this.click('@be_click');
        return this;
    }

Answer №6

window.browser.scrollBy(0, 3000);

Answer №7

browser.execute('window.scrollTo(0, 1080)')

I found this method to be effective in scrolling down to the end of the page.

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

Detecting the Escape key when the browser's search bar is open - a step-by-step guide

One feature on my website is an editor window that can be closed using the Escape key. The functionality is implemented in JavaScript: $(document).keyup( function(e) { // Closing editor window with ESCAPE KEY if(e.which == 27) { // Clic ...

Using React Refs to Trigger the video.play() Method - A Step-by-Step Guide

Is there a way to use a ref in order to trigger video.play()? Currently encountering an error: preview.bundle.js:261916 Uncaught TypeError: _this2.videoRef.play is not a function Take a look at my component: import React from 'react'; import s ...

Sliding divider across two div containers with full width

Seeking a JavaScript/jQuery function for a full page slider functionality. The HTML structure I'm working with is as follows: My objectives are twofold: Both slide1 and slide2 should occupy the full width of the page. Additionally, I am looking for ...

Steps to correctly reset an XMLHttpRequest object

I'm currently working on a project where I send AJAX requests, receive responses, and replace text based on those responses. However, it seems like I may be missing a fundamental concept in my approach. request.onreadystatechange = () => { if (r ...

Deliver varied asset routes depending on express js

I have a situation where I am working with express routes for different brands. My goal is to serve two separate asset directories for each brand route. One directory will be common for all brand routes, located at public/static, and the other will be spec ...

Tips for storing dynamically added row data from an HTML table to a (csv/txt) file using C#

I am dynamically adding new rows to a table named "newDataTable" using the JavaScript function below: function addRow() { //add a row to the rows collection and get a reference to the newly added row var table = document.getElemen ...

Objects within the Prototype in Javascript

While delving into the world of AngularJS, I stumbled upon an interesting revelation - when objects are placed in a prototype object, any instances inheriting from that prototype will alter the prototype's objects upon assignment. For example: funct ...

Ways to update the div's appearance depending on the current website's domain

There is a piece of code that is shared between two websites, referred to as www.firstsite.com and www.secondsite.com The goal is to conceal a specific div only when the user is on secondsite. The access to the HTML is limited, but there is an option to ...

Changes in menu layout in response to window resizing

The menu needs to be centered on the website and adjust to the browser window resizing. Currently, it's positioned in the center and the animation is working fine. However, when I attempt to make the menu responsive so that it stays centered when resi ...

Problem with extJS portal functionality

Currently, I am utilizing this particular URL for my application: . I attempted to swap out the existing chart in the third column with a bar chart and a pie chart (both of which work fine within panels and windows), but I encountered an "h is undefined" e ...

Can JSON be used to perform mathematical operations and calculations?

Utilizing the amazing json-server as my application's backend has been incredibly beneficial for custom data retrieval. However, it would be even more valuable if it supported calculations and expressions to mimic backend behavior. Consider this data ...

Storing a variable in a web element path with Selenium Java for iterating through multiple elements

Struggling with looping through multiple web elements using Selenium in Java: for (int i = 0; i < 100; i++) { driver.findElements(By.cssSelector("#matchListWithMessages > div.messageList > a:nth-child(5)")).click(); } The challenge ar ...

angular and node: troubleshooting the $http.get error

I have encountered an issue with the $http.get instruction. Without it on the main page, I receive a result of "random 46" which is correct. However, when I include $http.get, I get a result of "random {{ number }}". How can this problem be resolved? -se ...

Restricting Entry to a NodeJS Express Route

Currently, I am in the process of developing an express project where I have set up routes to supply data to frontend controllers via ajax calls, specifically those that start with /get_data. One issue I am facing is how to secure these routes from unauth ...

Does altering HX-GET in JavaScript have no impact on the outcome?

I need assistance with implementing HTMX in my FastAPI application that uses Tailwind and MongoDB for the database. Here is the form I am working with: <form id="currencyForm" hx-get="/currency_history_check/EUR" hx-target="#re ...

Having trouble fetching values in Node.js after a certain period of time has passed

Whenever the page loads, the sha1 function is supposed to run and it should run after 5 seconds. var crypto = require('crypto'); console.log(sha1()); setTimeout(sha1, 5000); console.log(sha1()); function sha1() { var dt = dateTime.create(); ...

"Encountered an Unspecified Variable Error in executing document

Every time I open my Chrome console, it keeps showing an error message saying "toggleOnlyRelatedPosts is not defined". The script I'm working on doesn't seem to be functioning properly. I've added so many variables that I now feel lost and o ...

Error: Surprising token found in ReactJS application on CodeSandbox

Encountering an unexpected token on line 5 error in my ReactJS project when testing it on CodeSandbox. Interestingly, the app runs smoothly without errors on my local machine. import React, { Component } from 'react'; import Header from ' ...

How can I access dynamically created input elements without using $refs, such as getting focus?

Is there a way to handle dynamically created inputs for editing purposes without using jQuery or vanilla JS all the time? Each input element has its own ID and is displayed through v-if when editing is triggered. However, Vue does not recognize them in r ...

The JavaScript functions are not loading within the onload event handler

I've got an HTML document that contains some Script sections. I've consolidated all the functions within a single Script Tag. Now, I want to be able to utilize these methods in both the onload and onclick events. Below is the HTML file with all t ...