获取错误:等待Protractor与页面同步时出错:{}

时间:2014-05-13 14:51:57

标签: angularjs protractor angularjs-e2e

我的e2e.conf.coffee文件是:

exports.config =
  baseUrl: 'http://localhost:9001'
  specs: [
    'e2e/**/*.coffee'
  ]

  framework: 'jasmine'

我的节点项目正在运行并侦听端口9001。

我的测试是:

describe 'Happy Path', ->
  it 'should show the login page', ->
    console.log browser

    expect(browser.getLocationAbsUrl()).toMatch("/view1");
  it 'should fail to login', ->
    setTimeout ->
      console.log "FAIL!"
    , 1200

我得到的错误是:

Failures:

  1) Happy Path should show the login page
   Message:
     Error: Error while waiting for Protractor to sync with the page: {}
   Stacktrace:
     Error: Error while waiting for Protractor to sync with the page: {}
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
==== async task ====
WebDriver.executeScript()
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
==== async task ====
Asynchronous test function: it("should show the login page")
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>
    at <anonymous>==== async task ====

我做错了什么?

5 个答案:

答案 0 :(得分:31)

(非常)简短版本:使用browser.driver.get代替browser.get

更长的版本: Protractor基本上是Selenium及其Javascript WebDriver代码的包装器。量角器添加代码等待Angular到#34;安定下来&#34; (在完成测试代码之前,完成通过其$ digest循环)。但是,如果您的页面上没有Angular,那么Protractor将永远等待#34; (实际上直到它超时)等待Angular解决。

Protractor向您的测试公开的browser对象是Protractor的一个实例(例如,如果您在使用var ptor = protractor.getInstance(); ptor.doSomething()的Stack Overflow上看到旧答案,那么您可以将ptor替换为{在那些旧答案中{1}}。 Protractor还将包装的Selenium WebDriver API公开为browser。所以,如果你打电话给browser.driver,你就会使用量角器(它会等待Angular安定下来),但是如果你打电话给browser.get,你就会使用Selenium(它没有了解Angular)。

大多数情况下,您将测试Angular页面,因此您希望使用browser.driver.get来获得Protractor的好处。但是,如果您的登录页面根本不使用Angular,那么您应该在测试登录页面的测试中使用browser.get而不是browser.driver.get。请注意,在测试的其余部分中,您还需要使用Selenium API而不是Protractor API:例如,如果您有一个HTML输入元素,其id =&#34; username&#34;在您网页的某个位置,您希望使用browser.get代替browser.driver.findElement(by.id('username'))来访问它。

有关更多示例,请参阅量角器测试套件中的this example(如果前一个测试套件消失,请尝试this link)。另见the Protractor docs哪个州:

  

当在页面上找不到Angular库时,量角器将失败。如果您的测试需要与非角度页面进行交互,请使用element(by.model('username'))直接访问webdriver实例。

示例代码:在上面的登录测试中,您可能希望执行以下操作:

browser.driver

(注意事项:我没有完成很多CoffeeScript,我完全有可能在上面的代码中出现了CoffeeScript语法错误。您可能需要在盲目复制和粘贴之前检查其语法然而,我 am 对逻辑充满信心,因为它几乎逐字地从我测试非Angular登录页面的Javascript代码中复制和粘贴。)

答案 1 :(得分:8)

如果您需要使用browser.get并收到此错误, 问题很可能是量角器配置文件中的rootElement属性。

默认情况下,Protractor假定ng-app声明位于BODY元素上。但是,在我们的例子中,它可以在DOM中的其他地方声明。所以我们必须将该元素的选择器分配给rootElement属性:

// rootElement: 'body', // default, but does not work in my case
rootElement: '.my-app', // or whatever selector the ng-app element has

对应的HTML:

<div ng-app="myApp" class="my-app">

我复制了http://www.tomgreuter.nl/tech/2014/03/timing-errors-with-angular-protractor-testing/

的答案

答案 2 :(得分:3)

我也遇到了这个错误,但在我的情况下,我的测试工作正常,扩展后发生了这个错误。

如果您尝试在describe块中调用getText()而不是测试用例,则可能会发生此错误。我的设置如下:

describe('Test Edit Functionality', function() {
    var testEntry = $$('.list-entry').first(),
        testEntryOldName = testEntry.getText();

   it('Should keep old name if edit is aborted', [...]);
});

导致错误Error while waiting for Protractor to sync with the page: {}

我通过将分配移动到beforeEach-block

来修复它
describe('Test Delete Functionality', function() {
    var testEntry = $$('.list-entry').first(),
        testEntryOldName;

   beforeEach(function() {
        testEntryOldName = testEntry.getText();
   });
});

或者,可能更好,将它分配到您需要此值的特定测试用例中(如果您根本不需要它)。

答案 3 :(得分:1)

我不确定在哪个地方拿到了这个答案,但这对我有用:

  1. class='ng-app'添加到包含您应用的元素。
  2. <div ng-app="myApp" ng-controller="myController" class="ng-app"></div>
    
    1. rootElement添加到您的protractor.conf
    2. exports.config = {
        specs: ['your-spec.js'],
        rootElement: ".ng-app"
      };
      
      1. 使用browser.driver.get而不是browser.get
      2. describe('foobar element', function() {
          it('should be "baz" after view is initialized', function() {
          browser.driver.get('http://localhost/view');
        
            var inputBox = $('input[name=foobar]');
            expect(inputBox.getAttribute('value')).toEqual("baz");
          });
        });
        

答案 4 :(得分:0)

几天前我在CT上收到了这个问题。我的测试在3天前运行良好,但是随后出现了量角器同步错误,并且无法解决此处和https://github.com/angular/protractor/issues/2643处提供的任何解决方案/黑客问题。

我检查了此问题仅在无头的Firefox中发生,并且在无头的Chrome上工作正常。从Firefox v69升级到最新版本(当前为v72)解决了该问题。我不知道为什么这个问题开始显现出来,以及如何通过升级解决,但是对于我值得考虑的问题,我认为此信息可能对其他人有用。