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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了量角器超时等待存在的元素相关的知识,希望对你有一定的参考价值。

我在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('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>

“原始”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.
答案

我想我明白了。出于某种原因,在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('test@test.com');

    });
});

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

另一答案

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

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

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

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 '));
      });
另一答案
browser.ignoreSynchronization = true;

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

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

getPageTimeout: 50000
另一答案

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

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

    // Your instructions to select and tests DOM elements

});
另一答案

不推荐使用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');

 });
});
另一答案

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

另一答案

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

以上是关于量角器超时等待存在的元素的主要内容,如果未能解决你的问题,请参考以下文章

错误超时等待量角器在 11 秒后与页面同步

量角器:失败:超时等待异步角度任务在11秒后完成

量角器+黄瓜等待和超时而不执行完整测试

等待元素在量角器中可见

Stack:WebDriverError:元素不可交互-量角器e2e

将一个角度应用程序导航到另一个角度应用程序时量角器超时错误