21

I've got an Angular app that requires authentication with Google, granting of some scopes, etc, and I'm trying to set up automatic e2e tests for it. I have protractor working well for me in general, but when we get to the google auth page, login, and get redirected, protractor fails the test because "document unloaded while waiting for result."

Is there a tool or technique I can use to authenticate to a development google account beforeEach test?

If I could just get the framework to hold on for a second while plain-old webdriver drives the login, and only really activate the angular stuff after I get to my target page, that would be perfect!

4

3 回答 3

21

关键是使用browser.driver.get而不是browser.get,并在browser.driver.sleep(someMilliseconds)使用特定于角度的命令之前让角度加载到您的最终目的地。

这是我的工作量角器规范,它首先授权给谷歌,然后计算转发器中的项目:

it('allows the user to add new slides', function () {
    browser.driver.get('http://localhost:3000/editor/?state=%7B"action":"create"%7D');

    // at this point my server redirects to google's auth page, so let's log in
    var emailInput = browser.driver.findElement(by.id('Email'));
    emailInput.sendKeys('user@googleappsdomain.com');

    var passwordInput = browser.driver.findElement(by.id('Passwd'));
    passwordInput.sendKeys('pa$sWo2d');  //you should not commit this to VCS

    var signInButton = browser.driver.findElement(by.id('signIn'));
    signInButton.click();

    // we're about to authorize some permissions, but the button isn't enabled for a second
    browser.driver.sleep(1500);

    var submitApproveAccess = browser.driver.findElement(by.id('submit_approve_access'));
    submitApproveAccess.click();

    // this nap is necessary to let angular load.
    browser.driver.sleep(10000);

    // at this point the protractor functions have something to hook into and 
    // will work as normal!
    element(by.id('new-slide-dropdown-trigger')).click();
    element(by.id('new-text-slide-trigger')).click();

    var slideList = element.all(by.repeater('slide in deck.getSlides()'));
    slideList.then(function(slideElements) {
        expect(slideElements.length).toEqual(1);
    });

});
于 2014-01-07T01:50:57.630 回答
8

我有一个 Google Auth 页面对象(如下),它为我完成了整个工作。

这里的关键是“isAngularSite(false);” 如果我们进入“角度”或“非角度”网站,功能女巫会指示 webdriver。(下面的实现)。

/* global element, browser, by */

'use strict';

var GOOGLE_USERNAME = 'my.account@google.com';
var GOOGLE_PASSWORD = 'password';
var ec = protractor.ExpectedConditions;

var Google = function () {
  this.emailInput = element(by.id('Email'));
  this.passwordInput = element(by.id('Passwd'));
  this.nextButton = element(by.id('next'));
  this.signInButton = element(by.id('signIn'));
  this.approveAccess = element(by.id('submit_approve_access'));

  this.loginToGoogle = function () {
    var self = this;

    /* Entering non angular site, it instructs webdriver to switch 
       to synchronous mode. At this point I assume we are on google
       login page */ 
    isAngularSite(false); 
    this.emailInput.sendKeys(GOOGLE_USERNAME);
    this.nextButton.click();

    this.passwordInput.isPresent().then(function () {
      browser.wait(ec.visibilityOf(self.passwordInput), BROWSER_WAIT).then(function () {
        self.passwordInput.sendKeys(GOOGLE_PASSWORD);
        self.signInButton.click();
        browser.wait(ec.elementToBeClickable(self.approveAccess), BROWSER_WAIT).then(function () {
          self.approveAccess.click();
          /* Now we are being redirected to our app, switch back to
             async mode (page with angular) */
          isAngularSite(true);
        });
      });
    });
  }
}

module.exports = new Google();

--- 把它扔进 protractor.conf.js

onPrepare: function () {
    global.isAngularSite = function (flag) {
      console.log('Switching to ' + (flag ? 'Asynchronous' : 'Synchronous') + ' mode.')
      browser.ignoreSynchronization = !flag;
    },
    global.BROWSER_WAIT = 5000;
  }

--- 这就是你将如何使用它:

it('should login though google', function(done) {
    mainPage.loginBtn.click().
    then(function () {
      loginPage.connectWithGoogleBtn.click();
      googlePage.loginToGoogle();
      browser.wait(mainPage.userName.isPresent()).
      then(function () {
        expect(mainPage.userName.getText()).
        toEqual('my.account@google.com');
        done();
      });
    });
  });
于 2015-11-20T16:41:41.780 回答
1

您应该使用waitForAngularEnabled量角器启用/禁用等待 Angular 任务。默认情况下,它将启用。您可以使用以下内容:

// do things on your Angular application
// go to external oauth page

waitForAngularEnabled(false)

// login on oauth page and redirect to your Angular application

waitForAngularEnabled(true)
browser.get('/home') // this is a page from your Angular application

waitForAngularEnabled返回一个承诺。在加载 Angular 页面之前,该browser.get函数会一直阻塞。

于 2020-05-24T19:12:51.507 回答