量角器异步/等待 UnhandledPromiseRejectionWarning:未处理的承诺拒绝

Posted

技术标签:

【中文标题】量角器异步/等待 UnhandledPromiseRejectionWarning:未处理的承诺拒绝【英文标题】:Protractor async/await UnhandledPromiseRejectionWarning: Unhandled promise rejection 【发布时间】:2018-10-11 17:42:08 【问题描述】:

所以我正在使用 async/await(Link) 迁移我的量角器测试。

到目前为止,在我不断遇到此问题之前,迁移有些成功。 因此,以下是我的测试步骤,然后是代码作为我正在处理的示例:

导航到特定页面 更改上下文(从学校转到高中) 获取高中房间列表 再次更改上下文(将学校更改为中学) 获取中学房间列表 比较两个列表

上述步骤的相关代码:

Test.ts

describe("Update room list based on changing context values", () => 
  let page: HelperClass;
  let highSchoolRoomNameList: string[] = [];
  let middleSchoolRoomNameList: string[] = [];

  beforeAll(async () => 
    page = new HelperClass();
    await page.setBrowserSize();
    await page.commonContextTestSteps();
  );

  it("Changing school dropdown value", async () => 
    await page.waitForElement(page.schoolDropDown, 5000);
    await page.schoolDropDown.click();

    await page.waitForElement(page.dropDownList, 5000);
    await page.dropDownList.get(0).click();

    await browser
      .switchTo()
      .frame(element(by.tagName("iframe")).getWebElement());

    await page.roomList.each( item => 
      item.getAttribute("innerText").then(text => 
        highSchoolRoomNameList.push(text);
      );
    );

    await page.waitForElement(page.schoolDropDown, 5000);
    await page.schoolDropDown.click();

    await page.waitForElement(page.dropDownList, 5000);
    await page.dropDownList.get(1).click();

    await browser.switchTo().defaultContent();

    await browser
      .switchTo()
      .frame(element(by.tagName("iframe")).getWebElement());

    await page.roomList.each(item => 
      item.getAttribute("innerText").then(text => 
        middleSchoolRoomNameList.push(text);
      );
    );

    await protractor.promise.controlFlow().execute(() => 
      expect(highSchoolRoomNameList).not.toEqual(middleSchoolRoomNameList);
    );
  );
);

我不断收到此错误:

(node:13672) UnhandledPromiseRejectionWarning: 未处理的承诺 拒绝(拒绝 id:1):StaleElementReferenceError:陈旧元素 参考:元素未附加到页面文档(会话 信息:chrome=65.0.3325.181)(驱动程序信息:chromedriver=2.38.552522 (437e6fbedfa8762dec75e2c5b3ddb86763dc9dcb),平台=Windows NT 6.1.7601 SP1 x86_64) (node:13672) [DEP0018] DeprecationWarning: 不推荐使用未处理的承诺拒绝。未来,承诺 未处理的拒绝将终止 Node.js 进程 具有非零退出代码。 (节点:13672) UnhandledPromiseRejectionWarning:未处理的承诺拒绝 (rejection id: 2): StaleElementReferenceError: stale element 参考:元素未附加到页面文档(会话 信息:铬=65.0.3325.181)

调试后我发现它在以下步骤中失败了

await browser
      .switchTo()
      .frame(element(by.tagName("iframe")).getWebElement());

    await page.roomList.each( item => 
      item.getAttribute("innerText").then(text => 
        highSchoolRoomNameList.push(text);
      );
    );

在我开始迁移到 async/await 之前,整个测试运行良好。这是我的 protractor.conf.js 文件:

// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts

const  SpecReporter  = require("jasmine-spec-reporter");

exports.config = 

  SELENIUM_PROMISE_MANAGER: false,
  allScriptsTimeout: 11000,
  suites: 
    navigation_suite: "./nav-wrapper/e2e/nav-wrapper-navigationTests/**/*.ts"
  ,
  specs: [
     "Test.ts"
  ],
  capabilities: 
    browserName: "chrome"
  ,
  directConnect: true,
  baseUrl: "http://localhost:3000",

  framework: "jasmine",
  jasmineNodeOpts: 
    showColors: true,
    // Set a longer Jasmine default Timeout for debugging purposes
    defaultTimeoutInterval: 999999,
    print: function() 
  ,

  onPrepare() 
    require("ts-node").register(
      project: "./nav-wrapper/e2e/tsconfig.e2e.json"
    );
    jasmine
      .getEnv()
      .addReporter(new SpecReporter( spec:  displayStacktrace: true  ));
  
;

任何关于如何重写这些方法的建议将不胜感激!

【问题讨论】:

尝试在await page.dropDownList.get(0).click(); 之后添加一些睡眠await browser.sleep(10*1000) 以进行调试,以等待页面更改完全加载 我已经调试了很多次,我基本上也是把列表输出到控制台,看看它是否抓住了一些东西,但仍然没有运气。如果我不走异步/等待迁移路线,它工作正常 【参考方案1】:

这不是重写方法问题的直接答案,但只是想帮助您获得比 Unhandled promise rejection 更好的错误(这并不是那么有帮助)

你在哪里使用.then 如果你把.catch() 放在该序列的末尾,你可以对错误做一些事情,比如在控制台中记录它。这是您无论如何都应该做的事情,但也可以帮助您找出导致错误的原因。

这是我的意思的一个例子:

asyncFuncA.then(AsyncFuncB)
      .then(AsyncFuncC)
      .then(AsyncFuncD).catch(e => 
          //Do something with the error here 
            console.error(e) 
            )

以及您的代码示例

await page.roomList.each((item) => 
        item
            .getAttribute('innerText')
            .then((text) => 
                highSchoolRoomNameList.push(text);
            )
            .catch((e) => 
                console.error(e);
            );
    );

【讨论】:

StaleElementReferenceError: stale element reference: element is not attached to the page document (Session info: chrome=65.0.3325.181) (Driver info: chromedriver=2.38.552522 (437e6fbedfa8762dec75e2c5b3ddb86763dc9dcb),platform=Windows NT 6.1.7601 SP1 x86_64)【参考方案2】:

如果你仍然有同样的错误。您可能会尝试以下 sn-p(根据您的稍作修改): 等待浏览器 。切换到() .frame(element(by.tagName("iframe")).getWebElement());

await page.roomList.each(async item => 
  await item.getAttribute("innerText").then(text => 
    highSchoolRoomNameList.push(text);
  );
);

【讨论】:

以上是关于量角器异步/等待 UnhandledPromiseRejectionWarning:未处理的承诺拒绝的主要内容,如果未能解决你的问题,请参考以下文章

量角器异步/等待 UnhandledPromiseRejectionWarning:未处理的承诺拒绝

强制量角器的 onPrepare 等待异步 http 请求

量角器:失败:超时等待异步角度任务在11秒后完成

量角器同步与异步

除了尝试捕获或承诺拒绝之外,有没有办法处理量角器的预期条件?

量角器:单击按钮后如何等待页面完成?