Documenting Cypress custom commands
Tags: cypress, javascript, typescript, beginners
Published: 2021-12-06 19:11:12

On November 23rd, 2021 I held my talk about documenting Cypress custom commands in the Cypress.io Dutch meetup group. Because of that I thought let me also write a blog about it so that people can get started with this ASAP and not when you have 100 commands.

For the people who want to follow step by step you can check out the manual way, there is also an easy way with using a VSCode plugin and for people interested in my story I also shared the youtube recording of the meetup.


## Manual way

The best way to learn something is to do it manually so let's create step by step each file needed so that in the end we have docs and IntelliSense for our custom commands.

One of Cypress's biggest features is having autocompletion(IntelliSense) and seeing what every Cypress command does with an extensive description without going outside your code editor. But this feature comes not out of the box when creating your custom commands. So how can we utilize the same feature Cypress is using, this can be achieved by creating our Type Definition file and extending the default Cypress types.

### Setup
So to start we need a jsconfig.json in the root folder or a tsconfig.json file in our cypress folder. I will use a tsconfig file for this example but I will give you also a jsconfig example file.

#### **`./jsconfig.json`**
```json
{
  "include": ["./node_modules/cypress", "cypress/**/*.js","./types/*.d.ts"]
}

```
#### **`./cypress/tsconfig.json`**
```json
{
  "compilerOptions": {
    "allowJs": true,
    "baseUrl": "../node_modules",
    "types": [
      "cypress"
    ],
    "noEmit": true
  },
  "include": [
    "**/*.*"
  ]
}
```
This will enable basic intellisense in all our files and the option to extend it with our own commands.
Now lets create a custom command called devSpecialCommand and place it in our commands file.

#### **`./cypress/support/commands.js`**
```js
Cypress.Commands.add('devSpecialCommand', (text, number) => { 
    cy.log(`This is our special command lets printout the text ${text} and the number ${number}`)
})
```
To add Intellisense and documentation we need to create a Type definition file. To keep it simple I will create a types folder inside our cypress project and call the file types.d.ts. Now lets add our the following code to this file so that we can start documenting our command.

#### **`./cypress/types/types.d.ts`**
```js
declare namespace Cypress {
  interface Chainable<Subject> {
    devSpecialCommand(text: String, number: Number): Chainable<any>;
  }
}

```
We extended the Cypress namespace and added our custom command to the list of options. When you press `cy.d` in one of your testfiles it will give you the option `cy.devSpecialCommand`


![cypress intellisense](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ifq8mhvfz5lhumg7blx.png)


![cypress completion](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4fj1rofbh0kt6choy1xs.png)

This still looks plain since we do have IntelliSense but we still have no idea what this plugin does. To add a better description we are going to utilize the [jsdoc](https://jsdoc.app/) in our Types file to describe what the feature is for.

Lets go back to our types file and add some description.
```js
    /**
     * @description This is a demo command for the dev.to blog
     * @param {string} text - Enter a random text
     * @param {number} number - Enter a number
     */
    devSpecialCommand(text: String, number: Number): Chainable<any>;
```
When we hover over our command implementation we now get a detailed view of what our command does and what the input fields are.

![full description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gi58imaf5o6dzv1mskso.png)

Now you have a way to document your command and make it readable for all users what the command is supposed to do. If you want to know more about documentation I suggest reading the jsdoc page of all possible annotations.

If after reading you have difficulties getting it to work you can also clone my demo repository [cypress custom commands](https://github.com/Xvier/cypress-dev-custom-commands)

## Easy way - VSCode plugin

When using VSCode there is an easy way of creating documentation or having IntelliSense to your Cypress project. So no more doing stuff by hand let us use a plugin to fix all the manual stuff. 

First of you need the plugin [Cypress Helper](https://marketplace.visualstudio.com/items?itemName=Shelex.vscode-cy-helper)

![cypres-helper plugin](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v04rui1xd5g6mvxjdqgn.png)

This plugin will do all the manual work for you and gives you a few features extra like:

- Creates the Type Definition file with the custom command name.
- If no jsconfig/tsconfig file is present then it creates a tsconfig.json file.
- Gives you the option to go to the custom command with a shortcut.
- Find unused custom commands.

With the plugin installed right-click in your custom commands file and select Cypress: Generate Custom Commands Types. This will generate a customCommand.d.ts file with your custom commands. 


![cypress plugin](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/867ttf9v023g4p5oqrd5.png)

A tip look in your notification tab of VSCode sometimes you won't get a popup to create a tsconfig file but if you click on the notification icon you will see the option. Now you can add documentation in the same way as the manual way. 
Thank you all for reading and if you want to watch the meetup recording you can do so below.

## Meetup Video - Skip to 23:05 for the demo

{% youtube vhdv2HOwOck %}