You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Protractor中Async/Await失效,禁用Promise Manager仍报错求助

解决Protractor禁用Promise Manager后Async/Await测试报错的问题

嘿,我来帮你搞定这个问题!你遇到的报错根源是旧的ExpectedConditions和禁用Selenium Promise Manager(PM)后的Promise机制不兼容,再加上测试里的断言写法有问题,咱们一步步来修正:

1. 先搞懂报错原因

当你禁用PM后,Protractor不再使用旧的ManagedPromise,转而用原生ES6 Promise。但protractor.ExpectedConditions(也就是你代码里的EC)返回的是依赖旧PM的预期条件对象,直接传给browser.wait就会触发那个TypeError,因为它还在尝试创建已被禁用的ManagedPromise。

另外,你测试里的expect(ec.isVisible(...))写法也不对——ec.isVisible是async函数,返回的是Promise,不能直接丢给expect,得先await拿到结果再断言。

2. 修正ExpectedCondition类的isVisible方法

咱们调整expectedCondition.js,让它适配原生Promise:

const EC = protractor.ExpectedConditions;
class ExpectedCondition {
  constructor() { this.el = new objects.Element(); }
  
  async isVisible(selector) {
    // getElement是同步创建元素定位器,不需要await
    const targetElement = this.el.getElement(selector);
    // browser.wait在禁用PM后返回原生Promise,直接await等待元素可见
    await browser.wait(
      EC.visibilityOf(targetElement), 
      5000,  // 设置超时时间,按需调整
      `元素 ${selector} 在5秒内未出现`
    );
    // 返回元素实际的可见状态,方便后续断言
    return targetElement.isDisplayed();
  }
}

3. 修正测试用例里的断言写法

把测试里的expect改成先await拿到可见状态,再断言:

it('should fail to log in without credentials', async () => {
  await loginPage.submit();
  
  // 先等待元素可见,再断言状态为true
  const emailErrorIsVisible = await ec.isVisible(loginPage.selectors.login.errors.lblEmailValidation);
  expect(emailErrorIsVisible).toBe(true);
  
  const passwordErrorIsVisible = await ec.isVisible(loginPage.selectors.login.errors.lblPasswordValidation);
  expect(passwordErrorIsVisible).toBe(true);
});

4. 更可靠地禁用Promise Manager

你现在是在spec文件里设置protractor.promise.USE_PROMISE_MANAGER = false;,这可能会因为加载顺序问题导致失效。建议直接在protractor.conf.js配置文件里设置:

exports.config = {
  // ...其他配置项
  SELENIUM_PROMISE_MANAGER: false,
  // ...
}

这样能确保PM在测试启动时就被禁用,避免环境变量未正确识别的问题(也就是报错里的SELENIUM_PROMISE_MANAGER environment variable: undefined)。

5. 额外检查点

  • element.js里的getElement方法是同步的,没问题——element(by.css(...))只是创建一个元素定位器对象,实际查找元素是在调用click()/isDisplayed()等方法时才发生,所以不需要加async。
  • 确保所有异步操作都加了await,你代码里的submit()、clickElement()这些已经处理好了,这点没问题。

按上面的步骤改完后,你的Async/Await测试应该就能正常运行啦!

内容的提问来源于stack exchange,提问作者catch22

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:37:55