Cypress Custom TypeScript Command is not a Functio

2019-07-13 18:22发布

问题:

I am implementing a custom Cypress in TypeScript:

// support/commands.js
const login = () => {
    console.log('Logging in...');
};

Cypress.Commands.add('login', login);

declare namespace Cypress {
    interface Chainable {
        login: typeof login;
    }
}

I try to call it using:

describe('Login Scenario', () => {
    it('should allow a user to login', () => {
        cy.visit('/');
        cy.login();
    });
});

Yet, it seems the command is not set up:

TypeError: cy.login is not a function

If I write the command in pure JavaScript (removing the namespace declaration and updating the call to (cy as any).login();, it works.

What am I missing?

回答1:

I fixed it by adding index.d.ts file in my commands folder. In this file I added something like this:

import { MyCustomType } from '../Types';

declare global {
  namespace Cypress {
    interface Chainable<Subject = any> {
      login(): Chainable<MyCustomType>;
    }
  }
}

If You don't import or export anything, just omit global namespace declaration:

declare namespace Cypress {
  interface Chainable<Subject = any> {
    login(): Chainable<MyCustomType>;
  }
}

Keep in mind that it won't work with Typesciprt < 2.3, becuase default generics type has to be supported.



回答2:

Here is what I use and I do not have to add /// <reference types="cypress" /> at the top of every file.

I have my custom typings under <projectroot>/cypress/support/index.d.ts

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

declare namespace Cypress {
  interface Chainable<Subject> {
    getByDataTest(tag: string): Chainable<any>
  }
}

And my <projectroot>/cypress/tsconfig.json looks like

{
  "compilerOptions": {
    "strict": true,
    "baseUrl": "../node_modules",
    "target": "es5",
    "lib": ["es5", "dom"],
    "types": ["cypress"],
    "typeRoots": ["./support"]
  },
  "include": ["**/*.ts"]
}

And TypeScript is finally happy

describe('when I want to select by data test tag', () => {
  it('should select by data test tag', () => {
    cy.getByDataTest('yolo').should('exist')
  });
});