What is the best way to choose an SVG with a title using Cypress?

In my Cypress script, I am looking to click on an element within a div that has the name "name1", description "description1", and title "title1".

Below is the HTML structure:

<div data-testid="table-body" role="rowgroup">
    <div role="row" data-testid="table-row-0">
        <div role="cell">
            <input data-testid="table-row-checkbox"/>
        </div>
        <div data-testid="table-cell-row-0-column-name">
            <button data-testid="expand-row"></button>
            <a class="subtle-link">name1</a>
        </div>
        <div data-testid="table-cell-row-0-column-description">
            description1
        </div>
        <div data-testid="table-cell-row-0-column-isIcon">
            <div>
                <svg>
                    <title>title2</title>
                </svg>
            </div>
        </div>
    </div>

    <div role="row" data-testid="table-row-1">
        <div role="cell">
            <input data-testid="table-row-1-checkbox"/>
        </div>
        <div data-testid="table-cell-row-1-column-name">
            <button data-testid="expand-row"></button>
            <a class="subtle-link">name1</a> //i want to click this element
        </div>
        <div data-testid="table-cell-row-column-description">
            description1
        </div>
        <div data-testid="table-cell-row-column-isIcon">
            <div>
                <svg>
                    <title>title1</title>
                </svg>
            </div>
        </div>
    </div>

    <div role="row" data-testid="table-row-2">
        <div role="cell">
            <input data-testid="table-row-checkbox"/>
        </div>
        <div data-testid="table-cell-row-2-column-name">
            <button data-testid="expand-row"></button>
            <a class="subtle-link">name2</a>
        </div>
        <div data-testid="table-cell-row-1-column-description">
            description2
        </div>
        <div data-testid="table-cell-row-0-column-isIcon">
            <div>
                <svg>
                    <title>title1</title>
                </svg>
            </div>
        </div>
    </div>
</div>

From the above DOM, there are two divs with the name "name1" and description "description1", but the titles are "title1" and "title2".

I attempted the following approach:

cy.get('div[role="row"]')
    .find('div', 'name1')
    .contains('svg', 'title1')
    .parent()
    .click();

However, this selects the first element with the name "name1" even though the title is "title2".

Answer №1

This task can be quite challenging, but I discovered a simple solution using a filter with callback function.

The row parameter represents the raw element (not wrapped in jQuery), so you can use .textContent() to retrieve the text of the node and its descendants - check out MDN - textContent().

cy.get('div[role="row"]')                           // 3 elements found
  .filter((_, row) => {
    return row.textContent.includes('title1') &&
      row.textContent.includes('description1') &&
      row.textContent.includes('name1')             // filters to 1 element
  })
  .find('a')
  .click()

You also have the option of using a selector that already includes the necessary filters

const selector = 'div[role="row"]' +
  ':contains("title1")' +
  ':contains("description1")' +
  ':contains("name1")';
cy.get(selector)
  .find('a')
  .click();

If searching for text within the row proves to be imprecise due to text appearing in other columns, a more accurate filter can target each individual element containing the text (using jQuery in this case),

cy.get('div[role="row"]')
  .filter((_, row) => {
    const title = Cypress.$(row).find('title').text();
    const description = Cypress.$(row).find('div[data-testid="table-cell-row-column-description"]').text();
    const name = Cypress.$(row).find('a.subtle-link').text();
    return title === 'title1' &&
      description === 'description1' &&
      name === 'name1';
  })
  .find('a')
  .click()

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

The Organization of Event Handling in ThreeJs

I am facing the challenge of managing multiple instantiated objects, each requiring its own handling of a specific event. Let's consider a class named "Foo": export default class Foo() { constructor(eventManager) { //reference to an event manage ...

The page quickly displays the splash page only if the user is logged in

I implemented a user authentication system where certain pages are displayed based on whether the user is logged in or not. For instance, when accessing localhost:3000/ (the home page), it should either show the splash screen or the dashboard of the logged ...

Choose a particular form when the dropdown option is changed

I have two forms that I would like to display based on the selection from a dropdown menu. For example, if "Form1" is selected from the dropdown, then Form1 should be displayed. If "Form2" is selected, then Form2 should be displayed. Can anyone suggest h ...

Adding over 20,000 rows to a table can be time-consuming, causing the page to become unresponsive once the process is complete

