Dan Swain
Dan Swain

Reputation: 3108

Cypress custom command is not recognized when invoked

I've created the following custom command in my cypress/support/commands.js file.

Cypress.Commands.add("login", (username, password) => {
    cy.request({
        method: 'POST',
        form: true,
        url: '/test/login/',
        body: {'username': username, 'password': password}
    })
})

I had tests passing and login working before moving the login functionality to this custom command. I'm invoking it in my spec with cy.login(testuser, testpwd), but I'm getting the following error message: TypeError: cy.login is not a function. The docs say that /cypress/support/commands.js is loaded before any test files are evaluated, so I assumed that simply placing a custom command in there would make the command available. I'm running the tests through the local (GUI) test runner.

Upvotes: 27

Views: 39171

Answers (9)

totymedli
totymedli

Reputation: 31182

tl;dr

Wrap the Cypress.Commands.adds to a function then import and run it.

Explanation

I had all my Cypress.Commands.adds in the support/commands.ts file. This was imported in support/e2e.ts with import './commands'; which worked fine until a recent dependency upgrade. To make it work again I modified the support/commands.ts file so it looks like this:

export default function addCustomCommands() {
  // all the Cypress.Commands.add calls
}

Then imported and executed this function in the support/e2e.ts file:

import addCustomCommands from './commands';

addCustomCommands();

Upvotes: 1

Jaime Roman
Jaime Roman

Reputation: 989

I'm using cypress version 12.16. This is my cypress.config.js

const { defineConfig } = require('cypress')

module.exports = defineConfig({
  e2e: {
    baseUrl: 'http://localhost:3000',
    supportFile: "cypress/support/index.js",  <------ refer the index.js file into support folder
  },
})

Then the index.js file is importing my customs commands

import './commands'

My commands.js file

Cypress.Commands.add('login', (url, user) => {
    //..
})
Cypress.Commands.add('logout', () => {
    //..
})

Upvotes: 1

DRC
DRC

Reputation: 1

I added at the top of commands.js.

/// <reference types="cypress" />
export{}

//CUSTOM COMMANDS...

This then exported and exposed the custom commands after cy. .

Upvotes: 0

Jayashani Mandila
Jayashani Mandila

Reputation: 11

Removing

import { cy } from "date-fns/locale";

or similar import

from the test file, resolved this. This gets added automatically to resolve undeclared cy objects

Permanent Solution: Add the following to cypress.json

"compilerOptions": {
   "types": ["cypress"]
}

Upvotes: 0

Deepanshu Singh
Deepanshu Singh

Reputation: 19

For me it worked when I added the type signature of the custom command in the file cypress/support/index.d.ts. For more information visit: Cypress example - Custom Commands

declare namespace Cypress {
  interface Chainable {
    clearLocalStorageIframe(): void
  }
}

I am using 7.2.0 Cypress and command.ts and index.ts file extension I have changed it to .ts

Upvotes: 1

pico_prob
pico_prob

Reputation: 1385

TL;DR: Check if your IDE tried to resolve cy

I slipped into this problem, because my IDE's autocomplete feature added a dependency to resolve the undeclared cy object – that gets injected by cypress.

const { default: cy } = require('date-fns/esm/locale/cy/index.js');

This was very unfortunate, as there is an ongoing (in 2022) issue with the custom commands and you can find a tons of hints..

Upvotes: 0

Oleksi&#239; Nikonov
Oleksi&#239; Nikonov

Reputation: 5598

It may help to put a line import './commands.js' into index.js.

Upvotes: 3

GrayedFox
GrayedFox

Reputation: 2563

To expand on @Dinesh Kumar's excellent answer, it's also important you haven't disabled support for the default support file (I know, unfortunate naming scheme in this case) inside your cypress.json by adding the line: supportFile: false.

Delete that line from your cypress.json if it's there. You can also specify a different path if you're not happy using the default path of cypress/support/index.js.

Working index.js with commands.js file - both in the support folder:

// index.js
const customCommands = require('./commands.js')

module.exports = {
  commands: customCommands
}

And double check your settings:

// cypress.json
{
  "baseUrl": "http://demo.your-domain.test",
  "supportFile": false,  // <-- delete this line present
  ...
}

Upvotes: 13

Dinesh Kumar
Dinesh Kumar

Reputation: 1742

All the code and referenced modules in index.js are loaded before your test file. So you need to refer(require) commands.js in your index.js file. You can however import commands.js module directly in your test file but then you need to include it every test file. Recommended approach is to include it in index.js file and you are not worried about explicitly refer in your test files.

Upvotes: 27

Related Questions