Cypress integration testing with amazon cognito

Viewed 2005

I am trying to create an e2e testing for our client app which uses amazon cognito for login. I am trying to follow the aws documentation on logging in. I am getting a network error. I am not sure if this is the right way. I am getting a network error because probably it's passing thru our VPN. How should I resolve this using the aws library? Below is the sample code I used which I got from AWS documentation.

var authenticationData = {
        Username : 'username',
        Password : 'password',
    };
    var authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(authenticationData);
    var poolData = { UserPoolId : 'us-east-1_ExaMPle',
        ClientId : '1example23456789'
    };
    var userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
    var userData = {
        Username : 'username',
        Pool : userPool
    };
    var cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
    cognitoUser.authenticateUser(authenticationDetails, {
        onSuccess: function (result) {
            var accessToken = result.getAccessToken().getJwtToken();

            /* Use the idToken for Logins Map when Federating User Pools with identity pools or when passing through an Authorization Header to an API Gateway Authorizer */
            var idToken = result.idToken.jwtToken;
        },

        onFailure: function(err) {
            alert(err);
        },

});
2 Answers

I'm also using VPN and the following worked for me. I added different login commands to commands.js file to handle user roles such as Admin, etc.

Cypress.Commands.add('loginAdmin', (overrides = {}) => {
Cypress.log({
  name: 'loginAdminViaCognito',
});  

var authenticationData = {
    Username: 'AdminUsername',
    Password: 'AdminPassword'
};
return doLogin(authenticationData);
});

I have generic doLogin function in the same file that I call and pass different authentication data

function doLogin(authData){
var poolData = {
    UserPoolId: 'aws-cognito-userpoolid', 
    ClientId: 'aws-cognito-app-clientid',
};
   
var userPool = new CognitoUserPool(poolData);
var cognitoUser = new AmazonCognitoIdentity.CognitoUser({Username: authData.Username, Pool: userPool});
       
const authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails(
    authData
);

return new Promise((resolve, reject) =>
    cognitoUser.authenticateUser(authenticationDetails, {
    onSuccess: function(result){ 
        let token = result.getIdToken().getJwtToken();
        //let accessToken = result.getAccessToken().jwtToken;
        //let refreshToken = result.getRefreshToken().token;
        
        resolve(token);
    },
    onFailure: function(err){            
        reject("Unable to get token. " + JSON.stringify(err));
    }
})
);}

Solutions using amazon-cognito-identity-js package only work if you don't have a client secret:

When creating the App, the generate client secret box must be unchecked because the JavaScript SDK doesn't support apps that have a client secret. https://www.npmjs.com/package/amazon-cognito-identity-js

My solution was instead to start my Cypress test by directly visiting the Cognito Login Page using cy.visit, entering my credentials, and then submit using redirect_uri to localhost works for some reason:

cy.visit('https://xxx.amazoncognito.com/login?client_id=xxx&response_type=token&scope=aws.cognito.signin.user.admin+email+openid+phone+profile&redirect_uri=https://127.0.0.1:8000/signedin')
cy.get('input[name=username]:visible').type('xxx')
cy.get('input[name=password]:visible').type('xxx')
cy.get('input[name=signInSubmitButton]:visible').click()
// real test starts here...

I don't understand why it works this way, but it does. The last click redirects me to my redirect_uri with the correct tokens.

EDIT: regrettably this also requires setting "chromeWebSecurity": false in cypress.json.

Related