Oidc-client-js: Testing with Protractor and Angular2 dosn't work after authorization

Created on 7 Mar 2017  路  7Comments  路  Source: IdentityModel/oidc-client-js

Hello,

We have a similar problem as described in the issue #244.
We used "angular-oauth2-oidc" npm package for authorization. With this package the protractor tests ran correctly. Now we use "oidc-client" npm package for authorization. With this package the test shows following error message after autorization:

  • Failed: Timed out waiting for asynchronous Angular tasks to finish after 11 seconds. This may be because the current page is not an Angular application.

This problem occurrs after calling "signinRedirectCallback" method.

In issue #244 is the solution to use a NgZone. The solution is not really appropriate for our application.
Does anyone have another solution for this problem?

Thanks.

question

Most helpful comment

The way I'm using the OIDC client is:

  • login on the identity server
  • redirect from the identity server to the app's /auth route
  • process the token and redirect back to the base route ('/')

In the test, I initiate that log in process and have protractor wait for the /auth route to process the token before continuing with the test. This method helped me a lot:

    /**
     * Wait for a page to load
     * @param {string} navToOrFrom the page that we're waiting to navigate to or from
     * @param {boolean} navTo true = wait to navigate to the page, false = wait to navigate from the page
     */
    public waitForPageToLoad(navToOrFrom: string, navTo: boolean) {
        browser.ignoreSynchronization = false;
        browser.wait(function() {
            const deferred = promise.defer();
            browser.getCurrentUrl().then((url) => {
                // true = url match, false = no match
                const urlTest = new RegExp(navToOrFrom).test(url);
                deferred.fulfill(navTo ? urlTest : !urlTest);
            });
            return deferred.promise;
        });
        browser.ignoreSynchronization = true;
    }

So in the tests, I do login with the identity server, then when that promise is resolved I use waitForPageToLoad('/auth', false); to wait for the /auth route to process the token and redirect back to the home page. This is all in a method called doLogin(), which returns a promise that resolves after login has completed and the id token has been processed.

In the tests, callers call this doLogin() method, then continue the test after doLogin has resolved, i.e.

doLogin().then(() => {
  // continue with the test
});

All 7 comments

I'm not sure if there's much I can do from within the library to help your testing scenario. Testing browser redirects is tricky from an automated testing tool that needs to own the browser window to execute the tests. Does the tooling have any additional support for testing scenarios where the main window needs to redirect away and then redirect back into the app?

The way I'm using the OIDC client is:

  • login on the identity server
  • redirect from the identity server to the app's /auth route
  • process the token and redirect back to the base route ('/')

In the test, I initiate that log in process and have protractor wait for the /auth route to process the token before continuing with the test. This method helped me a lot:

    /**
     * Wait for a page to load
     * @param {string} navToOrFrom the page that we're waiting to navigate to or from
     * @param {boolean} navTo true = wait to navigate to the page, false = wait to navigate from the page
     */
    public waitForPageToLoad(navToOrFrom: string, navTo: boolean) {
        browser.ignoreSynchronization = false;
        browser.wait(function() {
            const deferred = promise.defer();
            browser.getCurrentUrl().then((url) => {
                // true = url match, false = no match
                const urlTest = new RegExp(navToOrFrom).test(url);
                deferred.fulfill(navTo ? urlTest : !urlTest);
            });
            return deferred.promise;
        });
        browser.ignoreSynchronization = true;
    }

So in the tests, I do login with the identity server, then when that promise is resolved I use waitForPageToLoad('/auth', false); to wait for the /auth route to process the token and redirect back to the home page. This is all in a method called doLogin(), which returns a promise that resolves after login has completed and the id token has been processed.

In the tests, callers call this doLogin() method, then continue the test after doLogin has resolved, i.e.

doLogin().then(() => {
  // continue with the test
});

@Sean-Brown so you have protractor tests working? That's cool and I'm jealous that I don't know how that works :)

@AlexanderWuest does @Sean-Brown's feedback help?

Hello Sean,
Thank you for your answer.
Unfortunately it does not work. I've changed a couple of code lines so it works:

function waitForPageToLoad(navToOrFrom: string): any {
     const deferred = promise.defer();
     browser.wait(function () {
        return browser.getCurrentUrl().then((url) => {
             return RegExp(navToOrFrom).test(url);
        });
    }, 5000).then(() => {
    deferred.fulfill(true);
  });
  return deferred.promise;
}
function doLogin(myPage: UserAdminPage): any {
  const deferred = promise.defer();
  myPage.navigateToAddress("XXXXXXXXXXXXXXX/home");

  browser.getCurrentUrl().then((strurl) => {
    expect(strurl).toEqual("XXXXXXXXXXXXXXX/home");
    myPage.clickElement(LoginLink);
    waitForPageToLoad("identityservice").then(() => {

      browser.ignoreSynchronization = true;
      myPage.writeUserName("Bob");
      myPage.writePassword("12345");
      myPage.clickElement(LoginButton);
      browser.ignoreSynchronization = false;

      waitForPageToLoad("XXXXXXXXXXXXXXX").then(() => {
        deferred.fulfill(true);
      });
    });
  });
  return deferred.promise;
};
  fit("Correct login", () => {
     doLogin(myPage).then(() => {
     expect(myPage.getElementText(HomeButton1)).toEqual("Home");

    });
  });

The message is still coming:

sorry, I have closed the issue by mistake. It still does not work.

Unless some protractor guru comes along and helps out, I won't be able to do much. I'll close but if you find out what changes would need to be made to the library to help, feel free to reopen.

If you make your project public I can take a look at it

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pawepaw picture pawepaw  路  3Comments

pottabathini picture pottabathini  路  5Comments

baoduy picture baoduy  路  4Comments

arnaldo-infinite picture arnaldo-infinite  路  4Comments

rmja picture rmja  路  3Comments