【问题标题】:Protractor keeps waiting on finished HTTP requestsProtractor 一直在等待完成的 HTTP 请求
【发布时间】:2016-08-27 17:49:16
【问题描述】:

我有一个 RESTful API,现在我正在开发一个使用数据服务调用 API 的 angular2 应用程序。然后我想使用量角器实现端到端测试。我想从非常低的级别开始,所以我进行了测试以检查单击链接时我的组件是否存在。测试如下:

describe('my-webclient', () => {
    it('app should load', () => {
        browser.get('/');
        expect(element(by.css('my-app')).isPresent()).toBe(true);
    });

    it('app should have a top navigation', () => {
        expect(element(by.css('my-nav-top')).isPresent()).toBe(true);
    });

    it('app should have a side navigation', () => {
        expect(element(by.css('my-nav-side')).isPresent()).toBe(true);
    });

    it('app should have a content', () => {
        expect(element(by.css('my-content')).isPresent()).toBe(true);
    });

    it('app should load the overview for route "/"', () => {
        expect(element(by.css('my-overview')).isPresent()).toBe(true);
    });
});

问题是,overview 组件使用一些数据服务在ngOnInit 函数中发出HTTP 请求。然后量角器将永远阻塞,尽管 HTTP 请求很久以前就完成了。

当我监控测试时,我可以看到应用的加载方式,包括从我的 API 获取的所有数据。然后什么也没有发生,量角器最终会崩溃,说已经达到超时。

确切的错误信息是:

Failed: Timed out waiting for Protractor to synchronize with the page after 11 seconds. Please see https://github.com/angular/protractor/blob/master/docs/faq.md                                                                                                                                                            
While waiting for element with locator - Locator: By(css selector, my-app)

在 google 上搜索帮助时,我遇到了一些提示,即量角器将等待 angular 完成所有操作。嗯,这正是我想要的。当我在 chrome 的开发人员工具 (F12) 中监视网络选项卡时,应用程序加载后不久就什么也没有出现。因此,没有更多待处理的请求或任何等待量角器的东西。不过,确实如此,我只是不知道为什么。

所以,这是我的问题:在处理发出 HTTP 请求的数据服务时,我是否需要考虑一些特别的事情?或者:我可以做些什么来调试为什么量角器仍在等待超时命中。

顺便说一句,它绝对是数据服务。如果我将OverviewComponent::ngOnInit 中的所有内容都注释掉,那么测试将按照我的预期顺利通过。

【问题讨论】:

    标签: angular typescript protractor


    【解决方案1】:

    (简短回答 - 任何长时间运行的任务(超时、间隔、Promise 或 Observables)如果未正确处理,都会阻止测试。Http 会自行清理,因此可能不是您的问题。 )

    Http 很可能不是您的问题。

    Angular 2 使用区域来检测它的稳定/不稳定状态,而 Protractor 使用特定的可注入类 - Testability Class - 来确定应用程序状态。页面中所有现有 Angular2 应用程序的可测试性都暴露给 window 对象,这就是 Protractor 在 Angular 2 上保持标签的方式。

    Angular 使用区域来维护变更检测。在用户空间中,我们可以通过 NgZone 控制代码发生的位置(角度内或角度外),这对两件事很有用 - 测试和性能。任何在角度区域中运行的任务(除非我们另外指定,否则会发生这种情况)将触发更改检测,并且我们等待的任何异步任务将可测试性标记为不稳定。

    这意味着有很多因素可能会影响您应用的稳定性:

    • 在后台运行超时的管道(可能在您的特定情况下,如 here 所讨论的那样)
    • 一个组件或服务监听一个连续的异步任务:
      • 监听 Route.params observable
      • 设置重复超时或间隔
      • ...

    要解决此问题,您需要使用 NgZone 在 Angular 之外运行任务:

    this.ngZone.runOutsideAngular(() => {
      this._sub = Observable.timer(2000)
        .subscribe(() => this.ngZone.run(() => {this.content = "Loaded!"}));
    })
    

    查看工作示例 in this plunkthis talk by Julie Ralph 了解更多详情 - 她是 Protractor 背后的大脑。

    【讨论】:

    • 感谢您提供如此详尽的回答!
    【解决方案2】:

    因此,Tiagos 的回答无疑为我指明了正确的方向。我害怕这可能是我的 observables 的问题。发现它只是我用来刷新 jwt 的 window.setInterval() 后松了一口气。解决方法如下:

    constructor(private ngZone: NgZone) {
    }
    
    this.ngZone.runOutsideAngular(() => {
      Observable.interval(4 * 60 * 1000)
        .subscribe(data => {
          this.refreshJwt();
        });
    });
    

    【讨论】:

    • 您可能希望确保 this.refreshJwt()ngZone.run() 块内运行,以便正确检测到更改。
    猜你喜欢
    • 1970-01-01
    • 2020-07-22
    • 1970-01-01
    • 2021-06-04
    • 2018-07-19
    • 2017-08-08
    • 1970-01-01
    • 2017-07-04
    • 2019-05-19
    相关资源
    最近更新 更多