量角器超时等待存在的元素

问题描述 投票:2回答:7

我在Angular 2应用程序中开始一些测试,在第一次测试中我遇到了一些问题。

我想测试登录页面,所以我想填写电子邮件。这是我的测试代码:

describe('login page', function() {
    it('should login', function() {

        browser.get('http://localhost:3000/#/login');

        element(by.css('.form-control.ng-pristine.ng-valid.ng-untouched')).sendKeys('[email protected]');

    });
});

我的渲染HTML代码是:

<form class="login-form mt-lg ng-pristine ng-valid ng-touched">
   <!--template bindings={}-->
   <!--template bindings={}-->
   <div class="form-group">
     <input class="form-control ng-pristine ng-valid ng-touched" name="email" placeholder="E-mail" type="email">
   </div>
   <div class="form-group">
     <input class="form-control ng-untouched ng-pristine ng-valid" name="password" placeholder="Password" type="password">
   </div>
 <div class="clearfix">
    <div class="btn-toolbar float-xs-right m-t-1">
     <button class="btn btn-primary btn-sm" type="submit">Log in</button>
    </div>
    <div class="float-xs-left m-t-1">
      <a class="mt help-block">Forgot your password?</a>
    </div>
  </div>
</form>

“原始”HTML代码是:

<form class="login-form mt-lg" (ngSubmit)="login($event)">
  <div *ngIf="error" class="alert alert-danger">{{error}}</div>
  <div *ngIf="info" class="alert alert-info">{{info}}</div>
  <div class="form-group">
    <input type="email" class="form-control" name="email" placeholder="E-mail" [(ngModel)]="user.email" #email="ngModel">
  </div>
  <div class="form-group">
    <input class="form-control" name="password" type="password" placeholder="Senha" [(ngModel)]="user.password" #password="ngModel">
  </div>
  <div class="clearfix">
    <div class="btn-toolbar float-xs-right m-t-1">
      <button [disabled]="loading" class="btn btn-primary btn-sm" type="submit">Entrar</button>
    </div>
    <div class="float-xs-left m-t-1">
      <a class="mt help-block" (click)="modal.show()">Esqueceu sua senha?</a>
    </div>
  </div>
</form>

当我执行测试时,浏览器打开,页面完全加载,但随后超时:

Failed: Timed out waiting for asynchronous Angular tasks to finish after 11 seconds. This may be because the current page is not an Angular application. Please see the FAQ for more details: https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular
While waiting for element with locator - Locator: By(css selector, .form-control.ng-pristine.ng-valid.ng-untouched)

如果我在Chrome控制台中搜索此选择器,则返回预期元素:

document.querySelector('.form-control.ng-pristine.ng-valid.ng-untouched')

问题是当浏览器打开时我可以看到页面已满载并且输入就在那里! 11秒后(或左右)浏览器关闭并显示错误消息。我还尝试增加配置文件的超时时间:

allScriptsTimeout: 50000

但它仍然没有确定元素:

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
angularjs angular protractor
7个回答
9
投票

我想我明白了。出于某种原因,在Chrome控制台网络选项卡中有一个websocket请求为“待定”,因此显然Pratractor一直在等待此请求完成。这个请求有101个HTTP状态,我真的不知道这意味着什么但是在快速搜索之后我才知道它在Chrome控制台中被标记为“待定”。

要解决此问题,我会阻止同步:

browser.ignoreSynchronization = true;

并在配置文件中定义了超时:

allScriptsTimeout: 50000

它奏效了!

以下是最终代码的方式:

describe('login page', function() {
    it('should login', function() {

        browser.ignoreSynchronization = true;

        browser.get('http://localhost:3000/#/login');

        element(by.css('.form-control.ng-pristine.ng-valid.ng-untouched')).sendKeys('[email protected]');

    });
});

如果有人知道更好的解决方案或如何避免这个“websocket”请求,请告诉我。


1
投票

为什么不尝试按名称选择元素呢?

element(by.name('email')).sendKeys("[email protected]");
element(by.name('password')).sendKeys("mypassword");

0
投票

发生超时是因为您有两个具有相同类的元素,因此请包含以下索引

element(by.css('.form-control.ng-pristine.ng-valid.ng-untouched')[0]).sendKeys('[email protected]');

更新1:

试试这个

element(by.css('input[name=email]')).setAttribute('value','[email protected]').then((value: string) => {
            expect(value).toBe('[email protected]');
        });

更新2:

element(by.css('input[name=email]')).setAttribute('value','[email protected]').then((value: string) => {
                expect(value).toBe('[email protected]');
            });
                browser.wait(ExpectedConditions.not(
          ExpectedConditions.presenceOf(element(by.css('input[name=email]')))))
          .then(() => screenshot('received value '));
      });

0
投票
browser.ignoreSynchronization = true;

上面的代码使量角器不要等待Angular的承诺。这将在我们测试非角度网页时使用。

在您的问题中,您可以在jasmineNodeOptions中设置或增加getPageTimeout值。

getPageTimeout: 50000

0
投票

browser.get返回一个promise,以确保在选择元素之前加载DOM,你可以这样做:

browser.get(MY_URL).then(() => {

    // Your instructions to select and tests DOM elements

});

0
投票

不推荐使用browser.ignoreSynchronization。

使用...

describe('login page', function() {
it('should login', function() {

    browser.waitForAngularEnabled();

    browser.get('http://localhost:3000/#/login');

    element(by.css('.form-control.ng-pristine.ng-valid.ng-untouched')).sendKeys('[email protected]');

 });
});

0
投票

在我们的例子中,问题是超长超时。我们在16小时超时时实现了自动注释功能。每当我们执行任何动作时,量角器都会调用waitForAngular函数。 waitForAngular正在等待两件事:未完成的http请求和未完成的超时。检查您的代码。


-1
投票

使用名称或类型。你的班级名字看起来不太好。

© www.soinside.com 2019 - 2024. All rights reserved.