Choose an item from an unsorted list - warning "elementIdAttribute is not a valid function"

I am facing difficulties in accessing a value from a dropdown menu. The dropdown menu is generated using Bootstrap's dropdown.js.

In order to tackle this issue, I have created a custom command in "Nightwatch" with two input parameters: the locator of the dropdown button and the specific value that needs to be selected from the list. The expected output should be the selected value from the dropdown.

Challenge: Despite successfully opening the dropdown menu, any attempt to retrieve values from it results in the following error:

TypeError: this.elementIdAttribute is not a function

After going through numerous discussions on stack overflow, confirming that the syntax is accurate, I find myself running out of solutions.

However, by modifying the path to the dropdown element in the comments section and changing the value of li:nth-child(2), I can select any element from the list.

Below is the code snippet (highlighted with *** is the part causing the error):

exports.command = function(locator, valueToClick) {
    var dropdown;
    //locator example
    //.click('#form > div.panel.panel-primary > div.panel-body > div:nth-child(1) > div > div.btn-group.bootstrap-select.form-control.parsley-validated > button')
    //.click('#form > div.panel.panel-primary > div.panel-body > div:nth-child(1) > div > div.btn-group.bootstrap-select.form-control.parsley-validated.open > div > ul > li:nth-child(2) > a > span.text')
    // remove " > button" from the end
    var dropdownElementLocator = locator.slice(0,locator.length-9);
    //var openDrop = '#form > div.panel.panel-primary > div.panel-body > div:nth-child(1) > div > div.btn-group.bootstrap-select.form-control.parsley-validated.open > div > ul li a span.text'
    var openDrop = dropdownElementLocator + '.open > div > ul > li'

    this
        .click(locator)
        .elements('css selector', openDrop, function(result){
           console.log("number of elements = " + result.value.length);
           console.log(result);
           result.value.forEach(function (element){
                console.log(***this.elementIdAttribute***(element.ELEMENT, 'a').value);
           });

           var position = -1;
           var i = 0;
           result.value.forEach(function(value){
            i++;
            var loc = openDrop + ':nth-child(' + i + ') > a > span.text'
           })

           position = position>-1 ? position : 0;
           console.log("final position " + i )
           //add ".open > div > ul > li:nth-child(2) > a > span.text"
           dropdownElementLocator = dropdownElementLocator + ".open > div > ul > li:nth-child(" + (position+1) + ") > a > span.text";
           this.click(dropdownElementLocator);
        })      
};

Answer №1

To ensure the error was resolved, it was necessary to maintain the current value of 'this' in order to accommodate its varying scope within the code.

exports.command = function(locator, valueToClick) {
    var dropdown;
    var openDrop = dropdownElementLocator + '.open > div > ul > li'

    // Preserving the value of 'this' as its scope changes throughout the code
    browser = this;
    browser
        .click(locator)
        .elements('css selector', openDrop, function(result){
           console.log("number of elements = " + result.value.length);
           console.log(result);
           result.value.forEach(function (element){
                console.log(browser.elementIdAttribute(element.ELEMENT, 'a').value);
           }); 

           var position = -1;
           var i = 0;
           result.value.forEach(function(value){
            i++;
            var loc = openDrop + ':nth-child(' + i + ') > a > span.text'
            //this.element('css selector', loc, function(res) {
            //       console.log('value ' + i + ': ' + res)
            //})
           })

           position = position>-1 ? position : 0;
           console.log("final position " + i )
           //add ".open > div > ul > li:nth-child(2) > a > span.text"
           dropdownElementLocator = dropdownElementLocator + ".open > div > ul > li:nth-child(" + (position+1) + ") > a > span.text";
           browser.click(dropdownElementLocator);
        })      
};

Issue: Despite the adjustments made, accessing values from the dropdown remains problematic.

Answer №2

Resolved with the assistance of this helpful post

exports.command = function(locator, valueToClick) {
    var dropdown, position;
    //example locator
    //.click('#form > div.panel.panel-primary > div.panel-body > div:nth-child(1) > div > div.btn-group.bootstrap-select.form-control.parsley-validated > button')
    //.click('#form > div.panel.panel-primary > div.panel-body > div:nth-child(1) > div > div.btn-group.bootstrap-select.form-control.parsley-validated.open > div > ul > li:nth-child(2) > a > span.text')
    // remove " > button" from the end
    var dropdownElementLocator = locator.slice(0,locator.length-9);
    //var openDrop = '#form > div.panel.panel-primary > div.panel-body > div:nth-child(1) > div > div.btn-group.bootstrap-select.form-control.parsley-validated.open > div > ul li a span.text'
    var openDrop = dropdownElementLocator + '.open > div > ul > li'

    // save the value of 'this' to maintain scope consistency
    browser = this;
    browser
        .click(locator)
        .elements('css selector', openDrop, function(result){
            var i = 0;
            result.value.forEach(function (jsonWebElement){
                var jsonWebElementId = jsonWebElement.ELEMENT;
                browser.elementIdText(jsonWebElementId, function(jsonElement){
                    var text = jsonElement.value;
                    i++;
                    console.log("text " + i + " : " + text + " text.indexOf(valueToClick) - " + text.indexOf(valueToClick));

                    if(text.indexOf(valueToClick) == 0){
                        position = i;
                        console.log("position inside loop: " + position);
                    }
                });
            });
        })
        .perform(function(){
            position = position>-1 ? position : 1;
            console.log("final position " + position )
            //add ".open > div > ul > li:nth-child(2) > a > span.text"
            dropdownElementLocator = dropdownElementLocator + ".open > div > ul > li:nth-child(" + position + ") > a > span.text";
            browser.click(dropdownElementLocator);
        })         
};

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

