Advantages:
- Cypress framework captures snapshots at the time of test execution. This allows QAs or developers to hover over a specific command in the Command Log to see exactly what happened at that particular step.
- One doesn’t need to add explicit or implicit wait commands in test scripts, unlike Selenium. Cypress waits automatically for commands and assertions.
- Developers or QAs can use Spies, Stubs, and Clocks to verify and control the behavior of server responses, functions, or timers.
- The automatic scrolling operation ensures that an element is in view before performing any action (for example Clicking on a button)
- Earlier Cypress supported only Chrome testing. However, with recent updates, Cypress now provides support for Firefox and Edge browsers.
- As the programmer writes commands, Cypress executes them in real-time, providing visual feedback as they run. Cypress carries excellent documentation.
Limitations:
- One cannot use Cypress to drive two browsers at the same time
- It doesn’t provide support for multi-tabs
- Cypress only supports JavaScript for creating test cases
- Cypress doesn’t provide support for browsers like Safari at the moment.
- Limited support for iFrames
Cypress only supports the Cascading Style Sheets (CSS) selectors to identify the elements.However, it can also work with xpath, with the help of the ‘Cypress-Xpath’ plugin.
Syntax with attribute-id and tagname is tagname#id − input#user_email_login or #user_email_login
Syntax with attribute-class and tagname is tagname.class − input.user_email_ajax or .user_email_ajax
Syntax with any attribute value and tagname is tagname[attribute=’value’] − input[id=’user_email_login’]
* Match all element that contains the value
cy.get(‘[class*=”class-name”]’)
$ Match all element that ends with the value
cy.get(‘[class$=”class-name”]’)
^ Match all element that starts with the value
cy.get(‘[class^=”class-name”]’)
Cypress provides various methods to work with the first element, last element, or element at a specific index, then you need to use the first(), last(), or eq() functions along with cy.get().
Get the first Element in Cypress
The function .first() is used to get the first element in a set of elements
For Example:
cy.get(‘.name-text-box’).first()
Get the last Element in Cypress
Similar to the above example, here .last() function is used to get the last element in a set of elements.
For Example:
cy.get(‘.mobile-text-box’).last()
Get the specific element by index in Cypress
To get a specific element in the set of elements, using eq() function along with cy.get(‘.msg-body’) as shown below
For Example:
cy.get(‘.text-box’).eq(2)
Get Element By Containing Text in Cypress
Cypress provides contains() function along with the tag name and should be able to get the element.
The above approach is most useful to find the href link by Text in Cypress
For Example:
cy.get(‘a:contains(“Forgotten password?”)’).first().click()
Get DOM Element containing Text in Cypress
Cypress provides contains() function, which can be used with cy command or can be chained with cy.get() command to get the DOM element as seen in the examples below
Example 1:
Find the element having Text Sign In
cy.contains(‘Sign In’);
The above command searches for Text ‘Sign In’ inside the web page and returns the element. However, the command doesn’t check which type of element it is.
Example 2:
Find the DOM element having Text Sign In
cy.get(‘a’).contains(‘Sign In’);
The above command searches for all tags and returns the element if is having text ‘Sign In’. So, considering the first example, this approach is more specific to the tag name.
Cypress allows the use of regular expressions inside contains() function.
As seen in the below example, you can search for the element containing text that starts with b and has one or more word characters (numbers, alphabets, and _)
cy.contains(/^b\w+/)
To ignore the Case Sensitivity while using regular expressions inside contains() function, use { matchCase: false }
cy.get(‘div’).contains(‘capital sentence’, { matchCase: false })
To get the descended DOM element of a specific locator, use cy.find() function as seen in the example below:
For HTML Code
The following command returns all ordered list (li) elements inside the unordered list (ul) element
cy.get(‘#parent’).find(‘li’)
Get the Next Sibling in Cypress
The .next() function returns the next sibling in Cypress as seen below
cy.get('#my_ele').next();
Get the next sibling which is an input tag:
cy.get('#my_ele').next('input');
Get the Previous Sibling in Cypress
The .prev() function returns the previous sibling in Cypress as seen below
cy.get('#my_ele').prev();
Get the previous sibling which is an input tag, use the following command:
cy.get('#my_ele').prev('input');
Get All Next Siblings in Cypress
The .nextAll() function returns the next sibling in Cypress as seen below
cy.get('#my_ele').nextAll();
Get All Previous Sibling in Cypress
The .prevAll() function returns the previous sibling in Cypress as seen below
cy.get('#my_ele').prevAll();
Get Any Siblings
The .siblings() function is used to find the siblings in Cypress as seen below
cy.get('li').siblings('.active')
Or
cy.get('li').siblings()
Get The Siblings Until in Cypress
The functions .nextUntil() and .prevUntil() allows you to get all the siblings before or after a certain condition.
For example, to get all the next sibling elements until the element class name is ‘my_class_name’, use the command as seen below:
cy.get('li').nextUntil('.my_class_name')
Get previous sibling element until the element class name is ‘my_class_name’, use the command as seen below:
cy.get('li').prevUntil('.my_class_name')
Within Command in Cypress
The .within() function scopes all subsequent cy commands within this element as seen in the example below:
For HTML Code
The following command will search for the elements only within the form, instead of searching the whole code, and returns only the relevant elements within the form,
cy.get('form').within(($form) => {
// cy.get() will only search for elements within form,
// not within the entire document
cy.get('input[name="email"]').type('eaxample@email.com')
cy.get('input[name="password"]').type('mypassword')
cy.root().submit()
})
Cypress doesn’t support XPath out of the box, however, if you are already familiar with XPath then you can use the third-party plugin cypress-xpath to get the HTML element by XPath by using the following steps:
Step 1: Install the cypress-xpath plugin using the below command:
npm install -D cypress-xpath
Step 2: Set Up XPath plugin
Navigate to cypress/support/index.js and add the below line
require('cypress-xpath')
Step 3: Use cy.xpath() command in the script as seen in the example below
it('finds list items', () => {
cy.xpath('//ul[@class="todo-list"]//li')
.should('have.length', 3)
})
To get specific elements using XPath you can also chain the cy.xpath() to another command as seen below
it('finds list items', () => {
cy.xpath('//ul[@class="todo-list"]')
.xpath('./li')
.should('have.length', 3)
})
- Download and install node.js from https://nodejs.org/en/download/
- Once the installation is done, a nodejs file gets created in the Program files.
- In the System Properties pop-up, move to Advanced, click on Environment Variables. Then click on OK.
- In the Environment Variables pop-up, move to the System variables section and click on New.
- Enter NODE_HOME and the node.js path (noted earlier) in the Variable name and the Variable value fields respectively in the New System Variable pop-up.
- Once the path of the node.js file is set, we shall create an empty folder (say cypressautomation) in any desired location.
- Next, we need to have a JavaScript editor to write the code for Cypress. For this, we can download Visual Studio Code from the link https://code.visualstudio.com/
- Once the executable file is downloaded, and all the installation steps are completed, the Visual Studio Code gets launched.
- Select the option Open Folder from the File menu. Then, add the CypressAutomation folder (that we have created before) to the Visual Studio Code.
- We need to create the package.json file with the below command from terminal −
- We have to enter details like the package name, description, and so on, as mentioned in the image given below −
- npm init
- Once done, the package.json file gets created within the project folder with the information we have provided.
- Finally, to install Cypress run the command given below −
- npm install cypress –save-dev
Cypress Test Runner helps to trigger the test execution.
To open the Test Runner, we have to run the below mentioned command −
node_modules/.bin/cypress open
The Test Runner window opens up after some time with the message that a sample project folder structure has been provided by Cypress under examples folder.
Click on the OK, got it! button.
fixtures − Test data in form of key-value pairs for the tests are maintained here.
integration − Test cases for the framework are maintained here.
plugins − Cypress events (prior and post events to be executed for a test) are maintained here.
support − Reusable methods or customized commands, which can be utilised by test cases directly, without object creation are created here.
videos − Executed test steps are recorded in the form of videos and maintained here.
node_modules − Project dependencies from the npm are maintained in this folder.It is the heart of the Cypress project execution.
cypress.json − Default configurations are set in this folder. The values of the current configurations can be modified here, which overrules the default configurations.
package.json − Dependencies and scripts for the projects are maintained in this folder.
Basic Test Script
// test suite name
describe('Cypress Test Suite', function () {
// Test case
it('My First Cypress Test Case', function (){
// test step for URL launching
cy.visit("https://www.google.com/");
});
});
Test Execution
For execution from the command line, run the command given below −
./node_modules/.bin/cypress run
All the files within the integration folder get triggered.
For execution from the Test Runner, run the command stated below −
./node_modules/.bin/cypress open
Then, click on the spec file that we want to trigger for execution.
To trigger execution for a specific file from command line, run the command mentioned below −
cypress run --spec ""
Cypress has the capability to run tests across multiple browsers. Currently, Cypress has support for Chrome-family browsers (including Electron and Chromium-based Microsoft Edge), WebKit (Safari’s browser engine), and Firefox.
To run the execution in Chrome, you need to run the below mentioned command:
./node_modules/.bin/cypress run — browser chrome
To run the execution in Firefox, run the command given below:
./node_modules/.bin/cypress run — browser firefox
To run the execution in headed mode, run the command given below:
./node_modules/.bin/cypress run — headed
//element is visible & enabled
cy.get('#username').should('be.visible').and('be.enabled')
//element is checked
cy.contains('Checkbox').and('be.checked')
//checks element having class attribute chkbox
cy.get('.checkbox').check()
//obtains children of element n
cy.get('n').children()
//removes input abc
cy.get('#text').type('abc').clear()
//clear abc cookie
cy.clearCookie('abc')
//clear all cookies
cy.clearCookies()
//clear all local storage
cy.clearLocalStorage ()
//click on element with id username
cy.get('#username').click()
//returns element in #txt having HireQA text
cy.get('#txt').contains('HireQA')
//double clicks element with id submit
cy.get('#submit').dblclick()
//pause to debug at start of command
cy.get('#txt').debug()
//It obtains window.document on the active page.
cy.document()
//iterate through individual li
cy.get('li').each(() => {...})
//obtain third td in tr
cy.get('tr>td').eq(2)
//obtain td from tr
cy.get('tr').find('td')
//obtain first td in tr
cy.get('tr>td').first()
//obtain all td from tr in list
cy.get('tr>td')
//It obtains a particular browser cookie by its name.
cy.getCookie('abc')
//It obtains all the cookies
cy.getCookies()
//navigate back
cy.go('back')
//navigate forward
cy.go('forward')
//It launches an URL.
cy.visit('https://www.hireqa.co.in')
//Wait for a certain time in milliseconds
cy.wait(1000)
//It obtains the document title of the active page.
cy.title()
//It prints the messages to the Command Log.
cy.log('Cypress logging ')
//It is used for page reloading.
cy.reload()
Cypress gives us access to the current URL through the .location() command.
cy.location();
Extracting the path parameter:
cy.location('pathname');
Extracting the path using index:
cy.location('pathname').then(path => {
// path is the value from the previous command, `location("pathname").
// In our example, the value of `path` is "/path/1234".
const pathparam= path.split('/')[2];
});
Extract the value and store it for future:
Cypress provides a command named .wrap() to accomplish this. .wrap() takes a value and yields it as the result of a command, which can then be chained to any other Cypress commands.
cy.location('pathname').then(path => {
// path is the value from the previous command, `location("pathname").
// In our example, the value of `path` is "/path/1234".
const pathparam= path.split('/')[2];
cy.wrap(pathparam).as('pathparam');
});
Accessing the aliased pathparam
Aliased values can be accessed using another command: .get(). When retrieving values with named aliases, as in our situation, we specify the name with an @ prefix, like this:
cy.get('@pathparam');
We'll chain another .then() command to work with the result of the call to .get():
cy.get('@pathparam').then(pathparam => {
cy.request(`/api/articles/${pathparam}`).then(response => {
expect(response.status).to.eq(200);
// And any other assertions we want to make with our API response
});
});
Cypress Describe
describe() is basically to group our test cases. We can nest our tests in groups as deep as we deem necessary. describe() takes two arguments, the first is the name of the test group, and the second is a callback function. There can be multiple describe in same file. Also one describe can be declared inside another describe.
Cypress Context
context() is just an alias for describe(), and behaves the same way.
Cypress it
it() is used for an individual test case. it() takes two arguments, a string explaining what the test should do, and a callback function which contains our actual test:
Cypress Specify
specify() is an alias for it(), so choose whatever terminology works best for you.
describe('First Describe', () => {
describe('Describe Inside Describe', () => {
it('first test inside', () => {
})
})
it('1st test', () => {
})
specify('2nd test', () => {
})
it('3rd test', () => {
})
})
context('2nd suite', () => {
it('first test', () => {
})
it('2nd test', () => {
})
it('3rd test', () => {
})
})
() => we are declaring call back function, A callback is a function passed as an argument to another function.
-
14
Events
-
54
Hello
---------------------------------
cy.get('.versal-badge')
.closest('ul')
.should('have.class', 'list')
closest command used from this simple example we can conclude that it fetches the element of versal-badge of which its ancestor is ul tag and that ul tag contains a class called a list.
1. Implicit Assertion
a) should
b) and
2. Explicit Assertion
a) expect (BDD style)
b) assert (TDD style)
Implicit Assertion - should - example:
cy.visit("https://hireqa.co.in/interview-qa/?include_category=cypress")
cy.url().should('include', 'hireqa.co.in')
cy.url().should('eq', 'https://hireqa.co.in/interview-qa/?include_category=cypress')
cy.url().should('contain', 'hireqa')
//Verify the element is visible
cy.get('webelement').should('be.visible')
//Verify the element exist
cy.get('webelement').should('exist')
//Verify the entered username is correct
cy.get('webelement').type('username')
cy.get('webelement').should('have.value','username')
Implicit Assertion - and - example:
cy.visit("https://hireqa.co.in/interview-qa/?include_category=cypress")
cy.url().should('include', 'hireqa.co.in')
.and('eq', 'https://hireqa.co.in/interview-qa/?include_category=cypress')
.and('contain', 'hireqa')
.and('not.contain', 'xyz');
//Verify the logged-in user is same
let expectedName = 'hireqa';
cy.get('webelement').then((name) => {
let actualName = name.text()
expect(actualName).to.equal(expectedName)
})
//Assert example
assert.equal(actualName, expectedName)
assert.notEqual(actualName,expectedName)
//Click on radio button and verify the radio button is clicked
cy.get('.radiobutton').check().should('be.checked')
//Verifying the radio button is not clicked
cy.get('.radiobutton').should('not.be.checked')
//Select a single checkbox
cy.get('.checkbox').check().should('be.checked')
//Unselecting the checkbox
cy.get('.checkbox').uncheck().should('not.be.checked')
//Select multiple checkboxes using common locator
cy.get('.common-checkbox-locator').check().should('be.checked')
//Select the first checkbox
cy.get('.common-checkbox-locator').first().check().should('be.checked')
//Select the last checkbox
cy.get('.common-checkbox-locator').last().check().should('be.checked')
//Select the values from the Select dropdown
//First locate the dropdown and then the select the value
cy.get('.dropdown').select('India').should('have.value', 'India')
//Select the value from the dynamic dropdown by entering the value
cy.get('.dynamic-dropdown').click()
cy.get('.dropdown.text').type('India').type('{enter}')
//Verify the default selected value in dropdown
cy.get('.dropdown').should('have.text', 'India')
//Wikipedia search textbox example
cy.visit('https://www.wikipedia.org/')
cy.get('#searchInput').type('hyd')
cy.get('.suggestion-title').contains('Hyderabad').click()
//Google search example
cy.visit('https://www.google.com/')
cy.get('.gLFyf').type('Cypress')
cy.get('.wM6W7d > span').each(($el, index, $list) => {
if($el.text() == 'cypress automation')
{
cy.wrap($el).click()
}
//Click on Alert button to generate the alert
cy.get('.alert-button').click()
//Cypress will handle alerts using cy.on and window:alert
cy.on('window:alert', (t) => {
expect(t).to.contains('This is JS Alert')
})
//Alert window automatically will be closed by Cypress
//Fetch the text from web page and validate
cy.get('.alert-message').should('have.text', 'You clicked on Alert')
//Handle JS Confirmation Alert. Confirmation alert will have OK and CANCEL button.
cy.get('.confirmation-alert-button').click()
//Cypress will handle alerts using cy.on and window:confirm
cy.on('window:confirm', (t) => {
expect(t).to.contains('This is JS Confirmation Alert')
})
//Cypress automatically closes the alert by default clicking on OK button
cy.get('.alert-message').should('have.text', 'You clicked on OK')
//Click on CANCEL button on Confirm Alert
cy.on('window:confirm', ()=> false);
//Handle Javascript Prompt Alerts
//Get the control on prompt alert before generate the prompt alert
cy.window().then((win) => {
cy.stub(win, 'prompt').returns('Welcome to JS Prompt Alert');
})
cy.get('prompt-alert-button').click();
//Authentication Prompt Alert
cy.visit("url", { auth:
{
username : "admin",
password : "password"
}
}
);
or
cy.visit("https://username:password@url")
//This is applicable when new window opens in new tab and the element has target attribute
For Example:
Open New Window
Option 1 - Remove target attribute and the new window will open in the same browser window. It doesn't open the new tab.
cy.get('link').invoke('removeAttr', 'target').click();
//Verify the child window url
cy.url().should('include', 'child window url');
cy.wait(5000);
cy.go('back'); //back to parent tab
Option 2 - Get href value and use it
cy.visit('parenturl');
cy.get('link').then((e) => {
let childurl = e.prop('href');
cy.visit(childurl)
}
cy.url().should('include','childurl');
cy.wait(5000);
cy.go('back);
Note: Option -2 should have same domain
Option 1:
let iframe = cy.get('#iFrameID')
.its('0.contentDocument.body')
.should('be.visible')
.then('cy.wrap');
iframe.clear().type('Welcome to Hire QA');
Option 2:
Install cypress-iframe plugin - npm install -D cypress-iframe
Add the command in cypress/support/command.js : import 'cypress-iframe'
Load the frame or switch to the frame: cy.frameLoaded('#frameID')
Execute specific cy.js file - npx cypress run --spec
Execute all cy.js files under the folder - npx cypress run --spec
Execute the cy.js file in Chrome browser (it will run the scripts in headless mode) - npx cypress run --spec --browser=chrome
Execute the cy.js file in Chrome browser (it will run the scripts in headed mode) - npx cypress run --spec --browser=chrome --headed