收到错误:等待量角器与页面同步时出错:{}

问题描述 投票:8回答:5

我的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 ====

我在做什么错?

angularjs protractor angularjs-e2e
5个回答
32
投票

(非常简短的版本:使用browser.driver.get而不是browser.get

更长的版本:量角器基本上是Selenium及其Javascript WebDriver代码的包装。量角器添加代码以等待Angular“安顿下来”(即完成其$ digest循环),然后继续测试代码。但是,如果您的页面上没有Angular,则量角器将“永远”(实际上直到超时)等待Angular稳定。

[量角器]暴露给测试的browser对象是量角器的一个实例(即,如果在堆栈溢出中看到的旧答案为var ptor = protractor.getInstance(); ptor.doSomething(),则可以在这些旧答案中将ptor替换为browser) 。量角器还将封装的Selenium WebDriver API公开为browser.driver。因此,如果调用browser.get,则说明使用了量角器(它将等待Angular稳定下来),但是,如果调用browser.driver.get,则说明使用的是Selenium(对Angular不了解)。

大多数时候,您将测试Angular页面,因此,您将需要使用browser.get来获得Protractor的好处。但是,如果您的登录页面根本不使用Angular,则在测试登录页面的测试中应使用browser.driver.get而不是browser.get。请注意,在其余测试中,您还需要使用Selenium API而不是Protractor API:例如,如果您的HTML输入元素在页面中某处具有id =“ username”,用browser.driver.findElement(by.id('username'))而不是element(by.model('username'))访问它。

[有关更多示例,请参阅Protractor测试套件中的this example(如果先前的版本消失了,请尝试this link)。另请参见the Protractor docs哪个状态:

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

示例代码

:在上面的登录测试中,您需要执行以下操作:
describe 'Logging in', ->
  it 'should show the login page', ->
    browser.driver.get "http://my.site/login.html"
    // Wait for a specific element to appear before moving on
    browser.driver.wait ->
      browser.driver.isElementPresent(by.id("username"))
    , 1200
    expect(browser.driver.getCurrentUrl()).toMatch("/login.html");
  it 'should login', ->
    // We're still on the login page after running the previous test
    browser.driver.findElement(by.id("username")).sendKeys("some_username")
    browser.driver.findElement(by.id("password")).sendKeys("some_password")
    browser.driver.findElement(by.xpath('//input[@type="submit"]')).click()

((注意:我没有做太多的CoffeeScript,并且完全有可能在上面的代码中犯了CoffeeScript语法错误。您可能想在盲目复制和粘贴之前检查其语法。我am] >,但是对逻辑充满信心,因为它几乎是逐字逐句地从我的Java代码(用于测试非Angular登录页面)中复制并粘贴的。)

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

默认情况下,量角器假定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/复制了答案

我也收到此错误,但就我而言,我的测试正在正常进行,并且在扩展它们之后发生了此错误。

原来,如果您尝试在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();
   });
});

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

不确定目前我在哪里整理出这个答案,但这对我有用:

  1. class='ng-app'添加到包含您的应用程序的元素。
<div ng-app="myApp" ng-controller="myController" class="ng-app"></div>
  1. rootElement添加到您的protractor.conf
exports.config = {
  specs: ['your-spec.js'],
  rootElement: ".ng-app"
};
  1. 使用browser.driver.get而不是browser.get
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");
  });
});

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

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


8
投票

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


3
投票

我也收到此错误,但就我而言,我的测试正在正常进行,并且在扩展它们之后发生了此错误。


1
投票

不确定目前我在哪里整理出这个答案,但这对我有用:

  1. class='ng-app'添加到包含您的应用程序的元素。

0
投票

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

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

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