Reputation: 14748
I'm intercepting my login and logout routes in my functional tests with Cypress. (I have to stub them because the Magic technology I'm using for authentication does NOT support a test mode for the server side SDK, yet.)
Here is the code for the routes:
import {
loginRoute,
logoutRoute,
} from 'features/user-authentication/user-authentication-api';
// ...
cy.intercept(loginRoute, request => {
request.reply({
headers: {
'Set-Cookie': `magic-auth-token=${Cypress.env(
'validMagicAuthToken',
)}`,
},
statusCode: 200,
body: { success: true },
});
});
cy.intercept(logoutRoute, request => {
request.reply({
headers: {
'Set-Cookie': `magic-auth-token=; Max-Age=-1; Path=/`,
},
statusCode: 302,
});
});
I'm mimicking the original route's behavior, where they add and remove cookies. The login route's stub works perfectly. However, the stub for the login route does not.
The original logout route looks like this:
import { parse, serialize } from 'cookie';
// ...
function removeTokenCookie<T>(response: NextApiResponse<T>) {
const cookie = serialize(TOKEN_NAME, '', {
maxAge: -1,
path: '/',
});
response.setHeader('Set-Cookie', cookie);
}
const logoutHandler: NextApiHandler = async (request, response) => {
const session = await getSession(request);
if (session) {
await magic.users.logoutByIssuer(session.issuer);
}
removeTokenCookie(response);
response.writeHead(302, { Location: '/' });
response.end();
};
How can I remove the cookies using the logout route's stub? For some reason the cookie does NOT get removed when I set the headers as I did above.
Upvotes: 2
Views: 1839
Reputation: 23463
Cypress has the clearCookie command, but it can't be used inside the intercept callback.
cy.intercept(logoutRoute, request => {
cy.clearCookie('magic-auth-token')
request.reply...
})
This is the error
CypressError
Cypress detected that you returned a promise from a command while also invoking one or more cy commands in that promise.
The cy command you invoked inside the promise was: cy.clearCookie()
Looking at the source code for clearCookie, it boils down to the internal command
Cypress.automation('clear:cookie', { name: <cookie-name> })
While it's an internal command, it's use has been demo'd here Cypress Automation and here Testing an Application in Offline Network Mode
The type definitions were added recently Add type for Cypress.automation #7573
Here's a proof of concept,
it('clears cookies in intercept', () => {
cy.setCookie('magic-auth-token', '1234')
cy.getCookies().should('have.length', 1)
cy.intercept('*', (req) => {
Cypress.automation('clear:cookie', { name: 'magic-auth-token' })
})
cy.visit('http://example.com').then(() => {
// after the request has been intercepted
cy.getCookies().should('have.length', 0)
})
})
Upvotes: 3