【问题标题】:e2e protractor test requiring oauth authentication需要 oauth 身份验证的 e2e 量角器测试
【发布时间】:2014-01-06 21:38:07
【问题描述】:

我有一个 Angular 应用程序,需要通过 Google 进行身份验证、授予某些范围等,我正在尝试为其设置自动 e2e 测试。一般来说,我的量角器工作得很好,但是当我们进入谷歌身份验证页面、登录并被重定向时,量角器无法通过测试,因为“在等待结果时卸载了文档。”

在每次测试之前,我是否可以使用一种工具或技术来验证开发 Google 帐户?

如果我能让框架在普通的 webdriver 驱动登录时保持一秒钟,并且只有在我到达目标页面后才真正激活 angular 的东西,那将是完美的!

【问题讨论】:

    标签: angularjs oauth protractor angularjs-e2e


    【解决方案1】:

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

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

    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);
        });
    
    });
    

    【讨论】:

    • 我会在量角器测试中使用渗漏作为最后一个资源。
    • 与其在不确定的时间内休眠,不如等待DOM中的元素发生变化?
    【解决方案2】:

    我有一个 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();
          });
        });
      });
    

    【讨论】:

    • 抱歉很久才评论,但是mainPage和loginPage是什么?它们没有在任何地方定义。
    • mainPage 和 loggingPage 基本上是您在测试框架中可能拥有的页面对象......尽管您可以删除这些变量并且代码将具有类似的意义
    • 好的,那么 googlePage 变量呢 - 我如何使用第一个代码,我目前将它放在另一个文件中,该文件在规范中被调用。对吗?对于新手问题,我可能会使用聊天。
    【解决方案3】:

    您应该使用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 返回一个承诺。 browser.get 函数在加载 Angular 页面之前一直阻塞。

    【讨论】:

    • 我不知道为什么这被否决了。这可以澄清吗? demee 和 Riley Lark 发布的答案有效,但现在 waitForAngularEnabled 可用,我们应该使用它而不是睡眠计时器。将计时器设置得太高,您的测试将花费很长时间,设置得太低,您的测试可能会失败。当我们从 oauth 页面切换回来时,这个答案将立即继续测试您的 Angular 应用程序。
    猜你喜欢
    • 1970-01-01
    • 2013-04-15
    • 1970-01-01
    • 2017-12-03
    • 2023-03-22
    • 2019-12-28
    • 2017-07-28
    • 2012-06-01
    • 2015-07-30
    相关资源
    最近更新 更多