Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
432 views
in Technique[技术] by (71.8m points)

oauth - Protractor syncing to an Angular page after redirection to Auth0 non-Angular page

I have an Angular web app that uses Protractor for e2e tests. I recently added OAuth0 authentication. I disable Angular synchronisation before redirection to the non-Angular OAuth0 page using await browser.waitForAngularEnabled(false) and that works fine. However I cannot reenable Angular synchronisation using await browser.waitForAngularEnabled(true) again for the rest of that spec file test suite or I get the infamous protractor timeout errors. I'd like to re-enable Angular synchronisation as otherwise I have to use expected conditions, waits and sleeps to ensure follow-on pages are loaded and that can result in intermittent errors.

I have read all the questions and answers and have tried all the obvious - reloading the page, getting a new page, waits, long sleeps, etc, etc.

So my question is quite specific rather than looking for suggestions - does anyone understand the mechanism Protractor uses to sync with Angular pages and do you know whether it possible or not for Angular to resync after a redirection out to, and back from, a non Angular page, i.e. am I wasting my time looking for a fix. I read up a little on the mechanism - it loads a script to be run on the page but I'm unsure why that can't be loaded again when I do a browser.get{'/') after returning from the auth0 redirection.

Note that I can leave Angular synchronisation disabled and can get things to work so I am not asking for advice on just how to get things working. If you have faced the specific problem and come up with a fix I'd love to hear it.

Any help appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Answer - yes you can reenable angular in protractor. However, protractor doesn't always work with angular apps. So just make sure protractors synchronization will be working as it should with your app AND the page is ready for this.

First, manually open the app, and get authorized. Then in console run getAllAngularTestabilities(). If this command in not available, protractor can't work with angular. If the command is successful, take a look at returned object, specifically at hasPendingMacrotasks and hasPendingMicrotasks properties of obj[0]._ngZone. If any of them is true, protractor can't work with this page. If both of them are false then you can proceed to the next step

Now, when you now the page can talk to protractor with browser.waitForAngularEnabled(true) you need to implement the following method for your tests

let login = async function (username, password) {
  await browser.waitForAngularEnabled(false);
  await browser.get(url);
  await $usernameInput.sendKeys(username);
  await $passwordInput.sendKeys(password);
  await $loginButton.click();
  // MOST IMPORTANTLY, YOU HAVE TO WAIT UNTIL YOUR APP FULLY LOADED
  await browser.wait(
    // whatever you need to wait for,
    timeout,
    'failure message'
  );
  // AND FINALLY
  await browser.waitForAngularEnabled(true);
}

I mean you don't have to have this method, I just showed you the order of actions you have to follow to achieve your results.

Basically, the point is, when you login, make sure the non-angular login page is gone, and your angular page is fully loaded before reenabling waiting for angular.

Two approaches you could use:

  • wait for all key elements to be present
  • or write a function which will be returning return !obj[0]._ngZone.hasPendingMacrotasks && !obj[0]._ngZone.hasPendingMicrotasks and pass it to the browser.wait

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...