транспортир: случайный тест не пройден - PullRequest
0 голосов
/ 15 декабря 2018

Итак, я только начал работу над тестами транспортира, и столкнулся со следующей проблемой - мои тесты не пройдены непоследовательно.Иногда тест может пройти, и в следующий раз он не пройден.Причины неудачи очень разные, это может быть потому, что не удалось найти элемент на странице или элемент не имеет текста (даже если он есть).

Я работаю в Ubuntu 14.04, то же самоепроблема актуальна для Chrome Version 71.0.3578.80 и Firefox Version 60.0.2.AngularJS Version 1.7.2 и Protractor Version 5.4.0.Я полагаю, что проблема где-то в моем коде, поэтому ниже я привел пример существующей кодовой базы.

Вот мой конфиг транспортира

exports.config = {
  rootElement: '[ng-app="myapp"]',
  framework: 'jasmine',
  seleniumAddress: 'http://localhost:4444/wd/hub',
  specs: ['./e2e/**/*protractor.js'],
  SELENIUM_PROMISE_MANAGER: false,
  baseUrl: 'https://localhost/',
  allScriptsTimeout: 20000,
  jasmineNodeOpts: {
    defaultTimeoutInterval: 100000,
  },
   capabilities: {
     browserName: 'firefox',
     marionette: true,
     acceptInsecureCerts: true,
     'moz:firefoxOptions': {
       args: ['--headless'],
     },
   },
}

А здесь возможности для браузера Chrome

  capabilities: {
    browserName: 'chrome',
     chromeOptions: {
       args: [ "--headless", "--disable-gpu", "--window-size=1920,1080" ]
     }
  },

И, наконец, мой тестовый набор, который несколько раз не удался

const InsurerViewDriver = require('./insurer-view.driver');
const InsurerRefundDriver = require('./insurer-refund.driver');
const { PageDriver } = require('@utils/page');
const { NotificationsDriver } = require('@utils/service');
const moment = require('moment');

describe(InsurerViewDriver.pageUrl, () => {
  beforeAll(async () => {
    await InsurerViewDriver.goToPage();
  });

  it('- should test "Delete" button', async () => {
    await InsurerViewDriver.clickDelete();

    await NotificationsDriver.toBeShown('success');
    await PageDriver.userToBeNavigated('#/setup/insurers');

    await InsurerViewDriver.goToPage();
  });

  describe('Should test Refunds section', () => {
    it('- should test refund list content', async () => {
      expect(await InsurerRefundDriver.getTitle()).toEqual('REFUNDS');

      const refunds = InsurerRefundDriver.getRefunds();
      expect(await refunds.count()).toBe(1);

      const firstRow = refunds.get(0);
      expect(await firstRow.element(by.binding('item.name')).getText()).toEqual('Direct');
      expect(await firstRow.element(by.binding('item.amount')).getText()).toEqual('$ 50.00');
      expect(await firstRow.element(by.binding('item.number')).getText()).toEqual('');
      expect(await firstRow.element(by.binding('item.date')).getText()).toEqual(moment().format('MMMM DD YYYY'));
    });

    it('- should test add refund action', async () => {
      await InsurerRefundDriver.openNewRefundForm();

      const NewRefundFormDriver = InsurerRefundDriver.getNewRefundForm();

      await NewRefundFormDriver.setPayment(`#555555, ${moment().format('MMMM DD YYYY')} (amount: $2,000, rest: $1,500)`);
      await NewRefundFormDriver.setPaymentMethod('Credit Card');

      expect(await NewRefundFormDriver.getAmount()).toEqual('0');
      await NewRefundFormDriver.setAmount(200.05);
      await NewRefundFormDriver.setAuthorization('qwerty');

      await NewRefundFormDriver.submit();
      await NotificationsDriver.toBeShown('success');

      const interactions = InsurerRefundDriver.getRefunds();
      expect(await interactions.count()).toBe(2);

      expect(await InsurerViewDriver.getInsurerTitleValue('Balance:')).toEqual('Balance: $ 2,200.05');
      expect(await InsurerViewDriver.getInsurerTitleValue('Wallet:')).toEqual('Wallet: $ 4,799.95');
    });
  });
});

А вот некоторые функции из драйверов, на которые я ссылаюсь в тесте выше

  // PageDriver.userToBeNavigated
  this.userToBeNavigated = async function(url) {
    return await browser.wait(
      protractor.ExpectedConditions.urlContains(url),
      5000,
      `Expectation failed - user to be navigated to "${url}"`
    );
  };

  this.pageUrl = '#/insurer/33';

  // InsurerViewDriver.goToPage
  this.goToPage = async () => {
    await browser.get(this.pageUrl);
  };

  // InsurerViewDriver.clickDelete()
  this.clickDelete = async () => {
    await $('[ng-click="$ctrl.removeInsurer()"]').click();
    await DialogDriver.toBeShown('Are you sure you want to remove this entry?');
    await DialogDriver.confirm();
  };

  // NotificationsDriver.toBeShown
  this.toBeShown = async (type, text) => {
    const awaitSeconds = 6;
    return await browser.wait(
      protractor.ExpectedConditions.presenceOf(
        text ? element(by.cssContainingText('.toast-message', text)) : $(`.toast-${type}`)
      ),
      awaitSeconds * 1000,
      `${type} notification should be shown within ${awaitSeconds} sec`
    );
  }

  // InsurerRefundDriver.getRefunds()
  this.getRefunds = () => $('list-refunds-component').all(by.repeater('item in $data'));

