Accessing a Specific Element in ng-repeat using Protractor

Currently, I am in the process of writing end-to-end tests for an application that is under development. I am specifically focusing on creating a test for alerts generated by the alert directive (Angular UI Bootstrap) within a wrapper directive. Below is the code snippet that outlines my progress:

Let's start with the wrapper directive responsible for generating alerts:

// Import our directive controller
// The controller includes the necessary alert functions for the Angular UI Bootstrap alerts directive
import InfoAlertController from './info-alert.controller.js';

let moduleName = 'infoAlert';

// ## Directive Definition
class InfoAlert {

    constructor() {

        this.template =
        `
            <div>

                <alert
                    ng-repeat="alert in vm.alerts"
                    type="{{ alert.type }}"
                    close="vm.closeAlert($index)" >

                        {{ alert.msg }}

                </alert>

            </div>
        `;
        this.restrict = 'E';
        this.scope = {};
        this.bindToController = {

            name : '@?'
        };
        this.transclude = true;
        this.controller = InfoAlertController;
        this.controllerAs = 'vm';
    }

    // ### Optional Link Function
    link (scope, elem, attrs, vm, transclude) {

    }
}

export default [moduleName, directiveFactory(InfoAlert)];

Next, we can see how the directive is implemented in the user login component view:

<info-alert
     name="loginAlerts">
</info-alert>

The user login component acts as another directive and consists of a form with Angular validation that interacts with an Authentication service.

Now, let's take a look at the test scenario I am struggling to create:

describe('login component', () => {

    it('should display an error after failed authentication', () => {

            browser.get('/login');

            element(by.model('vm.user.username')).sendKeys('nerfherder');

            element(by.model('vm.user.password')).sendKeys('badpassword');

            element(by.css('.btn-custom')).click();

            let e = element(by.repeater('alert in vm.alerts').row(0));

            // No matter what I try, this always fails
            expect(e.isDisplayed()).toBe(true);
    });
});

When running the test, I receive an error message indicating Expected 0 to be greater than 0, suggesting that the method I am using to locate the alerts is not effective. I have attempted to target the alerts by their class using

element(by.css('.alert-danger'));
and element(by.css('.alert')); without success. Even using browser.waitForAngular(); did not yield the expected results.

I also experimented with Protractor Expected Conditions implementation, but unfortunately, it did not resolve the issue either.

While manual testing proves that all functionalities are operational and alerts are triggered during execution, I am still unable to overcome this hurdle. Any assistance would be greatly appreciated, as I find myself stuck at this point.

Solution

A solution based on alecxe's answer is presented below:

describe('login component', () => {

    it('should display an error after failed authentication', () => {

        let EC = protractor.ExpectedConditions;

        browser.get('/login');

        element(by.model('vm.user.username')).sendKeys('nerfherder');

        element(by.model('vm.user.password')).sendKeys('badpassword');

        let alert = element(by.repeater('alert in vm.alerts').row(0));

        let alertLoaded = EC.visibilityOf(alert);

        element(by.css('.btn-custom')).click();

        // Targeting UI Bootstrap alert class
        let e = element(by.css('.alert-danger'));

        browser.wait(alertLoaded, 5000);

        expect(e.isDisplayed()).toBe(true);
    });
});

Upon implementing this revised test approach, the test now executes successfully.

Answer №1

If you're experiencing issues with the alert not appearing, it's important to use explicit waiting:

var EC = protractor.ExpectedConditions;
browser.wait(EC.visibilityOf(element(by.repeater('notification in vm.notifications'))), 5000);

Answer №2

Give this a shot:

let items = element.all(by.repeater('alert in vm.alerts').row(0));

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

Maintain daily data that can be updated in JSON format

I'm working on a web application that utilizes client-side MVC with backbone.js and Spring on the server side. I have a scenario where I require data that needs to be updated daily or every couple of days. The data will be used on the client side for ...

Transferring PHP array data to JavaScript without being exposed in the source code

In the process of creating a historical database, I am currently handling over 2,000 photos that require categorization, out of which approximately 250 have already been uploaded. To efficiently store this data, I have set up a MySQL database with 26 field ...

When attempting to execute the "npm run prod" command, the terminal displays the error message "error:03000086:digital envelope routines::initialization error."

In my current project, which combines vue and laravel, I encountered an issue when trying to run the production command: npm run prod The error message that appeared was: opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization ...

Activate the button when a checkbox is ticked or when using the "select all" checkbox

