Creating custom ExpectedConditions with Protractor for detecting attribute changes

I've been working on creating a custom ExpectedConditions method that can wait for an element attribute to change.

Here is the approach I came up with:

const CustomExpectedCondition = function() {
  /**
   * Check if element's attribute matches the provided value.
   *
   * @param {ElementFinder} elementFinder
   * @param {string} attrName - name of the attribute to check
   * @param {string} attrVal - value to compare against
   *
   * @return {boolean}
   */
  this.attributeToMatch = async (elementFinder, attrName, attrVal) => {
    const EC = protractor.ExpectedConditions;
    const hasAttribute = async () => {
      const actualAttributeValue = await elementFinder.getAttribute(attrName);
      return actualAttributeValue.indexOf(attrVal) !== -1;
    };

    return await EC.and(EC.presenceOf(elementFinder), await hasAttribute);
  };
};

module.exports = new CustomExpectedCondition();

In my onPrepare section:

const {customExpectedConditions} = require('@utils/protractor');
global.CustomExpectedCondition = customExpectedConditions;

And finally, in my test suite:

 await browser.wait(await CustomExpectedCondition.attributeToMatch(dropdownElement, 'aria-hidden', 'false'), 3000);

Despite these steps, I keep receiving a

Failed: Wait timed out after 3006ms
error. Can anyone help me figure out what I might be doing wrong?

Answer №1

Kindly attempt the following changes:

this.attributeToHave = async (elementFinder, attrName, attrVal) => {
    const EC = protractor.ExpectedConditions;
    const hasAttr = async () => {
      const actualText = await elementFinder.getAttribute(attrName); // Make sure to include await
      return actualText.indexOf(attrVal) !== -1;
    };

    return await EC.and(EC.presenceOf(elementFinder), await hasAttr()); // Remember to invoke `hasAttr()` function.
};

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

Using Selenium Webdriver to set a cookie with a Chrome extension

I have been experimenting with a Chrome extension in order to set a cookie when I use a Selenium Webdriver instance to open a page. Despite trying various methods suggested on different Stack Overflow posts, none of them seem to work as the cookie does not ...

Reactively created menu using JQuery

Looking to implement a dynamic JQuery menu using React (ES6). Utilizing the JQuery menu examples (https://jqueryui.com/menu/) as a guide, however, those examples only cover static menus. It doesn't clarify how to modify menu items like updating labels ...

Python script encountering difficulties downloading PDF files via Chrome

Currently, I am working with selenium in python. My task involves clicking on the first PDF icon visible on a webpage. However, instead of downloading the PDF file, a new page appears with an "Open" button. Despite attempting to click on the open button ...

Using $nin alongside $and in Mongoose

Implementing a filter for an admin user using mongoose operations. The user should be able to view all saved files except for those that are classified as draft files. However, the admin user should still have access to their own saved draft files. Code ...

Send a vanilla JavaScript ajaxForm submission by completing the form

I am currently in the process of integrating JavaScript from an iOS application into a web application. I have control over the code for both apps. My objective is to develop a JavaScript function that can receive input from a barcode scanner, populate a w ...

When an option is selected in one dropdown, a list is dynamically populated in another dropdown. However, the entire column then displays the selected row's options in a table format

https://i.stack.imgur.com/q7tMT.png Upon selecting an option from a dropdown within a table row, I make a call to an API to fetch a list of strings into another dropdown field for that specific row. However, the entire column is being populated with that r ...

"Successfully implementing AJAX POST functionality, but encountering issues where callbacks are not triggering

I have gone through numerous posts addressing this issue and attempted various solutions, however, none seem to work for me. My AJAX POST function correctly adds the email to my mailing list, but the success and error callbacks are not consistently firing, ...

Developing an npm module that is compatible with both web browsers and Node.js

Currently, I am in the process of developing an npm package that will cater to both web apps and other node modules. If my focus was solely on browsers, I would simply assign window.myExport = myExport; as a direct solution (unless there is a more contemp ...

Placing JavaScript at the bottom of the page, sourced from a Partial Page

I'm trying to display JavaScript code from a Razor Partial Page at the bottom of a (layout) Page. In a similar discussion on Stack Overflow about Including JavaScript at bottom of page, from Partial Views, it was suggested by user Becuzz that using a ...

npm WARNING: The package @angular-devkit/[email protected] is in need of a peer dependency xxxx, however no installation for this dependency has

Attempting to launch an angular project and encountering the following errors: $ npm install npm WARN @angular-devkit/[email protected] requires a peer of @angular/compiler-cli@^14.0.0 but none is installed. You must install peer dependencies yoursel ...

Determine if lazy loading is functioning properly through programming

When it comes to Angular, ensuring lazy-loading remains intact can be tricky. Simply importing something from a lazy-loaded module into the app module can result in eager loading. That's why I make it a point to check for such errors during PR reviews ...

Testing the Mongoose save() method by mocking it in an integration test

I am currently facing an issue while trying to create a test scenario. The problem arises with the endpoint I have for a REST-API: Post represents a Mongoose model. router.post('/addPost', (req, res) => { const post = new Post(req.body); ...

Check a field for validation only when it is visible on the screen

One challenge I'm facing is with an asp.net webform. I have a hidden field that is only displayed when a user selects a radio button. The catch is, this hidden field needs to be mandatory only when it's visible; otherwise, I don't want it to ...

Can you explain the concept of a framework operating "on top of" node.js in a way that would be easy for a beginner to understand?

If someone is new to JavaScript, how would you explain the concept of "on top of node.js" in simple programming language? I am looking for a general explanation as well as specific reference to Express on top of node.js in the MEAN stack. Appreciate your ...

Warning: Unhandled promise rejection occurred while running the test

Currently delving into the world of selenium with a focus on testing the registration page. I've crafted a registration page class equipped with methods for monitoring registrations. However, upon attempting to execute a test within the application cl ...

Ensuring the next tab is not accessible until all fields in the current tab are filled

I am working on a form with a series of questions displayed one at a time, like a slide show. I need help with preventing the user from moving to the next set of questions if there is an empty field in the current set. Below is the script I am using to nav ...

Make an element in jQuery draggable but always within the viewport

My issue is that when I resize the window, the element stays in its position until I start dragging it. Once I drag it and then resize the window again, it doesn't stay within its container. To better illustrate my problem, you can view a demo on Fid ...

Model with no collection involved

Take a look at this Model and View setup. Why is the indicated line not functioning as expected? var app = app || {}; (function () { app.CurrentUserView = Backbone.View.extend({ el: $('.avatar-container'), template: ux.templ ...

Auto-complete feature not populating the input field in Google Chrome

Within my register form, I have various INPUT tags present. One of these INPUTs has the name email. <input type=text name=email id=email> When filling out this form in Chrome, I encounter a peculiar behavior. Upon clicking on the email input field ...

Invoke the function defined within a modal when dismissing a ui-bootstrap modal

Inside my ui-bootstrap modal controller, I have a $watch function set up for a variable. The code snippet looks like this: main.controller('modalCtrl', ['$scope', '$rootScope', '$modalInstance', function ($sc ...