Cypress.io API Automation Tips & Tricks
Pushkar Deshpande
10 YOE - UI + API + Mobile + PWA + Component + Performance Automation | Cypress.io | Playwright | WebdriverIO | Appium | Nightwatch | Postman | K6 | JS & TS | Cucumber | BDD | CI-CD | AWS | Docker | K8s | SAAS | OTT
/* Examples for method, url, headers, body to use in reusable custom commands as a parameters*/
method : 'GET/POST/DELETE/PUT', /* Anyone method should be used */
url : 'https://localhost:8080/api/v1',
headers : {
Authorization : 'Bearer API_KEY',
'Content-Type' : 'application/json'
},
body : {
name : 'abc',
email : 'abc@gmail.com'
}
/* Custom Reusable Command for POST & PUT Request Methods */
Cypress.Commands.add("apiRequestWithBody", (method, url, headers, body) => {
cy.request({
method,
url,
headers,
body,
failOnStatusCode: false
})
})
/* Custom Reusable Command for GET & DELETE Request Methods */
Cypress.Commands.add("apiRequestWithoutBody", (method, url, headers) => {
cy.request({
method,
url,
headers,
failOnStatusCode: false
})
})
/* API Validations Assertions for Status Code for POST & PUT Request */
POST & PUT Request
cy.apiRequestWithBody('POST', url, headers, body).then((response) => {
expect(response.status).to.equal(201)
})
cy.apiRequestWithBody('PUT', url, headers, body).then((response) => {
expect(response.status).to.eq(201)
})
/* API Validations Assertions for Status Code for GET & DELETE Request */
GET & DELETE Request
cy.apiRequestWithoutBody('GET', url, headers).then((response) => {
expect(response.status).to.eq(200)
})
cy.apiRequestWithoutBody('DELETE', url, headers, body).then((response) => {
expect(response.status).to.eq(204)
})
/* API Validations Assertions for Response Time less than 5 seconds for POST & PUT Request */
cy.apiRequestWithBody('POST', url, headers, body).then((response) => {
expect(response.duration).to.be.lessThan(5000)
})
cy.apiRequestWithBody('PUT', url, headers, body).then((response) => {
expect(response.duration).to.be.lessThan(5000)
})
/* API Validations Assertions for Response Time less than 5 seconds for GET & DELETE Request */
cy.apiRequestWithoutBody('GET', url, headers).then((response) => {
expect(response.duration).to.be.lessThan(5000)
})
cy.apiRequestWithoutBody('DELETE', url, headers).then((response) => {
expect(response.duration).to.be.lessThan(5000)
})
/* API Validations Assertions for Content Header should be application/json POST & PUT Request */
cy.apiRequestWithBody('POST', url, headers, body).then((response) => {
expect(response.headers['content-type']).to.include('application/json')
})
cy.apiRequestWithBody('PUT', url, headers, body).then((response) => {
expect(response.headers['content-type']).to.include('application/json')
})
/* API Validations Assertions for Content Header should be application/json GET & DELETE Request */
cy.apiRequestWithoutBody('GET', url, headers).then((response) => {
expect(response.headers['content-type']).to.include('application/json')
})
cy.apiRequestWithoutBody('DELETE', url, headers).then((response) => {
expect(response.headers['content-type']).to.include('application/json')
})
/* API Schema Validations */
Add in e2e.js or e2e.ts
import chaiJsonSchema from 'chai-json-schema'
chai.use(chaiJsonSchema)
install node package of "chai-json-schema"
const jsonSchema = {
type: 'object',
properties: {
accessToken: { type: 'string' },
refreshToken: { type: 'string' },
},
required: ['accessToken', 'refreshToken'],
}
cy.apiRequestWithBody('POST', url, body).then((response) => {
expect(response.body).to.be.jsonSchema(jsonSchema)
})
领英推è
/* To Test GET Request */
cy.request(“https://localhost:8080/api/posts/1â€).then((response) => {
expect(response.body).to.have.property('code', 200)
})
/* To Test POST Request */
cy.request({
method: 'POST',
url: 'https://localhost:3000/api/posts',
body: {
id : 2,
title : 'api'
}
}).then((response) => {
expect(response.body).has.property('title','api')
})
/* To Test PUT Request */
cy.request({
method: ‘PUT’,
url: ‘https://localhost:3000/api/posts/2’,
body: {
id : 2,
title : 'Test API'
}
}).then((response) => {
expect(response.body).has.property('title','Test API')
})
/* To Test DELETE Request */
cy.request({
method : 'DELETE',
url: 'https://localhost:3000/api/post/2'
}).then((response) => {
expect(response).to.be.empty;
})
/* To Update Existing Created Record by PUT Request */
const userId = 456
const updateData = {
id: userId,
name: 'abc',
email: 'test@gmail.com',
}
cy.request({
method: 'PUT',
url: `https://localhost:8080/api/v1/users/${userId}`,
body: updateData,
failOnStatusCode: false
}).then((response) => {
expect(response.status).to.eq(201)
})
/* To Spy & Stub Network Requests & Responses by intercept cypress command */
cy.intercept({
method : 'POST',
url : 'https://localhost:8080/login'
}).as('LoginURL')
cy.wait('@LoginURL')
/* To Create a Fixture data file & load it in test by cy.intercept */
users.json
[
{
"id": 1,
"name": "abc",
"email": "pqr@gmail.com"
}
]
cy.fixture('users').then((users) => {
cy.intercept('GET', '/api/users', users).as('getUsers');
});
cy.visit('/users');
cy.wait('@getUsers');
cy.get('.user-list').should('contain', 'abc');
/* To make POST Request directly via API & verify all data */
cy.request({
method: 'POST',
url: 'https://localhost:8080/api/v1/data',
body: {
name: 'test_1',
email: 'test@gmail.com',
designation: 'qa_engineer',
role: 'provide_quality'
}
}).as('data_creation')
/* To Verify the response of the POST request */
cy.get('@data_creation').then((response) => {
expect(response.status).to.eq(201)
expect(response.body).to.have.property('id')
expect(response.body).to.have.property('name', 'test_1')
expect(response.body).to.have.property('email', 'test@gmail.com')
expect(response.body).to.have.property('designation', 'qa_engineer')
expect(response.body).to.have.property('role', 'provide_quality')
})
/* To Verify the created data via a GET request */
cy.get('@data_creation').then((response) => {
const id = response.body.id
cy.request({
method: 'GET',
url: `https://localhost:8080/api/v1/data/${id}`
}).as('getData')
cy.get('@getData').then((getResponse) => {
expect(getResponse.status).to.eq(200)
expect(getResponse.body).to.have.property('id', id);
expect(getResponse.body).to.have.property('name', 'test_1')
expect(getResponse.body).to.have.property('email', 'test@gmail.com')
expect(getResponse.body).to.have.property('designation', 'qa_engineer')
expect(getResponse.body).to.have.property('role', 'provide_quality')
})
})
/* To create test data using a POST request method & verify all response validations */
cy.intercept('POST', 'https://localhost:8080/api/v1/data', (req) => {
}).as('data_creation');
/* Fill up the Form */
cy.get('input[name="name"]').type('test_1')
cy.get('input[name="email"]').type('test@gmail.com')
cy.get('input[name="designation"]').type('qa_engineer')
cy.get('input[name="role"]').type('provide_quality')
cy.get('form').submit()
/* Verify Request Payload */
cy.wait('@data_creation').its('request.body').should((body) => {
expect(body).to.have.property('name', 'test_1')
expect(body).to.have.property('email', 'test@gmail.com')
expect(body).to.have.property('designation', 'qa_engineer')
expect(body).to.have.property('role', 'provide_quality')
})
/* Verify Response */
cy.wait('@data_creation').then((response_data) => {
const responseBody = response_data.response.body
expect(response_data.response.status).to.eq(201)
expect(responseBody).to.have.property('id')
expect(responseBody).to.have.property('name', 'test_1')
expect(responseBody).to.have.property('email', 'test@gmail.com')
expect(responseBody).to.have.property('designation', 'qa_engineer')
expect(responseBody).to.have.property('role', 'provide_quality')
})
Staff QA Engineer/SDET @ KUBRA || Engineer in Computer Science || Cypress and Playwright Independent Contributor || Blogger || Accessibility — Creator of: WICK-A11Y, CYPRESS-AJV-SCHEMA-VALIDATOR, and PW-API-PLUGIN
7 个月Nice article Pushkar Deshpande! It covers a subject commonly forgotten, JSON schema validation. Have you checked out this other plugin for advance JSON schema validations in Cypress? https://dev.to/sebastianclavijo/cypress-ajv-schema-validator-plugin-the-brave-vigilante-for-your-api-contracts-5cfe
â””? ? Microsoft? Most Valuable Professional (MVP) ? Linkedin Top Quality Assurance Voice ? DZone Core Member ? Applitools Ambassador | Read My Blog at qaautomationlabs.com | AWS,PMI-ACP?,ITIL? PRINCE2 Practitioner?
8 个月Nice one
Strategic Transformation Executive | Founder @ HOBOSX & Military Allies – Empowering Business & Nonprofit Support for Military & Veteran Communities | Certified AI Transformation Leader
8 个月Unleash your testing potential with Cypress API tips & tricks! ???? #Testing #Automation
Startups Need Rapid Growth, Not Just Digital Impressions. We Help Create Omni-Channel Digital Strategies for Real Business Growth.
8 个月Excited to dive into these Cypress API automation tips! Streamlining our testing processes with advanced techniques like those Cypress offers is crucial for enhancing software quality and efficiency. Thanks for sharing these insights it's always great to stay ahead in the automation game!