DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • Modern Test Automation With AI (LLM) and Playwright MCP
  • AI-Driven Test Automation Techniques for Multimodal Systems
  • Debugging With Confidence in the Age of Observability-First Systems
  • Overcoming MFA Test Automation Challenges

Trending

  • Prioritizing Cloud Security Risks: A Developer's Guide to Tackling Security Debt
  • Advancing Robot Vision and Control
  • AI-Driven Root Cause Analysis in SRE: Enhancing Incident Resolution
  • How to Use AWS Aurora Database for a Retail Point of Sale (POS) Transaction System
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Testing, Tools, and Frameworks
  4. How To Share Variables Between Tests in Cypress

How To Share Variables Between Tests in Cypress

Cypress is a useful tool for creating automated tests for your web application. In this article, learn how Cypress shares variables between tests.

By 
Hamid Akhtar user avatar
Hamid Akhtar
·
Apr. 26, 24 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
1.8K Views

Join the DZone community and get the full member experience.

Join For Free

Best Practices for Sharing Variables in Cypress Tests

Cypress issues a command in a series. Each link in the chain is connected to the one before it as well as the one after. Cypress will automatically wait for the previous command to finish, ensuring that you don’t encounter race situations. I’ll use one as an example:

JavaScript
 
cy
.get('li')
.should('have.length', 5) // ensure the previous command retrieves elements
.eq(4) // ensure the previous assertion is successful
.click() // ensure the previous command is complete


Again, no command will be executed until the previous one has ended. The test fails (often in 4 seconds) if any of the commands are not completed in a timely manner.

Let’s take a second to consider the scenario from a different angle.

JavaScript
 
it('assigns value to variable', () => {
// Executed instantly, outside of chain
console.log('>>> log one') let boardId 
cy.request('/api/boards')
.then( response => { console.log('>>> log two') boardId = response.body[0].id
})

// Executed instantly, outside of chain
console.log('>>> log three')
 cy.visit('/board/' + boardId)
})


We hope this helps to clarify how console.log() functions work. The id variable, however, is another story. The use of it within the chain appears to be the case. Or is it?

Actually, no. Since it is passed as an argument, it is theoretically passed “from outside” and not in the command chain. This variable was set out at the start of the test. In our test, we are instructing Cypress to run the command.visit() with whatever the value of ‘/board/’ + id is.

Think about the “inside chain vs. outside chain” theory. Let’s review the code once more:

JavaScript
 
it('captures value in variable', () => {
// Instant variable declaration, no wait
let identifier cy.request('/api/boards')
.then( response => {
identifier = response.body[0].id
})

// Instant variable usage, no wait
cy.visit('/board/' + identifier)
})


Now that the issue is more evident, let’s examine the many ways we might pass values in our test. Let’s have a look at at least a few of the many solutions that exist for this.

Step up the Desired Code in the Command Chain

Making ensuring that everything in our command chain is included is the simplest solution. The .visit() function must be used inside the command chain in order to use the updated value. The id will be passed with a new value in this manner. This technique works well when you want to quickly pass a single variable because using multiple .then() functions may result in a “pyramid of doom.”

JavaScript
 
it('holds value in variable', () => {
let boardId // initialize variable
 cy.request('/api/boards')
.then( response => {
boardId = response.body[0].id // set value
cy.visit('/board/' + boardId) // use the newly set value
})

})


Separate Logic Into Several Tests

You can divide the logic into different tests and use a “setup” it() function to assign your variables before executing it() block to use that variable because Cypress executes it() blocks one at a time. This method may be fairly constrained, though, since each variable update requires a separate block. Not every it() function is now a test, so it’s not the ideal test design either. This may also result in a strange domino effect, when the failure of one test may be a result of the failure of another test.

Using Hooks

Using before() or beforeEach() hooks is a marginally better method of dividing a test. You are more logically dividing your test this way. You have two phases: the preparation process, which is separate from the test, and the execution phase, which is the test itself. This method also has the benefit of giving you explicit information in the error log when a hook fails.

Using Aliases and Hooks

Aliases are actually a part of the Cypress-bundled Mocha framework, which is used to run tests. Anytime you use the.as() command, an alias will be created in the Mocha context and may be accessed by using this keyword, as demonstrated in the example. It will be a shared variable, allowing you to share variables between tests in the specification. This keyword, however, must be used with the traditional function expression, function(){}, and cannot be used in functions using the arrow expression () =>{}. Take a look at this example.

JavaScript
 
beforeEach( function() {
cy.request('/api/boards')
.as('boardData')
})

// using it('utilize variable', () => { ... would not work
 it('utilize variable', function() {
cy.visit('/board/' + this.boardData.body[0].id) })


