Hello everyone, Cypress recently released version 12, and with it, made cy.session
generally available. The docs to cypress can be found here: session | Cypress Documentation
It promises being able to save time between tests by saving an entire browser session, so that you can recall it in another test or another suite and immediately jump into your test code without having to rerun login for example.
I found a setup that works, but it probably isn’t great yet.
- The
validate()
method isn’t really useful, as it should ideally check with the server that the user really exists and is logged in- The problem here is that I see no easy way around loading an actual page with Meteor and call a method. This requires an additional
visit
call which is really slow and adds up on long test suites.
- The problem here is that I see no easy way around loading an actual page with Meteor and call a method. This requires an additional
Here’s the code:
import { ADMIN_EMAIL, USER_PASSWORD } from '../e2eConstants';
// The cypress visit command also waits for the page to be interactive,
// but we need to wait for Meteor to be ready
// We first wait on "appReady", which is set after meteor.startup() is called
// We then call a basic meteor method to make sure we're talking with the server
Cypress.Commands.overwrite('visit', (originalFn, url, options) => {
originalFn(url, options);
cy.window().should('have.property', 'appReady', true);
cy.checkConnection();
});
Cypress.Commands.add('createSession', (email, password = USER_PASSWORD) => {
cy.session(
[email, cy.id],
() => {
cy.visit('/login');
cy.meteorLogin(email, password);
},
{
validate() {
cy.window().then(win => {
const loginToken = win.localStorage.getItem('Meteor.loginToken');
return !!loginToken;
});
},
},
);
});
describe('Cypress setup', () => {
before(() => {
cy.visit('/setupTest');
cy.callMethod('resetDatabase'); // As it says
cy.callMethod('generateScenario', { // Our fixture generator
scenario: {
users: [
{
_id: 'advisor1',
emails: [{ address: ADMIN_EMAIL, verified: true }],
},
],
},
});
cy.callMethod('setPassword', { // A bit expensive, so we only run it for users that we login with
userId: 'advisor1',
password: USER_PASSWORD,
});
});
beforeEach(() => {
cy.createSession(ADMIN_EMAIL);
cy.visit('/'); // Does require login
});
it('logs in and saves the session', () => {
cy.routeTo('/loans'); // Instant react-router routing by using reactRouter.push from the window object
cy.contains('Loans');
});
it('is already logged in', () => {
cy.routeTo('/users');
cy.contains('Accounts');
});
});
I’m curious to know if some of you have experimented with this, and found some more reliable/resilient bits of code to work with Cypress and Meteor?