Is it possible to loop through each row in a table using Cypress and execute the same actions on every iteration?

I have a frontend built with html/typescript that features a table of variable length containing action buttons in one of the columns. I am looking to create a Cypress test that will click on the first button of the first row, carry out a specific task, and then continue to click on the first button of each subsequent row to perform the same task.

Here is an initial preview of the table with the leftmost button that needs to be clicked for each row:

https://i.stack.imgur.com/U9D3k.png

Upon clicking the leftmost button for a row, a dialog box appears where the user must input values into two text fields before clicking OK:

https://i.stack.imgur.com/HljnX.png

In the actual application, the user can repeat this process for as many rows as needed.

The code snippet for the confirmation dialog looks like this:

<p-dialog class="e2e-mark--confirm-dialog" header="Publish Report" [modal]="true"
  [(visible)]="showPublishReportDialog" (onHide)="cancelPublishReport()" [style]="{width: '30vw'}">
<div class="detail-row">
  <div class="detail-property-container">
    <span class="selector-item-type detail-label">

      Notes: *&nbsp;
    </span>
    <input id="notes" pInputText maxlength="50" formControlName="notes" [(ngModel)]="publishReportNotes"
      [style]="{width: '20vw'}" [attr.data-cy]="'publishReportNotesText'">
  </div>
  <div class="detail-property-container">
    <span class="selector-item-type detail-label">
      Comments: *&nbsp;
    </span>
    <input id="comments" pInputText maxlength="50" formControlName="comments" [(ngModel)]="publishReportComments"
      [style]="{width: '20vw'}" [attr.data-cy]="'publishReportCommentsText'">
  </div>
  <span *ngIf="publishDraftInLaps" class="selector-item-type detail-label">
    This will also create a draft PCD in LAPS Planning & Scheduling - which will take a few minutes.
  </span>
</div>
<hr />
<p-footer>
  <button pButton label="Cancel" (click)="cancelManageWeaponSystemsDialog()"></button>
  <button pButton label="OK" (click)="publishReport(false)"
    [disabled]="publishReportForm.invalid" [attr.data-cy]="'publishReportButton'"></button>
</p-footer>
  </form>
</p-dialog>

Additionally, here is a segment of code from my test.cy.ts file:

The objective is to iterate through the rows of the table and execute the same functionality by clicking on the left button, filling in the dialog, and clicking OK for each row:

cy.get('tbody > tr')
        .each(($row, $rowIndex) => {
            cy.log('rowIndex:  ' + $rowIndex);
            
            let cell = $row.find('td:nth-child(2)');
            
            
                
            cy.log('publishin the ' + cell.text().trim() + ' file');
            let actionButtons = $row.find('td:nth-child(1)');
            let publishButton = actionButtons.children().first();
            publishButton.click();
            cy.setInputText('[data-cy="publishReportNotesText"]','Report Notes for ' + cell.text().trim());
            cy.setInputText('[data-cy="publishReportCommentsText"]','Report Comments for ' + cell.text().trim());
            cy.get('[data-cy="publishReportButton"]').click();
                
                 
            
    });

While this flow works smoothly for the first row processed, it encounters issues with the second row:

The dialog does not appear for the second row, preventing any inputs into the confirmation dialog:

'cy.type()' fails due to targeting a disabled element.

Any advice or suggestions would be greatly appreciated. Thank you.

Answer №1

To resolve the issue of targeting a disabled element, consider waiting for the element to become enabled.

cy.get('tbody > tr').each(($row, $rowIndex) => {
  ...
  publishButton.click();

  cy.get('[data-cy="publishReportNotesText"]').should('be.enabled')
  cy.setInputText('[data-cy="publishReportNotesText"]', ... )

  cy.get('[data-cy="publishReportCommentsText"]').should('be.enabled')
  cy.setInputText('[data-cy="publishReportCommentsText"]', ...)

  cy.get('[data-cy="publishReportButton"]').click()
});

The .each() method may be causing stale element references due to click() actions inside it that could modify the DOM.

If you have only three rows, avoid using .each() and handle each row separately as shown below:

cy.contains('tbody > tr', 'e2e_tests.xml').then(($row, $rowIndex) => {
  ...

Additionally, ensure that the text you input has been successfully updated in the DOM before proceeding to the next row.

cy.get('[data-cy="publishReportNotesText"]').should('be.enabled')
const text = 'Report Notes for ' + ...
cy.setInputText('[data-cy="publishReportNotesText"]', text)
cy.get('[data-cy="publishReportNotesText"]').should('have.value', text)

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

Learn how to generate specific error messages based on the field that caused the failure of the @Column({ unique: true }) Decorator. Error code 23505

Hey there! I'm currently facing an issue while trying to handle Sign Up exceptions in my code. I want to inform the user if their username OR email is already in use. Although using the decorator @Column({ unique: true}) allows me to catch error 23505 ...

The TypeScript namespace does not exist or cannot be located

Currently, I am working on coding in TypeScript. The specific code pertains to an Angular 2 application, but the main focus of my inquiry lies within TypeScript itself. Within my project, there are certain files that contain various models, such as the exa ...

Using a static value in the comparator is necessary for Array.find to function properly in Typescript

Looking to retrieve an item from an array: const device = this.selectedDevtype.devices.find(item => console.log(this.deviceID); return item.device_id === this.deviceID; }); console.log(device); When this.deviceID is logged, it shows "4", but t ...

Troubleshooting tsconfig configuration issue in Visual Studio Code for ExpressJS with TypeScript and Vitest integration testing

Let's dive right in with an illustration: Here is a simplified version of my project structure: src/ app.ts test/ integration/ example.spec.ts tsconfig.json tsconfig.json The main tsconfig.json file includes these settings: { & ...

Dynamic React Gallery with Interactive Image Picker

Looking to develop a new photo management application as an alternative to Google Photos, with a focus on displaying and selecting images in a user-friendly way. Currently using the react-grid-gallery library for this purpose. Here is my current implement ...

Update the input value with the selected option from the dropdown menu in Angular

How can I dynamically set the value of an input field based on the selection from a dropdown menu in Angular using Reactive Forms? Below is my HTML code: <nb-card> <nb-card-header> Services </nb-card-header> <nb-card-body&g ...

Ensuring the value of a v-text-field in Vuetify using Cypress

I am currently developing an end-to-end test suite using Cypress for my Vue and Vuetify frontend framework. My goal is to evaluate the value of a read-only v-text-field, which displays a computed property based on user input. The implementation of my v-tex ...

What are the reasons for the inability to send form-data in Postman?

Encountering an issue when trying to send form-data in postman as Sequelize returns an error: value cannot be null However, everything works fine when sending a raw request with JSON. Have tried using body-parser and multer, but no luck. This is my inde ...

Ways to access the chosen value from Ionic's popover modal

I have been working on a simple Ionic 4 Angular app and I am using an Ionic popover modal. The code below shows how I open the popover modal in my application: //home.page.ts async openModal(ev: Event) { const modal = await this.popoverController.create({ ...

Using React and TypeScript together can lead to issues when trying to use union keys as an index

I've implemented a hook using useState and the delete method to effectively manage my form values. const [values, setValues] = useState<tAllValues>({}); The values stored include: { name: 'Andrew', age: 34, avatar: [{ name: ...

Merging all Angular 2 project files into a single app.js document

I've scoured the depths of the internet for an answer to this burning question: How can I merge all my Angular 2 code, along with its dependencies, into a single file? Although this query has been posed countless times before, I bring a fresh perspect ...

What is the process of inserting a sparkline chart into a Kendo Angular grid?

I am attempting to display a bullet chart in the first column of my grid. <kendo-grid-column> <ng-template kendoChartSeriesTooltipTemplate let-value="value"> <div> <kendo-sparkline [data]="bulletData" type="bullet" [ ...

Personalizing Dialog Title in material-ui

While delving into the world of React and Material-UI, I encountered a challenge in updating the font color in the DialogTitle component. After browsing through various resources, I came across a helpful link that suggested overriding the dialog root class ...

Encountering issues when verifying the ID of Angular route parameters due to potential null or undefined strings

Imagine going to a component at the URL localhost:4200/myComponent/id. The ID, no matter what it is, will show up as a string in the component view. The following code snippet retrieves the ID parameter from the previous component ([routerLink]="['/m ...

Creating an Angular table using reactive forms: a step-by-step guide

After reviewing the HTML snippet provided below, it is evident that there is a table with looping through mat cell using *matCellDef="let model". Inside each cell, there are input fields which are reactive forms. Each row or cell needs to have it ...

Cypress OPENSSL_internal:NO_START_LINE error detected

Has anyone encountered this error before? I've already tried clearing the cypress cache and reinstalling it, but the error persists. I couldn't find a solution to resolve this issue. The version I am using is 6.5.0. Error: error:0900006e:PEM rou ...

Sending data using formData across multiple levels of a model in Angular

I have a model that I need to fill with data and send it to the server : export interface AddAlbumeModel { name: string; gener: string; signer: string; albumeProfile:any; albumPoster:any; tracks:TrackMode ...

Is there a way for me to access the data stored in session storage in Next.js?

One of the components in my project is a slider, which allows users to set the number of columns in an Image Gallery component. This code snippet shows the implementation of the slider component: export default function Slider({ value, handleChange }: ISl ...

Removing the AM and PM from OwlDateTime in Angular is simple since the time format is already in 24-hour time

Using OwlDateTime in a 24-hour format: <div *ngIf="isSchedule" class="form-inline"> <label style='margin-right:5px ;margin-left:210px'> Date Time: <input [owlDateTimeTrigger]="dt" [owlDateTime]="dt" class="form-control" placeh ...

Executing a function within JSX to dismiss a modal in NextJS

I am currently utilizing the Tanstack React Query library to perform a POST request from a Modal that includes a form: const addDay = (day: TDay) => { const apiURL = process.env.NEXT_PUBLIC_SERVER_URL const queryURL = apiURL + router ...