How to Test an .aspx Page on Sharepoint with Cypress

Viewed 839

I'm testing an .aspx web app page running AngularJS code on a Sharepoint server page. We're looking to implement Cypress testing for our page to cut down on testing times but accessing the page itself is proving difficult because Cypress needs to get through Microsoft/Azure's SSO in order to get to the page. We have an Azure app registered which is tied to the Sharepoint directory, which we're using to Authenticate the Cypress client. Our current code makes a cy.request to the token endpoint on the azure app, before getting a token, saving it to the current context, and redirecting to the page app. The initial request for a token works, we have the correct client/tenant ID and client secret. The issue is that when we try to redirect to the .aspx page, we're taken to the microsoft.login/{clientID}/authorize? page and new tabs are opened on loop until the test times out.

I've seen quite a few similar issues regarding getting past Azure's SSO, and am well aware that Cypress was not designed with Third-Party sites in mind. However given the setup of our app, its something we can't really avoid. I've looked at the recipes provided for Third-Party SSO and found it unhelpful because the page it directs to is not an .aspx page like ours is. That code was found here: https://github.com/cypress-io/cypress-example-recipes/blob/master/examples/logging-in__single-sign-on/cypress/integration/logging-in-single-sign-on-spec.js

I've also seen another page on the Cypress GitHub about this issue but again the issue was CLOSE but not exactly mine, so I'm unsure if I just misunderstood the solutions provided, or if they don't apply here. Anyway that discussion was found here:

(Other discussions I found there too) - https://xebia.com/blog/how-to-use-azure-ad-single-sign-on-with-cypress/ - https://github.com/cypress-io/cypress/issues/1489 - https://github.com/cypress-io/cypress/issues/992

I honestly feel I'm very close to the solution but just don't quite understand the theory behind it, and haven't found anyone with exact same issue, so if anyone knows what I'd need to do to get to the page to test it, it'd HUGELY help.

import AuthenticationContext from 'adal-angular';

describe('Signing in', () => {
    context('Doing stuff', function () {

        it('Navigate to main site', () => {
            const config = {
                tenant: {tenantID},
                clientSecret: {clientSecret},
                clientId: {clientId},
                redirectUri: 'https://{companyURL}.sharepoint.com/sites/{companyAPPDirectory}/index2.aspx',
            };

            const options = {
                method: 'POST',
                url: 'https://login.microsoftonline.com/{clientId}/oauth2/token',
                qs: {
                    redirectTo: 'https://https://{companyURL}.sharepoint.com/sites/{companyAPPDirectory}/index2.aspx',
                },
                redirect_uri: 'https://{companyURL}.sharepoint.com/sites/{companyAPPDirectory}/index2.aspx',
                headers: {
                    'cache-control': 'no-cache',
                    'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW',
                },
                followRedirect: true,
                form: true,
                body: {
                    grant_type: 'password',
                    response_type: 'code',
                    client_secret: config.clientSecret,
                    client_id: config.clientId,
                    username: {username},
                    password: {password},
                    scope: 'openid',
                    resource: config.clientId,
                },
            };
            const authContext = new AuthenticationContext(config);

            runWithAdal(authContext, config, options);

        });
    });
});

var doLogin = function (authContext, config, options) {
    if (
        !authContext.getCachedToken(config.endpoints.api) ||
        !authContext.getCachedToken(config.clientId)
    ) {
        cy.request(options).then((response) => {
            // Store the token and data in the location where adal expects it
            console.log(response);

            authContext._saveItem(authContext.CONSTANTS.STORAGE.IDTOKEN, response.body.access_token);
            authContext._saveItem(
                authContext.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + config.endpoints.api,
                response.body.access_token,
            );
            authContext._saveItem(
                authContext.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + config.clientId,
                response.body.access_token,
            );
            authContext._saveItem(
                authContext.CONSTANTS.STORAGE.EXPIRATION_KEY + config.endpoints.api,
                response.body.expires_on,
            );
            authContext._saveItem(
                authContext.CONSTANTS.STORAGE.EXPIRATION_KEY + config.clientId,
                response.body.expires_on,
            );
            authContext._saveItem(
                authContext.CONSTANTS.STORAGE.TOKEN_KEYS,
                [config.clientId].join(authContext.CONSTANTS.RESOURCE_DELIMETER) +
                authContext.CONSTANTS.RESOURCE_DELIMETER,
            );
            cy.visit('https://{companyURL}.sharepoint.com/sites/{companyAPPDirectory}/index2.aspx');
        });
    }
}

var runWithAdal = function (authContext, config, options) {
    //it must run in iframe to for refreshToken (parsing hash and get token)
    authContext.handleWindowCallback();

    //prevent iframe double app !!!
    if (window === window.parent || window.Cypress) {
        if (!authContext.isCallback(window.location.hash)) {
            if (
                !authContext.getCachedToken(authContext.config.clientId) ||
                (!window.Cypress && !authContext.getCachedUser())
            ) {
                doLogin(authContext, config, options);
            } else {

            }
        }
    }
}

We expect the Cypress iFrame to show the .aspx page after it reads the saved authenticated details.

The result instead is that it refreshes the page and then loads the login.microsoft/{clientID}/authorize? link in new tabs continuously. A tiny GIF of the issue

0 Answers
Related