We’re duplicating quite a few commands between the registration and login of our user for assertions. Let’s see how we can take these assertions and create a custom command to make the assertions.
We have the tests:
it('should register a new user', () => {
cy.createUser().then(user => {
cy.visit('/')
.getByText(/login/i)
.click()
.getByLabelText(/username/i)
.type(user.username)
.getByLabelText(/password/i)
.type(user.password)
.getByText(/submit/i)
.click()
// verify the user in localStorage
.url()
.should('eq', `${Cypress.config().baseUrl}/`)
.window()
.its('localStorage.token')
.should('be.a', 'string')
.getByTestId('username-display', {timeout: 500})
.should('have.text', user.username)
})
});
We can create some assertions commands to make it more reusable:
Cypress.Commands.add('assertHome', () => {
cy.url().should('eq', `${Cypress.config().baseUrl}/`)
})
Cypress.Commands.add('assertLoggedInAs', user => {
cy
.window()
.its('localStorage.token')
.should('be.a', 'string')
.getByTestId('username-display', {timeout: 500})
.should('have.text', user.username)
})
Then we can improve the test:
it('should register a new user', () => {
cy.createUser().then(user => {
cy.visit('/')
.getByText(/login/i)
.click()
.getByLabelText(/username/i)
.type(user.username)
.getByLabelText(/password/i)
.type(user.password)
.getByText(/submit/i)
.click()
.assertHome()
.assertLoggedInAs(user);
})
});
Run tests as an authenticated user with Cypress
For most applications you’re going to need to be logged in as a user to interact with the application. Let’s see how we can register as a new user and login as that user to test using the application as a logged in user.
Sometime you want to check some DOM element is not present, you cna use queryByTestId()
it('displays the username', () => {
cy.createUser().then(user => {
cy.visit('/')
.getByText(/login/i)
.click()
.getByLabelText(/username/i)
.type(user.username)
.getByLabelText(/password/i)
.type(user.password)
.getByText(/submit/i)
.click()
.assertLoggedInAs(user)
.getByText(/logout/i)
.click()
.queryByTestId('username-display', {timeout: 300})
.should('not.exist')
})
});
Almost every time we need to login, we’ll want to have a newly created user to login as. Let’s go ahead and combine the createNewUser and logincommands to create a single loginAsNewUser which we can use in any test that needs an authenticated user.
// support/commands.js Cypress.Commands.add('loginAsNewUser', () => { cy.createUser().then(user => { cy.login(user) }); }); Cypress.Commands.add('login', user => { cy.request({ url: 'http://localhost:3000/login', method: 'POST', body: user, }).then(({body}) => { window.localStorage.setItem('token', body.user.token); return body.user; }) })
// e2e/calcualtor.js describe('authenticated calculator', () => { it('displays the username', () => { cy.loginAsNewUser().then((user) => { cy.visit('/') .getByTestId('username-display') .should('have.text', user.username) .getByText(/logout/i) .click() .queryByTestId('username-display', {timeout: 300}) .should('not.exist') }) }); })
Install React DevTools with Cypress
Because Cypress runs in a real Chrome browser, we can install extensions, like React DevTools. The tricky bit will be to make our application hook up to the extension properly.
react-dev-tools.js
if (window.Cypress) { window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = window.parent.__REACT_DEVTOOLS_GLOBAL_HOOK__ }
Import the script before we import the REACT
index.js
import './react-dev-tools' import './global.css' import React from 'react'
