I'm facing an issue with a script that should enable a button when at least one checkbox is selected and a checkbox for selecting all checkboxes is used. The problem arises when I select the "select all" checkbox as it activates the button, but if I ...

I'm considering incorporating the "react-picky" third-party library for a filterable multiselect component in React Material UI, but it seems to deviate from the principles of Material Design

https://i.sstatic.net/dxpJO.pngInterested in using the third-party library "react-picky" for a filterable multiselect component with React Material UI, but finding that it doesn't align well with Material Design styles. Is there a way to style any th ...

Encountering the below error message when running the command to initialize expo project:

Dependency installation in progress... Warning: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="accfc3dec981c6dfec9d829e829b">[email protected]</a> is deprecated, consider upgrading to core-js@3 or a ne ...

Learn how to update scope variables in Angular.io's mat-autocomplete using the [displayWith] function feature

I'm encountering a problem where I am unable to update locally declared variables in the component controller that triggers the mat-autocomplete. The issue is that these variables are confined within a specific scope, preventing me from making any mod ...

The form does not seem to be updating or refreshing even after an AJAX submission and validation

I have a form set up to submit data to my database using jQuery Validate plugin and ajax. However, I'm encountering an issue where after clicking submit, the form does not clear out. While the data does get updated in the database, I need help figurin ...

CSS Flexibility

Greetings everyone, it's been a while since I dabbled in web development. I recently worked on my site with the intention of making it responsive using flexbox. This is my first time posting here, so please guide me on how to seek help more effective ...

Can you please tell me the name of the ??= operator in Typescript?

The Lit Element repository contains a function called range that utilizes the ??= operator. This operator resembles the nullish coalescing operator but with an equal sign. Do you know what this specific operator is called? Below is the complete code snipp ...

How can I easily move from a shared page to a specific page in Angular 8?

Just stepping into the world of front-end development, I have a scenario where my menu page offers 3 options to navigate: Go to Arena. Go to Dungeon. Go to Battleground. However, clicking on any of these options leads me to a common page for character p ...

Submitting a POST request using a Chrome Extension

I am in the process of developing a Chrome extension popup for logging into my server. The popup contains a simple form with fields for username, password, and a submit button. <form> <div class="form-group"> <label for="exampleInputE ...

I'm encountering an issue where I receive the error `Cannot read property 'map' of undefined` while attempting to integrate the backend with React. What could be causing this error and how

I'm currently learning React and I've been using a tutorial here to connect my database to the front end of my React application. Unfortunately, every time I try running 'npm start' at 'localhost:3000' in express-react/backend ...

I'm looking to incorporate a module from another component (Next.js, React.js) into my project

I need to implement the "StyledSwiperPagination(swiper-pagination-bullet) at SwiperImages.tsx" in "index.tsx". The problem is that when I added <StyledSwiperPagination /> in index.tsx, nothing appeared on the screen. Lorem ipsum dolor sit amet, co ...

Can existing servers support server side rendering?

I am currently working on building a Single Page Application (SPA) using the latest Angular framework. The SPA will involve a combination of static HTML pages, server side rendering, and possibly Nunjucks templating engine. My dilemma lies in the fact th ...

It appears that the lodash throttle function is not being invoked

I recently started utilizing lodash's throttle function to control the number of calls made to an API. However, I am facing difficulties as the call doesn't seem to be triggered successfully. Below is a simplified version of what I have attempte ...

I find myself pondering the reason behind my inability to overwrite the jquery function onRegionOver. The contents of the WAMP index.html file can

I'm curious about why I'm having trouble overriding the jquery function onRegionOver. Below is the code snippet from my WAMP index.html file. Can anyone suggest how I might use the WAMP console to troubleshoot this issue? I'm attempting to g ...

Implement a recursive approach to dynamically generate React components on-the-fly based on a JSON input

My goal is to develop a feature similar to Wix that allows users to drag and drop widgets while adjusting their properties to create unique layouts. To achieve this, I store the widgets as nested JSON documents which I intend to use in dynamically creating ...

Issue with redirecting after confirming user info permissions on Facebook login

Can anyone assist me with the final step of my Facebook login feature? The current issue is that when a new user first signs in, they are greeted with a popup labeled 'www.facebook.com/v11.0/dialog/oauth' that asks them to authorize my page to a ...

Is there a way to switch out the ionic2-super-tabs Toolbar for the ion-slides pager feature?

Hello there, Currently, I am utilizing the following plugin in my Ionic 3 project: https://github.com/zyra/ionic2-super-tabs The plugin offers a great functionality for swipeable tabs in Ionic applications. In its documentation, it demonstrates how to hi ...