Doctor Who
Doctor Who

Reputation: 1649

TS2339: Property 'username' does not exist on type 'JQuery<HTMLElement>'. When using Cypress fixtures

I'm new to using TypeScript, I'm trying to convert my Cypress tests to TS but I'm having an issue whenever I'm reading from the fixtures file I get an error e.g.

TS2339: Property 'username' does not exist on type 'JQuery'.

An example of when I get the error is:

 cy.fixture("details").as("details");

    cy.get("@details").then((users) => {
      const user: string = users.username;

I can get it to run if I make users of type any e.g.

.then((users: any)

but I know that's not a good way to get around it.

I've seen a couple of other questions with a similar error but I'm not sure how to get those solutions working with Cypress, can anyone suggest anything that might help?

Upvotes: 3

Views: 2885

Answers (2)

Eddy Gilmour
Eddy Gilmour

Reputation: 3120

In cypress.d.ts there's interface Chainable that includes this definition for the get(alias) syntax

/**
 * Get one or more DOM elements by alias.
 * @see https://on.cypress.io/get#Alias
 * @example
 *    // Get the aliased ‘todos’ elements
 *    cy.get('ul#todos').as('todos')
 *    //...hack hack hack...
 *    //later retrieve the todos
 *    cy.get('@todos')
 */
get<S = any>(alias: string, options?: Partial<Loggable & Timeoutable & Withinable & Shadow>): Chainable<S>

For some reason it's not picking up in tests, but you can patch it in

/// <reference types="cypress" />

// Add type definition in test file or /cypress/support/index.ts
declare namespace Cypress {
  interface Chainable {
    get<S = any>(alias: string, options?: Partial<Loggable & Timeoutable & Withinable & Shadow>): Chainable<S>
  }
}

it('sees the get(alias) type def', () => {

  cy.fixture("example").as("details")   // using example fixture installed by Cypress

  cy.get("@details").then((user) => {
    const name: string = user.name  // no error
    const email: string = user.email  // no error
  })
})

If you just want to type as a generic object, use Cypress.ObjectLike, defined in cypress.d.ts as

interface ObjectLike {
  [key: string]: any
}

Use in test as

/// <reference types="cypress" />

cy.get<Cypress.ObjectLike>("@details").then((user) => {
  const name: string = user.username;
})

Note
The Cypress dfn for alias has generic type get<S = any>, so your solution .then((users: any) => is pretty much equivalent.

Upvotes: 1

Mikhail Bolotov
Mikhail Bolotov

Reputation: 1104

First, you have to define a type for your user structure, something like this:

class User {
  username: string
}

After that you can reference this type when you request the alias value (notice the get<User> expression):

    cy.get<User>("@details").then((users) => {
          const user = users.username;
    }

Upvotes: 1

Related Questions