w3resource

Introduction to Cypress


In this tutorial we are going to provide you with a very good guide for understanding how to test with Cypress. This tutorial will be divided into two. In part one you will learn how to Cypress queries the DOM, how it manages subjects and different chains of commands and in part two, we will walk you through how you can make assertions about elements.

Sometimes, Cypress can be simple.

Simplicity entails getting more things done with less typing. Here is an example to illustrate this:

'''describe('Comment Resource', () => {
  it('Creating a New Comment', () => {
    cy.visit('/comments/new')     // 1.

    cy.get('input.comment-title') // 2.
      .type('My First Comment')   // 3.

    cy.get('input.comment-body')  // 4.
      .type('Hello, world!')   // 5.

    cy.contains('Submit')      // 6.
      .click()                 // 7.

    cy.url()                   // 8.
      .should('include', '/comments/my-first-comment')

    cy.get('h1')               // 9.
      .should('contain', 'My First Comment')
  })
})'''

Quite easy to comprehend right? But there are lots that have been covered by it, both on the client and the server. We will explore the basics of Cypress that makes the example work.

Querying Elements

Cypress is like jQuery

If  you have some jQuery background, you must have written a code similar to the code shown below, for querying elements:

$(‘.my-selector’)

This is similar to how you will query elements in Cypress.

cy.get(‘.my-selector’)

Actually, Cypress bundles jQuery and exposes many of its DOM traversal methods to you so that you can work with complex HTML structures with ease using APIs that you are already familiar with, here is an example:

'''cy.get('#main-content')
  .find('.article')
  .children('img[src^="/static"]')
  .first()'''

However, the process of accessing the DOM elements returned from a query works differently:

'''// This is fine, jQuery will return the element synchronously.
const $jqElement = $('.element')
// This does not work! Cypress will not return the element synchronously.
const $cyElement = cy.get('.element')'''

Here is the reason for that:

Cypress is Not like jQuery

There are however cases where jQuery and Cypress differ. For instance, when jQuery does not find any matching DOM elements from its selector, it will return an empty jQuery collection. In this case you will have to add conditional checks and keep retrying the queries manually.

However, when Cypress can’t find any matching DOM elements from its selector, it will automatically retry the query till the element is found or a set timeout is reached.

Querying by Text Content

There is another way to locate things, this is to look them up using their content, this is by using the same contents the users see. To do this, you can use the cy.contains() command, for instance:

'''// Find an element in the document that contains the text 'New Comment'
cy.contains('New Comment')
//Find an element within '.main' that contains the text 'New Comment'
cy.get('.main').contains('New Comment')'''

This enables you to write the tests from the perspective of a user that is interacting with your application. The users only know that they want to click on a button labelled "Submit". The user does not know the class or id of the element.

When Elements Are Missing

Cypress will anticipate the asynchronous nature of web applications and does not fail immediately an element is not found. Rather, Cypress will give your application a window of time to finish whatever it may be doing. This is called a timeout and the default timeout is 4 seconds, but you can customize it to a specific timeout period.

You can set the timeout on an element as shown below:

'''// You should give this element 10 seconds to appear
cy.get('.my-slow-selector', { timeout: 10000 })'''

Alternatively, you can globally set the timeout using the configuration setting: defaultCommandTimeout.

Chains of Commands

It is very important to understand the mechanism that Cypress uses to chain commands together. It will manage a Promise chain on your behalf, with each command yielding a "subject" to the next command until you either reach the end of the chain or you encounter an error.

Interacting with Elements

As shown in the initial example, Cypress enables you to click and type into elements using the .click() and the .type() commands using the cy.get() or cy.contains() command. That was a perfect example of chaining in action. Let us revisit it again:

'''cy.get('textarea.post-body')
  .type('This is an excellent post.')'''

In this example, we are chaining the .type() onto the cy.get(), this will tell it to type in the subject that is yielded from the cy.get() command.

Here are some additional commands that Cypress provided for you to interact with your application:

  • .blur() - Makes a focused DOM element blur.
  • .focus() - Focuses on a DOM element.
  • .clear() - Clears the value of an input or textarea.
  • .check() - Checks checkbox(es) or radio(s).
  • .uncheck() - Unchecks checkbox(es).
  • .select() - Selects an <option> within a <select>.
  • .dblclick() - Double-clicks a DOM element.
  • .rightclick() - Right-clicks a DOM element.

In the second part of this tutorial we will look at make Assertions about element.