Looking at my table structure, it appears as follows: <tr ng-repeat="friend in friends | orderBy:predicate:reverse"> <td>{{friend.name}}</td> <td>{{friend.phone}}</td> <td>{{f ...

What is the best way to enable swipe functionality for ion-items in Ionic without requiring a click?

I have been working on implementing an ion-list with swipable ion-items that do not need to be clicked on the side to trigger an event. The functionality I am aiming for is similar to the default contacts app on Samsung phones, where a left swipe calls an ...

Generate HTML table with CSS dynamically applied through jQuery

After performing some calculations and applying CSS rules using the .css() function in jQuery to color the background of a table, I am facing an issue when trying to print the page. The printed page appears in black and white without retaining any styling ...

"Troubleshooting ways to resolve babel-eslint import/export issues without the need for a configuration

Upon running npm start, I encountered the following error message: Parsing error: 'import' and 'export' may only appear at the top level After investigating this issue, suggestions included updating the eslint configuration file with ...

Improved method for managing hash URLs in AJAX-enabled websites

When dealing with pages that have a hash mark in the URL address bar, it can be inconvenient unless using HTML 5 and history.pushState() for AJAX loads. For example, when item1.html is loaded and then the user clicks to view item2.html, the URL changes to ...

Using GeoJson in Leaflet for map display

As I develop an Angular application with Leaflet, my goal is to showcase numerous municipalities within my country: https://i.sstatic.net/9cuSW.png In order to enhance navigation efficiency, I decided to divide my JSON file into multiple files and store ...

Manipulating Object origin data

I'm unsure if this can be achieved. I am aiming to create a header and footer that remain the same while only switching the content pages. The resources I have at my disposal cover HTML, JS, CSS, and JQuery. Below is a simplified version of my curre ...

Optimal method for utilizing Babel to generate a unified JavaScript bundle

I have multiple JS files and I need to combine them into a single JS bundle using Babel. Someone pointed me towards this first resource, but I am having trouble grasping the instructions: https://babeljs.io/docs/usage/cli/ While searching online, I came ...

The localStorage is currently being updated, however there seems to be an issue with the output where false is being mistakenly interpreted

My goal is to show the <BR/> component when the value is true, otherwise display the <Nothing/> component. Despite the value being false, the <BR/> is still appearing for some unknown reason. PC.js code: import React,{useContext, useStat ...

Angular - Dividing Values within Input Arrays

In the input field available to users, they can enter multiple inputs separated by commas. <div class="container"> Enter your values:<input type="text" multiple #inputCheck> <input type="submit"(cli ...

I am interested in utilizing Sequelize, Vue, and Node to implement a query that filters data once it is retrieved to display on my view

Within my project, there's a table tracking user responses to a quiz. By utilizing the following query, I've successfully retrieved all the information from that table and stored it in my TotalQuizResponses array for display: this.totalQuizRespon ...

What steps can I take to ensure that a JavaScript function does not execute when a DOM element from an array has already been chosen?

I am facing an issue with a script that dynamically changes the header based on the selected bubble in an array. The problem arises when the user clicks on the same bubble that is already selected, causing the JavaScript function to run and temporarily cha ...

Angular - Collaborative HTML format function

In my project, I have a function that sets the CSS class of an element dynamically. This function is used in different components where dynamic CSS needs to be applied. However, every time I make a change to the function, I have to update it in each compo ...

Utilizing ReactJS to Transfer States and Props within Reactable Table Rows

I am trying to use the Reactable library for displaying data tables in React. I want the state of my parent component, UsersTable, to be set or changed when a row in the table is clicked so that it remembers the id of the clicked record for future actions. ...

What is the best way to choose a random number using jQuery?

<div class="yyy"></div> <p>...</p> <pre><code>let content = $(".xxx").text(); $(".yyy").html(content); http://jsfiddle.net/tQeCv/ I just require this specific input : Number is {1|2|3|4}, and {one|two|three|four} ...

How can Angular's as-syntax be used to access the selected object?

When using syntax like ng-options="p.id as p.name for p in options" to select options, I encounter an issue. I require access to the variable p as well. This is necessary for displaying additional labels near inputs or buttons, or even making changes to in ...

What is the best way to utilize lodash in order to inspect every element within a collection, excluding those that do not fulfill my specified condition

let allChecked = _.every(this.collection, this.checked); I'm working on tweaking an existing code snippet that currently evaluates to true if every item in the collection has the checked property set to true. My goal is to adjust it so that it only c ...