cypress authentication flows using social network providers
This Cypress library makes it possible to perform third-party logins (think oauth) for services such as GitHub, Google or Facebook.
It does so by delegating the login process to a puppeteer
flow that performs the login and returns the cookies for the application under test so they can be set by the calling Cypress flow for the duration of the test.
Supported identity providers:
Provider | Plugin name |
---|---|
GoogleSocialLogin | |
GitHub | TBD |
TBD | |
TBD | |
TBD |
- Call the declared task with a set of options for the social login flow interaction
- Set the cookies for the test flow with the help of
Cypress.Cookies.defaults
cy.clearCookies()
return cy.task('GoogleSocialLogin', socialLoginOptions).then(({cookies}) => {
const cookie = cookies.filter(cookie => cookie.name === cookieName).pop()
if (cookie) {
cy.setCookie(cookie.name, cookie.value, {
domain: cookie.domain,
expiry: cookie.expires,
httpOnly: cookie.httpOnly,
path: cookie.path,
secure: cookie.secure
})
Cypress.Cookies.defaults({
whitelist: cookieName
})
}
})
Options passed to the task include:
Option name | Description | Example |
---|---|---|
username | ||
password | ||
loginUrl | The URL for the login page that includes the social network buttons | https://www.example.com/login |
headless | Whether to run puppeteer in headless more or not | true |
logs | Whether to log interaction with the loginUrl website & cookie data | false |
loginSelector | A selector on the page that defines the specific social network to use and can be clicked, such as a button or a link | 'a[href="/auth/auth0/google-oauth2"]' |
postLoginSelector | A selector on the post-login page that can be asserted upon to confirm a successful login | '.account-panel' |
Install the plugin as a dependency
npm install --save-dev cypress-social-logins
Import the cypress-social-logins
plugin definition for the specific social
network login you are interested of, and declare a task that performs the
login.
Example:
const {GoogleSocialLogin} = require('cypress-social-logins').plugins
module.exports = (on, config) => {
on('task', {
GoogleSocialLogin: GoogleSocialLogin
})
}
Once the Cypress task is defined we can expose a test case that makes use of it. The task will accept an options object with the username, password and other configurations that need to be specified so that the task can navigate through the page properly.
Once the task has completed it will return the list of cookies from the new
page. Most likely that these cookies need to be set for the rest of the
sessions in the test flow, hence the example code showing the case for
Cypress.Cookies.defaults
.
describe('Login', () => {
it('Login through Google', () => {
const username = Cypress.env('googleSocialLoginUsername')
const password = Cypress.env('googleSocialLoginPassword')
const cookieName = Cypress.env('cookieName')
const socialLoginOptions = {
username,
password,
loginUrl: Cypress.env('loginUrl'),
headless: true,
logs: false,
loginSelector: 'a[href="/auth/auth0/google-oauth2"]',
postLoginSelector: '.account-panel'
}
return cy.task('GoogleSocialLogin', socialLoginOptions).then(({cookies}) => {
cy.clearCookies()
const cookie = cookies.filter(cookie => cookie.name === cookieName).pop()
if (cookie) {
cy.setCookie(cookie.name, cookie.value, {
domain: cookie.domain,
expiry: cookie.expires,
httpOnly: cookie.httpOnly,
path: cookie.path,
secure: cookie.secure
})
Cypress.Cookies.defaults({
whitelist: cookieName
})
}
})
})
})
Make sure you are providing the plugin with the username or password in the options when instantiating it. If you're passing it via environment variables then the plugin will look for these two: CYPRESS_googleSocialLoginUsername
and CYPRESS_googleSocialLoginPassword
If clicking on the login button via the selector you passed opens up the login process in a pop-up or somewhere else that is not available in a direct DOM navigation of the current window then this plugin will not be able to know about it and click there to complete the login process.
See this issue for more context: lirantal#4
Liran Tal liran.tal@gmail.com