Using cy.task()

A Node.js server process is active in the background behind Cypress. Node can be used, and temporary data can be kept there. If you want, you can even seed a test database! Values from the last run are still present here as long as you don’t close the Cypress console.

Why do you do this? You can give a value to Node.js by using the command cy.task(). A “get” and “set” command must be written. This will be a piece of cake if you are comfortable with getters and setters like you are in Java.

assignUserId: (value) => { return (userIdentifier = value); }
 retrieveUserId: () => { return userIdentifier; }
 cy.get('User').then(($userIdentifier) => {
cy.task('assignUserId', $userIdentifier);
});
 cy.task('retrieveUserId').then((userIdentifier) => {
cy.get('User').type(userIdentifier);
});


Using Cypress – Fixtures

Cypress fixtures are used to maintain and save the test data for automation. The fixtures folder contains the fixtures for the Cypress project (example.json file). Basically, it makes it easier to import data from external files.

JavaScript
 
describe('Testing on Browserstack', function () {
//part of before hook
before(function(){
//retrieve fixture data
cy.fixture('sample').then(function(userData){
this.userData = userData
})
})
// test case
it('Test Scenario 1', function (){
// navigate to URL
cy.visit("https://signup.example.com/register/register.php")
//data utilized from fixture
cy.get(':nth-child(3) > [width="185"] > input')
.type(this.userData.userName)
cy.get('#mobno').type(this.userData.phoneNumber)
});
});


Code reuse is ensured by Cypress, which enables the same test script to be executed against several fixtures files.

Sharing Variables Between Test Files Using Environment Variables

We can create environment variables that the test automation framework can use globally and that all test cases can access. In our project’s cypress.json file, we can store this kind of customized environment variable.

We must specify the key as “env” in the cypress.json file and then set the value because a customized variable is not exposed by default Cypress configurations.

In the real test, we must also use Cypress.env and pass the value declared in the json file in order to access this variable.

JavaScript
 
describe('ExampleSite Test', function () {
// test case
it('Scenario A', function (){
// navigate to application using environment variable
cy.visit(Cypress.env('siteUrl'))
cy.getCookies()
cy.setCookie('cookieName', 'cookieValue')
});
});


We now know that Cypress is a test automation framework, and much like other test automation frameworks, it must run the same set of tests in a variety of test environments, including DEV, QA, UAT, and others. However, some values or variables, such as the application URL or credentials, could have different values in various test environments. Cypress offers methods for test scripts to access environment variables in order to deal with such circumstances. Environment variables are what Cypress considers to be all the variables within the “env” tag in the config.json file. Below is an example of its syntax:

JavaScript
 
{
"env": {
"api_key": "api_value"
}
}

// Retrieve all the environment variables
Cypress.env()

// Retrieve a specific environment variable using its key
Cypress.env('api_key')


Next, let’s consider a different instance.

JavaScript
 
{
"env": {
"Param1": "Data1",
"Param2": "Data2"
}
}

Cypress.env(); // {Param1: "Data1", Param2: "Data2"}

Cypress.env("Param1"); // It will return "Data1"


The “Cypress.env()” method in Cypress can be used to obtain environment variables.

Cypress Wrap

When utilizing cypress commands like should, type, or click on an object or jquery element, you may first want to wrap it in order to yield the objects that were placed in it and yield its resolved value.

JavaScript
 
cy.wrap(entity)
cy.wrap(entity, configurations)
 cy.wrap({Character: 'John'})

const Champion = () => {
return 'John'
}
 cy.wrap({ name: Champion }).invoke('name').should('eq', 'John')


  • Hero is a JavaScript object, and Cypress cannot be used to interact with it.
  • We use the key name passed with the object Hero in the wrap to assert that it should be equal to Naruto, and it returns true. We then utilize the wrap to convert the object Hero into Cypress.
JavaScript
 
describe('Utilizing Wrap Command', () => {
 it("Wrapping Various Data Types", () => {
// Variable
let colorStatement = 'Red Or Blue'
cy.wrap(colorStatement).should('eq', 'Red Or Blue')

// Object
let Character = {name: 'Itachi'}
cy.wrap(Character).should('have.property', 'name', 'Itachi')

// Array
let Characters = ['Itachi', 'Sasuke', 'Naruto', 'Sakura']
cy.wrap(Characters).should('include', 'Sakura')
}) })


Test automation Testing

Published at DZone with permission of Hamid Akhtar. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Modern Test Automation With AI (LLM) and Playwright MCP
  • AI-Driven Test Automation Techniques for Multimodal Systems
  • Debugging With Confidence in the Age of Observability-First Systems
  • Overcoming MFA Test Automation Challenges

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!