Authentication with email could simplify the signup process and prevent password mistakes. In the topic, we will use next-auth default email authentication method and test the workflow via cypress.
For quick start: repo
point check before cypress testing, make sure you can get the following results
- after signup with an email, a notification on the webpage
- an email notification in Mailtrap inbox
- webpage turn to login state with httpOnly cookie
cypress authentication work flow
Aim to solve the following test:
- send an email after a user signup
- check the email has been received
- make sure the email contains the link to the homepage
- click the link in email redirect to the homepage
- make sure the page turn to login state
- keep user login after page refresh
Setting up
npx yarn add cypress
-
optional
npx yarn add faker
- A user signup with an email
code .\cypress\integration\sample_spec.js
const faker = require('faker');
const randomEmail = faker.internet.email().toLowerCase();
describe('Login Test', () => {
it('Visits the test page', () => {
cy.visit('http://localhost:3000')
cy.contains('Sign in').click()
cy.url().should('include', '/api/auth/signin')
cy.get('#input-email-for-email-provider')
.type(randomEmail)
.should('have.value', randomEmail)
cy.contains('Sign in with Email').click()
cy.contains('Check your email')
});
it('should send an email containing a verification link', () => {
const inboxUrl = Cypress.env('inboxUrl')
const token = Cypress.env('Api-Token')
cy.getLastEmail().then(html => {
const link = html.match(/href="([^"]*)/)[1]
cy.expect(link).to.contains('/api/auth/callback/email')
cy.visit(link);
cy.contains(`Signed in as ${randomEmail}`)
cy.reload()
cy.contains(`Signed in as ${randomEmail}`)
//delete all mail
cy.request({
method: 'PATCH',
url: `${inboxUrl}/clean`,
headers: {
'Api-Token': token,
}
});
});
});
})
- API interacts with Mailtrap to get last mail
code .\cypress\support\commands.js
const inboxUrl = Cypress.env('inboxUrl')
const token = Cypress.env('Api-Token')
Cypress.Commands.add('getLastEmail', () => {
function requestEmail() {
return cy
.request({
method: 'GET',
url: `${inboxUrl}/messages`,
headers: {
'Api-Token': token,
},
json: true,
})
.then(({ body }) => {
if (body) {
let msgId = body[0].id
cy.request({
method: 'GET',
url: `${inboxUrl}/messages/${msgId}/body.html`,
headers: {
'Api-Token': token,
},
json: true,
}).then(({ body }) => {
if (body) { return body }
cy.wait(1000);
return requestEmail();
})
}
});
}
return requestEmail();
});
configuration
code cypress.json
- there could have network problems during the test, use "retries" to retry the test will save your time, visit cypress page for more info
{
"retries": 3
}
-
code cypress.env.json
{
"inboxUrl":"Your Mailtrap Inbox url with inboxId",
"Api-Token":"Your Mailtrap API token"
}
npx cypress open
- run sample_spec.js test
make a automatical process
npx yarn add start-server-and-test
-
npx start-server-and-test 'next dev' 3000 'cypress run'
Top comments (0)