What causes the lack of impact on lambda rendering speed despite integrating webpack?

Hey there, I've been working on implementing webpack for a project that involves microservices, Node.js, TypeScript, AWS, and AWS SAM. My main objectives are: Reduce the cold start time of lambda functions. Minimize security vulnerabilities by e ...

Tips for selecting the right decorator for your space

I am working on developing a game that utilizes an AI. This AI's API consists of 3 methods implemented in an Angular Service Here is a simplified version of the code: app.service('AI', [function(){ return { offer: angular.noop, ...

Ways to invoke a function simultaneously with the calling function in the React Context API

I need to implement a function update() within the context of WebContextProvider. This function will in turn call another function updateAgain() also located within WebContextProvider. Here is the code snippet for reference. import React, { createContex ...

Using ReactJS to incorporate events with an external DOM element

I am using ReactJS version 16.13.1 and I have the need to display an external DOM element along with its events. Let's consider having a <button type="button" id="testBtnSiri" onclick="alert('Functionality exists');">Testbutton Sir ...

Utilizing the body in GET requests for enhanced client-server communication

What makes url query strings better than request body values? There are distinct advantages to using url parameters, such as visibility in the address bar and the ability to save requests in the browser history. However, is there more to it? Could reques ...

Optimal method for setting up a controller with multiple asynchronous requests

I am utilizing 2 $http functions within my AngularJS application to populate the page content. These functions are called using ng-init. ng-init = "getOpen(); getClosed();" Is this the most optimal approach? The first function is as follows: $scope.get ...

Establishing flow types and generating unchangeable records

Looking to integrate Flow with Immutable.js Records, I've set up my record like this: const MyRecord = new Immutable.Record({id: undefined}) Now when I create records using new MyRecord({id: 1}), Flow gives me an error: constructor call Construct ...

The rate limit feature in NextJS does not function properly when used with middleware

Currently, I have implemented a rate limit using the lru-cache based on the official example provided by Vercel, and it is functioning flawlessly. My intention was to consolidate the try-catch block in a Middleware to handle all routes, instead of duplica ...

Ways to Resolve the Error "Uncaught TypeError: Cannot Assign Value to Undefined Property '0'"

After experimenting with the code below, I discovered that when arrays (bill, tipValue, totalAmmount) are declared within the object method, I encounter a "cannot set property '0' undefined" error. However, if the same arrays are declared outside ...

`Easily capturing screenshots of Retina displays using Xvfb and Selenium`

Looking to automate the process of capturing screenshots of my hybrid app for iTunes Connect while using Ubuntu 14.04 and chromedriver 2.15.322448. Automating screenshots with Selenium and Xvfb is straightforward, but achieving retina quality screenshots ...

Having trouble bringing a 3D object into ThreeJS?

Encountering difficulties while trying to load a 3D object into Three.JS on my website. The 3D images were created in Blender and then exported to .JSON format using MrDoobs exporter addon. edit: This is the exporter I am utilizing - https://github.com/mr ...

Show additional links beneath the main homepage URL in search engine result pages

Seeking a way to optimize search engine results to display sub-links under the main homepage of a website. Attached is a screenshot illustrating the desired outcome when searching for a particular term. Appreciate any insights or solutions on achieving thi ...

Code snippet for calculating the size of an HTML page using JavaScript/jQuery

Does anyone know of a way to calculate and display the size/weight (in KB) of an HTML page, similar to what is done here: Page size: 403.86KB This would include all resources such as text, images, and scripts. I came across a Pelican plugin that does th ...

Having trouble locating the correct identifier for the WebElement associated with signing in to iCloud.com

Having difficulty locating the 'sign in with Apple ID' element on the iclod.com page. Currently using: WebElement username = driver.findElement(By.xpath("//[@id=\"account_name_text_field\"]"); username.sendKeys("<a href="/cdn-cgi/l ...

ThreeJS bringing Maya-style wireframe rendering to life

Currently, I am attempting to create a wireframe that will display quads instead of triangles by utilizing the following code: var geo = new THREE.EdgesGeometry( _this.geometry ); // or WireframeGeometry var mat = new THREE.LineBasicMaterial( { color: 0xf ...

What is the reason for the code to execute without errors using the 'let' keyword, but encountering issues with the 'var' keyword?

Take a look at the code snippet below: <button id="btn-0">Button 1!</button> <button id="btn-1">Button 2!</button> <button id="btn-2">Button 3!</button> <button id="btn-3">Button 4!</button> <script type ...

Run a function upon clicking a button in JavaScript

Could someone please help me figure out what I am doing incorrectly in the code below? I am attempting to trigger a function when a button is clicked. The HTML: <button id="btn1">Press me!</button> <input type="button" id="btn2" value="Pr ...

Ways to update a prop and reset it to its original state using React Hooks

My goal is to take a string prop text, trim it, and then pass it to the state of a component. I used to achieve this using the componentDidMount function in the past. However, now I am trying to use the useEffect() hook but encountering an error: "Cannot ...

Can the localization be embedded into an svg image?

I am currently engaged in a project that involves working with multiple languages in React using i18next. Within this project, I have a set of SVG images that contain fixed text in a specific language. Here is a snippet from one of the SVG images: <tex ...

JavaScript shorthand is used to simplify code for variables with identical values

I have various similar codes that look like this : $(function() { function setupSlider(sliderId, prevId, nextId, pagerId) { $('#' + sliderId).carouFredSel({ auto: false, infinite:false, ...