The feature of using a custom find command in Cypress does not support chaining

I am interested in developing a customized Cypress find command that can make use of a data-test attribute.

cypress/support/index.ts

declare global {
  namespace Cypress {
    interface Chainable {
      /**
       * Creating a custom command to locate a DOM element by its data-test attribute.
       * @example cy.getByTestId('element')
       */
       getByTestId(selector: string): Chainable<JQuery<HTMLElement>>;

      /**
       * Creating a custom command to find a DOM element using its data-test attribute.
       * @example cy.findByTestId('element')
       */
      findByTestId(selector: string): Chainable<JQuery<HTMLElement>>;
    }
  }
}

cypress/support/commands.ts

Cypress.Commands.add('getByTestId', (selector, ...args) => {
  return cy.get(`[data-test=${selector}]`, ...args);
});

Cypress.Commands.add(
  'findByTestId',
  { prevSubject: 'element' },
  (subject, selector) => {
    return subject.find(`[data-test=${selector}]`);
  }
);

It is important to note that subject is of type JQuery<HTMLElement> and not

Cypress.Chainable<JQuery<HTMLElement>>
, causing subject.find to not be chainable with other methods.

I am encountering the following errors from TypeScript.

No overload matches this call.
  Overload 1 of 4, '(name: "findByTestId", options: CommandOptions & { prevSubject: false; }, fn: CommandFn<"findByTestId">): void', gave the following error.
  Overload 2 of 4, '(name: "findByTestId", options: CommandOptions & { prevSubject: true | keyof PrevSubjectMap<unknown> | ["optional"]; }, fn: CommandFnWithSubject<"findByTestId", unknown>): void', gave the following error.
  Overload 3 of 4, '(name: "findByTestId", options: CommandOptions & { prevSubject: "element"[]; }, fn: CommandFnWithSubject<"findByTestId", JQuery<HTMLElement>>): void', gave the following error.ts(2769)
cypress.d.ts(22, 5): The expected type comes from property 'prevSubject' which is declared here on type 'CommandOptions & { prevSubject: false; }'

Intended usage

cy.getByTestId('some-element')
  .findByTestId('some-test-id')
  .should('have.text', 'Text');

How can I resolve this issue?

Answer №1

It's possible that I'm mistaken, but it appears that subject.find(...) is utilizing the jQuery find method.

You might consider using cy.wrap(subject).find(...) instead, as this should result in the Cypress.Chainable wrapper.

Answer №2

In your programming file, you would include a command similar to this one. It is important to note that this will record the cy.wraps and you can choose to add log: false to suppress that. Additionally, you have the option to add another parameter and create an if statement to utilize data-testid with .contains().

Cypress.Commands.add(
  'byTestId',
  { prevSubject: 'optional' },
  (subject, id) => {
    if (subject) {
      return cy.wrap(subject).find(`[data-testid="${id}"]`)
    }
    return cy.get(`[data-testid="${id}"]`)
  },
)

This demonstrates how the command would be used in an application scenario.

cy.byTestId('first-id')
  // potentially include assertions for visibility check here
  .byTestId('id-inside-first-element')
  // potentially include assertions for visibility check here
  .byTestId('id-within-this-second-element')

Answer №3

Needed to include a cy.wrap function around the JQuery element as shown below.

Cypress.Commands.add(
  'findByTestId',
  { prevSubject: 'element' },
  (subject, selector) => {
    return cy.wrap(subject).find(`[data-test=${selector}]`);
  }
)

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

What is the best way to insert a React component or raw HTML into another React component?

Dealing with raw HTML markup returned from an AJAX call can be tricky in React. I've tried using dangerouslySetInnerHTML, but React just throws errors when I do. It's like trying to navigate through a maze. After some trial and error, I decided ...

Incorporate user input into Alert Dialog Boxes

Would you be able to assist me in displaying the input value from the "email" field in my alert box? The code seems to be working fine, but I'm having trouble getting the alert box to show the email form value. I decided to use Bootstrap for som ...

Choosing premier class and modifying characteristics

Looking for a solution to hide a div without modifying the HTML code directly? By using JQuery, you can manipulate the appearance of elements on a page. While it's possible to select the first instance of a class and retrieve its value, adding an attr ...

What are some ways to trigger a function once the modal has finished loading?

