Assertions

Learn about Cypress Assertions in this lesson.

We'll cover the following

After you’ve done all the actions, you’re likely going to make some assertions about what’s on the page. Cypress assertions are kind of complicated on one level in that there are a lot of options, but at the same time, the syntax has a couple of common patterns.

You can chain an assertion at the end of a series of commands with should. However, you need to do something between cy and should. You can’t just write cy.should("exist"), but you can write cy.get("selector").should("exist").

The should command typically takes as its first argument, what the Cypress docs call a chainer. Cypress takes its assertions from a library called Chai. Assertions in Chai are a chain of methods, as in to.be.null, or to.have.class or to.be.visible. A Cypress chainer is a string version of everything in the Chai method chain after to, so those assertions in Cypress would be should("be.null"), should("have.class", "class") or should("be.visible"). If the assertion needs an expected value, the way have.class does, then that value is the second argument. In a few cases, there are two arguments, so should("have.attr", "href", "/tickets").

In the argument case, you can also use the its command to coax the variable from the selected object. The its command applies a property getter to the currently yielded elements, so you could do cy.get(".thing").its("class").should("include", "thing") as a synonym of cy.get(".thing").should("have.class", "thing").

You can chain multiple should commands after each other, and if you want, you can use and as a synonym of should, as in should("have.class", "foo").and("be.visible").

The should command can also take a function. Within the function you can do assertions using regular Chai syntax, involving expect—the yielded argument is the set of elements:

cy.get(".tickets").should(($tickets) => {
  expect($tickets).to.have.length(10)
  expect($tickets.find("is-visible)).to.have.length(3)
}

You can also use expect syntax inside any then function in a Cypress command.

Stubs

Cypress uses the Sinon library for mock and stub behavior. I’m not going to get into all the details of Sinon here, but it does provide the ability to define stub methods cy.stub(foo, 'bar').returns('baz') or cy.stub(obj, 'method').resolves('foo'), and then assertions like expect(foo.bar).to.be.calledOnce.

You can also control the clock with cy.clock(). Once you’ve called cy.clock(), you can move the clock forward with cy.tick(milliseconds).

Maybe more usefully, you can also simulate a server and request data. To start this process you call cy.server(). After turning on a cy.server(), you can direct that server to produce canned responses to routes with the cy.route() command:

cy.server()
cy.route("/tickets", {id: 1, concert_id: 3, row: 2, seat: 3})

In this case, the first argument to route is a string or regular expression. Or, it’s two arguments where the first one is an HTTP method, and the second is the string or regex. The last argument is a string, array, object, or function.

Once a route is set, then HTTP requests that match the string or regex argument are not routed to the server but instead, return the last argument. Requests that don’t match a Cypress-defined route just go to the underlying server as expected.

This gets a little more interesting in conjunction with the cy.fixture() command. Cypress lets you keep fixture data, typically JSON or a string in files in the cypress/fixtures directory. You can then use cy.fixture() to access the file, and then use the data as the result of the routes.

So, if we’ve got a file cypress/fixtures/tickets.json, we could then do this:

cy.server()
cy.fixture("tickets.json").as("tickets")
cy.route('POST', '**/tickets', '@tickets')

Then any post request to tickets in your page will return the fixture file, making that data available for testing.

Get hands-on with 1200+ tech skills courses.