My Cypress note
— cypress — 2 min read
Resource
Lint error
cy.visit('/dashboard');
// Whency.location().should((loc) => { // Then expect(loc.pathname).to.eq('/login');});
ESLint may flag cy.visit()
as error as it can’t find the definition. Add plugin:cypress/recommended
to .eslintrc.js
module.exports = { parser: 'babel-eslint', extends: ['airbnb', 'prettier', 'plugin:prettier/recommended', 'plugin:cypress/recommended'], env: { browser: true, node: true,
Config.js
Cypress 12 has quite a few breaking changes and this migration guide comes very handy. One of the changes is using config.js
instead of config.json
.
const { defineConfig } = require('cypress');const { username, password, tokenApiUrl } = require('./cypress.plain.json');
module.exports = defineConfig({ e2e: { baseUrl: 'https://xcp.next.test.stacks.xenzonegroup.com', }, env: { username: username, password: password, tokenApiUrl: tokenApiUrl, },});
Using support
const _ = Cypress._;const url = require('url');const { username, password, tokenApiUrl } = Cypress.env();
describe('The dashboard', () => { describe('when a worker is not logged in', () => { it('should redirect to the login page', () => { // Given cy.visit('/dashboard');
// When cy.location().should((loc) => { // Then expect(loc.pathname).to.eq('/login'); }); }); });
describe('when a worker is logged in', () => { it('should be possible to visit the dashboard', () => { // Given cy.login();
// When cy.visit('/dashboard/schedule');
// Then cy.get('[data-test-id="dashboard"]').should('have.attr', 'data-test-id', 'dashboard'); }); });});
// cypress/support/e2e.jsimport './login';
const { username, password, tokenApiUrl } = Cypress.env();
if (!username || !password) throw new Error( 'Looks like there is no username or password Cypress env variables. Make sure you have cypress.env.json configured correctly! See README - One time setup: environment variables' );
Cypress.Commands.add('login', (overrides = {}) => { Cypress.log({ name: 'login', });
cy.request({ method: 'POST', url: 'https://auth.com/token', form: true, body: { username: username, password: password, grant_type: 'password', scope: 'type:user', }, }).then((resp) => { cy.setCookie( 'auth', JSON.stringify({ accessToken: resp.body.access_token, token_type: 'Bearer', expiresAt: Date.now() + resp.body.expires_in * 1000, }) ); });});
Parameterised tests
You can use parameterized tests in Cypress, which is an excellent way to reduce code duplication when you need to run the same tests with different data.
Use [].forEach
[ { fixture: 'general-notes.json', noteType: 'GeneralNote', noteContent: 'Note case note description', }, { fixture: 'caseNotes/flagged-notes.json', noteType: 'FlaggedNote', noteContent: 'Flagged case note description', }, ].forEach(({ fixture, noteType, noteContent }) => { it(`should be possible to add, save and then view a case note, of type "${noteType}"`, () => { cy.intercept('POST', '/users/**/notes', { fixture, });
cy.visit(`/dashboard/users/${serviceUser}`);
cy.get('[data-test-id="createButton"]').click(); cy.get('h2').should('have.text', 'Add Case Note');
cy.get(`input[value="${noteType}"]`).click();
cy.get('textarea').should('have.attr', 'name', 'description').type(noteContent);
cy.contains('SAVE').click(); cy.wait(['@get-case-note']);
cy.get('td').contains(noteContent).should('be.visible'); }); });
Select a button that contains a text
<button tabindex="0" class="c1392 c1626 c1637 c1638 c1640 c1641" type="button"> <span class="c1627">Add incident</span> <span class="c1402"></span></button>
cy.get('button').contains('Add incident').click();