【问题标题】:Chai as promised eventually not waiting long enough in Protractor e2e tests against an Angular appChai 正如承诺的那样,最终在针对 Angular 应用程序的 Protractor e2e 测试中等待的时间不够长
【发布时间】:2018-02-05 05:03:09
【问题描述】:

我正在为我最新的 Angular 4 应用程序使用 Protractor 和 Chai-as-promised。我现在只有 2 个 e2e 测试。一个登录现有用户,另一个注册新用户。如果注册成功,我的注册逻辑也会登录新创建的用户。

这里是html代码:

<ul class="navbar-nav my-2 my-lg-0">
  <li *ngIf="!isAuthenticated()" class="nav-item">
    <button id="loginLink" class="btn btn-link nav-link" style="line-height: inherit" type="button" role="button" (click)="openLoginModal()">Login</button>
  </li>
  <li *ngIf="!isAuthenticated() && signupAllowed()" class="nav-item">
    <button id="signupLink" class="btn btn-link nav-link" style="line-height: inherit" type="button" role="button" (click)="openSignupModal()">Sign up</button>
  </li>
  <li *ngIf="isAuthenticated()" class="nav-item">
    <a id="logoutLink" class="nav-link" role="button" (click)="logout()">Logout</a>
  </li>
</ul>

这是 e2e 测试代码:

import { browser, by, element } from "protractor";

const expect = global[ 'chai' ].expect;

describe('Auth', () => {
  describe('login/logout', () => {
    it('should login successfully with valid username and password tuple', () => {
      // arrange
      browser.get('/');
      expect(element(by.id('loginLink')).isPresent()).to.eventually.be.true;
      element(by.id('loginLink')).click();

      // act
      element(by.id('usernameInput')).sendKeys('jeep87c');
      element(by.id('passwordInput')).sendKeys('1111');
      element(by.id('loginBtn')).click();

      // assert
      expect(element(by.id('logoutLink')).isPresent()).to.eventually.be.true;
      element(by.id('logoutLink')).click();
      expect(element(by.id('loginLink')).isPresent().to.eventually.be.true;
    });
  });

  describe('signup/logout', () => {
    it('should succeeds with unused username and matching passwords and login', () => {
      // arrange
      browser.get('/');
      expect(element(by.id('signupLink')).isPresent()).to.eventually.be.true;
      element(by.id('signupLink')).click();

      // act
      element(by.id('usernameInput')).sendKeys('test');
      element(by.id('passwordInput')).sendKeys('1111');
      element(by.id('confirmPasswordInput')).sendKeys('1111');
      element(by.id('signupBtn')).click();

      // assert
      expect(element(by.id('logoutLink')).isPresent()).to.eventually.be.true;
      element(by.id('logoutLink')).click();
    });
  });
});

如您所见,这两个测试非常相似。但是,signup/logoutexpect(element(by.id('logoutLink')).isPresent()).to.eventually.be.true; 上失败,login/logout 测试中也存在这种情况,它成功了。

我错过了什么?感觉根本不用等。但它适用于login/logout(意味着测试成功)。

对 API 的登录和注册请求都需要大约 200 毫秒才能完成。需要注意的是,当用户提交注册表单时,它会首先触发对 api 的注册请求,如果成功,然后是登录请求。所以大约需要 400 毫秒才能完成。我猜,这超出了eventuallywill poll/wait 的范围。

编辑: 上面的代码中缺少一些expect(...).to.eventually,我已修复。 作为一个仅供参考,这是断言失败:

Auth signup/logout should succeeds with unused username and matching passwords and login:

  AssertionError: expected false to be true

感觉就像是在元素实际出现在 dom 中并且断言失败之前,promise 解决了。而不是再次轮询它,直到它为真或超时。

编辑#2: 刚刚尝试了完全相同的代码,但是在执行最后两行之前等待了 5 秒,它成功通过了...

setTimeout(function() {
  expect(element(by.id('logoutLink')).isPresent()).to.eventually.be.true;
  element(by.id('logoutLink')).click();
}, 5000);

所以肯定是expect(element(by.id('logoutLink')).isPresent()).to.eventually.be.true; 承诺解决快速到错误并未能通过测试。我该如何解决这个问题?

任何帮助将不胜感激。

【问题讨论】:

    标签: angular typescript protractor chai chai-as-promised


    【解决方案1】:

    我不确定是不是这个问题造成的,但是,一旦我从以下位置更改我的注册码:

    signup() {
      this.auth.signup(signupData)
          .subscribe({
                       error: (err: any) => {},
                       complete: () => {
                         this.auth.login(new LoginData(signupData.username, signupData.password))
                             .subscribe({
                                          error: (err: any) => {},
                                          complete: () => {
                                            this.activeModal.close();
                                            this.router.navigateByUrl('/');
                                          }
                                        });
                       }
                     });
    }
    

    收件人:

    signup() {
      this.auth.signup(signupData)
          .subscribe({
                       next: (response) => this.auth.setToken(response.json().token),
                       error: (err: any) => {}, // TODO-jeep87c: Handle 403, 401 with proper UI alert and 500/404 in common handler (use username.setErrors)
                       complete: () => {
                         this.activeModal.close();
                         this.router.navigateByUrl('/');
                       }
                     });
    }
    

    测试成功。我正在使用 ng2-ui-auth 作为 AngularJs 的原始 Satellizer 的 Angular 2+ 端口。

    这可能与我如何使用这些身份验证服务的方法返回的 Obsersables 有关。

    如果有人能解释一下,我很乐意真正了解这里发生的事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多