I'm looking to trigger a function on the Bootstrap modal after it has been opened. I came across the event show.bs.modal in the documentation. I attempted to connect to the modal using this code: $('#my-modal').on('show.bs.modal' ...

Using PHP and Ajax to retrieve a distinct string prior to executing a time-consuming script

It's a question that comes up often. In short, I want to display progress to the user while a lengthy script is running. This is my approach: store "progress" in mysql so that Ajax can access it (via PHP). "progress()" is the lengthy script being te ...

What are the steps to properly build and implement a buffer for socket communication?

I have encountered an issue while converting a code snippet to TypeScript, specifically with the use of a Buffer in conjunction with a UDP socket. The original code fragment is as follows: /// <reference path="../node_modules/DefinitelyTyped/node/node ...

Transforming a JSONP request to automatically parse a text response into JSON

If I have the following request $.ajax({ type: "GET", dataType: "jsonp", jsonp: "callback", jsonpCallback: "my_callback", url: my_https_url, headers:{"Content-Type":"text/html; charset=utf-8"}, success: function(data) { ...

Transform JSON-serialized string with HTML entities into an object

Looking for a solution to convert the following string into an object using Javascript: "[&quot;Software&quot;,&quot;3rd Party&quot;]" While I know how to convert HTML Entities to DOM Objects with this code: $("<div/>").html(encode ...

Experiencing an inexplicable blurring effect on the modal window

Introduction - I've implemented a feature where multiple modal windows can be opened on top of each other and closed sequentially. Recently, I added a blur effect that makes the background go blurry when a modal window is open. Subsequently opening an ...

Error message: "react-router typescript navigation version 0.13.3 - Unable to access 'router' property"

I'm currently in the process of porting an existing React project to TypeScript. Everything seems to be going smoothly, except for the Navigation mixin for react-router (version 0.13.3). I keep encountering an error message that says "Cannot read prop ...

obtain a Javascript variable within a Jade template by using inline code

script. var hide_section = 'block'; .title(style='display:#{hide_section}') I received an undefined value, any thoughts on why? Could it be because #{hide_section} is trying to access a variable from the back-end, such as the cont ...

Utilize Autocomplete component from Material UI to sift through distinct option values

Looking to implement unique options in the dropdown menu of an Autocomplete component from Material UI based on a specific property within a list of objects. The current issue is that duplicate values are appearing in the dropdown, like ['Color1&apos ...

What is the process for implementing a grid with 5 columns on larger screens and 2 columns on smaller screens using reactjs?

I am currently working on building a Grid using material UI and reactJs. I found the guidelines on this link https://mui.com/system/react-grid/. However, there seems to be an issue with creating 5 columns in the grid. I attempted to create a custom grid ...

How to manage a POST request in a GET route using express.js

Exploring the world of Express and Node.js together for the first time has brought me face to face with what appears to be a simple roadblock. I've set up an API route that utilizes the GET method. Here's the route: app.get('/api/v1/all&apo ...

Bokeh is having trouble loading from the CDN

I am currently attempting to embed a plot along with its data by utilizing autoload_static within a straightforward html page that I wish to view locally on my computer. According to the documentation, all I need to do is place the .js file in the specifie ...

Injection of dependencies in Angular can be done outside of the constructor

In my class, I have a constructor that takes in some data. export class MyClass { constructor(data: any) { this.data = data; } } I also want to include ChangeDetectorRef as a parameter in the constructor like this. constructor(data: any, cd: ...

Creating a Map Using HTML and JavaScript

My current project involves creating a simple map that can be moved with mouse drag functionality, featuring images such as islands. I have successfully retrieved the mouse position by declaring variables posX and e.clientX, as well as for e.clientY. Howe ...

Is VueJS2 using the computed property/method to modify Vue data?

My form in Vue is almost complete, but I'm facing an issue with an array that seems to be affecting my Vue.data object directly. Here's the situation: In my code, I have a method called getParams() which returns an object containing all the data ...

Selecting an object from JSON data with Angular using $routeParams

I am attempting to showcase information from a JSON file that is structured like this: [ { "category":"category1", "link":"category1", "expand":false, "keyword":"category1, category1 online, category1 something" }, { "category":" ...

"Utilize the attr attribute to showcase an image within an HTML select element

I'm trying to showcase the flag of each country in a dropdown menu. Here is the code I attempted: <select id="slcCountry"> <option flag="https://restcountries.eu/data/afg.svg">AFG</option> <option flag="https://restcountr ...