【问题标题】:Getting error: Error while waiting for Protractor to sync with the page: {}出现错误:等待 Protractor 与页面同步时出错:{}
【发布时间】:2023-03-26 01:37:02
【问题描述】:

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

我做错了什么??

【问题讨论】:

  • 这个问题在stackoverflow上被问了几次。只需将其复制并粘贴到 google-search ...
  • 我做了-答案没有给我任何指导
  • 取决于您的项目设置。如果您的登录页面是有角度的,您需要waitForAngular 如果没有,则有例外(我将不得不再次用谷歌搜索它们,只是在阅读时瞥了一眼......现在时间不多,明天再看)祝你好运!
  • 那么我该如何使用waitForAngular
  • var ptor = protractor.getInstance(); ptor.waitForAngular();还在赶时间,这个周末不会有太多时间。希望能帮上忙,回头看看

标签: angularjs protractor angularjs-e2e


【解决方案1】:

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

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

Protractor 向您的测试公开的 browser 对象是 Protractor 的一个实例(即,如果您在 Stack Overflow 上看到带有 var ptor = protractor.getInstance(); ptor.doSomething() 的旧答案,那么您可以在这些旧答案中将 ptor 替换为 browser )。 Protractor 还将封装的 Selenium WebDriver API 公开为browser.driver。因此,如果您调用 browser.get,您正在使用 Protractor(它会等待 Angular 稳定下来),但如果您调用 browser.driver.get,您正在使用 Selenium(它不了解 Angular)。

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

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

当在页面上找不到 Angular 库时,Protractor 将失败。如果您的测试需要与非 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 语法错误。您可能需要在盲目复制和粘贴之前检查它的语法。我 然而,我对逻辑很有信心,因为它几乎是从我测试非 Angular 登录页面的 Javascript 代码中逐字复制和粘贴的。)

【讨论】:

  • 这对我没有用...您可以在以下位置查看我的代码:gist.github.com/shamoons/2970175f3c815ff7f9ca
  • @Shamoon - 我看到了你的代码,但你遇到了什么错误?它仍然是“等待量角器同步时出错”吗?因为根据我的理解(以及我自己所做的),通过使用browser.driver,您应该不会再看到“等待量角器同步”错误。还有一件事要尝试:在等待同步的测试超时之前,添加browser.ignoreSynchronization = true; 看看是否有影响。
  • ng-learn.org/2014/02/… 一个人的方法,它广泛使用browser.ignoreSynchronization = true
  • 请注意,我根本没有使用过ignoreSynchronization(坚持使用browser.driver 对我有用),所以如果这条路上有杂草,我不知道。我怀疑的一件事是,在运行 确实 依赖于 Angular 的测试之前,您可能必须将其设置回 false;我在上面链接的文章最终在每个测试前都添加了 browser.ignoreSynchronization = (true/false) 声明,使用 onPreparebeforeEach 使其更容易一些。
  • 精彩回答@rmunn 感谢您提供有关 Protractor / Selenium 的详细背景。.. 肯定会帮助其他人解决与此问题无关的问题.. 像我一样!干杯
【解决方案2】:

如果您需要使用 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/复制了答案

【讨论】:

  • 请务必注意,如果您在确实具有 Angular 的页面上遇到此错误,这就是答案。如果这个问题似乎是这种情况,您也在将 Protractor 用于没有 Angular 的页面,那么接受的答案就是您需要的答案。
【解决方案3】:

我也遇到了这个错误,但在我的情况下,我的测试正在运行,并且在扩展它们之后发生了这个错误。

事实证明,如果您尝试在描述块而不是测试用例中调用 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();
   });
});

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

【讨论】:

    【解决方案4】:

    不确定我在哪里找到了给出这个答案的部分,但这对我有用:

    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");
      });
    });
    

    【讨论】:

      【解决方案5】:

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

      我检查了这个问题只发生在无头的 Firefox 中,并且在无头的 Chrome 中运行良好。从 Firefox v69 升级到最新版本(当前为 v72)解决了这个问题。我不知道为什么这个问题开始显现,以及它是如何通过升级解决的,但我认为这些信息可能对其他人有用。

      【讨论】:

        猜你喜欢
        • 2016-01-12
        • 2018-12-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-16
        • 1970-01-01
        相关资源
        最近更新 更多