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

时间:2017-03-10 22:25:45

标签: angularjs angular protractor

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

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

if(answersDone.Count != 2){
    NewNumber();
}else{
    //do whatever you want
}

我的渲染HTML代码是:

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('test@test.com');

    });
});

"原作" 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>

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

<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>

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

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)

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

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

但它仍然无法识别元素:

allScriptsTimeout: 50000

8 个答案:

答案 0 :(得分:9)

我想我明白了。出于某种原因,在Chrome控制台网络标签中有一个websocket请求为&#34;待定&#34;显然,Pratractor一直在等待这个要求完成。这个请求有101个HTTP状态,我真的不知道这意味着什么但是在快速搜索之后我才知道它被标记为&#34; Pending&#34;在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('test@test.com');

    });
});

如果有人知道更好的解决方案或如何避免这种情况,那么#webs; websocket&#34;请让我知道。

答案 1 :(得分:1)

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

element(by.name('email')).sendKeys("test@test.com");
element(by.name('password')).sendKeys("mypassword");

答案 2 :(得分:0)

发生超时是因为你有两个具有相同类的元素,所以包括下面的索引

element(by.css('.form-control.ng-pristine.ng-valid.ng-untouched')[0]).sendKeys('test@test.com');

更新1:

试试这个

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

更新2:

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

答案 3 :(得分:0)

browser.ignoreSynchronization = true;

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

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

getPageTimeout: 50000

答案 4 :(得分:0)

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

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

    // Your instructions to select and tests DOM elements

});

答案 5 :(得分: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('test@test.com');

 });
});

答案 6 :(得分:0)

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

答案 7 :(得分:-1)

使用名称或类型。你的课程名称看起来不太好。