Using Cy.wrap in Cypress
By Gurudatt S A, Community Contributor - September 17, 2024
This guide explains how to use cy.wrap in the Cypress framework. It is a powerful command that allows you to work with non-Cypress promises and objects. Understanding cy.wrap can help simplify your test automation scripts and handle asynchronous operations more effectively, improving the flow and reliability of your tests.
What is cy.wrap() in Cypress?
The Cypress wrap command allows you to use Cypress native chaining commands for values that are not returned/part of Cypress commands.
Syntax:
The syntax for using the Cypress cy.wrap() function is given below.
cy.wrap(<function/object/array>, <options>)
For example, consider making an API request that returns the following response object: { name: ‘Stephen’, age: 30 }.
const userDetails = { name: 'Stephen', age: 30 } cy.wrap(userDetails).should('have.property', 'name', 'Stephen')
In this example, the userDetails object is wrapped using cy.wrap(). Once wrapped, you can chain it with Cypress commands to assert or interact with the object, as shown in the code.
Read More: Cypress vs Selenium
When should you use cy.wrap() in Cypress?
You should use cy.wrap() in Cypress in the following scenarios:
- Handling Non-Cypress Values: When you need to work with values or objects that aren’t inherently managed by Cypress, but you still want to apply Cypress commands or assertions to them. By wrapping the value, you can integrate it into the Cypress command chain.
Example: Wrapping a jQuery object or a DOM element retrieved through custom logic. - Waiting for Non-Cypress Functions: If you need to execute a function or promise that isn’t native to Cypress (such as custom JavaScript functions or third-party promises), you can use cy.wrap() to ensure Cypress waits for its completion before continuing the test.
Example: Wrapping a custom promise or async function ensures Cypress properly waits for its resolution.
This ensures better synchronization between your code and Cypress commands.
Read More: What is new in Cypress 10
How to use cy. wrap() in Cypress?
Using BrowserStack’s Demo application to write the Cypress test, which demonstrates the use of cy.wrap().
Consider an example where you must click on the vendors and validate the number of products found.
Below will be our Cypress code using wrap().
it("cypress wrap example", () => { cy.visit("https://www.bstackdemo.com/") cy.get(".products-found").invoke("text").as("productsFound") cy.contains(".checkmark", "Apple").then(($checkmark) => { cy.wrap($checkmark).click() cy.get("@productsFound").should("eq", "9 Product(s) found.") cy.wrap($checkmark).click() cy.get("@productsFound").should("eq", "25 Product(s) found.") }) })
Code walkthrough:
1. Visit the BrowserStack’s demo application.
cy.visit("https://www.bstackdemo.com/")
2. Find the element that holds the number of products found text and assign that to an alias for later usage.
cy.get(".products-found").invoke("text").as("productsFound")
3. Find the element for a specific vendor and pass that jQuery element to then function for wrapping the jQuery element to perform Cypress’s native chaining commands.
cy.contains(".checkmark", "Apple").then(($checkmark) => { cy.wrap($checkmark).click() cy.get("@productsFound").should("eq", "9 Product(s) found.") cy.wrap($checkmark).click() cy.get("@productsFound").should("eq", "25 Product(s) found.") })
First click on the Vendor (Example: Apple) checkmark and then validate the right number of products found. Also, ensure when the checkmark is not enabled, the application shows the products for all the vendors.
Read More: How to handle click events in Cypress
Advanced Usage Scenarios
In this section, you will see how the Cypress wrap() can be used for scenarios where you want to assert response data and pass a function that returns values to the wrap().
If you access BrowserStack’s demo application with developer tools open, you can see the product API request, which fetches the phone models.
Write the Cypress test to intercept this Product API request and fetch the response. Once the response is fetched, verify using wrap () if it contains a specific phone title.
it("cypress wrap advanced example", () => { 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") }) })
Code walkthrough:
Start listening to the network connection using the below intercept code.
cy.intercept("api/products").as("productList")
Visit the BrowserStack demo application with the code below.
cy.visit("https://www.bstackdemo.com/")
In the code below, you wait for the Product API call to complete and then fetch its response. Notice how cy.wrap() is used to wrap the response body, allowing you to access and assert its properties using Cypress’s native functions:
cy.wait("@productList").then((responseData) => { cy.wrap(responseData.response.body).its("products").its(0) .should("have.property", "title", "iPhone 12") })
By wrapping the response body, you can easily chain Cypress commands to verify properties or perform further actions on the response data.
Example for using wrap with asynchronous function which returns promise
Consider an example where you have a function that performs the fetch API call and returns the promise with response JSON. The function is asynchronous, and it’s not part of the Cypress native command.
Hence, if you call this function along with Cypress commands, Cypress will not wait until the response is received. To solve this, you can wrap the function using cy.wrap(), as in the example below.
function fetchDataFromApi() { return fetch('https://www.bstackdemo.com/api/products') .then((response) => response.json()); } it("Wrapping function", () => { cy.wrap(fetchDataFromApi()).its("products").then((data) => { cy.wrap(data).its(0).should("have.property","title", "iPhone 12") }); })
How to run Cypress Dropdown Tests on Real Devices using BrowserStack?
To run the Cypress test in BrowserStack Cloud, follow the below steps:
1. Create a folder in your machine, Example, cypress-wrap-example
2. Open the terminal and access the newly created folder
3. Execute npm init and complete the installation
4. Install Cypress by executing the below command in the terminal
npm install cypress --save-dev
5. To create a folder structure of cypress, execute the below command in the terminal
npx cypress open
6. Follow the instructions to create examples
7. Inside the Cypress > e2e folder, create a new file named cypress-wrap.cy.js
8. Paste the below test code and save the file.
it("cypress wrap example", () => { cy.visit("https://www.bstackdemo.com/") cy.get(".products-found").invoke("text").as("productsFound") cy.contains(".checkmark", "Apple").then(($checkmark) => { cy.wrap($checkmark).click() cy.get("@productsFound").should("eq", "9 Product(s) found.") cy.wrap($checkmark).click() cy.get("@productsFound").should("eq", "25 Product(s) found.") }) }) it("cypress wrap advanced example", () => { cy.intercept("api/products").as("productList") cy.visit("https://www.bstackdemo.com/") cy.wait("@productList").then((responseData) => { cy.log(responseData.response.body) cy.wrap(responseData.response.body).its("products").its(0) .should("have.property", "title", "iPhone 12") }) }) function fetchDataFromApi() { return fetch('https://www.bstackdemo.com/api/products') .then((response) => response.json()); } it("Wrapping function", () => { cy.wrap(fetchDataFromApi()).its("products").then((data) => { cy.wrap(data).its(0).should("have.property","title", "iPhone 12") }); })
9. Install the BrowserStack Cypress CLI by running the below command in the terminal.
npm install -g browserstack-cypress-cli
10. From the root of the repository, execute the below command to create the BrowserStack configuration file
browserstack-cypress init
11. Open the browserstack.json file and update the username and accesskey (This will be available on the BrowserStackAutomate Website for your account)
12. Run the below command in the terminal from the root of your repository to execute the cypress tests in BrowserStack Cloud
browserstack-cypress run --sync
Why use BrowserStack Automate for Cypress Tests?
Here’s why you should run your Cypress tests on Real Devices & Browsers using BrowserStack Automate:
- Diverse Environment Testing: It enables the execution of Cypress tests across a broad selection of browsers and operating systems, eliminating the necessity for maintaining local testing infrastructure. This ensures consistent application performance across various platforms.
Read More: Cross-browser testing with Cypress
- Parallel Testing: BrowserStack Automate significantly reduces total testing time by allowing simultaneous execution of multiple Cypress test suites, facilitating quicker iterative feedback and accelerated deployment cycles.
Read More: Run Cypress tests in parallel
- CI/CD Integration: The platform seamlessly integrates with major CI/CD systems, including Jenkins, Travis CI, CircleCI, and GitHub Actions, automating the testing process within the development pipeline.
- Diagnostic Tools for Better Debugging: BrowserStack provides comprehensive diagnostic capabilities, including detailed logs, screenshots, and video recordings of test sessions, aiding in the swift identification and resolution of issues.
- Testing on Real Devices: Beyond simulated environments, BrowserStack also supports testing on real devices and browsers on the cloud, offering more precise and real-world test outcomes.
- Customizable Test Execution: Users can tailor test executions to meet specific needs through BrowserStack’s user interface or APIs, enabling adaptable and controlled test runs.
cy.wrap is a versatile and essential command in Cypress that allows you to effectively handle non-Cypress objects, functions, and promises. By wrapping objects or responses, you can seamlessly integrate Cypress’s native assertions and commands into your test scripts, enhancing both flexibility and readability.
Whether dealing with API responses, asynchronous operations, or external functions, mastering cy.wrap can significantly improve your test automation workflow and ensure more reliable results in your testing process.
BrowserStack Automate is an excellent choice for running Cypress tests because it offers a scalable, cloud-based infrastructure that eliminates the need for complex local setups. With support for real-time cross-browser testing, parallel execution, and integrations with CI/CD pipelines, BrowserStack ensures faster test runs and streamlined workflows. Choose BrowserStack Automate to enhance the reliability and performance of your Cypress test suite with ease.