Cypress’s cy.wrap()
command is a powerful tool for integrating non-Cypress values into your test command chain.
Understanding cy.wrap()
The cy.wrap()
command yields the object passed into it. If the object is a promise, it yields the resolved value.
Syntax
cy.wrap(subject)
cy.wrap(subject, options)
Arguments
- subject: The object to be yielded
- options:
log
(Boolean): Display command in Command log (default: true)timeout
(Number): Time to wait before timing out (default: defaultCommandTimeout)
Key Use Cases
1. Working with Objects
const getName = () => {
return 'Jane Lane'
}
cy.wrap({ name: getName }).invoke('name').should('eq', 'Jane Lane')
2. Handling DOM Elements
Basic Element Wrapping
cy.get('form').within(($form) => {
cy.wrap($form).should('have.class', 'form-container')
})
Conditional Wrapping
cy.get('button').then(($button) => {
if ($button.someMethod() === 'something') {
cy.wrap($button).click()
}
})
3. Managing Promises
Simple Promise Example
const myPromise = new Promise((resolve) => {
setTimeout(() => {
resolve({
type: 'success',
message: 'It worked!'
})
}, 2500)
})
it('should wait for promises', () => {
cy.wrap(myPromise).its('message').should('eq', 'It worked!')
})
Real-world Authentication Example
import { userService } from '../../src/_services/user.service'
it('authenticates with wrapped promise', () => {
const username = Cypress.env('username')
const password = Cypress.env('password')
cy.wrap(userService.login(username, password))
.should('be.an', 'object')
.and('have.keys', ['firstName', 'lastName', 'username', 'id', 'token'])
cy.visit('/')
cy.contains('Hi Test!').should('be.visible')
})
Advanced Patterns
1. Working with API Responses
Direct Function Wrap
function fetchDataFromApi() {
return fetch('https://www.bstackdemo.com/api/products')
.then((response) => response.json())
}
it("Wraps API function", () => {
cy.wrap(fetchDataFromApi()).its("products").then((data) => {
cy.wrap(data).its(0).should("have.property", "title", "iPhone 12")
})
})
Intercept and Wrap
it("Advanced API wrapping", () => {
cy.intercept("api/products").as("productList")
cy.visit("https://www.bstackdemo.com/")
cy.wait("@productList").then((responseData) => {
cy.wrap(responseData.response.body)
.its("products")
.its(0)
.should("have.property", "title", "iPhone 12")
})
})
2. Proper Async Handling
Important Note: cy.wrap()
doesn’t synchronize async function calls automatically. For proper sequencing:
// ❌ Problematic approach
cy.wrap(foo()) // Executes immediately
cy.get('button').click()
cy.wrap(bar()) // Might execute before click completes
// ✅ Correct approach
cy.wrap(foo())
cy.get('button')
.click()
.then(() => {
cy.wrap(bar()) // Executes after click completes
})
When to Use cy.wrap()
- To integrate jQuery elements or custom DOM queries into Cypress chains
- When working with promises from application code
- To assert against complex objects while maintaining command chaining
- When you need to conditionally execute Cypress commands on non-Cypress objects
Best Practices
- Always wrap promises returned by application code
- Use
.then()
for proper command sequencing - Combine with
.its()
for clean property assertions - Leverage aliases (
as()
) for complex objects you’ll reuse
Leave a Reply