执行量角器测试时“失败:等待量角器与页面同步时出错”

Posted

技术标签:

【中文标题】执行量角器测试时“失败:等待量角器与页面同步时出错”【英文标题】:"Failed: Error while waiting for Protractor to sync with the page" while executing Protractor tests 【发布时间】:2019-10-03 14:33:57 【问题描述】:

我尝试在包含 Angular 和非 Angular 组件的 Web 应用程序上执行一些量角器测试。 我的代码如下所示:

describe("Test Name", function() 
  it("Test case", function() 
    // first execute steps on a non-Angular component
    browser.waitForAngularEnabled(false);
    // some test steps

    // then execute tests on an Angular component, which opens in a new browser tab
    browser.waitForAngularEnabled(true);
    // some more test steps
    );
);

问题是运行上述测试后,浏览器启动并立即关闭并出现以下错误:

失败:等待 Protractor 与页面同步时出错:“angularJS 可测试性和 Angular 可测试性都未定义。这可能是因为这是一个非 Angular 页面,也可能是因为您的测试 涉及客户端导航,这可能会干扰 Protractor 的引导。详情见https://github.com/angular/protractor/issues/2643”

当我从代码中删除browser.waitForAngularEnabled(true);时,非Angular组件的步骤成功执行,然后在新的浏览器选项卡中打开应用程序的Angular组件,10秒内没有任何反应(没有执行任何步骤) 并且浏览器关闭并出现以下错误:

失败:等待 10007 毫秒后超时

【问题讨论】:

您的量角器版本是否 >6.0,如果不是,您的配置文件中是否声明了 SELEMIUM_PROMISE_MANAGER: false @mariobrosbb 您可能还应该添加测试步骤以帮助我们帮助您:-) 对我来说听起来像是一个异步问题。也许尝试使用 done 模式或将它们与 async\await 或 promise 链接起来。 【参考方案1】:

在与非 Angular 用户界面交互时使用 browser.ignoreSynchronization = true;,因为它使量角器不等待 Angular 承诺

browser.ignoreSynchronization = false; 后跟 browser.waitForAngular(); 与 Angular ui 交互时

【讨论】:

browser.ignoreSynchronization 已弃用 browser.waitForAngularEnabled() 是当前所需的替换【参考方案2】:

您可能应该考虑异步代码并等待承诺解决。另外,在测试函数中添加Jasmine's done parameter,让 selenium 知道测试何时结束。

可能导致此问题的另一件事是在您实际进入角度页面之前激活waitForAngularEnabled。我建议您在该调用前加上一个调用,以检查页面上的某些内容是否已经加载,这样您就知道 Angular 在等待 Angular 活动之前已准备好被量角器挂钩。

重要的是要注意,量角器会等待waitForAngularEnabled(true) 之后的下一个操作来触发检查,如果以后有人更改代码,依赖它可能会使问题不清楚。

describe("Test Name", function() 
  it("Test case", function(done) 
    // first execute steps on a non-Angular component
    browser.waitForAngularEnabled(false)
      .then(() => /* step1 */)
      .then(() => /* step2 */)
      // ...
      // ? this one is very important to make sure
      // we're in an angular page ?
      .then(() => ensurePageTitleIsVisible())
      .then(() => browser.waitForAngularEnabled(true))
      .then(() => done())
      .catch((err) => done.fail(err));
  );
);

function ensurePageTitleIsVisible() 
  return browser.wait(ExpectedConditions.visibilityOf(PAGE_TITLE_SELECTOR), jasmine.DEFAULT_TIMEOUT_INTERVAL, 'Title does not exist after timeout');

这也可能会为您提供更好的错误消息。

当然,你也可以用 async \ await 语法做同样的事情。

describe("Test Name", function() 
  it("Test case", function(done) 
    try 
      // first execute steps on a non-Angular component
      await browser.waitForAngularEnabled(false)
      await step1();
      await step2();
      // ...
      await browser.waitForAngularEnabled(true);
      done();
     catch(err) 
      done.fail(err);
    
  );
);

基本上,出现问题是因为您在 browser.waitForAngularEnabled 函数实际完成之前继续执行测试步骤。

【讨论】:

我相信在设置waitForAngularEnabled(true)之后,量角器只会在页面上有新的交互时才开始监控角度页面的稳定性,触发更改检测,所以很好(甚至可取)在非角度页面上设置waitForAngularEnabled(true),前提是您的下一个操作会将您带到角度页面。我认为您认为这是一个异步问题是正确的,OP 可能在没有意识到的情况下禁用了控制流 @DublinDev 酷!不知道:-)。但如果某些东西只适用于特定情况,我通常不喜欢使用它。如果我编写一个运行waitForAngularEnabled(true) 的测试,因为下一个操作将我带到一个角度页面,并且一个月后有人在导航之前添加一个新行来检查其他内容,它可能会在其他人不了解发生了什么的情况下中断。所以我认为我更喜欢在这样做之前确定我实际上是在一个有角度的页面中。它将使代码更清晰,更不易被以后的更改破坏 @DublinDev 为答案添加了评论 :-)

以上是关于执行量角器测试时“失败:等待量角器与页面同步时出错”的主要内容,如果未能解决你的问题,请参考以下文章

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

使用 appium 执行量角器脚本时等待异步脚本结果超时

从ng测试命令中排除量角器文件

如何在md-option中执行量角器测试

package.json执行与量角器中的其他构建工具有什么不同以便执行?

测试运行结束时未指定的量角器错误