Protractor: strategy for efficiently finding elements with identical attributes

I am currently testing a website that is built as a single page application using Angular.

Due to the nature of this architecture, much of the DOM is loaded in advance and hidden until needed. Depending on user actions, certain elements are displayed while others remain hidden. Protractor interprets all elements, whether visible or hidden, as part of the overall DOM structure. For example, if I try to locate an element by its id:

this.usernameTextbox = element(by.id('username'));

Protractor recognizes multiple elements with the same id - one visible due to ng-show and the other hidden because of ng-hide.

My question is, is there a way for Protractor to only identify elements that are not hidden?

Answer №1

Have you experimented with this approach:

browser.wait(function(){
    return element(by.id('username')).isDisplayed();
}, 1000).then(function(){
    //Implement your logic here
});

Answer №2

It is not possible to instruct the webdriver to specifically locate visible elements; instead, you must gather all elements that match a locator and then verify their visibility by checking their "displayedness".

In essence, utilize element.all() to identify all elements by id, and leverage filter() to sift through and isolate the one that is visible, as demonstrated in this code snippet:

var username = element.all(by.id("username")).filter(function (elm) {
    return elm.isDisplayed().then(function (value) {
        return value;
    });
}).first();

When I mention "reliably," I am referring to the fact that while theoretically it is possible to check for the presence of display: none or visibility: hidden (reference), it is not recommended due to the complexity of determining visibility which is handled by the webdriver's isDisplayed() method.

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

AngularJS ng-submit can be configured to trigger two separate actions

I am currently diving into AngularJS and working on a simple project to create an expense tracker as a beginner task. However, I have encountered some issues with my code. While I have successfully implemented most functions, I am struggling with the upda ...

Passing information from the created hook to the mounted hook in VueJS

How can I transfer data from the created function to the mounted function in VueJS? In my VueJS application, the code in my created function is as follows: created: function(){ $.getJSON({ url: 'static/timeline.json', success:function( ...

Establish a default route within a Node Express application to handle multiple generic URLs (url/index, url/index2, url/index3, and

Currently, I am in the process of learning React and Express frameworks through exercises provided by NodeSchool.io. My goal is to consolidate all exercise files into a single application with multiple pages named as: index index2 index3 index4 .. ...

JavaScript code for displaying mouse positions and Geolocation using OpenLayers, along with a Geocodezip demonstration

I have attempted to merge Geolocation and Mouse Position Display (longitude/latitude; outside of map) from the OpenLayers and geocodezip site, but I am facing issues. The Mouse Position Display works correctly, however, Geolocation does not seem to work. U ...

Steps for displaying a deeply nested array and string within an object that is nested further in an array

I've been troubleshooting an issue in my Next.js code where I'm trying to render data called items. My goal is to display the descriptions in an array as a list and display the description that is a string as it is. However, I cannot use the map ...

Using Vue3 and Vuex4: How to efficiently render only a subset of items from an array with v-for

Hello, I'm a first-time user and beginner developer seeking some assistance. I am in the process of creating a basic web application that retrieves an HTTP JSON response from an API and displays a more visually appealing list of results. However, I&ap ...

Error: Unable to locate sportsRecord due to missing function

updated answer1: Greetings, I have updated the question with some detailed records and console logs for better understanding. sportsRecord = { playerTigers:[ {TigerNo: 237, TigerName: "Bird Bay Area", TigerkGroupNo: 1, isDefault: true ...

Connecting events to maps in AngularUI

Currently, I am working with AngularJS and the AngularJS UI modules to integrate Google Maps into my application and perform various actions on its events. One issue I have encountered is that the ui-events call function is not passing any parameters or da ...

Display a few HTML elements sourced from a different online platform

I am trying to extract a specific value from a span element on another website and render it on my own website using either a GET/FETCH request or some other method. Currently, I have this code but I am struggling to extract the data I need. The data I am ...

WCAG-compliant Quasar q-table

Currently, I am working on an application that utilizes Quasar (CLI) and have successfully created a datatable using q-table. My next goal is to enhance the table's accessibility by adding an aria-label attribute to the column sorting icon. However, I ...

"Utilizing the connect() and withStyles() methods in React for class components: A step-by-step guide

Looking for ways to utilize connect() and withStyles() in React for a class component? const customStyles = makeStyles(theme => ({...}); const stylesObject = customStyles(); class CustomComponent extends React.Component { ... render() { ...

Create a canvas and include input boxes in an HTML document

I'm attempting to create a canvas line diagonally above two textboxes that are also positioned diagonally (similar to Samsung's pattern passcode) when a button is clicked, but I am facing difficulties in achieving this. I have attempted to solve ...

Error Encountered: Unable to Locate 'bootstrap' label in Bootstrap 5 Popover

I have been working on implementing a popover in my Angular 12 project using Bootstrap version v5.0.1. However, I am encountering a name error that I can't seem to resolve: var exampleEl = document.getElementById(item.name + index); var tooltip = ne ...

The design of RESTful web applications with a client-server architecture

I need clarification on how client-server architecture should function for a modern web application with a RESTful backend. For a web app, the client is typically the browser while the server is the web server. Programatically speaking, there are componen ...

Ways to access the props value within the lifecycle hooks of Vue JS

Is there a way to retrieve the value of props using lifecycle hooks such as mounted or updated, and then store that value in my v-model with additional text? I've been struggling to achieve this. I attempted using :value on the input element with bot ...

Working with multi-line HTML content within Javascript

I am currently using JavaScript to define the behavior of a button on a website. I want the button to add new HTML content to a specific part of the page, and I would like to use the MVC extension method Html.EditorFor to create this new HTML. Here is wha ...

Guide on how to update a div element without losing submitted information with the help of AJAX and PHP

After creating two HTML pages that incorporate AJAX refresh div tag code and use $_POST to post data from one page to another, I encountered a situation where the PHP page would retrieve data from a MySQL table. Let's take a look at the code I utilize ...

How can I display a loading message in bootbox during the execution of an ajax process?

In my application, there is a page that displays status in a drop-down menu with two options - Active and Inactive. Users can change the status by simply clicking on the menu and selecting an option. To track this status change process, I am using JQuery/A ...

Using async and await inside a setTimeout function within a forEach loop

Currently, I am facing a challenge with scheduling background jobs in Node.js. I need each job to run only after the previous one has finished. Below is the code snippet inside a function: jobArray.forEach((item, i) => { setTimeout(async () => { ...

I am encountering a problem with the app.patch() function not working properly. Although the get and delete functions are functioning as expected, the patch function seems to be

I am in the process of setting up a server that can handle CRUD operations. The Movie model currently only consists of one property, which is the title. Although I can create new movies, delete existing ones, and even search for a ...