// InsurerViewDriver.getInsurerTitleValue
this.getInsurerTitleValue = async (text) => {
    return await element(by.cssContainingText('header-content p', text)).getText();
  };

Я не могу загрузить весь код здесь, чтобы дать вам лучшее понимание, потому что у меня много кода до этого момента, но приведенный выше код является точным примером подхода, который я использую везде, кто-нибудь видит проблемув моем коде?Спасибо.

Ответы [ 4 ]

0 голосов
/ 20 декабря 2018

Через некоторое время я выяснил, в чем проблема.Причина была в том, как я перемещаюсь по приложению.

  this.goToPage = async () => {
    await browser.get(this.pageUrl);
  };

Оказывается, метод browser.get разрешается при изменении URL, но теперь, когда angularjs завершил компиляцию.Я использовал один и тот же подход в каждом наборе тестов, поэтому мои тесты проваливались непоследовательно, иногда страница не загружалась полностью перед началом теста.

Так что вот подход, который добился цели

  this.goToPage = async () => {
    await browser.get(this.pageUrl);
    await browser.wait(EC.presenceOf(`some important element`), 5000, 'Element did not appear after route change');
  };

Вы должны убедиться, что страница выполнила всю работу по компиляции, прежде чем двигаться дальше.

0 голосов
/ 18 декабря 2018

Прежде всего, добавьте этот блок перед экспортом вашей конфигурации.

process.on("unhandledRejection", ({message}) => {
    console.log("\x1b[36m%s\x1b[0m", `Unhandled rejection: ${message}`);
});

это по существу красочно регистрирует на консоли, если вы пропустили async / await где-нибудь, и это даст уверенность, что вы ничего не пропустили.

Во-вторых, я бы установил плагин "protractor-console", чтобы убедиться, что в консоли браузера нет ошибок / отклонений (т.е. исключаю возможность проблем со стороны вашего приложения), и добавил бы в ваш конфиг * 1006.*

plugins: [{
    package: "protractor-console",
    logLevels: [ "severe" ]
}]

Тогда следующая проблема, которую я ожидал бы с этими признаками, это некорректные функции ожидания.В идеале вы должны тестировать их отдельно при разработке проекта e2e, но так как все уже написано, я расскажу вам, как я их отлаживал.Обратите внимание, что этот подход, вероятно, не поможет вам, если ваши действия менее секунды (т.е. вы не можете их заметить).В противном случае следуйте этой цепочке.

1) Я создал конфигурацию запуска в WebStorm, как описано в моем комментарии здесь (найдите мой) Как отлаживать тесты углового транспортира в WebStorm

2) Установите точку останова в первой строке теста, который я хочу отладить

3) Затем выполните тестовый построчно, используя созданную конфигурацию запуска.

Когда вы начнете процесс отладки,Веб-шторм открывает панель с тремя разделами: фреймы, консоль, переменные.Если в разделе переменных есть сообщение connected to localhost и в списке нет переменных, это означает, что ваш шаг все еще выполняется.После завершения загрузки вы можете увидеть все свои переменные и выполнить следующую команду.Итак, основной принцип здесь - вы нажимаете кнопку «Перешагнуть» и следите за разделом переменных.Если переменные появляются перед тем, как загрузка приложений завершена (метод ожидания выполнен, но приложение все еще загружается, что неправильно), то вам нужно поработать над этим методом.Пройдя таким образом, я обнаружил множество пробелов в моих пользовательских методах ожидания.

И, наконец, если это не сработает, пожалуйста, прикрепите трассировку стека ваших ошибок и отправьте мне ping

0 голосов
/ 20 декабря 2018

Меня беспокоит этот фрагмент кода

describe(InsurerViewDriver.pageUrl, () => {
  beforeAll(async () => {
    await InsurerViewDriver.goToPage();
  });

  it('- should test "Delete" button', async () => {
    await InsurerViewDriver.clickDelete();

    await NotificationsDriver.toBeShown('success');
    await PageDriver.userToBeNavigated('#/setup/insurers');

    await InsurerViewDriver.goToPage(); // WHY IS THIS HERE?
  });

  describe('Should test Refunds section', () => {
    it('- should test refund list content', async () => {
      // DOESN'T THIS NEED SOME SETUP?
      expect(await InsurerRefundDriver.getTitle()).toEqual('REFUNDS');
// <truncated>

Вы не должны зависеть от первого условия it для настройки пакета под ним.Вы не опубликовали код для InsurerRefundDriver.getTitle(), но если этот код не отправляет браузер на правильный URL-адрес, а затем ждет завершения загрузки страницы, это проблема.Вы, вероятно, должны иметь await InsurerViewDriver.goToPage(); в предложении beforeEach.

0 голосов
/ 16 декабря 2018

Похоже, это может быть связано с асинхронным JavaScript.

browser.ignoreSynchronization = true;имеет глобальный эффект для всех ваших тестов.Возможно, вам придется установить его обратно в false, так что транспортир ждет завершения углового рендеринга страницы.например, в или перед вашей второй функцией beforeEach

...