Custom commands help you reuse test steps easily. Using TypeScript makes sure your commands are checked for mistakes before running tests.
TypeScript support for custom commands in Cypress
declare namespace Cypress {
interface Chainable {
customCommand(param: string): Chainable<Element>;
}
}
Cypress.Commands.add('customCommand', (param) => {
// command implementation
});Use declare namespace Cypress to add types for your commands.
Define your command inside interface Chainable with input and output types.
login command with typed email and password parameters.declare namespace Cypress {
interface Chainable {
login(email: string, password: string): Chainable<Element>;
}
}
Cypress.Commands.add('login', (email, password) => {
cy.get('#email').type(email);
cy.get('#password').type(password);
cy.get('button[type=submit]').click();
});selectItem command to click an item by name.declare namespace Cypress {
interface Chainable {
selectItem(itemName: string): Chainable<Element>;
}
}
Cypress.Commands.add('selectItem', (itemName) => {
cy.contains(itemName).click();
});This test adds a greet command that logs a greeting message. The test calls cy.greet('Alice') and you will see the greeting in the test log.
/// <reference types="cypress" /> declare namespace Cypress { interface Chainable { greet(name: string): Chainable<Element>; } } Cypress.Commands.add('greet', (name) => { cy.log(`Hello, ${name}!`); }); describe('Custom Command Test', () => { it('uses the greet command', () => { cy.greet('Alice'); }); });
Always add /// <reference types="cypress" /> at the top for TypeScript support.
Put your type declarations in a cypress/support/index.d.ts or similar file.
Use Chainable<Element> as the return type for commands that continue Cypress chaining.
Custom commands let you reuse test steps easily.
TypeScript support helps catch errors early and improves editor help.
Declare your commands in the Cypress.Chainable interface for typing.
Practice
Solution
Step 1: Understand TypeScript role in Cypress
TypeScript adds static type checking and editor support to catch errors early.Step 2: Identify benefit for custom commands
Typing custom commands improves autocomplete and prevents mistakes when using them.Final Answer:
It provides type checking and better editor autocomplete for custom commands. -> Option BQuick Check:
TypeScript support = type checking + autocomplete [OK]
- Confusing TypeScript support with test speed improvements
- Thinking it auto-generates reports
- Believing it enables multi-browser runs
Solution
Step 1: Recall TypeScript declaration syntax for Cypress commands
Custom commands are declared inside the Cypress namespace extending Chainable interface.Step 2: Match correct syntax
declare namespace Cypress { interface Chainable { myCommand(): Chainable<void> } } correctly uses 'declare namespace Cypress' and extends 'Chainable' with 'myCommand'.Final Answer:
declare namespace Cypress { interface Chainable { myCommand(): Chainable<void> } } -> Option DQuick Check:
Namespace + Chainable interface = correct declaration [OK]
- Missing 'declare' keyword
- Incorrect interface or namespace nesting
- Placing method outside Chainable interface
declare namespace Cypress {
interface Chainable {
login(email: string, password: string): Chainable<void>
}
}What is the correct way to use this
login command in a test?Solution
Step 1: Understand method signature
The login command takes two string arguments: email and password.Step 2: Match correct usage syntax
cy.login('user@example.com', 'pass123') calls login with two string arguments in order, matching the declaration.Final Answer:
cy.login('user@example.com', 'pass123') -> Option CQuick Check:
Method call with two string args = correct usage [OK]
- Using named parameters syntax (not valid in JS calls)
- Passing arguments as array instead of separate params
- Calling without required arguments
declare namespace Cypress {
interface Chainable {
clickButton(): void
}
}But when you use
cy.clickButton() in your test, TypeScript shows an error. What is the problem?Solution
Step 1: Check return type for custom commands
Custom commands should return Chainable<T> to allow chaining in Cypress.Step 2: Identify mismatch causing TypeScript error
Returning void breaks chaining and causes TypeScript to complain.Final Answer:
The return type should be Chainable<void>, not void. -> Option AQuick Check:
Custom commands must return Chainable for chaining [OK]
- Using void return type instead of Chainable
- Declaring commands outside Cypress namespace
- Assuming method names are restricted
fillForm that accepts an object with optional name and email fields. How should you declare it in TypeScript to support chaining and optional properties?Solution
Step 1: Define optional properties correctly
Use question marks (?) to mark properties as optional in the data object.Step 2: Ensure return type supports chaining
Return type must be Chainable<void> to allow chaining in Cypress tests.Final Answer:
declare namespace Cypress { interface Chainable { fillForm(data: { name?: string; email?: string }): Chainable<void> } } -> Option AQuick Check:
Optional props + Chainable return = correct declaration [OK]
- Forgetting '?' for optional properties
- Using void return type instead of Chainable
- Returning wrong Chainable generic type
Ready to prove it?
Pass the test and this pattern moves unknown
