Advanced Tips & Tricks of Cypress.io
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
/* Verify same text in column */
cy.get('[data-cy=*]').each($el => {
expect($el.text()).to.eq('Test, Inc.')
})
/* Persisting, Restoring & Clearing Local Storage */
const LOCAL_STORAGE_MEMORY = {}
const persistLocalStorage = () => {
Object.keys(localStorage).forEach(key => {
LOCAL_STORAGE_MEMORY[key] = localStorage[key]
})
}
const restoreLocalStorage = () => {
Object.keys(LOCAL_STORAGE_MEMORY).forEach(key => {
localStorage.setItem(key, LOCAL_STORAGE_MEMORY[key])
})
}
cy.persistLocalStorage();
cy.restoreLocalStorage();
cy.clearLocalStorage()
/* To Prevent from Uncaught Exceptions */
cy.on('uncaught:exception', (err, runnable) => {
// returning false here prevents Cypress from failing the test
console.log('error', err.message);
console.log('runnable', runnable);
return false;
});
/* Exception Handling */
cy.on('fail', (err, runnable) => {
console.log('error', err.message);
console.log('runnable', runnable);
return false;
});
/* Single File Upload */
Install Node Package - npm i cypress-file-upload
import 'cypress-file-upload'
const filePath = '10.jpg'
cy.get('input[type=file]').first().attachFile(filePath);
/* Multiple File Upload with an array */
const multifileUpload = () => {
cy.get('[data-cy=*]').click()
const filePath = [
'1.jpg',
'2.json',
'3.html',
'4.pdf',
'5.jpeg',
'6.xlsx',
'7.docx',
'8.pptx'
]
cy.get('input[type=file]').first().attachFile(filePath);
}
/* Asserting multiple elements text with an Array, objects & forEach */
const assertMultipleText = () => {
const buttons = [
{
element: '[data-cy=*]'
},
{
element: '[data-cy=*]'
},
{
element: '[data-cy=*]'
}
]
const getByDataButtons = () => {
buttons.forEach($sel => {
cy.get($sel.element)
.should('have.text',['text1','text2','text3']));
})
}
getByDataButtons();
}
Cypress.Commands.add('assertMultipleText', assertMultipleText);
/* Asserting multiple elements lengths with an Array, Objects & forEach */
const assertMultipleLength = () => {
const files = [
{
element: '[data-cy=*]'
},
{
element: '[data-cy=*]'
},
{
element: '[data-cy=*]'
}
]
const getByDataAssertMultipleLength = () => {
files.forEach($sel => {
cy.get($sel.element)
.should('have.length',3));
})
}
getByDataFiles();
}
Cypress.Commands.add('assertMultipleLength', assertMultipleLength)
/* Asserting multiple elements value with an Array, Objects & forEach */
const assertMultipleValues = () => {
const values = [
{
element: '[data-cy=*]'
},
{
element: '[data-cy=*]'
},
{
element: '[data-cy=*]'
}
]
const getByDataAssertMultipleValues = () => {
values.forEach($sel => {
cy.get($sel.element)
.should('have.value',[1,2,3]));
})
}
getByDataFiles();
}
Cypress.Commands.add('assertMultipleValues', assertMultipleValues)
/* Generate Number up to 10 digit */
const uuid2 = () => Math.floor(Math.random() * 9000000000) + 1000000000
const id2 = uuid2()
const number1 = `${id2}`
const number2 = `${id2}`
/* Call cypress custom command in loop for multiple times */
Cypress._.times(8, () => {
cy.multipleTimes()
})
/* To Press Enter after typing on input field with delay*/
cy.get('[data-cy=*]').type('test{enter}',{delay:0})
/* To Set & Get Environment Variables */
const uuid = () => Cypress._.random(0, 1e6)
const id = uuid()
const testNum = `test ${id}`
Cypress.env('test_case', testNum)
cy.get('[data-cy=*]').type(Cypress.env('test_case'),{delay: 0})
/* To Clear All Caches, Cookies & Sessions */
cy.clearAllLocalStorage();
cy.clearAllCookies()
cy.clearAllSessionStorage();
/* To hold mouse & click on button in row which is invisible */
cy.get('[data-cy=*]').then(($el) => {
setTimeout(() => {
// Trigger mouseout to simulate ending mouseover after 3 sec
$el.trigger('mouseout')
.click();
}, 10000); // 10000 millisec = 10 sec
});
/* To Store CSS selector value & use it in cypress */
let elementValue;
Cypress.Commands.add('cssValueReuse', () => {
cy.get('[data-cy=*]')
.invoke('text')
.then((text) => {
elementValue = text.trim();
// Store the element's text value in the variable
});
});
/* For Auto Scrolling */
cy.get('[data-cy=*]').scrollIntoView().should('be.visible');
/* To verify If element does Not exist */
expect(Cypress.$('[data-cy=*]')).not.to.exist;
/* To verify tooltip by Mouseover */
cy.get('[data-cy=*]').trigger('mouseover')
cy.contains('Tooltip')
/* To assert text for case-sensitive/insensitive conditions */
cy.get('[data-cy=*]').contains('hello world', { matchCase: false })
/* Leading & Trailing whitespace for text assertion */
cy.get('[data-cy=*]')
.invoke('text')
.then((text) => {
const trimmedText = text.trim();
const replaceAllText = trimmedText.replaceAll('\n', "");
const replaceText = replaceAllText.replace(/\s\s+/g, " ");
expect(replaceText).to.equal('text_to_assert');
});
/* To Check Multiple Checkbox serially */
cy.get('[data-cy=*]')
.find('input[type=checkbox][value=True]')
.then(($checkbox) => {
if($checkbox.is(':not(:checked)')) {
cy.wrap($checkbox).check()
}
else {
cy.wrap($checkbox).should('be.checked');
}
});
/* To handle sessions for login module per session*/
Cypress.Commands.add('loginEachSession', (username,password) => {
//only login once per session
cy.session('loginSessionAutomation', () => {
cy.visit('/login_url');
cy.get('[data-cy=username]').type(username);
cy.get('[data-cy=password]').type(password);
cy.get('[data-cy=submit]').click();
});
});
/* To Trim Table for Text */
cy.get('[data-cy=*]').should(($el) =>
expect($el.text().trim()).to.equal('Sign In'));
/* Approaches & Workarounds for handling multi-tab */
1st Approach
cy.contains('txt').invoke('removeAttr','attr_name').click();
2nd Approach
cy.contains('attr_text').invoke('attr','name_attr','_self').click();
3rd Approach
cy.window().then((win) => cy.stub(win, 'open').as('text'));
4th Approach
cy.get('[data-cy=*]')
.first()
.invoke('removeAttr', 'text')
.click({ force: true });
5th Approach
cy.visit('/url')'
/* Attribute href validation */
cy.get('[data-cy=*]')
.find('[data-cy=*]')
.should('have.attr', 'href', '/login/user');
/* To Create Users test data with Cypress Fixtures */
/* RBAC [ Role Back Access Control ] with JSON File */
Note - Create user_rbac.json file in cypress fixtures folder
{
user_view: {
username: '',
password: '',
role: 'view'
},
user_edit: {
username: '',
password: '',
role: 'edit'
},
user_delete: {
username: '',
password: '',
role: 'delete'
},
user_admin: {
username: '',
password: '',
role: 'admin'
},
user_superAdmin: {
username: '',
password: '',
role: 'superAdmin'
}
}
/ * Create Login Custom Command */
Cypress.Commands.add('login', (username,password) => {
cy.visit('/login_url');
cy.get('[data-cy=username]').type(username);
cy.get('[data-cy=password]').type(password);
cy.get('[data-cy=submit]').click();
});
/* Create Logout Custom Command */
Cypress.Commands.add('logout', () => {
cy.get('[data-cy=menu]').click();
cy.get('[data-cy=logout]').click();
})
/ * How to use JSON file while using RBAC during UI-Automation */
// To Import Path of Cypress Fixture Directory
import user from '../../../fixtures/user_rbac.json'
describe('Test RBAC Scenarios', () => {
it('Login with UserView Permission', () => {
cy.login(user.user_view.username,user.user_view.password);
cy.logout();
});
it('Login with UserEdit Permission', () => {
cy.login(user.user_edit.username,user.user_edit.password);
cy.logout();
});
it('Login with UserDelete Permission', () => {
cy.login(user.user_delete.username,user.user_delete.password);
cy.logout();
});
it('Login with UserAdmin Permission', () => {
cy.login(user.user_admin.username,user.user_admin.password);
cy.logout();
});
it('Login with UserSuperAdmin Permission', () => {
cy.login(user.user_superAdmin.username,
user.user_superAdmin.password);
cy.logout();
});
});
/* To Fill Up Form with An Array, Objects & forEach */
const formValidate = () => {
const uuid1 = () => Cypress._.random(0, 1e3)
const id1 = uuid1()
const firstName = `first${id1}`
const lastName = `last${id1}`
const email = `${id1}@yopmail.com`
const fillForm = [
{
element: '[data-cy=firstName]',
text: firstName
},
{
element: '[data-cy=lastName]',
text: lastName
},
{
element: '[data-cy=email]',
text: email
}
]
const getByDataFormValidate = () => {
fillForm.forEach($sel => {
cy.get($sel.element).type($sel.text, { delay: 0 });
cy.get($sel.element).should('have.value', $sel.text);
})
}
getByDataFormValidate();
}
Cypress.Commands.add('formValidate', formValidate);
/* To verify url */
cy.url().should('include', '/login');
/* Defining Global Hooks by excluding a few test scripts */
beforeEach(() => {
const excludedTests = [
'path/to/excluded/test.spec.js',
'path/to/another/excluded/test.spec.js',
];
})
/* Accessing iFrame */
Cypress.Commands.add('accessIframe', (iFrame) => {
cy.get(iFrame)
.its('0.contentDocument.body')
.should('be.visible')
.then(cy.wrap);
});