How to get a row and select a specific td in cypress?
Asked Answered
C

3

14

I have a table with 6 columns and variable rows. Now i want cypress to test the delete button. so i create a testitem in my table in the test before and want my program to delete this testitem.

How can i search in a table in column 2, filter the row and click on the button in column 6 with cypress?

I read the docu and guide on cypress.io but i have not find any solutions.

    <div class="row">
        <div class="top-buffer"></div>
        <div class="panel panel-primary">
            <div class="panel-heading panel-head">Article</div>
            <div class="panel-body">
                <div class="btn-group">
    
                    <a asp-action="Edit" asp-route-id="@Guid.Empty" class="btn btn-primary"><i class="" glyphicon glyphicon-plus"></i>NEW</a>
                </div>
                <div class="top-buffer"></div>
                <table class="table table-bordered table-striped table-condensed">
                    <thead>
                        <tr>
                            <th>1</th>
                            <th>2</th>
                            <th>3</th>
                            <th>4</th>
                            <th>5</th>
                        </tr>
                    </thead>
                    <tbody>
                        @foreach (var att in Model)
                        {
                        <tr>
                            <td>@Html.DisplayFor(modelItem => att.1)</td>
                            <td>@Html.DisplayFor(modelItem => att.2)</td>
                            <td>@Html.DisplayFor(modelItem => att.3)</td>
                            <td>@Html.DisplayFor(modelItem => att.4)</td>
                            <td>@Html.DisplayFor(modelItem => att.5)</td>
                            <td>
                                <a asp-action="Edit" asp-route-id="@att.Id" class="btn btn-info"><i class="glyphicon glyphicon-pencil"></i>EDIT</a>
                                <a asp-action="DeleteCategory" asp-route-id="@att.Id" class="btn btn-danger"><i class="glyphicon glyphicon-trash"></i>DELETE</a>
                            </td>
    
                        </tr>
                        }
                    </tbody>
                </table>
            </div>
        </div>
    </div>
Chough answered 4/2, 2020 at 10:49 Comment(3)
Can you add some HTML/Code? That will help us help you.. If you paste the HTML of your app here, I am sure someone will be able to help you..Isonomy
I see only one row, will that always be the case. Why do you need to search in column 2? You could easily click the button by cy.get('.btn').click, but I am thinking you will have more rows? Correct? I will try something down below..Isonomy
there is also a button to add more rows. so i can add rows i really need while using this webservice. but in my test i only want to delete the one item i will add duriing my test.Chough
P
30

The code you show is ASP.Net source which gets compiled on the server, so the HTML in the browser (the HTML your test needs to work with) will be different.

i.e @foreach (var att in Model) gives you a row for each item in Model and @Html.DisplayFor(modelItem => att.2) will be translated into some concrete content for column 2.

Therefore, it would be easier to answer if you run the app in a browser and copy and paste that HTML from the console.

Since you want to search on column 2, that can go two ways.

If the content in column 2 is very unique, e.g names that do not appear in other columns, you can target it just by looking for the text

cy.contains('td', 'text-to-search-for')  // gives you the cell 
  .parent()                              // gives you the row
  .within($tr => {                       // filters just that row
    .get('td a')                         // finds the buttons cell of that row
    .contains('DELETE')                  // finds the delete button
    .click()

OR

cy.contains('td', 'text-to-search-for')  // gives you the cell 
  .siblings()                            // gives you all the other cells in the row
  .contains('a', 'DELETE')               // finds the delete button
  .click()

If text you want to search for can appear in columns other than column 2, it becomes more difficult, but chances are the above will suffice.

The other thing to note, if your test scenario always uses the same data, e.g from a fixture file, you can target specific row numbers but that's a fragile test which will need re-writing if the structure of the page changes.

Postmistress answered 4/2, 2020 at 20:30 Comment(2)
Hi Marion Morrison I am really grateful for your help. It works for me.Chough
Thanks Marion, the first answer helped me. You can actually skip a step by just grabbing the 'tr' instead of the 'td' then you won't need to get the parent. This also allows you to grab something higher than the parent.Puma
I
3

Your Html only had one row, so clicking that button should be easy if that is the case..

cy.get('.btn').click

I am betting that will cause problem later, because you will probably have more rows.

 cy.get('table').find('tr').eq(ROW INDEX).find('td').eq(COLUMN INDEX).find('.btn-danger').click()

Now I don't think this is the best way to do this. I would suggest you add some classes to your code so you can easier get to your elements. For example add a class to the delete button that is class="delete-item" so you can use that in a selector

   cy.get('table').find('tr').eq(ROW INDEX).find('td').eq(COLUMN INDEX).find('.delete-item').click()

I am not 100% sure about this answer because I did not try it.

Isonomy answered 4/2, 2020 at 15:31 Comment(0)
L
1

You can do this in two ways:

First method:

You can add data-testid to your delete button and simply locate it with:

cy.get("[data-testid='YOUR TEST ID HERE']").eq(0).click()

Second method:

This is more like the first. You can add a dynamic data-testid to each row delete button. This can easily be done in the @foreach section. Using the index in the loop you can add a data-testid as YOUR-DATA-TEST-ID-${index}.

Then select with

cy.get(`[data-testid='YOUR-TEST-ID-${index}']`).click()
Loram answered 13/2 at 8:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.