Protractor async / await UnhandledPromiseRejectionWarning: отклонение необработанного обещания

Поэтому я переношу свои тесты транспортира, используя async / await (Ссылка на сайт).

Миграция пока проходит успешно, пока я не сталкиваюсь с этой проблемой. Итак, ниже приведены шаги моего теста, за которым следует код в качестве примера того, с чем я имею дело:

  • Переход на определенную страницу
  • меняет контекст (Смена школы на среднюю школу)
  • Захватывает список комнат в средней школе
  • Снова измените контекст (изменение школы на среднюю школу)
  • Получите список комнат средней школы
  • Сравните оба списка

Связанный код для шагов выше:

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: Unhandled promise rejection (rejection id: 1): 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) (node:13672) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. (node:13672) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): StaleElementReferenceError: stale element reference: element is not attached to the page document (Session info: chrome=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 browser.sleep(10*1000) для целей отладки после await page.dropDownList.get(0).click();, чтобы дождаться полной загрузки изменений страницы

yong 02.05.2018 02:41

Я отлаживал его несколько раз, я в основном выводил список на консоль, просто чтобы посмотреть, схватил он что-то или нет, но все равно не повезло. Он отлично работает, если я не иду по маршруту миграции async / await

user3166089 02.05.2018 18:41
Знаете ли вы, что директивы являются одной из самых мощных и универсальных функций Angular?
Знаете ли вы, что директивы являются одной из самых мощных и универсальных функций Angular?
Директивы позволяют расширять HTML новыми элементами и атрибутами и даже создавать собственные структурные директивы для манипулирования DOM. С...
Разница между Angular и React
Разница между Angular и React
React и AngularJS - это два самых популярных фреймворка для веб-разработки. Оба фреймворка имеют свои уникальные особенности и преимущества, которые...
5
2
3 353
2

Ответы 2

Это не прямой ответ на вопрос о переписывании методов, но просто хотел помочь вам получить лучшую ошибку, чем 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)
user3166089 01.05.2018 19:38

Если у вас все еще та же ошибка. Вероятно, вы можете попробовать следующий фрагмент (немного измененный по сравнению с вашим): ждать браузер .переключить на() .frame (элемент (by.tagName ("iframe")). getWebElement ());

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

Другие вопросы по теме