Reputation: 13367
I am trying to create e2e tests using Cypress for my Angular application. So far I managed to get the basics sorted, now I am trying to stub network requests.
I have created some fixtures and created a custom command:
Cypress.Commands.add('login', (email, password, happy = false) => {
let auth_url = Cypress.env('auth_url');
console.log(auth_url);
cy.get('[data-cy=email]').as('email');
cy.get('[data-cy=password]').as('password');
cy.get('[data-cy=login-form]').as('form');
cy.location('pathname').should('equal', '/login');
cy.get('@email').type(email);
cy.get('@password').type(password);
cy.get('@form').submit();
cy.fixture(happy ? 'successful-login.json' : 'failed-login.json').then((json) => {
console.log(json);
cy.intercept(`${auth_url}/connect/token`, json).then(() => {
if (!happy) return;
cy.fixture('current-user.json').then((currentUser) => {
console.log(currentUser);
cy.intercept(`/users/**`, currentUser);
});
});;
});
});
My fixtures are: successful-login.json:
{
"access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjRGNEVBQzE4N0Y5QUM1MTE4NjhFNTQ5OTA5RUIzOEQxIiwidHlwIjoiYXQrand0In0.eyJuYmYiOjE2MTYwMDgxNTksImV4cCI6MTYxNjAxMTc1OSwiaXNzIjoiaHR0cHM6Ly9zeHAtZGV2ZWxvcC1pZGVudGl0eS5henVyZXdlYnNpdGVzLm5ldCIsImF1ZCI6WyJzeHAiLCJpZGVudGl0eS1zZXJ2ZXIiXSwiY2xpZW50X2lkIjoiY2xpZW50Iiwic3ViIjoiYTIzM2Q0MDgtMjVjMi00ODZhLWFlMzgtOTMzMTk5YjU2OWRkIiwiYXV0aF90aW1lIjoxNjE2MDA4MTU4LCJpZHAiOiJsb2NhbCIsInJvbGUiOiJBZG1pbmlzdHJhdG9yIiwicGVybWlzc2lvbiI6WyJ1c2VyczpyZWFkIiwidXNlcnM6d3JpdGUiXSwianRpIjoiQTRDNjREMzk0RTcyNEY3QUE1NzRFQUNEMjA2ODM4RkIiLCJpYXQiOjE2MTYwMDgxNTksInNjb3BlIjpbImlkZW50aXR5OnJlYWQiLCJpZGVudGl0eTp3cml0ZSIsInN4cDpyZWFkIiwic3hwOndyaXRlIl0sImFtciI6WyJwd2QiXX0.e-TX3u3o8UJZ9nq7nyuMFWfRyjEh55CwWQSHhfFxt677_qCu6pJ1cuHHOMjMV0lc-hTXjbe-4lZ7oOVfOZA_gByFo6mFpq8co__Npj1YpMt18LOSuewspKldffgCZQm2wIKTqSmMIQoFDRoUmAmcBsbJZIqSx4KMYBz7OfsBmdU7TeNi8bjtLcglzBxgYko7njJuC9j1EarR9BC-tjPIb0eoROclfQlPcYb05T4RRMzi3dpFExEXzFMaiMnR8_q0VOPWzeL0phFcjm-r1nVTVvrRcCtvI3GPPxr5EshT4XHcg6pmxx8BUlWXI6u1gSnWShmvXP5n87HJTCjsJh8sEQ",
"expires_in": 3600,
"token_type": "Bearer",
"scope": "identity:read identity:write sxp:read sxp:write"
}
failed-login.json
{ "error": "invalid_grant", "error_description": "invalid_username_or_password" }
And finally, current-user.json:
{
"success": true,
"failure": false,
"error": null,
"result": {
"jobTitle": null,
"image": null,
"createdBy": "00000000-0000-0000-0000-000000000000",
"updatedBy": "00000000-0000-0000-0000-000000000000",
"dateCreated": "2021-02-26T11:23:18.074899",
"dateUpdated": "2021-02-26T11:23:18.0749379",
"deleted": false,
"roles": null,
"id": "a233d408-25c2-486a-ae38-933199b569dd",
"emailConfirmed": true,
"concurrencyStamp": "0246797d-fd93-4723-a142-95d5213f9ec7",
"phoneNumber": null,
"phoneNumberConfirmed": false,
"twoFactorEnabled": false,
"lockoutEnd": "2021-03-17T16:04:59.7781333+00:00",
"lockoutEnabled": true,
"accessFailedCount": 0
},
"message": null
}
The spec file looks like this:
/// <reference types="Cypress" />
describe('login workflow', () => {
it('does not work with wront credentials', () => {
const email = '[email protected]';
const password = 'test';
cy.visit('/');
cy.login(email, password).as('loginRequest').then(() => {
cy.contains('.mat-simple-snackbar span', 'Invalid username or password.');
});
});
it('happy path test', () => {
const email = '[email protected]';
const password = 'test';
cy.visit('/');
cy.location('pathname').should('equal', '/login');
cy.login(email, password, true).as('loginRequest').then(() => {
cy.location('pathname').should('equal', '/');
});
});
});
The issue I have is that even though the tests both say the routes are being stubbed:
The actual request, isn't:
The first test passes because the username and password are incorrect, even without stubbing the response, but the second test fails:
Because it doesn't stub the response:
Does anyone know what I am doing wrong?
Upvotes: 1
Views: 1255
Reputation:
Having a new intercept set up inside the .then()
of a previous intercept seems like it might be a problem. There's nothing executing after that last intercept that would trigger it.
Since intercepts should be set up before the trigger occurs, the following should be (nearly) logically equivalent,
Cypress.Commands.add('login', (email, password, happy = false) => {
cy.intercept(`/users/**`, { fixture: 'current-user.json' });
const auth_url = Cypress.env('auth_url');
const loginFixture = happy ? 'successful-login.json' : 'failed-login.json';
cy.intercept(`${auth_url}/connect/token`, { fixture: loginFixture });
cy.get('[data-cy=email]').as('email');
cy.get('[data-cy=password]').as('password');
cy.get('[data-cy=login-form]').as('form');
cy.location('pathname').should('equal', '/login');
cy.get('@email').type(email);
cy.get('@password').type(password);
cy.get('@form').submit();
});
The only difference is the /users
intercept is set up even if the auth
intercept fails, but you are controlling that outcome anyway (with happy
), so this should produce the same result
Upvotes: 2